1 #Copyright (c) 2009 Vincent Povirk
3 #Permission is hereby granted, free of charge, to any person
4 #obtaining a copy of this software and associated documentation
5 #files (the "Software"), to deal in the Software without
6 #restriction, including without limitation the rights to use,
7 #copy, modify, merge, publish, distribute, sublicense, and/or sell
8 #copies of the Software, and to permit persons to whom the
9 #Software is furnished to do so, subject to the following
12 #The above copyright notice and this permission notice shall be
13 #included in all copies or substantial portions of the Software.
15 #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 #EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 #OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 #NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 #HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 #WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 #FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 #OTHER DEALINGS IN THE SOFTWARE.
26 from ctypes
import POINTER
, windll
, c_void_p
, Structure
, byref
, cast
, create_string_buffer
, c_uint32
, Union
, addressof
27 from winlitecfg
import get_aw_symbols
28 from windef
import HRESULT
, DWORD
, LPCWSTR
, LPVOID
, GUID
, LPCOLESTR
, ULONG
, PULONG
, LPOLESTR
, ULARGE_INTEGER
, FILETIME
, CLSID
, S_OK
, REFCLSID
, LARGE_INTEGER
, UINT
, USHORT
, REFIID
, LPCTSTR
, FMTID
, REFFMTID
, WORD
, LPSTR
, LONG
29 from winliteutils
import get_symbols
30 from winlitecom
import IUnknown
34 def from_param(cls
, arg
):
46 class ISequentialStream(IUnknown
):
47 com_methods
= [('Read', HRESULT
, LPVOID
, ULONG
, PULONG
),
49 ('Write', HRESULT
, LPVOID
, ULONG
, PULONG
),
53 iid
= GUID("0c733a30-2a1c-11ce-ade5-00aa0044773d")
55 def read(self
, size
=None):
57 result
= create_string_buffer(size
)
59 self
.Read(cast(result
, LPVOID
), size
, byref(bytesread
))
60 return result
.raw
[0:bytesread
.value
]
63 result
= create_string_buffer(1024)
64 bytesread
= ULONG(1024)
65 while bytesread
.value
== 1024:
66 self
.Read(cast(result
, LPVOID
), 1024, byref(bytesread
))
67 block
= result
.raw
[0:bytesread
.value
]
69 return _bytes().join(blocks
)
76 class STATSTG(Structure
):
77 _fields_
= [('pwcsName', LPOLESTR
),
79 ('cbSize', ULARGE_INTEGER
),
84 ('grfLocksSupported', DWORD
),
86 ('grfStateBits', DWORD
),
94 _ole32
.CoTaskMemFree(cast(self
.pwcsName
, c_void_p
))
95 self
.owns_name
= False
101 class IStream(ISequentialStream
):
102 iid
= GUID("0000000c-0000-0000-C000-000000000046")
104 def stat(self
, mode
):
106 self
.Stat(byref(result
), mode
)
107 result
.owns_name
= True
110 def seek(self
, offset
, origin
):
111 result
= ULARGE_INTEGER()
112 self
.Seek(offset
, origin
, byref(result
))
115 IStream
.set_methods([('Seek', HRESULT
, LARGE_INTEGER
, DWORD
, POINTER(ULARGE_INTEGER
)),
117 ('SetSize', HRESULT
, ULARGE_INTEGER
),
118 ('CopyTo', HRESULT
, IStream
, ULARGE_INTEGER
, ULARGE_INTEGER
, ULARGE_INTEGER
),
119 #RemoteCopyTo = CopyTo
120 ('Commit', HRESULT
, DWORD
),
122 ('LockRegion', HRESULT
, ULARGE_INTEGER
, ULARGE_INTEGER
, DWORD
),
123 ('UnlockRegion', HRESULT
, ULARGE_INTEGER
, ULARGE_INTEGER
, DWORD
),
124 ('Stat', HRESULT
, POINTER(STATSTG
), DWORD
),
125 ('Clone', HRESULT
, IStream
.outparam
),
130 class IEnumSTATSTG(IUnknown
):
131 iid
= GUID("0000000d-0000-0000-C000-000000000046")
138 numreturned
= ULONG()
139 if self
.Next(1, byref(result
), byref(numreturned
)) == S_OK
and numreturned
.value
== 1:
140 result
.owns_name
= True
148 IEnumSTATSTG
.set_methods([('Next', HRESULT
, ULONG
, POINTER(STATSTG
), POINTER(ULONG
)),
149 ('Skip', HRESULT
, ULONG
),
151 ('Clone', HRESULT
, IEnumSTATSTG
.outparam
),
158 class IStorage(IUnknown
):
159 iid
= GUID("0000000b-0000-0000-C000-000000000046")
162 result
= IEnumSTATSTG
.outparam()
163 self
.EnumElements(0, None, 0, result
)
164 return iter(result
.get())
166 def stat(self
, mode
):
168 self
.Stat(byref(result
), mode
)
169 result
.owns_name
= True
172 def open_storage(self
, name
, mode
):
173 result
= IStorage
.outparam()
174 self
.OpenStorage(name
, None, mode
, None, 0, result
)
177 def open_stream(self
, name
, mode
):
178 result
= IStream
.outparam()
179 self
.OpenStream(name
, None, mode
, 0, result
)
182 def create_stream(self
, name
, mode
):
183 result
= IStream
.outparam()
184 self
.CreateStream(name
, mode
, 0, 0, result
)
187 IStorage
.set_methods([('CreateStream', HRESULT
, LPCOLESTR
, DWORD
, DWORD
, DWORD
, IStream
.outparam
),
188 ('OpenStream', HRESULT
, LPCOLESTR
, LPVOID
, DWORD
, DWORD
, IStream
.outparam
),
189 #RemoteOpenStream = OpenStream
190 ('CreateStorage', HRESULT
, LPCOLESTR
, DWORD
, DWORD
, DWORD
, IStorage
.outparam
),
191 ('OpenStorage', HRESULT
, LPCOLESTR
, IStorage
, DWORD
, SNB
, DWORD
, IStorage
.outparam
),
192 ('CopyTo', HRESULT
, DWORD
, POINTER(GUID
), SNB
, IStorage
),
193 ('MoveElementTo', HRESULT
, LPCOLESTR
, IStorage
, LPCOLESTR
, DWORD
),
194 ('Commit', HRESULT
, DWORD
),
196 ('EnumElements', HRESULT
, DWORD
, LPVOID
, DWORD
, IEnumSTATSTG
.outparam
),
197 #RemoteEnumElements = EnumElements
198 ('DestroyElement', HRESULT
, LPCOLESTR
),
199 ('RenameElement', HRESULT
, LPCOLESTR
, LPCOLESTR
),
200 ('SetElementTimes', HRESULT
, LPCOLESTR
, POINTER(FILETIME
), POINTER(FILETIME
), POINTER(FILETIME
)),
201 ('SetClass', HRESULT
, REFCLSID
),
202 ('SetStateBits', HRESULT
, DWORD
, DWORD
),
203 ('Stat', HRESULT
, POINTER(STATSTG
), DWORD
),
207 STGM_FAILIFTHERE
= 0x0
211 STGM_SHARE_EXCLUSIVE
= 0x10
212 STGM_SHARE_DENY_WRITE
= 0x20
213 STGM_SHARE_DENY_READ
= 0x30
214 STGM_SHARE_DENY_NONE
= 0x40
216 STGM_TRANSACTED
= 0x10000
217 STGM_CONVERT
= 0x20000
218 STGM_PRIORITY
= 0x40000
219 STGM_NOSCRATCH
= 0x100000
220 STGM_NOSNAPSHOT
= 0x200000
221 STGM_DIRECT_SWMR
= 0x400000
222 STGM_DELETEONRELEASE
= 0x4000000
223 STGM_SIMPLE
= 0x8000000
233 PRSPEC_INVALID
= 0xffffffff
237 class PROPSPEC(Structure
):
239 _fields_
= [('propid', PROPID
),
240 ('lpwstr', LPOLESTR
),
242 _fields_
= [('ulKind', ULONG
),
252 def _get_propvar_i4(value
):
253 return cast(addressof(value
), POINTER(LONG
)).contents
.value
255 def _get_propvar_lpstr(value
):
256 return cast(addressof(value
), POINTER(LPSTR
)).contents
.value
258 def _get_propvar_filetime(value
):
259 return cast(addressof(value
), POINTER(FILETIME
)).contents
262 VT_I4
: _get_propvar_i4
,
263 VT_LPSTR
: _get_propvar_lpstr
,
264 VT_FILETIME
: _get_propvar_filetime
,
267 class _PROPVAR_VALUE(Structure
):
268 _fields_
= [('cElems', ULONG
),
272 class PROPVARIANT(Structure
):
273 _fields_
= [('vt', VARTYPE
),
274 ('wReserved1', WORD
),
275 ('wReserved2', WORD
),
276 ('wReserved3', WORD
),
277 ('value', _PROPVAR_VALUE
), # to avoid the huge union, cast a pointer to this field
282 getter
= _propvar_getters
[self
.vt
]
286 return getter(self
.value
)
288 class STATPROPSTG(Structure
):
289 _fields_
= [('lpwstrName', LPOLESTR
),
294 class IEnumSTATPROPSTG(IUnknown
):
295 iid
= GUID("00000139-0000-0000-C000-000000000046")
301 result
= STATPROPSTG()
303 if self
.Next(1, byref(result
), byref(numfetched
)) == S_OK
:
308 IEnumSTATPROPSTG
.set_methods([('Next', HRESULT
, ULONG
, POINTER(STATPROPSTG
), POINTER(ULONG
)),
310 ('Skip', HRESULT
, ULONG
),
312 ('Clone', HRESULT
, IEnumSTATPROPSTG
.outparam
),
315 class STATPROPSETSTG(Structure
):
316 _fields_
= [('fmtid', FMTID
),
322 ('dwOSVersion', DWORD
),
325 class IPropertyStorage(IUnknown
):
326 iid
= GUID("00000138-0000-0000-C000-000000000046")
329 result
= IEnumSTATPROPSTG
.outparam()
333 def read_id(self
, propid
):
335 spec
.ulKind
= PRSPEC_PROPID
336 spec
.u
.propid
= propid
337 result
= PROPVARIANT()
338 self
.ReadMultiple(1, byref(spec
), byref(result
))
341 com_methods
= [('ReadMultiple', HRESULT
, ULONG
, POINTER(PROPSPEC
), POINTER(PROPVARIANT
)),
342 ('WriteMultiple', HRESULT
, ULONG
, POINTER(PROPSPEC
), POINTER(PROPVARIANT
), PROPID
),
343 ('DeleteMultiple', HRESULT
, ULONG
, POINTER(PROPSPEC
)),
344 ('ReadPropertyNames', HRESULT
, ULONG
, POINTER(PROPID
), POINTER(LPOLESTR
)),
345 ('WritePropertyNames', HRESULT
, ULONG
, POINTER(PROPID
), POINTER(LPOLESTR
)),
346 ('DeletePropertyNames', HRESULT
, ULONG
, POINTER(PROPID
)),
347 ('Commit', HRESULT
, DWORD
),
349 ('Enum', HRESULT
, IEnumSTATPROPSTG
.outparam
),
350 ('SetTimes', HRESULT
, POINTER(FILETIME
), POINTER(FILETIME
), POINTER(FILETIME
)),
351 ('SetClass', HRESULT
, REFCLSID
),
352 ('Stat', HRESULT
, POINTER(STATPROPSETSTG
)),
355 class IEnumSTATPROPSETSTG(IUnknown
):
356 iid
= GUID("0000013B-0000-0000-C000-000000000046")
362 result
= STATPROPSETSTG()
364 if self
.Next(1, byref(result
), byref(numfetched
)) == S_OK
:
371 IEnumSTATPROPSETSTG
.set_methods([('Next', HRESULT
, ULONG
, POINTER(STATPROPSETSTG
), POINTER(ULONG
)),
373 ('Skip', HRESULT
, ULONG
),
375 ('Clone', HRESULT
, IEnumSTATPROPSETSTG
.outparam
),
378 class IPropertySetStorage(IUnknown
):
379 iid
= GUID("0000013A-0000-0000-C000-000000000046")
382 result
= IEnumSTATPROPSETSTG
.outparam()
386 com_methods
= [('Create', HRESULT
, REFFMTID
, POINTER(CLSID
), DWORD
, DWORD
, IPropertyStorage
.outparam
),
387 ('Open', HRESULT
, REFFMTID
, DWORD
, IPropertyStorage
.outparam
),
388 ('Delete', HRESULT
, REFFMTID
),
389 ('Enum', HRESULT
, IEnumSTATPROPSETSTG
.outparam
),
392 class STGOPTIONS(Structure
):
393 _fields_
= [('usVersion', USHORT
),
394 ('reserved', USHORT
),
395 ('ulSectorSize', ULONG
),
396 ('pwcsTemplateFile', LPCWSTR
),
399 _ole32
= windll
.ole32
401 get_symbols(globals(), _ole32
, ['ReadClassStg', 'StgCreateStorageEx', 'StgIsStorageFile', 'StgOpenStorage'])
403 ReadClassStg
.restype
= HRESULT
404 ReadClassStg
.argtypes
= [IStorage
, POINTER(CLSID
)]
406 StgCreateStorageEx
.restype
= HRESULT
407 StgCreateStorageEx
.argtypes
= [LPCWSTR
, DWORD
, STGFMT
, DWORD
, POINTER(STGOPTIONS
), LPVOID
, REFIID
, POINTER(LPVOID
)]
409 StgIsStorageFile
.restype
= HRESULT
410 StgIsStorageFile
.argtypes
= [LPCWSTR
]
412 StgOpenStorage
.restype
= HRESULT
413 StgOpenStorage
.argtypes
= [LPCWSTR
, IStorage
, DWORD
, SNB
, DWORD
, IStorage
.outparam
]
415 def is_storage_file(filename
):
417 return StgIsStorageFile(filename
) == S_OK
421 def open_storage(filename
, mode
):
422 result
= IStorage
.outparam()
423 StgOpenStorage(filename
, None, mode
, None, 0, result
)
426 _shlwapi
= windll
.shlwapi
428 get_aw_symbols(globals(), _shlwapi
, ['SHCreateStreamOnFile'])
430 SHCreateStreamOnFile
.argtypes
= [LPCTSTR
, DWORD
, IStream
.outparam
]
431 SHCreateStreamOnFile
.restype
= HRESULT
433 def file_stream(filename
, mode
):
434 result
= IStream
.outparam()
435 SHCreateStreamOnFile(filename
, mode
, result
)