/************************************************************************
*                                                                       *
*   ntdll.h -- This module defines the internal NT APIs and data        *
*       structures that are intended for the use only by internal core  *
*       Windows components.  These APIs and data structures may change  *
*       at any time.                                                    *
*                                                                       *
*   These APIs and data structures are subject to changes from one      *
*       Windows release to another Windows release.  To maintain the    *
*       compatiblity of your application, avoid using these APIs and    *
*       data structures.                                                *
*                                                                       *
*   The appropriate mechanism for accessing the functions defined in    *
*       this header is to use LoadLibrary() for ntdll.dll and           *
*       GetProcAddress() for the particular function.  By using this    *
*       approach, your application will be more resilient to changes    *
*       for these functions between Windows releases.  If a function    *
*       prototype does change, then GetProcAddress() for that function  *
*       might detect the change and fail the function call, which your  *
*       application will be able to detect.  GetProcAddress() may not   *
*       be able to detect all signature changes, thus avoid using these *
*       internal functions.  Instead, your application should use the   *
*       appropriate Win32 function that provides equivalent or similiar *
*       functionality.                                                  *
*                                                                       *
*   Copyright (c) Microsoft Corp. All rights reserved.                  *
*                                                                       *
************************************************************************/

#ifndef _WINTERNL_
#define _WINTERNL_

#include <winapifamily.h>

#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)


#if (_WIN32_WINNT >= 0x0500)

#include <windef.h>
#include <ASSERT.h>

#pragma warning(push)
#pragma warning( disable : 4201 )

