diff --git a/ctypes_generation/extended_structs/_GUID.py b/ctypes_generation/extended_structs/_GUID.py new file mode 100644 index 0000000..ac99d00 --- /dev/null +++ b/ctypes_generation/extended_structs/_GUID.py @@ -0,0 +1,58 @@ +INITIAL_GUID = _GUID +class _GUID(INITIAL_GUID): + def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None): + data_tuple = (Data1, Data2, Data3, Data4) + self.name = name + self.strid = strid + if all(data is None for data in data_tuple): + return super(_GUID, self).__init__() + if any(data is None for data in data_tuple): + raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None") + super(_GUID, self).__init__(Data1, Data2, Data3, Data4) + + def __repr__(self): + notpresent = object() + # Handle IID created without '__init__' (like ctypes-ptr deref) + if getattr(self, "strid", notpresent) is notpresent: + self.strid = self.to_string() + if self.strid is None: + return super(_GUID, self).__repr__() + + if getattr(self, "name", notpresent) is notpresent: + self.name = None + if self.name is None: + return ''.format(self.strid.upper()) + return ''.format(self.strid.upper(), self.name) + + def to_string(self): + data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6)) + data4_str = data4_format.format(*self.Data4) + return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str + + def update_strid(self): + new_strid = self.to_string() + self.strid = new_strid + + @classmethod + def from_string(cls, iid): + part_iid = iid.split("-") + datas = [int(x, 16) for x in part_iid[:3]] + datas.append(int(part_iid[3][:2], 16)) + datas.append(int(part_iid[3][2:], 16)) + for i in range(6): + datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16)) + return cls.from_raw(*datas, strid=iid) + + @classmethod + def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs): + return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs) + + def __eq__(self, other): + if not isinstance(other, (_GUID, INITIAL_GUID)): + return NotImplemented + return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:]) + +LPGUID = POINTER(_GUID) +REFGUID = POINTER(_GUID) +REFCLSID = POINTER(_GUID) +REFIID = POINTER(_GUID) \ No newline at end of file diff --git a/ctypes_generation/generate.py b/ctypes_generation/generate.py index 9781ce8..75f7418 100644 --- a/ctypes_generation/generate.py +++ b/ctypes_generation/generate.py @@ -258,6 +258,8 @@ class InitialDefGenerator(CtypesGenerator): with open(target_file, "w") as f: f.writelines(all_lines) +EXTENDED_STRUCT = ["_GUID"] # TODO: check auto the dir + class StructGenerator(CtypesGenerator): PARSER = struct_parser.WinStructParser IMPORT_HEADER = dedent (""" @@ -329,7 +331,16 @@ class StructGenerator(CtypesGenerator): HEADER += self.TYPES_HEADER structs, enums = self.data - ctypes_lines = [self.common_header, HEADER] + [d.generate_ctypes() for l in (enums, structs) for d in l] + ctypes_lines = [self.common_header, HEADER] + for definition in [d for l in (enums, structs) for d in l]: + ctypes_lines.append(definition.generate_ctypes()) + if definition.name in EXTENDED_STRUCT: + print("Including extended definition for <{0}>".format(definition.name)) + extended_struct_filename = from_here(os.path.join("extended_structs", "{0}.py".format(definition.name))) + with open(extended_struct_filename) as f: + ctypes_lines.append(f.read()) + ctypes_lines.append(definition.generate_typedef_ctypes() + "\n") + ctypes_code = "\n".join(ctypes_lines) with open(self.outfilename, "w") as f: f.write(ctypes_code) @@ -501,68 +512,8 @@ class InitialCOMGenerator(CtypesGenerator): """) HEADER = dedent(""" - _GUID = IID - class IID(IID): - def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None): - data_tuple = (Data1, Data2, Data3, Data4) - self.name = name - self.strid = strid - if all(data is None for data in data_tuple): - return super(IID, self).__init__() - if any(data is None for data in data_tuple): - raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None") - super(IID, self).__init__(Data1, Data2, Data3, Data4) - - def __repr__(self): - notpresent = object() - # Handle IID created without '__init__' (like ctypes-ptr deref) - if getattr(self, "strid", notpresent) is notpresent: - self.strid = self.to_string() - if self.strid is None: - return super(IID, self).__repr__() - - if getattr(self, "name", notpresent) is notpresent: - self.name = None - if self.name is None: - return ''.format(self.strid.upper()) - return ''.format(self.strid.upper(), self.name) - - def to_string(self): - data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6)) - data4_str = data4_format.format(*self.Data4) - return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str - - def update_strid(self): - new_strid = self.to_string() - self.strid = new_strid - - @classmethod - def from_string(cls, iid): - part_iid = iid.split("-") - datas = [int(x, 16) for x in part_iid[:3]] - datas.append(int(part_iid[3][:2], 16)) - datas.append(int(part_iid[3][2:], 16)) - for i in range(6): - datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16)) - return cls.from_raw(*datas, strid=iid) - - @classmethod - def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs): - return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs) - - def __eq__(self, other): - if not isinstance(other, (IID, _GUID)): - return NotImplemented - return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:]) - generate_IID = IID.from_raw - GUID = IID - LPGUID = POINTER(GUID) - REFGUID = POINTER(GUID) - REFCLSID = POINTER(GUID) - REFIID = POINTER(GUID) - class COMInterface(ctypes.c_void_p): _functions_ = { } diff --git a/windows/generated_def/interfaces.py b/windows/generated_def/interfaces.py index 6113f73..f1f1a5a 100644 --- a/windows/generated_def/interfaces.py +++ b/windows/generated_def/interfaces.py @@ -8,68 +8,8 @@ from windef import * -_GUID = IID -class IID(IID): - def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None): - data_tuple = (Data1, Data2, Data3, Data4) - self.name = name - self.strid = strid - if all(data is None for data in data_tuple): - return super(IID, self).__init__() - if any(data is None for data in data_tuple): - raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None") - super(IID, self).__init__(Data1, Data2, Data3, Data4) - - def __repr__(self): - notpresent = object() - # Handle IID created without '__init__' (like ctypes-ptr deref) - if getattr(self, "strid", notpresent) is notpresent: - self.strid = self.to_string() - if self.strid is None: - return super(IID, self).__repr__() - - if getattr(self, "name", notpresent) is notpresent: - self.name = None - if self.name is None: - return ''.format(self.strid.upper()) - return ''.format(self.strid.upper(), self.name) - - def to_string(self): - data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6)) - data4_str = data4_format.format(*self.Data4) - return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str - - def update_strid(self): - new_strid = self.to_string() - self.strid = new_strid - - @classmethod - def from_string(cls, iid): - part_iid = iid.split("-") - datas = [int(x, 16) for x in part_iid[:3]] - datas.append(int(part_iid[3][:2], 16)) - datas.append(int(part_iid[3][2:], 16)) - for i in range(6): - datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16)) - return cls.from_raw(*datas, strid=iid) - - @classmethod - def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs): - return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs) - - def __eq__(self, other): - if not isinstance(other, (IID, _GUID)): - return NotImplemented - return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:]) - generate_IID = IID.from_raw -GUID = IID -LPGUID = POINTER(GUID) -REFGUID = POINTER(GUID) -REFCLSID = POINTER(GUID) -REFIID = POINTER(GUID) - class COMInterface(ctypes.c_void_p): _functions_ = { } diff --git a/windows/generated_def/winstructs.py b/windows/generated_def/winstructs.py index f8d2980..c1f1c6e 100644 --- a/windows/generated_def/winstructs.py +++ b/windows/generated_def/winstructs.py @@ -2464,6 +2464,69 @@ REFCLSID = POINTER(_GUID) GUID = _GUID REFIID = POINTER(_GUID) +INITIAL_GUID = _GUID +class _GUID(INITIAL_GUID): + def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None): + data_tuple = (Data1, Data2, Data3, Data4) + self.name = name + self.strid = strid + if all(data is None for data in data_tuple): + return super(_GUID, self).__init__() + if any(data is None for data in data_tuple): + raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None") + super(_GUID, self).__init__(Data1, Data2, Data3, Data4) + + def __repr__(self): + notpresent = object() + # Handle IID created without '__init__' (like ctypes-ptr deref) + if getattr(self, "strid", notpresent) is notpresent: + self.strid = self.to_string() + if self.strid is None: + return super(_GUID, self).__repr__() + + if getattr(self, "name", notpresent) is notpresent: + self.name = None + if self.name is None: + return ''.format(self.strid.upper()) + return ''.format(self.strid.upper(), self.name) + + def to_string(self): + data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6)) + data4_str = data4_format.format(*self.Data4) + return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str + + def update_strid(self): + new_strid = self.to_string() + self.strid = new_strid + + @classmethod + def from_string(cls, iid): + part_iid = iid.split("-") + datas = [int(x, 16) for x in part_iid[:3]] + datas.append(int(part_iid[3][:2], 16)) + datas.append(int(part_iid[3][2:], 16)) + for i in range(6): + datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16)) + return cls.from_raw(*datas, strid=iid) + + @classmethod + def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs): + return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs) + + def __eq__(self, other): + if not isinstance(other, (_GUID, INITIAL_GUID)): + return NotImplemented + return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:]) + +LPGUID = POINTER(_GUID) +REFGUID = POINTER(_GUID) +REFCLSID = POINTER(_GUID) +REFIID = POINTER(_GUID) +IID = _GUID +REFCLSID = POINTER(_GUID) +GUID = _GUID +REFIID = POINTER(_GUID) + class _TMP_signscale(Structure): _fields_ = [ ("scale", BYTE),