update xlib.api.win32

This commit is contained in:
iperov 2022-05-15 17:45:49 +04:00
parent 878c14756b
commit 2be3278753
21 changed files with 726 additions and 192 deletions

View file

@ -0,0 +1,40 @@
from ctypes import c_uint, c_int, Structure
class D3D_FEATURE_LEVEL(c_uint):
D3D_FEATURE_LEVEL_1_0_CORE = 0x1000
D3D_FEATURE_LEVEL_9_1 = 0x9100
D3D_FEATURE_LEVEL_9_2 = 0x9200
D3D_FEATURE_LEVEL_9_3 = 0x9300
D3D_FEATURE_LEVEL_10_0 = 0xa000
D3D_FEATURE_LEVEL_10_1 = 0xa100
D3D_FEATURE_LEVEL_11_0 = 0xb000
D3D_FEATURE_LEVEL_11_1 = 0xb100
D3D_FEATURE_LEVEL_12_0 = 0xc000
D3D_FEATURE_LEVEL_12_1 = 0xc100
class D3D12_COMMAND_LIST_TYPE(c_uint):
D3D12_COMMAND_LIST_TYPE_DIRECT = 0
D3D12_COMMAND_LIST_TYPE_BUNDLE = 1
D3D12_COMMAND_LIST_TYPE_COMPUTE = 2
D3D12_COMMAND_LIST_TYPE_COPY = 3
D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE = 4
D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS = 5
D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE = 6
class D3D12_COMMAND_QUEUE_FLAGS(c_uint):
D3D12_COMMAND_QUEUE_FLAG_NONE = 0
D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT = 0x1
class D3D12_COMMAND_QUEUE_DESC(Structure):
_fields_ = [('Type', D3D12_COMMAND_LIST_TYPE),
('Priority', c_int),
('Flags', D3D12_COMMAND_QUEUE_FLAGS),
('NodeMask', c_uint),
]
def __init__(self):
self.Type : D3D12_COMMAND_LIST_TYPE = D3D12_COMMAND_LIST_TYPE()
self.Priority : c_int = c_int()
self.Flags : D3D12_COMMAND_QUEUE_FLAGS = D3D12_COMMAND_QUEUE_FLAGS()
self.NodeMask : c_uint = c_uint()

View file

@ -0,0 +1 @@
from .helper import get_video_input_devices_names

View file

@ -0,0 +1,40 @@
from typing import List
from .. import ole32, uuids, strmif, wintypes, objidl, oaidl
def get_video_input_devices_names() -> List[str]:
"""
returns a list of available names of VideoInputDevice's
ole32 should be initialized before use
"""
# based on https://docs.microsoft.com/ru-ru/windows/win32/directshow/selecting-a-capture-device
names = []
sys_dev_enum = strmif.ICreateDevEnum()
if ole32.CoCreateInstance(uuids.CLSID_SystemDeviceEnum, None, ole32.CLSCTX.CLSCTX_INPROC_SERVER, strmif.ICreateDevEnum.IID, sys_dev_enum) == wintypes.ERROR.SUCCESS:
pEnumCat = objidl.IEnumMoniker()
if sys_dev_enum.CreateClassEnumerator(uuids.CLSID_VideoInputDeviceCategory, pEnumCat, 0) == wintypes.ERROR.SUCCESS:
moniker = objidl.IMoniker()
while pEnumCat.Next(1, moniker, None) == wintypes.ERROR.SUCCESS:
prop_bag = oaidl.IPropertyBag()
if moniker.BindToStorage(None, None, oaidl.IPropertyBag.IID, prop_bag) == wintypes.ERROR.SUCCESS:
var = wintypes.VARIANT()
hr = prop_bag.Read(wintypes.LPCOLESTR('Description'), var, None )
if hr != wintypes.ERROR.SUCCESS:
hr = prop_bag.Read(wintypes.LPCOLESTR('FriendlyName'), var, None )
names.append(var.value.bstrVal.value if hr == wintypes.ERROR.SUCCESS else 'unnamed')
prop_bag.Release()
moniker.Release()
pEnumCat.Release()
sys_dev_enum.Release()
return names

