| Home | Trees | Indices | Help |
|
|---|
|
|
1 # Copyright (c) 2009, Mario Vilas
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
6 #
7 # * Redistributions of source code must retain the above copyright notice,
8 # this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above copyright
10 # notice,this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
12 # * Neither the name of the copyright holder nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 # POSSIBILITY OF SUCH DAMAGE.
27
28 """
29 Debugging API wrappers in ctypes.
30
31 @see: U{http://apps.sourceforge.net/trac/winappdbg/wiki/Win32APIWrappers}
32 """
33
34 __revision__ = "$Id: advapi32.py 492 2009-12-01 03:18:32Z qvasimodo $"
35
36 from defines import *
37 from kernel32 import *
38
39 #--- Constants ----------------------------------------------------------------
40
41 # Privilege constants
42 SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege"
43 SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege"
44 SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege"
45 SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege"
46 SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege"
47 SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege"
48 SE_TCB_NAME = "SeTcbPrivilege"
49 SE_SECURITY_NAME = "SeSecurityPrivilege"
50 SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege"
51 SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege"
52 SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege"
53 SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege"
54 SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege"
55 SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege"
56 SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege"
57 SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege"
58 SE_BACKUP_NAME = "SeBackupPrivilege"
59 SE_RESTORE_NAME = "SeRestorePrivilege"
60 SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
61 SE_DEBUG_NAME = "SeDebugPrivilege"
62 SE_AUDIT_NAME = "SeAuditPrivilege"
63 SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege"
64 SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege"
65 SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege"
66 SE_UNDOCK_NAME = "SeUndockPrivilege"
67 SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege"
68 SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege"
69 SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege"
70 SE_IMPERSONATE_NAME = "SeImpersonatePrivilege"
71 SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege"
72
73 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
74 SE_PRIVILEGE_ENABLED = 0x00000002
75 SE_PRIVILEGE_REMOVED = 0x00000004
76 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000
77
78 TOKEN_ADJUST_PRIVILEGES = 0x00000020
79
80 LOGON_WITH_PROFILE = 0x00000001
81 LOGON_NETCREDENTIALS_ONLY = 0x00000002
82
83 #--- TOKEN_PRIVILEGE structure ------------------------------------------------
84
85 # typedef struct _LUID {
86 # DWORD LowPart;
87 # LONG HighPart;
88 # } LUID,
89 # *PLUID;
95
96 PLUID = POINTER(LUID)
97
98 # typedef struct _LUID_AND_ATTRIBUTES {
99 # LUID Luid;
100 # DWORD Attributes;
101 # } LUID_AND_ATTRIBUTES,
102 # *PLUID_AND_ATTRIBUTES;
108
109 # typedef struct _TOKEN_PRIVILEGES {
110 # DWORD PrivilegeCount;
111 # LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
112 # } TOKEN_PRIVILEGES,
113 # *PTOKEN_PRIVILEGES;
115 _fields_ = [
116 ("PrivilegeCount", DWORD),
117 ## ("Privileges", LUID_AND_ATTRIBUTES * ANYSIZE_ARRAY),
118 ("Privileges", LUID_AND_ATTRIBUTES),
119 ]
120 # See comments on AdjustTokenPrivileges about this structure
121
122 PTOKEN_PRIVILEGES = POINTER(TOKEN_PRIVILEGES)
123
124 #--- WAITCHAIN_NODE_INFO structure and types ----------------------------------
125
126 WCT_MAX_NODE_COUNT = 16
127 WCT_OBJNAME_LENGTH = 128
128 WCT_ASYNC_OPEN_FLAG = 0x1
129 WCTP_OPEN_ALL_FLAGS = WCT_ASYNC_OPEN_FLAG
130 WCT_OUT_OF_PROC_FLAG = 0x1
131 WCT_OUT_OF_PROC_COM_FLAG = 0x2
132 WCT_OUT_OF_PROC_CS_FLAG = 0x4
133 WCTP_GETINFO_ALL_FLAGS = WCT_OUT_OF_PROC_FLAG | WCT_OUT_OF_PROC_COM_FLAG | WCT_OUT_OF_PROC_CS_FLAG
134
135 HWCT = LPVOID
136
137 # typedef enum _WCT_OBJECT_TYPE
138 # {
139 # WctCriticalSectionType = 1,
140 # WctSendMessageType,
141 # WctMutexType,
142 # WctAlpcType,
143 # WctComType,
144 # WctThreadWaitType,
145 # WctProcessWaitType,
146 # WctThreadType,
147 # WctComActivationType,
148 # WctUnknownType,
149 # WctMaxType
150 # } WCT_OBJECT_TYPE;
151
152 WCT_OBJECT_TYPE = DWORD
153
154 WctCriticalSectionType = 1
155 WctSendMessageType = 2
156 WctMutexType = 3
157 WctAlpcType = 4
158 WctComType = 5
159 WctThreadWaitType = 6
160 WctProcessWaitType = 7
161 WctThreadType = 8
162 WctComActivationType = 9
163 WctUnknownType = 10
164 WctMaxType = 11
165
166 # typedef enum _WCT_OBJECT_STATUS
167 # {
168 # WctStatusNoAccess = 1, // ACCESS_DENIED for this object
169 # WctStatusRunning, // Thread status
170 # WctStatusBlocked, // Thread status
171 # WctStatusPidOnly, // Thread status
172 # WctStatusPidOnlyRpcss, // Thread status
173 # WctStatusOwned, // Dispatcher object status
174 # WctStatusNotOwned, // Dispatcher object status
175 # WctStatusAbandoned, // Dispatcher object status
176 # WctStatusUnknown, // All objects
177 # WctStatusError, // All objects
178 # WctStatusMax
179 # } WCT_OBJECT_STATUS;
180
181 WCT_OBJECT_STATUS = DWORD
182
183 WctStatusNoAccess = 1 # ACCESS_DENIED for this object
184 WctStatusRunning = 2 # Thread status
185 WctStatusBlocked = 3 # Thread status
186 WctStatusPidOnly = 4 # Thread status
187 WctStatusPidOnlyRpcss = 5 # Thread status
188 WctStatusOwned = 6 # Dispatcher object status
189 WctStatusNotOwned = 7 # Dispatcher object status
190 WctStatusAbandoned = 8 # Dispatcher object status
191 WctStatusUnknown = 9 # All objects
192 WctStatusError = 10 # All objects
193 WctStatusMax = 11
194
195 # typedef struct _WAITCHAIN_NODE_INFO {
196 # WCT_OBJECT_TYPE ObjectType;
197 # WCT_OBJECT_STATUS ObjectStatus;
198 # union {
199 # struct {
200 # WCHAR ObjectName[WCT_OBJNAME_LENGTH];
201 # LARGE_INTEGER Timeout;
202 # BOOL Alertable;
203 # } LockObject;
204 # struct {
205 # DWORD ProcessId;
206 # DWORD ThreadId;
207 # DWORD WaitTime;
208 # DWORD ContextSwitches;
209 # } ThreadObject;
210 # } ;
211 # }WAITCHAIN_NODE_INFO, *PWAITCHAIN_NODE_INFO;
212
214 _fields_ = [
215 ("ObjectName", WCHAR * WCT_OBJNAME_LENGTH),
216 ("Timeout", LONGLONG), # LARGE_INTEGER
217 ("Alertable", BOOL),
218 ]
219
221 _fields_ = [
222 ("ProcessId", DWORD),
223 ("ThreadId", DWORD),
224 ("WaitTime", DWORD),
225 ("ContextSwitches", DWORD),
226 ]
227
229 _fields_ = [
230 ("LockObject", _WAITCHAIN_NODE_INFO_STRUCT_1),
231 ("ThreadObject", _WAITCHAIN_NODE_INFO_STRUCT_2),
232 ]
233
235 _fields_ = [
236 ("ObjectType", WCT_OBJECT_TYPE),
237 ("ObjectStatus", WCT_OBJECT_STATUS),
238 ("u", _WAITCHAIN_NODE_INFO_UNION),
239 ]
240
241 PWAITCHAIN_NODE_INFO = POINTER(WAITCHAIN_NODE_INFO)
242
243 #--- advapi32.dll -------------------------------------------------------------
244
245 # BOOL WINAPI OpenProcessToken(
246 # __in HANDLE ProcessHandle,
247 # __in DWORD DesiredAccess,
248 # __out PHANDLE TokenHandle
249 # );
251 _OpenProcessToken = windll.advapi32.OpenProcessToken
252 _OpenProcessToken.argtypes = [HANDLE, DWORD, PHANDLE]
253 _OpenProcessToken.restype = bool
254 _OpenProcessToken.errcheck = RaiseIfZero
255
256 TokenHandle = HANDLE(INVALID_HANDLE_VALUE)
257 _OpenProcessToken(ProcessHandle, DesiredAccess, ctypes.byref(TokenHandle))
258 return Handle(TokenHandle.value)
259
260 # BOOL WINAPI OpenThreadToken(
261 # __in HANDLE ThreadHandle,
262 # __in DWORD DesiredAccess,
263 # __in BOOL OpenAsSelf,
264 # __out PHANDLE TokenHandle
265 # );
267 _OpenThreadToken = windll.advapi32.OpenThreadToken
268 _OpenThreadToken.argtypes = [HANDLE, DWORD, BOOL, PHANDLE]
269 _OpenThreadToken.restype = bool
270 _OpenThreadToken.errcheck = RaiseIfZero
271
272 TokenHandle = HANDLE(INVALID_HANDLE_VALUE)
273 _OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, ctypes.byref(TokenHandle))
274 return Handle(TokenHandle.value)
275
276 # BOOL WINAPI LookupPrivilegeValue(
277 # __in_opt LPCTSTR lpSystemName,
278 # __in LPCTSTR lpName,
279 # __out PLUID lpLuid
280 # );
282 _LookupPrivilegeValueA = windll.advapi32.LookupPrivilegeValueA
283 _LookupPrivilegeValueA.argtypes = [LPSTR, LPSTR, PLUID]
284 _LookupPrivilegeValueA.restype = bool
285 _LookupPrivilegeValueA.errcheck = RaiseIfZero
286
287 lpLuid = LUID()
288 if not lpSystemName:
289 lpSystemName = None
290 _LookupPrivilegeValueA(lpSystemName, lpName, ctypes.byref(lpLuid))
291 return lpLuid
292
294 _LookupPrivilegeValueW = windll.advapi32.LookupPrivilegeValueW
295 _LookupPrivilegeValueW.argtypes = [LPWSTR, LPWSTR, PLUID]
296 _LookupPrivilegeValueW.restype = bool
297 _LookupPrivilegeValueW.errcheck = RaiseIfZero
298
299 lpLuid = LUID()
300 if not lpSystemName:
301 lpSystemName = None
302 _LookupPrivilegeValueW(lpSystemName, lpName, ctypes.byref(lpLuid))
303 return lpLuid
304
305 LookupPrivilegeValue = GuessStringType(LookupPrivilegeValueA, LookupPrivilegeValueW)
306
307 # BOOL WINAPI LookupPrivilegeName(
308 # __in_opt LPCTSTR lpSystemName,
309 # __in PLUID lpLuid,
310 # __out_opt LPTSTR lpName,
311 # __inout LPDWORD cchName
312 # );
313
315 _LookupPrivilegeNameA = windll.advapi32.LookupPrivilegeNameA
316 _LookupPrivilegeNameA.argtypes = [LPSTR, PLUID, LPSTR, LPDWORD]
317 _LookupPrivilegeNameA.restype = bool
318 _LookupPrivilegeNameA.errcheck = RaiseIfZero
319
320 cchName = DWORD(0)
321 _LookupPrivilegeNameA(lpSystemName, ctypes.byref(lpLuid), NULL, ctypes.byref(cchName))
322 lpName = ctypes.create_string_buffer("", cchName.value)
323 _LookupPrivilegeNameA(lpSystemName, ctypes.byref(lpLuid), ctypes.byref(lpName), ctypes.byref(cchName))
324 return lpName.value
325
327 _LookupPrivilegeNameW = windll.advapi32.LookupPrivilegeNameW
328 _LookupPrivilegeNameW.argtypes = [LPWSTR, PLUID, LPWSTR, LPDWORD]
329 _LookupPrivilegeNameW.restype = bool
330 _LookupPrivilegeNameW.errcheck = RaiseIfZero
331
332 cchName = DWORD(0)
333 _LookupPrivilegeNameW(lpSystemName, ctypes.byref(lpLuid), NULL, ctypes.byref(cchName))
334 lpName = ctypes.create_unicode_buffer(u"", cchName.value)
335 _LookupPrivilegeNameW(lpSystemName, ctypes.byref(lpLuid), ctypes.byref(lpName), ctypes.byref(cchName))
336 return lpName.value
337
338 LookupPrivilegeName = GuessStringType(LookupPrivilegeNameA, LookupPrivilegeNameW)
339
340 # BOOL WINAPI AdjustTokenPrivileges(
341 # __in HANDLE TokenHandle,
342 # __in BOOL DisableAllPrivileges,
343 # __in_opt PTOKEN_PRIVILEGES NewState,
344 # __in DWORD BufferLength,
345 # __out_opt PTOKEN_PRIVILEGES PreviousState,
346 # __out_opt PDWORD ReturnLength
347 # );
349 _AdjustTokenPrivileges = windll.advapi32.AdjustTokenPrivileges
350 _AdjustTokenPrivileges.argtypes = [HANDLE, BOOL, LPVOID, DWORD, LPVOID, LPVOID]
351 _AdjustTokenPrivileges.restype = bool
352 _AdjustTokenPrivileges.errcheck = RaiseIfZero
353 #
354 # I don't know how to allocate variable sized structures in ctypes :(
355 # so this hack will work by using always TOKEN_PRIVILEGES of one element
356 # and calling the API many times. This also means the PreviousState
357 # parameter won't be supported yet as it's too much hassle. In a future
358 # version I look forward to implementing this function correctly.
359 #
360 if not NewState:
361 _AdjustTokenPrivileges(TokenHandle, TRUE, NULL, 0, NULL, NULL)
362 else:
363 success = True
364 for (privilege, enabled) in NewState:
365 if not isinstance(privilege, LUID):
366 privilege = LookupPrivilegeValue(NULL, privilege)
367 if enabled == True:
368 flags = SE_PRIVILEGE_ENABLED
369 elif enabled == False:
370 flags = SE_PRIVILEGE_REMOVED
371 elif enabled == None:
372 flags = 0
373 else:
374 flags = enabled
375 laa = LUID_AND_ATTRIBUTES(privilege, flags)
376 tp = TOKEN_PRIVILEGES(1, laa)
377 _AdjustTokenPrivileges(TokenHandle, FALSE, ctypes.byref(tp), sizeof(tp), NULL, NULL)
378
379 # BOOL WINAPI CreateProcessWithLogonW(
380 # __in LPCWSTR lpUsername,
381 # __in_opt LPCWSTR lpDomain,
382 # __in LPCWSTR lpPassword,
383 # __in DWORD dwLogonFlags,
384 # __in_opt LPCWSTR lpApplicationName,
385 # __inout_opt LPWSTR lpCommandLine,
386 # __in DWORD dwCreationFlags,
387 # __in_opt LPVOID lpEnvironment,
388 # __in_opt LPCWSTR lpCurrentDirectory,
389 # __in LPSTARTUPINFOW lpStartupInfo,
390 # __out LPPROCESS_INFORMATION lpProcessInfo
391 # );
392 -def CreateProcessWithLogonW(lpUsername = None, lpDomain = None, lpPassword = None, dwLogonFlags = 0, lpApplicationName = None, lpCommandLine = None, dwCreationFlags = 0, lpEnvironment = None, lpCurrentDirectory = None, lpStartupInfo = None):
393 _CreateProcessWithLogonW = windll.advapi32.CreateProcessWithLogonW
394 _CreateProcessWithLogonW.argtypes = [LPWSTR, LPWSTR, LPWSTR, DWORD, LPWSTR, LPWSTR, DWORD, LPVOID, LPWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION]
395 _CreateProcessWithLogonW.restype = bool
396 _CreateProcessWithLogonW.errcheck = RaiseIfZero
397
398 if not lpStartupInfo:
399 lpStartupInfo = STARTUPINFO()
400 lpStartupInfo.cb = sizeof(STARTUPINFO)
401 lpStartupInfo.lpReserved = 0
402 lpStartupInfo.lpDesktop = 0
403 lpStartupInfo.lpTitle = 0
404 lpStartupInfo.dwFlags = 0
405 lpStartupInfo.cbReserved2 = 0
406 lpStartupInfo.lpReserved2 = 0
407 lpProcessInformation = PROCESS_INFORMATION()
408 lpProcessInformation.hProcess = INVALID_HANDLE_VALUE
409 lpProcessInformation.hThread = INVALID_HANDLE_VALUE
410 lpProcessInformation.dwProcessId = 0
411 lpProcessInformation.dwThreadId = 0
412 _CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ctypes.byref(lpStartupInfo), ctypes.byref(lpProcessInformation))
413 return ProcessInformation(lpProcessInformation)
414
415 CreateProcessWithLogonA = MakeANSIVersion(CreateProcessWithLogonW)
416 CreateProcessWithLogon = CreateProcessWithLogonA
417
418 # BOOL WINAPI CreateProcessWithTokenW(
419 # __in HANDLE hToken,
420 # __in DWORD dwLogonFlags,
421 # __in_opt LPCWSTR lpApplicationName,
422 # __inout_opt LPWSTR lpCommandLine,
423 # __in DWORD dwCreationFlags,
424 # __in_opt LPVOID lpEnvironment,
425 # __in_opt LPCWSTR lpCurrentDirectory,
426 # __in LPSTARTUPINFOW lpStartupInfo,
427 # __out LPPROCESS_INFORMATION lpProcessInfo
428 # );
429 -def CreateProcessWithTokenW(hToken = None, dwLogonFlags = 0, lpApplicationName = None, lpCommandLine = None, dwCreationFlags = 0, lpEnvironment = None, lpCurrentDirectory = None, lpStartupInfo = None):
430 _CreateProcessWithTokenW = windll.advapi32.CreateProcessWithTokenW
431 _CreateProcessWithTokenW.argtypes = [HANDLE, DWORD, LPWSTR, LPWSTR, DWORD, LPVOID, LPWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION]
432 _CreateProcessWithTokenW.restype = bool
433 _CreateProcessWithTokenW.errcheck = RaiseIfZero
434
435 if not lpStartupInfo:
436 lpStartupInfo = STARTUPINFO()
437 lpStartupInfo.cb = sizeof(STARTUPINFO)
438 lpStartupInfo.lpReserved = 0
439 lpStartupInfo.lpDesktop = 0
440 lpStartupInfo.lpTitle = 0
441 lpStartupInfo.dwFlags = 0
442 lpStartupInfo.cbReserved2 = 0
443 lpStartupInfo.lpReserved2 = 0
444 lpProcessInformation = PROCESS_INFORMATION()
445 lpProcessInformation.hProcess = INVALID_HANDLE_VALUE
446 lpProcessInformation.hThread = INVALID_HANDLE_VALUE
447 lpProcessInformation.dwProcessId = 0
448 lpProcessInformation.dwThreadId = 0
449 _CreateProcessWithTokenW(hToken, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ctypes.byref(lpStartupInfo), ctypes.byref(lpProcessInformation))
450 return ProcessInformation(lpProcessInformation)
451
452 CreateProcessWithTokenA = MakeANSIVersion(CreateProcessWithTokenW)
453 CreateProcessWithToken = CreateProcessWithTokenA
454
455 # VOID CALLBACK WaitChainCallback(
456 # HWCT WctHandle,
457 # DWORD_PTR Context,
458 # DWORD CallbackStatus,
459 # LPDWORD NodeCount,
460 # PWAITCHAIN_NODE_INFO NodeInfoArray,
461 # LPBOOL IsCycle
462 # );
463 PWAITCHAINCALLBACK = WINFUNCTYPE(HWCT, LPVOID, DWORD, LPDWORD, PWAITCHAIN_NODE_INFO, LPBOOL)
464
465 # HWCT WINAPI OpenThreadWaitChainSession(
466 # __in DWORD Flags,
467 # __in_opt PWAITCHAINCALLBACK callback
468 # );
470 _OpenThreadWaitChainSession = windll.advapi32.OpenThreadWaitChainSession
471 _OpenThreadWaitChainSession.argtypes = [DWORD, PVOID]
472 _OpenThreadWaitChainSession.restype = HWCT
473 _OpenThreadWaitChainSession.errcheck = RaiseIfZero
474 if callback is not None:
475 callback = PWAITCHAINCALLBACK(callback)
476 return _OpenThreadWaitChainSession(Flags, callback)
477
478 # BOOL WINAPI GetThreadWaitChain(
479 # __in HWCT WctHandle,
480 # __in_opt DWORD_PTR Context,
481 # __in DWORD Flags,
482 # __in DWORD ThreadId,
483 # __inout LPDWORD NodeCount,
484 # __out PWAITCHAIN_NODE_INFO NodeInfoArray,
485 # __out LPBOOL IsCycle
486 # );
488 _GetThreadWaitChain = windll.advapi32.GetThreadWaitChain
489 _GetThreadWaitChain.argtypes = [HWCT, LPVOID, DWORD, DWORD, LPDWORD, PWAITCHAIN_NODE_INFO, LPBOOL]
490 _GetThreadWaitChain.restype = BOOL
491
492 NodeCount = DWORD(WCT_MAX_NODE_COUNT)
493 NodeInfoArray = (WAITCHAIN_NODE_INFO * WCT_MAX_NODE_COUNT)()
494 IsCycle = BOOL(FALSE)
495 _GetThreadWaitChain(WctHandle, Context, Flags, ThreadId, ctypes.byref(NodeCount), ctypes.cast(ctypes.pointer(NodeInfoArray), PWAITCHAIN_NODE_INFO), ctypes.byref(IsCycle))
496 NodeInfoArray = [ NodeInfoArray[index] for index in xrange(0, NodeCount.value) ]
497 IsCycle = bool(IsCycle)
498 return NodeInfoArray, IsCycle
499
500 # VOID WINAPI CloseThreadWaitChainSession(
501 # __in HWCT WctHandle
502 # );
504 _CloseThreadWaitChainSession = windll.advapi32.CloseThreadWaitChainSession
505 _CloseThreadWaitChainSession.argtypes = [HWCT]
506 _CloseThreadWaitChainSession(WctHandle)
507
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Feb 12 19:47:47 2010 | http://epydoc.sourceforge.net |