waitables.py (4017B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\osutils\win32api\waitables.py 2 import ctypes 3 from ctypes.wintypes import BOOL, DWORD, HANDLE 4 import weakref 5 QS_ALLEVENTS = 1215 6 QS_ALLINPUT = 1279 7 QS_RAWINPUT = 1024 8 MWMO_ALERTABLE = 2 9 STATUS_WAIT_0 = 0 10 STATUS_ABANDONED_WAIT_0 = 128 11 WAIT_OBJECT_0 = STATUS_WAIT_0 + 0 12 WAIT_IO_COMPLETION = 192 13 WAIT_ABANDONED_0 = STATUS_ABANDONED_WAIT_0 + 0 14 WAIT_FAILED = 4294967295L 15 INFINITE = 4294967295L 16 WAIT_TIMEOUT = 258 17 18 class Waitables(object): 19 20 def __init__(self): 21 self.waitables = weakref.WeakValueDictionary() 22 23 def InsertHandle(self, handle, callback): 24 if handle is None: 25 CreateEventW = ctypes.windll.kernel32.CreateEventW 26 CreateEventW.restype = HANDLE 27 handle = CreateEventW(None, BOOL(), BOOL(), None) 28 if not handle: 29 raise ctypes.WinError() 30 self.waitables[handle] = callback 31 return handle 32 33 def RemoveHandle(self, handle, close = False): 34 del self.waitables[handle] 35 if close: 36 if not ctypes.windll.kernel32.CloseHandle(HANDLE(handle)): 37 raise ctypes.WinError() 38 39 def Wait(self, milliseconds = 1000): 40 handles, callbacks = self.waitables.keys(), self.waitables.values() 41 HandleArray = ctypes.c_void_p * len(handles) 42 handles = HandleArray(*handles) 43 MsgWaitForMultipleObjectsEx = ctypes.windll.user32.MsgWaitForMultipleObjectsEx 44 MsgWaitForMultipleObjectsEx.restype = DWORD 45 ret = MsgWaitForMultipleObjectsEx(len(handles), handles, milliseconds, QS_ALLINPUT, MWMO_ALERTABLE) 46 if WAIT_OBJECT_0 <= ret <= WAIT_OBJECT_0 + len(handles) - 1: 47 idx = ret - WAIT_OBJECT_0 48 if handles[idx] in self.waitables: 49 callbacks[idx].OnObjectSignaled(handles[idx], False) 50 return self.Wait(0) 51 if ret == WAIT_OBJECT_0 + len(handles): 52 return ret 53 if WAIT_ABANDONED_0 <= ret <= WAIT_ABANDONED_0 + len(handles) - 1: 54 idx = ret - WAIT_OBJECT_0 55 if handles[idx] in self.waitables: 56 callbacks[idx].OnObjectSignaled(handles[idx], True) 57 return self.Wait(0) 58 if ret == WAIT_IO_COMPLETION: 59 return ret 60 if ret == WAIT_TIMEOUT: 61 return ret 62 if ret == WAIT_FAILED: 63 raise ctypes.WinError() 64 else: 65 raise RuntimeError('Wait: Unknown return value from MsgWaitForMultipleObjectsEx:', ret) 66 67 68 def WaitForSingleObject(handle, milliseconds = 0): 69 ret = ctypes.windll.kernel32.WaitForSingleObject(handle, milliseconds) 70 if ret == WAIT_OBJECT_0: 71 return True 72 if ret == WAIT_TIMEOUT: 73 return False 74 if ret == WAIT_FAILED: 75 raise ctypes.WinError() 76 else: 77 raise RuntimeError('WaitForSingleObject: Unknown return value from wait:', ret) 78 79 80 def WaitForMultipleObjects(handles, waitAll, milliseconds): 81 HandleArray = ctypes.c_void_p * len(handles) 82 handles = HandleArray(*handles) 83 ctypes.WaitForMultipleObjects(len(handles), handles, bool(waitAll), milliseconds) 84 85 86 FILE_NOTIFY_CHANGE_FILE_NAME = 1 87 FILE_NOTIFY_CHANGE_DIR_NAME = 2 88 FILE_NOTIFY_CHANGE_ATTRIBUTES = 4 89 FILE_NOTIFY_CHANGE_SIZE = 8 90 FILE_NOTIFY_CHANGE_LAST_WRITE = 16 91 FILE_NOTIFY_CHANGE_LAST_ACCESS = 32 92 FILE_NOTIFY_CHANGE_CREATION = 64 93 FILE_NOTIFY_CHANGE_SECURITY = 256 94 95 def FindFirstChangeNotification(pathName, watchSubTree, notifyFilter): 96 FindFirstChangeNotificationW = ctypes.windll.kernel32.FindFirstChangeNotificationW 97 FindFirstChangeNotificationW.restype = HANDLE 98 return FindFirstChangeNotificationW(unicode(pathName), bool(watchSubTree), notifyFilter) 99 100 101 def FindNextChangeNotification(handle): 102 if not ctypes.windll.kernel32.FindNextChangeNotification(HANDLE(handle)): 103 raise ctypes.WinError() 104 105 106 def FindCloseChangeNotification(handle): 107 if not ctypes.windll.kernel32.FindCloseChangeNotification(HANDLE(handle)): 108 raise ctypes.WinError()