View file

@ -1,13 +1,13 @@
from ctypes import (POINTER, WINFUNCTYPE, byref, c_byte, c_int64, c_longlong, from ctypes import POINTER, c_longlong, c_uint, c_void_p
c_size_t, c_ubyte, c_uint, c_uint32, c_ulong, c_void_p, from typing import Union
c_wchar)
from typing import List, Union
from xlib.api.win32.wintypes.wintypes import BOOL from xlib.api.win32.wintypes.wintypes import BOOL
from ..wintypes import (ERROR, GUID, HRESULT, REFGUID, REFIID, IUnknown, dll_import, from ..wintypes import (ERROR, GUID, HRESULT, REFGUID, REFIID, IUnknown,
interface) dll_import, interface)
from .structs import * from .structs import *
@interface @interface
class IDXGIObject(IUnknown): class IDXGIObject(IUnknown):
def SetPrivateData (self, guid : REFGUID, id : c_uint, data : c_void_p) -> HRESULT: ... def SetPrivateData (self, guid : REFGUID, id : c_uint, data : c_void_p) -> HRESULT: ...

View file

@ -33,6 +33,6 @@ def SetPriorityClass(hProcess : HANDLE, priority_class : DWORD ) -> BOOL: ...
def WaitForSingleObject(hHandle : HANDLE, dwMilliseconds : DWORD) -> DWORD:... def WaitForSingleObject(hHandle : HANDLE, dwMilliseconds : DWORD) -> DWORD:...
@dll_import('kernel32') @dll_import('kernel32')
def Sleep( dwMilliseconds : DWORD):... def Sleep( dwMilliseconds : DWORD) -> None:...

View file

@ -0,0 +1 @@
from .oaidl import IPropertyBag, IErrorLog

View file

@ -0,0 +1,14 @@
from ctypes import POINTER, c_void_p, c_wchar_p
from ..wintypes import (GUID, DWORD, IUnknown, interface, VARIANT, HRESULT, LPCOLESTR)
@interface
class IErrorLog(IUnknown):
def AddError(self, pszPropName : LPCOLESTR, pExcepInfo : c_void_p) -> HRESULT: ... #EXCEPINFO
IID = GUID('3127ca40-446e-11ce-8135-00aa004bb851')
@interface
class IPropertyBag(IUnknown):
def Read(self, pszPropName : LPCOLESTR, pVar : POINTER(VARIANT), pErrorLog : IErrorLog) -> HRESULT: ...
def Write(self, pszPropName : LPCOLESTR, pVar : POINTER(VARIANT)) -> HRESULT: ...
IID = GUID('55272a00-42cb-11ce-8135-00aa004bb851')

View file

@ -0,0 +1 @@
from .objidl import IEnumMoniker, IMoniker, IPersistStream, IPersist, IStream

View file

