| Home | Trees | Indices | Help |
|
|---|
|
|
1 # Copyright (c) 2009-2010, 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 Wrapper for advapi32.dll in ctypes.
30 """
31
32 __revision__ = "$Id: advapi32.py 720 2010-07-11 12:38:14Z qvasimodo $"
33
34 from defines import *
35 from kernel32 import *
36
37 # XXX TODO
38 # + add registry APIs
39 # + add service control manager APIs
40
41 #--- Constants ----------------------------------------------------------------
42
43 # Privilege constants
44 SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege"
45 SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege"
46 SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege"
47 SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege"
48 SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege"
49 SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege"
50 SE_TCB_NAME = "SeTcbPrivilege"
51 SE_SECURITY_NAME = "SeSecurityPrivilege"
52 SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege"
53 SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege"
54 SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege"
55 SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege"
56 SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege"
57 SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege"
58 SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege"
59 SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege"
60 SE_BACKUP_NAME = "SeBackupPrivilege"
61 SE_RESTORE_NAME = "SeRestorePrivilege"
62 SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
63 SE_DEBUG_NAME = "SeDebugPrivilege"
64 SE_AUDIT_NAME = "SeAuditPrivilege"
65 SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege"
66 SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege"
67 SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege"
68 SE_UNDOCK_NAME = "SeUndockPrivilege"
69 SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege"
70 SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege"
71 SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege"
72 SE_IMPERSONATE_NAME = "SeImpersonatePrivilege"
73 SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege"
74
75 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
76 SE_PRIVILEGE_ENABLED = 0x00000002
77 SE_PRIVILEGE_REMOVED = 0x00000004
78 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000
79
80 TOKEN_ADJUST_PRIVILEGES = 0x00000020
81
82 LOGON_WITH_PROFILE = 0x00000001
83 LOGON_NETCREDENTIALS_ONLY = 0x00000002
84
85 HKEY_CLASSES_ROOT = 0x80000000
86 HKEY_CURRENT_USER = 0x80000001
87 HKEY_LOCAL_MACHINE = 0x80000002
88 HKEY_USERS = 0x80000003
89 HKEY_PERFORMANCE_DATA = 0x80000004
90 HKEY_CURRENT_CONFIG = 0x80000005
91
92 #--- TOKEN_PRIVILEGE structure ------------------------------------------------
93
94 # typedef struct _LUID {
95 # DWORD LowPart;
96 # LONG HighPart;
97 # } LUID,
98 # *PLUID;
104
105 PLUID = POINTER(LUID)
106
107 # typedef struct _LUID_AND_ATTRIBUTES {
108 # LUID Luid;
109 # DWORD Attributes;
110 # } LUID_AND_ATTRIBUTES,
111 # *PLUID_AND_ATTRIBUTES;
117
118 # typedef struct _TOKEN_PRIVILEGES {
119 # DWORD PrivilegeCount;
120 # LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
121 # } TOKEN_PRIVILEGES,
122 # *PTOKEN_PRIVILEGES;
124 _fields_ = [
125 ("PrivilegeCount", DWORD),
126 ## ("Privileges", LUID_AND_ATTRIBUTES * ANYSIZE_ARRAY),
127 ("Privileges", LUID_AND_ATTRIBUTES),
128 ]
129 # See comments on AdjustTokenPrivileges about this structure
130
131 PTOKEN_PRIVILEGES = POINTER(TOKEN_PRIVILEGES)
132
133 #--- WAITCHAIN_NODE_INFO structure and types ----------------------------------
134
135 WCT_MAX_NODE_COUNT = 16
136 WCT_OBJNAME_LENGTH = 128
137 WCT_ASYNC_OPEN_FLAG = 0x1
138 WCTP_OPEN_ALL_FLAGS = WCT_ASYNC_OPEN_FLAG
139 WCT_OUT_OF_PROC_FLAG = 0x1
140 WCT_OUT_OF_PROC_COM_FLAG = 0x2
141 WCT_OUT_OF_PROC_CS_FLAG = 0x4
142 WCTP_GETINFO_ALL_FLAGS = WCT_OUT_OF_PROC_FLAG | WCT_OUT_OF_PROC_COM_FLAG | WCT_OUT_OF_PROC_CS_FLAG
143
144 HWCT = LPVOID
145
146 # typedef enum _WCT_OBJECT_TYPE
147 # {
148 # WctCriticalSectionType = 1,
149 # WctSendMessageType,
150 # WctMutexType,
151 # WctAlpcType,
152 # WctComType,
153 # WctThreadWaitType,
154 # WctProcessWaitType,
155 # WctThreadType,
156 # WctComActivationType,
157 # WctUnknownType,
158 # WctMaxType
159 # } WCT_OBJECT_TYPE;
160
161 WCT_OBJECT_TYPE = DWORD
162
163 WctCriticalSectionType = 1
164 WctSendMessageType = 2
165 WctMutexType = 3
166 WctAlpcType = 4
167 WctComType = 5
168 WctThreadWaitType = 6
169 WctProcessWaitType = 7
170 WctThreadType = 8
171 WctComActivationType = 9
172 WctUnknownType = 10
173 WctMaxType = 11
174
175 # typedef enum _WCT_OBJECT_STATUS
176 # {
177 # WctStatusNoAccess = 1, // ACCESS_DENIED for this object
178 # WctStatusRunning, // Thread status
179 # WctStatusBlocked, // Thread status
180 # WctStatusPidOnly, // Thread status
181 # WctStatusPidOnlyRpcss, // Thread status
182 # WctStatusOwned, // Dispatcher object status
183 # WctStatusNotOwned, // Dispatcher object status
184 # WctStatusAbandoned, // Dispatcher object status
185 # WctStatusUnknown, // All objects
186 # WctStatusError, // All objects
187 # WctStatusMax
188 # } WCT_OBJECT_STATUS;
189
190 WCT_OBJECT_STATUS = DWORD
191
192 WctStatusNoAccess = 1 # ACCESS_DENIED for this object
193 WctStatusRunning = 2 # Thread status
194 WctStatusBlocked = 3 # Thread status
195 WctStatusPidOnly = 4 # Thread status
196 WctStatusPidOnlyRpcss = 5 # Thread status
197 WctStatusOwned = 6 # Dispatcher object status
198 WctStatusNotOwned = 7 # Dispatcher object status
199 WctStatusAbandoned = 8 # Dispatcher object status
200 WctStatusUnknown = 9 # All objects
201 WctStatusError = 10 # All objects
202 WctStatusMax = 11
203
204 # typedef struct _WAITCHAIN_NODE_INFO {
205 # WCT_OBJECT_TYPE ObjectType;
206 # WCT_OBJECT_STATUS ObjectStatus;
207 # union {
208 # struct {
209 # WCHAR ObjectName[WCT_OBJNAME_LENGTH];
210 # LARGE_INTEGER Timeout;
211 # BOOL Alertable;
212 # } LockObject;
213 # struct {
214 # DWORD ProcessId;
215 # DWORD ThreadId;
216 # DWORD WaitTime;
217 # DWORD ContextSwitches;
218 # } ThreadObject;
219 # } ;
220 # }WAITCHAIN_NODE_INFO, *PWAITCHAIN_NODE_INFO;
221
223 _fields_ = [
224 ("ObjectName", WCHAR * WCT_OBJNAME_LENGTH),
225 ("Timeout", LONGLONG), # LARGE_INTEGER
226 ("Alertable", BOOL),
227 ]
228
230 _fields_ = [
231 ("ProcessId", DWORD),
232 ("ThreadId", DWORD),
233 ("WaitTime", DWORD),
234 ("ContextSwitches", DWORD),
235 ]
236
238 _fields_ = [
239 ("LockObject", _WAITCHAIN_NODE_INFO_STRUCT_1),
240 ("ThreadObject", _WAITCHAIN_NODE_INFO_STRUCT_2),
241 ]
242
244 _fields_ = [
245 ("ObjectType", WCT_OBJECT_TYPE),
246 ("ObjectStatus", WCT_OBJECT_STATUS),
247 ("u", _WAITCHAIN_NODE_INFO_UNION),
248 ]
249
250 PWAITCHAIN_NODE_INFO = POINTER(WAITCHAIN_NODE_INFO)
251
252 #--- Handle wrappers ----------------------------------------------------------
253
254 # XXX maybe add functions related to the tokens here?
262
263 #--- advapi32.dll -------------------------------------------------------------
264
265 # BOOL WINAPI OpenProcessToken(
266 # __in HANDLE ProcessHandle,
267 # __in DWORD DesiredAccess,
268 # __out PHANDLE TokenHandle
269 # );
271 _OpenProcessToken = windll.advapi32.OpenProcessToken
272 _OpenProcessToken.argtypes = [HANDLE, DWORD, PHANDLE]
273 _OpenProcessToken.restype = bool
274 _OpenProcessToken.errcheck = RaiseIfZero
275
276 tokenHandle = HANDLE(INVALID_HANDLE_VALUE)
277 _OpenProcessToken(ProcessHandle, DesiredAccess, ctypes.byref(tokenHandle))
278 return TokenHandle(tokenHandle.value)
279
280 # BOOL WINAPI OpenThreadToken(
281 # __in HANDLE ThreadHandle,
282 # __in DWORD DesiredAccess,
283 # __in BOOL OpenAsSelf,
284 # __out PHANDLE TokenHandle
285 # );
287 _OpenThreadToken = windll.advapi32.OpenThreadToken
288 _OpenThreadToken.argtypes = [HANDLE, DWORD, BOOL, PHANDLE]
289 _OpenThreadToken.restype = bool
290 _OpenThreadToken.errcheck = RaiseIfZero
291
292 tokenHandle = HANDLE(INVALID_HANDLE_VALUE)
293 _OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, ctypes.byref(tokenHandle))
294 return TokenHandle(tokenHandle.value)
295
296 # BOOL WINAPI LookupPrivilegeValue(
297 # __in_opt LPCTSTR lpSystemName,
298 # __in LPCTSTR lpName,
299 # __out PLUID lpLuid
300 # );
302 _LookupPrivilegeValueA = windll.advapi32.LookupPrivilegeValueA
303 _LookupPrivilegeValueA.argtypes = [LPSTR, LPSTR, PLUID]
304 _LookupPrivilegeValueA.restype = bool
305 _LookupPrivilegeValueA.errcheck = RaiseIfZero
306
307 lpLuid = LUID()
308 if not lpSystemName:
309 lpSystemName = None
310 _LookupPrivilegeValueA(lpSystemName, lpName, ctypes.byref(lpLuid))
311 return lpLuid
312
314 _LookupPrivilegeValueW = windll.advapi32.LookupPrivilegeValueW
315 _LookupPrivilegeValueW.argtypes = [LPWSTR, LPWSTR, PLUID]
316 _LookupPrivilegeValueW.restype = bool
317 _LookupPrivilegeValueW.errcheck = RaiseIfZero
318
319 lpLuid = LUID()
320 if not lpSystemName:
321 lpSystemName = None
322 _LookupPrivilegeValueW(lpSystemName, lpName, ctypes.byref(lpLuid))
323 return lpLuid
324
325 LookupPrivilegeValue = GuessStringType(LookupPrivilegeValueA, LookupPrivilegeValueW)
326
327 # BOOL WINAPI LookupPrivilegeName(
328 # __in_opt LPCTSTR lpSystemName,
329 # __in PLUID lpLuid,
330 # __out_opt LPTSTR lpName,
331 # __inout LPDWORD cchName
332 # );
333
335 _LookupPrivilegeNameA = windll.advapi32.LookupPrivilegeNameA
336 _LookupPrivilegeNameA.argtypes = [LPSTR, PLUID, LPSTR, LPDWORD]
337 _LookupPrivilegeNameA.restype = bool
338 _LookupPrivilegeNameA.errcheck = RaiseIfZero
339
340 cchName = DWORD(0)
341 _LookupPrivilegeNameA(lpSystemName, ctypes.byref(lpLuid), NULL, ctypes.byref(cchName))
342 lpName = ctypes.create_string_buffer("", cchName.value)
343 _LookupPrivilegeNameA(lpSystemName, ctypes.byref(lpLuid), ctypes.byref(lpName), ctypes.byref(cchName))
344 return lpName.value
345
347 _LookupPrivilegeNameW = windll.advapi32.LookupPrivilegeNameW
348 _LookupPrivilegeNameW.argtypes = [LPWSTR, PLUID, LPWSTR, LPDWORD]
349 _LookupPrivilegeNameW.restype = bool
350 _LookupPrivilegeNameW.errcheck = RaiseIfZero
351
352 cchName = DWORD(0)
353 _LookupPrivilegeNameW(lpSystemName, ctypes.byref(lpLuid), NULL, ctypes.byref(cchName))
354 lpName = ctypes.create_unicode_buffer(u"", cchName.value)
355 _LookupPrivilegeNameW(lpSystemName, ctypes.byref(lpLuid), ctypes.byref(lpName), ctypes.byref(cchName))
356 return lpName.value
357
358 LookupPrivilegeName = GuessStringType(LookupPrivilegeNameA, LookupPrivilegeNameW)
359
360 # BOOL WINAPI AdjustTokenPrivileges(
361 # __in HANDLE TokenHandle,
362 # __in BOOL DisableAllPrivileges,
363 # __in_opt PTOKEN_PRIVILEGES NewState,
364 # __in DWORD BufferLength,
365 # __out_opt PTOKEN_PRIVILEGES PreviousState,
366 # __out_opt PDWORD ReturnLength
367 # );
369 _AdjustTokenPrivileges = windll.advapi32.AdjustTokenPrivileges
370 _AdjustTokenPrivileges.argtypes = [HANDLE, BOOL, LPVOID, DWORD, LPVOID, LPVOID]
371 _AdjustTokenPrivileges.restype = bool
372 _AdjustTokenPrivileges.errcheck = RaiseIfZero
373 #
374 # I don't know how to allocate variable sized structures in ctypes :(
375 # so this hack will work by using always TOKEN_PRIVILEGES of one element
376 # and calling the API many times. This also means the PreviousState
377 # parameter won't be supported yet as it's too much hassle. In a future
378 # version I look forward to implementing this function correctly.
379 #
380 if not NewState:
381 _AdjustTokenPrivileges(TokenHandle, TRUE, NULL, 0, NULL, NULL)
382 else:
383 success = True
384 for (privilege, enabled) in NewState:
385 if not isinstance(privilege, LUID):
386 privilege = LookupPrivilegeValue(NULL, privilege)
387 if enabled == True:
388 flags = SE_PRIVILEGE_ENABLED
389 elif enabled == False:
390 flags = SE_PRIVILEGE_REMOVED
391 elif enabled == None:
392 flags = 0
393 else:
394 flags = enabled
395 laa = LUID_AND_ATTRIBUTES(privilege, flags)
396 tp = TOKEN_PRIVILEGES(1, laa)
397 _AdjustTokenPrivileges(TokenHandle, FALSE, ctypes.byref(tp), sizeof(tp), NULL, NULL)
398
399 # BOOL WINAPI CreateProcessWithLogonW(
400 # __in LPCWSTR lpUsername,
401 # __in_opt LPCWSTR lpDomain,
402 # __in LPCWSTR lpPassword,
403 # __in DWORD dwLogonFlags,
404 # __in_opt LPCWSTR lpApplicationName,
405 # __inout_opt LPWSTR lpCommandLine,
406 # __in DWORD dwCreationFlags,
407 # __in_opt LPVOID lpEnvironment,
408 # __in_opt LPCWSTR lpCurrentDirectory,
409 # __in LPSTARTUPINFOW lpStartupInfo,
410 # __out LPPROCESS_INFORMATION lpProcessInfo
411 # );
412 -def CreateProcessWithLogonW(lpUsername = None, lpDomain = None, lpPassword = None, dwLogonFlags = 0, lpApplicationName = None, lpCommandLine = None, dwCreationFlags = 0, lpEnvironment = None, lpCurrentDirectory = None, lpStartupInfo = None):
413 _CreateProcessWithLogonW = windll.advapi32.CreateProcessWithLogonW
414 _CreateProcessWithLogonW.argtypes = [LPWSTR, LPWSTR, LPWSTR, DWORD, LPWSTR, LPWSTR, DWORD, LPVOID, LPWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION]
415 _CreateProcessWithLogonW.restype = bool
416 _CreateProcessWithLogonW.errcheck = RaiseIfZero
417
418 if not lpStartupInfo:
419 lpStartupInfo = STARTUPINFO()
420 lpStartupInfo.cb = sizeof(STARTUPINFO)
421 lpStartupInfo.lpReserved = 0
422 lpStartupInfo.lpDesktop = 0
423 lpStartupInfo.lpTitle = 0
424 lpStartupInfo.dwFlags = 0
425 lpStartupInfo.cbReserved2 = 0
426 lpStartupInfo.lpReserved2 = 0
427 lpProcessInformation = PROCESS_INFORMATION()
428 lpProcessInformation.hProcess = INVALID_HANDLE_VALUE
429 lpProcessInformation.hThread = INVALID_HANDLE_VALUE
430 lpProcessInformation.dwProcessId = 0
431 lpProcessInformation.dwThreadId = 0
432 _CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ctypes.byref(lpStartupInfo), ctypes.byref(lpProcessInformation))
433 return ProcessInformation(lpProcessInformation)
434
435 CreateProcessWithLogonA = MakeANSIVersion(CreateProcessWithLogonW)
436 CreateProcessWithLogon = CreateProcessWithLogonA
437
438 # BOOL WINAPI CreateProcessWithTokenW(
439 # __in HANDLE hToken,
440 # __in DWORD dwLogonFlags,
441 # __in_opt LPCWSTR lpApplicationName,
442 # __inout_opt LPWSTR lpCommandLine,
443 # __in DWORD dwCreationFlags,
444 # __in_opt LPVOID lpEnvironment,
445 # __in_opt LPCWSTR lpCurrentDirectory,
446 # __in LPSTARTUPINFOW lpStartupInfo,
447 # __out LPPROCESS_INFORMATION lpProcessInfo
448 # );
449 -def CreateProcessWithTokenW(hToken = None, dwLogonFlags = 0, lpApplicationName = None, lpCommandLine = None, dwCreationFlags = 0, lpEnvironment = None, lpCurrentDirectory = None, lpStartupInfo = None):
450 _CreateProcessWithTokenW = windll.advapi32.CreateProcessWithTokenW
451 _CreateProcessWithTokenW.argtypes = [HANDLE, DWORD, LPWSTR, LPWSTR, DWORD, LPVOID, LPWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION]
452 _CreateProcessWithTokenW.restype = bool
453 _CreateProcessWithTokenW.errcheck = RaiseIfZero
454
455 if not lpStartupInfo:
456 lpStartupInfo = STARTUPINFO()
457 lpStartupInfo.cb = sizeof(STARTUPINFO)
458 lpStartupInfo.lpReserved = 0
459 lpStartupInfo.lpDesktop = 0
460 lpStartupInfo.lpTitle = 0
461 lpStartupInfo.dwFlags = 0
462 lpStartupInfo.cbReserved2 = 0
463 lpStartupInfo.lpReserved2 = 0
464 lpProcessInformation = PROCESS_INFORMATION()
465 lpProcessInformation.hProcess = INVALID_HANDLE_VALUE
466 lpProcessInformation.hThread = INVALID_HANDLE_VALUE
467 lpProcessInformation.dwProcessId = 0
468 lpProcessInformation.dwThreadId = 0
469 _CreateProcessWithTokenW(hToken, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ctypes.byref(lpStartupInfo), ctypes.byref(lpProcessInformation))
470 return ProcessInformation(lpProcessInformation)
471
472 CreateProcessWithTokenA = MakeANSIVersion(CreateProcessWithTokenW)
473 CreateProcessWithToken = CreateProcessWithTokenA
474
475 # VOID CALLBACK WaitChainCallback(
476 # HWCT WctHandle,
477 # DWORD_PTR Context,
478 # DWORD CallbackStatus,
479 # LPDWORD NodeCount,
480 # PWAITCHAIN_NODE_INFO NodeInfoArray,
481 # LPBOOL IsCycle
482 # );
483 PWAITCHAINCALLBACK = WINFUNCTYPE(HWCT, DWORD_PTR, DWORD, LPDWORD, PWAITCHAIN_NODE_INFO, LPBOOL)
484
485 # HWCT WINAPI OpenThreadWaitChainSession(
486 # __in DWORD Flags,
487 # __in_opt PWAITCHAINCALLBACK callback
488 # );
490 _OpenThreadWaitChainSession = windll.advapi32.OpenThreadWaitChainSession
491 _OpenThreadWaitChainSession.argtypes = [DWORD, PVOID]
492 _OpenThreadWaitChainSession.restype = HWCT
493 _OpenThreadWaitChainSession.errcheck = RaiseIfZero
494 if callback is not None:
495 callback = PWAITCHAINCALLBACK(callback)
496 return _OpenThreadWaitChainSession(Flags, callback)
497
498 # BOOL WINAPI GetThreadWaitChain(
499 # __in HWCT WctHandle,
500 # __in_opt DWORD_PTR Context,
501 # __in DWORD Flags,
502 # __in DWORD ThreadId,
503 # __inout LPDWORD NodeCount,
504 # __out PWAITCHAIN_NODE_INFO NodeInfoArray,
505 # __out LPBOOL IsCycle
506 # );
508 _GetThreadWaitChain = windll.advapi32.GetThreadWaitChain
509 _GetThreadWaitChain.argtypes = [HWCT, DWORD_PTR, DWORD, DWORD, LPDWORD, PWAITCHAIN_NODE_INFO, LPBOOL]
510 _GetThreadWaitChain.restype = BOOL
511
512 NodeCount = DWORD(WCT_MAX_NODE_COUNT)
513 NodeInfoArray = (WAITCHAIN_NODE_INFO * WCT_MAX_NODE_COUNT)()
514 IsCycle = BOOL(FALSE)
515 _GetThreadWaitChain(WctHandle, Context, Flags, ThreadId, ctypes.byref(NodeCount), ctypes.cast(ctypes.pointer(NodeInfoArray), PWAITCHAIN_NODE_INFO), ctypes.byref(IsCycle))
516 NodeInfoArray = [ NodeInfoArray[index] for index in xrange(0, NodeCount.value) ]
517 IsCycle = bool(IsCycle)
518 return NodeInfoArray, IsCycle
519
520 # VOID WINAPI CloseThreadWaitChainSession(
521 # __in HWCT WctHandle
522 # );
524 _CloseThreadWaitChainSession = windll.advapi32.CloseThreadWaitChainSession
525 _CloseThreadWaitChainSession.argtypes = [HWCT]
526 _CloseThreadWaitChainSession(WctHandle)
527
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Jul 20 14:32:22 2010 | http://epydoc.sourceforge.net |