#ifdef __cplusplus
extern "C" {
#endif

typedef PVOID *PPVOID;

typedef LARGE_INTEGER TIME;
typedef TIME *PTIME;

//
// ClientId
//
typedef struct __CLIENT_ID_
{
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;

//
// These data structures and type definitions are needed for compilation and
// use of the internal Windows APIs defined in this header.
//

typedef _Return_type_success_(return >= 0) LONG NTSTATUS;

typedef CONST char *PCSZ;

//Строка
typedef struct __STRING_
{
    USHORT Length;
    USHORT MaximumLength;
    PCHAR Buffer;
} STRING;
typedef STRING *PSTRING;

//ANSI-строка
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;
typedef PSTRING PCANSI_STRING;

typedef STRING OEM_STRING;
typedef PSTRING POEM_STRING;
typedef CONST STRING* PCOEM_STRING;

//Unicode-строка
typedef struct __UNICODE_STRING_
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;


//
// These APIs might be need for some of the internal Windows functions,
// defined in this header file.
//

//ANSI-functions
__kernel_entry VOID
NTAPI
RtlCopyString(
    PSTRING DestinationString,
    PSTRING SourceString
    );

__kernel_entry CHAR
NTAPI
RtlUpperChar(
    CHAR Character
    );

__kernel_entry LONG
NTAPI
RtlCompareString(
    PSTRING String1,
    PSTRING String2,
    BOOLEAN CaseInSensitive
    );

__kernel_entry BOOLEAN
NTAPI
RtlEqualString(
    PSTRING String1,
    PSTRING String2,
    BOOLEAN CaseInSensitive
    );

__kernel_entry VOID
NTAPI
RtlUpperString(
    PSTRING DestinationString,
    PSTRING SourceString
    );

__kernel_entry VOID
NTAPI 
RtlFreeAnsiString (
    PANSI_STRING AnsiString
    );

__kernel_entry NTSTATUS
NTAPI
RtlCreateUnicodeString(
    OUT PUNICODE_STRING DestinationString,
    IN PCWSTR SourceString
    );

__kernel_entry VOID
NTAPI 
RtlFreeUnicodeString (
    PUNICODE_STRING UnicodeString
    );

__kernel_entry VOID
NTAPI 
RtlFreeOemString(
    POEM_STRING OemString
    );

__kernel_entry VOID
NTAPI 
RtlInitString (
    PSTRING DestinationString,
    PCSZ SourceString
    );

__kernel_entry VOID
NTAPI 
RtlInitAnsiString (
    PANSI_STRING DestinationString,
    PCSZ SourceString
    );

__kernel_entry VOID
NTAPI 
RtlInitUnicodeString (
    PUNICODE_STRING DestinationString,
    PCWSTR SourceString
    );

//
// NLS String functions
//
__kernel_entry NTSTATUS
NTAPI
RtlAnsiStringToUnicodeString (
    PUNICODE_STRING DestinationString,
    PCANSI_STRING SourceString,
    BOOLEAN AllocateDestinationString
    );

__kernel_entry NTSTATUS
NTAPI
RtlUnicodeStringToAnsiString (
    PANSI_STRING DestinationString,
    PCUNICODE_STRING SourceString,
    BOOLEAN AllocateDestinationString
    );

__kernel_entry NTSTATUS
NTAPI
RtlUnicodeStringToOemString(
    POEM_STRING DestinationString,
    PCUNICODE_STRING SourceString,
    BOOLEAN AllocateDestinationString
    );

//
// Use the Win32 API instead
//     WideCharToMultiByte
//     set CodePage to CP_ACP
//     set cbMultiByte to 0
//
__kernel_entry NTSTATUS
NTAPI
RtlUnicodeToMultiByteSize(
    _Out_ PULONG BytesInMultiByteString,
    _In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString,
    _In_ ULONG BytesInUnicodeString
    );

__kernel_entry LONG
NTAPI
RtlCompareUnicodeString(
    PUNICODE_STRING String1,
    PUNICODE_STRING String2,
    BOOLEAN CaseInSensitive
    );

__kernel_entry BOOLEAN
NTAPI
RtlEqualUnicodeString(
    const UNICODE_STRING *String1,
    const UNICODE_STRING *String2,
    BOOLEAN CaseInSensitive
    );

__kernel_entry BOOLEAN
NTAPI
RtlPrefixUnicodeString(
    IN PUNICODE_STRING String1,
    IN PUNICODE_STRING String2,
    IN BOOLEAN CaseInSensitive
    );

__kernel_entry NTSTATUS
NTAPI
RtlUpcaseUnicodeString(
    PUNICODE_STRING DestinationString,
    PUNICODE_STRING SourceString,
    BOOLEAN AllocateDestinationString
    );

__kernel_entry VOID
NTAPI
RtlCopyUnicodeString(
    PUNICODE_STRING DestinationString,
    PUNICODE_STRING SourceString
    );

__kernel_entry NTSTATUS
NTAPI
RtlAppendUnicodeStringToString(
    PUNICODE_STRING Destination,
    PUNICODE_STRING Source
    );

__kernel_entry NTSTATUS
NTAPI
RtlAppendUnicodeToString(
    PUNICODE_STRING Destination,
    PCWSTR Source
    );

__kernel_entry WCHAR
NTAPI
RtlUpcaseUnicodeChar(
    WCHAR SourceCharacter
    );

__kernel_entry NTSTATUS
NTAPI
RtlUnicodeStringToInteger(
    IN PUNICODE_STRING UnicodeString,
    IN ULONG Base,
    OUT PULONG Result
                         );

//
// Use the C runtime function instead
//     strtol
//
__kernel_entry NTSTATUS
NTAPI
RtlCharToInteger (
    PCSZ String,
    ULONG Base,
    PULONG Value
    );

//
// use the Win32 API instead
//     ConvertSidToStringSid
//
__kernel_entry NTSTATUS
NTAPI
RtlConvertSidToUnicodeString (
    PUNICODE_STRING UnicodeString,
    PSID Sid,
    BOOLEAN AllocateDestinationString
    );

//
// use the CryptoAPIs instead
//     CryptGenRandom
//
__kernel_entry ULONG
NTAPI 
RtlUniform (
    PULONG Seed
    );


// Объект секция

typedef struct __OBJECT_ATTRIBUTES_
{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

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

#define SECTION_QUERY       0x0001
#define SECTION_MAP_WRITE   0x0002
#define SECTION_MAP_READ    0x0004
#define SECTION_MAP_EXECUTE 0x0008
#define SECTION_EXTEND_SIZE 0x0010
#define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\
                            SECTION_MAP_WRITE |      \
                            SECTION_MAP_READ |       \
                            SECTION_MAP_EXECUTE |    \
                            SECTION_EXTEND_SIZE)

NTSYSAPI
NTSTATUS 
NTAPI
NtCreateSection(
	OUT PHANDLE SectionHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN PLARGE_INTEGER MaximumSize OPTIONAL,
	IN ULONG Protect,
	IN ULONG Attributes,
	IN HANDLE FileHandle OPTIONAL 
	);

NTSYSAPI
NTSTATUS
NTAPI
NtOpenSection(
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

#define SEC_ALIGN_BASE_AND_OFFSET 0x40000000

NTSYSAPI
NTSTATUS
NTAPI
NtMapViewOfSection(
    IN HANDLE SectionHandle,
    IN HANDLE ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN ULONG ZeroBits,
    IN SIZE_T CommitSize,
    IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
    IN OUT PSIZE_T ViewSize,
    IN SECTION_INHERIT InheritDisposition,
    IN ULONG AllocationType,
    IN ULONG Protect
    );

NTSYSAPI
NTSTATUS 
NTAPI
NtUnmapViewOfSection(
	IN HANDLE ProcessHandle,
	IN PVOID BaseAddress
	);

typedef enum _SECTIONINFOCLASS {
	SectionBasicInformation,
	SectionImageInformation
} SECTIONINFOCLASS;

typedef struct __SECTION_BASIC_INFORMATION_
{
	ULONG Reserved;
	ULONG Attributes;
	LARGE_INTEGER MaximumSize;
} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;

typedef struct __SECTION_IMAGE_INFORMATION_
{
	ULONG EntryPoint;               // 0000
	ULONG Unknown0;                 // 0004
	ULONG ReservedStackSize;        // 0008
	ULONG CommittedStackSize;       // 000C
	ULONG Subsystem;                // 0010
	USHORT SubsystemVersionMinor;   // 0014
	USHORT SubsystemVersionMajor;   // 0016
	ULONG Unknown1;                 // 0018
	ULONG Characteristics;          // 001C
	ULONG Machine;                  // 0020
	ULONG Unknown2;                 // 0024
	ULONG Unknown3;                 // 0028
	ULONG Unknown4;                 // 002C
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;   // 0030

NTSYSAPI
NTSTATUS
NTAPI
NtQuerySection(
	IN HANDLE SectionHandle,
	IN SECTIONINFOCLASS SectionInformationClass,
    OUT PVOID SectionInformation,
    IN ULONG SectionInformationLength,
    OUT PULONG ReturnLength OPTIONAL
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtExtendSection(
	IN HANDLE SectionHandle,
	IN PLARGE_INTEGER NewSize 
	);


//Объект процесс


//
// Thread priority
//

typedef LONG KPRIORITY;

typedef struct __IO_STATUS_BLOCK_
{
    union {
        NTSTATUS Status;
        PVOID Pointer;
    } DUMMYUNIONNAME;

    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef
VOID
(NTAPI *PIO_APC_ROUTINE) (
    IN PVOID ApcContext,
    IN PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG Reserved
    );

//
// Блок окружения процесса
//
//
// The PEB_LDR_DATA, LDR_DATA_TABLE_ENTRY, RTL_USER_PROCESS_PARAMETERS, PEB
// and TEB structures are subject to changes between Windows releases; thus,
// the field offsets and reserved fields may change. The reserved fields are
// reserved for use only by the Windows operating systems. Do not assume a
// maximum size for these structures.
//
// Instead of using the InMemoryOrderModuleList field of the
//     LDR_DATA_TABLE_ENTRY structure, use the Win32 API EnumProcessModules
//
// Instead of using the IsBeingDebugged field of the PEB structure, use the
//     Win32 APIs IsDebuggerPresent or CheckRemoteDebuggerPresent
//
// Instead of using the SessionId field of the PEB structure, use the Win32
//     APIs GetCurrentProcessId and ProcessIdToSessionId
//
// Instead of using the Tls fields of the TEB structure, use the Win32 APIs
//     TlsAlloc, TlsGetValue, TlsSetValue and TlsFree
//
// Instead of using the ReservedForOle field, use the COM API
//     CoGetContextToken
//
// Sample x86 assembly code that gets the SessionId (subject to change
//     between Windows releases, use the Win32 APIs to make your application
//     resilient to changes)
//     mov     eax,fs:[00000018]
//     mov     eax,[eax+0x30]
//     mov     eax,[eax+0x1d4]
//

//
// N.B. Fields marked as reserved do not necessarily reflect the structure
//      of the real struct. They may simply guarantee that the offets of 
//      the exposed fields are correct. When code matches this pattern,
//
//          TYPE1 ExposedField1;
//          BYTE ReservedBytes[b];
//          PVOID ReservedPtrs[p];
//          TYPE2 ExposedField2;
//
//      or that pattern with ReservedBytes and ReservedPtrs swapped, it is
//      likely that 'b' and 'p' are derived from the following system:
//
//          GapThirtyTwo = 4p + b
//          GapSixtyFour = 8p + b
//      
//      where GapThirtyTwo is the number of bytes between the two exposed
//      fields in the 32-bit version of the real struct and GapSixtyFour
//      is the number of bytes between the two exposed fields in the 64-bit
//      version of the real struct.
//
//      Also note that such code must take into account the alignment of
//      the ReservedPtrs field.
//

// symbols
typedef struct __LDR_DATA_TABLE_ENTRY_
{
    LIST_ENTRY  InMemoryEntryLinks;
    LIST_ENTRY  InMemoryOrderLinks;
    PVOID       Reserved2[2];
    PVOID       DllBase;
    PVOID       pStartRoutine;
    DWORD_PTR   dwImageSize;
    UNICODE_STRING FullDllName;
    UNICODE_STRING ShortDllName;
    PVOID       Reserved5[3];
    union {
        ULONG CheckSum;
        PVOID Reserved6;
    } DUMMYUNIONNAME;
    ULONG       TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct __PEB_LDR_DATA_
{
    ULONG Length;
    BOOLEAN Initialized;
    HANDLE SsHandle;
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID EntryInProgress;
    BOOLEAN ShutdownInProgress;
    HANDLE ShutdownThreadId;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _INITIAL_TEB
{
    struct
    {
        PVOID OldStackBase;
        PVOID OldStackLimit;
    } OldInitialTeb;
    PVOID StackBase;
    PVOID StackLimit;
    PVOID StackAllocationBase;
} INITIAL_TEB, *PINITIAL_TEB;

typedef struct PROC_THREAD_NATIVE_ATTRIBUTE {
    DWORD NativeAttributeId;
    DWORD DataSize;
    PVOID DataPointer;
    DWORD OutLengthPointer;
}*PPROC_THREAD_NATIVE_ATTRIBUTE;

typedef struct PROC_THREAD_NATIVE_ATTRIBUTE_LIST {
    DWORD Length;
    PROC_THREAD_NATIVE_ATTRIBUTE Items[8];
    //the variable amount, CreateProcessInternalW reserves a place for several tens elements 
}*PPROC_THREAD_NATIVE_ATTRIBUTE_LIST;

typedef struct _RTL_DRIVE_LETTER_CURDIR {
    USHORT Flags;
    USHORT Length;
    ULONG TimeStamp;
    UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;

//
// Блок параметров процесса
//

//если флаг установлен, то все адреса абсолютные
#define PPFLAG_NORMALIZED 0x1L
#define PPFLAG_PSAPI      0x2L

typedef struct __RTL_USER_PROCESS_PARAMETERS_
{
    ULONG AllocationSize;
    ULONG ActualSize;
    ULONG Flags; // PPFLAG_xxx
    ULONG dwDebug;
    PVOID ConsoleHandle;                 // 0010 = 00000024
    ULONG ConsoleFlags;                  // 0014 = 00000000
    HANDLE InputHandle;
    HANDLE OutputHandle;
    HANDLE ErrorHandle;
    UNICODE_STRING CurrentDirectory;
    HANDLE CurrentDir;
    UNICODE_STRING SearchPaths;
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
    PVOID EnvironmentBlock;
    ULONG dwX;
    ULONG dwY;
    ULONG dwXSize;
    ULONG dwYSize;
    ULONG dwXCountChars;
    ULONG dwYCountChars;
    ULONG dwFillAttribute;
    ULONG dwFlags;
    ULONG dwShowWindow;
    UNICODE_STRING usConsoleTitle;
    UNICODE_STRING usDesktop;
    UNICODE_STRING usShellInfo;          // 0080 = ""
    UNICODE_STRING usRuntimeData;        // 0088 = {00000000,00000000}
    RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory [0x20]; // 0090 = {0}
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef
VOID
(NTAPI *PPS_POST_PROCESS_INIT_ROUTINE) (
    VOID
    );

#define GDI_HANDLE_BUFFER_SIZE32 34
#define GDI_HANDLE_BUFFER_SIZE64 60
#ifndef WIN64
#define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32
#else
#define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE64
#endif
typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE];
typedef ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32];
typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64];

// symbols
typedef struct __PEB_
{
    BOOLEAN InheritedAddressSpace;
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;
    union
    {
        BOOLEAN BitField;
        struct
        {
            BOOLEAN ImageUsesLargePages : 1;
            BOOLEAN IsProtectedProcess : 1;
            BOOLEAN IsLegacyProcess : 1;
            BOOLEAN IsImageDynamicallyRelocated : 1;
            BOOLEAN SkipPatchingUser32Forwarders : 1;
            BOOLEAN IsPackagedProcess : 1;
            BOOLEAN IsAppContainer : 1;
            BOOLEAN SpareBits : 1;
        };
    };
    HANDLE Mutant;
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PVOID SubSystemData;
    PVOID ProcessHeap;
    PRTL_CRITICAL_SECTION FastPebLock;
    PVOID AtlThunkSListPtr;
    PVOID IFEOKey;
    union
    {
        ULONG CrossProcessFlags;
        struct
        {
            ULONG ProcessInJob : 1;
            ULONG ProcessInitializing : 1;
            ULONG ProcessUsingVEH : 1;
            ULONG ProcessUsingVCH : 1;
            ULONG ProcessUsingFTH : 1;
            ULONG ReservedBits0 : 27;
        };
        ULONG EnvironmentUpdateCount;
    };
    union
    {
        PVOID KernelCallbackTable;
        PVOID UserSharedInfoPtr;
    };
    ULONG SystemReserved[1];
    ULONG AtlThunkSListPtr32;
    PVOID ApiSetMap;
    ULONG TlsExpansionCounter;
    PVOID TlsBitmap;
    ULONG TlsBitmapBits[2];
    PVOID ReadOnlySharedMemoryBase;
    PVOID HotpatchInformation;
    PVOID* ReadOnlyStaticServerData;
    PVOID AnsiCodePageData;
    PVOID OemCodePageData;
    PVOID UnicodeCaseTableData;
    ULONG NumberOfProcessors;
    ULONG NtGlobalFlag;
    LARGE_INTEGER CriticalSectionTimeout;
    SIZE_T HeapSegmentReserve;
    SIZE_T HeapSegmentCommit;
    SIZE_T HeapDeCommitTotalFreeThreshold;
    SIZE_T HeapDeCommitFreeBlockThreshold;
    ULONG NumberOfHeaps;
    ULONG MaximumNumberOfHeaps;
    PVOID* ProcessHeaps;
    PVOID GdiSharedHandleTable;
    PVOID ProcessStarterHelper;
    ULONG GdiDCAttributeList;
    PRTL_CRITICAL_SECTION LoaderLock;
    ULONG OSMajorVersion;
    ULONG OSMinorVersion;
    USHORT OSBuildNumber;
    USHORT OSCSDVersion;
    ULONG OSPlatformId;
    ULONG ImageSubsystem;
    ULONG ImageSubsystemMajorVersion;
    ULONG ImageSubsystemMinorVersion;
    ULONG_PTR ImageProcessAffinityMask;
    GDI_HANDLE_BUFFER GdiHandleBuffer;
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    PVOID TlsExpansionBitmap;
    ULONG TlsExpansionBitmapBits[32];
    ULONG SessionId;
    ULARGE_INTEGER AppCompatFlags;
    ULARGE_INTEGER AppCompatFlagsUser;
    PVOID pShimData;
    PVOID AppCompatInfo;
    UNICODE_STRING CSDVersion;
    PVOID ActivationContextData;
    PVOID ProcessAssemblyStorageMap;
    PVOID SystemDefaultActivationContextData;
    PVOID SystemAssemblyStorageMap;
    SIZE_T MinimumStackCommit;
    PVOID* FlsCallback;
    LIST_ENTRY FlsListHead;
    PVOID FlsBitmap;
    ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)];
    ULONG FlsHighIndex;
    PVOID WerRegistrationData;
    PVOID WerShipAssertPtr;
    PVOID pContextData;
    PVOID pImageHeaderHash;
    union
    {
        ULONG TracingFlags;
        struct
        {
            ULONG HeapTracingEnabled : 1;
            ULONG CritSecTracingEnabled : 1;
            ULONG LibLoaderTracingEnabled : 1;
            ULONG SpareTracingBits : 29;
        };
    };
    ULONGLONG CsrServerReadOnlySharedMemoryBase;
} PEB, *PPEB;

//
// Process Information Classes
//
typedef enum _PROCESSINFOCLASS {
    ProcessBasicInformation,
    ProcessQuotaLimits,
    ProcessIoCounters,
    ProcessVmCounters,
    ProcessTimes,
    ProcessBasePriority,
    ProcessRaisePriority,
    ProcessDebugPort,
    ProcessExceptionPort,
    ProcessAccessToken,
    ProcessLdtInformation,
    ProcessLdtSize,
    ProcessDefaultHardErrorMode,
    ProcessIoPortHandlers,          // Note: this is kernel mode only
    ProcessPooledUsageAndLimits,
    ProcessWorkingSetWatch,
    ProcessUserModeIOPL,
    ProcessEnableAlignmentFaultFixup,
    ProcessPriorityClass,
    ProcessWx86Information,
    ProcessHandleCount,
    ProcessAffinityMask,
    ProcessPriorityBoost,
    ProcessDeviceMap,
    ProcessSessionInformation,
    ProcessForegroundInformation,
    ProcessWow64Information,
    ProcessImageFileName,
    ProcessLUIDDeviceMapsEnabled,
    ProcessBreakOnTermination,
    ProcessDebugObjectHandle,
    ProcessDebugFlags,
    ProcessHandleTracing,
    ProcessIoPriority,
    ProcessExecuteFlags,
    ProcessTlsInformation,
    ProcessCookie,
    ProcessImageInformation,
    ProcessCycleTime,
    ProcessPagePriority,
    ProcessInstrumentationCallback,
    ProcessThreadStackAllocation,
    ProcessWorkingSetWatchEx,
    ProcessImageFileNameWin32,
    ProcessImageFileMapping,
    ProcessAffinityUpdateMode,
    ProcessMemoryAllocationMode,
    ProcessGroupInformation,
    ProcessTokenVirtualizationEnabled,
    ProcessOwnerInformation,
    ProcessWindowInformation,
    ProcessHandleInformation,
    ProcessMitigationPolicy,
    ProcessDynamicFunctionTableInformation,
    ProcessHandleCheckingMode,
    ProcessKeepAliveCount,
    ProcessRevokeFileHandles,
    ProcessWorkingSetControl,
    ProcessHandleTable,
    ProcessCheckStackExtentsMode,
    ProcessCommandLineInformation,
    ProcessProtectionInformation,
    MaxProcessInfoClass             // MaxProcessInfoClass should always be the last enum
} PROCESSINFOCLASS;

#define NtCurrentProcess() ((HANDLE)-1)


//
// Process Information Structures
//

//
// Working set page priority information.
// Used with ProcessPagePriority and ThreadPagePriority
//
typedef struct __PAGE_PRIORITY_INFORMATION_
{
    ULONG PagePriority;
} PAGE_PRIORITY_INFORMATION, *PPAGE_PRIORITY_INFORMATION;

//
// PageFaultHistory Information
//  NtQueryInformationProcess using ProcessWorkingSetWatch
//
typedef struct __PROCESS_WS_WATCH_INFORMATION_
{
    PVOID FaultingPc;
    PVOID FaultingVa;
} PROCESS_WS_WATCH_INFORMATION, *PPROCESS_WS_WATCH_INFORMATION;

//
// Basic and Extended Basic Process Information
//  NtQueryInformationProcess using ProcessBasicInformation
//
typedef struct __PROCESS_BASIC_INFORMATION_
{
    NTSTATUS ExitStatus;
    PPEB PebBaseAddress;
    ULONG_PTR AffinityMask;
    KPRIORITY BasePriority;
    ULONG_PTR UniqueProcessId;
    ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

typedef struct __PROCESS_EXTENDED_BASIC_INFORMATION_
{
    SIZE_T Size;    // Must be set to structure size on input
    PROCESS_BASIC_INFORMATION BasicInfo;
    union {
        ULONG Flags;
        struct {
            ULONG IsProtectedProcess : 1;
            ULONG IsWow64Process : 1;
            ULONG IsProcessDeleting : 1;
            ULONG IsCrossSessionCreate : 1;
            ULONG IsFrozen : 1;
            ULONG IsBackground : 1;
            ULONG IsStronglyNamed : 1;
            ULONG SpareBits : 25;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;
} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION;


//
// Process Device Map information
//  NtQueryInformationProcess using ProcessDeviceMap
//  NtSetInformationProcess using ProcessDeviceMap
//
typedef struct __PROCESS_DEVICEMAP_INFORMATION_
{
    union {
        struct {
            HANDLE DirectoryHandle;
        } Set;
        struct {
            ULONG DriveMap;
            UCHAR DriveType[32];
        } Query;
    } DUMMYUNIONNAME;
} PROCESS_DEVICEMAP_INFORMATION, *PPROCESS_DEVICEMAP_INFORMATION;

typedef struct __PROCESS_DEVICEMAP_INFORMATION_EX_
{
    union {
        struct {
            HANDLE DirectoryHandle;
        } Set;
        struct {
            ULONG DriveMap;
            UCHAR DriveType[32];
        } Query;
    } DUMMYUNIONNAME;
    ULONG Flags;    // specifies that the query type
} PROCESS_DEVICEMAP_INFORMATION_EX, *PPROCESS_DEVICEMAP_INFORMATION_EX;

//
// PROCESS_DEVICEMAP_INFORMATION_EX flags
//
#define PROCESS_LUID_DOSDEVICES_ONLY 0x00000001

//
// Multi-User Session specific Process Information
//  NtQueryInformationProcess using ProcessSessionInformation
//
typedef struct __PROCESS_SESSION_INFORMATION_
{
    ULONG SessionId;
} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION;

typedef struct __PROCESS_HANDLE_TRACING_ENABLE_
{
    ULONG Flags;
} PROCESS_HANDLE_TRACING_ENABLE, *PPROCESS_HANDLE_TRACING_ENABLE;

typedef struct __PROCESS_HANDLE_TRACING_ENABLE_EX_
{
    ULONG Flags;
    ULONG TotalSlots;
} PROCESS_HANDLE_TRACING_ENABLE_EX, *PPROCESS_HANDLE_TRACING_ENABLE_EX;

#define PROCESS_HANDLE_EXCEPTIONS_ENABLED 0x00000001ul

#define PROCESS_HANDLE_TRACING_MAX_STACKS 16

typedef struct __PROCESS_HANDLE_TRACING_ENTRY_
{
    HANDLE Handle;
    CLIENT_ID ClientId;
    ULONG Type;
    PVOID Stacks[PROCESS_HANDLE_TRACING_MAX_STACKS];
} PROCESS_HANDLE_TRACING_ENTRY, *PPROCESS_HANDLE_TRACING_ENTRY;

typedef struct __PROCESS_HANDLE_TRACING_QUERY_
{
    HANDLE Handle;
    ULONG  TotalTraces;
    PROCESS_HANDLE_TRACING_ENTRY HandleTrace[1];
} PROCESS_HANDLE_TRACING_QUERY, *PPROCESS_HANDLE_TRACING_QUERY;


//
// Process Virtual Memory Counters
//  NtQueryInformationProcess using ProcessVmCounters
//

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;
typedef VM_COUNTERS *PVM_COUNTERS;

typedef struct __VM_COUNTERS_EX_
{
    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;
    SIZE_T PrivateUsage;
} VM_COUNTERS_EX;

typedef VM_COUNTERS_EX *PVM_COUNTERS_EX;

//
// Process KeepAlive Count
// NtQueryInformationProcess using ProcessKeepAliveCount
//
typedef struct __PROCESS_KEEPALIVE_COUNT_INFORMATION_
{
    ULONG WakeCount;
    ULONG NoWakeCount;
} PROCESS_KEEPALIVE_COUNT_INFORMATION, *PPROCESS_KEEPALIVE_COUNT_INFORMATION;

//
// Process File Handle Revocation
// NtSetInformationProcess using ProcessRevokeFileHandles
//
typedef struct __PROCESS_REVOKE_FILE_HANDLES_INFORMATION_
{
    UNICODE_STRING TargetDevicePath;
} PROCESS_REVOKE_FILE_HANDLES_INFORMATION, *PPROCESS_REVOKE_FILE_HANDLES_INFORMATION;


//
// Process Image File Name
// NtSetInformationProcess using ProcessImageFileName or ProcessImageFileNameWin32
//
// ProcessInformationLength = sizeof(PROCESS_IMAGE_FILE_NAME_INFORMATION) + BufferLength
//
typedef struct __PROCESS_IMAGE_FILE_NAME_INFORMATION_
{
    UNICODE_STRING usProcessImageFileName;
} PROCESS_IMAGE_FILE_NAME_INFORMATION, *PPROCESS_IMAGE_FILE_NAME_INFORMATION;
//
// Process Pooled Quota Usage and Limits
//  NtQueryInformationProcess using ProcessPooledUsageAndLimits
//
typedef struct __POOLED_USAGE_AND_LIMITS_
{
    SIZE_T PeakPagedPoolUsage;
    SIZE_T PagedPoolUsage;
    SIZE_T PagedPoolLimit;
    SIZE_T PeakNonPagedPoolUsage;
    SIZE_T NonPagedPoolUsage;
    SIZE_T NonPagedPoolLimit;
    SIZE_T PeakPagefileUsage;
    SIZE_T PagefileUsage;
    SIZE_T PagefileLimit;
} POOLED_USAGE_AND_LIMITS;
typedef POOLED_USAGE_AND_LIMITS *PPOOLED_USAGE_AND_LIMITS;

//
// Process Security Context Information
//  NtSetInformationProcess using ProcessAccessToken
// PROCESS_SET_ACCESS_TOKEN access to the process is needed
// to use this info level.
//
typedef struct __PROCESS_ACCESS_TOKEN_
{

    //
    // Handle to Primary token to assign to the process.
    // TOKEN_ASSIGN_PRIMARY access to this token is needed.
    //

    HANDLE Token;

    //
    // Handle to the initial thread of the process.
    // A process's access token can only be changed if the process has
    // no threads or a single thread that has not yet begun execution.
    //
    // N.B. This field is unused.
    //

    HANDLE Thread;

} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN;

//
// Process Exception Port Information
//  NtSetInformationProcess using ProcessExceptionPort
// PROCESS_SET_PORT access to the process is needed
// to use this info level.
//
#define PROCESS_EXCEPTION_PORT_ALL_STATE_BITS     0x00000003UL
#define PROCESS_EXCEPTION_PORT_ALL_STATE_FLAGS    ((ULONG_PTR)((1UL << PROCESS_EXCEPTION_PORT_ALL_STATE_BITS) - 1))

typedef struct __PROCESS_EXCEPTION_PORT_
{

    //
    // Handle to the exception port. No particular access required.
    //

    _In_ HANDLE ExceptionPortHandle;

    //
    // Miscellaneous state flags to be cached along with the exception
    // port in the kernel.
    //

    _Inout_ ULONG StateFlags;

} PROCESS_EXCEPTION_PORT, *PPROCESS_EXCEPTION_PORT;

//
// Process/Thread System and User Time
//  NtQueryInformationProcess using ProcessTimes
//  NtQueryInformationThread using ThreadTimes
//
typedef struct __KERNEL_USER_TIMES_
{
    LARGE_INTEGER CreateTime;
    LARGE_INTEGER ExitTime;
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES;
typedef KERNEL_USER_TIMES *PKERNEL_USER_TIMES;


NTSYSAPI
PPEB
NTAPI
RtlGetCurrentPeb();

NTSYSAPI                                            
NTSTATUS
NTAPI
RtlCreateProcessParameters(
	OUT PRTL_USER_PROCESS_PARAMETERS* ProcessParameters,
	IN PUNICODE_STRING ApplicationName,
	IN PUNICODE_STRING SearchPaths OPTIONAL,
	IN PUNICODE_STRING CurrentDirectory OPTIONAL,
	IN PUNICODE_STRING CommandLine OPTIONAL,
	IN PVOID EnvironmentBlock OPTIONAL,
	IN PUNICODE_STRING pusConsoleTitle OPTIONAL,
	IN PUNICODE_STRING pusDesktop OPTIONAL,
    IN PUNICODE_STRING ShellInfo OPTIONAL,
    IN PUNICODE_STRING RuntimeData OPTIONAL
	);

NTSYSAPI                                            
PRTL_USER_PROCESS_PARAMETERS 
NTAPI
RtlNormalizeProcessParams(
	IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters
	);

NTSYSAPI                                            
NTSTATUS
NTAPI
RtlDestroyProcessParameters(
	IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters
	);

NTSYSAPI                                            
PRTL_USER_PROCESS_PARAMETERS
NTAPI
RtlDeNormalizeProcessParams(
	IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters
	);

NTSYSAPI                                            
PRTL_USER_PROCESS_PARAMETERS
NTAPI
RtlNormalizeProcessParams(
	IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters
	);

typedef struct __RTL_PROCESS_INFORMATION_
{
	ULONG Size;
	//
	// PROCESS_INFORMATION
	//
	HANDLE ProcessHandle;
	HANDLE ThreadHandle;
	CLIENT_ID ClientId;
	//
	SECTION_IMAGE_INFORMATION SectionImageInfo;
} RTL_PROCESS_INFORMATION, *PRTL_PROCESS_INFORMATION;

NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserProcess(
	IN PUNICODE_STRING FileName,
	IN ULONG FileObjectAttributes,
	IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
	IN PVOID ProcessSecurityDescriptor OPTIONAL,
	IN PVOID ThreadSecurityDescriptor OPTIONAL,
	IN HANDLE ParentProcess OPTIONAL,
	IN BOOLEAN InheritHandles,
	IN HANDLE DebugPort OPTIONAL,
	IN HANDLE ExceptionPort OPTIONAL,
	OUT PRTL_PROCESS_INFORMATION ProcessInfo
	);

// windows-internals-book:"Chapter 5"
typedef enum _PS_CREATE_STATE
{
    PsCreateInitialState,
    PsCreateFailOnFileOpen,
    PsCreateFailOnSectionCreate,
    PsCreateFailExeFormat,
    PsCreateFailMachineMismatch,
    PsCreateFailExeName, // Debugger specified
    PsCreateSuccess,
    PsCreateMaximumStates
} PS_CREATE_STATE;

typedef struct _PS_CREATE_INFO
{
    SIZE_T Size;
    PS_CREATE_STATE State;
    union
    {
        // PsCreateInitialState
        struct
        {
            union
            {
                ULONG InitFlags;
                struct
                {
                    UCHAR WriteOutputOnExit : 1;
                    UCHAR DetectManifest : 1;
                    UCHAR SpareBits1 : 6;
                    UCHAR IFEOKeyState : 2;
                    UCHAR SpareBits2 : 6;
                    USHORT ProhibitedImageCharacteristics : 16;
                };
            };
            ACCESS_MASK AdditionalFileAccess;
        } InitState;
        // PsCreateFailOnSectionCreate
        struct
        {
            HANDLE FileHandle;
        } FailSection;
        // PsCreateFailExeName
        struct
        {
            HANDLE IFEOKey;
        } ExeName;
        // PsCreateSuccess
        struct
        {
            union
            {
                ULONG OutputFlags;
                struct
                {
                    UCHAR ProtectedProcess : 1;
                    UCHAR AddressSpaceOverride : 1;
                    UCHAR DevOverrideEnabled : 1; // from Image File Execution Options
                    UCHAR ManifestDetected : 1;
                    UCHAR SpareBits1 : 4;
                    UCHAR SpareBits2 : 8;
                    USHORT SpareBits3 : 16;
                };
            };
            HANDLE FileHandle;
            HANDLE SectionHandle;
            ULONGLONG UserProcessParametersNative;
            ULONG UserProcessParametersWow64;
            ULONG CurrentParameterFlags;
            ULONGLONG PebAddressNative;
            ULONG PebAddressWow64;
            ULONGLONG ManifestAddress;
            ULONG ManifestSize;
        } SuccessState;
    };
} PS_CREATE_INFO, *PPS_CREATE_INFO;

typedef struct _PS_ATTRIBUTE
{
    ULONG Attribute;
    SIZE_T Size;
    union
    {
        ULONG Value;
        PVOID ValuePtr;
    };
    PSIZE_T ReturnLength;
} PS_ATTRIBUTE, *PPS_ATTRIBUTE;

typedef struct _PS_ATTRIBUTE_LIST
{
    SIZE_T TotalLength;
    PS_ATTRIBUTE Attributes[1];
} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;

#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004
#define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008
#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010

// Extended PROCESS_CREATE_FLAGS_*
// begin_rev
#define PROCESS_CREATE_FLAGS_LARGE_PAGE_SYSTEM_DLL 0x00000020
#define PROCESS_CREATE_FLAGS_PROTECTED_PROCESS 0x00000040
#define PROCESS_CREATE_FLAGS_CREATE_SESSION 0x00000080 // ?
#define PROCESS_CREATE_FLAGS_INHERIT_FROM_PARENT 0x00000100
// end_rev

NTSYSCALLAPI
NTSTATUS
NTAPI
NtCreateUserProcess(
    __out PHANDLE ProcessHandle,
    __out PHANDLE ThreadHandle,
    __in ACCESS_MASK ProcessDesiredAccess,
    __in ACCESS_MASK ThreadDesiredAccess,
    __in_opt POBJECT_ATTRIBUTES ProcessObjectAttributes,
    __in_opt POBJECT_ATTRIBUTES ThreadObjectAttributes,
    __in ULONG ProcessFlags, // PROCESS_CREATE_FLAGS_*
    __in ULONG ThreadFlags,  // THREAD_CREATE_FLAGS_*
    __in_opt PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
    __inout PPS_CREATE_INFO CreateInfo,
    __in_opt PPS_ATTRIBUTE_LIST AttributeList
    );

NTSYSAPI                                            
NTSTATUS                                            
NTAPI                                               
NtCreateProcess(
	OUT PHANDLE ProcessHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes,
	IN HANDLE ParentProcess,
	IN BOOLEAN InheritHandles,
	IN HANDLE SectionHandle,
	IN HANDLE DebugPort OPTIONAL,
	IN HANDLE ExceptionPort OPTIONAL
	);

NTSYSAPI
VOID
NTAPI
RtlAcquirePebLock(
	);

NTSYSAPI
VOID
NTAPI
RtlReleasePebLock(
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtTerminateProcess(
	IN HANDLE ProcessHandle,
	IN ULONG  ProcessExitCode
	);

NTSYSAPI
DECLSPEC_NORETURN
VOID
NTAPI
RtlExitUserProcess(
    _In_ DWORD dwExitCode
    );

__kernel_entry NTSYSCALLAPI
NTSTATUS
NTAPI
NtOpenProcess(
    _Out_ PHANDLE ProcessHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_ POBJECT_ATTRIBUTES ObjectAttributes,
    _In_opt_ PCLIENT_ID ClientId
    );

__kernel_entry NTSTATUS
NTAPI 
NtQueryInformationProcess (
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );

NTSYSCALLAPI
NTSTATUS
NTAPI
NtSetInformationProcess(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    IN PVOID ProcessInformation,
    IN ULONG ProcessInformationLength
                       );



// Объект поток

//
// Блок окружения потока
//


#define GDI_BATCH_BUFFER_SIZE 310
typedef struct _GDI_TEB_BATCH
{
    ULONG Offset;
    ULONG_PTR HDC;
    ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
} GDI_TEB_BATCH, *PGDI_TEB_BATCH;

typedef struct _TEB_ACTIVE_FRAME_CONTEXT
{
    ULONG Flags;
    PSTR FrameName;
} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT;

typedef struct _TEB_ACTIVE_FRAME
{
    ULONG Flags;
    struct _TEB_ACTIVE_FRAME *Previous;
    PTEB_ACTIVE_FRAME_CONTEXT Context;
} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME;

typedef struct __TEB_
{
    NT_TIB NtTib;
    PVOID EnvironmentPointer;
    CLIENT_ID ClientId;
    PVOID ActiveRpcHandle;
    PVOID ThreadLocalStoragePointer;
    PPEB ProcessEnvironmentBlock;
    ULONG LastErrorValue;
    ULONG CountOfOwnedCriticalSections;
    PVOID CsrClientThread;
    PVOID Win32ThreadInfo;
    ULONG User32Reserved[26];
    ULONG UserReserved[5];
    PVOID WOW32Reserved;
    LCID CurrentLocale;
    ULONG FpSoftwareStatusRegister;
    PVOID SystemReserved1[54];
    NTSTATUS ExceptionCode;
    PVOID ActivationContextStackPointer;
#ifdef _M_X64
    UCHAR SpareBytes[24];
#else
    UCHAR SpareBytes[36];
#endif
    ULONG TxFsContext;
    GDI_TEB_BATCH GdiTebBatch;
    CLIENT_ID RealClientId;
    HANDLE GdiCachedProcessHandle;
    ULONG GdiClientPID;
    ULONG GdiClientTID;
    PVOID GdiThreadLocalInfo;
    ULONG_PTR Win32ClientInfo[62];
    PVOID glDispatchTable[233];
    ULONG_PTR glReserved1[29];
    PVOID glReserved2;
    PVOID glSectionInfo;
    PVOID glSection;
    PVOID glTable;
    PVOID glCurrentRC;
    PVOID glContext;
    NTSTATUS LastStatusValue;
    UNICODE_STRING StaticUnicodeString;
    WCHAR StaticUnicodeBuffer[261];
    PVOID DeallocationStack;
    PVOID TlsSlots[64];
    LIST_ENTRY TlsLinks;
    PVOID Vdm;
    PVOID ReservedForNtRpc;
    PVOID DbgSsReserved[2];
    ULONG HardErrorMode;
#ifdef _M_X64
    PVOID Instrumentation[11];
#else
    PVOID Instrumentation[9];
#endif
    GUID ActivityId;
    PVOID SubProcessTag;
    PVOID EtwLocalData;
    PVOID EtwTraceData;
    PVOID WinSockData;
    ULONG GdiBatchCount;
    union
    {
        PROCESSOR_NUMBER CurrentIdealProcessor;
        ULONG IdealProcessorValue;
        struct
        {
            UCHAR ReservedPad0;
            UCHAR ReservedPad1;
            UCHAR ReservedPad2;
            UCHAR IdealProcessor;
        };
    };
    ULONG GuaranteedStackBytes;
    PVOID ReservedForPerf;
    PVOID ReservedForOle;
    ULONG WaitingOnLoaderLock;
    PVOID SavedPriorityState;
    ULONG_PTR SoftPatchPtr1;
    PVOID ThreadPoolData;
    PPVOID TlsExpansionSlots;
#ifdef _M_X64
    PVOID DeallocationBStore;
    PVOID BStoreLimit;
#endif
    ULONG MuiGeneration;
    ULONG IsImpersonating;
    PVOID NlsCache;
    PVOID pShimData;
    ULONG HeapVirtualAffinity;
    HANDLE CurrentTransactionHandle;
    PTEB_ACTIVE_FRAME ActiveFrame;
    PVOID FlsData;
    PVOID PreferredLanguages;
    PVOID UserPrefLanguages;
    PVOID MergedPrefLanguages;
    ULONG MuiImpersonation;
    union
    {
        USHORT CrossTebFlags;
        USHORT SpareCrossTebBits : 16;
    };
    union
    {
        USHORT SameTebFlags;
        struct
        {
            USHORT SafeThunkCall : 1;
            USHORT InDebugPrint : 1;
            USHORT HasFiberData : 1;
            USHORT SkipThreadAttach : 1;
            USHORT WerInShipAssertCode : 1;
            USHORT RanProcessInit : 1;
            USHORT ClonedThread : 1;
            USHORT SuppressDebugMsg : 1;
            USHORT DisableUserStackWalk : 1;
            USHORT RtlExceptionAttached : 1;
            USHORT InitialThread : 1;
            USHORT SessionAware : 1;
            USHORT SpareSameTebBits : 4;
        };
    };
    PVOID TxnScopeEnterCallback;
    PVOID TxnScopeExitCallback;
    PVOID TxnScopeContext;
    ULONG LockCount;
    ULONG SpareUlong0;
    PVOID ResourceRetValue;
    PVOID ReservedForWdf;
} TEB, *PTEB;


//
// Thread Information Classes
//

typedef enum _THREADINFOCLASS {
    ThreadBasicInformation,
    ThreadTimes,
    ThreadPriority,
    ThreadBasePriority,
    ThreadAffinityMask,
    ThreadImpersonationToken,
    ThreadDescriptorTableEntry,
    ThreadEnableAlignmentFaultFixup,
    ThreadEventPair_Reusable,
    ThreadQuerySetWin32StartAddress,
    ThreadZeroTlsCell,
    ThreadPerformanceCount,
    ThreadAmILastThread,
    ThreadIdealProcessor,
    ThreadPriorityBoost,
    ThreadSetTlsArrayAddress,   // Obsolete
    ThreadIsIoPending,
    ThreadHideFromDebugger,
    ThreadBreakOnTermination,
    ThreadSwitchLegacyState,
    ThreadIsTerminated,
    ThreadLastSystemCall,
    ThreadIoPriority,
    ThreadCycleTime,
    ThreadPagePriority,
    ThreadActualBasePriority,
    ThreadTebInformation,
    ThreadCSwitchMon,          // Obsolete
    ThreadCSwitchPmu,
    ThreadWow64Context,
    ThreadGroupInformation,
    ThreadUmsInformation,      // UMS
    ThreadCounterProfiling,
    ThreadIdealProcessorEx,
    ThreadCpuAccountingInformation,
    ThreadSuspendCount,
    MaxThreadInfoClass
} THREADINFOCLASS;

#define THREAD_CSWITCH_PMU_DISABLE  FALSE
#define THREAD_CSWITCH_PMU_ENABLE   TRUE


#define NtCurrentThread() ((HANDLE)-2)

NTSYSAPI
NTSTATUS 
NTAPI
RtlCreateUserThread(
	IN HANDLE ProcessHandle,
	IN PVOID SecurityDescriptor OPTIONAL,
	IN BOOLEAN CreateSuspended,
	IN ULONG ZeroBits OPTIONAL,
	IN SIZE_T ReservedStackSize OPTIONAL,
    IN SIZE_T CommittedStackSize OPTIONAL,
	IN PVOID StartRoutine,
	IN PVOID Argument,
	OUT PHANDLE ThreadHandle OPTIONAL,
	OUT PCLIENT_ID ClientID OPTIONAL
	);

NTSYSAPI
DECLSPEC_NORETURN
VOID
NTAPI
RtlExitUserThread(
    _In_ DWORD dwExitCode
    );

NTSYSAPI
VOID 
NTAPI
RtlRaiseStatus(
    NTSTATUS dwNtStatus
              );

#include <pshpack4.h>
typedef struct __STACK_INFO_
{
	ULONG Unknown1;
	ULONG Unknown2;
	PVOID StackBase;
	PVOID StackLimit;
	PVOID AllocationBase;
} STACK_INFO, *PSTACK_INFO;
#include <poppack.h>


__kernel_entry NTSTATUS
NTAPI
NtCreateThread(
    OUT PHANDLE ThreadHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN HANDLE ProcessHandle,
	OUT PCLIENT_ID ClientID,
	IN PCONTEXT Context,
	IN PSTACK_INFO StackInfo,
	IN BOOLEAN CreateSuspended 
	);

__kernel_entry NTSTATUS
NTAPI
NtOpenThread(
    OUT PHANDLE ThreadHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN PCLIENT_ID ClientId
    );

__kernel_entry NTSTATUS
NTAPI
NtTerminateThread(
	IN HANDLE ThreadHandle,
	IN ULONG ThreadExitCode
	);

__kernel_entry NTSTATUS
NTAPI
NtQueryInformationThread(
    IN HANDLE ThreadHandle,
    IN THREADINFOCLASS ThreadInformationClass,
    OUT PVOID ThreadInformation,
    IN ULONG ThreadInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );

__kernel_entry NTSTATUS
NTAPI
NtSetInformationThread(
    IN HANDLE ThreadHandle,
    IN THREADINFOCLASS ThreadInformationClass,
    IN PVOID ThreadInformation,
    IN ULONG ThreadInformationLength
    );

typedef struct __THREAD_BASIC_INFORMATION_
{
	NTSTATUS ExitStatus;
	PTEB TebBaseAddress;
	CLIENT_ID ClientID;
	KAFFINITY AffinityMask;
	KPRIORITY BasePriority;
	KPRIORITY Priority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;

typedef struct __THREAD_AM_I_LAST_THREAD_
{
	BOOLEAN AmILastThread;
} THREAD_AM_I_LAST_THREAD, *PTHREAD_AM_I_LAST_THREAD;

__kernel_entry NTSTATUS
NTAPI
NtGetContextThread(
	IN HANDLE ThreadHandle,
	IN OUT PCONTEXT ThreadContext
	);

__kernel_entry NTSTATUS
NTAPI
NtSetContextThread(
	IN HANDLE ThreadHandle,
	IN PCONTEXT ThreadContext
	);

__kernel_entry NTSTATUS
NTAPI
NtResumeThread(
    IN  HANDLE ThreadHandle,
	OUT PULONG SuspendCount OPTIONAL
	);

__kernel_entry NTSTATUS
NTAPI
NtSuspendThread(
    IN  HANDLE ThreadHandle,
	OUT PULONG SuspendCount OPTIONAL
	);




// Получение информации о системе

typedef enum _NT_PRODUCT_TYPE {
    NtProductWinNt = 1,
    NtProductLanManNt,
    NtProductServer
} NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE;

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation = 0,
    SystemInfoProcessor = 1,
    SystemPerformanceInformation = 2,
    SystemTimeOfDayInformation = 3,
    SystemProcessInformation = 5,
    SystemInfoConfiguration = 7,
    SystemProcessorPerformanceInformation = 8,
    SystemInfoDrivers = 11,
    SystemInterruptInformation = 23,
    SystemExceptionInformation = 33,
    SystemInfoKernelDebuggerPresent = 35,   // return BOOLEAN
    SystemRegistryQuotaInformation = 37,
    SystemLookasideInformation = 45,
    SystemPolicyInformation = 134,
} SYSTEM_INFORMATION_CLASS;

typedef struct __SYSTEM_BASIC_INFORMATION_
{ // SystemBasicInformation
    ULONG Unknown0;
    ULONG DefaultTimerResolution;
    ULONG PageSize;
    SIZE_T AvailablePhysicalMemory;
    ULONG Unknown1;
    SIZE_T TotalPhysicalMemory;
    ULONG AllocationGranularity;
    PVOID MinimumApplicationAddress;
    PVOID MaximumApplicationAddress;
    ULONG ActiveProcessorMask;
    CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;

typedef struct __SYSTEM_INFO_PROCESSOR_
{ // SystemInfoProcessor
    USHORT ProcessorArchitecture;
    USHORT ProcessorLevel;
    USHORT ProcessorRevision;
    USHORT Unknown0;
    ULONG  Unknown1;
} SYSTEM_INFO_PROCESSOR, *PSYSTEM_INFO_PROCESSOR;

typedef struct __SYSTEM_PERFORMANCE_INFORMATION_
{ // SystemPerformanceInformation
    BYTE Reserved1[312];
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;

typedef struct __SYSTEM_TIMEOFDAY_INFORMATION_
{ // SystemTimeOfDayInformation
    TIME  StartTime;
    TIME  CurrentTime;
    LARGE_INTEGER Bias;
    ULONG TimeZoneID;
    BYTE Reserved1[20];
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;

typedef struct __SYSTEM_PROCESS_INFORMATION_
{
    ULONG NextEntryOffset;
    BYTE Reserved1[52];
    PVOID Reserved2[3];
    HANDLE UniqueProcessId;
    PVOID Reserved3;
    ULONG HandleCount;
    BYTE Reserved4[4];
    PVOID Reserved5[11];
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivatePageCount;
    LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

typedef struct __SYSTEM_INFO_CONFIGURATION_
{ // SystemInfoConfiguration
    ULONG DiskCount;
    ULONG FloppyCount;
    ULONG CdRomCount;
    ULONG TapeCount;
    ULONG SerialCount;
    ULONG ParallelCount;
} SYSTEM_INFO_CONFIGURATION, *PSYSTEM_INFO_CONFIGURATION;

typedef struct __SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_
{ // SystemProcessorPerformanceInformation
    LARGE_INTEGER IdleTime;
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER Reserved1[2];
    ULONG Reserved2;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

typedef struct __DRIVER_INFO_
{
    ULONG Unknown1;
    ULONG Unknown2;
    LARGE_INTEGER Size;
    ULONG Index;
    ULONG Unknown4;
    CHAR  PathName[MAX_PATH];
} DRIVER_INFO, *PDRIVER_INFO;

typedef struct __SYSTEM_INFO_DRIVERS_
{ // SystemInfoDrivers
    ULONG NumberOfDrivers;
    ULONG Reserved;
    DRIVER_INFO Drivers[ANYSIZE_ARRAY];
} SYSTEM_INFO_DRIVERS, *PSYSTEM_INFO_DRIVERS;

typedef struct __SYSTEM_INTERRUPT_INFORMATION_
{ // SystemInterruptInformation
    BYTE Reserved1[24];
} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;

typedef struct __SYSTEM_EXCEPTION_INFORMATION_
{ // SystemExceptionInformation
    BYTE Reserved1[16];
} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION;

typedef struct __SYSTEM_REGISTRY_QUOTA_INFORMATION_
{ // SystemRegistryQuotaInformation
    ULONG RegistryQuotaAllowed;
    ULONG RegistryQuotaUsed;
    PVOID Reserved1;
} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION;

typedef struct __SYSTEM_LOOKASIDE_INFORMATION_
{ // SystemLookasideInformation
    BYTE Reserved1[32];
} SYSTEM_LOOKASIDE_INFORMATION, *PSYSTEM_LOOKASIDE_INFORMATION;

typedef struct __SYSTEM_POLICY_INFORMATION_
{ // SystemPolicyInformation
    PVOID Reserved1[2];
    ULONG Reserved2[3];
} SYSTEM_POLICY_INFORMATION, *PSYSTEM_POLICY_INFORMATION;

__kernel_entry BOOLEAN
NTAPI
RtlGetNtProductType(
    OUT PNT_PRODUCT_TYPE ProductType
                   );

__kernel_entry NTSTATUS
NTAPI
NtQueryPerformanceCounter(
    OUT PLARGE_INTEGER PerformanceCounter,
    OUT PLARGE_INTEGER Frequency
                         );

//
// use the Win32 APIs instead
//     GetSystemRegistryQuota
//     GetSystemTimes
// use the CryptoAPIs instead for generating random data
//     CryptGenRandom
//
__kernel_entry NTSTATUS
NTAPI 
NtQuerySystemInformation (
    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );



//
// Object Information Classes
//

typedef enum _OBJECT_INFORMATION_CLASS {
    ObjectBasicInformation = 0,
    ObjectTypeInformation = 2
} OBJECT_INFORMATION_CLASS;

//
//  Public Object Information definitions
//

typedef struct __PUBLIC_OBJECT_BASIC_INFORMATION_
{
    ULONG Attributes;
    ACCESS_MASK GrantedAccess;
    ULONG HandleCount;
    ULONG PointerCount;

    ULONG Reserved[10];    // reserved for internal use

} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;

typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION_
{

    UNICODE_STRING TypeName;

    ULONG Reserved [22];    // reserved for internal use

} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;

#if (_WIN32_WINNT >= 0x0501)
//
// use the WTS API instead
//     WTSGetActiveConsoleSessionId
// The active console id is cached as a volatile ULONG in a constant
// memory location.  This x86 memory location is subject to changes between
// Windows releases.  Use the WTS API to make your application resilient to
// changes.
//
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
#endif // (_WIN32_WINNT >= 0x0501)

//
// These functions are intended for use by internal core Windows components
// since these functions may change between Windows releases.
//

#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))

//Функции для работы с любым объектом

//
// use the Win32 API instead
//     CloseHandle
//
__kernel_entry NTSTATUS
NTAPI 
NtClose (
    IN HANDLE Handle
    );

NTSTATUS
NTAPI
NtMakeTemporaryObject(
    IN HANDLE Handle
    );

#define DUPLICATE_CLOSE_SOURCE      0x00000001  
#define DUPLICATE_SAME_ACCESS       0x00000002  

NTSTATUS 
NTAPI
NtDuplicateObject(
	IN HANDLE SourceProcessHandle,
	IN HANDLE SourceHandle,
	IN HANDLE TargetProcessHandle,
	OUT PHANDLE TargetHandle OPTIONAL,
	IN ACCESS_MASK DesiredAccess,
	IN ULONG Attributes,//OBJ_xxx 
	IN ULONG Options
	);



//Объект файл 

#define FILE_READ_DATA            ( 0x0001 )    // файл и канал
#define FILE_LIST_DIRECTORY       ( 0x0001 )    // каталог

#define FILE_WRITE_DATA           ( 0x0002 )    // файл и канал
#define FILE_ADD_FILE             ( 0x0002 )    // каталог

#define FILE_APPEND_DATA          ( 0x0004 )    // файл
#define FILE_ADD_SUBDIRECTORY     ( 0x0004 )    // каталог
#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 )    // именованный канал

#define FILE_READ_EA              ( 0x0008 )    // файл и каталог
#define FILE_READ_PROPERTIES      FILE_READ_EA

#define FILE_WRITE_EA             ( 0x0010 )    // файл и каталог
#define FILE_WRITE_PROPERTIES     FILE_WRITE_EA

#define FILE_EXECUTE              ( 0x0020 )    // файл
#define FILE_TRAVERSE             ( 0x0020 )    // каталог

#define FILE_DELETE_CHILD         ( 0x0040 )    // каталог

#define FILE_READ_ATTRIBUTES      ( 0x0080 )    // все

#define FILE_WRITE_ATTRIBUTES     ( 0x0100 )    // все

#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)

#define FILE_GENERIC_READ         (STANDARD_RIGHTS_READ     |\
                                   FILE_READ_DATA           |\
                                   FILE_READ_ATTRIBUTES     |\
                                   FILE_READ_EA             |\
                                   SYNCHRONIZE)


#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\
                                   FILE_WRITE_DATA          |\
                                   FILE_WRITE_ATTRIBUTES    |\
                                   FILE_WRITE_EA            |\
                                   FILE_APPEND_DATA         |\
                                   SYNCHRONIZE)


#define FILE_GENERIC_EXECUTE      (STANDARD_RIGHTS_EXECUTE  |\
                                   FILE_READ_ATTRIBUTES     |\
                                   FILE_EXECUTE             |\
                                   SYNCHRONIZE)

//
// Разделение доступа
//

#define FILE_SHARE_READ                 0x00000001  
#define FILE_SHARE_WRITE                0x00000002  
#define FILE_SHARE_DELETE               0x00000004

//
// Атрибуты файла
//

#define FILE_ATTRIBUTE_READONLY         0x00000001  
#define FILE_ATTRIBUTE_HIDDEN           0x00000002  
#define FILE_ATTRIBUTE_SYSTEM           0x00000004  
#define FILE_ATTRIBUTE_DIRECTORY        0x00000010  
#define FILE_ATTRIBUTE_ARCHIVE          0x00000020  
#define FILE_ATTRIBUTE_NORMAL           0x00000080  
#define FILE_ATTRIBUTE_TEMPORARY        0x00000100  
#define FILE_ATTRIBUTE_RESERVED0        0x00000200
#define FILE_ATTRIBUTE_RESERVED1        0x00000400
#define FILE_ATTRIBUTE_COMPRESSED       0x00000800  

#define FILE_CASE_SENSITIVE_SEARCH      0x00000001  
#define FILE_CASE_PRESERVED_NAMES       0x00000002  
#define FILE_UNICODE_ON_DISK            0x00000004  
#define FILE_PERSISTENT_ACLS            0x00000008  
#define FILE_FILE_COMPRESSION           0x00000010  
#define FILE_VOLUME_IS_COMPRESSED       0x00008000

#define FILE_ATTRIBUTE_VALID_FLAGS      0x00001fb7
#define FILE_ATTRIBUTE_VALID_SET_FLAGS  0x00000fa7

//
// Диспозиция
//

#define FILE_SUPERSEDE                  0x00000000
#define FILE_OPEN                       0x00000001
#define FILE_CREATE                     0x00000002
#define FILE_OPEN_IF                    0x00000003
#define FILE_OVERWRITE                  0x00000004
#define FILE_OVERWRITE_IF               0x00000005
#define FILE_MAXIMUM_DISPOSITION        0x00000005

//
// Информация, возвращаемая NtCreateFile/NtOpenFile
//

#define FILE_SUPERSEDED                 0x00000000
#define FILE_OPENED                     0x00000001
#define FILE_CREATED                    0x00000002
#define FILE_OVERWRITTEN                0x00000003
#define FILE_EXISTS                     0x00000004
#define FILE_DOES_NOT_EXIST             0x00000005

//
// Опции создания/открытия файла
//

#define FILE_DIRECTORY_FILE                     0x00000001
#define FILE_WRITE_THROUGH                      0x00000002
#define FILE_SEQUENTIAL_ONLY                    0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008

#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
#define FILE_NON_DIRECTORY_FILE                 0x00000040
#define FILE_CREATE_TREE_CONNECTION             0x00000080

#define FILE_COMPLETE_IF_OPLOCKED               0x00000100
#define FILE_NO_EA_KNOWLEDGE                    0x00000200
#define FILE_DISABLE_TUNNELING                  0x00000400
#define FILE_RANDOM_ACCESS                      0x00000800

#define FILE_DELETE_ON_CLOSE                    0x00001000
#define FILE_OPEN_BY_FILE_ID                    0x00002000
#define FILE_OPEN_FOR_BACKUP_INTENT             0x00004000
#define FILE_NO_COMPRESSION                     0x00008000


//
// Максимальная длина имени файла
//

#define MAXIMUM_FILENAME_LENGTH         256

//
// use the Win32 API instead
//     CreateFile
//
__kernel_entry NTSTATUS
NTAPI 
NtCreateFile (
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength
    );

//
// use the Win32 API instead
//     CreateFile
//
__kernel_entry NTSTATUS
NTAPI 
NtOpenFile (
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG ShareAccess,
    IN ULONG OpenOptions
    );


//Реестр и объект ключ реестра

//
// Subroutines for dealing with the Registry
//


typedef
_Function_class_(RTL_QUERY_REGISTRY_ROUTINE)
_IRQL_requires_max_(PASSIVE_LEVEL)
_IRQL_requires_same_
NTSTATUS
NTAPI
RTL_QUERY_REGISTRY_ROUTINE(
_In_z_ PWSTR ValueName,
_In_ ULONG ValueType,
_In_reads_bytes_opt_(ValueLength) PVOID ValueData,
_In_ ULONG ValueLength,
_In_opt_ PVOID Context,
_In_opt_ PVOID EntryContext
);
typedef RTL_QUERY_REGISTRY_ROUTINE *PRTL_QUERY_REGISTRY_ROUTINE;

typedef struct __RTL_QUERY_REGISTRY_TABLE_
{
    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
    ULONG Flags;
    PWSTR Name;
    PVOID EntryContext;
    ULONG DefaultType;
    PVOID DefaultData;
    ULONG DefaultLength;

} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;


//
// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE
// entry is interpreted.  A NULL name indicates the end of the table.
//

#define RTL_QUERY_REGISTRY_SUBKEY   0x00000001  // Name is a subkey and remainder of
// table or until next subkey are value
// names for that subkey to look at.

#define RTL_QUERY_REGISTRY_TOPKEY   0x00000002  // Reset current key to original key for
// this and all following table entries.

#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004  // Fail if no match found for this table
// entry.

#define RTL_QUERY_REGISTRY_NOVALUE  0x00000008  // Used to mark a table entry that has no
// value name, just wants a call out, not
// an enumeration of all values.

#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010  // Used to suppress the expansion of
// REG_MULTI_SZ into multiple callouts or
// to prevent the expansion of environment
// variable values in REG_EXPAND_SZ

#define RTL_QUERY_REGISTRY_DIRECT   0x00000020  // QueryRoutine field ignored.  EntryContext
// field points to location to store value.
// For null terminated strings, EntryContext
// points to UNICODE_STRING structure that
// that describes maximum size of buffer.
// If .Buffer field is NULL then a buffer is
// allocated.
//

#define RTL_QUERY_REGISTRY_DELETE   0x00000040  // Used to delete value keys after they
// are queried.

#define RTL_QUERY_REGISTRY_NOSTRING 0x00000080  // THIS IS DEPRECATED - use RTL_QUERY_REGISTRY_TYPECHECK
//
// Used with RTL_QUERY_REGISTRY_DIRECT in
// cases where the caller expects a
// non-string value.  Otherwise, the
// assumption that EntryContext points to
// a UNICODE_STRING structure can overrun
// the caller's buffer.
//

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100 // Used with RTL_QUERY_REGISTRY_DIRECT to
// validate the registry value type
// expected by caller with actual type thats
// read from the registry.


//
// Use the most significant byte of DefaultType from QueryTable, as the
// caller's expected REG_TYPE
//
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT      24
#define RTL_QUERY_REGISTRY_TYPECHECK_MASK       (0xff << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT)

NTSYSAPI
NTSTATUS
NTAPI
RtlQueryRegistryValues(
    _In_     ULONG RelativeTo,
    _In_     PCWSTR Path,
    _Inout_ _At_(*(*QueryTable).EntryContext, _Pre_unknown_)
        PRTL_QUERY_REGISTRY_TABLE QueryTable,
    _In_opt_ PVOID Context,
    _In_opt_ PVOID Environment
    );

NTSYSAPI
NTSTATUS
NTAPI
RtlWriteRegistryValue(
    _In_ ULONG RelativeTo,
    _In_ PCWSTR Path,
    _In_z_ PCWSTR ValueName,
    _In_ ULONG ValueType,
    _In_reads_bytes_opt_(ValueLength) PVOID ValueData,
    _In_ ULONG ValueLength
    );

NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteRegistryValue(
    _In_ ULONG RelativeTo,
    _In_ PCWSTR Path,
    _In_z_ PCWSTR ValueName
    );

NTSYSAPI
NTSTATUS
NTAPI
RtlCreateRegistryKey(
    _In_ ULONG RelativeTo,
    _In_ PWSTR Path
    );

NTSYSAPI
NTSTATUS
NTAPI
RtlCheckRegistryKey(
    _In_ ULONG RelativeTo,
    _In_ PWSTR Path
    );

//
// The following values for the RelativeTo parameter determine what the
// Path parameter to RtlQueryRegistryValues is relative to.
//
#define RTL_REGISTRY_ABSOLUTE     0   // Path is a full path
#define RTL_REGISTRY_SERVICES     1   // \Registry\Machine\System\CurrentControlSet\Services
#define RTL_REGISTRY_CONTROL      2   // \Registry\Machine\System\CurrentControlSet\Control
#define RTL_REGISTRY_WINDOWS_NT   3   // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
#define RTL_REGISTRY_DEVICEMAP    4   // \Registry\Machine\Hardware\DeviceMap
#define RTL_REGISTRY_USER         5   // \Registry\User\CurrentUser
#define RTL_REGISTRY_MAXIMUM      6
#define RTL_REGISTRY_HANDLE       0x40000000    // Low order bits are registry handle
#define RTL_REGISTRY_OPTIONAL     0x80000000    // Indicates the key node is optional


//
// use the Win32 API instead
//     N/A
//
__kernel_entry NTSTATUS
NTAPI
NtRenameKey (
    _In_ HANDLE KeyHandle,
    _In_ PUNICODE_STRING NewName
    );

//
// use the Win32 API instead
//     RegNotifyChangeKeyValue
//
__kernel_entry NTSTATUS
NTAPI
NtNotifyChangeMultipleKeys (
    _In_ HANDLE MasterKeyHandle,
    _In_opt_ ULONG Count,
    _In_reads_opt_(Count) OBJECT_ATTRIBUTES SubordinateObjects[],
    _In_opt_ HANDLE Event,
    _In_opt_ PIO_APC_ROUTINE ApcRoutine,
    _In_opt_ PVOID ApcContext,
    _Out_ PIO_STATUS_BLOCK IoStatusBlock,
    _In_ ULONG CompletionFilter,
    _In_ BOOLEAN WatchTree,
    _Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
    _In_ ULONG BufferSize,
    _In_ BOOLEAN Asynchronous
    );

//
// use the Win32 API instead
//     RegQueryValueEx
//
typedef struct __KEY_VALUE_ENTRY_
{
    PUNICODE_STRING ValueName;
    ULONG           DataLength;
    ULONG           DataOffset;
    ULONG           Type;
} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;

__kernel_entry NTSTATUS
NTAPI
NtQueryMultipleValueKey (
    _In_ HANDLE KeyHandle,
    _Inout_updates_(EntryCount) PKEY_VALUE_ENTRY ValueEntries,
    _In_ ULONG EntryCount,
    _Out_writes_bytes_(*BufferLength) PVOID ValueBuffer,
    _Inout_ PULONG BufferLength,
    _Out_opt_ PULONG RequiredBufferLength
    );

//
// use the Win32 API instead
//     N/A
//
typedef enum _KEY_SET_INFORMATION_CLASS {
    KeyWriteTimeInformation,
    KeyWow64FlagsInformation,
    KeyControlFlagsInformation,
    KeySetVirtualizationInformation,
    KeySetDebugInformation,
    KeySetHandleTagsInformation,
    MaxKeySetInfoClass  // MaxKeySetInfoClass should always be the last enum
} KEY_SET_INFORMATION_CLASS;

__kernel_entry NTSTATUS
NTAPI
NtSetInformationKey (
    _In_ HANDLE KeyHandle,
    _In_ _Strict_type_match_
        KEY_SET_INFORMATION_CLASS KeySetInformationClass,
    _In_reads_bytes_(KeySetInformationLength) PVOID KeySetInformation,
    _In_ ULONG KeySetInformationLength
    );


//
// Registry Specific Access Rights.
//

#define KEY_QUERY_VALUE         (0x0001)
#define KEY_SET_VALUE           (0x0002)
#define KEY_CREATE_SUB_KEY      (0x0004)
#define KEY_ENUMERATE_SUB_KEYS  (0x0008)
#define KEY_NOTIFY              (0x0010)
#define KEY_CREATE_LINK         (0x0020)

#define KEY_READ                ((STANDARD_RIGHTS_READ       |\
                                  KEY_QUERY_VALUE            |\
                                  KEY_ENUMERATE_SUB_KEYS     |\
                                  KEY_NOTIFY)                 \
                                  &                           \
                                 (~SYNCHRONIZE))


#define KEY_WRITE               ((STANDARD_RIGHTS_WRITE      |\
                                  KEY_SET_VALUE              |\
                                  KEY_CREATE_SUB_KEY)         \
                                  &                           \
                                 (~SYNCHRONIZE))

#define KEY_EXECUTE             ((KEY_READ)                   \
                                  &                           \
                                 (~SYNCHRONIZE))

#define KEY_ALL_ACCESS          ((STANDARD_RIGHTS_ALL        |\
                                  KEY_QUERY_VALUE            |\
                                  KEY_SET_VALUE              |\
                                  KEY_CREATE_SUB_KEY         |\
                                  KEY_ENUMERATE_SUB_KEYS     |\
                                  KEY_NOTIFY                 |\
                                  KEY_CREATE_LINK)            \
                                  &                           \
                                 (~SYNCHRONIZE))

//
// Open/Create Options
//

#define REG_OPTION_RESERVED         (0x00000000L)   // Parameter is reserved

#define REG_OPTION_NON_VOLATILE     (0x00000000L)   // Key is preserved
                                                    // when system is rebooted

#define REG_OPTION_VOLATILE         (0x00000001L)   // Key is not preserved
                                                    // when system is rebooted

#define REG_OPTION_CREATE_LINK      (0x00000002L)   // Created key is a
                                                    // symbolic link

#define REG_OPTION_BACKUP_RESTORE   (0x00000004L)   // open for backup or restore
                                                    // special access rules
                                                    // privilege required

#define REG_OPTION_OPEN_LINK        (0x00000008L)   // Open symbolic link

#ifndef REG_LEGAL_OPTION
#define REG_LEGAL_OPTION            \
                (REG_OPTION_RESERVED            |\
                 REG_OPTION_NON_VOLATILE        |\
                 REG_OPTION_VOLATILE            |\
                 REG_OPTION_CREATE_LINK         |\
				 REG_OPTION_BACKUP_RESTORE		|\
                 REG_OPTION_OPEN_LINK)
#endif

//
// Key creation/open disposition
//

#define REG_CREATED_NEW_KEY         (0x00000001L)   // New Registry Key created
#define REG_OPENED_EXISTING_KEY     (0x00000002L)   // Existing Key opened

//
// Key restore flags
//

#define REG_WHOLE_HIVE_VOLATILE     (0x00000001L)   // Restore whole hive volatile
#define REG_REFRESH_HIVE            (0x00000002L)   // Unwind changes to last flush
#define REG_NO_LAZY_FLUSH           (0x00000004L)   // Never lazy flush this hive

//
// Key query structures
//

typedef struct __KEY_BASIC_INFORMATION_
{
    LARGE_INTEGER LastWriteTime;
    ULONG   TitleIndex;
    ULONG   NameLength;
    WCHAR   Name[1];            // Variable length string
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;

typedef struct __KEY_NODE_INFORMATION_
{
    LARGE_INTEGER LastWriteTime;
    ULONG   TitleIndex;
    ULONG   ClassOffset;
    ULONG   ClassLength;
    ULONG   NameLength;
    WCHAR   Name[1];            // Variable length string
//          Class[1];           // Variable length string not declared
} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;

typedef struct __KEY_FULL_INFORMATION_
{
    LARGE_INTEGER LastWriteTime;
    ULONG   TitleIndex;
    ULONG   ClassOffset;
    ULONG   ClassLength;
    ULONG   SubKeys;
    ULONG   MaxNameLen;
    ULONG   MaxClassLen;
    ULONG   Values;
    ULONG   MaxValueNameLen;
    ULONG   MaxValueDataLen;
    WCHAR   Class[1];           // Variable length
} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;

typedef enum _KEY_INFORMATION_CLASS {
    KeyBasicInformation,
    KeyNodeInformation,
    KeyFullInformation
} KEY_INFORMATION_CLASS;

typedef struct __KEY_WRITE_TIME_INFORMATION_
{
    LARGE_INTEGER LastWriteTime;
} KEY_WRITE_TIME_INFORMATION, *PKEY_WRITE_TIME_INFORMATION;

//
// Value entry query structures
//

typedef struct __KEY_VALUE_BASIC_INFORMATION_
{
    ULONG   TitleIndex;
    ULONG   Type;
    ULONG   NameLength;
    WCHAR   Name[1];            // Variable size
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;

typedef struct __KEY_VALUE_FULL_INFORMATION_
{
    ULONG   TitleIndex;
    ULONG   Type;
    ULONG   DataOffset;
    ULONG   DataLength;
    ULONG   NameLength;
    WCHAR   Name[1];            // Variable size
//          Data[1];            // Variable size data not declared
} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;

typedef struct __KEY_VALUE_PARTIAL_INFORMATION_
{
    ULONG   TitleIndex;
    ULONG   Type;
    ULONG   DataLength;
    UCHAR   Data[1];            // Variable size
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;

typedef enum _KEY_VALUE_INFORMATION_CLASS {
    KeyValueBasicInformation,
    KeyValueFullInformation, 
    KeyValuePartialInformation 
} KEY_VALUE_INFORMATION_CLASS;

//
// Predefined Value Types.
//

#define REG_NONE                    ( 0 )   // No value type
#define REG_SZ                      ( 1 )   // Unicode nul terminated string
#define REG_EXPAND_SZ               ( 2 )   // Unicode nul terminated string
                                            // (with environment variable references)
#define REG_BINARY                  ( 3 )   // Free form binary
#define REG_DWORD                   ( 4 )   // 32-bit number
#define REG_DWORD_LITTLE_ENDIAN     ( 4 )   // 32-bit number (same as REG_DWORD)
#define REG_DWORD_BIG_ENDIAN        ( 5 )   // 32-bit number
#define REG_LINK                    ( 6 )   // Symbolic Link (unicode)
#define REG_MULTI_SZ                ( 7 )   // Multiple Unicode strings
#define REG_RESOURCE_LIST           ( 8 )   // Resource list in the resource map
#define REG_FULL_RESOURCE_DESCRIPTOR ( 9 )  // Resource list in the hardware description
#define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )

NTSYSAPI
NTSTATUS
NTAPI
NtCreateKey(
    OUT PHANDLE KeyHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN ULONG TitleIndex,
    IN PUNICODE_STRING Class OPTIONAL,
    IN ULONG CreateOptions,
    OUT PULONG Disposition OPTIONAL
    );

NTSYSAPI
NTSTATUS
NTAPI
NtOpenKey(
    OUT PHANDLE KeyHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

NTSYSAPI
NTSTATUS
NTAPI
NtDeleteKey(
    IN HANDLE KeyHandle
    );

NTSYSAPI
NTSTATUS
NTAPI
NtEnumerateKey(
    IN HANDLE KeyHandle,
    IN ULONG Index,
    IN KEY_INFORMATION_CLASS KeyInformationClass,
    OUT PVOID KeyInformation,
    IN ULONG Length,
    OUT PULONG ResultLength
    );

NTSYSAPI
NTSTATUS
NTAPI
NtEnumerateValueKey(
    IN HANDLE KeyHandle,
    IN ULONG Index,
    IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
    OUT PVOID KeyValueInformation,
    IN ULONG Length,
    OUT PULONG ResultLength
    );

NTSYSAPI
NTSTATUS
NTAPI
RtlpNtEnumerateSubKey(
    IN HANDLE KeyHandle,
    OUT PUNICODE_STRING SubKeyName,
    IN ULONG  Index,
    DWORD     Unknown
                     );

NTSYSAPI
NTSTATUS
NTAPI
NtFlushKey(
    IN HANDLE KeyHandle
    );

NTSYSAPI
NTSTATUS
NTAPI
NtQueryKey(
    IN HANDLE KeyHandle,
    IN KEY_INFORMATION_CLASS KeyInformationClass,
    OUT PVOID KeyInformation,
    IN ULONG Length,
    OUT PULONG ResultLength
    );

NTSYSAPI
NTSTATUS
NTAPI
NtQueryValueKey(
    IN HANDLE KeyHandle,
    IN PUNICODE_STRING ValueName,
    IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
    OUT PVOID KeyValueInformation,
    IN ULONG Length,
    OUT PULONG ResultLength
    );

NTSYSAPI
NTSTATUS
NTAPI
NtSetValueKey(
    IN HANDLE KeyHandle,
    IN PUNICODE_STRING ValueName,
    IN ULONG TitleIndex OPTIONAL,
    IN ULONG Type,
    IN PVOID Data,
    IN ULONG DataSize
    );

NTSYSAPI
NTSTATUS
NTAPI
NtDeleteValueKey(
    IN HANDLE KeyHandle,
    IN PUNICODE_STRING ValueName
	);

NTSYSAPI
NTSTATUS
NTAPI
NtLoadKey(
	//directory field specified parent key
	//name field specified creating key
	IN POBJECT_ATTRIBUTES KeyToLoad,
	IN POBJECT_ATTRIBUTES File
	);

NTSYSAPI
NTSTATUS
NTAPI
NtUnloadKey(
	//directory field specified parent key
	//name field specified unloading key
	IN POBJECT_ATTRIBUTES KeyToUnLoad
	);

NTSYSAPI
NTSTATUS
NTAPI
NtSaveKey(
	IN HANDLE KeyHandle,
	IN HANDLE FileHandle
	);

NTSYSAPI
NTSTATUS
NTAPI
NtRestoreKey(
	IN HANDLE KeyHandle,
	IN HANDLE FileHandle,
	IN ULONG Flags
	);

NTSYSAPI
NTSTATUS
NTAPI
NtReplaceKey(
	IN POBJECT_ATTRIBUTES NewFile,
	IN HANDLE KeyHandle,
	IN POBJECT_ATTRIBUTES OldFile
	);

NTSYSAPI
NTSTATUS
NTAPI
RtlOpenCurrentUser(
    IN ACCESS_MASK DesiredAccess,
    OUT PHANDLE phCurrentUserKey
                  );


//
// Классы информации об устройстве и файловой системе
//

typedef enum __FSINFOCLASS_
{
    FileFsVolumeInformation = 1,
    FileFsLabelInformation,         //2
    FileFsSizeInformation,          //3
    FileFsDeviceInformation,        //4
    FileFsAttributeInformation,     //5
    FileFsQuotaQueryInformation,    //6
    FileFsQuotaSetInformation,      //7
    FileFsControlQueryInformation,  //8
    FileFsControlSetInformation,    //9
    FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;

typedef struct __FILE_FS_VOLUME_INFORMATION_
{
	TIME VolumeCreationTime;
	ULONG VolumeSerialNumber;
	ULONG VolumeNameSize;
	BOOLEAN CreationTimeSupported;
	UCHAR Spare;
	WCHAR VolumeName[ANYSIZE_ARRAY];
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;     

typedef struct __FILE_FS_LABEL_INFORMATION_
{
	ULONG LabelNameSize;
	WCHAR LabelName[ANYSIZE_ARRAY];
} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION;     

typedef struct __FILE_FS_SIZE_INFORMATION_
{
	ULARGE_INTEGER TotalNumberOfClusters;
	ULARGE_INTEGER NumberOfFreeClusters;
	ULONG SectorsPerCluster;
	ULONG BytesPerSector;
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;     

#ifndef DEVICE_TYPE
#define DEVICE_TYPE ULONG
#endif

typedef struct __FILE_FS_DEVICE_INFORMATION_
{
    DEVICE_TYPE DeviceType;
    ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;     
                                                                
typedef struct __FILE_FS_ATTRIBUTE_INFORMATION_
{
	ULONG FileSystemFlags;
	LONG MaximumComponentLength;
	ULONG FileSystemNameSize;
	WCHAR FileSystemName[ANYSIZE_ARRAY];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
     
//Флаги файловых систем

#define FS_CASE_IS_PRESERVED            FILE_CASE_PRESERVED_NAMES
#define FS_CASE_SENSITIVE               FILE_CASE_SENSITIVE_SEARCH
#define FS_UNICODE_STORED_ON_DISK       FILE_UNICODE_ON_DISK
#define FS_PERSISTENT_ACLS              FILE_PERSISTENT_ACLS
#define FS_VOL_IS_COMPRESSED            FILE_VOLUME_IS_COMPRESSED
#define FS_FILE_COMPRESSION             FILE_FILE_COMPRESSION

//
// Характеристики устройств
//

#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_DEVICE_BEEP                0x00000001
#define FILE_DEVICE_CD_ROM              0x00000002
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM  0x00000003
#define FILE_DEVICE_CONTROLLER          0x00000004
#define FILE_DEVICE_DATALINK            0x00000005
#define FILE_DEVICE_DFS                 0x00000006
#define FILE_DEVICE_DISK                0x00000007
#define FILE_DEVICE_DISK_FILE_SYSTEM    0x00000008
#define FILE_DEVICE_FILE_SYSTEM         0x00000009
#define FILE_DEVICE_INPORT_PORT         0x0000000a
#define FILE_DEVICE_KEYBOARD            0x0000000b
#define FILE_DEVICE_MAILSLOT            0x0000000c
#define FILE_DEVICE_MIDI_IN             0x0000000d
#define FILE_DEVICE_MIDI_OUT            0x0000000e
#define FILE_DEVICE_MOUSE               0x0000000f
#define FILE_DEVICE_MULTI_UNC_PROVIDER  0x00000010
#define FILE_DEVICE_NAMED_PIPE          0x00000011
#define FILE_DEVICE_NETWORK             0x00000012
#define FILE_DEVICE_NETWORK_BROWSER     0x00000013
#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
#define FILE_DEVICE_NULL                0x00000015
#define FILE_DEVICE_PARALLEL_PORT       0x00000016
#define FILE_DEVICE_PHYSICAL_NETCARD    0x00000017
#define FILE_DEVICE_PRINTER             0x00000018
#define FILE_DEVICE_SCANNER             0x00000019
#define FILE_DEVICE_SERIAL_MOUSE_PORT   0x0000001a
#define FILE_DEVICE_SERIAL_PORT         0x0000001b
#define FILE_DEVICE_SCREEN              0x0000001c
#define FILE_DEVICE_SOUND               0x0000001d
#define FILE_DEVICE_STREAMS             0x0000001e
#define FILE_DEVICE_TAPE                0x0000001f
#define FILE_DEVICE_TAPE_FILE_SYSTEM    0x00000020
#define FILE_DEVICE_TRANSPORT           0x00000021
#define FILE_DEVICE_UNKNOWN             0x00000022
#define FILE_DEVICE_VIDEO               0x00000023
#define FILE_DEVICE_VIRTUAL_DISK        0x00000024
#define FILE_DEVICE_WAVE_IN             0x00000025
#define FILE_DEVICE_WAVE_OUT            0x00000026
#define FILE_DEVICE_8042_PORT           0x00000027
#define FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
#define FILE_DEVICE_BATTERY             0x00000029
#define FILE_DEVICE_BUS_EXTENDER        0x0000002a

//
// Методы передачи буферов
//

#define METHOD_BUFFERED                 0
#define METHOD_IN_DIRECT                1
#define METHOD_OUT_DIRECT               2
#define METHOD_NEITHER                  3

// Макрос для определения кодов управления

#define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)


#define FILE_ANY_ACCESS                 0
#define FILE_READ_ACCESS          ( 0x0001 )    // файл и канал
#define FILE_WRITE_ACCESS         ( 0x0002 )    // файл и канал


NTSYSAPI
NTSTATUS
NTAPI
NtQueryVolumeInformationFile(
	IN HANDLE FileHandle,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
	OUT PVOID VolumeInformation,
    IN ULONG Length,
	IN FS_INFORMATION_CLASS FsInformationClass
	);

NTSYSAPI
NTSTATUS
NTAPI
NtSetVolumeInformationFile(
	IN HANDLE FileHandle,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN PVOID VolumeInformation,
    IN ULONG Length,
	IN FS_INFORMATION_CLASS FsInformationClass
	);

typedef
VOID
(NTAPI *PIO_APC_ROUTINE) (
    IN PVOID ApcContext,
    IN PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG Reserved
    );

//
// use the Win32 API instead
//     DeviceIoControl
//
__kernel_entry NTSTATUS
NTAPI 
NtDeviceIoControlFile (
    IN HANDLE FileHandle,
    IN HANDLE Event OPTIONAL,
    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    IN PVOID ApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG IoControlCode,
    IN PVOID InputBuffer OPTIONAL,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer OPTIONAL,
    IN ULONG OutputBufferLength
    );

__kernel_entry NTSTATUS
NTAPI
NtFsControlFile(
	IN HANDLE DeviceHandle,
	IN HANDLE Event OPTIONAL,
    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    IN PVOID ApcContext OPTIONAL,
	IN OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN ULONG  IoControlCode,
	IN PVOID  InBuffer,	
    IN ULONG  InBufferSize,
    OUT PVOID  OutBuffer,
    IN ULONG  OutBufferSize
	);

#define FILE_NOTIFY_CHANGE_FILE_NAME    0x00000001   
#define FILE_NOTIFY_CHANGE_DIR_NAME     0x00000002   
#define FILE_NOTIFY_CHANGE_ATTRIBUTES   0x00000004   
#define FILE_NOTIFY_CHANGE_SIZE         0x00000008   
#define FILE_NOTIFY_CHANGE_LAST_WRITE   0x00000010   
#define FILE_NOTIFY_CHANGE_SECURITY     0x00000100   

#define FILE_ACTION_ADDED				0x00000001
#define FILE_ACTION_REMOVED				0x00000002
#define FILE_ACTION_MODIFIED			0x00000003
#define FILE_ACTION_RENAMED_OLD_NAME	0x00000004
#define FILE_ACTION_RENAMED_NEW_NAME	0x00000005

#if !defined(_WINNT_) || (_MSC_VER < 1000)

typedef struct __FILE_NOTIFY_INFORMATION_ {
	ULONG NextEntryOffset;
	ULONG Action;
	ULONG FileNameLength;
	WCHAR FileName[1];
}FILE_NOTIFY_INFORMATION;

#endif

__kernel_entry NTSTATUS
NTAPI
NtNotifyChangeDirectoryFile(
	IN HANDLE DirectoryHandle,
	IN HANDLE EventHandle OPTIONAL,
	IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
	IN PVOID ApcContext OPTIONAL,
	IN PIO_STATUS_BLOCK IoStatusBlock,
	OUT PVOID Buffer,
	IN ULONG BufferLength,
	IN ULONG NotifyFiltr,//FILE_NOTIFY_CHANGE_xxx
	IN BOOLEAN WatchSubtree
	);


// Классы информации о файле

typedef enum _FILE_INFORMATION_CLASS {
    FileDirectoryInformation = 1,
    FileFullDirectoryInformation,       //2
    FileBothDirectoryInformation,       //3
    FileBasicInformation,               //4
    FileStandardInformation,            //5
    FileInternalInformation,            //6
    FileEaInformation,                  //7
    FileAccessInformation,              //8
    FileNameInformation,                //9
    FileRenameInformation,              //10 (0Ah)
    FileLinkInformation,                //11 (0Bh)
    FileNamesInformation,               //12 (0Ch)
    FileDispositionInformation,         //13 (0Dh)
    FilePositionInformation,            //14 (0Eh)
    FileFullEaInformation,              //15 (0Fh)
    FileModeInformation,                //16 (10h)
    FileAlignmentInformation,           //17 (11h)
    FileAllInformation,                 //18 (12h)
    FileAllocationInformation,          //19 (13h)
    FileEndOfFileInformation,           //20 (14h)
    FileAlternateNameInformation,       //21 (15h)
    FileStreamInformation,              //22 (16h)
    FilePipeInformation,                //23 (17h)
    FilePipeLocalInformation,           //24 (18h)
    FilePipeRemoteInformation,          //25 (19h)
    FileMailslotQueryInformation,       //26 (1Ah)
    FileMailslotSetInformation,         //27 (1Bh)
    FileCompressionInformation,         //28 (1Ch)
    FileCopyOnWriteInformation,         //29 (1Dh)
    FileCompletionInformation,          //30 (1Eh)
    FileMoveClusterInformation,         //31 (1Fh)
    FileOleClassIdInformation,          //32 (20h)
    FileOleStateBitsInformation,        //33 (21h)
    FileApplicationExplorableInformation,//34 (22h)
    FileApplicationExplorableChildrenInformation,//35 (23h)
    FileObjectIdInformation,            //36 (24h)
    FileOleAllInformation,              //37 (25h)
    FileOleDirectoryInformation,        //38 (26h)
    FileTransactionCommitInformation,   //39 (27h)
    FileContentIndexInformation,        //40 (28h)
    FileInheritContentIndexInformation, //41 (29h)
    FileOleInformation,                 //42 (2Ah)
    FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

typedef struct __FILE_QUERY_DIRECTORY_
{
	ULONG NextEntryOffset;
	ULONG Unknown1;
	TIME CreationTime;
	TIME LastAccessTime;
	TIME LastWriteTime;
	TIME ChangeTime;
	LARGE_INTEGER EndOfFile;
	LARGE_INTEGER AllocationSize;
	ULONG FileAttributes;
	ULONG FileNameLength;
	union {
		struct {
			WCHAR FileName[ANYSIZE_ARRAY];
		} Class1;
		struct {
			ULONG Unknown2;
			WCHAR FileName[ANYSIZE_ARRAY];
		} Class2;
		struct {
			ULONG Unknown2;
			USHORT AlternateFileNameLength;
			WCHAR AlternateFileName[12];
			WCHAR FileName[ANYSIZE_ARRAY];
		} Class3;
	};
} FILE_QUERY_DIRECTORY, *PFILE_QUERY_DIRECTORY;

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;

__kernel_entry NTSTATUS
NTAPI
NtQueryDirectoryFile(
	IN HANDLE DirectoryFileHandle,
	IN HANDLE EventHandle OPTIONAL,
	IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
	IN PVOID ApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
	OUT PVOID Buffer,
	IN ULONG BufferLength,
	IN FILE_INFORMATION_CLASS DirectoryInfoClass,
	IN BOOLEAN ByOne,
	IN PUNICODE_STRING SearchTemplate OPTIONAL,
	IN BOOLEAN Reset
	);

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;         
                                                            
typedef struct __FILE_STANDARD_INFORMATION_
{                 
    LARGE_INTEGER AllocationSize;                           
    LARGE_INTEGER EndOfFile;                                
    ULONG NumberOfLinks;                                    
    BOOLEAN DeletePending;                                  
    BOOLEAN Directory;                                      
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;   
                                                            
#include <pshpack4.h>
typedef struct __FILE_EA_INFORMATION_
{
	ULONG EaLength; 
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;

typedef struct __FILE_ACCESS_INFORMATION_
{
	ACCESS_MASK GrantedAccess;
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
#include <poppack.h>

typedef struct __FILE_NAME_INFORMATION_
{
	ULONG NameSize;
	WCHAR Name[ANYSIZE_ARRAY];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

#include <pshpack1.h>
typedef struct __FILE_DISPOSITION_INFORMATION_
{                  
    BOOLEAN DeleteFile;                                         
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; 
#include <poppack.h>
                                                                
typedef struct __FILE_POSITION_INFORMATION_
{                 
    LARGE_INTEGER CurrentByteOffset;                        
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;   
                                                            
typedef struct __FILE_FULL_EA_INFORMATION_
{
    ULONG NextEntryOffset;
    UCHAR Flags;
    UCHAR EaNameLength;
    USHORT EaValueLength;
    CHAR EaName[1];//за ней следует EaValue
	//CHAR EaValue[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;

typedef struct __FILE_MODE_INFORMATION_
{                
    ULONG Mode;                             
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; 
                                                            
//
// Выравнивание
//

#define FILE_BYTE_ALIGNMENT             0x00000000
#define FILE_WORD_ALIGNMENT             0x00000001
#define FILE_LONG_ALIGNMENT             0x00000003
#define FILE_QUAD_ALIGNMENT             0x00000007
#define FILE_OCTA_ALIGNMENT             0x0000000f
#define FILE_32_BYTE_ALIGNMENT          0x0000001f
#define FILE_64_BYTE_ALIGNMENT          0x0000003f
#define FILE_128_BYTE_ALIGNMENT         0x0000007f
#define FILE_256_BYTE_ALIGNMENT         0x000000ff
#define FILE_512_BYTE_ALIGNMENT         0x000001ff

typedef struct __FILE_ALIGNMENT_INFORMATION_
{                
    ULONG AlignmentRequirement;                             
} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; 
                                                            
typedef struct __FILE_END_OF_FILE_INFORMATION_
{                  
    LARGE_INTEGER EndOfFile;                                    
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; 
                                                                
typedef struct __FILE_ALTERNATE_NAME_INFORMATION_
{
	ULONG NameSize;
	WCHAR Name[ANYSIZE_ARRAY];
} FILE_ALTERNATE_NAME_INFORMATION, *PFILE_ALTERNATE_NAME_INFORMATION;

typedef struct __FILE_STREAM_INFORMATION_
{
    ULONG NextEntryOffset;
	ULONG StreamNameLength;
	LARGE_INTEGER StreamLength;
	LARGE_INTEGER AllocationSize;
	WCHAR StreamName[ANYSIZE_ARRAY];
} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;

#define COMPRESSION_FORMAT_NONE          (0x0000)   
#define COMPRESSION_FORMAT_DEFAULT       (0x0001)   
#define COMPRESSION_FORMAT_LZNT1         (0x0002)   

typedef struct __FILE_COMPRESSION_INFORMATION_
{
	LARGE_INTEGER CompressedSize;
	USHORT CompressionFormat; //COMPRESSION_FORMAT_xxx
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;

typedef struct __FILE_COMPLETION_INFORMATION_
{
	HANDLE CompletionPort;
	ULONG CompletionKey;
} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION;

__kernel_entry NTSTATUS
NTAPI
NtQueryEaFile(
	IN HANDLE FileHandle,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID Buffer,
    IN ULONG BufferLength,
	IN BOOLEAN ByOne,
	IN PVOID EaList OPTIONAL,
	IN ULONG EaListLength,
	IN PVOID EaName OPTIONAL,
	IN BOOLEAN Reset 
	);

__kernel_entry NTSTATUS
NTAPI
NtSetEaFile(
	IN HANDLE FileHandle,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN PVOID EaBuffer,
	IN ULONG EaLength
	);

__kernel_entry NTSTATUS
NTAPI
NtQueryInformationFile(
    IN HANDLE FileHandle,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
    );

__kernel_entry NTSTATUS
NTAPI
NtSetInformationFile(
    IN HANDLE FileHandle,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
    );

//
// Специальные значения смещения
//

#define FILE_WRITE_TO_END_OF_FILE       0xffffffff
#define FILE_USE_FILE_POINTER_POSITION  0xfffffffe

__kernel_entry NTSTATUS
NTAPI
NtReadFile(
    IN HANDLE FileHandle,
    IN HANDLE Event OPTIONAL,
    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    IN PVOID ApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID Buffer,
    IN ULONG Length,
    IN PLARGE_INTEGER ByteOffset OPTIONAL,
    IN PULONG Key OPTIONAL
    );

__kernel_entry NTSTATUS
NTAPI
NtWriteFile(
    IN HANDLE FileHandle,
    IN HANDLE Event OPTIONAL,
    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    IN PVOID ApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID Buffer,
    IN ULONG Length,
    IN PLARGE_INTEGER ByteOffset OPTIONAL,
    IN PULONG Key OPTIONAL
    );

__kernel_entry NTSTATUS
NTAPI
NtQueryAttributesFile(
	IN POBJECT_ATTRIBUTES FileObjectAttributes,
	OUT PFILE_BASIC_INFORMATION FileAttributes
	);

#if (_WIN32_WINNT>=0x0400)

typedef struct __FULL_FILE_ATTRIBUTES_
{ 
	TIME CreationTime;
	TIME LastAccessTime;
	TIME LastWriteTime;
	TIME ChangeTime;
	LARGE_INTEGER EndOfFile;
	LARGE_INTEGER AllocationSize;
	ULONG FileAttributes;
} FULL_FILE_ATTRIBUTES, *PFULL_FILE_ATTRIBUTES;

__kernel_entry NTSTATUS
NTAPI
NtQueryFullAttributesFile(
	IN POBJECT_ATTRIBUTES FileObjectAttributes,
	OUT PFULL_FILE_ATTRIBUTES FullFileAttributes
	);

#endif //_WIN32_WINNT >= 0x0400

__kernel_entry NTSTATUS
NTAPI
NtDeleteFile(
	IN POBJECT_ATTRIBUTES FileObjectAttributes
	);


//Вспомогательные функции

typedef enum _DOS_PATHNAME_TYPE {
	Path_UNCFullName=1,// "\\x" или "\\.x" 
	Path_DeviceRootDir,// "x:\" 
	Path_StreamName,// "x:x" 
	Path_RelativeDir,// "\x" 
	Path_RelativeName,// "xx" 
	Path_UNCLocalName,// "\\.\"	
	Path_UNCLocalRoot // "\\.0" 
} DOS_PATHNAME_TYPE, *PDOS_PATHNAME_TYPE;

NTSYSAPI                                            
DOS_PATHNAME_TYPE
NTAPI                                               
RtlDetermineDosPathNameType_U(
	IN PCWSTR PathName
	);

typedef struct __RELATIVE_NAME_
{
	UNICODE_STRING Name;
	HANDLE CurrentDir;
} RELATIVE_NAME, *PRELATIVE_NAME;

NTSYSAPI
BOOLEAN 
NTAPI
RtlDosPathNameToNtPathName_U(
	IN PCWSTR DosPathName,
	OUT PUNICODE_STRING NtPathName,
	OUT PWSTR* FilePartInNtPathName OPTIONAL,
	OUT PRELATIVE_NAME RelativeName OPTIONAL
	);

NTSYSAPI ULONG NTAPI RtlGetCurrentDirectory_U(
    ULONG MaximumLength,
    PWSTR Buffer
    );

NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(
    IN PUNICODE_STRING name
    );


//Порт завершения операций ввода-вывода
#define IO_COMPLETION_QUERY_STATE   0x0001
#define IO_COMPLETION_MODIFY_STATE  0x0002  
#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) 

__kernel_entry NTSTATUS
NTAPI
NtCreateIoCompletion(
	OUT PHANDLE IoCompletionPortHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN ULONG NumberOfConcurrentThreads
	);

__kernel_entry NTSTATUS
NTAPI
NtOpenIoCompletion(
    OUT PHANDLE IoCompletionPortHandle,
    IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes
    );

__kernel_entry NTSTATUS
NTAPI
NtSetIoCompletion(
	IN HANDLE IoCompletionPortHandle,
	IN ULONG CompletionKey, //отдельная величина на каждый файл
	IN ULONG CompletionValue,//отдельная величина на каждую операцию
	IN NTSTATUS CompletionStatus,
	IN ULONG CompletionInformation
	);

__kernel_entry NTSTATUS
NTAPI
NtRemoveIoCompletion(
	IN HANDLE IoCompletionPortHandle,
	OUT PULONG CompletionKey, //отдельная величина на каждый файл
	OUT PULONG CompletionValue,//отдельная величина на каждую операцию
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN PTIME Timeout OPTIONAL 
	);

typedef enum _IOCOMPLETION_INFORMATION_CLASS {
	IoCompletionInfo
} IOCOMPLETION_INFORMATION_CLASS, *PIOCOMPLETION_INFORMATION_CLASS;

#include <pshpack4.h>
typedef struct __IOCOMPLETION_INFO_
{
	ULONG QueueLength;
} IOCOMPLETION_INFO, *PIOCOMPLETION_INFO;
#include <poppack.h>

__kernel_entry NTSTATUS
NTAPI
NtQueryIoCompletion(
	IN HANDLE IoCompletionPortHandle,
	IN IOCOMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
    OUT PVOID IoCompletionInformation,
    IN ULONG Length,
	OUT PULONG LengthReturned OPTIONAL
	);


//Функции ожидания
#define MAXIMUM_WAIT_OBJECTS 64

//
// use the Win32 API instead
//     WaitForSingleObjectEx
//
__kernel_entry NTSTATUS
NTAPI
NtWaitForSingleObject (
    IN HANDLE Handle,
    IN BOOLEAN Alertable,
    IN PLARGE_INTEGER Timeout OPTIONAL
    );

typedef enum _WAIT_TYPE {
    WaitAll,
    WaitAny
    } WAIT_TYPE;

__kernel_entry NTSTATUS
NTAPI
NtWaitForMultipleObjects(
	IN ULONG NumberOfHandles,
	IN PHANDLE ArrayOfHandles,
	IN WAIT_TYPE WaitType,
	IN BOOLEAN Alertable, 
    IN PLARGE_INTEGER Timeout OPTIONAL
	);

__kernel_entry NTSTATUS
NTAPI
NtDelayExecution(
	IN BOOLEAN Alertable, 
    IN PLARGE_INTEGER Timeout
	);


//
// use the Win32 API instead
//     CheckNameLegalDOS8Dot3
//
BOOLEAN
NTAPI 
RtlIsNameLegalDOS8Dot3 (
    IN PUNICODE_STRING Name,
    IN OUT POEM_STRING OemName OPTIONAL,
    IN OUT PBOOLEAN NameContainsSpaces OPTIONAL
    );

//
// This function might be needed for some of the internal Windows functions,
// defined in this header file.
//
//Преобразование статуса в ошибку
_When_(Status < 0, _Out_range_(>, 0))
_When_(Status >= 0, _Out_range_(==, 0))
ULONG
NTAPI 
RtlNtStatusToDosError (
   NTSTATUS Status
   );

//
// use the Win32 APIs instead
//     GetFileInformationByHandle
//     GetFileInformationByHandleEx
//     GetProcessInformation
//     GetThreadInformation
//     
__kernel_entry NTSTATUS
NTAPI
NtQueryObject (
    _In_opt_ HANDLE Handle,
    _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
    _Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
    _In_ ULONG ObjectInformationLength,
    _Out_opt_ PULONG ReturnLength
    );


//
// use the Win32 API instead
//     GetSystemTimeAsFileTime
//
__kernel_entry NTSTATUS
NTAPI 
NtQuerySystemTime (
    OUT PLARGE_INTEGER SystemTime
    );

//
// use the Win32 API instead
//     LocalFileTimeToFileTime
//
__kernel_entry NTSTATUS
NTAPI
RtlLocalTimeToSystemTime (
    IN PLARGE_INTEGER LocalTime,
    OUT PLARGE_INTEGER SystemTime
    );

//
// use the Win32 API instead
//     SystemTimeToFileTime to convert to FILETIME structures
//     copy the resulting FILETIME structures to ULARGE_INTEGER structures
//     perform the calculation
//
__kernel_entry BOOLEAN
NTAPI 
RtlTimeToSecondsSince1970 (
    PLARGE_INTEGER Time,
    PULONG ElapsedSeconds
    );


#define LOGONID_CURRENT     ((ULONG)-1)
#define SERVERNAME_CURRENT  ((HANDLE)NULL)

typedef enum _WINSTATIONINFOCLASS {
    WinStationInformation = 8
} WINSTATIONINFOCLASS;


typedef struct __WINSTATIONINFORMATIONW_
{
    BYTE Reserved2[70];
    ULONG LogonId;
    BYTE Reserved3[1140];
} WINSTATIONINFORMATIONW, * PWINSTATIONINFORMATIONW;

//
// this function is implemented in winsta.dll (you need to loadlibrary to call this function)
// this internal function retrives the LogonId (also called SessionId) for the current process
// You should avoid using this function as it can change. you can retrieve the same information 
// Using public api WTSQuerySessionInformation. Pass WTSSessionId as the WTSInfoClass parameter
// 
typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)(
    HANDLE, ULONG, WINSTATIONINFOCLASS, PVOID, ULONG, PULONG );

//
// Generic test for success on any status value (non-negative numbers
// indicate success).
//

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif

//
// Generic test for information on any status value.
//

#ifndef NT_INFORMATION
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
#endif

//
// Generic test for warning on any status value.
//

#ifndef NT_WARNING
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
#endif

//
// Generic test for error on any status value.
//

#ifndef NT_ERROR
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
#endif

//++
//
// VOID
// InitializeObjectAttributes(
//     OUT POBJECT_ATTRIBUTES p,
//     IN PUNICODE_STRING n,
//     IN ULONG a,
//     IN HANDLE r,
//     IN PSECURITY_DESCRIPTOR s
//     )
//
//--

#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
    }
#endif

//
// Valid values for the Attributes field
//

#define OBJ_INHERIT             0x00000002L
#define OBJ_PERMANENT           0x00000010L
#define OBJ_EXCLUSIVE           0x00000020L
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define OBJ_OPENIF              0x00000080L
#define OBJ_OPENLINK            0x00000100L
#define OBJ_KERNEL_HANDLE       0x00000200L
#define OBJ_FORCE_ACCESS_CHECK  0x00000400L
#define OBJ_VALID_ATTRIBUTES    0x000007F2L

//
// Define the create disposition values
//

#define FILE_SUPERSEDE                  0x00000000
#define FILE_OPEN                       0x00000001
#define FILE_CREATE                     0x00000002
#define FILE_OPEN_IF                    0x00000003
#define FILE_OVERWRITE                  0x00000004
#define FILE_OVERWRITE_IF               0x00000005
#define FILE_MAXIMUM_DISPOSITION        0x00000005

//
// Define the create/open option flags
//

#define FILE_DIRECTORY_FILE                     0x00000001
#define FILE_WRITE_THROUGH                      0x00000002
#define FILE_SEQUENTIAL_ONLY                    0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008

#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
#define FILE_NON_DIRECTORY_FILE                 0x00000040
#define FILE_CREATE_TREE_CONNECTION             0x00000080

#define FILE_COMPLETE_IF_OPLOCKED               0x00000100
#define FILE_NO_EA_KNOWLEDGE                    0x00000200
#define FILE_OPEN_REMOTE_INSTANCE               0x00000400
#define FILE_RANDOM_ACCESS                      0x00000800

#define FILE_DELETE_ON_CLOSE                    0x00001000
#define FILE_OPEN_BY_FILE_ID                    0x00002000
#define FILE_OPEN_FOR_BACKUP_INTENT             0x00004000
#define FILE_NO_COMPRESSION                     0x00008000

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
#define FILE_OPEN_REQUIRING_OPLOCK              0x00010000
#endif

#define FILE_RESERVE_OPFILTER                   0x00100000
#define FILE_OPEN_REPARSE_POINT                 0x00200000
#define FILE_OPEN_NO_RECALL                     0x00400000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY          0x00800000

#define FILE_VALID_OPTION_FLAGS                 0x00ffffff
#define FILE_VALID_PIPE_OPTION_FLAGS            0x00000032
#define FILE_VALID_MAILSLOT_OPTION_FLAGS        0x00000032
#define FILE_VALID_SET_FLAGS                    0x00000036

//
// Define the I/O status information return values for NtCreateFile/NtOpenFile
//

#define FILE_SUPERSEDED                 0x00000000
#define FILE_OPENED                     0x00000001
#define FILE_CREATED                    0x00000002
#define FILE_OVERWRITTEN                0x00000003
#define FILE_EXISTS                     0x00000004
#define FILE_DOES_NOT_EXIST             0x00000005



#define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')


// Объект каталог

#define DIRECTORY_QUERY                 (0x0001)
#define DIRECTORY_TRAVERSE              (0x0002)
#define DIRECTORY_CREATE_OBJECT         (0x0004)
#define DIRECTORY_CREATE_SUBDIRECTORY   (0x0008)

#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)

NTSTATUS
NTAPI
NtCreateDirectoryObject(
    OUT PHANDLE DirectoryHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

NTSTATUS 
NTAPI
NtOpenDirectoryObject(
    OUT PHANDLE DirectoryHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

typedef struct __OBJECT_NAMETYPE_INFO_
{
    UNICODE_STRING ObjectName;
    UNICODE_STRING ObjectType;
} OBJECT_NAMETYPE_INFO, *POBJECT_NAMETYPE_INFO;

typedef enum __DIRECTORYINFOCLASS_
{
	ObjectArray,
	ObjectByOne
} DIRECTORYINFOCLASS, *PDIRECTORYINFOCLASS;

#define QUERY_DIRECTORY_BUF_SIZE 0x200

NTSTATUS
NTAPI
NtQueryDirectoryObject(
	IN HANDLE DirectoryObjectHandle,
	OUT PVOID ObjectInfoBuffer,
	IN ULONG ObjectInfoBufferLength, 
	IN DIRECTORYINFOCLASS DirectoryInformationClass,
	IN BOOLEAN First, 
	IN OUT PULONG ObjectIndex,
	OUT PULONG LengthReturned
	);


// Объект символическая ссылка

#define SYMBOLIC_LINK_QUERY (0x0001)

#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)

NTSTATUS 
NTAPI
NtCreateSymbolicLinkObject(
    OUT PHANDLE ObjectHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
	IN PUNICODE_STRING SubstituteString
    );

NTSTATUS 
NTAPI
NtOpenSymbolicLinkObject(
    OUT PHANDLE ObjectHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

typedef struct __OBJECT_NAME_INFORMATION_
{               
    UNICODE_STRING Name;                                
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;   

NTSTATUS 
NTAPI
NtQuerySymbolicLinkObject(
	IN HANDLE ObjectHandle,
	OUT POBJECT_NAME_INFORMATION SubstituteString,
	OUT PULONG SubstituteStringLength //в байтах
	);


// Работа с "Критической Секцией"

NTSTATUS 
NTAPI
RtlInitializeCriticalSection(
    OUT PRTL_CRITICAL_SECTION pCriticalSection
                            );

NTSTATUS 
NTAPI
RtlInitializeCriticalSectionAndSpinCount(
    OUT PRTL_CRITICAL_SECTION pCriticalSection,
    IN LONG nSpinCount
                                        );

NTSTATUS 
NTAPI
RtlEnterCriticalSection(
    IN OUT PRTL_CRITICAL_SECTION pCriticalSection
                       );

NTSTATUS 
NTAPI
RtlLeaveCriticalSection(
    IN OUT PRTL_CRITICAL_SECTION pCriticalSection
                       );

NTSTATUS 
NTAPI
RtlDeleteCriticalSection(
    IN OUT PRTL_CRITICAL_SECTION pCriticalSection
                        );


// Объект событие

#define EVENT_QUERY_STATE       0x0001 
#define EVENT_MODIFY_STATE      0x0002  
#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) 

NTSYSAPI
NTSTATUS 
NTAPI
NtSetEvent(
	IN HANDLE EventHandle,
	IN PBOOLEAN OldState OPTIONAL
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtPulseEvent(
	IN HANDLE EventHandle,
	IN PBOOLEAN OldState OPTIONAL
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtResetEvent(
	IN HANDLE EventHandle,
	IN PBOOLEAN OldState OPTIONAL
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtClearEvent(
	IN HANDLE EventHandle
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtOpenEvent(
    OUT PHANDLE EventHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

typedef enum _EVENT_TYPE {
    NotificationEvent,	 //событие со сбросом вручную
    SynchronizationEvent //событие с автоматическим сбросом
    } EVENT_TYPE;

NTSYSAPI
NTSTATUS 
NTAPI
NtCreateEvent(
    OUT PHANDLE EventHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN EVENT_TYPE EventType,
	IN BOOLEAN InitialState 
	);

typedef enum __EVENTINFOCLASS_
{
	EventInfo
} EVENTINFOCLASS;

typedef struct __EVENT_INFO_
{
	EVENT_TYPE EventType;
	BOOLEAN Signaled;
} EVENT_INFO, *PEVENT_INFO;

NTSYSAPI
NTSTATUS 
NTAPI
NtQueryEvent(
	IN HANDLE EventHandle,
	IN EVENTINFOCLASS EventInformationClass,
	OUT PVOID EventInformation,
	IN ULONG EventInformationLength,
	OUT PULONG LengthReturned OPTIONAL 
	);


// Объект семафор

#define SEMAPHORE_QUERY_STATE       0x0001	
#define SEMAPHORE_MODIFY_STATE      0x0002  
#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) 

NTSYSAPI
NTSTATUS 
NTAPI
NtCreateSemaphore(
	OUT PHANDLE SemaphoreHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN ULONG InitialCount,
	IN ULONG MaximumCount
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtOpenSemaphore(
    OUT PHANDLE SemaphoreHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

NTSYSAPI
NTSTATUS 
NTAPI
NtReleaseSemaphore(
	IN HANDLE SemaphoreHandle,
	IN ULONG ReleaseCount,
	OUT PULONG PreviousCount OPTIONAL
	);

typedef enum _SEMAPHOREINFOCLASS {
	SemaphoreInfo
} SEMAPHOREINFOCLASS;

typedef struct __SEMAPHORE_INFO_
{
	ULONG CurrentCount;
	ULONG MaximumCount;
} SEMAPHORE_INFO, *PSEMAPHORE_INFO;

NTSYSAPI
NTSTATUS 
NTAPI
NtQuerySemaphore(
	IN HANDLE SemaphoreHandle,
	IN SEMAPHOREINFOCLASS SemaphoreInformationClass,
	OUT PVOID SemaphoreInformation,
	IN ULONG SemaphoreInformationLength,
	OUT PULONG LengthReturned OPTIONAL 
	);


// Объект "мутант"

#define MUTANT_QUERY_STATE      0x0001

#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|\
                          MUTANT_QUERY_STATE)
NTSYSAPI
NTSTATUS 
NTAPI
NtCreateMutant(
	OUT PHANDLE MutantHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
	IN BOOLEAN InitialOwner 
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtOpenMutant(
    OUT PHANDLE MutantHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

NTSYSAPI
NTSTATUS 
NTAPI
NtReleaseMutant(
	IN HANDLE MutantHandle,
	OUT PLONG OldOwnedCount OPTIONAL
	);

typedef enum __MUTANTINFOCLASS_
{
	MutantInfo
} MUTANTINFOCLASS;

typedef struct __MUTANT_INFO_
{
	LONG OwnedCount;
	BOOLEAN Owned;
} MUTANT_INFO, *PMUTANT_INFO;

NTSYSAPI
NTSTATUS 
NTAPI
NtQueryMutant(
	IN HANDLE MutantHandle,
	IN MUTANTINFOCLASS MutantInformationClass,
	OUT PVOID MutantInformation,
	IN ULONG MutantInformationLength,
	OUT PULONG LengthReturned OPTIONAL 
	);


// Функции работы с предупреждениями

NTSYSAPI
NTSTATUS 
NTAPI
NtAlertThread(
	IN HANDLE ThreadHandle
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtTestAlert(
	);


// Объект таймер

#define TIMER_QUERY_STATE       0x0001	
#define TIMER_MODIFY_STATE      0x0002  
#ifndef TIMER_ALL_ACCESS
#define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|\
                          TIMER_QUERY_STATE|TIMER_MODIFY_STATE)
#endif

#if (_WIN32_WINNT >= 0x0400)
typedef enum _TIMER_TYPE {
    NotificationTimer,	 //таймер со сбросом вручную
    SynchronizationTimer //таймер с автоматическим сбросом
    } TIMER_TYPE;
#endif //_WIN32_WINNT >= 0x0400

NTSYSAPI
NTSTATUS
NTAPI
NtCreateTimer(
    OUT PHANDLE TimerHandle,
    IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
#if (_WIN32_WINNT >= 0x0400)
	,IN TIMER_TYPE TimerType 
#endif
	);

NTSYSAPI
NTSTATUS
NTAPI
NtOpenTimer(
    OUT PHANDLE TimerHandle,
    IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
	);

NTSYSAPI
NTSTATUS
NTAPI
NtCancelTimer(
    IN HANDLE TimerHandle,
	IN PBOOLEAN OldState OPTIONAL
	);

#if !defined(_WINBASE) || (_WIN32_WINNT < 0400)

typedef
VOID
(NTAPI *PTIMERAPCROUTINE) (
    IN PVOID ApcContext,
    IN ULONG TimeLow,
    IN ULONG TimeHigh
    );

#endif

NTSYSAPI
NTSTATUS
NTAPI
NtSetTimer(
    IN HANDLE TimerHandle,
	IN PTIME DueTime,
	IN PTIMERAPCROUTINE TimerFunc OPTIONAL,
	IN PVOID ApcContext OPTIONAL,
	IN BOOLEAN Resume,
#if (_WIN32_WINNT >= 0x0400)
	IN LONG Period,	//в миллисекундах
#endif
	IN PBOOLEAN OldState OPTIONAL 
	);

typedef enum _TIMERINFOCLASS {
	TimerInfo
} TIMERINFOCLASS;

typedef struct __TIMER_INFO_
{ 
	TIME DueTime;
	BOOLEAN Signaled;
} TIMER_INFO, *PTIMER_INFO;

NTSYSAPI
NTSTATUS
NTAPI
NtQueryTimer(
	IN HANDLE TimerHandle,
	IN TIMERINFOCLASS TimerInformationClass,
	OUT PVOID TimerInformation,
	IN ULONG TimerInformationLength,
	OUT PULONG LengthReturned OPTIONAL 
	);

NTSYSAPI
NTSTATUS
NTAPI
NtSetTimerResolution(
	IN ULONG TimerResolution,
	IN BOOLEAN Set, 
	OUT PULONG SetTimerResolution 
	);

NTSYSAPI
NTSTATUS
NTAPI
NtQueryTimerResolution(
	OUT PULONG MaximumTimerResolution,
	OUT PULONG MinimumTimerResolution,
	OUT PULONG CurrentTimerResolution 
	);


// Время

typedef struct __TIME_FIELDS_
{
    USHORT Year;        // диапазон [1601...]
    USHORT Month;       // диапазон [1..12]
    USHORT Day;         // диапазон [1..31]
    USHORT Hour;        // диапазон [0..23]
    USHORT Minute;      // диапазон [0..59]
    USHORT Second;      // диапазон [0..59]
    USHORT Milliseconds;// диапазон [0..999]
    USHORT Weekday;     // диапазон [0..6] == [Воскресенье..Суббота]
} TIME_FIELDS;
typedef TIME_FIELDS *PTIME_FIELDS;

NTSYSAPI
VOID
NTAPI
RtlTimeToTimeFields (
    IN PTIME Time,
    OUT PTIME_FIELDS TimeFields
    );

NTSYSAPI
BOOLEAN
NTAPI
RtlTimeFieldsToTime (
    IN PTIME_FIELDS TimeFields,
    OUT PTIME Time
    );

//
// Define kernel debugger print prototypes and macros.
//
// N.B. The following function cannot be directly imported because there are
//      a few places in the source tree where this function is redefined.
//

VOID
NTAPI
DbgBreakPoint(
    VOID
    );

// end_wdm

NTSYSAPI
VOID
NTAPI
DbgBreakPointWithStatus(
    IN ULONG Status
    );

// begin_wdm

#define DBG_STATUS_CONTROL_C        1
#define DBG_STATUS_SYSRQ            2
#define DBG_STATUS_BUGCHECK_FIRST   3
#define DBG_STATUS_BUGCHECK_SECOND  4
#define DBG_STATUS_FATAL            5
#define DBG_STATUS_DEBUG_CONTROL    6

#if DBG

#define KdPrint(_x_) DbgPrint _x_
#define KdBreakPoint() DbgBreakPoint()

// end_wdm

#define KdBreakPointWithStatus(s) DbgBreakPointWithStatus(s)

// begin_wdm

#else

#define KdPrint(_x_)
#define KdBreakPoint()

// end_wdm

#define KdBreakPointWithStatus(s)

// begin_wdm
#endif

#ifndef _DBGNT_

ULONG
_cdecl
DbgPrint(
    PCH Format,
    ...
    );

// end_wdm

ULONG
_cdecl
DbgPrintReturnControlC(
    PCH Format,
    ...
    );

// begin_wdm
#endif // _DBGNT_



// Виртуальная память

#define PAGE_NOACCESS          0x01     
#define PAGE_READONLY          0x02     
#define PAGE_READWRITE         0x04     
#define PAGE_WRITECOPY         0x08     
#define PAGE_EXECUTE           0x10     
#define PAGE_EXECUTE_READ      0x20     
#define PAGE_EXECUTE_READWRITE 0x40     
#define PAGE_EXECUTE_WRITECOPY 0x80     
#define PAGE_GUARD            0x100     
#define PAGE_NOCACHE          0x200     

#define MEM_COMMIT           0x1000     
#define MEM_RESERVE          0x2000     
#define MEM_DECOMMIT         0x4000     
#define MEM_RELEASE          0x8000     
#define MEM_FREE            0x10000     
#define MEM_PRIVATE         0x20000     
#define MEM_MAPPED          0x40000     
#define MEM_TOP_DOWN       0x100000     
#define MEM_LARGE_PAGES  0x20000000
     
#define SEC_FILE           0x800000     
#define SEC_IMAGE         0x1000000     
#define SEC_RESERVE       0x4000000     
#define SEC_COMMIT        0x8000000     
#define SEC_NOCACHE      0x10000000     
#define MEM_IMAGE         SEC_IMAGE

NTSYSAPI
NTSTATUS 
NTAPI
NtAllocateVirtualMemory(
	IN HANDLE ProcessHandle,
	IN OUT PVOID *RegionAddress,
	IN ULONG ZeroBits,
    IN OUT SIZE_T *RegionSize,
	IN ULONG AllocationType,
	IN ULONG ProtectionType
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtFreeVirtualMemory(
	IN HANDLE ProcessHandle,
	IN OUT PVOID *RegionAddress,
    IN OUT SIZE_T *RegionSize,
	IN ULONG FreeType
	);

#define UNLOCK_TYPE_NON_PRIVILEGED	0x00000001L
#define UNLOCK_TYPE_PRIVILEGED		0x00000002L

NTSYSAPI
NTSTATUS 
NTAPI
NtLockVirtualMemory(
	IN HANDLE ProcessHandle,
	IN OUT PVOID *RegionAddress,
    IN OUT SIZE_T *RegionSize,
	IN ULONG UnlockTypeRequired
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtUnlockVirtualMemory(
	IN HANDLE ProcessHandle,
	IN OUT PVOID *RegionAddress,
    IN OUT SIZE_T *RegionSize,
	IN ULONG UnlockTypeRequiested
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtReadVirtualMemory(
	IN HANDLE ProcessHandle,
	IN PVOID StartAddress,
	OUT PVOID Buffer,
    IN SIZE_T BytesToRead,
    OUT SIZE_T *BytesReaded OPTIONAL
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtWriteVirtualMemory(
	IN HANDLE ProcessHandle,
	IN PVOID StartAddress,
	IN PVOID Buffer,
    IN SIZE_T BytesToWrite,
    OUT SIZE_T *BytesWritten OPTIONAL
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtProtectVirtualMemory(
	IN HANDLE ProcessHandle,
	IN OUT PVOID *RegionAddress,
	IN OUT SIZE_T *RegionSize,
	IN ULONG DesiredProtection,
	OUT PULONG OldProtection
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtFlushVirtualMemory(
	IN HANDLE ProcessHandle,
	IN PVOID* StartAddress,
    IN SIZE_T *BytesToFlush,
	OUT PIO_STATUS_BLOCK StatusBlock 
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtFlushInstructionCache(
	IN HANDLE   ProcessHandle,
	IN PVOID    StartAddress,
    IN SIZE_T   BytesToFlush
	);

typedef enum _MEMORYINFOCLASS {
	MemoryBasicInformation,
	MemoryEntryInformation
} MEMORYINFOCLASS;

typedef struct __MEMORY_ENTRY_INFORMATION_
{
	ULONG NumberOfEntries;
	PVOID Entries[ANYSIZE_ARRAY];
} MEMORY_ENTRY_INFORMATION, *PMEMORY_ENTRY_INFORMATION;

NTSYSAPI
NTSTATUS 
NTAPI
NtQueryVirtualMemory(
	IN HANDLE ProcessHandle,
	IN PVOID RegionAddress,
	IN MEMORYINFOCLASS MemoryInformationClass,
	IN PVOID VirtualMemoryInfo,
	IN ULONG Length,
	OUT PULONG ActualLength OPTIONAL
	);


// Куча

#define HEAP_NO_SERIALIZE               0x00000001      
#define HEAP_GROWABLE                   0x00000002      
#define HEAP_GENERATE_EXCEPTIONS        0x00000004      
#define HEAP_ZERO_MEMORY                0x00000008      
#define HEAP_REALLOC_IN_PLACE_ONLY      0x00000010      
#define HEAP_TAIL_CHECKING_ENABLED      0x00000020      
#define HEAP_FREE_CHECKING_ENABLED      0x00000040      
#define HEAP_DISABLE_COALESCE_ON_FREE   0x00000080      
#define HEAP_CREATE_ALIGN_16            0x00010000      
#define HEAP_CREATE_ENABLE_TRACING      0x00020000      
#define HEAP_MAXIMUM_TAG                0x0FFF              
#define HEAP_PSEUDO_TAG_FLAG            0x8000
#ifndef HEAP_TAG_SHIFT              
#define HEAP_TAG_SHIFT                  18                  
#define HEAP_MAKE_TAG_FLAGS( b, o ) ((DWORD)((b) + ((o) << 18))) 
#endif

typedef PVOID PHEAP_INFO;

NTSYSAPI
HANDLE 
NTAPI
RtlCreateHeap(
	IN ULONG    AllocationFlags,
	IN PVOID    BaseAddress OPTIONAL,
    IN SIZE_T   MaximumSize,
    IN SIZE_T   InitialSize,
	IN PVOID    UnknownAddress OPTIONAL,
	IN PHEAP_INFO HeapInfo OPTIONAL 
	);

NTSYSAPI
PVOID
NTAPI
RtlAllocateHeap(
	IN HANDLE HeapHandle,
	IN ULONG AllocationFlags,
    IN SIZE_T NumberOfBytes
	);

NTSYSAPI
PVOID
NTAPI
RtlReAllocateHeap(
	IN HANDLE   HeapHandle,
	IN ULONG    AllocationFlags,
	IN PVOID    MemoryBlock,
    IN SIZE_T   NumberOfBytes
	);

NTSYSAPI
BOOLEAN
NTAPI
RtlFreeHeap(
    IN HANDLE HeapHandle,
    IN ULONG FreeingFlags,
    IN PVOID MemoryBlock
   );

NTSYSAPI
SIZE_T
NTAPI
RtlSizeHeap(
	IN HANDLE HeapHandle,
	IN ULONG AllocationFlags,
	IN PVOID MemoryBlock
	);

NTSYSAPI
PVOID   
NTAPI
RtlDestroyHeap(
	IN HANDLE HeapHandle
	);

NTSYSAPI
BOOLEAN
NTAPI
RtlValidateHeap(
	IN HANDLE HeapHandle,
	IN ULONG AccessFlags,
	IN PVOID MemoryBlock OPTIONAL
	);

NTSYSAPI
ULONG 
NTAPI
RtlGetProcessHeaps(
	IN ULONG NumberOfHeaps,
	OUT PHANDLE ProcessHeaps 
	);

NTSYSAPI
ULONG 
NTAPI
RtlCompactHeap(
	IN HANDLE HeapHandle,
	IN ULONG AccessFlags
	);

NTSYSAPI
BOOLEAN
NTAPI
RtlLockHeap(
	IN HANDLE HeapHandle
	);

NTSYSAPI
BOOLEAN
NTAPI
RtlUnlockHeap(
	IN HANDLE HeapHandle
	);

typedef struct __RTL_PROCESS_HEAP_ENTRY_
{
    PVOID lpData;
    ULONG cbData;
    UCHAR cbOverhead;
    UCHAR iRegionIndex;
    SHORT wFlags;
    union {
        struct {
            HANDLE hMem;
            ULONG dwReserved[ 3 ];
        } Block;
        struct {
            ULONG dwCommittedSize;
            ULONG dwUnCommittedSize;
            PVOID lpFirstBlock;
            PVOID lpLastBlock;
        } Region;
    };
} RTL_PROCESS_HEAP_ENTRY, *PRTL_PROCESS_HEAP_ENTRY;

#define RTL_PROCESS_HEAP_REGION					0x0002
#define RTL_PROCESS_HEAP_UNCOMMITTED_RANGE		0x0100
#define RTL_PROCESS_HEAP_ENTRY_BUSY				0x0001
#define RTL_PROCESS_HEAP_ENTRY_MOVEABLE			0x0200
#define RTL_PROCESS_HEAP_ENTRY_DDESHARE_BUSY    0x0400

NTSYSAPI
BOOLEAN
NTAPI
RtlWalkHeap(
    IN HANDLE HeapHandle,
    IN OUT PRTL_PROCESS_HEAP_ENTRY EntryInfo
    );

NTSYSAPI
ULONG 
NTAPI
RtlCreateTagHeap(	
	IN HANDLE HeapHandle,
	IN ULONG Flags,
	IN PCWSTR TagName,
	IN PCWSTR TagSubName
	);

#include <pshpack4.h>
typedef struct __RTL_HEAP_TAG_INFO_
{
	ULONG AllocCount;
	ULONG FreeCount;
	ULONG MemoryUsed;
} RTL_HEAP_TAG_INFO, *LPRTL_HEAP_TAG_INFO, *PRTL_HEAP_TAG_INFO;
#include <poppack.h>

NTSYSAPI
PCWSTR 
NTAPI
RtlQueryTagHeap(
	IN HANDLE HeapHandle,
	IN ULONG Flags,
	IN USHORT TagNumber,
	IN BOOLEAN ZeroInternalTagInfo,
	OUT PRTL_HEAP_TAG_INFO HeapTagInfo OPTIONAL 
	);


// Загрузчик

NTSYSAPI
VOID 
NTAPI
LdrShutdownThread(
	VOID
	);

NTSYSAPI
VOID 
NTAPI
LdrShutdownProcess(
	VOID
	);

NTSYSAPI
VOID 
NTAPI
LdrFlushAlternateResourceModules(
	VOID
                                );

NTSYSAPI
NTSTATUS
NTAPI
LdrDisableThreadCalloutsForDll(
	IN HANDLE DllHandle
	);

NTSYSAPI
NTSTATUS
NTAPI
LdrUnloadDll(
	IN HANDLE DllHandle
	);

NTSYSAPI
NTSTATUS
NTAPI
LdrGetDllHandle(
	IN PCWSTR SearchPaths OPTIONAL,
	IN ULONG Reserved,	
	IN PUNICODE_STRING ModuleName,
	OUT PHANDLE DllHandle
	);

#define LDR_DONT_RESOLVE_DLL_REFERENCES	0x00000002L

NTSYSAPI
NTSTATUS
NTAPI
LdrLoadDll(
	IN PCWSTR SearchPaths OPTIONAL,
	IN PULONG ActionWhenLoading OPTIONAL,
	IN PUNICODE_STRING ModuleName,
	OUT PHANDLE DllHandle
	);

NTSYSAPI
NTSTATUS
NTAPI
LdrGetProcedureAddress(
	IN HANDLE ModuleHandle,
	IN PSTRING ProcedureName OPTIONAL,
	IN ULONG ProcedureOrdinalValue OPTIONAL,
	OUT PVOID *ProcedureAddress
	);

NTSYSAPI
NTSTATUS
NTAPI
LdrVerifyImageMatchesChecksum(
	IN HANDLE FileHandle
	);

//SubKey under "\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\"
NTSYSAPI
NTSTATUS
NTAPI
LdrQueryImageFileExecutionOptions(
	IN PUNICODE_STRING SubKey,
	IN PCWSTR ValueName,
	IN ULONG ValueSize,
	OUT PVOID Buffer,
	IN ULONG BufferSize,
	OUT PULONG ReturnedLength OPTIONAL
	);

NTSYSAPI
ULONG
NTAPI
RtlRemoteCall(
    HANDLE hProcess,
    HANDLE hThread,
    FARPROC pfCalledRoutine,
    DWORD UnknownParam1,
    DWORD UnknownParam2,
    DWORD UnknownParam3,
    DWORD UnknownParam4
             );

NTSYSAPI
NTSTATUS
NTAPI
NtAlertThread(
    IN HANDLE hThreadHandle
             );


// Получение заголовков исполняемого файла

NTSYSAPI
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(
IN HANDLE InstanceHandle
);


// Блок переменных окружения

NTSYSAPI
NTSTATUS
NTAPI
RtlCreateEnvironment(
	IN BOOLEAN CopyCurrent,
	OUT PVOID* EnvironmentBlock
	);

NTSYSAPI                                            
NTSTATUS
NTAPI                                               
RtlDestroyEnvironment(
	IN PVOID EnvironmentBlock
	);

NTSYSAPI
NTSTATUS
NTAPI
RtlExpandEnvironmentStrings_U(
	IN PVOID EnvironmentBlock OPTIONAL,
	IN PUNICODE_STRING SourceString,
	OUT PUNICODE_STRING ExpandedString,
	OUT PULONG BytesRequired
	);

NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentVariable(
	IN PVOID EnvironmentBlock OPTIONAL,
	IN PUNICODE_STRING VariableName,
	IN PUNICODE_STRING VariableValue OPTIONAL
	);

NTSYSAPI
NTSTATUS
NTAPI
RtlQueryEnvironmentVariable_U(
	IN PVOID EnvironmentBlock OPTIONAL,
	IN PUNICODE_STRING VariableName,
	OUT PUNICODE_STRING VariableValue
	);

NTSYSAPI
NTSTATUS
NTAPI
RtlSetCurrentEnvironment(
	PVOID NewEnvironmentBlock,
	PVOID* OldEnvironmentBlock OPTIONAL
	);

// Вспомогательная функция для BootExecute-программ

NTSYSAPI
VOID 
NTAPI
NtDisplayString(
	IN PUNICODE_STRING DisplayString
	);

//Полезные макросы

#define NtGetProcessHeap()		(NtCurrentTeb()->PebBaseAddress->DefaultHeap)



// объект "порт"

typedef struct __TPortMessageHeader_
{
    WORD        wMessageDataLength;
    WORD        wMessageLength;
    WORD        wMsgCodeLow;
    WORD        wMsgCodeHigh;
    CLIENT_ID   stClientID;
    DWORD       field_10;
    DWORD       dwPortSectionCreated;
////  Port Message Data begin ////////////////////
//  BYTE    arPortMessageData[wMessageDataLength];
} TPortMessageHeader, *PTPortMessageHeader;

typedef struct __TAcceptPortSectionDescr_
{
    DWORD   dwAllocSize;        // = 0x0C;
    DWORD   dwPortSectionSize;
    PVOID   pPortSectionBaseVA;
} TAcceptPortSectionDescr, *PTAcceptPortSectionDescr;

typedef struct __TConnectPortStruct
{
    DWORD   dwStructSize;           // = sizeof TConnectPortStruct; (0x18)
    HANDLE  hPortSection;
    DWORD   field_8;                // = 0;
    DWORD   dwSectionSize;
    PVOID   pSectionStartVA;
    PVOID   pSectionStopVA;
} TConnectPortStruct, *PTConnectPortStruct;

typedef struct __TPortAuthStruct_
{
    DWORD   dwUnknown;
    SID_IDENTIFIER_AUTHORITY TopLevelAuth;
} TPortAuthStruct, *PTPortAuthStruct;

NTSYSAPI
NTSTATUS 
NTAPI
NtCreatePort(
    OUT PHANDLE phPortHandle,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN ULONG    MessageConnectDataLength,   // = 0x0C
    IN ULONG    MessageLengthMax,
    IN ACCESS_MASK DesiredAccess
            );

NTSYSAPI
NTSTATUS 
NTAPI
NtConnectPort(
    OUT PHANDLE phPortHandle,
    IN PUNICODE_STRING  pusPortName,    // полный путь в дереве объектов
    IN PTPortAuthStruct pPortAuthStruct,
    DWORD   Unknown1,
    IN OUT PTAcceptPortSectionDescr pAcceptPortSectionDescr OPTIONAL,
    DWORD   Unknown3,
    IN OUT PVOID    pConnectPortMsg,
    IN OUT PDWORD   pdwMessageLength
             );

NTSYSAPI
NTSTATUS 
NTAPI
NtRequestWaitReplyPort(
    IN HANDLE   hPortHandle,
    IN PVOID    pRequestMessage,    // Какое из двух сообщений исходящее, а какое входящее
    OUT PVOID   pReplyMessage       // я точно не знаю. В "termsrv.exe" они совмещены.
                      );            // А разбираться с этим - облом.          Сергей Дюков.

NTSYSAPI
NTSTATUS 
NTAPI
NtAcceptConnectPort(
    OUT PHANDLE phAcceptPortHandle,
    IN PVOID    pAcceptPortStruct OPTIONAL, // для "WinApiPort" значение PVOID(pClientApiDescr->dwClientIndx)
    IN PVOID    pConnectPortMsg,
    IN BOOLEAN  bSectionCreated,
    IN OUT PTConnectPortStruct   pConnectPortStruct OPTIONAL,
    OUT PTAcceptPortSectionDescr pAcceptPortSectionDescr
                   );

NTSYSAPI
NTSTATUS 
NTAPI
NtCompleteConnectPort(
    IN HANDLE hAcceptPortHandle
                     );

NTSYSAPI
NTSTATUS 
NTAPI
NtReplyWaitReceivePort(
    IN HANDLE   hPortHandle,
    OUT PVOID   *ppAcceptConnectPortStruct,
    IN PVOID    pReplyMsg OPTIONAL,
    OUT PVOID   pReceiveMsg
                      );

NTSYSAPI
NTSTATUS 
NTAPI
NtReplyPort(
    IN HANDLE   hPortHandle,
    IN PVOID    pReplyMsg
           );


// Win32 Server Routines

typedef struct __TCaptureBuffer_
{
    DWORD       dwAllocatedSize;        // 0000
    DWORD       field_4;                // 0004
    DWORD       dwSlotsMaped;           // 0008
    PVOID       pNextDataPtr;           // 000C
//// Slots array and Message Data /////////////
//  PVOID*      Slots[dwSlotsCount];    // 0010
//  BYTE        MsgData[dwDataSize];
} TCaptureBuffer, *PTCaptureBuffer;

typedef struct __TWin32ApiMsg_
{
    WORD        wMessageDataLength;     // 0000
    WORD        wMessageLength;         // 0002
    WORD        wMsgCodeLow;            // 0004
    WORD        wMsgCodeHigh;           // 0006
    CLIENT_ID   stClientID;             // 0008
    DWORD       field_10;               // 0010
    DWORD       dwPortSectionCreated;   // 0014
////  Port Message Data begin  ////////////////
    PTCaptureBuffer pMsgBuffer;         // 0018
    WORD            wDispatchCode;      // 001C
    WORD            wSrvIndx;           // 001E
    NTSTATUS        dwNtStatus;         // 0020
    DWORD           field_24;           // 0024
////  Message specific fields  ////////////////
//  BYTE                MsgDataFields[nApiDataLength];  // 0028
} TWin32ApiMsg, *PTWin32ApiMsg;

NTSYSAPI
NTSTATUS 
NTAPI
CsrClientCallServer(
    PTWin32ApiMsg pWin32ApiMsg,
    PTCaptureBuffer pCaptureBuffer,
    DWORD dwDispatchStruct,
    LONG nApiDataLength
                   );

NTSYSAPI
NTSTATUS 
NTAPI
CsrClientConnectToServer(
    PCWSTR   pWindowsDirectoryObjectPath,
    DWORD    dwDllID,
    PVOID pClientDllDescr OPTIONAL,
    PVOID    pTransferData,
    PDWORD   pdwDataLength,
    PBOOLEAN pbNativeProcess OPTIONAL
                        );


// Система безопосности

//
// These must be converted to LUIDs before use.
//

#define SE_MIN_WELL_KNOWN_PRIVILEGE       (2L)
#define SE_CREATE_TOKEN_PRIVILEGE         (2L)
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE   (3L)
#define SE_LOCK_MEMORY_PRIVILEGE          (4L)
#define SE_INCREASE_QUOTA_PRIVILEGE       (5L)

//
// Unsolicited Input is obsolete and unused.
//

#define SE_UNSOLICITED_INPUT_PRIVILEGE    (6L)

#define SE_MACHINE_ACCOUNT_PRIVILEGE      (6L)
#define SE_TCB_PRIVILEGE                  (7L)
#define SE_SECURITY_PRIVILEGE             (8L)
#define SE_TAKE_OWNERSHIP_PRIVILEGE       (9L)
#define SE_LOAD_DRIVER_PRIVILEGE          (10L)
#define SE_SYSTEM_PROFILE_PRIVILEGE       (11L)
#define SE_SYSTEMTIME_PRIVILEGE           (12L)
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE  (13L)
#define SE_INC_BASE_PRIORITY_PRIVILEGE    (14L)
#define SE_CREATE_PAGEFILE_PRIVILEGE      (15L)
#define SE_CREATE_PERMANENT_PRIVILEGE     (16L)
#define SE_BACKUP_PRIVILEGE               (17L)
#define SE_RESTORE_PRIVILEGE              (18L)
#define SE_SHUTDOWN_PRIVILEGE             (19L)
#define SE_DEBUG_PRIVILEGE                (20L)
#define SE_AUDIT_PRIVILEGE                (21L)
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE   (22L)
#define SE_CHANGE_NOTIFY_PRIVILEGE        (23L)
#define SE_REMOTE_SHUTDOWN_PRIVILEGE      (24L)
#define SE_UNDOCK_PRIVILEGE               (25L)
#define SE_SYNC_AGENT_PRIVILEGE           (26L)
#define SE_ENABLE_DELEGATION_PRIVILEGE    (27L)
#define SE_MAX_WELL_KNOWN_PRIVILEGE       (SE_ENABLE_DELEGATION_PRIVILEGE)

NTSYSAPI
NTSTATUS
NTAPI
RtlAdjustPrivilege(
	IN ULONG Privilege,         //SE_xxx_PRIVILEGE
	IN BOOLEAN Enable,
	IN BOOLEAN CurrentThread,   //FALSE-CurrentProcess
	OUT PBOOLEAN Enabled 
	);

NTSYSAPI
NTSTATUS 
NTAPI
NtPrivilegeCheck(               // PrivilegeCheck
    IN HANDLE ClientToken,
    IN PPRIVILEGE_SET RequiredPrivileges,
    OUT PBOOLEAN pfResult
                );

NTSYSAPI
NTSTATUS 
NTAPI
NtPrivilegeObjectAuditAlarm(    // ObjectPrivilegeAuditAlarmW
    IN PUNICODE_STRING SubsystemName,   // subsystem name
    IN LPVOID HandleId OPTIONAL,        // handle identifier
    IN HANDLE ClientToken,              // handle to client's access token
    IN DWORD DesiredAccess,             // desired access rights
    IN PPRIVILEGE_SET Privileges,       // privileges
    IN BOOLEAN AccessGranted            // results
                           );

NTSYSAPI
NTSTATUS 
NTAPI
NtOpenThreadToken(              // OpenThreadToken
    IN HANDLE ThreadHandle,
    IN DWORD DesiredAccess,
    IN BOOLEAN OpenAsSelf,
    OUT PHANDLE TokenHandle
                 );

NTSYSAPI
NTSTATUS 
NTAPI
NtOpenProcessToken(             // OpenProcessToken
    IN HANDLE ProcessHandle,
    IN ULONG DesiredAccess,
    OUT PHANDLE TokenHandle
                  );

NTSYSAPI
NTSTATUS 
NTAPI
NtQueryInformationToken(        // GetTokenInformation
    IN HANDLE TokenHandle,
    IN TOKEN_INFORMATION_CLASS TokenInformationClass,
    OUT LPVOID TokenInformation,
    IN ULONG TokenInformationLength,
    OUT PULONG ReturnLength OPTIONAL
                       );

NTSYSAPI
ULONG 
NTAPI
RtlLengthSid(                   // GetLengthSid
    IN PSID pSid
            );

NTSYSAPI
NTSTATUS 
NTAPI
RtlCopySid(                     // CopySid
    IN DWORD nDestinationSidLength,
    OUT PSID pDestinationSid,
    IN PSID  pSourceSid
          );

NTSYSAPI
NTSTATUS 
NTAPI
RtlCreateSecurityDescriptor(    // InitializeSecurityDescriptor
    OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
    IN ULONG dwRevision
                           );

NTSYSAPI
NTSTATUS 
NTAPI
RtlCreateAcl(                   // InitializeAcl
    OUT PACL pAcl,
    IN DWORD nAclLength,
    IN DWORD dwAclRevision
            );

NTSYSAPI
NTSTATUS 
NTAPI
RtlAddAce(                      // AddAce
    IN OUT PACL pAcl,
    IN DWORD dwAceRevision,
    IN DWORD dwStartingAceIndex,
    IN LPVOID pAceList,
    IN DWORD nAceListLength
         );

NTSYSAPI
NTSTATUS 
NTAPI
RtlAddAccessAllowedAce(         // AddAccessAllowedAce
    IN OUT PACL pAcl,
    IN DWORD dwAceRevision,
    IN DWORD AccessMask,
    IN PSID  pSid
                      );

NTSYSAPI
NTSTATUS 
NTAPI
RtlGetAce(                      // GetAce
    IN PACL  pAcl,
    IN DWORD dwAceIndex,
    OUT LPVOID *pAce
         );

NTSYSAPI
NTSTATUS 
NTAPI
RtlSetDaclSecurityDescriptor(   // SetSecurityDescriptorDacl
    IN OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
    IN BOOLEAN bDaclPresent,
    IN PACL    pDacl,
    IN BOOLEAN bDaclDefaulted
                            );

NTSYSAPI
NTSTATUS 
NTAPI
NtSetSecurityObject(            // SetKernelObjectSecurity
    IN HANDLE Handle,
    IN SECURITY_INFORMATION SecurityInformation,
    IN PSECURITY_DESCRIPTOR SecurityDescriptor
                   );

NTSYSAPI
NTSTATUS 
NTAPI
RtlAllocateAndInitializeSid(    // AllocateAndInitializeSid
    IN PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
    IN BYTE nSubAuthorityCount,
    IN DWORD dwSubAuthority0,
    IN DWORD dwSubAuthority1,
    IN DWORD dwSubAuthority2,
    IN DWORD dwSubAuthority3,
    IN DWORD dwSubAuthority4,
    IN DWORD dwSubAuthority5,
    IN DWORD dwSubAuthority6,
    IN DWORD dwSubAuthority7,
    OUT PSID *pSid
                           );

NTSYSAPI
NTSTATUS 
NTAPI
RtlFreeSid(
    IN PSID pSid
          );

NTSYSAPI
NTSTATUS 
NTAPI
RtlGetDaclSecurityDescriptor(   // GetSecurityDescriptorDacl
    IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
    OUT PBOOLEAN lpbDaclPresent,
    OUT PACL *pDacl,
    OUT PBOOLEAN lpbDaclDefaulted
                            );

NTSYSAPI
ULONG 
NTAPI
RtlLengthRequiredSid(           // GetSidLengthRequired
    IN ULONG nSubAuthorityCount
                    );

NTSYSAPI
NTSTATUS 
NTAPI
RtlInitializeSid(               // InitializeSid
    OUT PSID Sid,
    IN PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
    IN BYTE nSubAuthorityCount
                );

NTSYSAPI
PDWORD 
NTAPI
RtlSubAuthoritySid(             // GetSidSubAuthority
    IN PSID pSid,
    IN DWORD nSubAuthority
                  );


// Error Message Service

NTSYSAPI
NTSTATUS 
NTAPI
RtlFindMessage(
    IN HANDLE   hModule,
    IN DWORD    dwFlags,
    IN DWORD    dwParam3,
    IN DWORD    dwStrIndx,
    OUT PWSTR   *ppwsMessage
              );


//
//  Doubly-linked list manipulation routines.
//

//
//  VOID
//  InitializeListHead32(
//      PLIST_ENTRY32 ListHead
//      );
//

#define InitializeListHead32(ListHead) (\
    (ListHead)->Flink = (ListHead)->Blink = PtrToUlong((ListHead)))

#define RTL_STATIC_LIST_HEAD(x) LIST_ENTRY x = { &x, &x }

FORCEINLINE
VOID
InitializeListHead(
    _Out_ PLIST_ENTRY ListHead
    )

{

    ListHead->Flink = ListHead->Blink = ListHead;
    return;
}

_Must_inspect_result_
BOOLEAN
CFORCEINLINE
IsListEmpty(
    _In_ const LIST_ENTRY * ListHead
    )

{

    return (BOOLEAN)(ListHead->Flink == ListHead);
}

FORCEINLINE
BOOLEAN
RemoveEntryListUnsafe(
    _In_ PLIST_ENTRY Entry
    )

{

    PLIST_ENTRY Blink;
    PLIST_ENTRY Flink;

    Flink = Entry->Flink;
    Blink = Entry->Blink;
    Blink->Flink = Flink;
    Flink->Blink = Blink;
    return (BOOLEAN)(Flink == Blink);
}

#if defined(NO_KERNEL_LIST_ENTRY_CHECKS)

FORCEINLINE
BOOLEAN
RemoveEntryList(
    _In_ PLIST_ENTRY Entry
    )

{

    PLIST_ENTRY Blink;
    PLIST_ENTRY Flink;

    Flink = Entry->Flink;
    Blink = Entry->Blink;
    Blink->Flink = Flink;
    Flink->Blink = Blink;
    return (BOOLEAN)(Flink == Blink);
}

FORCEINLINE
PLIST_ENTRY
RemoveHeadList(
    _Inout_ PLIST_ENTRY ListHead
    )

{

    PLIST_ENTRY Flink;
    PLIST_ENTRY Entry;

    Entry = ListHead->Flink;
    Flink = Entry->Flink;
    ListHead->Flink = Flink;
    Flink->Blink = ListHead;
    return Entry;
}



FORCEINLINE
PLIST_ENTRY
RemoveTailList(
    _Inout_ PLIST_ENTRY ListHead
    )

{

    PLIST_ENTRY Blink;
    PLIST_ENTRY Entry;

    Entry = ListHead->Blink;
    Blink = Entry->Blink;
    ListHead->Blink = Blink;
    Blink->Flink = ListHead;
    return Entry;
}


FORCEINLINE
VOID
InsertTailList(
    _Inout_ PLIST_ENTRY ListHead,
    _Inout_ __drv_aliasesMem PLIST_ENTRY Entry
    )
{

    PLIST_ENTRY Blink;

    Blink = ListHead->Blink;
    Entry->Flink = ListHead;
    Entry->Blink = Blink;
    Blink->Flink = Entry;
    ListHead->Blink = Entry;
    return;
}


FORCEINLINE
VOID
InsertHeadList(
    _Inout_ PLIST_ENTRY ListHead,
    _Inout_ __drv_aliasesMem PLIST_ENTRY Entry
    )
{

    PLIST_ENTRY Flink;

    Flink = ListHead->Flink;
    Entry->Flink = Flink;
    Entry->Blink = ListHead;
    Flink->Blink = Entry;
    ListHead->Flink = Entry;
    return;
}

FORCEINLINE
VOID
AppendTailList(
    _Inout_ PLIST_ENTRY ListHead,
    _Inout_ PLIST_ENTRY ListToAppend
    )
{

    PLIST_ENTRY ListEnd = ListHead->Blink;

    ListHead->Blink->Flink = ListToAppend;
    ListHead->Blink = ListToAppend->Blink;
    ListToAppend->Blink->Flink = ListHead;
    ListToAppend->Blink = ListEnd;
    return;
}

#else // NO_KERNEL_LIST_ENTRY_CHECKS

//++
//VOID
//FatalListEntryError (
//    _In_ PVOID p1,
//    _In_ PVOID p2,
//    _In_ PVOID p3
//    );
//
// Routine Description:
//
//    This routine reports a fatal list entry error.  It is implemented here as a
//    wrapper around RtlFailFast so that alternative reporting mechanisms (such
//    as simply logging and trying to continue) can be easily switched in.
//
// Arguments:
//
//    p1 - Supplies the first failure parameter.
//
//    p2 - Supplies the second failure parameter.
//
//    p3 - Supplies the third failure parameter.
//
//Return Value:
//
//    None.
//--

FORCEINLINE
VOID
FatalListEntryError(
    _In_ PVOID p1,
    _In_ PVOID p2,
    _In_ PVOID p3
    )

{
    UNREFERENCED_PARAMETER(p1);
    UNREFERENCED_PARAMETER(p2);
    UNREFERENCED_PARAMETER(p3);
    assert(FALSE);
    RtlExitUserProcess(FAST_FAIL_CORRUPT_LIST_ENTRY);
}

FORCEINLINE
VOID
RtlpCheckListEntry(
    _In_ PLIST_ENTRY Entry
    )

{

    if ((((Entry->Flink)->Blink) != Entry) || (((Entry->Blink)->Flink) != Entry)) {
        FatalListEntryError((PVOID)(Entry),
                            (PVOID)((Entry->Flink)->Blink),
                            (PVOID)((Entry->Blink)->Flink));
    }
}


FORCEINLINE
BOOLEAN
RemoveEntryList(
    _In_ PLIST_ENTRY Entry
    )

{

    PLIST_ENTRY PrevEntry;
    PLIST_ENTRY NextEntry;

    NextEntry = Entry->Flink;
    PrevEntry = Entry->Blink;
    if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry)) {
        FatalListEntryError((PVOID)PrevEntry,
                            (PVOID)Entry,
                            (PVOID)NextEntry);
    }

    PrevEntry->Flink = NextEntry;
    NextEntry->Blink = PrevEntry;
    return (BOOLEAN)(PrevEntry == NextEntry);
}

FORCEINLINE
PLIST_ENTRY
RemoveHeadList(
    _Inout_ PLIST_ENTRY ListHead
    )

{

    PLIST_ENTRY Entry;
    PLIST_ENTRY NextEntry;

    Entry = ListHead->Flink;

#if DBG

    RtlpCheckListEntry(ListHead);

#endif

    NextEntry = Entry->Flink;
    if ((Entry->Blink != ListHead) || (NextEntry->Blink != Entry)) {
        FatalListEntryError((PVOID)ListHead,
                            (PVOID)Entry,
                            (PVOID)NextEntry);
    }

    ListHead->Flink = NextEntry;
    NextEntry->Blink = ListHead;

    return Entry;
}

FORCEINLINE
PLIST_ENTRY
RemoveTailList(
    _Inout_ PLIST_ENTRY ListHead
    )
{

    PLIST_ENTRY Entry;
    PLIST_ENTRY PrevEntry;

    Entry = ListHead->Blink;

#if DBG

    RtlpCheckListEntry(ListHead);

#endif

    PrevEntry = Entry->Blink;
    if ((Entry->Flink != ListHead) || (PrevEntry->Flink != Entry)) {
        FatalListEntryError((PVOID)PrevEntry,
                            (PVOID)Entry,
                            (PVOID)ListHead);
    }

    ListHead->Blink = PrevEntry;
    PrevEntry->Flink = ListHead;
    return Entry;
}


FORCEINLINE
VOID
InsertTailList(
    _Inout_ PLIST_ENTRY ListHead,
    _Out_ __drv_aliasesMem PLIST_ENTRY Entry
    )
{

    PLIST_ENTRY PrevEntry;

#if DBG

    RtlpCheckListEntry(ListHead);

#endif

    PrevEntry = ListHead->Blink;
    Entry->Flink = ListHead;
    Entry->Blink = PrevEntry;
    if (PrevEntry->Flink != ListHead) {
        FatalListEntryError((PVOID)PrevEntry,
                            (PVOID)ListHead,
                            (PVOID)PrevEntry->Flink);
    }

    PrevEntry->Flink = Entry;
    ListHead->Blink = Entry;
    return;
}


FORCEINLINE
VOID
InsertHeadList(
    _Inout_ PLIST_ENTRY ListHead,
    _Out_ __drv_aliasesMem PLIST_ENTRY Entry
    )

{

    PLIST_ENTRY NextEntry;

#if DBG

    RtlpCheckListEntry(ListHead);

#endif

    NextEntry = ListHead->Flink;
    Entry->Flink = NextEntry;
    Entry->Blink = ListHead;
    if (NextEntry->Blink != ListHead) {
        FatalListEntryError((PVOID)ListHead,
                            (PVOID)NextEntry,
                            (PVOID)NextEntry->Blink);
    }

    NextEntry->Blink = Entry;
    ListHead->Flink = Entry;
    return;
}

FORCEINLINE
VOID
AppendTailList(
    _Inout_ PLIST_ENTRY ListHead,
    _Inout_ PLIST_ENTRY ListToAppend
    )
{
    PLIST_ENTRY ListEnd = ListHead->Blink;

    RtlpCheckListEntry(ListHead);
    RtlpCheckListEntry(ListToAppend);
    ListHead->Blink->Flink = ListToAppend;
    ListHead->Blink = ListToAppend->Blink;
    ListToAppend->Blink->Flink = ListHead;
    ListToAppend->Blink = ListEnd;
    return;
}

#endif // NO_KERNEL_LIST_ENTRY_CHECKS

FORCEINLINE
PSINGLE_LIST_ENTRY
PopEntryList(
    _Inout_ PSINGLE_LIST_ENTRY ListHead
    )
{

    PSINGLE_LIST_ENTRY FirstEntry;

    FirstEntry = ListHead->Next;
    if (FirstEntry != NULL) {
        ListHead->Next = FirstEntry->Next;
    }

    return FirstEntry;
}


FORCEINLINE
VOID
PushEntryList(
    _Inout_ PSINGLE_LIST_ENTRY ListHead,
    _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry
    )

{

    Entry->Next = ListHead->Next;
    ListHead->Next = Entry;
    return;
}



#ifdef __cplusplus
}
#endif

#pragma warning(pop)

#endif // (_WIN32_WINNT >= 0x0500)


#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion

#endif // _WINTERNL_