@ -0,0 +1,107 @@
from ctypes import POINTER, c_void_p
from ..wintypes import (GUID, DWORD, IUnknown, CLSID, interface, HRESULT, REFIID, BOOL, ULARGE_INTEGER)
@interface
class IStream(IUnknown): #ISequentialStream
IID = GUID('0000000c-0000-0000-c000-000000000046')
@interface
class IPersist(IUnknown):
def GetClassID(self, pClassID : POINTER(CLSID) ) -> HRESULT: ...
IID = GUID('0000010c-0000-0000-c000-000000000046')
@interface
class IPersistStream(IPersist):
def IsDirty(self) -> HRESULT: ...
def Load(self, pStm : IStream) -> HRESULT: ...
def Save(self, pStm : IStream, fClearDirty : BOOL) -> HRESULT: ...
def GetSizeMax(self, pcbSize : POINTER(ULARGE_INTEGER) ) -> HRESULT: ...
IID = GUID('00000109-0000-0000-c000-000000000046')
@interface
class IMoniker(IPersistStream):
def BindToObject(self,
pbc : c_void_p, #IBindCtx
pmkToLeft : IUnknown, #IMoniker,
riidResult : REFIID,
ppvResult : POINTER(c_void_p)) -> HRESULT: ...
def BindToStorage(self,
pbc : c_void_p, #IBindCtx
pmkToLeft : IUnknown, #IMoniker,
riid : REFIID,
ppvObj : POINTER(c_void_p)) -> HRESULT: ...
# virtual HRESULT STDMETHODCALLTYPE Reduce(
# IBindCtx *pbc,
# DWORD dwReduceHowFar,
# IMoniker **ppmkToLeft,
# IMoniker **ppmkReduced) = 0;
# virtual HRESULT STDMETHODCALLTYPE ComposeWith(
# IMoniker *pmkRight,
# WINBOOL fOnlyIfNotGeneric,
# IMoniker **ppmkComposite) = 0;
# virtual HRESULT STDMETHODCALLTYPE Enum(
# WINBOOL fForward,
# IEnumMoniker **ppenumMoniker) = 0;
# virtual HRESULT STDMETHODCALLTYPE IsEqual(
# IMoniker *pmkOtherMoniker) = 0;
# virtual HRESULT STDMETHODCALLTYPE Hash(
# DWORD *pdwHash) = 0;
# virtual HRESULT STDMETHODCALLTYPE IsRunning(
# IBindCtx *pbc,
# IMoniker *pmkToLeft,
# IMoniker *pmkNewlyRunning) = 0;
# virtual HRESULT STDMETHODCALLTYPE GetTimeOfLastChange(
# IBindCtx *pbc,
# IMoniker *pmkToLeft,
# FILETIME *pFileTime) = 0;
# virtual HRESULT STDMETHODCALLTYPE Inverse(
# IMoniker **ppmk) = 0;
# virtual HRESULT STDMETHODCALLTYPE CommonPrefixWith(
# IMoniker *pmkOther,
# IMoniker **ppmkPrefix) = 0;
# virtual HRESULT STDMETHODCALLTYPE RelativePathTo(
# IMoniker *pmkOther,
# IMoniker **ppmkRelPath) = 0;
# virtual HRESULT STDMETHODCALLTYPE GetDisplayName(
# IBindCtx *pbc,
# IMoniker *pmkToLeft,
# LPOLESTR *ppszDisplayName) = 0;
# virtual HRESULT STDMETHODCALLTYPE ParseDisplayName(
# IBindCtx *pbc,
# IMoniker *pmkToLeft,
# LPOLESTR pszDisplayName,
# ULONG *pchEaten,
# IMoniker **ppmkOut) = 0;
# virtual HRESULT STDMETHODCALLTYPE IsSystemMoniker(
# DWORD *pdwMksys) = 0;
IID = GUID('0000000f-0000-0000-c000-000000000046')
@interface
class IEnumMoniker(IUnknown):
#def CreateClassEnumerator(refiid : REFIID, enumMoniker : POINTER(IEnumMoniker), flags : DWORD ) -> HRESULT: ...
def Next(self, celt : DWORD, rgelt : POINTER(IMoniker), pceltFetched : POINTER(DWORD)) -> HRESULT: ...
#virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt) = 0;
#virtual HRESULT STDMETHODCALLTYPE Reset() = 0;
#virtual HRESULT STDMETHODCALLTYPE Clone(IEnumMoniker **ppenum) = 0;
IID = GUID('00000102-0000-0000-C000-000000000046')

View file

@ -0,0 +1 @@
from .ole32 import CoInitializeEx, COINIT, CLSCTX, CoCreateInstance, CoUninitialize

