NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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()