/* ntdll.h.  Contains ntdll specific stuff not defined elsewhere.

   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
   2011, 2012, 2013 Red Hat, Inc.

   This file is part of Cygwin.

   This software is a copyrighted work licensed under the terms of the
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
   details. */

#pragma once

#include <ntstatus.h>

/* custom status code: */
#define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269)

/* As of March 2013, Mingw doesn't define these status codes yet. */
#ifndef STATUS_NETWORK_OPEN_RESTRICTION
#define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS)0xC0000201)
#endif
#ifndef STATUS_SYMLINK_CLASS_DISABLED
#define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS)0xC0000715)
#endif

#define NtCurrentProcess() ((HANDLE) (LONG_PTR) -1)
#define NtCurrentThread()  ((HANDLE) (LONG_PTR) -2)

/* Creation information returned in IO_STATUS_BLOCK. */
#define FILE_SUPERSEDED     0
#define FILE_OPENED         1
#define FILE_CREATED        2
#define FILE_OVERWRITTEN    3
#define FILE_EXISTS         4
#define FILE_DOES_NOT_EXIST 5

/* Relative file position values in NtWriteFile call. */
#define FILE_WRITE_TO_END_OF_FILE      (-1LL)
#define FILE_USE_FILE_POINTER_POSITION (-2LL)

/* Device Characteristics. */
#define FILE_REMOVABLE_MEDIA           0x00000001
#define FILE_READ_ONLY_DEVICE          0x00000002
#define FILE_FLOPPY_DISKETTE           0x00000004
#define FILE_WRITE_ONCE_MEDIA          0x00000008
#define FILE_REMOTE_DEVICE             0x00000010
#define FILE_DEVICE_IS_MOUNTED         0x00000020
#define FILE_VIRTUAL_VOLUME            0x00000040
#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
#define FILE_DEVICE_SECURE_OPEN        0x00000100

/* Allocation type values in NtMapViewOfSection call. */
#define AT_EXTENDABLE_FILE 0x00002000
#define AT_ROUND_TO_PAGE 0x40000000

/* Lock type in NtLockVirtualMemory/NtUnlockVirtualMemory call. */
#define MAP_PROCESS 1
#define MAP_SYSTEM  2

/* Directory access rights (only in NT namespace). */
#define DIRECTORY_QUERY 1
#define DIRECTORY_TRAVERSE 2
#define DIRECTORY_CREATE_OBJECT 4
#define DIRECTORY_CREATE_SUBDIRECTORY 8
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)

/* Symbolic link access rights (only in NT namespace). */
#define SYMBOLIC_LINK_QUERY 1

/* Transaction access rights. */
#ifndef TRANSACTION_ALL_ACCESS
#define TRANSACTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x3F)
#endif

/* Event object access rights. */
#define EVENT_QUERY_STATE 1

/* Semaphore access rights. */
#define SEMAPHORE_QUERY_STATE 1

/* Specific ACCESS_MASKSs for objects created in Cygwin. */
#define CYG_SHARED_DIR_ACCESS	(DIRECTORY_QUERY \
				 | DIRECTORY_TRAVERSE \
				 | DIRECTORY_CREATE_SUBDIRECTORY \
				 | DIRECTORY_CREATE_OBJECT \
				 | READ_CONTROL)
#define CYG_MUTANT_ACCESS	(MUTANT_QUERY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)
#define CYG_EVENT_ACCESS	(EVENT_QUERY_STATE \
				 | EVENT_MODIFY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)
#define CYG_SEMAPHORE_ACCESS	(SEMAPHORE_QUERY_STATE \
				 | SEMAPHORE_MODIFY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)

/* Definitions for first parameter of RtlQueryRegistryValues. */
#define RTL_REGISTRY_ABSOLUTE 0
#define RTL_REGISTRY_SERVICES 1
#define RTL_REGISTRY_CONTROL 2
#define RTL_REGISTRY_WINDOWS_NT 3
#define RTL_REGISTRY_DEVICEMAP 4
#define RTL_REGISTRY_USER 5
#define RTL_REGISTRY_HANDLE 0x40000000
#define RTL_REGISTRY_OPTIONAL 0x80000000

/* Flags values for QueryTable parameter of RtlQueryRegistryValues. */
#define RTL_QUERY_REGISTRY_SUBKEY 0x01
#define RTL_QUERY_REGISTRY_TOPKEY 0x02
#define RTL_QUERY_REGISTRY_REQUIRED 0x04
#define RTL_QUERY_REGISTRY_NOVALUE 0x08
#define RTL_QUERY_REGISTRY_NOEXPAND 0x10
#define RTL_QUERY_REGISTRY_DIRECT 0x20
#define RTL_QUERY_REGISTRY_DELETE 0x40
#define RTL_QUERY_REGISTRY_NOSTRING 0x80

/* What RtlQueryProcessDebugInformation shall return. */
#define PDI_MODULES 0x01
#define PDI_HEAPS 0x04
#define PDI_HEAP_BLOCKS 0x10
#define PDI_WOW64_MODULES 0x40

/* VM working set list protection values.  Returned by NtQueryVirtualMemory. */
#define WSLE_PAGE_READONLY 0x001
#define WSLE_PAGE_EXECUTE 0x002
#define WSLE_PAGE_EXECUTE_READ 0x003
#define WSLE_PAGE_READWRITE 0x004
#define WSLE_PAGE_WRITECOPY 0x005
#define WSLE_PAGE_EXECUTE_READWRITE 0x006
#define WSLE_PAGE_EXECUTE_WRITECOPY 0x007
#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
#define WSLE_PAGE_SHAREABLE 0x100

/* Known debug heap flags */
#define HEAP_FLAG_NOSERIALIZE	       0x1
#define HEAP_FLAG_GROWABLE	       0x2
#define HEAP_FLAG_EXCEPTIONS	       0x4
#define HEAP_FLAG_NONDEFAULT	    0x1000
#define HEAP_FLAG_SHAREABLE	    0x8000
#define HEAP_FLAG_EXECUTABLE	   0x40000
#define HEAP_FLAG_DEBUGGED	0x40000000