View file

@ -0,0 +1,18 @@
from ctypes import (POINTER, WINFUNCTYPE, byref, c_byte, c_int64, c_longlong,
c_size_t, c_ubyte, c_uint, c_uint32, c_ulong, c_void_p,
c_wchar)
from typing import Union
from ..wintypes import (DWORD, ERROR, GUID, HRESULT, REFCLSID, REFGUID, REFIID,
IUnknown, dll_import, interface)
from .structs import *
@dll_import('ole32')
def CoInitializeEx(pvReserved : c_void_p, dwCoInit : COINIT ) -> HRESULT: ...
@dll_import('ole32')
def CoUninitialize() -> None: ...
@dll_import('ole32')
def CoCreateInstance (rclsid : REFCLSID, pUnkOuter : POINTER(IUnknown), dwClsContext : CLSCTX, refiid : REFIID, ppv : POINTER(IUnknown) ) -> HRESULT: ...

View file

@ -0,0 +1,36 @@
from ..wintypes import DWORD
class COINIT(DWORD):
APARTMENTTHREADED = 0x2
MULTITHREADED = 0x2
DISABLE_OLE1DDE = 0x4
SPEED_OVER_MEMORY = 0x8
class CLSCTX(DWORD):
CLSCTX_INPROC_SERVER = 0x1
CLSCTX_INPROC_HANDLER = 0x2
CLSCTX_LOCAL_SERVER = 0x4
CLSCTX_INPROC_SERVER16 = 0x8
CLSCTX_REMOTE_SERVER = 0x10
CLSCTX_INPROC_HANDLER16 = 0x20
CLSCTX_RESERVED1 = 0x40
CLSCTX_RESERVED2 = 0x80
CLSCTX_RESERVED3 = 0x100
CLSCTX_RESERVED4 = 0x200
CLSCTX_NO_CODE_DOWNLOAD = 0x400
CLSCTX_RESERVED5 = 0x800
CLSCTX_NO_CUSTOM_MARSHAL = 0x1000
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000
CLSCTX_NO_FAILURE_LOG = 0x4000
CLSCTX_DISABLE_AAA = 0x8000
CLSCTX_ENABLE_AAA = 0x10000
CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000
CLSCTX_ACTIVATE_X86_SERVER = 0x40000
CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000
CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000
CLSCTX_ENABLE_CLOAKING = 0x100000
CLSCTX_APPCONTAINER = 0x400000
CLSCTX_ACTIVATE_AAA_AS_IU = 0x800000
CLSCTX_RESERVED6 = 0x1000000
CLSCTX_ACTIVATE_ARM32_SERVER = 0x2000000
CLSCTX_PS_DLL = 0x8000000

View file

@ -0,0 +1 @@
from .oleaut32 import VariantInit

View file

@ -0,0 +1,7 @@
from ctypes import POINTER, Structure
from ..wintypes import VARIANT, dll_import
@dll_import('OleAut32')
def VariantInit( pvarg : POINTER(VARIANT) ) -> None: ...

View file

@ -0,0 +1 @@
from .strmif import ICreateDevEnum

View file

@ -0,0 +1,10 @@
from ctypes import POINTER
from ..objidl import IEnumMoniker
from ..wintypes import DWORD, GUID, HRESULT, REFIID, IUnknown, interface
@interface
class ICreateDevEnum(IUnknown):
def CreateClassEnumerator(self, refiid : REFIID, enumMoniker : POINTER(IEnumMoniker), flags : DWORD ) -> HRESULT: ...
IID = GUID('29840822-5B84-11D0-BD3B-00A0C911CE86')

View file

@ -0,0 +1 @@
from .uuids import CLSID_SystemDeviceEnum, CLSID_VideoInputDeviceCategory

View file

