diff --git a/windows/test/mytest.py b/windows/test/mytest.py index 59e8904..695a174 100644 --- a/windows/test/mytest.py +++ b/windows/test/mytest.py @@ -51,6 +51,31 @@ class WindowsTestCase(unittest.TestCase): # def setUp(self): # pass + @check_for_gc_garbage + def test_limited_handle_query(self): + #if len(smss_list) != 1: + # raise ValueError("Not just one smss.exe: {0}".format(smss_list)) + + class CustomTestRaise(ValueError): + pass + + def custom_get_handle(): + raise CustomTestRaise("_get_handle() should not be called during this test") + + with Calc32() as calc: + save_handle = calc._handle + del calc._handle + calc._get_handle = custom_get_handle + # Check that trying to get a handle raise 'CustomTestRaise' + with self.assertRaises(CustomTestRaise): + calc.handle + # List of attributes that only require PROCESS_QUERY_INFOR + calc.bitness + calc.time_info + # Re-set the handle to be able to kill it + calc._handle = save_handle + + @check_for_gc_garbage def test_pop_calc_32(self): with Calc32() as calc: diff --git a/windows/winobject/process.py b/windows/winobject/process.py index 3d457c7..3fad120 100644 --- a/windows/winobject/process.py +++ b/windows/winobject/process.py @@ -327,7 +327,8 @@ class Process(AutoHandle): :type: :class:`bool` """ - return utils.is_wow_64(self.handle) + # return utils.is_wow_64(self.handle) + return utils.is_wow_64(self.limited_handle) @utils.fixedpropety def bitness(self): @@ -341,6 +342,13 @@ class Process(AutoHandle): return 32 return 64 + @utils.fixedpropety + def limited_handle(self): + if windows.system.version[0] <= 5: + # Windows XP | Serveur 2003 + return winproxy.OpenProcess(PROCESS_QUERY_INFORMATION, dwProcessId=self.pid) + return winproxy.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, dwProcessId=self.pid) + @utils.fixedpropety def ppid(self): @@ -662,24 +670,33 @@ class Process(AutoHandle): ExitTime = FILETIME() KernelTime = FILETIME() UserTime = FILETIME() - winproxy.GetProcessTimes(self.handle, CreationTime, ExitTime, KernelTime, UserTime) + winproxy.GetProcessTimes(self.limited_handle, CreationTime, ExitTime, KernelTime, UserTime) creation = (CreationTime.dwHighDateTime << 32) + CreationTime.dwLowDateTime exit = (ExitTime.dwHighDateTime << 32) + ExitTime.dwLowDateTime kernel = (KernelTime.dwHighDateTime << 32) + KernelTime.dwLowDateTime user = (UserTime.dwHighDateTime << 32) + UserTime.dwLowDateTime - return TimeInfo(creation, exit, kernel, user) def open_token(self, flags=TOKEN_QUERY): token_handle = HANDLE() - winproxy.OpenProcessToken(self.handle, flags, byref(token_handle)) + winproxy.OpenProcessToken(self.limited_handle, flags, byref(token_handle)) return Token(token_handle.value) token = property(open_token) + def __del__(self): + super(Process, self).__del__() + # Same logic that AutoHandle.__del__ for Process.limited_handle + # Assert that Process inherit AutoHandle + if hasattr(self, "_limited_handle") and self._limited_handle: + # Prevent some bug where dbgprint might be None when __del__ is called in a closing process + dbgprint("Closing limited handle {0} for {1}".format(hex(self._limited_handle), self), "HANDLE") if dbgprint is not None else None + self._close_function(self._limited_handle) + + # @utils.fixedpropety # def token(self): # """The token of the process