Package winappdbg :: Package win32 :: Module advapi32
[hide private]
[frames] | no frames]

Source Code for Module winappdbg.win32.advapi32

  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; 
99 -class LUID(Structure):
100 _fields_ = [ 101 ("LowPart", DWORD), 102 ("HighPart", LONG), 103 ]
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;
112 -class LUID_AND_ATTRIBUTES(Structure):
113 _fields_ = [ 114 ("Luid", LUID), 115 ("Attributes", DWORD), 116 ]
117 118 # typedef struct _TOKEN_PRIVILEGES { 119 # DWORD PrivilegeCount; 120 # LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; 121 # } TOKEN_PRIVILEGES, 122 # *PTOKEN_PRIVILEGES;
123 -class TOKEN_PRIVILEGES(Structure):
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
222 -class _WAITCHAIN_NODE_INFO_STRUCT_1(Structure):
223 _fields_ = [ 224 ("ObjectName", WCHAR * WCT_OBJNAME_LENGTH), 225 ("Timeout", LONGLONG), # LARGE_INTEGER 226 ("Alertable", BOOL), 227 ]
228
229 -class _WAITCHAIN_NODE_INFO_STRUCT_2(Structure):
230 _fields_ = [ 231 ("ProcessId", DWORD), 232 ("ThreadId", DWORD), 233 ("WaitTime", DWORD), 234 ("ContextSwitches", DWORD), 235 ]
236
237 -class _WAITCHAIN_NODE_INFO_UNION(Union):
238 _fields_ = [ 239 ("LockObject", _WAITCHAIN_NODE_INFO_STRUCT_1), 240 ("ThreadObject", _WAITCHAIN_NODE_INFO_STRUCT_2), 241 ]
242
243 -class WAITCHAIN_NODE_INFO(Structure):
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?
255 -class TokenHandle (Handle):
256 """ 257 Access token handle. 258 259 @see: L{Handle} 260 """ 261 pass
262 263 #--- advapi32.dll ------------------------------------------------------------- 264 265 # BOOL WINAPI OpenProcessToken( 266 # __in HANDLE ProcessHandle, 267 # __in DWORD DesiredAccess, 268 # __out PHANDLE TokenHandle 269 # );
270 -def OpenProcessToken(ProcessHandle, DesiredAccess):
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 # );
286 -def OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf = True):
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 # );
301 -def LookupPrivilegeValueA(lpSystemName, lpName):
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
313 -def LookupPrivilegeValueW(lpSystemName, lpName):
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
334 -def LookupPrivilegeNameA(lpSystemName, lpLuid):
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
346 -def LookupPrivilegeNameW(lpSystemName, lpLuid):
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 # );
368 -def AdjustTokenPrivileges(TokenHandle, NewState = ()):
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 # );
489 -def OpenThreadWaitChainSession(Flags = 0, callback = None):
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 # );
507 -def GetThreadWaitChain(WctHandle, Context, Flags, ThreadId):
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 # );
523 -def CloseThreadWaitChainSession(WctHandle):
524 _CloseThreadWaitChainSession = windll.advapi32.CloseThreadWaitChainSession 525 _CloseThreadWaitChainSession.argtypes = [HWCT] 526 _CloseThreadWaitChainSession(WctHandle)
527