/* IOCTL code to impersonate client of named pipe. */
#define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, \
					METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef enum _FILE_INFORMATION_CLASS
{
  FileDirectoryInformation = 1,
  FileFullDirectoryInformation, // 2
  FileBothDirectoryInformation, // 3
  FileBasicInformation, // 4 wdm
  FileStandardInformation, // 5 wdm
  FileInternalInformation, // 6
  FileEaInformation, // 7
  FileAccessInformation, // 8
  FileNameInformation, // 9
  FileRenameInformation, // 10
  FileLinkInformation, // 11
  FileNamesInformation, // 12
  FileDispositionInformation, // 13
  FilePositionInformation, // 14 wdm
  FileFullEaInformation, // 15
  FileModeInformation, // 16
  FileAlignmentInformation, // 17
  FileAllInformation, // 18
  FileAllocationInformation, // 19
  FileEndOfFileInformation, // 20 wdm
  FileAlternateNameInformation, // 21
  FileStreamInformation, // 22
  FilePipeInformation, // 23
  FilePipeLocalInformation, // 24
  FilePipeRemoteInformation, // 25
  FileMailslotQueryInformation, // 26
  FileMailslotSetInformation, // 27
  FileCompressionInformation, // 28
  FileObjectIdInformation, // 29
  FileCompletionInformation, // 30
  FileMoveClusterInformation, // 31
  FileQuotaInformation, // 32
  FileReparsePointInformation, // 33
  FileNetworkOpenInformation, // 34
  FileAttributeTagInformation, // 35
  FileTrackingInformation, // 36
  FileIdBothDirectoryInformation, // 37
  FileIdFullDirectoryInformation, // 38
  FileValidDataLengthInformation, // 39
  FileShortNameInformation, // 40
  FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

/* Checked on 64 bit. */
typedef struct _FILE_NAMES_INFORMATION
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  ULONG  FileNameLength;
  WCHAR  FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_DIRECTORY_INFORMATION
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  LARGE_INTEGER  CreationTime;
  LARGE_INTEGER  LastAccessTime;
  LARGE_INTEGER  LastWriteTime;
  LARGE_INTEGER  ChangeTime;
  LARGE_INTEGER  EndOfFile;
  LARGE_INTEGER  AllocationSize;
  ULONG  FileAttributes;
  ULONG  FileNameLength;
  WCHAR  FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_BOTH_DIR_INFORMATION
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  LARGE_INTEGER  CreationTime;
  LARGE_INTEGER  LastAccessTime;
  LARGE_INTEGER  LastWriteTime;
  LARGE_INTEGER  ChangeTime;
  LARGE_INTEGER  EndOfFile;
  LARGE_INTEGER  AllocationSize;
  ULONG  FileAttributes;
  ULONG  FileNameLength;
  ULONG  EaSize;
  CCHAR  ShortNameLength;
  WCHAR  ShortName[12];
  WCHAR  FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_ID_BOTH_DIR_INFORMATION
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  LARGE_INTEGER  CreationTime;
  LARGE_INTEGER  LastAccessTime;
  LARGE_INTEGER  LastWriteTime;
  LARGE_INTEGER  ChangeTime;
  LARGE_INTEGER  EndOfFile;
  LARGE_INTEGER  AllocationSize;
  ULONG  FileAttributes;
  ULONG  FileNameLength;
  ULONG  EaSize;
  CCHAR  ShortNameLength;
  WCHAR  ShortName[12];
  LARGE_INTEGER  FileId;
  WCHAR  FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;

typedef enum _SYSTEM_INFORMATION_CLASS
{
  SystemBasicInformation = 0,
  SystemPerformanceInformation = 2,
  SystemTimeOfDayInformation = 3,
  SystemProcessInformation = 5,
  SystemProcessorPerformanceInformation = 8,
  SystemHandleInformation = 16,
  SystemPagefileInformation = 18,
  /* There are a lot more of these... */
} SYSTEM_INFORMATION_CLASS;

/* Checked on 64 bit. */
typedef struct _SYSTEM_BASIC_INFORMATION
{
  ULONG Unknown;
  ULONG MaximumIncrement;
  ULONG PhysicalPageSize;
  ULONG NumberOfPhysicalPages;
  ULONG LowestPhysicalPage;
  ULONG HighestPhysicalPage;
  ULONG AllocationGranularity;
  ULONG_PTR LowestUserAddress;
  ULONG_PTR HighestUserAddress;
  ULONG_PTR ActiveProcessors;
  UCHAR NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;

/* Checked on 64 bit. */
typedef struct _SYSTEM_PAGEFILE_INFORMATION
{
  ULONG NextEntryOffset;
  ULONG CurrentSize;
  ULONG TotalUsed;
  ULONG PeakUsed;
  UNICODE_STRING FileName;
} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
  LARGE_INTEGER IdleTime;
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER DpcTime;
  LARGE_INTEGER InterruptTime;
  ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

typedef LONG KPRIORITY;

/* Checked on 64 bit. */
typedef struct _VM_COUNTERS
{
  SIZE_T PeakVirtualSize;
  SIZE_T VirtualSize;
  ULONG PageFaultCount;
  SIZE_T PeakWorkingSetSize;
  SIZE_T WorkingSetSize;
  SIZE_T QuotaPeakPagedPoolUsage;
  SIZE_T QuotaPagedPoolUsage;
  SIZE_T QuotaPeakNonPagedPoolUsage;
  SIZE_T QuotaNonPagedPoolUsage;
  SIZE_T PagefileUsage;
  SIZE_T PeakPagefileUsage;
} VM_COUNTERS, *PVM_COUNTERS;

/* Checked on 64 bit. */
typedef struct _CLIENT_ID
{
  HANDLE UniqueProcess;
  HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef enum
{
  StateInitialized,
  StateReady,
  StateRunning,
  StateStandby,
  StateTerminated,
  StateWait,
  StateTransition,
  StateUnknown,
} THREAD_STATE;

typedef enum
{
  Executive,
  FreePage,
  PageIn,
  PoolAllocation,
  DelayExecution,
  Suspended,
  UserRequest,
  WrExecutive,
  WrFreePage,
  WrPageIn,
  WrPoolAllocation,
  WrDelayExecution,
  WrSuspended,
  WrUserRequest,
  WrEventPair,
  WrQueue,
  WrLpcReceive,
  WrLpcReply,
  WrVirtualMemory,
  WrPageOut,
  WrRendezvous,
  Spare2,
  Spare3,
  Spare4,
  Spare5,
  Spare6,
  WrKernel,
  MaximumWaitReason
} KWAIT_REASON;

/* Checked on 64 bit. */
typedef struct _SYSTEM_THREADS
{
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER CreateTime;
  ULONG WaitTime;
  PVOID StartAddress;
  CLIENT_ID ClientId;
  KPRIORITY Priority;
  KPRIORITY BasePriority;
  ULONG ContextSwitchCount;
  THREAD_STATE State;
  KWAIT_REASON WaitReason;
  DWORD Reserved;
} SYSTEM_THREADS, *PSYSTEM_THREADS;

/* Checked on 64 bit. */
typedef struct _SYSTEM_PROCESS_INFORMATION
{
  ULONG NextEntryOffset;
  ULONG NumberOfThreads;
  ULONG Reserved1[6];
  LARGE_INTEGER CreateTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER KernelTime;
  UNICODE_STRING ImageName;
  KPRIORITY BasePriority;
  HANDLE UniqueProcessId;
  HANDLE InheritedFromUniqueProcessId;
  ULONG HandleCount;
  ULONG SessionId;
  ULONG PageDirectoryBase;
  VM_COUNTERS VirtualMemoryCounters;
  SIZE_T PrivatePageCount;
  IO_COUNTERS IoCounters;
  SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

/* Checked on 64 bit. */
typedef struct _IO_STATUS_BLOCK
{
  union {
    NTSTATUS Status;
    PVOID Pointer;
  };
  ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

/* Checked on 64 bit. */
typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
  LARGE_INTEGER IdleTime;
  LARGE_INTEGER ReadTransferCount;
  LARGE_INTEGER WriteTransferCount;
  LARGE_INTEGER OtherTransferCount;
  ULONG ReadOperationCount;
  ULONG WriteOperationCount;
  ULONG OtherOperationCount;
  ULONG AvailablePages;
  ULONG TotalCommittedPages;
  ULONG TotalCommitLimit;
  ULONG PeakCommitment;
  ULONG PageFaults;
  ULONG WriteCopyFaults;
  ULONG TransitionFaults;
  ULONG Reserved1;
  ULONG DemandZeroFaults;
  ULONG PagesRead;
  ULONG PageReadIos;
  ULONG Reserved2[2];
  ULONG PagefilePagesWritten;
  ULONG PagefilePageWriteIos;
  ULONG MappedFilePagesWritten;
  ULONG MappedFilePageWriteIos;
  ULONG PagedPoolUsage;
  ULONG NonPagedPoolUsage;
  ULONG PagedPoolAllocs;
  ULONG PagedPoolFrees;
  ULONG NonPagedPoolAllocs;
  ULONG NonPagedPoolFrees;
  ULONG TotalFreeSystemPtes;
  ULONG SystemCodePage;
  ULONG TotalSystemDriverPages;
  ULONG TotalSystemCodePages;
  ULONG SmallNonPagedLookasideListAllocateHits;
  ULONG SmallPagedLookasideListAllocateHits;
  ULONG Reserved3;
  ULONG MmSystemCachePage;
  ULONG PagedPoolPage;
  ULONG SystemDriverPage;
  ULONG FastReadNoWait;
  ULONG FastReadWait;
  ULONG FastReadResourceMiss;
  ULONG FastReadNotPossible;
  ULONG FastMdlReadNoWait;
  ULONG FastMdlReadWait;
  ULONG FastMdlReadResourceMiss;
  ULONG FastMdlReadNotPossible;
  ULONG MapDataNoWait;
  ULONG MapDataWait;
  ULONG MapDataNoWaitMiss;
  ULONG MapDataWaitMiss;
  ULONG PinMappedDataCount;
  ULONG PinReadNoWait;
  ULONG PinReadWait;
  ULONG PinReadNoWaitMiss;
  ULONG PinReadWaitMiss;
  ULONG CopyReadNoWait;
  ULONG CopyReadWait;
  ULONG CopyReadNoWaitMiss;
  ULONG CopyReadWaitMiss;
  ULONG MdlReadNoWait;
  ULONG MdlReadWait;
  ULONG MdlReadNoWaitMiss;
  ULONG MdlReadWaitMiss;
  ULONG ReadAheadIos;
  ULONG LazyWriteIos;
  ULONG LazyWritePages;
  ULONG DataFlushes;
  ULONG DataPages;
  ULONG ContextSwitches;
  ULONG FirstLevelTbFills;
  ULONG SecondLevelTbFills;
  ULONG SystemCalls;
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
{
  LARGE_INTEGER BootTime;
  LARGE_INTEGER CurrentTime;
  LARGE_INTEGER TimeZoneBias;
  ULONG CurrentTimeZoneId;
  BYTE Reserved1[20];		/* Per MSDN.  Always 0. */
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;

typedef enum _PROCESSINFOCLASS
{
  ProcessBasicInformation = 0,
  ProcessQuotaLimits = 1,
  ProcessVmCounters = 3,
  ProcessTimes = 4,
  ProcessSessionInformation = 24,
  ProcessWow64Information = 26,
  ProcessImageFileName = 27
} PROCESSINFOCLASS;

/* Checked on 64 bit. */
typedef struct _DEBUG_BUFFER
{
  HANDLE SectionHandle;
  PVOID SectionBase;
  PVOID RemoteSectionBase;
  ULONG_PTR SectionBaseDelta;
  HANDLE EventPairHandle;
  ULONG_PTR Unknown[2];
  HANDLE RemoteThreadHandle;
  ULONG InfoClassMask;
  ULONG_PTR SizeOfInfo;
  ULONG_PTR AllocatedSize;
  ULONG_PTR SectionSize;
  PVOID ModuleInformation;
  PVOID BackTraceInformation;
  PVOID HeapInformation;
  PVOID LockInformation;
  PVOID Reserved[8];
} DEBUG_BUFFER, *PDEBUG_BUFFER;

/* Checked on 64 bit. */
typedef struct _DEBUG_HEAP_INFORMATION
{
  ULONG_PTR Base;
  ULONG Flags;
  USHORT Granularity;
  USHORT Unknown;
  ULONG_PTR Allocated;
  ULONG_PTR Committed;
  ULONG TagCount;
  ULONG BlockCount;
  ULONG Reserved[7];
  PVOID Tags;
  PVOID Blocks;
} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;

/* Checked on 64 bit. */
typedef struct _DEBUG_HEAP_ARRAY
{
  ULONG Count;
  DEBUG_HEAP_INFORMATION Heaps[1];
} DEBUG_HEAP_ARRAY, *PDEBUG_HEAP_ARRAY;

/* Checked on 64 bit. */
typedef struct _DEBUG_HEAP_BLOCK
{
  ULONG_PTR Size;
  ULONG Flags;
  ULONG_PTR Committed;
  ULONG_PTR Address;
} DEBUG_HEAP_BLOCK, *PDEBUG_HEAP_BLOCK;

/* Checked on 64 bit. */
typedef struct _DEBUG_MODULE_INFORMATION
{
  ULONG_PTR Reserved[2];
  ULONG_PTR Base;
  ULONG Size;
  ULONG Flags;
  USHORT Index;
  USHORT Unknown;
  USHORT LoadCount;
  USHORT ModuleNameOffset;
  CHAR ImageName[256];
} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _DEBUG_MODULE_ARRAY
{
  ULONG Count;
  DEBUG_MODULE_INFORMATION Modules[1];
} DEBUG_MODULE_ARRAY, *PDEBUG_MODULE_ARRAY;

/* Checked on 64 bit. */
typedef struct _KERNEL_USER_TIMES
{
  LARGE_INTEGER CreateTime;
  LARGE_INTEGER ExitTime;
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;

/* Checked on 64 bit. */
typedef struct _LDR_DATA_TABLE_ENTRY
{
  /* Heads up!  The pointers within the LIST_ENTRYs don't point to the
     start of the next LDR_DATA_TABLE_ENTRY, but rather they point to the
     start of their respective LIST_ENTRY *within* LDR_DATA_TABLE_ENTRY. */
  LIST_ENTRY InLoadOrderLinks;
  LIST_ENTRY InMemoryOrderLinks;
  LIST_ENTRY InInitializationOrderLinks;
  PVOID DllBase;
  PVOID EntryPoint;
  ULONG SizeOfImage;
  UNICODE_STRING FullDllName;
  UNICODE_STRING BaseDllName;
  ULONG Flags;
  USHORT LoadCount;
  /* More follows.  Left out since it's just not used.  The aforementioned
     part of the structure is stable from at least NT4 up to Windows 8,
     including WOW64. */
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

/* Checked on 64 bit. */
typedef struct _PEB_LDR_DATA
{
  ULONG Length;
  BOOLEAN Initialized;
  PVOID SsHandle;
  /* Heads up!  The pointers within the LIST_ENTRYs don't point to the
     start of the next LDR_DATA_TABLE_ENTRY, but rather they point to the
     start of their respective LIST_ENTRY *within* LDR_DATA_TABLE_ENTRY. */
  LIST_ENTRY InLoadOrderModuleList;
  LIST_ENTRY InMemoryOrderModuleList;
  LIST_ENTRY InInitializationOrderModuleList;
  PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

/* Checked on 64 bit. */
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
  ULONG AllocationSize;
  ULONG Size;
  ULONG Flags;
  ULONG DebugFlags;
  HANDLE hConsole;
  ULONG ProcessGroup;
  HANDLE hStdInput;
  HANDLE hStdOutput;
  HANDLE hStdError;
  UNICODE_STRING CurrentDirectoryName;
  HANDLE CurrentDirectoryHandle;
  UNICODE_STRING DllPath;
  UNICODE_STRING ImagePathName;
  UNICODE_STRING CommandLine;
  PWSTR Environment;
  ULONG dwX;
  ULONG dwY;
  ULONG dwXSize;
  ULONG dwYSize;
  ULONG dwXCountChars;
  ULONG dwYCountChars;
  ULONG dwFillAttribute;
  ULONG dwFlags;
  ULONG wShowWindow;
  UNICODE_STRING WindowTitle;
  UNICODE_STRING DesktopInfo;
  UNICODE_STRING ShellInfo;
  UNICODE_STRING RuntimeInfo;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

/* Checked on 64 bit. */
typedef struct _PEB
{
  BYTE Reserved1[2];
  BYTE BeingDebugged;
  BYTE Reserved2[1];
  PVOID Reserved3[2];
  PPEB_LDR_DATA Ldr;
  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  PVOID Reserved4;
  PVOID ProcessHeap;
  PRTL_CRITICAL_SECTION FastPebLock;
  PVOID Reserved5[2];
  ULONG EnvironmentUpdateCount;
  BYTE Reserved6[228];
  PVOID Reserved7[49];
  ULONG SessionId;
  /* A lot more follows... */
} PEB, *PPEB;

/* Checked on 64 bit. */
typedef struct _GDI_TEB_BATCH
{
  ULONG Offset;
  HANDLE HDC;
  ULONG Buffer[0x136];
} GDI_TEB_BATCH, *PGDI_TEB_BATCH;

/* Checked on 64 bit. */
typedef struct _TEB
{
  NT_TIB Tib;
  PVOID EnvironmentPointer;
  CLIENT_ID ClientId;
  PVOID ActiveRpcHandle;
  PVOID ThreadLocalStoragePointer;
  PPEB Peb;
  ULONG LastErrorValue;
  ULONG CountOfOwnedCriticalSections;
  PVOID CsrClientThread;
  PVOID Win32ThreadInfo;
  ULONG User32Reserved[26];
  ULONG UserReserved[5];
  PVOID WOW32Reserved;
  LCID CurrentLocale;
  ULONG FpSoftwareStatusRegister;
  PVOID SystemReserved1[54];
  LONG ExceptionCode;
  PVOID ActivationContextStackPointer;
  UCHAR SpareBytes1[0x30 - 3 * sizeof(PVOID)];
  ULONG TxFsContext;
  GDI_TEB_BATCH GdiTebBatch;
  CLIENT_ID RealClientId;
  PVOID GdiCachedProcessHandle;
  ULONG GdiClientPID;
  ULONG GdiClientTID;
  PVOID GdiThreadLocalInfo;
  SIZE_T Win32ClientInfo[62];
  PVOID glDispatchTable[233];
  SIZE_T glReserved1[29];
  PVOID glReserved2;
  PVOID glSectionInfo;
  PVOID glSection;
  PVOID glTable;
  PVOID glCurrentRC;
  PVOID glContext;
  ULONG LastStatusValue;
  UNICODE_STRING StaticUnicodeString;
  WCHAR StaticUnicodeBuffer[261];
  PVOID DeallocationStack;
  PVOID TlsSlots[64];
  BYTE Reserved3[8];
  PVOID Reserved4[26];
  PVOID ReservedForOle;
  PVOID Reserved5[4];
  PVOID TlsExpansionSlots;
  /* A lot more follows... */
} TEB, *PTEB;

/* Checked on 64 bit. */
typedef struct _KSYSTEM_TIME
{
  ULONG LowPart;
  LONG High1Time;
  LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;

/* Checked on 64 bit. */
typedef struct _KUSER_SHARED_DATA
{
  BYTE Reserved1[0x08];
  KSYSTEM_TIME InterruptTime;
  BYTE Reserved2[0x2c8];
  ULONG DismountCount;
  /* A lot more follows... */
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;

/* Checked on 64 bit. */
typedef struct _PROCESS_BASIC_INFORMATION
{
  NTSTATUS ExitStatus;
  PPEB PebBaseAddress;
  KAFFINITY AffinityMask;
  KPRIORITY BasePriority;	/* !!!Broken on WOW64!!! */
  ULONG_PTR UniqueProcessId;
  ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

/* Checked on 64 bit. */
typedef struct _PROCESS_SESSION_INFORMATION
{
  ULONG  SessionId;
} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION;

typedef enum _MEMORY_INFORMATION_CLASS
{
  MemoryBasicInformation,
  MemoryWorkingSetList,
  MemorySectionName,
  MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;

/* Checked on 64 bit. */
typedef struct _MEMORY_WORKING_SET_LIST
{
  ULONG NumberOfPages;
  ULONG_PTR WorkingSetList[1];
} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;

/* Checked on 64 bit. */
typedef struct _MEMORY_SECTION_NAME
{
  UNICODE_STRING SectionFileName;
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;

/* Checked on 64 bit. */
typedef struct _FILE_BASIC_INFORMATION
{
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;
  ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_STANDARD_INFORMATION
{
  LARGE_INTEGER AllocationSize;
  LARGE_INTEGER EndOfFile;
  ULONG NumberOfLinks;
  BOOLEAN DeletePending;
  BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_NETWORK_OPEN_INFORMATION
{
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;
  LARGE_INTEGER AllocationSize;
  LARGE_INTEGER EndOfFile;
  ULONG FileAttributes;
} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_INTERNAL_INFORMATION
{
  LARGE_INTEGER FileId;
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_EA_INFORMATION
{
  ULONG EaSize;
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_ACCESS_INFORMATION
{
  ACCESS_MASK AccessFlags;
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_DISPOSITION_INFORMATION
{
  BOOLEAN DeleteFile;
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_POSITION_INFORMATION
{
  LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_END_OF_FILE_INFORMATION
{
  LARGE_INTEGER EndOfFile;
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_MODE_INFORMATION
{
  ULONG Mode;
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_ALIGNMENT_INFORMATION
{
  ULONG AlignmentRequirement;
} FILE_ALIGNMENT_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_NAME_INFORMATION
{
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_LINK_INFORMATION
{
  BOOLEAN ReplaceIfExists;
  HANDLE RootDirectory;
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_RENAME_INFORMATION
{
  BOOLEAN ReplaceIfExists;
  HANDLE RootDirectory;
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_ALL_INFORMATION {
  FILE_BASIC_INFORMATION     BasicInformation;
  FILE_STANDARD_INFORMATION  StandardInformation;
  FILE_INTERNAL_INFORMATION  InternalInformation;
  FILE_EA_INFORMATION        EaInformation;
  FILE_ACCESS_INFORMATION    AccessInformation;
  FILE_POSITION_INFORMATION  PositionInformation;
  FILE_MODE_INFORMATION      ModeInformation;
  FILE_ALIGNMENT_INFORMATION AlignmentInformation;
  FILE_NAME_INFORMATION      NameInformation;
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;

enum
{
  FILE_PIPE_DISCONNECTED_STATE = 1,
  FILE_PIPE_LISTENING_STATE = 2,
  FILE_PIPE_CONNECTED_STATE = 3,
  FILE_PIPE_CLOSING_STATE = 4
};

/* Checked on 64 bit. */
typedef struct _FILE_PIPE_LOCAL_INFORMATION
{
  ULONG NamedPipeType;
  ULONG NamedPipeConfiguration;
  ULONG MaximumInstances;
  ULONG CurrentInstances;
  ULONG InboundQuota;
  ULONG ReadDataAvailable;
  ULONG OutboundQuota;
  ULONG WriteQuotaAvailable;
  ULONG NamedPipeState;
  ULONG NamedPipeEnd;
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_COMPRESSION_INFORMATION
{
  LARGE_INTEGER CompressedFileSize;
  USHORT CompressionFormat;
  UCHAR	CompressionUnitShift;
  UCHAR ChunkShift;
  UCHAR ClusterShift;
  UCHAR Reserved[3];
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_FS_DEVICE_INFORMATION
{
  ULONG DeviceType;
  ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
{
  ULONG FileSystemAttributes;
  ULONG MaximumComponentNameLength;
  ULONG FileSystemNameLength;
  WCHAR FileSystemName[1];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;

/* Checked on 64 bit. */
#pragma pack(push,4)
typedef struct _FILE_FS_VOLUME_INFORMATION
{
  LARGE_INTEGER VolumeCreationTime;
  ULONG VolumeSerialNumber;
  ULONG VolumeLabelLength;
  BOOLEAN SupportsObjects;
  BOOLEAN __dummy;
  WCHAR VolumeLabel[1];
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
#pragma pack(pop)

/* Checked on 64 bit. */
typedef struct _FILE_FS_SIZE_INFORMATION
{
  LARGE_INTEGER TotalAllocationUnits;
  LARGE_INTEGER AvailableAllocationUnits;
  ULONG SectorsPerAllocationUnit;
  ULONG BytesPerSector;
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_FS_FULL_SIZE_INFORMATION
{
  LARGE_INTEGER TotalAllocationUnits;
  LARGE_INTEGER CallerAvailableAllocationUnits;
  LARGE_INTEGER ActualAvailableAllocationUnits;
  ULONG SectorsPerAllocationUnit;
  ULONG BytesPerSector;
} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_FS_OBJECTID_INFORMATION
{
  UCHAR ObjectId[16];
  UCHAR ExtendedInfo[48];
} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;

typedef enum _FSINFOCLASS {
  FileFsVolumeInformation = 1,
  FileFsLabelInformation,
  FileFsSizeInformation,
  FileFsDeviceInformation,
  FileFsAttributeInformation,
  FileFsControlInformation,
  FileFsFullSizeInformation,
  FileFsObjectIdInformation,
  FileFsDriverPathInformation,
  FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;

typedef enum _OBJECT_INFORMATION_CLASS
{
  ObjectBasicInformation = 0,
  ObjectNameInformation = 1,
  ObjectHandleInformation = 4
   // and many more
} OBJECT_INFORMATION_CLASS;

/* Checked on 64 bit. */
typedef struct _OBJECT_BASIC_INFORMATION
{
  ULONG Attributes;
  ACCESS_MASK GrantedAccess;
  ULONG HandleCount;
  ULONG PointerCount;
  ULONG PagedPoolUsage;
  ULONG NonPagedPoolUsage;
  ULONG Reserved[3];
  ULONG NameInformationLength;
  ULONG TypeInformationLength;
  ULONG SecurityDescriptorLength;
  LARGE_INTEGER CreateTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;

/* Checked on 64 bit. */
typedef struct _OBJECT_NAME_INFORMATION
{
  UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION;

/* Checked on 64 bit. */
typedef struct _DIRECTORY_BASIC_INFORMATION
{
  UNICODE_STRING ObjectName;
  UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_GET_EA_INFORMATION
{
  ULONG NextEntryOffset;
  UCHAR EaNameLength;
  CHAR EaName[1];
} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_FULL_EA_INFORMATION
{
  ULONG NextEntryOffset;
  UCHAR Flags;
  UCHAR EaNameLength;
  USHORT EaValueLength;
  CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;

/* Checked on 64 bit. */
typedef struct _FILE_MAILSLOT_SET_INFORMATION
{
  LARGE_INTEGER ReadTimeout;
} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION;

typedef VOID NTAPI (*PIO_APC_ROUTINE)(PVOID, PIO_STATUS_BLOCK, ULONG);

/* Checked on 64 bit. */
typedef struct _EVENT_BASIC_INFORMATION
{
  EVENT_TYPE EventType;
  LONG SignalState;
} EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION;

typedef enum _EVENT_INFORMATION_CLASS
{
  EventBasicInformation = 0
} EVENT_INFORMATION_CLASS, *PEVENT_INFORMATION_CLASS;

/* Checked on 64 bit. */
typedef struct _SEMAPHORE_BASIC_INFORMATION
{
  LONG CurrentCount;
  LONG MaximumCount;
} SEMAPHORE_BASIC_INFORMATION, *PSEMAPHORE_BASIC_INFORMATION;

typedef enum _SEMAPHORE_INFORMATION_CLASS
{
  SemaphoreBasicInformation = 0
} SEMAPHORE_INFORMATION_CLASS, *PSEMAPHORE_INFORMATION_CLASS;

typedef enum _THREADINFOCLASS
{
  ThreadBasicInformation = 0,
  ThreadTimes = 1,
  ThreadImpersonationToken = 5
} THREADINFOCLASS, *PTHREADINFOCLASS;

/* Checked on 64 bit. */
typedef struct _THREAD_BASIC_INFORMATION
{
  NTSTATUS ExitStatus;
  PNT_TIB TebBaseAddress;
  CLIENT_ID ClientId;
  KAFFINITY AffinityMask;
  KPRIORITY Priority;
  KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;

typedef enum _TIMER_INFORMATION_CLASS {
  TimerBasicInformation = 0
} TIMER_INFORMATION_CLASS, *PTIMER_INFORMATION_CLASS;

typedef struct _TIMER_BASIC_INFORMATION {
  LARGE_INTEGER TimeRemaining;
  BOOLEAN SignalState;
} TIMER_BASIC_INFORMATION, *PTIMER_BASIC_INFORMATION;

typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)
		 (PWSTR, ULONG, PVOID, ULONG, PVOID, PVOID);

typedef struct _RTL_QUERY_REGISTRY_TABLE
{
  PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
  ULONG Flags;
  PCWSTR Name;
  PVOID EntryContext;
  ULONG DefaultType;
  PVOID DefaultData;
  ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;

typedef enum _KEY_VALUE_INFORMATION_CLASS
{
  KeyValueBasicInformation = 0,
  KeyValueFullInformation,
  KeyValuePartialInformation
} KEY_VALUE_INFORMATION_CLASS, *PKEY_VALUE_INFORMATION_CLASS;

typedef struct _KEY_VALUE_PARTIAL_INFORMATION
{
  ULONG TitleIndex;
  ULONG Type;
  ULONG DataLength;
  UCHAR Data[1];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;

typedef enum _SECTION_INHERIT
{
  ViewShare = 1,
  ViewUnmap = 2
} SECTION_INHERIT;

typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);

/* Function declarations for ntdll.dll.  These don't appear in any
   standard Win32 header.  */

#ifdef __cplusplus
/* This is the mapping of the KUSER_SHARED_DATA structure into the user
   address space on BOTH architectures, 32 and 64 bit!
   We need it here to access the current DismountCount and InterruptTime.  */
static volatile KUSER_SHARED_DATA &SharedUserData
	= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;

extern "C"
{
#endif
  NTSTATUS NTAPI NtAccessCheck (PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK,
				PGENERIC_MAPPING, PPRIVILEGE_SET, PULONG,
				PACCESS_MASK, PNTSTATUS);
  NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
					  ULONG, PTOKEN_PRIVILEGES, PULONG);
  NTSTATUS NTAPI NtAllocateLocallyUniqueId (PLUID);
  NTSTATUS NTAPI NtAllocateUuids (PLARGE_INTEGER, PULONG, PULONG, PUCHAR);
  NTSTATUS NTAPI NtCancelTimer (HANDLE, PBOOLEAN);
  NTSTATUS NTAPI NtClose (HANDLE);
  NTSTATUS NTAPI NtCommitTransaction (HANDLE, BOOLEAN);
  NTSTATUS NTAPI NtCreateDirectoryObject (PHANDLE, ACCESS_MASK,
					  POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtCreateKey (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
			      PUNICODE_STRING, ULONG, PULONG);
  NTSTATUS NTAPI NtCreateEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				EVENT_TYPE, BOOLEAN);
  NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
			     PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
			     ULONG, ULONG, PVOID, ULONG);
  NTSTATUS NTAPI NtCreateMailslotFile(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				      PIO_STATUS_BLOCK, ULONG, ULONG, ULONG,
				      PLARGE_INTEGER);
  NTSTATUS NTAPI NtCreateMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				 BOOLEAN);
  NTSTATUS NTAPI NtCreateSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				  PLARGE_INTEGER, ULONG, ULONG, HANDLE);
  NTSTATUS NTAPI NtCreateSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				    LONG, LONG);
  NTSTATUS NTAPI NtCreateTimer (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				TIMER_TYPE);
  NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				TOKEN_TYPE, PLUID, PLARGE_INTEGER, PTOKEN_USER,
				PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
				PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL,
				PTOKEN_SOURCE);
  NTSTATUS NTAPI NtCreateTransaction (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				      LPGUID, HANDLE, ULONG, ULONG, ULONG,
				      PLARGE_INTEGER, PUNICODE_STRING);
  NTSTATUS NTAPI NtDuplicateToken (HANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				   BOOLEAN, TOKEN_TYPE, PHANDLE);
  NTSTATUS NTAPI NtFsControlFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
				  PIO_STATUS_BLOCK, ULONG, PVOID, ULONG,
				  PVOID, ULONG);
  NTSTATUS NTAPI NtFlushBuffersFile (HANDLE, PIO_STATUS_BLOCK);
  NTSTATUS NTAPI NtLoadKey (POBJECT_ATTRIBUTES, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtLockFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
			     PIO_STATUS_BLOCK, PLARGE_INTEGER, PLARGE_INTEGER,
			     ULONG, BOOLEAN, BOOLEAN);
  NTSTATUS NTAPI NtLockVirtualMemory (HANDLE, PVOID *, PSIZE_T, ULONG);
  NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG_PTR, SIZE_T,
				     PLARGE_INTEGER, PSIZE_T, SECTION_INHERIT,
				     ULONG, ULONG);
  NTSTATUS NTAPI NtNotifyChangeDirectoryFile (HANDLE, HANDLE, PIO_APC_ROUTINE,
					      PVOID, PIO_STATUS_BLOCK,
					      PFILE_NOTIFY_INFORMATION, ULONG,
					      ULONG, BOOLEAN);
  NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
					POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
			     PIO_STATUS_BLOCK, ULONG, ULONG);
  NTSTATUS NTAPI NtOpenKey (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenProcessToken (HANDLE, ACCESS_MASK, PHANDLE);
  NTSTATUS NTAPI NtOpenThreadToken (HANDLE, ACCESS_MASK, BOOLEAN, PHANDLE);
  NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenSymbolicLinkObject (PHANDLE, ACCESS_MASK,
					   POBJECT_ATTRIBUTES);
  /* WARNING!  Don't rely on the timestamp information returned by
     NtQueryAttributesFile.  Only the DOS file attribute info is reliable. */
  NTSTATUS NTAPI NtPrivilegeCheck (HANDLE, PPRIVILEGE_SET, PBOOLEAN);
  NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
					PFILE_BASIC_INFORMATION);
  NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID,
				      PIO_STATUS_BLOCK, PVOID, ULONG,
				      FILE_INFORMATION_CLASS, BOOLEAN,
				      PUNICODE_STRING, BOOLEAN);
  NTSTATUS NTAPI NtQueryDirectoryObject (HANDLE, PVOID, ULONG, BOOLEAN,
					 BOOLEAN, PULONG, PULONG);
  NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
				BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
  NTSTATUS NTAPI NtQueryEvent (HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG,
			       PULONG);
  NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES,
					    PFILE_NETWORK_OPEN_INFORMATION);
  NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
					 ULONG, FILE_INFORMATION_CLASS);
  NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,
					    PVOID, ULONG, PULONG);
  NTSTATUS NTAPI NtQueryInformationThread (HANDLE, THREADINFOCLASS, PVOID,
					   ULONG, PULONG);
  NTSTATUS NTAPI NtQueryInformationToken (HANDLE, TOKEN_INFORMATION_CLASS,
					  PVOID, ULONG, PULONG);
  NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, VOID *,
				ULONG, ULONG *);
  NTSTATUS NTAPI NtQuerySemaphore (HANDLE, SEMAPHORE_INFORMATION_CLASS,
				   PVOID, ULONG, PULONG);
  NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
					   PVOID, ULONG, PULONG);
  NTSTATUS WINAPI NtQuerySystemTime (PLARGE_INTEGER);
  NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
					PSECURITY_DESCRIPTOR, ULONG, PULONG);
  NTSTATUS NTAPI NtQuerySymbolicLinkObject (HANDLE, PUNICODE_STRING, PULONG);
  NTSTATUS NTAPI NtQueryTimer (HANDLE, TIMER_INFORMATION_CLASS, PVOID,
			       ULONG, PULONG);
  NTSTATUS NTAPI NtQueryTimerResolution (PULONG, PULONG, PULONG);
  NTSTATUS NTAPI NtQueryValueKey (HANDLE, PUNICODE_STRING,
				  KEY_VALUE_INFORMATION_CLASS, PVOID, ULONG,
				  PULONG);
  NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
				       PVOID, SIZE_T, PSIZE_T);
  NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, IO_STATUS_BLOCK *,
					       VOID *, ULONG,
					       FS_INFORMATION_CLASS);
  NTSTATUS NTAPI NtReadFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
			     PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
			     PULONG);
  NTSTATUS NTAPI NtRollbackTransaction (HANDLE, BOOLEAN);
  NTSTATUS NTAPI NtSetEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG);
  NTSTATUS NTAPI NtSetEvent (HANDLE, PULONG);
  NTSTATUS NTAPI NtSetInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
				       FILE_INFORMATION_CLASS);
  NTSTATUS NTAPI NtSetInformationThread (HANDLE, THREADINFOCLASS, PVOID, ULONG);
  NTSTATUS NTAPI NtSetInformationToken (HANDLE, TOKEN_INFORMATION_CLASS, PVOID,
					ULONG);
  NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
				      PSECURITY_DESCRIPTOR);
  NTSTATUS NTAPI NtSetTimer (HANDLE, PLARGE_INTEGER, PTIMER_APC_ROUTINE, PVOID,
			     BOOLEAN, LONG, PBOOLEAN);
  NTSTATUS NTAPI NtSetTimerResolution (ULONG, BOOLEAN, PULONG);
  NTSTATUS NTAPI NtSetValueKey (HANDLE, PUNICODE_STRING, ULONG, ULONG, PVOID,
				ULONG);
  NTSTATUS NTAPI NtUnlockFile (HANDLE, PIO_STATUS_BLOCK, PLARGE_INTEGER,
			       PLARGE_INTEGER, ULONG);
  NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, PSIZE_T, ULONG);
  NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
  NTSTATUS NTAPI NtWriteFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
			      PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
			      PULONG);
  NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD (PSECURITY_DESCRIPTOR,
					      PSECURITY_DESCRIPTOR, PULONG);
  VOID NTAPI RtlAcquirePebLock ();
  NTSTATUS NTAPI RtlAddAccessAllowedAce (PACL, ULONG, ACCESS_MASK, PSID);
  NTSTATUS NTAPI RtlAddAccessAllowedAceEx (PACL, ULONG, ULONG, ACCESS_MASK,
					   PSID);
  NTSTATUS NTAPI RtlAddAccessDeniedAce (PACL, ULONG, ACCESS_MASK, PSID);
  NTSTATUS NTAPI RtlAddAccessDeniedAceEx (PACL, ULONG, ULONG, ACCESS_MASK,
					  PSID);
  NTSTATUS NTAPI RtlAddAce (PACL, ULONG, ULONG, PVOID, ULONG);
  PVOID NTAPI RtlAllocateHeap (PVOID, ULONG, SIZE_T);
  NTSTATUS NTAPI RtlAppendUnicodeToString (PUNICODE_STRING, PCWSTR);
  NTSTATUS NTAPI RtlAppendUnicodeStringToString (PUNICODE_STRING,
						 PUNICODE_STRING);
  NTSTATUS NTAPI RtlAnsiStringToUnicodeString (PUNICODE_STRING, PANSI_STRING,
					       BOOLEAN);
  NTSTATUS NTAPI RtlCheckRegistryKey (ULONG, PCWSTR);
  LONG NTAPI RtlCompareUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
				      BOOLEAN);
  NTSTATUS NTAPI RtlConvertSidToUnicodeString (PUNICODE_STRING, PSID, BOOLEAN);
  NTSTATUS NTAPI RtlConvertToAutoInheritSecurityObject (PSECURITY_DESCRIPTOR,
							PSECURITY_DESCRIPTOR,
							PSECURITY_DESCRIPTOR *,
							GUID *, BOOLEAN,
							PGENERIC_MAPPING);
  NTSTATUS NTAPI RtlCopySid (ULONG, PSID, PSID);
  VOID NTAPI RtlCopyUnicodeString (PUNICODE_STRING, PUNICODE_STRING);
  NTSTATUS NTAPI RtlCreateAcl (PACL, ULONG, ULONG);
  PDEBUG_BUFFER NTAPI RtlCreateQueryDebugBuffer (ULONG, BOOLEAN);
  NTSTATUS NTAPI RtlCreateRegistryKey (ULONG, PCWSTR);
  NTSTATUS NTAPI RtlCreateSecurityDescriptor (PSECURITY_DESCRIPTOR, ULONG);
  BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR);
  NTSTATUS NTAPI RtlDeleteSecurityObject (PSECURITY_DESCRIPTOR *);
  NTSTATUS NTAPI RtlDestroyQueryDebugBuffer (PDEBUG_BUFFER);
  NTSTATUS NTAPI RtlDowncaseUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
					   BOOLEAN);
  NTSTATUS NTAPI RtlEnterCriticalSection (PRTL_CRITICAL_SECTION);
  BOOLEAN NTAPI RtlEqualPrefixSid (PSID, PSID);
  BOOLEAN NTAPI RtlEqualSid (PSID, PSID);
  BOOLEAN NTAPI RtlEqualUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
				       BOOLEAN);
  VOID NTAPI RtlFreeAnsiString (PANSI_STRING);
  BOOLEAN NTAPI RtlFreeHeap (HANDLE, ULONG, PVOID);
  VOID NTAPI RtlFreeOemString (POEM_STRING);
  VOID NTAPI RtlFreeUnicodeString (PUNICODE_STRING);
  BOOLEAN NTAPI RtlFirstFreeAce (PACL, PVOID *);
  NTSTATUS NTAPI RtlGetAce (PACL, ULONG, PVOID);
  NTSTATUS NTAPI RtlGetControlSecurityDescriptor (PSECURITY_DESCRIPTOR,
						  PSECURITY_DESCRIPTOR_CONTROL,
						  PULONG);
  HANDLE NTAPI RtlGetCurrentTransaction ();
  NTSTATUS NTAPI RtlGetDaclSecurityDescriptor (PSECURITY_DESCRIPTOR, PBOOLEAN,
					       PACL *, PBOOLEAN);
  NTSTATUS NTAPI RtlGetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID *,
						PBOOLEAN);
  NTSTATUS NTAPI RtlGetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID *,
						PBOOLEAN);
  NTSTATUS NTAPI RtlGetVersion (PRTL_OSVERSIONINFOEXW);
  PSID_IDENTIFIER_AUTHORITY NTAPI RtlIdentifierAuthoritySid (PSID);
  VOID NTAPI RtlInitEmptyUnicodeString (PUNICODE_STRING, PCWSTR, USHORT);
  VOID NTAPI RtlInitAnsiString (PANSI_STRING, PCSTR);
  NTSTATUS NTAPI RtlInitializeSid (PSID, PSID_IDENTIFIER_AUTHORITY, UCHAR);
  VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
  NTSTATUS NTAPI RtlIntegerToUnicodeString (ULONG, ULONG, PUNICODE_STRING);
  ULONG NTAPI RtlIsDosDeviceName_U (PCWSTR);
  NTSTATUS NTAPI RtlLeaveCriticalSection (PRTL_CRITICAL_SECTION);
  ULONG NTAPI RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR);
  ULONG NTAPI RtlLengthSid (PSID);
  ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
  NTSTATUS NTAPI RtlOemStringToUnicodeString (PUNICODE_STRING, POEM_STRING,
					       BOOLEAN);
  BOOLEAN NTAPI RtlPrefixUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
					BOOLEAN);
  NTSTATUS NTAPI RtlQueryProcessDebugInformation (ULONG, ULONG, PDEBUG_BUFFER);
  NTSTATUS NTAPI RtlQueryRegistryValues (ULONG, PCWSTR,
					 PRTL_QUERY_REGISTRY_TABLE, PVOID,
					 PVOID);
  VOID NTAPI RtlReleasePebLock ();
  VOID NTAPI RtlSecondsSince1970ToTime (ULONG, PLARGE_INTEGER);
  NTSTATUS NTAPI RtlSetCurrentDirectory_U (PUNICODE_STRING);
  BOOLEAN NTAPI RtlSetCurrentTransaction (HANDLE);
  NTSTATUS NTAPI RtlSetControlSecurityDescriptor (PSECURITY_DESCRIPTOR,
						  SECURITY_DESCRIPTOR_CONTROL,
						  SECURITY_DESCRIPTOR_CONTROL);
  NTSTATUS NTAPI RtlSetDaclSecurityDescriptor (PSECURITY_DESCRIPTOR, BOOLEAN,
					       PACL, BOOLEAN);
  NTSTATUS NTAPI RtlSetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID,
						BOOLEAN);
  NTSTATUS NTAPI RtlSetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID,
						BOOLEAN);
  PUCHAR NTAPI RtlSubAuthorityCountSid (PSID);
  PULONG NTAPI RtlSubAuthoritySid (PSID, ULONG);
  ULONG NTAPI RtlUnicodeStringToAnsiSize (PUNICODE_STRING);
  NTSTATUS NTAPI RtlUnicodeStringToAnsiString (PANSI_STRING, PUNICODE_STRING,
					       BOOLEAN);
  NTSTATUS NTAPI RtlUnicodeStringToOemString (PANSI_STRING, PUNICODE_STRING,
					      BOOLEAN);
  WCHAR NTAPI RtlUpcaseUnicodeChar (WCHAR);
  NTSTATUS NTAPI RtlUpcaseUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
					 BOOLEAN);
  NTSTATUS NTAPI RtlWriteRegistryValue (ULONG, PCWSTR, PCWSTR, ULONG, PVOID,
					ULONG);

#ifdef __cplusplus
  /* A few Rtl functions are either actually macros, or they just don't
     exist even though they would be a big help.  We implement them here,
     partly as inline functions. */

  /* RtlInitEmptyUnicodeString is defined as a macro in wdm.h, but that file
     is missing entirely in w32api. */
  inline
  VOID NTAPI RtlInitEmptyUnicodeString(PUNICODE_STRING dest, PCWSTR buf,
				       USHORT len)
  {
    dest->Length = 0;
    dest->MaximumLength = len;
    dest->Buffer = (PWSTR) buf;
  }
  /* Like RtlInitEmptyUnicodeString, but initialize Length to len, too.
     This is for instance useful when creating a UNICODE_STRING from an
     NtQueryInformationFile info buffer, where the length of the filename
     is known, but you can't rely on the string being 0-terminated.
     If you know it's 0-terminated, just use RtlInitUnicodeString(). */
  inline
  VOID NTAPI RtlInitCountedUnicodeString (PUNICODE_STRING dest, PCWSTR buf,
					  USHORT len)
  {
    dest->Length = dest->MaximumLength = len;
    dest->Buffer = (PWSTR) buf;
  }
  /* Split path into dirname and basename part.  This function does not
     copy anything!  It just initializes the dirname and basename
     UNICODE_STRINGs so that their Buffer members point to the right spot
     into path's Buffer, and the Length (and MaximumLength) members are set
     to match the dirname part and the basename part.
     Note that dirname's Length is set so that it also includes the trailing
     backslash.  If you don't need it, just subtract sizeof(WCHAR) from
     dirname.Length. */
  inline
  VOID NTAPI RtlSplitUnicodePath (PUNICODE_STRING path, PUNICODE_STRING dirname,
				  PUNICODE_STRING basename)
  {
    USHORT len = path->Length / sizeof (WCHAR);
    while (len > 0 && path->Buffer[--len] != L'\\')
      ;
    ++len;
    if (dirname)
      RtlInitCountedUnicodeString (dirname, path->Buffer, len * sizeof (WCHAR));
    if (basename)
      RtlInitCountedUnicodeString (basename, &path->Buffer[len],
				   path->Length - len * sizeof (WCHAR));
  }
  /* Check if prefix is a prefix of path. */
  inline
  BOOLEAN NTAPI RtlEqualUnicodePathPrefix (PUNICODE_STRING path,
					   PUNICODE_STRING prefix,
					   BOOLEAN caseinsensitive)
  {
    UNICODE_STRING p;

    RtlInitCountedUnicodeString (&p, path->Buffer,
				 prefix->Length < path->Length
				 ? prefix->Length : path->Length);
    return RtlEqualUnicodeString (&p, prefix, caseinsensitive);
  }
  /* Check if suffix is a suffix of path. */
  inline
  BOOL NTAPI RtlEqualUnicodePathSuffix (PUNICODE_STRING path,
					PUNICODE_STRING suffix,
					BOOLEAN caseinsensitive)
  {
    UNICODE_STRING p;

    if (suffix->Length < path->Length)
      RtlInitCountedUnicodeString (&p, (PWCHAR) ((PBYTE) path->Buffer
				       + path->Length - suffix->Length),
				   suffix->Length);
    else
      RtlInitCountedUnicodeString (&p, path->Buffer, path->Length);
    return RtlEqualUnicodeString (&p, suffix, caseinsensitive);
  }
  /* Implemented in strfuncs.cc.  Create a Hex UNICODE_STRING from a given
     64 bit integer value.  If append is TRUE, append the hex string,
     otherwise overwrite dest.  Returns either STATUS_SUCCESS, or
     STATUS_BUFFER_OVERFLOW, if the unicode buffer is too small (hasn't
     room for 16 WCHARs). */
  NTSTATUS NTAPI RtlInt64ToHexUnicodeString (ULONGLONG value,
					     PUNICODE_STRING dest,
					     BOOLEAN append);
  /* Set file attributes.  Don't change file times. */
  inline
  NTSTATUS NTAPI NtSetAttributesFile (HANDLE h, ULONG attr)
  {
    IO_STATUS_BLOCK io;
    FILE_BASIC_INFORMATION fbi;
    fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart =
    fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL;
    fbi.FileAttributes = attr ?: FILE_ATTRIBUTE_NORMAL;
    return NtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
  }

  /* This test for a signalled event is twice as fast as calling
     WaitForSingleObject (event, 0). */
  inline
  BOOL NTAPI IsEventSignalled (HANDLE event)
  {
    EVENT_BASIC_INFORMATION ebi;
    return NT_SUCCESS (NtQueryEvent (event, EventBasicInformation,
				     &ebi, sizeof ebi, NULL))
	   && ebi.SignalState != 0;

  }
}
#endif