@ -0,0 +1,4 @@
from ..wintypes import CLSID
CLSID_SystemDeviceEnum = CLSID('62BE5D10-60EB-11d0-BD3B-00A0C911CE86')
CLSID_VideoInputDeviceCategory = CLSID('860bb310-5d01-11d0-bd3b-00a0c911ce86')

View file

@ -1,6 +1,4 @@
#from ctypes import c_void_p, c_wchar_p, POINTER from ..wintypes import DWORD, MMRESULT, dll_import
from ..wintypes import BOOL, DWORD, MMRESULT, dll_import
@dll_import('Winmm') @dll_import('Winmm')
def timeBeginPeriod(uPeriod : DWORD) -> MMRESULT: ... def timeBeginPeriod(uPeriod : DWORD) -> MMRESULT: ...

View file

@ -1,3 +1,6 @@
from .wintypes import (BOOL, DWORD, ERROR, GUID, HANDLE, HRESULT, IID, from .wintypes import (BOOL, CHAR, CLSID, DOUBLE, DWORD, ERROR, FLOAT, GUID,
LARGE_INTEGER, MMERROR, MMRESULT, REFGUID, REFIID, HANDLE, HRESULT, IID, INT, LARGE_INTEGER, LONG,
IUnknown, dll_import, interface) LONGLONG, LPCOLESTR, MMERROR, MMRESULT, PVOID,
REFCLSID, REFGUID, REFIID, SHORT, UINT, ULARGE_INTEGER,
USHORT, VARIANT, VARTYPE, WORD, IUnknown, dll_import,
interface)

View file

