diff --git a/ctypes_generation/com_parser.py b/ctypes_generation/com_parser.py index e28da2d..83639cf 100644 --- a/ctypes_generation/com_parser.py +++ b/ctypes_generation/com_parser.py @@ -77,7 +77,7 @@ class WinComParser(Parser): args.append(self.parse_argument()) #print("Pass <{0}>".format(p)) self.next_token() - self.assert_token_type(ColonToken) + self.assert_token_type(SemiColonToken) return ret_type.value, method_name.value, args def parse(self): @@ -113,7 +113,7 @@ class WinComParser(Parser): self.next_token() self.assert_token_type(StarToken) typedefptr = self.assert_token_type(NameToken).value - self.assert_token_type(ColonToken) + self.assert_token_type(SemiColonToken) res.typedefptr = typedefptr return res diff --git a/ctypes_generation/definitions/com/ICallFrameWalker.txt b/ctypes_generation/definitions/com/ICallFrameWalker.txt index e2666bb..bcb4a21 100644 --- a/ctypes_generation/definitions/com/ICallFrameWalker.txt +++ b/ctypes_generation/definitions/com/ICallFrameWalker.txt @@ -1,25 +1,25 @@ typedef struct ICallFrameWalkerVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( - ICallFrameWalker * This, - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( - ICallFrameWalker * This); - - ULONG ( STDMETHODCALLTYPE *Release )( - ICallFrameWalker * This); - - HRESULT ( STDMETHODCALLTYPE *OnWalkInterface )( - ICallFrameWalker * This, - /* [in] */ REFIID iid, - /* [in] */ PVOID *ppvInterface, - /* [in] */ BOOL fIn, - /* [in] */ BOOL fOut); - - END_INTERFACE - } ICallFrameWalkerVtbl; \ No newline at end of file +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICallFrameWalker * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICallFrameWalker * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ICallFrameWalker * This); + + HRESULT ( STDMETHODCALLTYPE *OnWalkInterface )( + ICallFrameWalker * This, + /* [in] */ REFIID iid, + /* [in] */ PVOID *ppvInterface, + /* [in] */ BOOL fIn, + /* [in] */ BOOL fOut); + + END_INTERFACE +} ICallFrameWalkerVtbl; \ No newline at end of file diff --git a/ctypes_generation/definitions/com/template.py b/ctypes_generation/definitions/com/template.py index 9152744..b07145e 100644 --- a/ctypes_generation/definitions/com/template.py +++ b/ctypes_generation/definitions/com/template.py @@ -13,3 +13,13 @@ class COMInterface(ctypes.c_void_p): return functools.partial(self._functions_[name], self) return super(COMInterface, self).__getattribute__(name) + def __repr__(self): + description = "" if not self.value else "" + return "<{0}{1} at {2:#x}>".format(type(self).__name__, description, id(self)) + + # Simplified API for QueryInterface for interface embeding there IID + def query(self, interfacetype): + interface = interfacetype() + self.QueryInterface(interface.IID, interface) + return interface + diff --git a/ctypes_generation/definitions/defines/windef.txt b/ctypes_generation/definitions/defines/windef.txt index 31543ca..c011b07 100644 --- a/ctypes_generation/definitions/defines/windef.txt +++ b/ctypes_generation/definitions/defines/windef.txt @@ -796,6 +796,7 @@ #define PERSIST_E_SIZEINDEFINITE (0x800B000AL) #define PERSIST_E_NOTSELFSIZING (0x800B000BL) #define TRUST_E_NOSIGNATURE (0x800B0100L) +#define TRUST_E_BAD_DIGEST (0x80096010L) #define CERT_E_EXPIRED (0x800B0101L) #define CERT_E_VALIDITYPERIODNESTING (0x800B0102L) #define CERT_E_PURPOSE (0x800B0106L) diff --git a/ctypes_generation/definitions/functions/winfunc.txt b/ctypes_generation/definitions/functions/winfunc.txt index 0c1de77..f9c2c4e 100644 --- a/ctypes_generation/definitions/functions/winfunc.txt +++ b/ctypes_generation/definitions/functions/winfunc.txt @@ -1677,3 +1677,27 @@ NTSTATUS WINAPI ApiSetResolveToHost ( _Out_ PBOOLEAN Resolved, _Out_ PUNICODE_STRING HostBinary ); + + +VOID WINAPI Sleep( + _In_ DWORD dwMilliseconds +); + +DWORD WINAPI SleepEx( + _In_ DWORD dwMilliseconds, + _In_ BOOL bAlertable +); + +BOOL WINAPI GetProcessMitigationPolicy( + _In_ HANDLE hProcess, + _In_ PROCESS_MITIGATION_POLICY MitigationPolicy, + _Out_ PVOID lpBuffer, + _In_ SIZE_T dwLength +); + + +BOOL WINAPI SetProcessMitigationPolicy( + _In_ PROCESS_MITIGATION_POLICY MitigationPolicy, + _In_ PVOID lpBuffer, + _In_ SIZE_T dwLength +); diff --git a/ctypes_generation/definitions/simple_types.txt b/ctypes_generation/definitions/simple_types.txt index aea14ab..9c683f0 100644 --- a/ctypes_generation/definitions/simple_types.txt +++ b/ctypes_generation/definitions/simple_types.txt @@ -30,6 +30,7 @@ OLECHAR = c_wchar POLECHAR = c_wchar_p PUCHAR = POINTER(UCHAR) double = c_double +DATE = double PSID = PVOID ULONGLONG = c_ulonglong LONGLONG = c_longlong diff --git a/ctypes_generation/definitions/structures/com.txt b/ctypes_generation/definitions/structures/com.txt index 703cd4c..8a07ec8 100644 --- a/ctypes_generation/definitions/structures/com.txt +++ b/ctypes_generation/definitions/structures/com.txt @@ -76,4 +76,10 @@ typedef enum tagMSHLFLAGS { MSHLFLAGS_TABLESTRONG = 1, MSHLFLAGS_TABLEWEAK = 2, MSHLFLAGS_NOPING = 4 -} MSHLFLAGS; \ No newline at end of file +} MSHLFLAGS; + +typedef enum tagCALLFRAME_WALK { + CALLFRAME_WALK_IN = 1, + CALLFRAME_WALK_INOUT = 2, + CALLFRAME_WALK_OUT = 4 +} CALLFRAME_WALK; \ No newline at end of file diff --git a/ctypes_generation/definitions/structures/winstruct.txt b/ctypes_generation/definitions/structures/winstruct.txt index 1d6433b..08c8407 100644 --- a/ctypes_generation/definitions/structures/winstruct.txt +++ b/ctypes_generation/definitions/structures/winstruct.txt @@ -3039,7 +3039,7 @@ typedef struct _SYSTEMTIME { WORD wMinute; WORD wSecond; WORD wMilliseconds; -} SYSTEMTIME, *PSYSTEMTIME; +} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; typedef struct _CERT_EXTENSIONS { diff --git a/ctypes_generation/func_parser.py b/ctypes_generation/func_parser.py index a692c9b..fae8bf3 100644 --- a/ctypes_generation/func_parser.py +++ b/ctypes_generation/func_parser.py @@ -100,7 +100,7 @@ class WinFuncParser(Parser): params.append(self.parse_func_arg(has_winapi)) self.assert_token_type(CloseParenthesisToken) - self.assert_token_type(ColonToken) + self.assert_token_type(SemiColonToken) return WinFunc(return_type, func_name, params) def parse(self): diff --git a/ctypes_generation/simpleparser.py b/ctypes_generation/simpleparser.py index 7139032..da4cf35 100644 --- a/ctypes_generation/simpleparser.py +++ b/ctypes_generation/simpleparser.py @@ -24,6 +24,10 @@ class NameToken(Token): pass class ColonToken(NoValueToken): + value = ":" + pass + +class SemiColonToken(NoValueToken): value = ";" pass @@ -73,8 +77,9 @@ class Lexer(object): keywords = ["typedef", "struct", "enum", "union", "const"] token_chr = {"*" : StarToken, "[" : OpenSquareBracketToken, "]" : CloseSquareBracketToken, - "{" : OpenBracketToken, "}" : CloseBracketToken, ";" : ColonToken, - "," : CommaToken, "(" : OpenParenthesisToken, ")" : CloseParenthesisToken, "#" : SharpToken, "=" : EqualToken} + "{" : OpenBracketToken, "}" : CloseBracketToken, ";" : SemiColonToken, + "," : CommaToken, "(" : OpenParenthesisToken, ")" : CloseParenthesisToken, "#" : SharpToken, "=" : EqualToken, + ":": ColonToken} def __init__(self, code, newlinetoken=False): self.code = code diff --git a/ctypes_generation/struct_parser.py b/ctypes_generation/struct_parser.py index 4f7d589..3b2cb8e 100644 --- a/ctypes_generation/struct_parser.py +++ b/ctypes_generation/struct_parser.py @@ -1,18 +1,27 @@ import dummy_wintypes import itertools -from winstruct import WinStruct, WinUnion, WinStructType, Ptr, WinEnum +from winstruct import WinStruct, WinUnion, WinStructType, Ptr, WinEnum, BitFieldValue from simpleparser import * + + class WinStructParser(Parser): def __init__(self, *args, **kwargs): super(WinStructParser, self).__init__(*args, **kwargs) self.pack = None - def parse_array(self, ): - self.assert_token_type(OpenSquareBracketToken) - number = self.assert_token_type(NameToken).value - self.assert_token_type(CloseSquareBracketToken) - return number + def parse_array_or_bitfield(self): + if type(self.peek()) == OpenSquareBracketToken: + # Array + self.assert_token_type(OpenSquareBracketToken) + number = self.assert_token_type(NameToken).value + self.assert_token_type(CloseSquareBracketToken) + return number + # Bitfield + self.assert_token_type(ColonToken) + nb_bits = self.promote_to_int(self.next_token()) + return BitFieldValue(nb_bits) + def parse_def(self): if self.peek() == KeywordToken("struct"): @@ -26,16 +35,16 @@ class WinStructParser(Parser): def_name = self.assert_token_type(NameToken) - if type(self.peek()) == ColonToken: + if type(self.peek()) == SemiColonToken: self.next_token() return (def_type, def_name, 1) - number_rep = self.parse_array() - self.assert_token_type(ColonToken) + number_rep = self.parse_array_or_bitfield() + self.assert_token_type(SemiColonToken) return (def_type, def_name, number_rep) def parse_typedef(self, struct): - if type(self.peek()) == ColonToken: # Just a ; no typedef + if type(self.peek()) == SemiColonToken: # Just a ; no typedef self.next_token() return sep = CommaToken() @@ -50,7 +59,7 @@ class WinStructParser(Parser): name = self.assert_token_type(NameToken) add_to_typedef(name.value) sep = self.next_token() - self.assert_token_type(ColonToken, sep) + self.assert_token_type(SemiColonToken, sep) def parse_enum(self, is_typedef): """Handle enum typedef with no value assignement and 1 typedef after""" @@ -87,7 +96,7 @@ class WinStructParser(Parser): self.parse_typedef(res_enum) #other_name = self.assert_token_type(NameToken).value #res_enum.add_typedef(other_name) - #self.assert_token_type(ColonToken) + #self.assert_token_type(SemiColonToken) return res_enum @@ -126,7 +135,7 @@ class WinStructParser(Parser): if is_typedef: self.parse_typedef(result) else: - self.assert_token_type(ColonToken) + self.assert_token_type(SemiColonToken) return result def parse(self): diff --git a/ctypes_generation/winstruct.py b/ctypes_generation/winstruct.py index cac8bf7..e6f1a22 100644 --- a/ctypes_generation/winstruct.py +++ b/ctypes_generation/winstruct.py @@ -4,6 +4,15 @@ import collections #Ptr = collections.namedtuple('Ptr', ['']) + +class BitFieldValue(object): + def __init__(self, nb_bits): + assert isinstance(nb_bits, int) + self.nb_bits = nb_bits + + def __int__(self): + return self.nb_bits + class WinStructType(object): def __init__(self, name): self.name = name @@ -70,7 +79,9 @@ class WinStruct(object): res += ["{0}._pack_ = ".format(self.pack)] res += ["{0}._fields_ = [".format(self.name)] for (ftype, name, nb_rep) in self.fields: - if nb_rep == 1: + if isinstance(nb_rep, BitFieldValue): + res += [' ("{0}", {1}, {2}),'.format(name, ftype.generate_ctypes(), nb_rep.nb_bits)] + elif nb_rep == 1: res+= [' ("{0}", {1}),'.format(name, ftype.generate_ctypes())] else: res+= [' ("{0}", {1} * {2}),'.format(name, ftype.generate_ctypes(), nb_rep)] @@ -96,7 +107,10 @@ class WinStruct(object): for (ftype, name, nb_rep) in self.fields: - if nb_rep == 1: + if isinstance(nb_rep, BitFieldValue): + # Should I check 'ftype' somewhere when we have a bitfield ? + res+= ' ("{0}", {1}, {2}),\n'.format(name, ftype.generate_ctypes(), nb_rep.nb_bits) + elif nb_rep == 1: res+= ' ("{0}", {1}),\n'.format(name, ftype.generate_ctypes()) else: res+= ' ("{0}", {1} * {2}),\n'.format(name, ftype.generate_ctypes(), nb_rep)