1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2009-2014, Mario Vilas
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10#     * Redistributions of source code must retain the above copyright notice,
11#       this list of conditions and the following disclaimer.
12#     * Redistributions in binary form must reproduce the above copyright
13#       notice,this list of conditions and the following disclaimer in the
14#       documentation and/or other materials provided with the distribution.
15#     * Neither the name of the copyright holder nor the names of its
16#       contributors may be used to endorse or promote products derived from
17#       this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29# POSSIBILITY OF SUCH DAMAGE.
30
31"""
32Wrapper for ntdll.dll in ctypes.
33"""
34
35__revision__ = "$Id$"
36
37from winappdbg.win32.defines import *
38
39#==============================================================================
40# This is used later on to calculate the list of exported symbols.
41_all = None
42_all = set(vars().keys())
43_all.add('peb_teb')
44#==============================================================================
45
46from winappdbg.win32.peb_teb import *
47
48#--- Types --------------------------------------------------------------------
49
50SYSDBG_COMMAND          = DWORD
51PROCESSINFOCLASS        = DWORD
52THREADINFOCLASS         = DWORD
53FILE_INFORMATION_CLASS  = DWORD
54
55#--- Constants ----------------------------------------------------------------
56
57# DEP flags for ProcessExecuteFlags
58MEM_EXECUTE_OPTION_ENABLE               = 1
59MEM_EXECUTE_OPTION_DISABLE              = 2
60MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4
61MEM_EXECUTE_OPTION_PERMANENT            = 8
62
63# SYSTEM_INFORMATION_CLASS
64# http://www.informit.com/articles/article.aspx?p=22442&seqNum=4
65SystemBasicInformation                  = 1     # 0x002C
66SystemProcessorInformation              = 2     # 0x000C
67SystemPerformanceInformation            = 3     # 0x0138
68SystemTimeInformation                   = 4     # 0x0020
69SystemPathInformation                   = 5     # not implemented
70SystemProcessInformation                = 6     # 0x00F8 + per process
71SystemCallInformation                   = 7     # 0x0018 + (n * 0x0004)
72SystemConfigurationInformation          = 8     # 0x0018
73SystemProcessorCounters                 = 9     # 0x0030 per cpu
74SystemGlobalFlag                        = 10    # 0x0004
75SystemInfo10                            = 11    # not implemented
76SystemModuleInformation                 = 12    # 0x0004 + (n * 0x011C)
77SystemLockInformation                   = 13    # 0x0004 + (n * 0x0024)
78SystemInfo13                            = 14    # not implemented
79SystemPagedPoolInformation              = 15    # checked build only
80SystemNonPagedPoolInformation           = 16    # checked build only
81SystemHandleInformation                 = 17    # 0x0004 + (n * 0x0010)
82SystemObjectInformation                 = 18    # 0x0038+ + (n * 0x0030+)
83SystemPagefileInformation               = 19    # 0x0018+ per page file
84SystemInstemulInformation               = 20    # 0x0088
85SystemInfo20                            = 21    # invalid info class
86SystemCacheInformation                  = 22    # 0x0024
87SystemPoolTagInformation                = 23    # 0x0004 + (n * 0x001C)
88SystemProcessorStatistics               = 24    # 0x0000, or 0x0018 per cpu
89SystemDpcInformation                    = 25    # 0x0014
90SystemMemoryUsageInformation1           = 26    # checked build only
91SystemLoadImage                         = 27    # 0x0018, set mode only
92SystemUnloadImage                       = 28    # 0x0004, set mode only
93SystemTimeAdjustmentInformation         = 29    # 0x000C, 0x0008 writeable
94SystemMemoryUsageInformation2           = 30    # checked build only
95SystemInfo30                            = 31    # checked build only
96SystemInfo31                            = 32    # checked build only
97SystemCrashDumpInformation              = 33    # 0x0004
98SystemExceptionInformation              = 34    # 0x0010
99SystemCrashDumpStateInformation         = 35    # 0x0008
100SystemDebuggerInformation               = 36    # 0x0002
101SystemThreadSwitchInformation           = 37    # 0x0030
102SystemRegistryQuotaInformation          = 38    # 0x000C
103SystemLoadDriver                        = 39    # 0x0008, set mode only
104SystemPrioritySeparationInformation     = 40    # 0x0004, set mode only
105SystemInfo40                            = 41    # not implemented
106SystemInfo41                            = 42    # not implemented
107SystemInfo42                            = 43    # invalid info class
108SystemInfo43                            = 44    # invalid info class
109SystemTimeZoneInformation               = 45    # 0x00AC
110SystemLookasideInformation              = 46    # n * 0x0020
111# info classes specific to Windows 2000
112# WTS = Windows Terminal Server
113SystemSetTimeSlipEvent                  = 47    # set mode only
114SystemCreateSession                     = 48    # WTS, set mode only
115SystemDeleteSession                     = 49    # WTS, set mode only
116SystemInfo49                            = 50    # invalid info class
117SystemRangeStartInformation             = 51    # 0x0004
118SystemVerifierInformation               = 52    # 0x0068
119SystemAddVerifier                       = 53    # set mode only
120SystemSessionProcessesInformation       = 54    # WTS
121
122# NtQueryInformationProcess constants (from MSDN)
123##ProcessBasicInformation = 0
124##ProcessDebugPort        = 7
125##ProcessWow64Information = 26
126##ProcessImageFileName    = 27
127
128# PROCESS_INFORMATION_CLASS
129# http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PROCESS_INFORMATION_CLASS.html
130ProcessBasicInformation             = 0
131ProcessQuotaLimits                  = 1
132ProcessIoCounters                   = 2
133ProcessVmCounters                   = 3
134ProcessTimes                        = 4
135ProcessBasePriority                 = 5
136ProcessRaisePriority                = 6
137ProcessDebugPort                    = 7
138ProcessExceptionPort                = 8
139ProcessAccessToken                  = 9
140ProcessLdtInformation               = 10
141ProcessLdtSize                      = 11
142ProcessDefaultHardErrorMode         = 12
143ProcessIoPortHandlers               = 13
144ProcessPooledUsageAndLimits         = 14
145ProcessWorkingSetWatch              = 15
146ProcessUserModeIOPL                 = 16
147ProcessEnableAlignmentFaultFixup    = 17
148ProcessPriorityClass                = 18
149ProcessWx86Information              = 19
150ProcessHandleCount                  = 20
151ProcessAffinityMask                 = 21
152ProcessPriorityBoost                = 22
153
154ProcessWow64Information             = 26
155ProcessImageFileName                = 27
156
157# http://www.codeproject.com/KB/security/AntiReverseEngineering.aspx
158ProcessDebugObjectHandle            = 30
159
160ProcessExecuteFlags                 = 34
161
162# THREAD_INFORMATION_CLASS
163ThreadBasicInformation              = 0
164ThreadTimes                         = 1
165ThreadPriority                      = 2
166ThreadBasePriority                  = 3
167ThreadAffinityMask                  = 4
168ThreadImpersonationToken            = 5
169ThreadDescriptorTableEntry          = 6
170ThreadEnableAlignmentFaultFixup     = 7
171ThreadEventPair                     = 8
172ThreadQuerySetWin32StartAddress     = 9
173ThreadZeroTlsCell                   = 10
174ThreadPerformanceCount              = 11
175ThreadAmILastThread                 = 12
176ThreadIdealProcessor                = 13
177ThreadPriorityBoost                 = 14
178ThreadSetTlsArrayAddress            = 15
179ThreadIsIoPending                   = 16
180ThreadHideFromDebugger              = 17
181
182# OBJECT_INFORMATION_CLASS
183ObjectBasicInformation              = 0
184ObjectNameInformation               = 1
185ObjectTypeInformation               = 2
186ObjectAllTypesInformation           = 3
187ObjectHandleInformation             = 4
188
189# FILE_INFORMATION_CLASS
190FileDirectoryInformation            = 1
191FileFullDirectoryInformation        = 2
192FileBothDirectoryInformation        = 3
193FileBasicInformation                = 4
194FileStandardInformation             = 5
195FileInternalInformation             = 6
196FileEaInformation                   = 7
197FileAccessInformation               = 8
198FileNameInformation                 = 9
199FileRenameInformation               = 10
200FileLinkInformation                 = 11
201FileNamesInformation                = 12
202FileDispositionInformation          = 13
203FilePositionInformation             = 14
204FileFullEaInformation               = 15
205FileModeInformation                 = 16
206FileAlignmentInformation            = 17
207FileAllInformation                  = 18
208FileAllocationInformation           = 19
209FileEndOfFileInformation            = 20
210FileAlternateNameInformation        = 21
211FileStreamInformation               = 22
212FilePipeInformation                 = 23
213FilePipeLocalInformation            = 24
214FilePipeRemoteInformation           = 25
215FileMailslotQueryInformation        = 26
216FileMailslotSetInformation          = 27
217FileCompressionInformation          = 28
218FileCopyOnWriteInformation          = 29
219FileCompletionInformation           = 30
220FileMoveClusterInformation          = 31
221FileQuotaInformation                = 32
222FileReparsePointInformation         = 33
223FileNetworkOpenInformation          = 34
224FileObjectIdInformation             = 35
225FileTrackingInformation             = 36
226FileOleDirectoryInformation         = 37
227FileContentIndexInformation         = 38
228FileInheritContentIndexInformation  = 37
229FileOleInformation                  = 39
230FileMaximumInformation              = 40
231
232# From http://www.nirsoft.net/kernel_struct/vista/EXCEPTION_DISPOSITION.html
233# typedef enum _EXCEPTION_DISPOSITION
234# {
235#          ExceptionContinueExecution = 0,
236#          ExceptionContinueSearch = 1,
237#          ExceptionNestedException = 2,
238#          ExceptionCollidedUnwind = 3
239# } EXCEPTION_DISPOSITION;
240ExceptionContinueExecution  = 0
241ExceptionContinueSearch     = 1
242ExceptionNestedException    = 2
243ExceptionCollidedUnwind     = 3
244
245#--- PROCESS_BASIC_INFORMATION structure --------------------------------------
246
247# From MSDN:
248#
249# typedef struct _PROCESS_BASIC_INFORMATION {
250#     PVOID Reserved1;
251#     PPEB PebBaseAddress;
252#     PVOID Reserved2[2];
253#     ULONG_PTR UniqueProcessId;
254#     PVOID Reserved3;
255# } PROCESS_BASIC_INFORMATION;
256##class PROCESS_BASIC_INFORMATION(Structure):
257##    _fields_ = [
258##        ("Reserved1",       PVOID),
259##        ("PebBaseAddress",  PPEB),
260##        ("Reserved2",       PVOID * 2),
261##        ("UniqueProcessId", ULONG_PTR),
262##        ("Reserved3",       PVOID),
263##]
264
265# From http://catch22.net/tuts/tips2
266# (Only valid for 32 bits)
267#
268# typedef struct
269# {
270#     ULONG      ExitStatus;
271#     PVOID      PebBaseAddress;
272#     ULONG      AffinityMask;
273#     ULONG      BasePriority;
274#     ULONG_PTR  UniqueProcessId;
275#     ULONG_PTR  InheritedFromUniqueProcessId;
276# } PROCESS_BASIC_INFORMATION;
277
278# My own definition follows:
279class PROCESS_BASIC_INFORMATION(Structure):
280    _fields_ = [
281        ("ExitStatus",                      SIZE_T),
282        ("PebBaseAddress",                  PVOID),     # PPEB
283        ("AffinityMask",                    KAFFINITY),
284        ("BasePriority",                    SDWORD),
285        ("UniqueProcessId",                 ULONG_PTR),
286        ("InheritedFromUniqueProcessId",    ULONG_PTR),
287]
288
289#--- THREAD_BASIC_INFORMATION structure ---------------------------------------
290
291# From http://undocumented.ntinternals.net/UserMode/Structures/THREAD_BASIC_INFORMATION.html
292#
293# typedef struct _THREAD_BASIC_INFORMATION {
294#   NTSTATUS ExitStatus;
295#   PVOID TebBaseAddress;
296#   CLIENT_ID ClientId;
297#   KAFFINITY AffinityMask;
298#   KPRIORITY Priority;
299#   KPRIORITY BasePriority;
300# } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
301class THREAD_BASIC_INFORMATION(Structure):
302    _fields_ = [
303        ("ExitStatus",      NTSTATUS),
304        ("TebBaseAddress",  PVOID),     # PTEB
305        ("ClientId",        CLIENT_ID),
306        ("AffinityMask",    KAFFINITY),
307        ("Priority",        SDWORD),
308        ("BasePriority",    SDWORD),
309]
310
311#--- FILE_NAME_INFORMATION structure ------------------------------------------
312
313# typedef struct _FILE_NAME_INFORMATION {
314#     ULONG FileNameLength;
315#     WCHAR FileName[1];
316# } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
317class FILE_NAME_INFORMATION(Structure):
318    _fields_ = [
319        ("FileNameLength",  ULONG),
320        ("FileName",        WCHAR * 1),
321    ]
322
323#--- SYSDBG_MSR structure and constants ---------------------------------------
324
325SysDbgReadMsr  = 16
326SysDbgWriteMsr = 17
327
328class SYSDBG_MSR(Structure):
329    _fields_ = [
330        ("Address", ULONG),
331        ("Data",    ULONGLONG),
332]
333
334#--- IO_STATUS_BLOCK structure ------------------------------------------------
335
336# typedef struct _IO_STATUS_BLOCK {
337#     union {
338#         NTSTATUS Status;
339#         PVOID Pointer;
340#     };
341#     ULONG_PTR Information;
342# } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
343class IO_STATUS_BLOCK(Structure):
344    _fields_ = [
345        ("Status",      NTSTATUS),
346        ("Information", ULONG_PTR),
347    ]
348    def __get_Pointer(self):
349        return PVOID(self.Status)
350    def __set_Pointer(self, ptr):
351        self.Status = ptr.value
352    Pointer = property(__get_Pointer, __set_Pointer)
353
354PIO_STATUS_BLOCK = POINTER(IO_STATUS_BLOCK)
355
356#--- ntdll.dll ----------------------------------------------------------------
357
358# ULONG WINAPI RtlNtStatusToDosError(
359#   __in  NTSTATUS Status
360# );
361def RtlNtStatusToDosError(Status):
362    _RtlNtStatusToDosError = windll.ntdll.RtlNtStatusToDosError
363    _RtlNtStatusToDosError.argtypes = [NTSTATUS]
364    _RtlNtStatusToDosError.restype = ULONG
365    return _RtlNtStatusToDosError(Status)
366
367# NTSYSAPI NTSTATUS NTAPI NtSystemDebugControl(
368#   IN SYSDBG_COMMAND Command,
369#   IN PVOID InputBuffer OPTIONAL,
370#   IN ULONG InputBufferLength,
371#   OUT PVOID OutputBuffer OPTIONAL,
372#   IN ULONG OutputBufferLength,
373#   OUT PULONG ReturnLength OPTIONAL
374# );
375def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, OutputBuffer = None, OutputBufferLength = None):
376    _NtSystemDebugControl = windll.ntdll.NtSystemDebugControl
377    _NtSystemDebugControl.argtypes = [SYSDBG_COMMAND, PVOID, ULONG, PVOID, ULONG, PULONG]
378    _NtSystemDebugControl.restype = NTSTATUS
379
380    # Validate the input buffer
381    if InputBuffer is None:
382        if InputBufferLength is None:
383            InputBufferLength = 0
384        else:
385            raise ValueError(
386                "Invalid call to NtSystemDebugControl: "
387                "input buffer length given but no input buffer!")
388    else:
389        if InputBufferLength is None:
390            InputBufferLength = sizeof(InputBuffer)
391        InputBuffer = byref(InputBuffer)
392
393    # Validate the output buffer
394    if OutputBuffer is None:
395        if OutputBufferLength is None:
396            OutputBufferLength = 0
397        else:
398            OutputBuffer = ctypes.create_string_buffer("", OutputBufferLength)
399    elif OutputBufferLength is None:
400        OutputBufferLength = sizeof(OutputBuffer)
401
402    # Make the call (with an output buffer)
403    if OutputBuffer is not None:
404        ReturnLength = ULONG(0)
405        ntstatus = _NtSystemDebugControl(Command, InputBuffer, InputBufferLength, byref(OutputBuffer), OutputBufferLength, byref(ReturnLength))
406        if ntstatus != 0:
407            raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
408        ReturnLength = ReturnLength.value
409        if ReturnLength != OutputBufferLength:
410            raise ctypes.WinError(ERROR_BAD_LENGTH)
411        return OutputBuffer, ReturnLength
412
413    # Make the call (without an output buffer)
414    ntstatus = _NtSystemDebugControl(Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, None)
415    if ntstatus != 0:
416        raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
417
418ZwSystemDebugControl = NtSystemDebugControl
419
420# NTSTATUS WINAPI NtQueryInformationProcess(
421#   __in       HANDLE ProcessHandle,
422#   __in       PROCESSINFOCLASS ProcessInformationClass,
423#   __out      PVOID ProcessInformation,
424#   __in       ULONG ProcessInformationLength,
425#   __out_opt  PULONG ReturnLength
426# );
427def NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformationLength = None):
428    _NtQueryInformationProcess = windll.ntdll.NtQueryInformationProcess
429    _NtQueryInformationProcess.argtypes = [HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG]
430    _NtQueryInformationProcess.restype = NTSTATUS
431    if ProcessInformationLength is not None:
432        ProcessInformation = ctypes.create_string_buffer("", ProcessInformationLength)
433    else:
434        if   ProcessInformationClass == ProcessBasicInformation:
435            ProcessInformation = PROCESS_BASIC_INFORMATION()
436            ProcessInformationLength = sizeof(PROCESS_BASIC_INFORMATION)
437        elif ProcessInformationClass == ProcessImageFileName:
438            unicode_buffer = ctypes.create_unicode_buffer(u"", 0x1000)
439            ProcessInformation = UNICODE_STRING(0, 0x1000, addressof(unicode_buffer))
440            ProcessInformationLength = sizeof(UNICODE_STRING)
441        elif ProcessInformationClass in (ProcessDebugPort, ProcessWow64Information, ProcessWx86Information, ProcessHandleCount, ProcessPriorityBoost):
442            ProcessInformation = DWORD()
443            ProcessInformationLength = sizeof(DWORD)
444        else:
445            raise Exception("Unknown ProcessInformationClass, use an explicit ProcessInformationLength value instead")
446    ReturnLength = ULONG(0)
447    ntstatus = _NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, byref(ProcessInformation), ProcessInformationLength, byref(ReturnLength))
448    if ntstatus != 0:
449        raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
450    if   ProcessInformationClass == ProcessBasicInformation:
451        retval = ProcessInformation
452    elif ProcessInformationClass in (ProcessDebugPort, ProcessWow64Information, ProcessWx86Information, ProcessHandleCount, ProcessPriorityBoost):
453        retval = ProcessInformation.value
454    elif ProcessInformationClass == ProcessImageFileName:
455        vptr = ctypes.c_void_p(ProcessInformation.Buffer)
456        cptr = ctypes.cast( vptr, ctypes.c_wchar * ProcessInformation.Length )
457        retval = cptr.contents.raw
458    else:
459        retval = ProcessInformation.raw[:ReturnLength.value]
460    return retval
461
462ZwQueryInformationProcess = NtQueryInformationProcess
463
464# NTSTATUS WINAPI NtQueryInformationThread(
465#   __in       HANDLE ThreadHandle,
466#   __in       THREADINFOCLASS ThreadInformationClass,
467#   __out      PVOID ThreadInformation,
468#   __in       ULONG ThreadInformationLength,
469#   __out_opt  PULONG ReturnLength
470# );
471def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformationLength = None):
472    _NtQueryInformationThread = windll.ntdll.NtQueryInformationThread
473    _NtQueryInformationThread.argtypes = [HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG]
474    _NtQueryInformationThread.restype = NTSTATUS
475    if ThreadInformationLength is not None:
476        ThreadInformation = ctypes.create_string_buffer("", ThreadInformationLength)
477    else:
478        if   ThreadInformationClass == ThreadBasicInformation:
479            ThreadInformation = THREAD_BASIC_INFORMATION()
480        elif ThreadInformationClass == ThreadHideFromDebugger:
481            ThreadInformation = BOOLEAN()
482        elif ThreadInformationClass == ThreadQuerySetWin32StartAddress:
483            ThreadInformation = PVOID()
484        elif ThreadInformationClass in (ThreadAmILastThread, ThreadPriorityBoost):
485            ThreadInformation = DWORD()
486        elif ThreadInformationClass == ThreadPerformanceCount:
487            ThreadInformation = LONGLONG()  # LARGE_INTEGER
488        else:
489            raise Exception("Unknown ThreadInformationClass, use an explicit ThreadInformationLength value instead")
490        ThreadInformationLength = sizeof(ThreadInformation)
491    ReturnLength = ULONG(0)
492    ntstatus = _NtQueryInformationThread(ThreadHandle, ThreadInformationClass, byref(ThreadInformation), ThreadInformationLength, byref(ReturnLength))
493    if ntstatus != 0:
494        raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
495    if   ThreadInformationClass == ThreadBasicInformation:
496        retval = ThreadInformation
497    elif ThreadInformationClass == ThreadHideFromDebugger:
498        retval = bool(ThreadInformation.value)
499    elif ThreadInformationClass in (ThreadQuerySetWin32StartAddress, ThreadAmILastThread, ThreadPriorityBoost, ThreadPerformanceCount):
500        retval = ThreadInformation.value
501    else:
502        retval = ThreadInformation.raw[:ReturnLength.value]
503    return retval
504
505ZwQueryInformationThread = NtQueryInformationThread
506
507# NTSTATUS
508#   NtQueryInformationFile(
509#     IN HANDLE  FileHandle,
510#     OUT PIO_STATUS_BLOCK  IoStatusBlock,
511#     OUT PVOID  FileInformation,
512#     IN ULONG  Length,
513#     IN FILE_INFORMATION_CLASS  FileInformationClass
514#     );
515def NtQueryInformationFile(FileHandle, FileInformationClass, FileInformation, Length):
516    _NtQueryInformationFile = windll.ntdll.NtQueryInformationFile
517    _NtQueryInformationFile.argtypes = [HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, DWORD]
518    _NtQueryInformationFile.restype = NTSTATUS
519    IoStatusBlock = IO_STATUS_BLOCK()
520    ntstatus = _NtQueryInformationFile(FileHandle, byref(IoStatusBlock), byref(FileInformation), Length, FileInformationClass)
521    if ntstatus != 0:
522        raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
523    return IoStatusBlock
524
525ZwQueryInformationFile = NtQueryInformationFile
526
527# DWORD STDCALL CsrGetProcessId (VOID);
528def CsrGetProcessId():
529    _CsrGetProcessId = windll.ntdll.CsrGetProcessId
530    _CsrGetProcessId.argtypes = []
531    _CsrGetProcessId.restype = DWORD
532    return _CsrGetProcessId()
533
534#==============================================================================
535# This calculates the list of exported symbols.
536_all = set(vars().keys()).difference(_all)
537__all__ = [_x for _x in _all if not _x.startswith('_')]
538__all__.sort()
539#==============================================================================
540