@ -1,14 +1,19 @@
import ctypes import ctypes
import uuid import uuid
from ctypes import (POINTER, WINFUNCTYPE, byref, c_byte, c_int64, from ctypes import (POINTER, WINFUNCTYPE, c_char_p, c_int16, c_int32, c_float, c_double, c_uint8,
c_longlong, c_size_t, c_ubyte, c_uint, c_uint32, c_ulong, c_int64, c_int8, c_size_t, c_ubyte, c_uint, c_uint16,
c_void_p, c_wchar) c_uint32, c_uint64, c_ulong, c_void_p, c_wchar_p)
from ctypes.util import find_library from ctypes.util import find_library
from enum import IntEnum from enum import IntEnum
dlls_by_name = {} dlls_by_name = {}
def dll_import(dll_name): def dll_import(dll_name):
"""
always annotate return type even if it is None !
"""
dll = dlls_by_name.get(dll_name, None) dll = dlls_by_name.get(dll_name, None)
if dll is None: if dll is None:
try: try:
@ -88,6 +93,7 @@ def interface(cls_obj):
class ERROR(IntEnum): class ERROR(IntEnum):
# https://raw.githubusercontent.com/tpn/winsdk-10/master/Include/10.0.14393.0/shared/winerror.h # https://raw.githubusercontent.com/tpn/winsdk-10/master/Include/10.0.14393.0/shared/winerror.h
SUCCESS = 0 SUCCESS = 0
INVALID_FUNCTION = 1
E_NOINTERFACE = 0x80004002 E_NOINTERFACE = 0x80004002
DXGI_ERROR_NOT_FOUND = 0x887A0002 DXGI_ERROR_NOT_FOUND = 0x887A0002
@ -152,6 +158,159 @@ class HANDLE(c_void_p):
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()
class BOOL(c_size_t):
def __eq__(self, other):
if isinstance(other, self.__class__):
return (self.value != 0) == (other.value != 0)
elif isinstance(other, bool):
return (self.value != 0) == other
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'BOOL ({self.value != 0})'
def __repr__(self):
return self.__str__()
class CHAR(c_int8):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'CHAR ({self.value})'
def __repr__(self):
return self.__str__()
class BYTE(c_uint8):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'BYTE ({self.value})'
def __repr__(self):
return self.__str__()
class SHORT(c_int16):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'SHORT ({self.value})'
def __repr__(self):
return self.__str__()
class USHORT(c_uint16):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'USHORT ({self.value})'
def __repr__(self):
return self.__str__()
class LONG(c_int32):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'LONG ({self.value})'
def __repr__(self):
return self.__str__()
class ULONG(c_uint32):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'ULONG ({self.value})'
def __repr__(self):
return self.__str__()
class INT(c_int32):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'INT ({self.value})'
def __repr__(self):
return self.__str__()
class UINT(c_uint32):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'UINT ({self.value})'
def __repr__(self):
return self.__str__()
class WORD(c_uint16):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'WORD ({self.value})'
def __repr__(self):
return self.__str__()
class DWORD(c_uint): class DWORD(c_uint):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, self.__class__): if isinstance(other, self.__class__):
@ -182,12 +341,10 @@ class LARGE_INTEGER(c_int64):
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()
class BOOL(c_size_t): class LONGLONG(c_int64):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, self.__class__): if isinstance(other, self.__class__):
return (self.value != 0) == (other.value != 0) return self.value == other.value
elif isinstance(other, bool):
return (self.value != 0) == other
else: else:
return False return False
def __ne__(self, other): def __ne__(self, other):
@ -195,21 +352,104 @@ class BOOL(c_size_t):
def __hash__(self): def __hash__(self):
return self.value.__hash__() return self.value.__hash__()
def __str__(self): def __str__(self):
return f'BOOL ({self.value != 0})' return f'LONGLONG ({self.value})'
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()
class ULONGLONG(c_uint64):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'ULONGLONG ({self.value})'
def __repr__(self):
return self.__str__()
class ULARGE_INTEGER(c_uint64):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'ULARGE_INTEGER ({self.value})'
def __repr__(self):
return self.__str__()
class FLOAT(c_float):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'FLOAT ({self.value})'
def __repr__(self):
return self.__str__()
class DOUBLE(c_double):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'DOUBLE ({self.value})'
def __repr__(self):
return self.__str__()
class PVOID(c_void_p):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.value == other.value
else:
return False
def __ne__(self, other):
return not(self == other)
def __hash__(self):
return self.value.__hash__()
def __str__(self):
return f'PVOID ({self.value})'
def __repr__(self):
return self.__str__()
class GUID (ctypes.Structure): class GUID (ctypes.Structure):
_fields_ = [('data', c_ubyte * 16)] _fields_ = [('data', c_ubyte * 16)]
def __init__(self, hexstr=None): def __init__(self, hexstr=None):
super().__init__() super().__init__()
self.data[:] = uuid.UUID(hexstr).bytes_le self.data[:] = uuid.UUID(hexstr).bytes_le
class CSTR(c_char_p):
def __init__(self, s : str):
super().__init__(s.encode('utf-8'))
class CLSID(GUID): ...
class LPCOLESTR(c_wchar_p): ...
class BSTR(c_wchar_p): ...
IID = GUID IID = GUID
REFIID = POINTER(IID) REFIID = POINTER(IID)
REFGUID = POINTER(GUID) REFGUID = POINTER(GUID)
REFCLSID = POINTER(CLSID)
#LPOLESTR = POINTER(OLESTR)
@interface @interface
class IUnknown(c_void_p): class IUnknown(c_void_p):
@ -226,126 +466,136 @@ class IUnknown(c_void_p):
return None return None
# class COMObject(c_void_p): class VARTYPE(SHORT):
# """ VT_EMPTY = 0
# base class for COM objects VT_NULL = 1
VT_I2 = 2
VT_I4 = 3
VT_R4 = 4
VT_R8 = 5
VT_CY = 6
VT_DATE = 7
VT_BSTR = 8
VT_DISPATCH = 9
VT_ERROR = 10
VT_BOOL = 11
VT_VARIANT = 12
VT_UNKNOWN = 13
VT_DECIMAL = 14
VT_I1 = 16
VT_UI1 = 17
VT_UI2 = 18
VT_UI4 = 19
VT_I8 = 20
VT_UI8 = 21
VT_INT = 22
VT_UINT = 23
VT_VOID = 24
VT_HRESULT = 25
VT_PTR = 26
VT_SAFEARRAY = 27
VT_CARRAY = 28
VT_USERDEFINED = 29
VT_LPSTR = 30
VT_LPWSTR = 31
VT_RECORD = 36
VT_INT_PTR = 37
VT_UINT_PTR = 38
VT_FILETIME = 64
VT_BLOB = 65
VT_STREAM = 66
VT_STORAGE = 67
VT_STREAMED_OBJECT = 68
VT_STORED_OBJECT = 69
VT_BLOB_OBJECT = 70
VT_CF = 71
VT_CLSID = 72
VT_VERSIONED_STREAM = 73
VT_BSTR_BLOB = 0xfff
VT_VECTOR = 0x1000
VT_ARRAY = 0x2000
VT_BYREF = 0x4000
VT_RESERVED = 0x8000
VT_ILLEGAL = 0xffff
VT_ILLEGALMASKED = 0xfff
VT_TYPEMASK = 0xff
# you should implement _vf_table in every subclass class _VARIANT_RECORD(ctypes.Structure):
# """ _fields_ = [ ('pvRecord', PVOID),
# def _vf_table(): return dict() ('pRecInfo', IUnknown ) ] #IRecordInfo
# def _get_vf_func(self, name): class _VARIANT_NAME_3(ctypes.Union):
# """ _fields_ = [ ('llVal', LONGLONG),
# returns function from vf table by name ('lVal', LONG),
# """ ('bVal', BYTE),
# if self.value is None: ('iVal', SHORT),
# raise Exception(f'COMObject {self} was not assigned.') ('fltVal', FLOAT),
('dblVal', DOUBLE),
#VARIANT_BOOL boolVal;
#VARIANT_BOOL __OBSOLETE__VARIANT_BOOL;
#SCODE scode;
#CY cyVal;
#DATE date;
('bstrVal', BSTR),
('punkVal', IUnknown),
#IDispatch *pdispVal;
#SAFEARRAY *parray;
('pbVal', POINTER(BYTE)),
('piVal', POINTER(SHORT)),
('plVal', POINTER(LONG)),
('pllVal', POINTER(LONGLONG)),
('pfltVal', POINTER(FLOAT)),
('pdblVal', POINTER(DOUBLE)),
# VARIANT_BOOL *pboolVal;
# VARIANT_BOOL *__OBSOLETE__VARIANT_PBOOL;
# SCODE *pscode;
# CY *pcyVal;
# DATE *pdate;
('pbstrVal', POINTER(BSTR) ),
('ppunkVal', POINTER(IUnknown) ),
# IDispatch **ppdispVal;
# SAFEARRAY **pparray;
# VARIANT *pvarVal;
('byref', PVOID),
('cVal', CHAR),
('uiVal', USHORT),
('ulVal', ULONG),
('ullVal', ULONGLONG),
('intVal', INT),
('uintVal', UINT),
#DECIMAL *pdecVal;
('pcVal', POINTER(CHAR)),
('puiVal', POINTER(USHORT)),
('pulVal', POINTER(ULONG)),
('pullVal', POINTER(ULONGLONG)),
('pintVal', POINTER(INT)),
('puintVal', POINTER(UINT)),
# vf_proto_cls = self.__class__ ('record', _VARIANT_RECORD ),
]
# vf = getattr(vf_proto_cls, '_vf', None) class VARIANT(ctypes.Structure):
# if vf is None: _fields_ = [('vt', VARTYPE ),
# vf = {} ('wReserved1', WORD),
('wReserved2', WORD),
('wReserved3', WORD),
('value', _VARIANT_NAME_3),
]
def __init__(self):
"""
by default initialized to VT_EMPTY
"""
# hierarchy = [] self.vt : VARTYPE = VARTYPE.VT_EMPTY
# while vf_proto_cls != COMObject: #self.wReserved1 : WORD = WORD()
# hierarchy.insert(0, vf_proto_cls) #self.wReserved2 : WORD = WORD()
# vf_proto_cls = vf_proto_cls.__bases__[0] #self.wReserved3 : WORD = WORD()
#self.value : _VARIANT_NAME_3 = _VARIANT_NAME_3()
super().__init__()
# func_id = 0 def __repr__(self): return self.__str__()
# for vf_proto_cls in hierarchy: def __str__(self):
# for func_name, func_type in vf_proto_cls._vf_table().items(): return f'VARIANT object: { self.vt }'
# if func_name in vf:
# raise Exception(f'Function duplicate {func_name} in {self}')
# vf[func_name] = (func_id, func_type)
# func_id += 1
# setattr(vf_proto_cls, '_vf', vf)
# func_id, func_type = vf[name]
# vf_table = ct.cast( c_void_p( ct.cast(self, POINTER(c_void_p))[0] ), POINTER(c_void_p))
# return func_type(vf_table[func_id])
# class IUnknown(COMObject):
# def QueryInterface(self, iid : REFIID, out_IUnknown : POINTER(c_void_p)) -> HRESULT:
# return self._get_vf_func('QueryInterface')(self, iid, out_IUnknown)
# def AddRef(self) -> c_ulong:
# return self._get_vf_func('AddRef')(self)
# def Release(self) -> c_ulong:
# return self._get_vf_func('Release')(self)
# IID = GUID('00000000-0000-0000-C000-000000000046')
# def _vf_table(): return dict(
# QueryInterface = WINFUNCTYPE(HRESULT, IUnknown, REFIID, POINTER(IUnknown) ),
# AddRef = WINFUNCTYPE(c_ulong, IUnknown),
# Release = WINFUNCTYPE(c_ulong, IUnknown),
# )
# def query_interface(self, iid : IID) -> 'IUnknown':
# out_IUnknown = IUnknown()
# hr = self.QueryInterface(iid, out_IUnknown)
# if hr == ERROR.SUCCESS:
# return out_IUnknown
# return None
# class COMBase(c_void_p): ...
# def com_class(cls_obj):
# virtual_idx = 0
# # Determine virtuals count from parent class
# parent = cls_obj.__bases__[0]
# if parent != COMBase:
# virtual_idx = parent._virtuals_count
# # Walk through all virtuals and assign virtual idx
# for key, value in cls_obj.__dict__.items():
# _virtual_idx = getattr(value, '_virtual_idx', None)
# if _virtual_idx is not None:
# value._virtual_idx = virtual_idx
# virtual_idx += 1
# cls_obj._virtuals_count = virtual_idx
# return cls_obj
# @com_class
# class IUnknown(COMBase):
# @virtual
# def QueryInterface(self, refiid : REFIID, pIUnknown : POINTER(c_void_p) ) -> HRESULT: ...
# @virtual
# def AddRef(self : COMBase) -> c_ulong: ...
# @virtual
# def Release(self : COMBase) -> c_ulong: ...
# def virtual(func):
# func_type = None
# def wrapper(this, *args):
# if wrapper._functype is None:
# x = wrapper._virtual_idx
# anno = list(func.__annotations__.values())
# wrapper._functype = WINFUNCTYPE(anno[-1], *anno[:-1])
# vf_table = ct.cast( c_void_p( ct.cast(this, POINTER(c_void_p))[0] ), POINTER(c_void_p))
# real_func = wrapper._functype( vf_table[wrapper._virtual_idx] )
# import code
# code.interact(local=dict(globals(), **locals()))
# return real_func(this, *args)
# wrapper._func = func
# wrapper._functype = None
# wrapper._virtual_idx = -1
# return wrapper