/*++ BUILD Version: 0082     Increment this if a change has global effects
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
    winnt.h
Abstract:
    This module defines the 32-Bit Windows types and constants that are
    defined by NT, but exposed through the Win32 API.
Revision History:
--*/

#ifndef _WINNT_
#define _WINNT_

//#include <ctype.h>
#define ANYSIZE_ARRAY 1

#define MAX_NATURAL_ALIGNMENT sizeof(DWORD)
#define MEMORY_ALLOCATION_ALIGNMENT 8

// Basics
#ifndef VOID
#define VOID void
#define CHAR char
#define SHORT short
#define LONG long
#endif

// UNICODE (Wide Character) types
#define WCHAR unsigned short
#define PWCHAR dword
#define LPWCH dword
#define LPCWCH dword
#define LPWSTR dword
#define LPCWSTR dword

// ANSI (Multi-byte Character) types
#define PCHAR dword
#define LPSTR dword
#define LPCSTR dword
#define PSHORT dword
#define PLONG dword
#define HANDLE dword

// Flag (bit) fields
#define FCHAR byte
#define FSHORT word
#define FLONG dword

// Component Object Model defines, and macros
#ifndef _HRESULT_DEFINED
#define _HRESULT_DEFINED
#define HRESULT long
#endif // !_HRESULT_DEFINED

#define CCHAR char
#define LCID dword
#define PLCID PDWORD
#define LANGID word
#define APPLICATION_ERROR_MASK       0x20000000
#define ERROR_SEVERITY_SUCCESS       0x00000000
#define ERROR_SEVERITY_INFORMATIONAL 0x40000000
#define ERROR_SEVERITY_WARNING       0x80000000
#define ERROR_SEVERITY_ERROR         0xC0000000

// _M_IX86 included so that EM CONTEXT structure compiles with
// x86 programs. *** TBD should this be for all architectures?

// 16 byte aligned type for 128 bit floats

// For we define a 128 bit structure and use __declspec(align(16)) pragma to
// align to 128 bits.

struct FLOAT128 {
    qword LowPart;
    qword HighPart;
};

// __int64 is only supported by 2.0 and later midl.
// __midl is set by the 2.0 midl and not by 1.0 midl.
#define LONGLONG qword
#define ULONGLONG qword

#define MAXLONGLONG                      0x7fffffffffffffff

#define PLONGLONG dword
#define PULONGLONG dword

// Update Sequence Number
#define USN qword

struct LARGE_INTEGER {
  LONGLONG QuadPart;
};

// Locally Unique Identifier
struct LUID {
  DWORD LowPart;
  LONG HighPart;
};

#define _DWORDLONG_
#define DWORDLONG qword
#define PDWORDLONG dword

#define Int64ShllMod32(a,b) a<<b
#define Int64ShraMod32(a,b) a>>b
#define Int64ShrlMod32(a,b) a>>b

#define ANSI_NULL 0
#define UNICODE_NULL 0
#define UNICODE_STRING_MAX_BYTES 65534
#define UNICODE_STRING_MAX_CHARS 32767
#define BOOLEAN byte
#define PBOOLEAN dword
//  Doubly linked list structure.  Can be used as either a list head, or
//  as link words.
struct LIST_ENTRY {
  dword Flink;
  dword Blink;
};

//  Singly linked list structure. Can be used as either a list head, or
//  as link words.
struct SINGLE_LIST_ENTRY {
  dword Next;
};

// These are needed for portable debugger support.
struct LIST_ENTRY32 {
  DWORD Flink;
  DWORD Blink;
};

#include <guiddef.h>

#ifndef __OBJECTID_DEFINED
#define __OBJECTID_DEFINED

struct OBJECTID {     // size is 20
  GUID Lineage;
  DWORD Uniquifier;
};
#endif // !_OBJECTID_DEFINED

#define MINCHAR     0x80
#define MAXCHAR     0x7f
#define MINSHORT    0x8000
#define MAXSHORT    0x7fff
#define MINLONG     0x80000000
#define MAXLONG     0x7fffffff
#define MAXBYTE     0xff
#define MAXWORD     0xffff
#define MAXDWORD    0xffffffff
// Calculate the byte offset of a field in a structure of type type.
#define FIELD_OFFSET(type,field)    #type.field

// Calculate the size of a field in a structure of type type, without
// knowing or stating the type of the field.
#define RTL_FIELD_SIZE(type,field) (sizeof(type.field)

// Calculate the size of a structure of type type up through and
// including a field.
#define RTL_SIZEOF_THROUGH_FIELD(type,field) FIELD_OFFSET(type,field) + RTL_FIELD_SIZE(type,field)

#define VER_SERVER_NT                       0x80000000
#define VER_WORKSTATION_NT                  0x40000000
#define VER_SUITE_SMALLBUSINESS             0x00000001
#define VER_SUITE_ENTERPRISE                0x00000002
#define VER_SUITE_BACKOFFICE                0x00000004
#define VER_SUITE_COMMUNICATIONS            0x00000008
#define VER_SUITE_TERMINAL                  0x00000010
#define VER_SUITE_SMALLBUSINESS_RESTRICTED  0x00000020
#define VER_SUITE_EMBEDDEDNT                0x00000040
#define VER_SUITE_DATACENTER                0x00000080
#define VER_SUITE_SINGLEUSERTS              0x00000100
#define VER_SUITE_PERSONAL                  0x00000200
#define VER_SUITE_BLADE                     0x00000400

//  Language IDs.
//  The following two combinations of primary language ID and
//  sublanguage ID have special semantics:
//    Primary Language ID   Sublanguage ID      Result
//    -------------------   ---------------     ------------------------
//    LANG_NEUTRAL          SUBLANG_NEUTRAL     Language neutral
//    LANG_NEUTRAL          SUBLANG_DEFAULT     User default language
//    LANG_NEUTRAL          SUBLANG_SYS_DEFAULT System default language
//    LANG_INVARIANT        SUBLANG_NEUTRAL     Invariant locale
//  Primary language IDs.
#define LANG_NEUTRAL                     0x00
#define LANG_INVARIANT                   0x7f
#define LANG_AFRIKAANS                   0x36
#define LANG_ALBANIAN                    0x1c
#define LANG_ARABIC                      0x01
#define LANG_ARMENIAN                    0x2b
#define LANG_ASSAMESE                    0x4d
#define LANG_AZERI                       0x2c
#define LANG_BASQUE                      0x2d
#define LANG_BELARUSIAN                  0x23
#define LANG_BENGALI                     0x45
#define LANG_BULGARIAN                   0x02
#define LANG_CATALAN                     0x03
#define LANG_CHINESE                     0x04
#define LANG_CROATIAN                    0x1a
#define LANG_CZECH                       0x05
#define LANG_DANISH                      0x06
#define LANG_DIVEHI                      0x65
#define LANG_DUTCH                       0x13
#define LANG_ENGLISH                     0x09
#define LANG_ESTONIAN                    0x25
#define LANG_FAEROESE                    0x38
#define LANG_FARSI                       0x29
#define LANG_FINNISH                     0x0b
#define LANG_FRENCH                      0x0c
#define LANG_GALICIAN                    0x56
#define LANG_GEORGIAN                    0x37
#define LANG_GERMAN                      0x07
#define LANG_GREEK                       0x08
#define LANG_GUJARATI                    0x47
#define LANG_HEBREW                      0x0d
#define LANG_HINDI                       0x39
#define LANG_HUNGARIAN                   0x0e
#define LANG_ICELANDIC                   0x0f
#define LANG_INDONESIAN                  0x21
#define LANG_ITALIAN                     0x10
#define LANG_JAPANESE                    0x11
#define LANG_KANNADA                     0x4b
#define LANG_KASHMIRI                    0x60
#define LANG_KAZAK                       0x3f
#define LANG_KONKANI                     0x57
#define LANG_KOREAN                      0x12
#define LANG_KYRGYZ                      0x40
#define LANG_LATVIAN                     0x26
#define LANG_LITHUANIAN                  0x27
#define LANG_MACEDONIAN                  0x2f   // the Former Yugoslav Republic of Macedonia
#define LANG_MALAY                       0x3e
#define LANG_MALAYALAM                   0x4c
#define LANG_MANIPURI                    0x58
#define LANG_MARATHI                     0x4e
#define LANG_MONGOLIAN                   0x50
#define LANG_NEPALI                      0x61
#define LANG_NORWEGIAN                   0x14
#define LANG_ORIYA                       0x48
#define LANG_POLISH                      0x15
#define LANG_PORTUGUESE                  0x16
#define LANG_PUNJABI                     0x46
#define LANG_ROMANIAN                    0x18
#define LANG_RUSSIAN                     0x19
#define LANG_SANSKRIT                    0x4f
#define LANG_SERBIAN                     0x1a
#define LANG_SINDHI                      0x59
#define LANG_SLOVAK                      0x1b
#define LANG_SLOVENIAN                   0x24
#define LANG_SPANISH                     0x0a
#define LANG_SWAHILI                     0x41
#define LANG_SWEDISH                     0x1d
#define LANG_SYRIAC                      0x5a
#define LANG_TAMIL                       0x49
#define LANG_TATAR                       0x44
#define LANG_TELUGU                      0x4a
#define LANG_THAI                        0x1e
#define LANG_TURKISH                     0x1f
#define LANG_UKRAINIAN                   0x22
#define LANG_URDU                        0x20
#define LANG_UZBEK                       0x43
#define LANG_VIETNAMESE                  0x2a

//  Sublanguage IDs.
//  The name immediately following SUBLANG_ dictates which primary
//  language ID that sublanguage ID can be combined with to form a
//  valid language ID.
#define SUBLANG_NEUTRAL                  0x00    // language neutral
#define SUBLANG_DEFAULT                  0x01    // user default
#define SUBLANG_SYS_DEFAULT              0x02    // system default
#define SUBLANG_ARABIC_SAUDI_ARABIA      0x01    // Arabic (Saudi Arabia)
#define SUBLANG_ARABIC_IRAQ              0x02    // Arabic (Iraq)
#define SUBLANG_ARABIC_EGYPT             0x03    // Arabic (Egypt)
#define SUBLANG_ARABIC_LIBYA             0x04    // Arabic (Libya)
#define SUBLANG_ARABIC_ALGERIA           0x05    // Arabic (Algeria)
#define SUBLANG_ARABIC_MOROCCO           0x06    // Arabic (Morocco)
#define SUBLANG_ARABIC_TUNISIA           0x07    // Arabic (Tunisia)
#define SUBLANG_ARABIC_OMAN              0x08    // Arabic (Oman)
#define SUBLANG_ARABIC_YEMEN             0x09    // Arabic (Yemen)
#define SUBLANG_ARABIC_SYRIA             0x0a    // Arabic (Syria)
#define SUBLANG_ARABIC_JORDAN            0x0b    // Arabic (Jordan)
#define SUBLANG_ARABIC_LEBANON           0x0c    // Arabic (Lebanon)
#define SUBLANG_ARABIC_KUWAIT            0x0d    // Arabic (Kuwait)
#define SUBLANG_ARABIC_UAE               0x0e    // Arabic (U.A.E)
#define SUBLANG_ARABIC_BAHRAIN           0x0f    // Arabic (Bahrain)
#define SUBLANG_ARABIC_QATAR             0x10    // Arabic (Qatar)
#define SUBLANG_AZERI_LATIN              0x01    // Azeri (Latin)
#define SUBLANG_AZERI_CYRILLIC           0x02    // Azeri (Cyrillic)
#define SUBLANG_CHINESE_TRADITIONAL      0x01    // Chinese (Taiwan)
#define SUBLANG_CHINESE_SIMPLIFIED       0x02    // Chinese (PR China)
#define SUBLANG_CHINESE_HONGKONG         0x03    // Chinese (Hong Kong S.A.R., P.R.C.)
#define SUBLANG_CHINESE_SINGAPORE        0x04    // Chinese (Singapore)
#define SUBLANG_CHINESE_MACAU            0x05    // Chinese (Macau S.A.R.)
#define SUBLANG_DUTCH                    0x01    // Dutch
#define SUBLANG_DUTCH_BELGIAN            0x02    // Dutch (Belgian)
#define SUBLANG_ENGLISH_US               0x01    // English (USA)
#define SUBLANG_ENGLISH_UK               0x02    // English (UK)
#define SUBLANG_ENGLISH_AUS              0x03    // English (Australian)
#define SUBLANG_ENGLISH_CAN              0x04    // English (Canadian)
#define SUBLANG_ENGLISH_NZ               0x05    // English (New Zealand)
#define SUBLANG_ENGLISH_EIRE             0x06    // English (Irish)
#define SUBLANG_ENGLISH_SOUTH_AFRICA     0x07    // English (South Africa)
#define SUBLANG_ENGLISH_JAMAICA          0x08    // English (Jamaica)
#define SUBLANG_ENGLISH_CARIBBEAN        0x09    // English (Caribbean)
#define SUBLANG_ENGLISH_BELIZE           0x0a    // English (Belize)
#define SUBLANG_ENGLISH_TRINIDAD         0x0b    // English (Trinidad)
#define SUBLANG_ENGLISH_ZIMBABWE         0x0c    // English (Zimbabwe)
#define SUBLANG_ENGLISH_PHILIPPINES      0x0d    // English (Philippines)
#define SUBLANG_FRENCH                   0x01    // French
#define SUBLANG_FRENCH_BELGIAN           0x02    // French (Belgian)
#define SUBLANG_FRENCH_CANADIAN          0x03    // French (Canadian)
#define SUBLANG_FRENCH_SWISS             0x04    // French (Swiss)
#define SUBLANG_FRENCH_LUXEMBOURG        0x05    // French (Luxembourg)
#define SUBLANG_FRENCH_MONACO            0x06    // French (Monaco)
#define SUBLANG_GERMAN                   0x01    // German
#define SUBLANG_GERMAN_SWISS             0x02    // German (Swiss)
#define SUBLANG_GERMAN_AUSTRIAN          0x03    // German (Austrian)
#define SUBLANG_GERMAN_LUXEMBOURG        0x04    // German (Luxembourg)
#define SUBLANG_GERMAN_LIECHTENSTEIN     0x05    // German (Liechtenstein)
#define SUBLANG_ITALIAN                  0x01    // Italian
#define SUBLANG_ITALIAN_SWISS            0x02    // Italian (Swiss)
#define SUBLANG_KASHMIRI_SASIA           0x02    // Kashmiri (South Asia)
#define SUBLANG_KASHMIRI_INDIA           0x02    // For app compatibility only
#define SUBLANG_KOREAN                   0x01    // Korean (Extended Wansung)
#define SUBLANG_LITHUANIAN               0x01    // Lithuanian
#define SUBLANG_MALAY_MALAYSIA           0x01    // Malay (Malaysia)
#define SUBLANG_MALAY_BRUNEI_DARUSSALAM  0x02    // Malay (Brunei Darussalam)
#define SUBLANG_NEPALI_INDIA             0x02    // Nepali (India)
#define SUBLANG_NORWEGIAN_BOKMAL         0x01    // Norwegian (Bokmal)
#define SUBLANG_NORWEGIAN_NYNORSK        0x02    // Norwegian (Nynorsk)
#define SUBLANG_PORTUGUESE               0x02    // Portuguese
#define SUBLANG_PORTUGUESE_BRAZILIAN     0x01    // Portuguese (Brazilian)
#define SUBLANG_SERBIAN_LATIN            0x02    // Serbian (Latin)
#define SUBLANG_SERBIAN_CYRILLIC         0x03    // Serbian (Cyrillic)
#define SUBLANG_SPANISH                  0x01    // Spanish (Castilian)
#define SUBLANG_SPANISH_MEXICAN          0x02    // Spanish (Mexican)
#define SUBLANG_SPANISH_MODERN           0x03    // Spanish (Modern)
#define SUBLANG_SPANISH_GUATEMALA        0x04    // Spanish (Guatemala)
#define SUBLANG_SPANISH_COSTA_RICA       0x05    // Spanish (Costa Rica)
#define SUBLANG_SPANISH_PANAMA           0x06    // Spanish (Panama)
#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07  // Spanish (Dominican Republic)
#define SUBLANG_SPANISH_VENEZUELA        0x08    // Spanish (Venezuela)
#define SUBLANG_SPANISH_COLOMBIA         0x09    // Spanish (Colombia)
#define SUBLANG_SPANISH_PERU             0x0a    // Spanish (Peru)
#define SUBLANG_SPANISH_ARGENTINA        0x0b    // Spanish (Argentina)
#define SUBLANG_SPANISH_ECUADOR          0x0c    // Spanish (Ecuador)
#define SUBLANG_SPANISH_CHILE            0x0d    // Spanish (Chile)
#define SUBLANG_SPANISH_URUGUAY          0x0e    // Spanish (Uruguay)
#define SUBLANG_SPANISH_PARAGUAY         0x0f    // Spanish (Paraguay)
#define SUBLANG_SPANISH_BOLIVIA          0x10    // Spanish (Bolivia)
#define SUBLANG_SPANISH_EL_SALVADOR      0x11    // Spanish (El Salvador)
#define SUBLANG_SPANISH_HONDURAS         0x12    // Spanish (Honduras)
#define SUBLANG_SPANISH_NICARAGUA        0x13    // Spanish (Nicaragua)
#define SUBLANG_SPANISH_PUERTO_RICO      0x14    // Spanish (Puerto Rico)
#define SUBLANG_SWEDISH                  0x01    // Swedish
#define SUBLANG_SWEDISH_FINLAND          0x02    // Swedish (Finland)
#define SUBLANG_URDU_PAKISTAN            0x01    // Urdu (Pakistan)
#define SUBLANG_URDU_INDIA               0x02    // Urdu (India)
#define SUBLANG_UZBEK_LATIN              0x01    // Uzbek (Latin)
#define SUBLANG_UZBEK_CYRILLIC           0x02    // Uzbek (Cyrillic)
//  Sorting IDs.
#define SORT_DEFAULT                     0x0     // sorting default
#define SORT_JAPANESE_XJIS               0x0     // Japanese XJIS order
#define SORT_JAPANESE_UNICODE            0x1     // Japanese Unicode order
#define SORT_CHINESE_BIG5                0x0     // Chinese BIG5 order
#define SORT_CHINESE_PRCP                0x0     // PRC Chinese Phonetic order
#define SORT_CHINESE_UNICODE             0x1     // Chinese Unicode order
#define SORT_CHINESE_PRC                 0x2     // PRC Chinese Stroke Count order
#define SORT_CHINESE_BOPOMOFO            0x3     // Traditional Chinese Bopomofo order
#define SORT_KOREAN_KSC                  0x0     // Korean KSC order
#define SORT_KOREAN_UNICODE              0x1     // Korean Unicode order
#define SORT_GERMAN_PHONE_BOOK           0x1     // German Phone Book order
#define SORT_HUNGARIAN_DEFAULT           0x0     // Hungarian Default order
#define SORT_HUNGARIAN_TECHNICAL         0x1     // Hungarian Technical order
#define SORT_GEORGIAN_TRADITIONAL        0x0     // Georgian Traditional order
#define SORT_GEORGIAN_MODERN             0x1     // Georgian Modern order
// end_r_winnt

//  A language ID is a 16 bit value which is the combination of a
//  primary language ID and a secondary language ID.  The bits are
//  allocated as follows:
//       +-----------------------+-------------------------+
//       |     Sublanguage ID    |   Primary Language ID   |
//       +-----------------------+-------------------------+
//        15                   10 9                       0   bit
//  Language ID creation/extraction macros:
//    MAKELANGID    - construct language id from a primary language id and
//                    a sublanguage id.
//    PRIMARYLANGID - extract primary language id from a language id.
//    SUBLANGID     - extract sublanguage id from a language id.
#define MAKELANGID(p,s)       s<<10|p
#define PRIMARYLANGID(lgid)    lgid&0x3ff
#define SUBLANGID(lgid)        lgid>>10

//  A locale ID is a 32 bit value which is the combination of a
//  language ID, a sort ID, and a reserved area.  The bits are
//  allocated as follows:
//       +-------------+---------+-------------------------+
//       |   Reserved  | Sort ID |      Language ID        |
//       +-------------+---------+-------------------------+
//        31         20 19     16 15                      0   bit
//  Locale ID creation/extraction macros:
//    MAKELCID            - construct the locale id from a language id and a sort id.
//    MAKESORTLCID        - construct the locale id from a language id, sort id, and sort version.
//    LANGIDFROMLCID      - extract the language id from a locale id.
//    SORTIDFROMLCID      - extract the sort id from a locale id.
//    SORTVERSIONFROMLCID - extract the sort version from a locale id.
#define NLS_VALID_LOCALE_MASK  0x000fffff
#define MAKELCID(lgid,srtid)  srtid<<16|lgid
//#define MAKESORTLCID(lgid,srtid,ver)  MAKELCID(lgid, srtid) | (ver << 20)
#define LANGIDFROMLCID(lcid)   lcid&0xFFFF
#define SORTIDFROMLCID(lcid)   lcid>>16&0xf
#define SORTVERSIONFROMLCID(lcid)  lcid >> 20 & 0xf

//  Default System and User IDs for language and locale.
#define LANG_SYSTEM_DEFAULT    MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT)
#define LANG_USER_DEFAULT      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
#define LOCALE_SYSTEM_DEFAULT  MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)
#define LOCALE_USER_DEFAULT    MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT)

#define LOCALE_NEUTRAL MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)
#define LOCALE_INVARIANT MAKELCID(MAKELANGID(LANG_INVARIANT,SUBLANG_NEUTRAL),SORT_DEFAULT)

#ifndef WIN32_NO_STATUS
/*lint -save -e767 */
#define STATUS_WAIT_0                    0x00000000L
#define STATUS_ABANDONED_WAIT_0          0x00000080L
#define STATUS_USER_APC                  0x000000C0L
#define STATUS_TIMEOUT                   0x00000102L
#define STATUS_PENDING                   0x00000103L
#define DBG_EXCEPTION_HANDLED            0x00010001L
#define DBG_CONTINUE                     0x00010002L
#define STATUS_SEGMENT_NOTIFICATION      0x40000005L
#define DBG_TERMINATE_THREAD             0x40010003L
#define DBG_TERMINATE_PROCESS            0x40010004L
#define DBG_CONTROL_C                    0x40010005L
#define DBG_CONTROL_BREAK                0x40010008L
#define STATUS_GUARD_PAGE_VIOLATION      0x80000001L
#define STATUS_DATATYPE_MISALIGNMENT     0x80000002L
#define STATUS_BREAKPOINT                0x80000003L
#define STATUS_SINGLE_STEP               0x80000004L
#define DBG_EXCEPTION_NOT_HANDLED        0x80010001L
#define STATUS_ACCESS_VIOLATION          0xC0000005L
#define STATUS_IN_PAGE_ERROR             0xC0000006L
#define STATUS_INVALID_HANDLE            0xC0000008L
#define STATUS_NO_MEMORY                 0xC0000017L
#define STATUS_ILLEGAL_INSTRUCTION       0xC000001DL
#define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025L
#define STATUS_INVALID_DISPOSITION       0xC0000026L
#define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008CL
#define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008DL
#define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008EL
#define STATUS_FLOAT_INEXACT_RESULT      0xC000008FL
#define STATUS_FLOAT_INVALID_OPERATION   0xC0000090L
#define STATUS_FLOAT_OVERFLOW            0xC0000091L
#define STATUS_FLOAT_STACK_CHECK         0xC0000092L
#define STATUS_FLOAT_UNDERFLOW           0xC0000093L
#define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094L
#define STATUS_INTEGER_OVERFLOW          0xC0000095L
#define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096L
#define STATUS_STACK_OVERFLOW            0xC00000FDL
#define STATUS_CONTROL_C_EXIT            0xC000013AL
#define STATUS_FLOAT_MULTIPLE_FAULTS     0xC00002B4L
#define STATUS_FLOAT_MULTIPLE_TRAPS      0xC00002B5L
#define STATUS_REG_NAT_CONSUMPTION       0xC00002C9L
#define STATUS_SXS_EARLY_DEACTIVATION    0xC015000FL
#define STATUS_SXS_INVALID_DEACTIVATION  0xC0150010L
/*lint -restore */
#endif
#define MAXIMUM_WAIT_OBJECTS 64     // Maximum number of wait objects

#define MAXIMUM_SUSPEND_COUNT MAXCHAR // Maximum times thread can be suspended

//  Define the size of the 80387 save area, which is in the context frame.
#define SIZE_OF_80387_REGISTERS      80

// The following flags control the contents of the CONTEXT structure.
#ifndef(RC_INVOKED)

#define CONTEXT_i386    0x00010000    // this assumes that i386 and
#define CONTEXT_i486    0x00010000    // i486 have identical context records

// end_wx86
#define CONTEXT_CONTROL         CONTEXT_i386|0x00000001L // SS:SP, CS:IP, FLAGS, BP
#define CONTEXT_INTEGER         CONTEXT_i386|0x00000002L // AX, BX, CX, DX, SI, DI
#define CONTEXT_SEGMENTS        CONTEXT_i386|0x00000004L // DS, ES, FS, GS
#define CONTEXT_FLOATING_POINT  CONTEXT_i386|0x00000008L // 387 state
#define CONTEXT_DEBUG_REGISTERS CONTEXT_i386|0x00000010L // DB 0-3,6,7
#define CONTEXT_EXTENDED_REGISTERS CONTEXT_i386|0x00000020L // cpu specific extensions

#define CONTEXT_FULL CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS

// begin_wx86

#endif

#define MAXIMUM_SUPPORTED_EXTENSION     512

struct FLOATING_SAVE_AREA {
  DWORD   ControlWord;
  DWORD   StatusWord;
  DWORD   TagWord;
  DWORD   ErrorOffset;
  DWORD   ErrorSelector;
  DWORD   DataOffset;
  DWORD   DataSelector;
  BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
  DWORD   Cr0NpxState;
};

// Context Frame
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) is is used to constuct a call frame for APC delivery,
//  and 3) it is used in the user level thread creation routines.
//  The layout of the record conforms to a standard call frame.
struct CONTEXT {
  // The flags values within this flag control the contents of
  // a CONTEXT record.
  // If the context record is used as an input parameter, then
  // for each portion of the context record controlled by a flag
  // whose value is set, it is assumed that that portion of the
  // context record contains valid context. If the context record
  // is being used to modify a threads context, then only that
  // portion of the threads context will be modified.
  // If the context record is used as an IN OUT parameter to capture
  // the context of a thread, then only those portions of the thread's
  // context corresponding to set flags will be returned.
  // The context record is never used as an OUT only parameter.
  DWORD ContextFlags;
  // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
  // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
  // included in CONTEXT_FULL.
  DWORD   Dr0;
  DWORD   Dr1;
  DWORD   Dr2;
  DWORD   Dr3;
  DWORD   Dr6;
  DWORD   Dr7;
  // This section is specified/returned if the
  // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
  FLOATING_SAVE_AREA FloatSave;
  // This section is specified/returned if the
  // ContextFlags word contians the flag CONTEXT_SEGMENTS.
  DWORD   SegGs;
  DWORD   SegFs;
  DWORD   SegEs;
  DWORD   SegDs;
  // This section is specified/returned if the
  // ContextFlags word contians the flag CONTEXT_INTEGER.
  DWORD   Edi;
  DWORD   Esi;
  DWORD   Ebx;
  DWORD   Edx;
  DWORD   Ecx;
  DWORD   Eax;
  // This section is specified/returned if the
  // ContextFlags word contians the flag CONTEXT_CONTROL.
  DWORD   Ebp;
  DWORD   Eip;
  DWORD   SegCs;              // MUST BE SANITIZED
  DWORD   EFlags;             // MUST BE SANITIZED
  DWORD   Esp;
  DWORD   SegSs;
  // This section is specified/returned if the ContextFlags word
  // contains the flag CONTEXT_EXTENDED_REGISTERS.
  // The format and contexts are processor specific
  BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
};

#ifndef _LDT_ENTRY_DEFINED
#define _LDT_ENTRY_DEFINED

struct LDT_ENTRY {
  WORD    LimitLow;
  WORD    BaseLow;
  union {
    struct {
      BYTE    BaseMid;
      BYTE    Flags1;     // Declare as bytes to avoid alignment
      BYTE    Flags2;     // Problems.
      BYTE    BaseHi;
    } Bytes;
    struct {
      DWORD   BaseMid : 8;
      DWORD   Type : 5;
      DWORD   Dpl : 2;
      DWORD   Pres : 1;
      DWORD   LimitHi : 4;
      DWORD   Sys : 1;
      DWORD   Reserved_0 : 1;
      DWORD   Default_Big : 1;
      DWORD   Granularity : 1;
      DWORD   BaseHi : 8;
    } Bits;
  } HighWord;
};

#endif

#define EXCEPTION_NONCONTINUABLE 0x1    // Noncontinuable exception
#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters

// Exception record definition.

struct EXCEPTION_RECORD {
  DWORD    ExceptionCode;
  DWORD ExceptionFlags;
  dword ExceptionRecord;
  dword ExceptionAddress;
  DWORD NumberParameters;
  dword ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
};

struct EXCEPTION_RECORD32 {
  DWORD    ExceptionCode;
  DWORD ExceptionFlags;
  DWORD ExceptionRecord;
  DWORD ExceptionAddress;
  DWORD NumberParameters;
  DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
};

struct EXCEPTION_RECORD64 {
  DWORD    ExceptionCode;
  DWORD ExceptionFlags;
  qword ExceptionRecord;
  qword ExceptionAddress;
  DWORD NumberParameters;
  DWORD __unusedAlignment;
  qword ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
};

// Typedef for pointer returned by exception_info()
struct EXCEPTION_POINTERS {
  dword ExceptionRecord;
  dword ContextRecord;
};
////////////////////////////////////////////////////////////////////////
//                             ACCESS MASK                            //
////////////////////////////////////////////////////////////////////////

//  Define the access mask as a longword sized structure divided up as
//  follows:
//       3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//       1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//      +---------------+---------------+-------------------------------+
//      |G|G|G|G|Res'd|A| StandardRights|         SpecificRights        |
//      |R|W|E|A|     |S|               |                               |
//      +-+-------------+---------------+-------------------------------+
//      typedef struct _ACCESS_MASK {
//          WORD   SpecificRights;
//          BYTE  StandardRights;
//          BYTE  AccessSystemAcl : 1;
//          BYTE  Reserved : 3;
//          BYTE  GenericAll : 1;
//          BYTE  GenericExecute : 1;
//          BYTE  GenericWrite : 1;
//          BYTE  GenericRead : 1;
//      } ACCESS_MASK;
//      typedef ACCESS_MASK *PACCESS_MASK;
//  but to make life simple for programmer's we'll allow them to specify
//  a desired access mask by simply OR'ing together mulitple single rights
//  and treat an access mask as a DWORD.  For example
//      DesiredAccess = DELETE | READ_CONTROL
//  So we'll declare ACCESS_MASK as DWORD
// begin_ntddk begin_wdm begin_nthal begin_ntifs
#define ACCESS_MASK dword

////////////////////////////////////////////////////////////////////////
//                             ACCESS TYPES                           //
////////////////////////////////////////////////////////////////////////

// begin_ntddk begin_wdm begin_nthal begin_ntifs
//  The following are masks for the predefined standard access types
#define DELETE                           0x00010000L
#define READ_CONTROL                     0x00020000L
#define WRITE_DAC                        0x00040000L
#define WRITE_OWNER                      0x00080000L
#define SYNCHRONIZE                      0x00100000L
#define STANDARD_RIGHTS_REQUIRED         0x000F0000L
#define STANDARD_RIGHTS_READ             READ_CONTROL
#define STANDARD_RIGHTS_WRITE            READ_CONTROL
#define STANDARD_RIGHTS_EXECUTE          READ_CONTROL
#define STANDARD_RIGHTS_ALL              0x001F0000L
#define SPECIFIC_RIGHTS_ALL              0x0000FFFFL

// AccessSystemAcl access type
#define ACCESS_SYSTEM_SECURITY           0x01000000L

// MaximumAllowed access type
#define MAXIMUM_ALLOWED                  0x02000000L

//  These are the generic rights.
#define GENERIC_READ                     0x80000000L
#define GENERIC_WRITE                    0x40000000L
#define GENERIC_EXECUTE                  0x20000000L
#define GENERIC_ALL                      0x10000000L

//  Define the generic mapping array.  This is used to denote the
//  mapping of each generic access right to a specific access mask.
struct GENERIC_MAPPING {
  ACCESS_MASK GenericRead;
  ACCESS_MASK GenericWrite;
  ACCESS_MASK GenericExecute;
  ACCESS_MASK GenericAll;
};

////////////////////////////////////////////////////////////////////////
//                        LUID_AND_ATTRIBUTES                         //
////////////////////////////////////////////////////////////////////////
#pragma pack(push,4)
struct LUID_AND_ATTRIBUTES {
  LUID Luid;
  DWORD Attributes;
};
#pragma pack(pop)

////////////////////////////////////////////////////////////////////////
//              Security Id     (SID)                                 //
////////////////////////////////////////////////////////////////////////
// Pictorially the structure of an SID is as follows:
//         1   1   1   1   1   1
//         5   4   3   2   1   0   9   8   7   6   5   4   3   2   1   0
//      +---------------------------------------------------------------+
//      |      SubAuthorityCount        |Reserved1 (SBZ)|   Revision    |
//      +---------------------------------------------------------------+
//      |                   IdentifierAuthority[0]                      |
//      +---------------------------------------------------------------+
//      |                   IdentifierAuthority[1]                      |
//      +---------------------------------------------------------------+
//      |                   IdentifierAuthority[2]                      |
//      +---------------------------------------------------------------+
//      |                                                               |
//      +- -  -  -  -  -  -  -  SubAuthority[]  -  -  -  -  -  -  -  - -+
//      |                                                               |
//      +---------------------------------------------------------------+

// begin_ntifs

#ifndef SID_IDENTIFIER_AUTHORITY_DEFINED
#define SID_IDENTIFIER_AUTHORITY_DEFINED
struct SID_IDENTIFIER_AUTHORITY {
  BYTE  Value[6];
};
#endif

#ifndef SID_DEFINED
#define SID_DEFINED
struct SID {
  BYTE  Revision;
  BYTE  SubAuthorityCount;
  SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
  DWORD SubAuthority[ANYSIZE_ARRAY];
};
#endif

#define SID_REVISION                     1    // Current revision level
#define SID_MAX_SUB_AUTHORITIES          15
#define SID_RECOMMENDED_SUB_AUTHORITIES  1    // Will change to around 6
                                                // in a future release.
#ifndef MIDL_PASS
#define SECURITY_MAX_SID_SIZE  \
      SID_MAX_SUB_AUTHORITIES * sizeof(DWORD)+sizeof(SID)-sizeof(DWORD)
#endif // MIDL_PASS

enum SID_NAME_USE{
  SidTypeUser = 1,
  SidTypeGroup,
  SidTypeDomain,
  SidTypeAlias,
  SidTypeWellKnownGroup,
  SidTypeDeletedAccount,
  SidTypeInvalid,
  SidTypeUnknown,
  SidTypeComputer
};

struct SID_AND_ATTRIBUTES {
  dword Sid;
  DWORD Attributes;
};

/////////////////////////////////////////////////////////////////////////////
// Universal well-known SIDs                                               //
//     Null SID                     S-1-0-0                                //
//     World                        S-1-1-0                                //
//     Local                        S-1-2-0                                //
//     Creator Owner ID             S-1-3-0                                //
//     Creator Group ID             S-1-3-1                                //
//     Creator Owner Server ID      S-1-3-2                                //
//     Creator Group Server ID      S-1-3-3                                //
//     (Non-unique IDs)             S-1-4                                  //
/////////////////////////////////////////////////////////////////////////////

#define SECURITY_NULL_SID_AUTHORITY         {0,0,0,0,0,0}
#define SECURITY_WORLD_SID_AUTHORITY        {0,0,0,0,0,1}
#define SECURITY_LOCAL_SID_AUTHORITY        {0,0,0,0,0,2}
#define SECURITY_CREATOR_SID_AUTHORITY      {0,0,0,0,0,3}
#define SECURITY_NON_UNIQUE_AUTHORITY       {0,0,0,0,0,4}
#define SECURITY_RESOURCE_MANAGER_AUTHORITY {0,0,0,0,0,9}

#define SECURITY_NULL_RID                 0x00000000L
#define SECURITY_WORLD_RID                0x00000000L
#define SECURITY_LOCAL_RID                0x00000000L

#define SECURITY_CREATOR_OWNER_RID        0x00000000L
#define SECURITY_CREATOR_GROUP_RID        0x00000001L

#define SECURITY_CREATOR_OWNER_SERVER_RID 0x00000002L
#define SECURITY_CREATOR_GROUP_SERVER_RID 0x00000003L

/////////////////////////////////////////////////////////////////////////////
// NT well-known SIDs                                                      //
//     NT Authority          S-1-5                                         //
//     Dialup                S-1-5-1                                       //
//     Network               S-1-5-2                                       //
//     Batch                 S-1-5-3                                       //
//     Interactive           S-1-5-4                                       //
//     Service               S-1-5-6                                       //
//     AnonymousLogon        S-1-5-7       (aka null logon session)        //
//     Proxy                 S-1-5-8                                       //
//     ServerLogon           S-1-5-9       (aka domain controller account) //
//     Self                  S-1-5-10      (self RID)                      //
//     Authenticated User    S-1-5-11      (Authenticated user somewhere)  //
//     Restricted Code       S-1-5-12      (Running restricted code)       //
//     Terminal Server       S-1-5-13      (Running on Terminal Server)    //
//     Remote Logon          S-1-5-14      (Remote Interactive Logon)      //
//     (Logon IDs)           S-1-5-5-X-Y                                   //
//     (NT non-unique IDs)   S-1-5-0x15-...                                //
//     (Built-in domain)     s-1-5-0x20                                    //
/////////////////////////////////////////////////////////////////////////////

#define SECURITY_NT_AUTHORITY           {0,0,0,0,0,5}   // ntifs

#define SECURITY_DIALUP_RID             0x00000001L
#define SECURITY_NETWORK_RID            0x00000002L
#define SECURITY_BATCH_RID              0x00000003L
#define SECURITY_INTERACTIVE_RID        0x00000004L
#define SECURITY_SERVICE_RID            0x00000006L
#define SECURITY_ANONYMOUS_LOGON_RID    0x00000007L
#define SECURITY_PROXY_RID              0x00000008L
#define SECURITY_ENTERPRISE_CONTROLLERS_RID 0x00000009L
#define SECURITY_SERVER_LOGON_RID       SECURITY_ENTERPRISE_CONTROLLERS_RID
#define SECURITY_PRINCIPAL_SELF_RID     0x0000000AL
#define SECURITY_AUTHENTICATED_USER_RID 0x0000000BL
#define SECURITY_RESTRICTED_CODE_RID    0x0000000CL
#define SECURITY_TERMINAL_SERVER_RID    0x0000000DL
#define SECURITY_REMOTE_LOGON_RID       0x0000000EL

#define SECURITY_LOGON_IDS_RID          0x00000005L
#define SECURITY_LOGON_IDS_RID_COUNT    3L

#define SECURITY_LOCAL_SYSTEM_RID       0x00000012L
#define SECURITY_LOCAL_SERVICE_RID      0x00000013L
#define SECURITY_NETWORK_SERVICE_RID    0x00000014L

#define SECURITY_NT_NON_UNIQUE                 0x00000015L
#define SECURITY_NT_NON_UNIQUE_SUB_AUTH_COUNT  3L

#define SECURITY_BUILTIN_DOMAIN_RID     0x00000020L

/////////////////////////////////////////////////////////////////////////////
// well-known domain relative sub-authority values (RIDs)...               //
/////////////////////////////////////////////////////////////////////////////

// Well-known users ...
#define DOMAIN_USER_RID_ADMIN          0x000001F4L
#define DOMAIN_USER_RID_GUEST          0x000001F5L
#define DOMAIN_USER_RID_KRBTGT         0x000001F6L

// well-known groups ...
#define DOMAIN_GROUP_RID_ADMINS        0x00000200L
#define DOMAIN_GROUP_RID_USERS         0x00000201L
#define DOMAIN_GROUP_RID_GUESTS        0x00000202L
#define DOMAIN_GROUP_RID_COMPUTERS     0x00000203L
#define DOMAIN_GROUP_RID_CONTROLLERS   0x00000204L
#define DOMAIN_GROUP_RID_CERT_ADMINS   0x00000205L
#define DOMAIN_GROUP_RID_SCHEMA_ADMINS 0x00000206L
#define DOMAIN_GROUP_RID_ENTERPRISE_ADMINS 0x00000207L
#define DOMAIN_GROUP_RID_POLICY_ADMINS 0x00000208L

// well-known aliases ...
#define DOMAIN_ALIAS_RID_ADMINS        0x00000220L
#define DOMAIN_ALIAS_RID_USERS         0x00000221L
#define DOMAIN_ALIAS_RID_GUESTS        0x00000222L
#define DOMAIN_ALIAS_RID_POWER_USERS   0x00000223L
#define DOMAIN_ALIAS_RID_ACCOUNT_OPS   0x00000224L
#define DOMAIN_ALIAS_RID_SYSTEM_OPS    0x00000225L
#define DOMAIN_ALIAS_RID_PRINT_OPS     0x00000226L
#define DOMAIN_ALIAS_RID_BACKUP_OPS    0x00000227L
#define DOMAIN_ALIAS_RID_REPLICATOR    0x00000228L
#define DOMAIN_ALIAS_RID_RAS_SERVERS   0x00000229L
#define DOMAIN_ALIAS_RID_PREW2KCOMPACCESS 0x0000022AL
#define DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS 0x0000022BL
#define DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS 0x0000022CL

// Allocate the System Luid.  The first 1000 LUIDs are reserved.
// Use #999 here (0x3E7 = 999)
#define SYSTEM_LUID                     { 0x3E7, 0x0 }
#define ANONYMOUS_LOGON_LUID            { 0x3e6, 0x0 }
#define LOCALSERVICE_LUID               { 0x3e5, 0x0 }
#define NETWORKSERVICE_LUID             { 0x3e4, 0x0 }
 // end_ntifs

////////////////////////////////////////////////////////////////////////
//                          User and Group related SID attributes     //
////////////////////////////////////////////////////////////////////////

// Group attributes
#define SE_GROUP_MANDATORY              0x00000001L
#define SE_GROUP_ENABLED_BY_DEFAULT     0x00000002L
#define SE_GROUP_ENABLED                0x00000004L
#define SE_GROUP_OWNER                  0x00000008L
#define SE_GROUP_USE_FOR_DENY_ONLY      0x00000010L
#define SE_GROUP_LOGON_ID               0xC0000000L
#define SE_GROUP_RESOURCE               0x20000000L

////////////////////////////////////////////////////////////////////////
//                         ACL  and  ACE                              //
////////////////////////////////////////////////////////////////////////

//  Define an ACL and the ACE format.  The structure of an ACL header
//  followed by one or more ACEs.  Pictorally the structure of an ACL header
//  is as follows:
//       3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//       1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//      +-------------------------------+---------------+---------------+
//      |            AclSize            |      Sbz1     |  AclRevision  |
//      +-------------------------------+---------------+---------------+
//      |              Sbz2             |           AceCount            |
//      +-------------------------------+-------------------------------+
//  The current AclRevision is defined to be ACL_REVISION.
//  AclSize is the size, in bytes, allocated for the ACL.  This includes
//  the ACL header, ACES, and remaining free space in the buffer.
//  AceCount is the number of ACES in the ACL.
// begin_ntddk begin_wdm begin_ntifs
// This is the *current* ACL revision
#define ACL_REVISION     2
#define ACL_REVISION_DS  4

// This is the history of ACL revisions.  Add a new one whenever
// ACL_REVISION is updated
#define ACL_REVISION1   1
#define MIN_ACL_REVISION ACL_REVISION2
#define ACL_REVISION2   2
#define ACL_REVISION3   3
#define ACL_REVISION4   4
#define MAX_ACL_REVISION ACL_REVISION4

struct ACL {
  BYTE  AclRevision;
  BYTE  Sbz1;
  WORD   AclSize;
  WORD   AceCount;
  WORD   Sbz2;
};
// end_ntddk end_wdm

//  The structure of an ACE is a common ace header followed by ace type
//  specific data.  Pictorally the structure of the common ace header is
//  as follows:
//       3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//       1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//      +---------------+-------+-------+---------------+---------------+
//      |            AceSize            |    AceFlags   |     AceType   |
//      +---------------+-------+-------+---------------+---------------+
//  AceType denotes the type of the ace, there are some predefined ace
//  types
//  AceSize is the size, in bytes, of ace.
//  AceFlags are the Ace flags for audit and inheritance, defined shortly.

struct ACE_HEADER {
  BYTE  AceType;
  BYTE  AceFlags;
  WORD   AceSize;
};

//  The following are the predefined ace types that go into the AceType
//  field of an Ace header.
#define ACCESS_MIN_MS_ACE_TYPE                  0x0
#define ACCESS_ALLOWED_ACE_TYPE                 0x0
#define ACCESS_DENIED_ACE_TYPE                  0x1
#define SYSTEM_AUDIT_ACE_TYPE                   0x2
#define SYSTEM_ALARM_ACE_TYPE                   0x3
#define ACCESS_MAX_MS_V2_ACE_TYPE               0x3
#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE        0x4
#define ACCESS_MAX_MS_V3_ACE_TYPE               0x4
#define ACCESS_MIN_MS_OBJECT_ACE_TYPE           0x5
#define ACCESS_ALLOWED_OBJECT_ACE_TYPE          0x5
#define ACCESS_DENIED_OBJECT_ACE_TYPE           0x6
#define SYSTEM_AUDIT_OBJECT_ACE_TYPE            0x7
#define SYSTEM_ALARM_OBJECT_ACE_TYPE            0x8
#define ACCESS_MAX_MS_OBJECT_ACE_TYPE           0x8
#define ACCESS_MAX_MS_V4_ACE_TYPE               0x8
#define ACCESS_MAX_MS_ACE_TYPE                  0x8
#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE        0x9
#define ACCESS_DENIED_CALLBACK_ACE_TYPE         0xA
#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE 0xB
#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE  0xC
#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE          0xD
#define SYSTEM_ALARM_CALLBACK_ACE_TYPE          0xE
#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE   0xF
#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE   0x10
#define ACCESS_MAX_MS_V5_ACE_TYPE               0x10

//  The following are the inherit flags that go into the AceFlags field
//  of an Ace header.
#define OBJECT_INHERIT_ACE                0x1
#define CONTAINER_INHERIT_ACE             0x2
#define NO_PROPAGATE_INHERIT_ACE          0x4
#define INHERIT_ONLY_ACE                  0x8
#define INHERITED_ACE                     0x10
#define VALID_INHERIT_FLAGS               0x1F

//  The following are the currently defined ACE flags that go into the
//  AceFlags field of an ACE header.  Each ACE type has its own set of
//  AceFlags.
//  SUCCESSFUL_ACCESS_ACE_FLAG - used only with system audit and alarm ACE
//  types to indicate that a message is generated for successful accesses.
//  FAILED_ACCESS_ACE_FLAG - used only with system audit and alarm ACE types
//  to indicate that a message is generated for failed accesses.
//  SYSTEM_AUDIT and SYSTEM_ALARM AceFlags
//  These control the signaling of audit and alarms for success or failure.
#define SUCCESSFUL_ACCESS_ACE_FLAG       0x40
#define FAILED_ACCESS_ACE_FLAG           0x80

//  We'll define the structure of the predefined ACE types.  Pictorally
//  the structure of the predefined ACE's is as follows:
//       3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//       1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//      +---------------+-------+-------+---------------+---------------+
//      |    AceFlags   | Resd  |Inherit|    AceSize    |     AceType   |
//      +---------------+-------+-------+---------------+---------------+
//      |                              Mask                             |
//      +---------------------------------------------------------------+
//      |                                                               |
//      +                                                               +
//      |                                                               |
//      +                              Sid                              +
//      |                                                               |
//      +                                                               +
//      |                                                               |
//      +---------------------------------------------------------------+
//  Mask is the access mask associated with the ACE.  This is either the
//  access allowed, access denied, audit, or alarm mask.
//  Sid is the Sid associated with the ACE.
//  The following are the four predefined ACE types.
//  Examine the AceType field in the Header to determine
//  which structure is appropriate to use for casting.

struct ACCESS_ALLOWED_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
};

struct ACCESS_DENIED_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
};

struct SYSTEM_AUDIT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
};

struct SYSTEM_ALARM_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
};
// end_ntifs

struct ACCESS_ALLOWED_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
};

struct ACCESS_DENIED_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
};

struct SYSTEM_AUDIT_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
};

struct SYSTEM_ALARM_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
};

// Callback ace support in post Win2000.
// Resource managers can put their own data after Sidstart + Length of the sid
struct ACCESS_ALLOWED_CALLBACK_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct ACCESS_DENIED_CALLBACK_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct SYSTEM_AUDIT_CALLBACK_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct SYSTEM_ALARM_CALLBACK_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct ACCESS_ALLOWED_CALLBACK_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct ACCESS_DENIED_CALLBACK_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct SYSTEM_AUDIT_CALLBACK_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

struct _SYSTEM_ALARM_CALLBACK_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
  // Opaque resouce manager specific data
};

// Currently define Flags for "OBJECT" ACE types.
#define ACE_OBJECT_TYPE_PRESENT           0x1
#define ACE_INHERITED_OBJECT_TYPE_PRESENT 0x2

//  The following declarations are used for setting and querying information
//  about and ACL.  First are the various information classes available to
//  the user.
enum ACL_INFORMATION_CLASS{
  AclRevisionInformation = 1,
  AclSizeInformation
};

//  This record is returned/sent if the user is requesting/setting the
//  AclRevisionInformation
struct ACL_REVISION_INFORMATION {
  DWORD AclRevision;
};

//  This record is returned if the user is requesting AclSizeInformation
struct ACL_SIZE_INFORMATION {
  DWORD AceCount;
  DWORD AclBytesInUse;
  DWORD AclBytesFree;
};

////////////////////////////////////////////////////////////////////////
//                             SECURITY_DESCRIPTOR                    //
////////////////////////////////////////////////////////////////////////
//  Define the Security Descriptor and related data types.
//  This is an opaque data structure.
// begin_wdm begin_ntddk begin_ntifs
// Current security descriptor revision value
#define SECURITY_DESCRIPTOR_REVISION     1
#define SECURITY_DESCRIPTOR_REVISION1    1
// end_wdm end_ntddk

#define SE_OWNER_DEFAULTED               0x0001
#define SE_GROUP_DEFAULTED               0x0002
#define SE_DACL_PRESENT                  0x0004
#define SE_DACL_DEFAULTED                0x0008
#define SE_SACL_PRESENT                  0x0010
#define SE_SACL_DEFAULTED                0x0020
#define SE_DACL_AUTO_INHERIT_REQ         0x0100
#define SE_SACL_AUTO_INHERIT_REQ         0x0200
#define SE_DACL_AUTO_INHERITED           0x0400
#define SE_SACL_AUTO_INHERITED           0x0800
#define SE_DACL_PROTECTED                0x1000
#define SE_SACL_PROTECTED                0x2000
#define SE_RM_CONTROL_VALID              0x4000
#define SE_SELF_RELATIVE                 0x8000

//  Where:
//      SE_OWNER_DEFAULTED - This boolean flag, when set, indicates that the
//          SID pointed to by the Owner field was provided by a
//          defaulting mechanism rather than explicitly provided by the
//          original provider of the security descriptor.  This may
//          affect the treatment of the SID with respect to inheritence
//          of an owner.
//      SE_GROUP_DEFAULTED - This boolean flag, when set, indicates that the
//          SID in the Group field was provided by a defaulting mechanism
//          rather than explicitly provided by the original provider of
//          the security descriptor.  This may affect the treatment of
//          the SID with respect to inheritence of a primary group.
//      SE_DACL_PRESENT - This boolean flag, when set, indicates that the
//          security descriptor contains a discretionary ACL.  If this
//          flag is set and the Dacl field of the SECURITY_DESCRIPTOR is
//          null, then a null ACL is explicitly being specified.
//      SE_DACL_DEFAULTED - This boolean flag, when set, indicates that the
//          ACL pointed to by the Dacl field was provided by a defaulting
//          mechanism rather than explicitly provided by the original
//          provider of the security descriptor.  This may affect the
//          treatment of the ACL with respect to inheritence of an ACL.
//          This flag is ignored if the DaclPresent flag is not set.
//      SE_SACL_PRESENT - This boolean flag, when set,  indicates that the
//          security descriptor contains a system ACL pointed to by the
//          Sacl field.  If this flag is set and the Sacl field of the
//          SECURITY_DESCRIPTOR is null, then an empty (but present)
//          ACL is being specified.
//      SE_SACL_DEFAULTED - This boolean flag, when set, indicates that the
//          ACL pointed to by the Sacl field was provided by a defaulting
//          mechanism rather than explicitly provided by the original
//          provider of the security descriptor.  This may affect the
//          treatment of the ACL with respect to inheritence of an ACL.
//          This flag is ignored if the SaclPresent flag is not set.
//      SE_SELF_RELATIVE - This boolean flag, when set, indicates that the
//          security descriptor is in self-relative form.  In this form,
//          all fields of the security descriptor are contiguous in memory
//          and all pointer fields are expressed as offsets from the
//          beginning of the security descriptor.  This form is useful
//          for treating security descriptors as opaque data structures
//          for transmission in communication protocol or for storage on
//          secondary media.
// Pictorially the structure of a security descriptor is as follows:
//       3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//       1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//      +---------------------------------------------------------------+
//      |            Control            |Reserved1 (SBZ)|   Revision    |
//      +---------------------------------------------------------------+
//      |                            Owner                              |
//      +---------------------------------------------------------------+
//      |                            Group                              |
//      +---------------------------------------------------------------+
//      |                            Sacl                               |
//      +---------------------------------------------------------------+
//      |                            Dacl                               |
//      +---------------------------------------------------------------+
// In general, this data structure should be treated opaquely to ensure future
// compatibility.

struct SECURITY_DESCRIPTOR_RELATIVE {
  BYTE  Revision;
  BYTE  Sbz1;
  word Control;
  DWORD Owner;
  DWORD Group;
  DWORD Sacl;
  DWORD Dacl;
};

struct SECURITY_DESCRIPTOR {
  BYTE  Revision;
  BYTE  Sbz1;
  word Control;
  dword Owner;
  dword Group;
  dword Sacl;
  dword Dacl;
};
#define SECURITY_DESCRIPTOR_MIN_LENGTH   sizeof(SECURITY_DESCRIPTOR)
// end_ntifs

// Where:
//     Revision - Contains the revision level of the security
//         descriptor.  This allows this structure to be passed between
//         systems or stored on disk even though it is expected to
//         change in the future.
//     Control - A set of flags which qualify the meaning of the
//         security descriptor or individual fields of the security
//         descriptor.
//     Owner - is a pointer to an SID representing an object's owner.
//         If this field is null, then no owner SID is present in the
//         security descriptor.  If the security descriptor is in
//         self-relative form, then this field contains an offset to
//         the SID, rather than a pointer.
//     Group - is a pointer to an SID representing an object's primary
//         group.  If this field is null, then no primary group SID is
//         present in the security descriptor.  If the security descriptor
//         is in self-relative form, then this field contains an offset to
//         the SID, rather than a pointer.
//     Sacl - is a pointer to a system ACL.  This field value is only
//         valid if the DaclPresent control flag is set.  If the
//         SaclPresent flag is set and this field is null, then a null
//         ACL  is specified.  If the security descriptor is in
//         self-relative form, then this field contains an offset to
//         the ACL, rather than a pointer.
//     Dacl - is a pointer to a discretionary ACL.  This field value is
//         only valid if the DaclPresent control flag is set.  If the
//         DaclPresent flag is set and this field is null, then a null
//         ACL (unconditionally granting access) is specified.  If the
//         security descriptor is in self-relative form, then this field
//         contains an offset to the ACL, rather than a pointer.

////////////////////////////////////////////////////////////////////////
//               Object Type list for AccessCheckByType               //
////////////////////////////////////////////////////////////////////////

struct OBJECT_TYPE_LIST {
  WORD   Level;
  WORD   Sbz;
  GUID *ObjectType;
};

// DS values for Level
#define ACCESS_OBJECT_GUID       0
#define ACCESS_PROPERTY_SET_GUID 1
#define ACCESS_PROPERTY_GUID     2
#define ACCESS_MAX_LEVEL         4

// Parameters to NtAccessCheckByTypeAndAditAlarm
enum AUDIT_EVENT_TYPE{
  AuditEventObjectAccess,
  AuditEventDirectoryServiceAccess
};

#define AUDIT_ALLOW_NO_PRIVILEGE 0x1

// DS values for Source and ObjectTypeName
#define ACCESS_DS_SOURCE_A "DS"
#define ACCESS_DS_SOURCE_W L"DS"
#define ACCESS_DS_OBJECT_TYPE_NAME_A "Directory Service Object"
#define ACCESS_DS_OBJECT_TYPE_NAME_W L"Directory Service Object"

////////////////////////////////////////////////////////////////////////
//               Privilege Related Data Structures                    //
////////////////////////////////////////////////////////////////////////

// begin_wdm begin_ntddk begin_nthal
// Privilege attributes
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT 0x00000001L
#define SE_PRIVILEGE_ENABLED            0x00000002L
#define SE_PRIVILEGE_USED_FOR_ACCESS    0x80000000L

// Privilege Set Control flags
#define PRIVILEGE_SET_ALL_NECESSARY    1

//  Privilege Set - This is defined for a privilege set of one.
//                  If more than one privilege is needed, then this structure
//                  will need to be allocated with more space.
//  Note: don't change this structure without fixing the INITIAL_PRIVILEGE_SET
//  structure (defined in se.h)
struct PRIVILEGE_SET {
  DWORD PrivilegeCount;
  DWORD Control;
  LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
};

////////////////////////////////////////////////////////////////////////
//               NT Defined Privileges                                //
////////////////////////////////////////////////////////////////////////
#define SE_CREATE_TOKEN_NAME              "SeCreateTokenPrivilege"
#define SE_ASSIGNPRIMARYTOKEN_NAME        "SeAssignPrimaryTokenPrivilege"
#define SE_LOCK_MEMORY_NAME               "SeLockMemoryPrivilege"
#define SE_INCREASE_QUOTA_NAME            "SeIncreaseQuotaPrivilege"
#define SE_UNSOLICITED_INPUT_NAME         "SeUnsolicitedInputPrivilege"
#define SE_MACHINE_ACCOUNT_NAME           "SeMachineAccountPrivilege"
#define SE_TCB_NAME                       "SeTcbPrivilege"
#define SE_SECURITY_NAME                  "SeSecurityPrivilege"
#define SE_TAKE_OWNERSHIP_NAME            "SeTakeOwnershipPrivilege"
#define SE_LOAD_DRIVER_NAME               "SeLoadDriverPrivilege"
#define SE_SYSTEM_PROFILE_NAME            "SeSystemProfilePrivilege"
#define SE_SYSTEMTIME_NAME                "SeSystemtimePrivilege"
#define SE_PROF_SINGLE_PROCESS_NAME       "SeProfileSingleProcessPrivilege"
#define SE_INC_BASE_PRIORITY_NAME         "SeIncreaseBasePriorityPrivilege"
#define SE_CREATE_PAGEFILE_NAME           "SeCreatePagefilePrivilege"
#define SE_CREATE_PERMANENT_NAME          "SeCreatePermanentPrivilege"
#define SE_BACKUP_NAME                    "SeBackupPrivilege"
#define SE_RESTORE_NAME                   "SeRestorePrivilege"
#define SE_SHUTDOWN_NAME                  "SeShutdownPrivilege"
#define SE_DEBUG_NAME                     "SeDebugPrivilege"
#define SE_AUDIT_NAME                     "SeAuditPrivilege"
#define SE_SYSTEM_ENVIRONMENT_NAME        "SeSystemEnvironmentPrivilege"
#define SE_CHANGE_NOTIFY_NAME             "SeChangeNotifyPrivilege"
#define SE_REMOTE_SHUTDOWN_NAME           "SeRemoteShutdownPrivilege"
#define SE_UNDOCK_NAME                    "SeUndockPrivilege"
#define SE_SYNC_AGENT_NAME                "SeSyncAgentPrivilege"
#define SE_ENABLE_DELEGATION_NAME         "SeEnableDelegationPrivilege"
#define SE_MANAGE_VOLUME_NAME             "SeManageVolumePrivilege"

////////////////////////////////////////////////////////////////////
//           Security Quality Of Service                          //
////////////////////////////////////////////////////////////////////
// begin_wdm begin_ntddk begin_nthal begin_ntifs
// Impersonation Level
// Impersonation level is represented by a pair of bits in Windows.
// If a new impersonation level is added or lowest value is changed from
// 0 to something else, fix the Windows CreateFile call.
enum SECURITY_IMPERSONATION_LEVEL{
  SecurityAnonymous,
  SecurityIdentification,
  SecurityImpersonation,
  SecurityDelegation
};

#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation
#define SECURITY_MIN_IMPERSONATION_LEVEL SecurityAnonymous
#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation
#define VALID_IMPERSONATION_LEVEL(L) ((L >= SECURITY_MIN_IMPERSONATION_LEVEL) && (L <= SECURITY_MAX_IMPERSONATION_LEVEL))

////////////////////////////////////////////////////////////////////
//           Token Object Definitions                             //
////////////////////////////////////////////////////////////////////
// Token Specific Access Rights.
#define TOKEN_ASSIGN_PRIMARY    0x0001
#define TOKEN_DUPLICATE         0x0002
#define TOKEN_IMPERSONATE       0x0004
#define TOKEN_QUERY             0x0008
#define TOKEN_QUERY_SOURCE      0x0010
#define TOKEN_ADJUST_PRIVILEGES 0x0020
#define TOKEN_ADJUST_GROUPS     0x0040
#define TOKEN_ADJUST_DEFAULT    0x0080
#define TOKEN_ADJUST_SESSIONID  0x0100

#define TOKEN_ALL_ACCESS_P STANDARD_RIGHTS_REQUIRED |\
                          TOKEN_ASSIGN_PRIMARY      |\
                          TOKEN_DUPLICATE           |\
                          TOKEN_IMPERSONATE         |\
                          TOKEN_QUERY               |\
                          TOKEN_QUERY_SOURCE        |\
                          TOKEN_ADJUST_PRIVILEGES   |\
                          TOKEN_ADJUST_GROUPS       |\
                          TOKEN_ADJUST_DEFAULT

#define TOKEN_ALL_ACCESS  TOKEN_ALL_ACCESS_P |\
                          TOKEN_ADJUST_SESSIONID
#define TOKEN_READ       STANDARD_RIGHTS_READ      |\
                          TOKEN_QUERY
#define TOKEN_WRITE      STANDARD_RIGHTS_WRITE     |\
                          TOKEN_ADJUST_PRIVILEGES   |\
                          TOKEN_ADJUST_GROUPS       |\
                          TOKEN_ADJUST_DEFAULT
#define TOKEN_EXECUTE    STANDARD_RIGHTS_EXECUTE

// Token Types
enum TOKEN_TYPE{
  TokenPrimary = 1,
  TokenImpersonation
};

// Token Information Classes.
enum TOKEN_INFORMATION_CLASS{
  TokenUser = 1,
  TokenGroups,
  TokenPrivileges,
  TokenOwner,
  TokenPrimaryGroup,
  TokenDefaultDacl,
  TokenSource,
  TokenType,
  TokenImpersonationLevel,
  TokenStatistics,
  TokenRestrictedSids,
  TokenSessionId,
  TokenGroupsAndPrivileges,
  TokenSessionReference,
  TokenSandBoxInert
};

// Token information class structures
struct TOKEN_USER {
  SID_AND_ATTRIBUTES User;
};

struct TOKEN_GROUPS {
  DWORD GroupCount;
  SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
};

struct TOKEN_PRIVILEGES {
  DWORD PrivilegeCount;
  LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
};

struct TOKEN_OWNER {
  dword Owner;
};

struct TOKEN_PRIMARY_GROUP {
  dword PrimaryGroup;
};

struct TOKEN_DEFAULT_DACL {
  dword DefaultDacl;
};

struct TOKEN_GROUPS_AND_PRIVILEGES {
  DWORD SidCount;
  DWORD SidLength;
  dword Sids;
  DWORD RestrictedSidCount;
  DWORD RestrictedSidLength;
  dword RestrictedSids;
  DWORD PrivilegeCount;
  DWORD PrivilegeLength;
  dword Privileges;
  LUID AuthenticationId;
};

#define TOKEN_SOURCE_LENGTH 8

struct TOKEN_SOURCE {
  CHAR SourceName[TOKEN_SOURCE_LENGTH];
  LUID SourceIdentifier;
};

struct TOKEN_STATISTICS {
  LUID TokenId;
  LUID AuthenticationId;
  LARGE_INTEGER ExpirationTime;
  dword TokenType;
  dword ImpersonationLevel;
  DWORD DynamicCharged;
  DWORD DynamicAvailable;
  DWORD GroupCount;
  DWORD PrivilegeCount;
  LUID ModifiedId;
};

struct TOKEN_CONTROL {
  LUID TokenId;
  LUID AuthenticationId;
  LUID ModifiedId;
  TOKEN_SOURCE TokenSource;
};

// Security Tracking Mode
#define SECURITY_DYNAMIC_TRACKING      TRUE
#define SECURITY_STATIC_TRACKING       FALSE

// Quality Of Service
struct SECURITY_QUALITY_OF_SERVICE {
  DWORD Length;
  dword ImpersonationLevel;
  BOOLEAN ContextTrackingMode;
  BOOLEAN EffectiveOnly;
};

// Used to represent information related to a thread impersonation
struct SE_IMPERSONATION_STATE {
  dword Token;
  BOOLEAN CopyOnOpen;
  BOOLEAN EffectiveOnly;
  dword Level;
};

#define DISABLE_MAX_PRIVILEGE   0x1
#define SANDBOX_INERT           0x2

#define OWNER_SECURITY_INFORMATION       0x00000001L
#define GROUP_SECURITY_INFORMATION       0x00000002L
#define DACL_SECURITY_INFORMATION        0x00000004L
#define SACL_SECURITY_INFORMATION        0x00000008L

#define PROTECTED_DACL_SECURITY_INFORMATION     0x80000000L
#define PROTECTED_SACL_SECURITY_INFORMATION     0x40000000L
#define UNPROTECTED_DACL_SECURITY_INFORMATION   0x20000000L
#define UNPROTECTED_SACL_SECURITY_INFORMATION   0x10000000L

#define PROCESS_TERMINATE         0x0001
#define PROCESS_CREATE_THREAD     0x0002
#define PROCESS_SET_SESSIONID     0x0004
#define PROCESS_VM_OPERATION      0x0008
#define PROCESS_VM_READ           0x0010
#define PROCESS_VM_WRITE          0x0020
#define PROCESS_DUP_HANDLE        0x0040
#define PROCESS_CREATE_PROCESS    0x0080
#define PROCESS_SET_QUOTA         0x0100
#define PROCESS_SET_INFORMATION   0x0200
#define PROCESS_QUERY_INFORMATION 0x0400
#define PROCESS_SUSPEND_RESUME    0x0800
#define PROCESS_ALL_ACCESS        STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xFFF
// begin_nthal

#define MAXIMUM_PROCESSORS 32
// end_nthal

#define THREAD_TERMINATE               0x0001
#define THREAD_SUSPEND_RESUME          0x0002
#define THREAD_GET_CONTEXT             0x0008
#define THREAD_SET_CONTEXT             0x0010
#define THREAD_SET_INFORMATION         0x0020
#define THREAD_QUERY_INFORMATION       0x0040
#define THREAD_SET_THREAD_TOKEN        0x0080
#define THREAD_IMPERSONATE             0x0100
#define THREAD_DIRECT_IMPERSONATION    0x0200
// begin_ntddk begin_wdm begin_ntifs

#define THREAD_ALL_ACCESS         STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF

// end_ntddk end_wdm end_ntifs
#define JOB_OBJECT_ASSIGN_PROCESS           0x0001
#define JOB_OBJECT_SET_ATTRIBUTES           0x0002
#define JOB_OBJECT_QUERY                    0x0004
#define JOB_OBJECT_TERMINATE                0x0008
#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES  0x0010
#define JOB_OBJECT_ALL_ACCESS       STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1F

struct JOB_SET_ARRAY {
  HANDLE JobHandle;   // Handle to job object to insert
  DWORD MemberLevel;  // Level of this job in the set. Must be > 0. Can be sparse.
  DWORD Flags;        // Unused. Must be zero
};

#define TLS_MINIMUM_AVAILABLE 64

struct NT_TIB {
  dword ExceptionList;
  dword StackBase;
  dword StackLimit;
  dword SubSystemTib;
  union {
    dword FiberData;
    DWORD Version;
  };
  dword ArbitraryUserPointer;
  dword Self;
};

// 32 and 64 bit specific version for wow64 and the debugger
struct NT_TIB32 {
  DWORD ExceptionList;
  DWORD StackBase;
  DWORD StackLimit;
  DWORD SubSystemTib;
  union {
    DWORD FiberData;
    DWORD Version;
  };
  DWORD ArbitraryUserPointer;
  DWORD Self;
};

struct NT_TIB64 {
  qword ExceptionList;
  qword StackBase;
  qword StackLimit;
  qword SubSystemTib;
  union {
     qword FiberData;
     DWORD Version;
  };
  qword ArbitraryUserPointer;
  qword Self;
};

#define THREAD_BASE_PRIORITY_LOWRT  15  // value that gets a thread to LowRealtime-1
#define THREAD_BASE_PRIORITY_MAX    2   // maximum thread base priority boost
#define THREAD_BASE_PRIORITY_MIN    -2  // minimum thread base priority boost
#define THREAD_BASE_PRIORITY_IDLE   -15 // value that gets a thread to idle

struct QUOTA_LIMITS {
  SIZE_T PagedPoolLimit;
  SIZE_T NonPagedPoolLimit;
  SIZE_T MinimumWorkingSetSize;
  SIZE_T MaximumWorkingSetSize;
  SIZE_T PagefileLimit;
  LARGE_INTEGER TimeLimit;
};

struct IO_COUNTERS {
  ULONGLONG  ReadOperationCount;
  ULONGLONG  WriteOperationCount;
  ULONGLONG  OtherOperationCount;
  ULONGLONG ReadTransferCount;
  ULONGLONG WriteTransferCount;
  ULONGLONG OtherTransferCount;
};

struct JOBOBJECT_BASIC_ACCOUNTING_INFORMATION {
  LARGE_INTEGER TotalUserTime;
  LARGE_INTEGER TotalKernelTime;
  LARGE_INTEGER ThisPeriodTotalUserTime;
  LARGE_INTEGER ThisPeriodTotalKernelTime;
  DWORD TotalPageFaultCount;
  DWORD TotalProcesses;
  DWORD ActiveProcesses;
  DWORD TotalTerminatedProcesses;
};

struct JOBOBJECT_BASIC_LIMIT_INFORMATION {
  LARGE_INTEGER PerProcessUserTimeLimit;
  LARGE_INTEGER PerJobUserTimeLimit;
  DWORD LimitFlags;
  SIZE_T MinimumWorkingSetSize;
  SIZE_T MaximumWorkingSetSize;
  DWORD ActiveProcessLimit;
  dword Affinity;
  DWORD PriorityClass;
  DWORD SchedulingClass;
};

struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
  JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
  IO_COUNTERS IoInfo;
  SIZE_T ProcessMemoryLimit;
  SIZE_T JobMemoryLimit;
  SIZE_T PeakProcessMemoryUsed;
  SIZE_T PeakJobMemoryUsed;
};

struct JOBOBJECT_BASIC_PROCESS_ID_LIST {
  DWORD NumberOfAssignedProcesses;
  DWORD NumberOfProcessIdsInList;
  dword ProcessIdList[1];
};

struct JOBOBJECT_BASIC_UI_RESTRICTIONS {
  DWORD UIRestrictionsClass;
};

struct JOBOBJECT_SECURITY_LIMIT_INFORMATION {
  DWORD SecurityLimitFlags ;
  HANDLE JobToken ;
  dword SidsToDisable ;
  dword PrivilegesToDelete ;
  dword RestrictedSids ;
};

struct JOBOBJECT_END_OF_JOB_TIME_INFORMATION {
  DWORD EndOfJobTimeAction;
};

struct JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
  dword CompletionKey;
  HANDLE CompletionPort;
};

struct JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION {
  JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo;
  IO_COUNTERS IoInfo;
};

struct JOBOBJECT_JOBSET_INFORMATION {
  DWORD MemberLevel;
};

#define JOB_OBJECT_TERMINATE_AT_END_OF_JOB  0
#define JOB_OBJECT_POST_AT_END_OF_JOB       1

// Completion Port Messages for job objects
// These values are returned via the lpNumberOfBytesTransferred parameter
#define JOB_OBJECT_MSG_END_OF_JOB_TIME          1
#define JOB_OBJECT_MSG_END_OF_PROCESS_TIME      2
#define JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT     3
#define JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO      4
#define JOB_OBJECT_MSG_NEW_PROCESS              6
#define JOB_OBJECT_MSG_EXIT_PROCESS             7
#define JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS    8
#define JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT     9
#define JOB_OBJECT_MSG_JOB_MEMORY_LIMIT         10

// Basic Limits
#define JOB_OBJECT_LIMIT_WORKINGSET                 0x00000001
#define JOB_OBJECT_LIMIT_PROCESS_TIME               0x00000002
#define JOB_OBJECT_LIMIT_JOB_TIME                   0x00000004
#define JOB_OBJECT_LIMIT_ACTIVE_PROCESS             0x00000008
#define JOB_OBJECT_LIMIT_AFFINITY                   0x00000010
#define JOB_OBJECT_LIMIT_PRIORITY_CLASS             0x00000020
#define JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME          0x00000040
#define JOB_OBJECT_LIMIT_SCHEDULING_CLASS           0x00000080

// Extended Limits
#define JOB_OBJECT_LIMIT_PROCESS_MEMORY             0x00000100
#define JOB_OBJECT_LIMIT_JOB_MEMORY                 0x00000200
#define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400
#define JOB_OBJECT_LIMIT_BREAKAWAY_OK               0x00000800
#define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK        0x00001000
#define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE          0x00002000
#define JOB_OBJECT_LIMIT_RESERVED2                  0x00004000
#define JOB_OBJECT_LIMIT_RESERVED3                  0x00008000
#define JOB_OBJECT_LIMIT_RESERVED4                  0x00010000
#define JOB_OBJECT_LIMIT_RESERVED5                  0x00020000
#define JOB_OBJECT_LIMIT_RESERVED6                  0x00040000
#define JOB_OBJECT_LIMIT_VALID_FLAGS            0x0007ffff
#define JOB_OBJECT_BASIC_LIMIT_VALID_FLAGS      0x000000ff
#define JOB_OBJECT_EXTENDED_LIMIT_VALID_FLAGS   0x00003fff
#define JOB_OBJECT_RESERVED_LIMIT_VALID_FLAGS   0x0007ffff

// UI restrictions for jobs
#define JOB_OBJECT_UILIMIT_NONE             0x00000000

#define JOB_OBJECT_UILIMIT_HANDLES          0x00000001
#define JOB_OBJECT_UILIMIT_READCLIPBOARD    0x00000002
#define JOB_OBJECT_UILIMIT_WRITECLIPBOARD   0x00000004
#define JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS 0x00000008
#define JOB_OBJECT_UILIMIT_DISPLAYSETTINGS  0x00000010
#define JOB_OBJECT_UILIMIT_GLOBALATOMS      0x00000020
#define JOB_OBJECT_UILIMIT_DESKTOP          0x00000040
#define JOB_OBJECT_UILIMIT_EXITWINDOWS      0x00000080
#define JOB_OBJECT_UILIMIT_ALL              0x000000FF
#define JOB_OBJECT_UI_VALID_FLAGS           0x000000FF
#define JOB_OBJECT_SECURITY_NO_ADMIN            0x00000001
#define JOB_OBJECT_SECURITY_RESTRICTED_TOKEN    0x00000002
#define JOB_OBJECT_SECURITY_ONLY_TOKEN          0x00000004
#define JOB_OBJECT_SECURITY_FILTER_TOKENS       0x00000008
#define JOB_OBJECT_SECURITY_VALID_FLAGS         0x0000000f

enum JOBOBJECTINFOCLASS{
  JobObjectBasicAccountingInformation = 1,
  JobObjectBasicLimitInformation,
  JobObjectBasicProcessIdList,
  JobObjectBasicUIRestrictions,
  JobObjectSecurityLimitInformation,
  JobObjectEndOfJobTimeInformation,
  JobObjectAssociateCompletionPortInformation,
  JobObjectBasicAndIoAccountingInformation,
  JobObjectExtendedLimitInformation,
  JobObjectJobSetInformation,
  MaxJobObjectInfoClass
};
#define EVENT_MODIFY_STATE      0x0002
#define EVENT_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3
#define MUTANT_QUERY_STATE      0x0001
#define MUTANT_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|MUTANT_QUERY_STATE
#define SEMAPHORE_MODIFY_STATE      0x0002
#define SEMAPHORE_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3
// Timer Specific Access Rights.

#define TIMER_QUERY_STATE       0x0001
#define TIMER_MODIFY_STATE      0x0002

#define TIMER_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|\
                          TIMER_QUERY_STATE|TIMER_MODIFY_STATE

#define TIME_ZONE_ID_UNKNOWN  0
#define TIME_ZONE_ID_STANDARD 1
#define TIME_ZONE_ID_DAYLIGHT 2
#define MAXIMUM_NUMA_NODES 16

struct SYSTEM_NUMA_INFORMATION{
  DWORD       HighestNodeNumber;
  DWORD       Reserved;
  union {
      ULONGLONG   ActiveProcessorsAffinityMask[MAXIMUM_NUMA_NODES];
      ULONGLONG   AvailableMemory[MAXIMUM_NUMA_NODES];
  };
};

#define PROCESSOR_INTEL_386     386
#define PROCESSOR_INTEL_486     486
#define PROCESSOR_INTEL_PENTIUM 586
#define PROCESSOR_INTEL_IA64    2200
#define PROCESSOR_MIPS_R4000    4000    // incl R4101 & R3910 for Windows CE
#define PROCESSOR_ALPHA_21064   21064
#define PROCESSOR_PPC_601       601
#define PROCESSOR_PPC_603       603
#define PROCESSOR_PPC_604       604
#define PROCESSOR_PPC_620       620
#define PROCESSOR_HITACHI_SH3   10003   // Windows CE
#define PROCESSOR_HITACHI_SH3E  10004   // Windows CE
#define PROCESSOR_HITACHI_SH4   10005   // Windows CE
#define PROCESSOR_MOTOROLA_821  821     // Windows CE
#define PROCESSOR_SHx_SH3       103     // Windows CE
#define PROCESSOR_SHx_SH4       104     // Windows CE
#define PROCESSOR_STRONGARM     2577    // Windows CE - 0xA11
#define PROCESSOR_ARM720        1824    // Windows CE - 0x720
#define PROCESSOR_ARM820        2080    // Windows CE - 0x820
#define PROCESSOR_ARM920        2336    // Windows CE - 0x920
#define PROCESSOR_ARM_7TDMI     70001   // Windows CE
#define PROCESSOR_OPTIL         0x494f  // MSIL
#define PROCESSOR_ARCHITECTURE_INTEL            0
#define PROCESSOR_ARCHITECTURE_MIPS             1
#define PROCESSOR_ARCHITECTURE_ALPHA            2
#define PROCESSOR_ARCHITECTURE_PPC              3
#define PROCESSOR_ARCHITECTURE_SHX              4
#define PROCESSOR_ARCHITECTURE_ARM              5
#define PROCESSOR_ARCHITECTURE_IA64             6
#define PROCESSOR_ARCHITECTURE_ALPHA64          7
#define PROCESSOR_ARCHITECTURE_MSIL             8
#define PROCESSOR_ARCHITECTURE_AMD64            9
#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64    10
#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
#define PF_FLOATING_POINT_PRECISION_ERRATA  0
#define PF_FLOATING_POINT_EMULATED          1
#define PF_COMPARE_EXCHANGE_DOUBLE          2
#define PF_MMX_INSTRUCTIONS_AVAILABLE       3
#define PF_PPC_MOVEMEM_64BIT_OK             4
#define PF_ALPHA_BYTE_INSTRUCTIONS          5
#define PF_XMMI_INSTRUCTIONS_AVAILABLE      6
#define PF_3DNOW_INSTRUCTIONS_AVAILABLE     7
#define PF_RDTSC_INSTRUCTION_AVAILABLE      8
#define PF_PAE_ENABLED                      9
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE   10

struct MEMORY_BASIC_INFORMATION {
  dword BaseAddress;
  dword AllocationBase;
  DWORD AllocationProtect;
  SIZE_T RegionSize;
  DWORD State;
  DWORD Protect;
  DWORD Type;
};

struct MEMORY_BASIC_INFORMATION32 {
  DWORD BaseAddress;
  DWORD AllocationBase;
  DWORD AllocationProtect;
  DWORD RegionSize;
  DWORD State;
  DWORD Protect;
  DWORD Type;
};

struct MEMORY_BASIC_INFORMATION64 {
  ULONGLONG BaseAddress;
  ULONGLONG AllocationBase;
  DWORD     AllocationProtect;
  DWORD     __alignment1;
  ULONGLONG RegionSize;
  DWORD     State;
  DWORD     Protect;
  DWORD     Type;
  DWORD     __alignment2;
};

#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
#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 PAGE_WRITECOMBINE     0x400
#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_RESET           0x80000
#define MEM_TOP_DOWN       0x100000
#define MEM_WRITE_WATCH    0x200000
#define MEM_PHYSICAL       0x400000
#define MEM_4MB_PAGES    0x80000000
#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
#define WRITE_WATCH_FLAG_RESET 0x01

// Define access rights to files and directories
// The FILE_READ_DATA and FILE_WRITE_DATA constants are also defined in
// devioctl.h as FILE_READ_ACCESS and FILE_WRITE_ACCESS. The values for these
// constants *MUST* always be in sync.
// The values are redefined in devioctl.h because they must be available to
// both DOS and NT.

#define FILE_READ_DATA            0x0001    // file & pipe
#define FILE_LIST_DIRECTORY       0x0001    // directory
#define FILE_WRITE_DATA           0x0002    // file & pipe
#define FILE_ADD_FILE             0x0002    // directory
#define FILE_APPEND_DATA          0x0004    // file
#define FILE_ADD_SUBDIRECTORY     0x0004    // directory
#define FILE_CREATE_PIPE_INSTANCE 0x0004    // named pipe
#define FILE_READ_EA              0x0008    // file & directory
#define FILE_WRITE_EA             0x0010    // file & directory
#define FILE_EXECUTE              0x0020    // file
#define FILE_TRAVERSE             0x0020    // directory
#define FILE_DELETE_CHILD         0x0040    // directory
#define FILE_READ_ATTRIBUTES      0x0080    // all
#define FILE_WRITE_ATTRIBUTES     0x0100    // all

#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_DEVICE               0x00000040
#define FILE_ATTRIBUTE_NORMAL               0x00000080
#define FILE_ATTRIBUTE_TEMPORARY            0x00000100
#define FILE_ATTRIBUTE_SPARSE_FILE          0x00000200
#define FILE_ATTRIBUTE_REPARSE_POINT        0x00000400
#define FILE_ATTRIBUTE_COMPRESSED           0x00000800
#define FILE_ATTRIBUTE_OFFLINE              0x00001000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
#define FILE_ATTRIBUTE_ENCRYPTED            0x00004000
#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_LAST_ACCESS  0x00000020
#define FILE_NOTIFY_CHANGE_CREATION     0x00000040
#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
#define MAILSLOT_NO_MESSAGE             -1
#define MAILSLOT_WAIT_FOREVER           -1
#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_QUOTAS              0x00000020
#define FILE_SUPPORTS_SPARSE_FILES      0x00000040
#define FILE_SUPPORTS_REPARSE_POINTS    0x00000080
#define FILE_SUPPORTS_REMOTE_STORAGE    0x00000100
#define FILE_VOLUME_IS_COMPRESSED       0x00008000
#define FILE_SUPPORTS_OBJECT_IDS        0x00010000
#define FILE_SUPPORTS_ENCRYPTION        0x00020000
#define FILE_NAMED_STREAMS              0x00040000
#define FILE_READ_ONLY_VOLUME           0x00080000

// Define the file notification information structure
struct FILE_NOTIFY_INFORMATION {
  DWORD NextEntryOffset;
  DWORD Action;
  DWORD FileNameLength;
  WCHAR FileName[1];
};

// Define segement buffer structure for scatter/gather read/write.
union FILE_SEGMENT_ELEMENT{
  dword Buffer;
  ULONGLONG Alignment;
};

// The reparse GUID structure is used by all 3rd party layered drivers to
// store data in a reparse point. For non-Microsoft tags, The GUID field
// cannot be GUID_NULL.
// The constraints on reparse tags are defined below.
// Microsoft tags can also be used with this format of the reparse point buffer.
struct REPARSE_GUID_DATA_BUFFER {
  DWORD  ReparseTag;
  WORD   ReparseDataLength;
  WORD   Reserved;
  GUID   ReparseGuid;
  struct {
    BYTE   DataBuffer[1];
  } GenericReparseBuffer;
};

#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER,GenericReparseBuffer)

// Maximum allowed size of the reparse data.
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE      16 * 1024

// Predefined reparse tags.
// These tags need to avoid conflicting with IO_REMOUNT defined in ntos\inc\io.h
#define IO_REPARSE_TAG_RESERVED_ZERO             0
#define IO_REPARSE_TAG_RESERVED_ONE              1

// The value of the following constant needs to satisfy the following conditions:
//  (1) Be at least as large as the largest of the reserved tags.
//  (2) Be strictly smaller than all the tags in use.
#define IO_REPARSE_TAG_RESERVED_RANGE            IO_REPARSE_TAG_RESERVED_ONE

// The reparse tags are a DWORD. The 32 bits are laid out as follows:
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +-+-+-+-+-----------------------+-------------------------------+
//  |M|R|N|R|     Reserved bits     |       Reparse Tag Value       |
//  +-+-+-+-+-----------------------+-------------------------------+
// M is the Microsoft bit. When set to 1, it denotes a tag owned by Microsoft.
//   All ISVs must use a tag with a 0 in this position.
//   Note: If a Microsoft tag is used by non-Microsoft software, the
//   behavior is not defined.
// R is reserved.  Must be zero for non-Microsoft tags.
// N is name surrogate. When set to 1, the file represents another named
//   entity in the system.
// The M and N bits are OR-able.
// The following macros check for the M and N bit values:
// Macro to determine whether a reparse point tag corresponds to a tag
// owned by Microsoft.

#define IsReparseTagMicrosoft(_tag) _tag&0x80000000

// Macro to determine whether a reparse point tag is a name surrogate
#define IsReparseTagNameSurrogate(_tag) _tag&0x20000000

#define IO_REPARSE_TAG_MOUNT_POINT               0xA0000003L
#define IO_REPARSE_TAG_HSM                       0xC0000004L
#define IO_REPARSE_TAG_SIS                       0x80000007L
#define IO_REPARSE_TAG_FILTER_MANAGER            0x8000000BL
#define IO_COMPLETION_MODIFY_STATE  0x0002
#define IO_COMPLETION_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3
#define DUPLICATE_CLOSE_SOURCE      0x00000001
#define DUPLICATE_SAME_ACCESS       0x00000002

enum SYSTEM_POWER_STATE{
  PowerSystemUnspecified = 0,
  PowerSystemWorking     = 1,
  PowerSystemSleeping1   = 2,
  PowerSystemSleeping2   = 3,
  PowerSystemSleeping3   = 4,
  PowerSystemHibernate   = 5,
  PowerSystemShutdown    = 6,
  PowerSystemMaximum     = 7
};

#define POWER_SYSTEM_MAXIMUM 7

enum POWER_ACTION{
  PowerActionNone = 0,
  PowerActionReserved,
  PowerActionSleep,
  PowerActionHibernate,
  PowerActionShutdown,
  PowerActionShutdownReset,
  PowerActionShutdownOff,
  PowerActionWarmEject
};

enum DEVICE_POWER_STATE{
  PowerDeviceUnspecified = 0,
  PowerDeviceD0,
  PowerDeviceD1,
  PowerDeviceD2,
  PowerDeviceD3,
  PowerDeviceMaximum
};

#define ES_SYSTEM_REQUIRED  0x00000001
#define ES_DISPLAY_REQUIRED 0x00000002
#define ES_USER_PRESENT     0x00000004
#define ES_CONTINUOUS       0x80000000

#define EXECUTION_STATE dword

enum LATENCY_TIME{
  LT_DONT_CARE,
  LT_LOWEST_LATENCY
};

// end_ntminiport end_ntifs end_wdm end_ntddk
//-----------------------------------------------------------------------------
// Device Power Information
// Accessable via CM_Get_DevInst_Registry_Property_Ex(CM_DRP_DEVICE_POWER_DATA)
//-----------------------------------------------------------------------------
#define PDCAP_D0_SUPPORTED              0x00000001
#define PDCAP_D1_SUPPORTED              0x00000002
#define PDCAP_D2_SUPPORTED              0x00000004
#define PDCAP_D3_SUPPORTED              0x00000008
#define PDCAP_WAKE_FROM_D0_SUPPORTED    0x00000010
#define PDCAP_WAKE_FROM_D1_SUPPORTED    0x00000020
#define PDCAP_WAKE_FROM_D2_SUPPORTED    0x00000040
#define PDCAP_WAKE_FROM_D3_SUPPORTED    0x00000080
#define PDCAP_WARM_EJECT_SUPPORTED      0x00000100

struct CM_POWER_DATA{
  DWORD               PD_Size;
  dword  PD_MostRecentPowerState;
  DWORD               PD_Capabilities;
  DWORD               PD_D1Latency;
  DWORD               PD_D2Latency;
  DWORD               PD_D3Latency;
  dword  PD_PowerStateMapping[POWER_SYSTEM_MAXIMUM];
  dword  PD_DeepestSystemWake;
};

// begin_ntddk
enum POWER_INFORMATION_LEVEL{
  SystemPowerPolicyAc,
  SystemPowerPolicyDc,
  VerifySystemPolicyAc,
  VerifySystemPolicyDc,
  SystemPowerCapabilities,
  SystemBatteryState,
  SystemPowerStateHandler,
  ProcessorStateHandler,
  SystemPowerPolicyCurrent,
  AdministratorPowerPolicy,
  SystemReserveHiberFile,
  ProcessorInformation,
  SystemPowerInformation,
  ProcessorStateHandler2,
  LastWakeTime,                                   // Compare with KeQueryInterruptTime()
  LastSleepTime,                                  // Compare with KeQueryInterruptTime()
  SystemExecutionState,
  SystemPowerStateNotifyHandler,
  ProcessorPowerPolicyAc,
  ProcessorPowerPolicyDc,
  VerifyProcessorPowerPolicyAc,
  VerifyProcessorPowerPolicyDc,
  ProcessorPowerPolicyCurrent
};

// begin_wdm

// System power manager capabilities
struct BATTERY_REPORTING_SCALE{
  DWORD       Granularity;
  DWORD       Capacity;
};

// Power Policy Management interfaces
struct POWER_ACTION_POLICY{
  dword    Action;
  DWORD           Flags;
  DWORD           EventCode;
};

// POWER_ACTION_POLICY->Flags:
#define POWER_ACTION_QUERY_ALLOWED      0x00000001
#define POWER_ACTION_UI_ALLOWED         0x00000002
#define POWER_ACTION_OVERRIDE_APPS      0x00000004
#define POWER_ACTION_LIGHTEST_FIRST     0x10000000
#define POWER_ACTION_LOCK_CONSOLE       0x20000000
#define POWER_ACTION_DISABLE_WAKES      0x40000000
#define POWER_ACTION_CRITICAL           0x80000000

// POWER_ACTION_POLICY->EventCode flags
#define POWER_LEVEL_USER_NOTIFY_TEXT    0x00000001
#define POWER_LEVEL_USER_NOTIFY_SOUND   0x00000002
#define POWER_LEVEL_USER_NOTIFY_EXEC    0x00000004
#define POWER_USER_NOTIFY_BUTTON        0x00000008
#define POWER_USER_NOTIFY_SHUTDOWN      0x00000010
#define POWER_FORCE_TRIGGER_RESET       0x80000000

// system battery drain policies
struct SYSTEM_POWER_LEVEL{
  BOOLEAN                 Enable;
  BYTE                    Spare[3];
  DWORD                   BatteryLevel;
  POWER_ACTION_POLICY     PowerPolicy;
  dword      MinSystemState;
};

// Discharge policy constants
#define NUM_DISCHARGE_POLICIES      4
#define DISCHARGE_POLICY_CRITICAL   0
#define DISCHARGE_POLICY_LOW        1

// Throttling policies
#define PO_THROTTLE_NONE            0
#define PO_THROTTLE_CONSTANT        1
#define PO_THROTTLE_DEGRADE         2
#define PO_THROTTLE_ADAPTIVE        3
#define PO_THROTTLE_MAXIMUM         4   // not a policy, just a limit

// system power policies
struct SYSTEM_POWER_POLICY {
  DWORD                   Revision;       // 1
  // events
  POWER_ACTION_POLICY     PowerButton;
  POWER_ACTION_POLICY     SleepButton;
  POWER_ACTION_POLICY     LidClose;
  dword      LidOpenWake;
  DWORD                   Reserved;
  // "system idle" detection
  POWER_ACTION_POLICY     Idle;
  DWORD                   IdleTimeout;
  BYTE                    IdleSensitivity;
  // dynamic throttling policy
  //      PO_THROTTLE_NONE, PO_THROTTLE_CONSTANT, PO_THROTTLE_DEGRADE, or PO_THROTTLE_ADAPTIVE
  BYTE                    DynamicThrottle;
  BYTE                    Spare2[2];
  // meaning of power action "sleep"
  dword      MinSleep;
  dword      MaxSleep;
  dword      ReducedLatencySleep;
  DWORD                   WinLogonFlags;
  // parameters for dozing
  DWORD                   Spare3;
  DWORD                   DozeS4Timeout;
  // battery policies
  DWORD                   BroadcastCapacityResolution;
  SYSTEM_POWER_LEVEL      DischargePolicy[NUM_DISCHARGE_POLICIES];
  // video policies
  DWORD                   VideoTimeout;
  BOOLEAN                 VideoDimDisplay;
  DWORD                   VideoReserved[3];
  // hard disk policies
  DWORD                   SpindownTimeout;
  // processor policies
  BOOLEAN                 OptimizeForPower;
  BYTE                    FanThrottleTolerance;
  BYTE                    ForcedThrottle;
  BYTE                    MinThrottle;
  POWER_ACTION_POLICY     OverThrottled;
};

// processor power policy state
struct PROCESSOR_POWER_POLICY_INFO {
  // Time based information (will be converted to kernel units)
  DWORD                   TimeCheck;                      // in US
  DWORD                   DemoteLimit;                    // in US
  DWORD                   PromoteLimit;                   // in US
  // Percentage based information
  BYTE                    DemotePercent;
  BYTE                    PromotePercent;
  BYTE                    Spare[2];
  // Flags
  DWORD                   AllowDemotion:1;
  DWORD                   AllowPromotion:1;
  DWORD                   Reserved:30;
};

// processor power policy
struct PROCESSOR_POWER_POLICY {
  DWORD                       Revision;       // 1
  // Dynamic Throttling Policy
  BYTE                        DynamicThrottle;
  BYTE                        Spare[3];
  // Flags
  DWORD                       Reserved;
  // System policy information
  // The Array is last, in case it needs to be grown and the structure
  // revision incremented.
  DWORD                       PolicyCount;
  PROCESSOR_POWER_POLICY_INFO Policy[3];
};

// administrator power policy overrides
struct ADMINISTRATOR_POWER_POLICY {
  // meaning of power action "sleep"
  dword      MinSleep;
  dword      MaxSleep;
  // video policies
  DWORD                   MinVideoTimeout;
  DWORD                   MaxVideoTimeout;
  // disk policies
  DWORD                   MinSpindownTimeout;
  DWORD                   MaxSpindownTimeout;
};

struct SYSTEM_POWER_CAPABILITIES{
  // Misc supported system features
  BOOLEAN             PowerButtonPresent;
  BOOLEAN             SleepButtonPresent;
  BOOLEAN             LidPresent;
  BOOLEAN             SystemS1;
  BOOLEAN             SystemS2;
  BOOLEAN             SystemS3;
  BOOLEAN             SystemS4;           // hibernate
  BOOLEAN             SystemS5;           // off
  BOOLEAN             HiberFilePresent;
  BOOLEAN             FullWake;
  BOOLEAN             VideoDimPresent;
  BOOLEAN             ApmPresent;
  BOOLEAN             UpsPresent;
  // Processors
  BOOLEAN             ThermalControl;
  BOOLEAN             ProcessorThrottle;
  BYTE                ProcessorMinThrottle;
  BYTE                ProcessorMaxThrottle;
  BYTE                spare2[4];
  // Disk
  BOOLEAN             DiskSpinDown;
  BYTE                spare3[8];
  // System Battery
  BOOLEAN             SystemBatteriesPresent;
  BOOLEAN             BatteriesAreShortTerm;
  BATTERY_REPORTING_SCALE BatteryScale[3];
  // Wake
  dword  AcOnLineWake;
  dword  SoftLidWake;
  dword  RtcWake;
  dword  MinDeviceWakeState; // note this may change on driver load
  dword  DefaultLowLatencyWake;
};

struct SYSTEM_BATTERY_STATE{
  BOOLEAN             AcOnLine;
  BOOLEAN             BatteryPresent;
  BOOLEAN             Charging;
  BOOLEAN             Discharging;
  BOOLEAN             Spare1[4];
  DWORD               MaxCapacity;
  DWORD               RemainingCapacity;
  DWORD               Rate;
  DWORD               EstimatedTime;
  DWORD               DefaultAlert1;
  DWORD               DefaultAlert2;
};

// Image Format
#ifndef _MAC
#pragma pack(push,4)
#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
#define IMAGE_OS2_SIGNATURE                 0x454E      // NE
#define IMAGE_OS2_SIGNATURE_LE              0x454C      // LE
#define IMAGE_VXD_SIGNATURE                 0x454C      // LE
#define IMAGE_NT_SIGNATURE                  0x00004550  // PE00
#pragma pack(push,2)
#else
#pragma pack(push,1)
#define IMAGE_DOS_SIGNATURE                 0x4D5A      // MZ
#define IMAGE_OS2_SIGNATURE                 0x4E45      // NE
#define IMAGE_OS2_SIGNATURE_LE              0x4C45      // LE
#define IMAGE_NT_SIGNATURE                  0x50450000  // PE00
#endif

struct IMAGE_DOS_HEADER {      // DOS .EXE header
  WORD   e_magic;                     // Magic number
  WORD   e_cblp;                      // Bytes on last page of file
  WORD   e_cp;                        // Pages in file
  WORD   e_crlc;                      // Relocations
  WORD   e_cparhdr;                   // Size of header in paragraphs
  WORD   e_minalloc;                  // Minimum extra paragraphs needed
  WORD   e_maxalloc;                  // Maximum extra paragraphs needed
  WORD   e_ss;                        // Initial (relative) SS value
  WORD   e_sp;                        // Initial SP value
  WORD   e_csum;                      // Checksum
  WORD   e_ip;                        // Initial IP value
  WORD   e_cs;                        // Initial (relative) CS value
  WORD   e_lfarlc;                    // File address of relocation table
  WORD   e_ovno;                      // Overlay number
  WORD   e_res[4];                    // Reserved words
  WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
  WORD   e_oeminfo;                   // OEM information; e_oemid specific
  WORD   e_res2[10];                  // Reserved words
  LONG   e_lfanew;                    // File address of new exe header
};

struct IMAGE_OS2_HEADER {      // OS/2 .EXE header
  WORD   ne_magic;                    // Magic number
  CHAR   ne_ver;                      // Version number
  CHAR   ne_rev;                      // Revision number
  WORD   ne_enttab;                   // Offset of Entry Table
  WORD   ne_cbenttab;                 // Number of bytes in Entry Table
  LONG   ne_crc;                      // Checksum of whole file
  WORD   ne_flags;                    // Flag word
  WORD   ne_autodata;                 // Automatic data segment number
  WORD   ne_heap;                     // Initial heap allocation
  WORD   ne_stack;                    // Initial stack allocation
  LONG   ne_csip;                     // Initial CS:IP setting
  LONG   ne_sssp;                     // Initial SS:SP setting
  WORD   ne_cseg;                     // Count of file segments
  WORD   ne_cmod;                     // Entries in Module Reference Table
  WORD   ne_cbnrestab;                // Size of non-resident name table
  WORD   ne_segtab;                   // Offset of Segment Table
  WORD   ne_rsrctab;                  // Offset of Resource Table
  WORD   ne_restab;                   // Offset of resident name table
  WORD   ne_modtab;                   // Offset of Module Reference Table
  WORD   ne_imptab;                   // Offset of Imported Names Table
  LONG   ne_nrestab;                  // Offset of Non-resident Names Table
  WORD   ne_cmovent;                  // Count of movable entries
  WORD   ne_align;                    // Segment alignment shift count
  WORD   ne_cres;                     // Count of resource segments
  BYTE   ne_exetyp;                   // Target Operating system
  BYTE   ne_flagsothers;              // Other .EXE flags
  WORD   ne_pretthunks;               // offset to return thunks
  WORD   ne_psegrefbytes;             // offset to segment ref. bytes
  WORD   ne_swaparea;                 // Minimum code swap area size
  WORD   ne_expver;                   // Expected Windows version number
};

struct IMAGE_VXD_HEADER {      // Windows VXD header
  WORD   e32_magic;                   // Magic number
  BYTE   e32_border;                  // The byte ordering for the VXD
  BYTE   e32_worder;                  // The word ordering for the VXD
  DWORD  e32_level;                   // The EXE format level for now = 0
  WORD   e32_cpu;                     // The CPU type
  WORD   e32_os;                      // The OS type
  DWORD  e32_ver;                     // Module version
  DWORD  e32_mflags;                  // Module flags
  DWORD  e32_mpages;                  // Module # pages
  DWORD  e32_startobj;                // Object # for instruction pointer
  DWORD  e32_eip;                     // Extended instruction pointer
  DWORD  e32_stackobj;                // Object # for stack pointer
  DWORD  e32_esp;                     // Extended stack pointer
  DWORD  e32_pagesize;                // VXD page size
  DWORD  e32_lastpagesize;            // Last page size in VXD
  DWORD  e32_fixupsize;               // Fixup section size
  DWORD  e32_fixupsum;                // Fixup section checksum
  DWORD  e32_ldrsize;                 // Loader section size
  DWORD  e32_ldrsum;                  // Loader section checksum
  DWORD  e32_objtab;                  // Object table offset
  DWORD  e32_objcnt;                  // Number of objects in module
  DWORD  e32_objmap;                  // Object page map offset
  DWORD  e32_itermap;                 // Object iterated data map offset
  DWORD  e32_rsrctab;                 // Offset of Resource Table
  DWORD  e32_rsrccnt;                 // Number of resource entries
  DWORD  e32_restab;                  // Offset of resident name table
  DWORD  e32_enttab;                  // Offset of Entry Table
  DWORD  e32_dirtab;                  // Offset of Module Directive Table
  DWORD  e32_dircnt;                  // Number of module directives
  DWORD  e32_fpagetab;                // Offset of Fixup Page Table
  DWORD  e32_frectab;                 // Offset of Fixup Record Table
  DWORD  e32_impmod;                  // Offset of Import Module Name Table
  DWORD  e32_impmodcnt;               // Number of entries in Import Module Name Table
  DWORD  e32_impproc;                 // Offset of Import Procedure Name Table
  DWORD  e32_pagesum;                 // Offset of Per-Page Checksum Table
  DWORD  e32_datapage;                // Offset of Enumerated Data Pages
  DWORD  e32_preload;                 // Number of preload pages
  DWORD  e32_nrestab;                 // Offset of Non-resident Names Table
  DWORD  e32_cbnrestab;               // Size of Non-resident Name Table
  DWORD  e32_nressum;                 // Non-resident Name Table Checksum
  DWORD  e32_autodata;                // Object # for automatic data object
  DWORD  e32_debuginfo;               // Offset of the debugging information
  DWORD  e32_debuglen;                // The length of the debugging info. in bytes
  DWORD  e32_instpreload;             // Number of instance pages in preload section of VXD file
  DWORD  e32_instdemand;              // Number of instance pages in demand load section of VXD file
  DWORD  e32_heapsize;                // Size of heap - for 16-bit apps
  BYTE   e32_res3[12];                // Reserved words
  DWORD  e32_winresoff;
  DWORD  e32_winreslen;
  WORD   e32_devid;                   // Device ID for VxD
  WORD   e32_ddkver;                  // DDK version for VxD
};

#ifndef _MAC
#pragma pack(pop)                    // Back to 4 byte packing
#endif
// File header format.
struct IMAGE_FILE_HEADER {
  WORD    Machine;
  WORD    NumberOfSections;
  DWORD   TimeDateStamp;
  DWORD   PointerToSymbolTable;
  DWORD   NumberOfSymbols;
  WORD    SizeOfOptionalHeader;
  WORD    Characteristics;
};

#define IMAGE_SIZEOF_FILE_HEADER             20

#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable  (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Agressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM                    0x1000  // System File.
#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.

#define IMAGE_FILE_MACHINE_UNKNOWN           0
#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.
#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP            0x01a3
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2
#define IMAGE_FILE_MACHINE_AM33              0x01d3
#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon
#define IMAGE_FILE_MACHINE_CEF               0x0CEF
#define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE               0xC0EE

// Directory format.
struct IMAGE_DATA_DIRECTORY {
  DWORD   VirtualAddress;
  DWORD   Size;
};

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

// Optional header format.
struct IMAGE_OPTIONAL_HEADER32{
  // Standard fields.
  WORD    Magic;
  BYTE    MajorLinkerVersion;
  BYTE    MinorLinkerVersion;
  DWORD   SizeOfCode;
  DWORD   SizeOfInitializedData;
  DWORD   SizeOfUninitializedData;
  DWORD   AddressOfEntryPoint;
  DWORD   BaseOfCode;
  DWORD   BaseOfData;
  // NT additional fields.
  DWORD   ImageBase;
  DWORD   SectionAlignment;
  DWORD   FileAlignment;
  WORD    MajorOperatingSystemVersion;
  WORD    MinorOperatingSystemVersion;
  WORD    MajorImageVersion;
  WORD    MinorImageVersion;
  WORD    MajorSubsystemVersion;
  WORD    MinorSubsystemVersion;
  DWORD   Win32VersionValue;
  DWORD   SizeOfImage;
  DWORD   SizeOfHeaders;
  DWORD   CheckSum;
  WORD    Subsystem;
  WORD    DllCharacteristics;
  DWORD   SizeOfStackReserve;
  DWORD   SizeOfStackCommit;
  DWORD   SizeOfHeapReserve;
  DWORD   SizeOfHeapCommit;
  DWORD   LoaderFlags;
  DWORD   NumberOfRvaAndSizes;
  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
};

struct IMAGE_ROM_OPTIONAL_HEADER {
  WORD   Magic;
  BYTE   MajorLinkerVersion;
  BYTE   MinorLinkerVersion;
  DWORD  SizeOfCode;
  DWORD  SizeOfInitializedData;
  DWORD  SizeOfUninitializedData;
  DWORD  AddressOfEntryPoint;
  DWORD  BaseOfCode;
  DWORD  BaseOfData;
  DWORD  BaseOfBss;
  DWORD  GprMask;
  DWORD  CprMask[4];
  DWORD  GpValue;
};

struct IMAGE_OPTIONAL_HEADER64 {
  WORD        Magic;
  BYTE        MajorLinkerVersion;
  BYTE        MinorLinkerVersion;
  DWORD       SizeOfCode;
  DWORD       SizeOfInitializedData;
  DWORD       SizeOfUninitializedData;
  DWORD       AddressOfEntryPoint;
  DWORD       BaseOfCode;
  ULONGLONG   ImageBase;
  DWORD       SectionAlignment;
  DWORD       FileAlignment;
  WORD        MajorOperatingSystemVersion;
  WORD        MinorOperatingSystemVersion;
  WORD        MajorImageVersion;
  WORD        MinorImageVersion;
  WORD        MajorSubsystemVersion;
  WORD        MinorSubsystemVersion;
  DWORD       Win32VersionValue;
  DWORD       SizeOfImage;
  DWORD       SizeOfHeaders;
  DWORD       CheckSum;
  WORD        Subsystem;
  WORD        DllCharacteristics;
  ULONGLONG   SizeOfStackReserve;
  ULONGLONG   SizeOfStackCommit;
  ULONGLONG   SizeOfHeapReserve;
  ULONGLONG   SizeOfHeapCommit;
  DWORD       LoaderFlags;
  DWORD       NumberOfRvaAndSizes;
  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
};

#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER      56
#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER      28
#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER    224
#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER    240

#define IMAGE_NT_OPTIONAL_HDR32_MAGIC      0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC       0x107

#define IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER32
#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER     IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
#define IMAGE_NT_OPTIONAL_HDR_MAGIC         IMAGE_NT_OPTIONAL_HDR32_MAGIC
/*
struct IMAGE_NT_HEADERS64 {
  DWORD Signature;
  IMAGE_FILE_HEADER FileHeader;
  IMAGE_OPTIONAL_HEADER64 OptionalHeader;
};*/

struct IMAGE_NT_HEADERS {
  DWORD Signature;
  IMAGE_FILE_HEADER FileHeader;
  IMAGE_OPTIONAL_HEADER32 OptionalHeader;
};

struct IMAGE_ROM_HEADERS {
  IMAGE_FILE_HEADER FileHeader;
  IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
};

#define IMAGE_NT_HEADERS IMAGE_NT_HEADERS32

// Subsystem Values
#define IMAGE_SUBSYSTEM_UNKNOWN              0   // Unknown subsystem.
#define IMAGE_SUBSYSTEM_NATIVE               1   // Image doesn't require a subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_GUI          2   // Image runs in the Windows GUI subsystem.
#define IMAGE_SUBSYSTEM_WINDOWS_CUI          3   // Image runs in the Windows character subsystem.
#define IMAGE_SUBSYSTEM_OS2_CUI              5   // image runs in the OS/2 character subsystem.
#define IMAGE_SUBSYSTEM_POSIX_CUI            7   // image runs in the Posix character subsystem.
#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS       8   // image is a native Win9x driver.
#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI       9   // Image runs in the Windows CE subsystem.
#define IMAGE_SUBSYSTEM_EFI_APPLICATION      10  //
#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER  11   //
#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER   12  //
#define IMAGE_SUBSYSTEM_EFI_ROM              13
#define IMAGE_SUBSYSTEM_XBOX                 14

// DllCharacteristics Entries
//      IMAGE_LIBRARY_PROCESS_INIT           0x0001     // Reserved.
//      IMAGE_LIBRARY_PROCESS_TERM           0x0002     // Reserved.
//      IMAGE_LIBRARY_THREAD_INIT            0x0004     // Reserved.
//      IMAGE_LIBRARY_THREAD_TERM            0x0008     // Reserved.
#define IMAGE_DLLCHARACTERISTICS_NO_BIND     0x0800     // Do not bind this image.
//                                           0x1000     // Reserved.
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER  0x2000     // Driver uses WDM model
//                                           0x4000     // Reserved.
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE     0x8000

// Directory Entries
#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
//      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS             9   // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   // COM Runtime descriptor

// Non-COFF Object file header
struct ANON_OBJECT_HEADER {
  WORD    Sig1;            // Must be IMAGE_FILE_MACHINE_UNKNOWN
  WORD    Sig2;            // Must be 0xffff
  WORD    Version;         // >= 1 (implies the CLSID field is present)
  WORD    Machine;
  DWORD   TimeDateStamp;
  CLSID   ClassID;         // Used to invoke CoCreateInstance
  DWORD   SizeOfData;      // Size of data that follows the header
};

// Section header format.
#define IMAGE_SIZEOF_SHORT_NAME              8

struct IMAGE_SECTION_HEADER {
  BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
  union {
    DWORD   PhysicalAddress;
    DWORD   VirtualSize;
  }Misc;
  DWORD   VirtualAddress;
  DWORD   SizeOfRawData;
  DWORD   PointerToRawData;
  DWORD   PointerToRelocations;
  DWORD   PointerToLinenumbers;
  WORD    NumberOfRelocations;
  WORD    NumberOfLinenumbers;
  DWORD   Characteristics;
};

#define IMAGE_SIZEOF_SECTION_HEADER          40

// Section characteristics.
//      IMAGE_SCN_TYPE_REG                   0x00000000  // Reserved.
//      IMAGE_SCN_TYPE_DSECT                 0x00000001  // Reserved.
//      IMAGE_SCN_TYPE_NOLOAD                0x00000002  // Reserved.
//      IMAGE_SCN_TYPE_GROUP                 0x00000004  // Reserved.
#define IMAGE_SCN_TYPE_NO_PAD                0x00000008  // Reserved.
//      IMAGE_SCN_TYPE_COPY                  0x00000010  // Reserved.
#define IMAGE_SCN_CNT_CODE                   0x00000020  // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA       0x00000040  // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA     0x00000080  // Section contains uninitialized data.
#define IMAGE_SCN_LNK_OTHER                  0x00000100  // Reserved.
#define IMAGE_SCN_LNK_INFO                   0x00000200  // Section contains comments or some other type of information.
//      IMAGE_SCN_TYPE_OVER                  0x00000400  // Reserved.
#define IMAGE_SCN_LNK_REMOVE                 0x00000800  // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT                 0x00001000  // Section contents comdat.
//                                           0x00002000  // Reserved.
//      IMAGE_SCN_MEM_PROTECTED - Obsolete   0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC          0x00004000  // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL                      0x00008000  // Section content can be accessed relative to GP
#define IMAGE_SCN_MEM_FARDATA                0x00008000
//      IMAGE_SCN_MEM_SYSHEAP  - Obsolete    0x00010000
#define IMAGE_SCN_MEM_PURGEABLE              0x00020000
#define IMAGE_SCN_MEM_16BIT                  0x00020000
#define IMAGE_SCN_MEM_LOCKED                 0x00040000
#define IMAGE_SCN_MEM_PRELOAD                0x00080000
#define IMAGE_SCN_ALIGN_1BYTES               0x00100000  //
#define IMAGE_SCN_ALIGN_2BYTES               0x00200000  //
#define IMAGE_SCN_ALIGN_4BYTES               0x00300000  //
#define IMAGE_SCN_ALIGN_8BYTES               0x00400000  //
#define IMAGE_SCN_ALIGN_16BYTES              0x00500000  // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES              0x00600000  //
#define IMAGE_SCN_ALIGN_64BYTES              0x00700000  //
#define IMAGE_SCN_ALIGN_128BYTES             0x00800000  //
#define IMAGE_SCN_ALIGN_256BYTES             0x00900000  //
#define IMAGE_SCN_ALIGN_512BYTES             0x00A00000  //
#define IMAGE_SCN_ALIGN_1024BYTES            0x00B00000  //
#define IMAGE_SCN_ALIGN_2048BYTES            0x00C00000  //
#define IMAGE_SCN_ALIGN_4096BYTES            0x00D00000  //
#define IMAGE_SCN_ALIGN_8192BYTES            0x00E00000  //
// Unused                                    0x00F00000
#define IMAGE_SCN_ALIGN_MASK                 0x00F00000
#define IMAGE_SCN_LNK_NRELOC_OVFL            0x01000000  // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE            0x02000000  // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED             0x04000000  // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED              0x08000000  // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED                 0x10000000  // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE                0x20000000  // Section is executable.
#define IMAGE_SCN_MEM_READ                   0x40000000  // Section is readable.
#define IMAGE_SCN_MEM_WRITE                  0x80000000  // Section is writeable.

// TLS Chaacteristic Flags
#define IMAGE_SCN_SCALE_INDEX                0x00000001  // Tls index is scaled

#ifndef _MAC
#pragma pack(push,2)  // Symbols, relocs, and linenumbers are 2 byte packed
#endif
// Symbol format.
struct IMAGE_SYMBOL {
  union {
    BYTE    ShortName[8];
    struct {
      DWORD   Short;     // if 0, use LongName
      DWORD   Long;      // offset into string table
    } Name;
    DWORD   LongName[2];    // PBYTE [2]
  }N;
  DWORD   Value;
  SHORT   SectionNumber;
  WORD    Type;
  BYTE    StorageClass;
  BYTE    NumberOfAuxSymbols;
};

#define IMAGE_SIZEOF_SYMBOL                  18

// Section values.
// Symbols have a section number of the section in which they are
// defined. Otherwise, section numbers have the following meanings:
#define IMAGE_SYM_UNDEFINED           0          // Symbol is undefined or is common.
#define IMAGE_SYM_ABSOLUTE            -1         // Symbol is an absolute value.
#define IMAGE_SYM_DEBUG               -2         // Symbol is a special debug item.
#define IMAGE_SYM_SECTION_MAX         0xFEFF            // Values 0xFF00-0xFFFF are special

// Type (fundamental) values.
#define IMAGE_SYM_TYPE_NULL                 0x0000  // no type.
#define IMAGE_SYM_TYPE_VOID                 0x0001  //
#define IMAGE_SYM_TYPE_CHAR                 0x0002  // type character.
#define IMAGE_SYM_TYPE_SHORT                0x0003  // type short integer.
#define IMAGE_SYM_TYPE_INT                  0x0004  //
#define IMAGE_SYM_TYPE_LONG                 0x0005  //
#define IMAGE_SYM_TYPE_FLOAT                0x0006  //
#define IMAGE_SYM_TYPE_DOUBLE               0x0007  //
#define IMAGE_SYM_TYPE_STRUCT               0x0008  //
#define IMAGE_SYM_TYPE_UNION                0x0009  //
#define IMAGE_SYM_TYPE_ENUM                 0x000A  // enumeration.
#define IMAGE_SYM_TYPE_MOE                  0x000B  // member of enumeration.
#define IMAGE_SYM_TYPE_BYTE                 0x000C  //
#define IMAGE_SYM_TYPE_WORD                 0x000D  //
#define IMAGE_SYM_TYPE_UINT                 0x000E  //
#define IMAGE_SYM_TYPE_DWORD                0x000F  //
#define IMAGE_SYM_TYPE_PCODE                0x8000  //
// Type (derived) values.
#define IMAGE_SYM_DTYPE_NULL                0       // no derived type.
#define IMAGE_SYM_DTYPE_POINTER             1       // pointer.
#define IMAGE_SYM_DTYPE_FUNCTION            2       // function.
#define IMAGE_SYM_DTYPE_ARRAY               3       // array.
// Storage classes.
#define IMAGE_SYM_CLASS_END_OF_FUNCTION     -1
#define IMAGE_SYM_CLASS_NULL                0x0000
#define IMAGE_SYM_CLASS_AUTOMATIC           0x0001
#define IMAGE_SYM_CLASS_EXTERNAL            0x0002
#define IMAGE_SYM_CLASS_STATIC              0x0003
#define IMAGE_SYM_CLASS_REGISTER            0x0004
#define IMAGE_SYM_CLASS_EXTERNAL_DEF        0x0005
#define IMAGE_SYM_CLASS_LABEL               0x0006
#define IMAGE_SYM_CLASS_UNDEFINED_LABEL     0x0007
#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT    0x0008
#define IMAGE_SYM_CLASS_ARGUMENT            0x0009
#define IMAGE_SYM_CLASS_STRUCT_TAG          0x000A
#define IMAGE_SYM_CLASS_MEMBER_OF_UNION     0x000B
#define IMAGE_SYM_CLASS_UNION_TAG           0x000C
#define IMAGE_SYM_CLASS_TYPE_DEFINITION     0x000D
#define IMAGE_SYM_CLASS_UNDEFINED_STATIC    0x000E
#define IMAGE_SYM_CLASS_ENUM_TAG            0x000F
#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM      0x0010
#define IMAGE_SYM_CLASS_REGISTER_PARAM      0x0011
#define IMAGE_SYM_CLASS_BIT_FIELD           0x0012
#define IMAGE_SYM_CLASS_FAR_EXTERNAL        0x0044  //
#define IMAGE_SYM_CLASS_BLOCK               0x0064
#define IMAGE_SYM_CLASS_FUNCTION            0x0065
#define IMAGE_SYM_CLASS_END_OF_STRUCT       0x0066
#define IMAGE_SYM_CLASS_FILE                0x0067
// new
#define IMAGE_SYM_CLASS_SECTION             0x0068
#define IMAGE_SYM_CLASS_WEAK_EXTERNAL       0x0069
#define IMAGE_SYM_CLASS_CLR_TOKEN           0x006B

// type packing constants
#define N_BTMASK                            0x000F
#define N_TMASK                             0x0030
#define N_TMASK1                            0x00C0
#define N_TMASK2                            0x00F0
#define N_BTSHFT                            4
#define N_TSHIFT                            2
// MACROS

// Basic Type of  x
#define BTYPE(x) x&N_BTMASK

// Is x a pointer?
#ifndef ISPTR
#define ISPTR(x) x&N_TMASK == IMAGE_SYM_DTYPE_POINTER << N_BTSHFT
#endif

// Is x a function?
#ifndef ISFCN
#define ISFCN(x) x&N_TMASK == IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT
#endif

// Is x an array?
#ifndef ISARY
#define ISARY(x) x&N_TMASK == IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT
#endif

// Is x a structure, union, or enumeration TAG?
#ifndef ISTAG
#define ISTAG(x) (x==IMAGE_SYM_CLASS_STRUCT_TAG)||(x==IMAGE_SYM_CLASS_UNION_TAG)||(x==IMAGE_SYM_CLASS_ENUM_TAG)
#endif

// Auxiliary entry format.
union IMAGE_AUX_SYMBOL{
  struct {
    DWORD    TagIndex;                      // struct, union, or enum tag index
    union {
      struct {
        WORD    Linenumber;             // declaration line number
        WORD    Size;                   // size of struct, union, or enum
      } LnSz;
     DWORD    TotalSize;
    } Misc;
    union {
      struct {                            // if ISFCN, tag, or .bb
        DWORD    PointerToLinenumber;
        DWORD    PointerToNextFunction;
      } Function;
      struct {                            // if ISARY, up to 4 dimen.
        WORD     Dimension[4];
      } Array;
    } FcnAry;
    WORD    TvIndex;                        // tv index
  } Sym;
  struct {
    BYTE    Name[IMAGE_SIZEOF_SYMBOL];
  } File;
  struct {
    DWORD   Length;                         // section length
    WORD    NumberOfRelocations;            // number of relocation entries
    WORD    NumberOfLinenumbers;            // number of line numbers
    DWORD   CheckSum;                       // checksum for communal
    SHORT   Number;                         // section number to associate with
    BYTE    Selection;                      // communal selection type
  } Section;
};

#define IMAGE_SIZEOF_AUX_SYMBOL             18

enum IMAGE_AUX_SYMBOL_TYPE{
  IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1,
};

#pragma pack(push,2)
struct IMAGE_AUX_SYMBOL_TOKEN_DEF {
  BYTE  bAuxType;                  // IMAGE_AUX_SYMBOL_TYPE
  BYTE  bReserved;                 // Must be 0
  DWORD SymbolTableIndex;
  BYTE  rgbReserved[12];           // Must be 0
};
#pragma pack(pop)

// Communal selection types.
#define IMAGE_COMDAT_SELECT_NODUPLICATES    1
#define IMAGE_COMDAT_SELECT_ANY             2
#define IMAGE_COMDAT_SELECT_SAME_SIZE       3
#define IMAGE_COMDAT_SELECT_EXACT_MATCH     4
#define IMAGE_COMDAT_SELECT_ASSOCIATIVE     5
#define IMAGE_COMDAT_SELECT_LARGEST         6
#define IMAGE_COMDAT_SELECT_NEWEST          7
#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY  1
#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY    2
#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS      3

// Relocation format.
struct IMAGE_RELOCATION {
  union {
    DWORD   VirtualAddress;
    DWORD   RelocCount;             // Set to the real count when IMAGE_SCN_LNK_NRELOC_OVFL is set
  };
  DWORD   SymbolTableIndex;
  WORD    Type;
};

#define IMAGE_SIZEOF_RELOCATION         10

// I386 relocation types.
#define IMAGE_REL_I386_ABSOLUTE         0x0000  // Reference is absolute, no relocation is necessary
#define IMAGE_REL_I386_DIR16            0x0001  // Direct 16-bit reference to the symbols virtual address
#define IMAGE_REL_I386_REL16            0x0002  // PC-relative 16-bit reference to the symbols virtual address
#define IMAGE_REL_I386_DIR32            0x0006  // Direct 32-bit reference to the symbols virtual address
#define IMAGE_REL_I386_DIR32NB          0x0007  // Direct 32-bit reference to the symbols virtual address, base not included
#define IMAGE_REL_I386_SEG12            0x0009  // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
#define IMAGE_REL_I386_SECTION          0x000A
#define IMAGE_REL_I386_SECREL           0x000B
#define IMAGE_REL_I386_TOKEN            0x000C  // clr token
#define IMAGE_REL_I386_SECREL7          0x000D  // 7 bit offset from base of section containing target
#define IMAGE_REL_I386_REL32            0x0014  // PC-relative 32-bit reference to the symbols virtual address

// MIPS relocation types.
#define IMAGE_REL_MIPS_ABSOLUTE         0x0000  // Reference is absolute, no relocation is necessary
#define IMAGE_REL_MIPS_REFHALF          0x0001
#define IMAGE_REL_MIPS_REFWORD          0x0002
#define IMAGE_REL_MIPS_JMPADDR          0x0003
#define IMAGE_REL_MIPS_REFHI            0x0004
#define IMAGE_REL_MIPS_REFLO            0x0005
#define IMAGE_REL_MIPS_GPREL            0x0006
#define IMAGE_REL_MIPS_LITERAL          0x0007
#define IMAGE_REL_MIPS_SECTION          0x000A
#define IMAGE_REL_MIPS_SECREL           0x000B
#define IMAGE_REL_MIPS_SECRELLO         0x000C  // Low 16-bit section relative referemce (used for >32k TLS)
#define IMAGE_REL_MIPS_SECRELHI         0x000D  // High 16-bit section relative reference (used for >32k TLS)
#define IMAGE_REL_MIPS_TOKEN            0x000E  // clr token
#define IMAGE_REL_MIPS_JMPADDR16        0x0010
#define IMAGE_REL_MIPS_REFWORDNB        0x0022
#define IMAGE_REL_MIPS_PAIR             0x0025

// Alpha Relocation types.
#define IMAGE_REL_ALPHA_ABSOLUTE        0x0000
#define IMAGE_REL_ALPHA_REFLONG         0x0001
#define IMAGE_REL_ALPHA_REFQUAD         0x0002
#define IMAGE_REL_ALPHA_GPREL32         0x0003
#define IMAGE_REL_ALPHA_LITERAL         0x0004
#define IMAGE_REL_ALPHA_LITUSE          0x0005
#define IMAGE_REL_ALPHA_GPDISP          0x0006
#define IMAGE_REL_ALPHA_BRADDR          0x0007
#define IMAGE_REL_ALPHA_HINT            0x0008
#define IMAGE_REL_ALPHA_INLINE_REFLONG  0x0009
#define IMAGE_REL_ALPHA_REFHI           0x000A
#define IMAGE_REL_ALPHA_REFLO           0x000B
#define IMAGE_REL_ALPHA_PAIR            0x000C
#define IMAGE_REL_ALPHA_MATCH           0x000D
#define IMAGE_REL_ALPHA_SECTION         0x000E
#define IMAGE_REL_ALPHA_SECREL          0x000F
#define IMAGE_REL_ALPHA_REFLONGNB       0x0010
#define IMAGE_REL_ALPHA_SECRELLO        0x0011  // Low 16-bit section relative reference
#define IMAGE_REL_ALPHA_SECRELHI        0x0012  // High 16-bit section relative reference
#define IMAGE_REL_ALPHA_REFQ3           0x0013  // High 16 bits of 48 bit reference
#define IMAGE_REL_ALPHA_REFQ2           0x0014  // Middle 16 bits of 48 bit reference
#define IMAGE_REL_ALPHA_REFQ1           0x0015  // Low 16 bits of 48 bit reference
#define IMAGE_REL_ALPHA_GPRELLO         0x0016  // Low 16-bit GP relative reference
#define IMAGE_REL_ALPHA_GPRELHI         0x0017  // High 16-bit GP relative reference

// IBM PowerPC relocation types.
#define IMAGE_REL_PPC_ABSOLUTE          0x0000  // NOP
#define IMAGE_REL_PPC_ADDR64            0x0001  // 64-bit address
#define IMAGE_REL_PPC_ADDR32            0x0002  // 32-bit address
#define IMAGE_REL_PPC_ADDR24            0x0003  // 26-bit address, shifted left 2 (branch absolute)
#define IMAGE_REL_PPC_ADDR16            0x0004  // 16-bit address
#define IMAGE_REL_PPC_ADDR14            0x0005  // 16-bit address, shifted left 2 (load doubleword)
#define IMAGE_REL_PPC_REL24             0x0006  // 26-bit PC-relative offset, shifted left 2 (branch relative)
#define IMAGE_REL_PPC_REL14             0x0007  // 16-bit PC-relative offset, shifted left 2 (br cond relative)
#define IMAGE_REL_PPC_TOCREL16          0x0008  // 16-bit offset from TOC base
#define IMAGE_REL_PPC_TOCREL14          0x0009  // 16-bit offset from TOC base, shifted left 2 (load doubleword)
#define IMAGE_REL_PPC_ADDR32NB          0x000A  // 32-bit addr w/o image base
#define IMAGE_REL_PPC_SECREL            0x000B  // va of containing section (as in an image sectionhdr)
#define IMAGE_REL_PPC_SECTION           0x000C  // sectionheader number
#define IMAGE_REL_PPC_IFGLUE            0x000D  // substitute TOC restore instruction iff symbol is glue code
#define IMAGE_REL_PPC_IMGLUE            0x000E  // symbol is glue code; virtual address is TOC restore instruction
#define IMAGE_REL_PPC_SECREL16          0x000F  // va of containing section (limited to 16 bits)
#define IMAGE_REL_PPC_REFHI             0x0010
#define IMAGE_REL_PPC_REFLO             0x0011
#define IMAGE_REL_PPC_PAIR              0x0012
#define IMAGE_REL_PPC_SECRELLO          0x0013  // Low 16-bit section relative reference (used for >32k TLS)
#define IMAGE_REL_PPC_SECRELHI          0x0014  // High 16-bit section relative reference (used for >32k TLS)
#define IMAGE_REL_PPC_GPREL             0x0015
#define IMAGE_REL_PPC_TOKEN             0x0016  // clr token
#define IMAGE_REL_PPC_TYPEMASK          0x00FF  // mask to isolate above values in IMAGE_RELOCATION.Type

// Flag bits in IMAGE_RELOCATION.TYPE
#define IMAGE_REL_PPC_NEG               0x0100  // subtract reloc value rather than adding it
#define IMAGE_REL_PPC_BRTAKEN           0x0200  // fix branch prediction bit to predict branch taken
#define IMAGE_REL_PPC_BRNTAKEN          0x0400  // fix branch prediction bit to predict branch not taken
#define IMAGE_REL_PPC_TOCDEFN           0x0800  // toc slot defined in file (or, data in toc)

// Hitachi SH3 relocation types.
#define IMAGE_REL_SH3_ABSOLUTE          0x0000  // No relocation
#define IMAGE_REL_SH3_DIRECT16          0x0001  // 16 bit direct
#define IMAGE_REL_SH3_DIRECT32          0x0002  // 32 bit direct
#define IMAGE_REL_SH3_DIRECT8           0x0003  // 8 bit direct, -128..255
#define IMAGE_REL_SH3_DIRECT8_WORD      0x0004  // 8 bit direct .W (0 ext.)
#define IMAGE_REL_SH3_DIRECT8_LONG      0x0005  // 8 bit direct .L (0 ext.)
#define IMAGE_REL_SH3_DIRECT4           0x0006  // 4 bit direct (0 ext.)
#define IMAGE_REL_SH3_DIRECT4_WORD      0x0007  // 4 bit direct .W (0 ext.)
#define IMAGE_REL_SH3_DIRECT4_LONG      0x0008  // 4 bit direct .L (0 ext.)
#define IMAGE_REL_SH3_PCREL8_WORD       0x0009  // 8 bit PC relative .W
#define IMAGE_REL_SH3_PCREL8_LONG       0x000A  // 8 bit PC relative .L
#define IMAGE_REL_SH3_PCREL12_WORD      0x000B  // 12 LSB PC relative .W
#define IMAGE_REL_SH3_STARTOF_SECTION   0x000C  // Start of EXE section
#define IMAGE_REL_SH3_SIZEOF_SECTION    0x000D  // Size of EXE section
#define IMAGE_REL_SH3_SECTION           0x000E  // Section table index
#define IMAGE_REL_SH3_SECREL            0x000F  // Offset within section
#define IMAGE_REL_SH3_DIRECT32_NB       0x0010  // 32 bit direct not based
#define IMAGE_REL_SH3_GPREL4_LONG       0x0011  // GP-relative addressing
#define IMAGE_REL_SH3_TOKEN             0x0012  // clr token
#define IMAGE_REL_ARM_ABSOLUTE          0x0000  // No relocation required
#define IMAGE_REL_ARM_ADDR32            0x0001  // 32 bit address
#define IMAGE_REL_ARM_ADDR32NB          0x0002  // 32 bit address w/o image base
#define IMAGE_REL_ARM_BRANCH24          0x0003  // 24 bit offset << 2 & sign ext.
#define IMAGE_REL_ARM_BRANCH11          0x0004  // Thumb: 2 11 bit offsets
#define IMAGE_REL_ARM_TOKEN             0x0005  // clr token
#define IMAGE_REL_ARM_GPREL12           0x0006  // GP-relative addressing (ARM)
#define IMAGE_REL_ARM_GPREL7            0x0007  // GP-relative addressing (Thumb)
#define IMAGE_REL_ARM_BLX24             0x0008
#define IMAGE_REL_ARM_BLX11             0x0009
#define IMAGE_REL_ARM_SECTION           0x000E  // Section table index
#define IMAGE_REL_ARM_SECREL            0x000F  // Offset within section
#define IMAGE_REL_AM_ABSOLUTE           0x0000
#define IMAGE_REL_AM_ADDR32             0x0001
#define IMAGE_REL_AM_ADDR32NB           0x0002
#define IMAGE_REL_AM_CALL32             0x0003
#define IMAGE_REL_AM_FUNCINFO           0x0004
#define IMAGE_REL_AM_REL32_1            0x0005
#define IMAGE_REL_AM_REL32_2            0x0006
#define IMAGE_REL_AM_SECREL             0x0007
#define IMAGE_REL_AM_SECTION            0x0008
#define IMAGE_REL_AM_TOKEN              0x0009

// X86-64 relocations
#define IMAGE_REL_AMD64_ABSOLUTE        0x0000  // Reference is absolute, no relocation is necessary
#define IMAGE_REL_AMD64_ADDR64          0x0001  // 64-bit address (VA).
#define IMAGE_REL_AMD64_ADDR32          0x0002  // 32-bit address (VA).
#define IMAGE_REL_AMD64_ADDR32NB        0x0003  // 32-bit address w/o image base (RVA).
#define IMAGE_REL_AMD64_REL32           0x0004  // 32-bit relative address from byte following reloc
#define IMAGE_REL_AMD64_REL32_1         0x0005  // 32-bit relative address from byte distance 1 from reloc
#define IMAGE_REL_AMD64_REL32_2         0x0006  // 32-bit relative address from byte distance 2 from reloc
#define IMAGE_REL_AMD64_REL32_3         0x0007  // 32-bit relative address from byte distance 3 from reloc
#define IMAGE_REL_AMD64_REL32_4         0x0008  // 32-bit relative address from byte distance 4 from reloc
#define IMAGE_REL_AMD64_REL32_5         0x0009  // 32-bit relative address from byte distance 5 from reloc
#define IMAGE_REL_AMD64_SECTION         0x000A  // Section index
#define IMAGE_REL_AMD64_SECREL          0x000B  // 32 bit offset from base of section containing target
#define IMAGE_REL_AMD64_SECREL7         0x000C  // 7 bit unsigned offset from base of section containing target
#define IMAGE_REL_AMD64_TOKEN           0x000D  // 32 bit metadata token

// IA64 relocation types.
#define IMAGE_REL_IA64_ABSOLUTE         0x0000
#define IMAGE_REL_IA64_IMM14            0x0001
#define IMAGE_REL_IA64_IMM22            0x0002
#define IMAGE_REL_IA64_IMM64            0x0003
#define IMAGE_REL_IA64_DIR32            0x0004
#define IMAGE_REL_IA64_DIR64            0x0005
#define IMAGE_REL_IA64_PCREL21B         0x0006
#define IMAGE_REL_IA64_PCREL21M         0x0007
#define IMAGE_REL_IA64_PCREL21F         0x0008
#define IMAGE_REL_IA64_GPREL22          0x0009
#define IMAGE_REL_IA64_LTOFF22          0x000A
#define IMAGE_REL_IA64_SECTION          0x000B
#define IMAGE_REL_IA64_SECREL22         0x000C
#define IMAGE_REL_IA64_SECREL64I        0x000D
#define IMAGE_REL_IA64_SECREL32         0x000E
#define IMAGE_REL_IA64_DIR32NB          0x0010
#define IMAGE_REL_IA64_SREL14           0x0011
#define IMAGE_REL_IA64_SREL22           0x0012
#define IMAGE_REL_IA64_SREL32           0x0013
#define IMAGE_REL_IA64_UREL32           0x0014
#define IMAGE_REL_IA64_PCREL60X         0x0015  // This is always a BRL and never converted
#define IMAGE_REL_IA64_PCREL60B         0x0016  // If possible, convert to MBB bundle with NOP.B in slot 1
#define IMAGE_REL_IA64_PCREL60F         0x0017  // If possible, convert to MFB bundle with NOP.F in slot 1
#define IMAGE_REL_IA64_PCREL60I         0x0018  // If possible, convert to MIB bundle with NOP.I in slot 1
#define IMAGE_REL_IA64_PCREL60M         0x0019  // If possible, convert to MMB bundle with NOP.M in slot 1
#define IMAGE_REL_IA64_IMMGPREL64       0x001A
#define IMAGE_REL_IA64_TOKEN            0x001B  // clr token
#define IMAGE_REL_IA64_GPREL32          0x001C
#define IMAGE_REL_IA64_ADDEND           0x001F

// CEF relocation types.
#define IMAGE_REL_CEF_ABSOLUTE          0x0000  // Reference is absolute, no relocation is necessary
#define IMAGE_REL_CEF_ADDR32            0x0001  // 32-bit address (VA).
#define IMAGE_REL_CEF_ADDR64            0x0002  // 64-bit address (VA).
#define IMAGE_REL_CEF_ADDR32NB          0x0003  // 32-bit address w/o image base (RVA).
#define IMAGE_REL_CEF_SECTION           0x0004  // Section index
#define IMAGE_REL_CEF_SECREL            0x0005  // 32 bit offset from base of section containing target
#define IMAGE_REL_CEF_TOKEN             0x0006  // 32 bit metadata token

// clr relocation types.
#define IMAGE_REL_CEE_ABSOLUTE          0x0000  // Reference is absolute, no relocation is necessary
#define IMAGE_REL_CEE_ADDR32            0x0001  // 32-bit address (VA).
#define IMAGE_REL_CEE_ADDR64            0x0002  // 64-bit address (VA).
#define IMAGE_REL_CEE_ADDR32NB          0x0003  // 32-bit address w/o image base (RVA).
#define IMAGE_REL_CEE_SECTION           0x0004  // Section index
#define IMAGE_REL_CEE_SECREL            0x0005  // 32 bit offset from base of section containing target
#define IMAGE_REL_CEE_TOKEN             0x0006  // 32 bit metadata token

#define IMAGE_REL_M32R_ABSOLUTE       0x0000   // No relocation required
#define IMAGE_REL_M32R_ADDR32         0x0001   // 32 bit address
#define IMAGE_REL_M32R_ADDR32NB       0x0002   // 32 bit address w/o image base
#define IMAGE_REL_M32R_ADDR24         0x0003   // 24 bit address
#define IMAGE_REL_M32R_GPREL16        0x0004   // GP relative addressing
#define IMAGE_REL_M32R_PCREL24        0x0005   // 24 bit offset << 2 & sign ext.
#define IMAGE_REL_M32R_PCREL16        0x0006   // 16 bit offset << 2 & sign ext.
#define IMAGE_REL_M32R_PCREL8         0x0007   // 8 bit offset << 2 & sign ext.
#define IMAGE_REL_M32R_REFHALF        0x0008   // 16 MSBs
#define IMAGE_REL_M32R_REFHI          0x0009   // 16 MSBs; adj for LSB sign ext.
#define IMAGE_REL_M32R_REFLO          0x000A   // 16 LSBs
#define IMAGE_REL_M32R_PAIR           0x000B   // Link HI and LO
#define IMAGE_REL_M32R_SECTION        0x000C   // Section table index
#define IMAGE_REL_M32R_SECREL32       0x000D   // 32 bit section relative reference
#define IMAGE_REL_M32R_TOKEN          0x000E   // clr token
#define EMARCH_ENC_I17_IMM7B_INST_WORD_X         3  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM7B_SIZE_X              7  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X     4  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM7B_VAL_POS_X           0  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM9D_INST_WORD_X         3  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM9D_SIZE_X              9  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X     18  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM9D_VAL_POS_X           7  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM5C_INST_WORD_X         3  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM5C_SIZE_X              5  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X     13  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM5C_VAL_POS_X           16  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IC_INST_WORD_X            3  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IC_SIZE_X                 1  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IC_INST_WORD_POS_X        12  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IC_VAL_POS_X              21  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41a_INST_WORD_X        1  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41a_SIZE_X             10  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X    14  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41a_VAL_POS_X          22  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41b_INST_WORD_X        1  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41b_SIZE_X             8  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X    24  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41b_VAL_POS_X          32  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41c_INST_WORD_X        2  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41c_SIZE_X             23  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X    0  // Intel-IA64-Filler
#define EMARCH_ENC_I17_IMM41c_VAL_POS_X          40  // Intel-IA64-Filler
#define EMARCH_ENC_I17_SIGN_INST_WORD_X          3  // Intel-IA64-Filler
#define EMARCH_ENC_I17_SIGN_SIZE_X               1  // Intel-IA64-Filler
#define EMARCH_ENC_I17_SIGN_INST_WORD_POS_X      27  // Intel-IA64-Filler
#define EMARCH_ENC_I17_SIGN_VAL_POS_X            63  // Intel-IA64-Filler

// Line number format.
struct IMAGE_LINENUMBER {
  union {
    DWORD   SymbolTableIndex;               // Symbol table index of function name if Linenumber is 0.
    DWORD   VirtualAddress;                 // Virtual address of line number.
  }Type;
  WORD    Linenumber;                         // Line number.
};

#define IMAGE_SIZEOF_LINENUMBER              6

#ifndef _MAC
#pragma pack(pop)                        // Back to 4 byte packing
#endif
// Based relocation format.
struct IMAGE_BASE_RELOCATION {
  DWORD   VirtualAddress;
  DWORD   SizeOfBlock;
//  WORD    TypeOffset[1];
};

#define IMAGE_SIZEOF_BASE_RELOCATION         8

// Based relocation types.
#define IMAGE_REL_BASED_ABSOLUTE              0
#define IMAGE_REL_BASED_HIGH                  1
#define IMAGE_REL_BASED_LOW                   2
#define IMAGE_REL_BASED_HIGHLOW               3
#define IMAGE_REL_BASED_HIGHADJ               4
#define IMAGE_REL_BASED_MIPS_JMPADDR          5
#define IMAGE_REL_BASED_MIPS_JMPADDR16        9
#define IMAGE_REL_BASED_IA64_IMM64            9
#define IMAGE_REL_BASED_DIR64                 10

// Archive format.
#define IMAGE_ARCHIVE_START_SIZE             8
#define IMAGE_ARCHIVE_START                  "!<arch>\n"
#define IMAGE_ARCHIVE_END                    "`\n"
#define IMAGE_ARCHIVE_PAD                    "\n"
#define IMAGE_ARCHIVE_LINKER_MEMBER          "/               "
#define IMAGE_ARCHIVE_LONGNAMES_MEMBER       "//              "

struct IMAGE_ARCHIVE_MEMBER_HEADER {
  BYTE     Name[16];                          // File member name - `/' terminated.
  BYTE     Date[12];                          // File member date - decimal.
  BYTE     UserID[6];                         // File member user id - decimal.
  BYTE     GroupID[6];                        // File member group id - decimal.
  BYTE     Mode[8];                           // File member mode - octal.
  BYTE     Size[10];                          // File member size - decimal.
  BYTE     EndHeader[2];                      // String to end header.
};

#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR      60

// DLL support.
// Export Format
struct IMAGE_EXPORT_DIRECTORY {
  DWORD   Characteristics;
  DWORD   TimeDateStamp;
  WORD    MajorVersion;
  WORD    MinorVersion;
  DWORD   Name;
  DWORD   Base;
  DWORD   NumberOfFunctions;
  DWORD   NumberOfNames;
  DWORD   AddressOfFunctions;     // RVA from base of image
  DWORD   AddressOfNames;         // RVA from base of image
  DWORD   AddressOfNameOrdinals;  // RVA from base of image
};

// Import Format
struct IMAGE_IMPORT_BY_NAME {
  WORD    Hint;
  BYTE    Name[1];
};
/*
#pragma pack(push,8)
struct IMAGE_THUNK_DATA64 {
  union {
    ULONGLONG ForwarderString;  // PBYTE
    ULONGLONG Function;         // PDWORD
    ULONGLONG Ordinal;
    ULONGLONG AddressOfData;    // PIMAGE_IMPORT_BY_NAME
  }u1;
};
#pragma pack(pop)*/
struct IMAGE_THUNK_DATA32 {
  union {
    DWORD ForwarderString;      // PBYTE
    DWORD Function;             // PDWORD
    DWORD Ordinal;
    DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME
  }u1;
};

//#define IMAGE_ORDINAL_FLAG64 0x8000000000000000
#define IMAGE_ORDINAL_FLAG32 0x80000000
//#define IMAGE_ORDINAL64(Ordinal) Ordinal & 0xffff
#define IMAGE_ORDINAL32(Ordinal) Ordinal & 0xffff
//#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) (Ordinal & IMAGE_ORDINAL_FLAG64 != 0)
#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) (Ordinal & IMAGE_ORDINAL_FLAG32 != 0)

/*// Thread Local Storage
struct IMAGE_TLS_DIRECTORY64 {
  ULONGLONG   StartAddressOfRawData;
  ULONGLONG   EndAddressOfRawData;
  ULONGLONG   AddressOfIndex;         // PDWORD
  ULONGLONG   AddressOfCallBacks;     // PIMAGE_TLS_CALLBACK *;
  DWORD   SizeOfZeroFill;
  DWORD   Characteristics;
};*/

struct IMAGE_TLS_DIRECTORY32 {
  DWORD   StartAddressOfRawData;
  DWORD   EndAddressOfRawData;
  DWORD   AddressOfIndex;             // PDWORD
  DWORD   AddressOfCallBacks;         // PIMAGE_TLS_CALLBACK *
  DWORD   SizeOfZeroFill;
  DWORD   Characteristics;
};

#define IMAGE_ORDINAL_FLAG              IMAGE_ORDINAL_FLAG32
#define IMAGE_ORDINAL(Ordinal)          IMAGE_ORDINAL32(Ordinal)
#define IMAGE_THUNK_DATA IMAGE_THUNK_DATA32
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)  IMAGE_SNAP_BY_ORDINAL32(Ordinal)
#define IMAGE_TLS_DIRECTORY IMAGE_TLS_DIRECTORY32

struct IMAGE_IMPORT_DESCRIPTOR {
  union {
    DWORD   Characteristics;            // 0 for terminating null import descriptor
    DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
  };
  DWORD   TimeDateStamp;                  // 0 if not bound,
                                          // -1 if bound, and real date\time stamp
                                          //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                          // O.W. date/time stamp of DLL bound to (Old BIND)
  DWORD   ForwarderChain;                 // -1 if no forwarders
  DWORD   Name;
  DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
};

// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ]
struct IMAGE_BOUND_IMPORT_DESCRIPTOR {
  DWORD   TimeDateStamp;
  WORD    OffsetModuleName;
  WORD    NumberOfModuleForwarderRefs;
// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
};

struct IMAGE_BOUND_FORWARDER_REF {
  DWORD   TimeDateStamp;
  WORD    OffsetModuleName;
  WORD    Reserved;
};

// Resource Format.
// Resource directory consists of two counts, following by a variable length
// array of directory entries.  The first count is the number of entries at
// beginning of the array that have actual names associated with each entry.
// The entries are in ascending order, case insensitive strings.  The second
// count is the number of entries that immediately follow the named entries.
// This second count identifies the number of entries that have 16-bit integer
// Ids as their name.  These entries are also sorted in ascending order.
// This structure allows fast lookup by either name or number, but for any
// given resource entry only one form of lookup is supported, not both.
// This is consistant with the syntax of the .RC file and the .RES file.
struct IMAGE_RESOURCE_DIRECTORY {
  DWORD   Characteristics;
  DWORD   TimeDateStamp;
  WORD    MajorVersion;
  WORD    MinorVersion;
  WORD    NumberOfNamedEntries;
  WORD    NumberOfIdEntries;
//  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
};

#define IMAGE_RESOURCE_NAME_IS_STRING        0x80000000
#define IMAGE_RESOURCE_DATA_IS_DIRECTORY     0x80000000
// Each directory contains the 32-bit Name of the entry and an offset,
// relative to the beginning of the resource directory of the data associated
// with this directory entry.  If the name of the entry is an actual text
// string instead of an integer Id, then the high order bit of the name field
// is set to one and the low order 31-bits are an offset, relative to the
// beginning of the resource directory of the string, which is of type
// IMAGE_RESOURCE_DIRECTORY_STRING.  Otherwise the high bit is clear and the
// low-order 16-bits are the integer Id that identify this resource directory
// entry. If the directory entry is yet another resource directory (i.e. a
// subdirectory), then the high order bit of the offset field will be
// set to indicate this.  Otherwise the high bit is clear and the offset
// field points to a resource data entry.
struct IMAGE_RESOURCE_DIRECTORY_ENTRY {
  union {
    struct {
      DWORD NameOffset:31;
      DWORD NameIsString:1;
    };
    DWORD   Name;
    WORD    Id;
  };
  union {
    DWORD   OffsetToData;
    struct {
      DWORD   OffsetToDirectory:31;
      DWORD   DataIsDirectory:1;
    };
  };
};

// For resource directory entries that have actual string names, the Name
// field of the directory entry points to an object of the following type.
// All of these string objects are stored together after the last resource
// directory entry and before the first resource data object.  This minimizes
// the impact of these variable length objects on the alignment of the fixed
// size directory entry objects.
struct IMAGE_RESOURCE_DIRECTORY_STRING {
  WORD    Length;
  CHAR    NameString[ 1 ];
};

struct IMAGE_RESOURCE_DIR_STRING_U {
  WORD    Length;
  WCHAR   NameString[ 1 ];
};

// Each resource data entry describes a leaf node in the resource directory
// tree.  It contains an offset, relative to the beginning of the resource
// directory of the data for the resource, a size field that gives the number
// of bytes of data at that offset, a CodePage that should be used when
// decoding code point values within the resource data.  Typically for new
// applications the code page would be the unicode code page.
struct IMAGE_RESOURCE_DATA_ENTRY {
  DWORD   OffsetToData;
  DWORD   Size;
  DWORD   CodePage;
  DWORD   Reserved;
};

// Load Configuration Directory Entry
struct IMAGE_LOAD_CONFIG_DIRECTORY32{
  DWORD   Characteristics;
  DWORD   TimeDateStamp;
  WORD    MajorVersion;
  WORD    MinorVersion;
  DWORD   GlobalFlagsClear;
  DWORD   GlobalFlagsSet;
  DWORD   CriticalSectionDefaultTimeout;
  DWORD   DeCommitFreeBlockThreshold;
  DWORD   DeCommitTotalFreeThreshold;
  DWORD   LockPrefixTable;            // VA
  DWORD   MaximumAllocationSize;
  DWORD   VirtualMemoryThreshold;
  DWORD   ProcessHeapFlags;
  DWORD   ProcessAffinityMask;
  WORD    CSDVersion;
  WORD    Reserved1;
  DWORD   EditList;                   // VA
  DWORD   Reserved[ 1 ];
};
/*
struct IMAGE_LOAD_CONFIG_DIRECTORY64{
  DWORD   Characteristics;
  DWORD   TimeDateStamp;
  WORD    MajorVersion;
  WORD    MinorVersion;
  DWORD   GlobalFlagsClear;
  DWORD   GlobalFlagsSet;
  DWORD   CriticalSectionDefaultTimeout;
  ULONGLONG  DeCommitFreeBlockThreshold;
  ULONGLONG  DeCommitTotalFreeThreshold;
  ULONGLONG  LockPrefixTable;         // VA
  ULONGLONG  MaximumAllocationSize;
  ULONGLONG  VirtualMemoryThreshold;
  ULONGLONG  ProcessAffinityMask;
  DWORD   ProcessHeapFlags;
  WORD    CSDVersion;
  WORD    Reserved1;
  ULONGLONG  EditList;                // VA
  DWORD   Reserved[ 2 ];
};*/

#define IMAGE_LOAD_CONFIG_DIRECTORY IMAGE_LOAD_CONFIG_DIRECTORY32

// WIN CE Exception table format
// Function table entry format.  Function table is pointed to by the
// IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry.
struct IMAGE_CE_RUNTIME_FUNCTION_ENTRY {
  DWORD FuncStart;
  DWORD PrologLen : 8;
  DWORD FuncLen : 22;
  DWORD ThirtyTwoBit : 1;
  DWORD ExceptionFlag : 1;
};
/*
struct IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY {
  ULONGLONG BeginAddress;
  ULONGLONG EndAddress;
  ULONGLONG ExceptionHandler;
  ULONGLONG HandlerData;
  ULONGLONG PrologEndAddress;
};

struct IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY {
  DWORD BeginAddress;
  DWORD EndAddress;
  DWORD ExceptionHandler;
  DWORD HandlerData;
  DWORD PrologEndAddress;
};*/

struct IMAGE_RUNTIME_FUNCTION_ENTRY {
  DWORD BeginAddress;
  DWORD EndAddress;
  DWORD UnwindInfoAddress;
};

#define IMAGE_IA64_RUNTIME_FUNCTION_ENTRY IMAGE_RUNTIME_FUNCTION_ENTRY

// Debug Format
struct IMAGE_DEBUG_DIRECTORY {
  DWORD   Characteristics;
  DWORD   TimeDateStamp;
  WORD    MajorVersion;
  WORD    MinorVersion;
  DWORD   Type;
  DWORD   SizeOfData;
  DWORD   AddressOfRawData;
  DWORD   PointerToRawData;
};

#define IMAGE_DEBUG_TYPE_UNKNOWN          0
#define IMAGE_DEBUG_TYPE_COFF             1
#define IMAGE_DEBUG_TYPE_CODEVIEW         2
#define IMAGE_DEBUG_TYPE_FPO              3
#define IMAGE_DEBUG_TYPE_MISC             4
#define IMAGE_DEBUG_TYPE_EXCEPTION        5
#define IMAGE_DEBUG_TYPE_FIXUP            6
#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC      7
#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC    8
#define IMAGE_DEBUG_TYPE_BORLAND          9
#define IMAGE_DEBUG_TYPE_RESERVED10       10
#define IMAGE_DEBUG_TYPE_CLSID            11

struct IMAGE_COFF_SYMBOLS_HEADER {
  DWORD   NumberOfSymbols;
  DWORD   LvaToFirstSymbol;
  DWORD   NumberOfLinenumbers;
  DWORD   LvaToFirstLinenumber;
  DWORD   RvaToFirstByteOfCode;
  DWORD   RvaToLastByteOfCode;
  DWORD   RvaToFirstByteOfData;
  DWORD   RvaToLastByteOfData;
};

#define FRAME_FPO       0
#define FRAME_TRAP      1
#define FRAME_TSS       2
#define FRAME_NONFPO    3

struct FPO_DATA {
  DWORD       ulOffStart;             // offset 1st byte of function code
  DWORD       cbProcSize;             // # bytes in function
  DWORD       cdwLocals;              // # bytes in locals/4
  WORD        cdwParams;              // # bytes in params/4
  WORD        cbProlog : 8;           // # bytes in prolog
  WORD        cbRegs   : 3;           // # regs saved
  WORD        fHasSEH  : 1;           // TRUE if SEH in func
  WORD        fUseBP   : 1;           // TRUE if EBP has been allocated
  WORD        reserved : 1;           // reserved for future use
  WORD        cbFrame  : 2;           // frame type
};
#define SIZEOF_RFPO_DATA 16

#define IMAGE_DEBUG_MISC_EXENAME    1

struct IMAGE_DEBUG_MISC {
  DWORD       DataType;               // type of misc data, see defines
  DWORD       Length;                 // total length of record, rounded to four
                                      // byte multiple.
  BOOLEAN     Unicode;                // TRUE if data is unicode string
  BYTE        Reserved[ 3 ];
  BYTE        Data[ 1 ];              // Actual data
};

// Function table extracted from MIPS/ALPHA/IA64 images.  Does not contain
// information needed only for runtime support.  Just those fields for
// each entry needed by a debugger.
struct IMAGE_FUNCTION_ENTRY {
  DWORD   StartingAddress;
  DWORD   EndingAddress;
  DWORD   EndOfPrologue;
};

struct _IMAGE_FUNCTION_ENTRY64 {
  ULONGLONG   StartingAddress;
  ULONGLONG   EndingAddress;
  union {
    ULONGLONG   EndOfPrologue;
    ULONGLONG   UnwindInfoAddress;
  };
};

// Debugging information can be stripped from an image file and placed
// in a separate .DBG file, whose file name part is the same as the
// image file name part (e.g. symbols for CMD.EXE could be stripped
// and placed in CMD.DBG).  This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
// flag in the Characteristics field of the file header.  The beginning of
// the .DBG file contains the following structure which captures certain
// information from the image file.  This allows a debug to proceed even if
// the original image file is not accessable.  This header is followed by
// zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
// IMAGE_DEBUG_DIRECTORY structures.  The latter structures and those in
// the image file contain file offsets relative to the beginning of the
// .DBG file.
// If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
// is left in the image file, but not mapped.  This allows a debugger to
// compute the name of the .DBG file, from the name of the image in the
// IMAGE_DEBUG_MISC structure.
struct IMAGE_SEPARATE_DEBUG_HEADER {
  WORD        Signature;
  WORD        Flags;
  WORD        Machine;
  WORD        Characteristics;
  DWORD       TimeDateStamp;
  DWORD       CheckSum;
  DWORD       ImageBase;
  DWORD       SizeOfImage;
  DWORD       NumberOfSections;
  DWORD       ExportedNamesSize;
  DWORD       DebugDirectorySize;
  DWORD       SectionAlignment;
  DWORD       Reserved[2];
};

struct NON_PAGED_DEBUG_INFO {
  WORD        Signature;
  WORD        Flags;
  DWORD       Size;
  WORD        Machine;
  WORD        Characteristics;
  DWORD       TimeDateStamp;
  DWORD       CheckSum;
  DWORD       SizeOfImage;
  ULONGLONG   ImageBase;
  //DebugDirectorySize
  //IMAGE_DEBUG_DIRECTORY
};

#ifndef _MAC
#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
#define NON_PAGED_DEBUG_SIGNATURE      0x494E
#else
#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4449  // DI
#define NON_PAGED_DEBUG_SIGNATURE      0x4E49  // NI
#endif

#define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000
#define IMAGE_SEPARATE_DEBUG_MISMATCH   0x8000  // when DBG was updated, the
                                                // old checksum didn't match.

//  The .arch section is made up of headers, each describing an amask position/value
//  pointing to an array of IMAGE_ARCHITECTURE_ENTRY's.  Each "array" (both the header
//  and entry arrays) are terminiated by a quadword of 0xffffffffL.
//  NOTE: There may be quadwords of 0 sprinkled around and must be skipped.
struct IMAGE_ARCHITECTURE_HEADER{
  unsigned int AmaskValue: 1;                 // 1 -> code section depends on mask bit
                                              // 0 -> new instruction depends on mask bit
  int :7;                                     // MBZ
  unsigned int AmaskShift: 8;                 // Amask bit in question for this fixup
  int :16;                                    // MBZ
  DWORD FirstEntryRVA;                        // RVA into .arch section to array of ARCHITECTURE_ENTRY's
};

struct IMAGE_ARCHITECTURE_ENTRY{
  DWORD FixupInstRVA;                         // RVA of instruction to fixup
  DWORD NewInst;                              // fixup instruction (see alphaops.h)
};

#pragma pack(pop)                // Back to the initial value
// The following structure defines the new import object.  Note the values of the first two fields,
// which must be set as stated in order to differentiate old and new import members.
// Following this structure, the linker emits two null-terminated strings used to recreate the
// import at the time of use.  The first string is the import's name, the second is the dll's name.
#define IMPORT_OBJECT_HDR_SIG2  0xffff

struct IMPORT_OBJECT_HEADER {
  WORD    Sig1;                       // Must be IMAGE_FILE_MACHINE_UNKNOWN
  WORD    Sig2;                       // Must be IMPORT_OBJECT_HDR_SIG2.
  WORD    Version;
  WORD    Machine;
  DWORD   TimeDateStamp;              // Time/date stamp
  DWORD   SizeOfData;                 // particularly useful for incremental links
  union {
    WORD    Ordinal;                // if grf & IMPORT_OBJECT_ORDINAL
    WORD    Hint;
  };
  WORD    Type : 2;                   // IMPORT_TYPE
  WORD    NameType : 3;               // IMPORT_NAME_TYPE
  WORD    Reserved : 11;              // Reserved. Must be zero.
};

enum IMPORT_OBJECT_TYPE{
  IMPORT_OBJECT_CODE = 0,
  IMPORT_OBJECT_DATA = 1,
  IMPORT_OBJECT_CONST = 2,
};

enum IMPORT_OBJECT_NAME_TYPE{
  IMPORT_OBJECT_ORDINAL = 0,          // Import by ordinal
  IMPORT_OBJECT_NAME = 1,             // Import name == public symbol name.
  IMPORT_OBJECT_NAME_NO_PREFIX = 2,   // Import name == public symbol name skipping leading ?, @, or optionally _.
  IMPORT_OBJECT_NAME_UNDECORATE = 3,  // Import name == public symbol name skipping leading ?, @, or optionally _
                                      // and truncating at first @
};

#ifndef __IMAGE_COR20_HEADER_DEFINED__
#define __IMAGE_COR20_HEADER_DEFINED__

enum ReplacesCorHdrNumericDefines{
// COM+ Header entry point flags.
  COMIMAGE_FLAGS_ILONLY               =0x00000001,
  COMIMAGE_FLAGS_32BITREQUIRED        =0x00000002,
  COMIMAGE_FLAGS_IL_LIBRARY           =0x00000004,
  COMIMAGE_FLAGS_TRACKDEBUGDATA       =0x00010000,
// Version flags for image.
  COR_VERSION_MAJOR_V2                =2,
  COR_VERSION_MAJOR                   =COR_VERSION_MAJOR_V2,
  COR_VERSION_MINOR                   =0,
  COR_DELETED_NAME_LENGTH             =8,
  COR_VTABLEGAP_NAME_LENGTH           =8,
// Maximum size of a NativeType descriptor.
  NATIVE_TYPE_MAX_CB                  =1,
  COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE=0xFF,
// #defines for the MIH FLAGS
  IMAGE_COR_MIH_METHODRVA             =0x01,
  IMAGE_COR_MIH_EHRVA                 =0x02,
  IMAGE_COR_MIH_BASICBLOCK            =0x08,
// V-table constants
  COR_VTABLE_32BIT                    =0x01,          // V-table slots are 32-bits in size.
  COR_VTABLE_64BIT                    =0x02,          // V-table slots are 64-bits in size.
  COR_VTABLE_FROM_UNMANAGED           =0x04,          // If set, transition from unmanaged.
  COR_VTABLE_CALL_MOST_DERIVED        =0x10,          // Call most derived method described by
// EATJ constants
  IMAGE_COR_EATJ_THUNK_SIZE           =32,            // Size of a jump thunk reserved range.
// Max name lengths
  //@todo: Change to unlimited name lengths.
  MAX_CLASS_NAME                      =1024,
  MAX_PACKAGE_NAME                    =1024,
};

// COM+ 2.0 header structure.
struct IMAGE_COR20_HEADER
{
  // Header versioning
  DWORD                   cb;
  WORD                    MajorRuntimeVersion;
  WORD                    MinorRuntimeVersion;
  // Symbol table and startup information
  IMAGE_DATA_DIRECTORY    MetaData;
  DWORD                   Flags;
  DWORD                   EntryPointToken;
  // Binding information
  IMAGE_DATA_DIRECTORY    Resources;
  IMAGE_DATA_DIRECTORY    StrongNameSignature;
  // Regular fixup and binding information
  IMAGE_DATA_DIRECTORY    CodeManagerTable;
  IMAGE_DATA_DIRECTORY    VTableFixups;
  IMAGE_DATA_DIRECTORY    ExportAddressTableJumps;
  // Precompiled image info (internal use only - set to zero)
  IMAGE_DATA_DIRECTORY    ManagedNativeHeader;
};

#endif // __IMAGE_COR20_HEADER_DEFINED__
// End Image Format

#ifndef _SLIST_HEADER_
#define _SLIST_HEADER_

#define SLIST_ENTRY SINGLE_LIST_ENTRY
#define _SLIST_ENTRY _SINGLE_LIST_ENTRY
#define PSLIST_ENTRY PSINGLE_LIST_ENTRY

struct SLIST_HEADER {
  SLIST_ENTRY Next;
  WORD   Depth;
  WORD   Sequence;
};

#endif

//VOID RtlInitializeSListHead(dword ListHead);
//dword RtlFirstEntrySList(dword ListHead);
//dword RtlInterlockedPopEntrySList(dword ListHead);
//dword RtlInterlockedPushEntrySList(dword ListHead,dword ListEntry);
//dword RtlInterlockedFlushSList(dword ListHead);
//WORD RtlQueryDepthSList(dword ListHead);

#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
#define HEAP_TAG_SHIFT                  18
#define HEAP_MAKE_TAG_FLAGS(b,o) o<<18+b

#define IS_TEXT_UNICODE_ASCII16               0x0001
#define IS_TEXT_UNICODE_REVERSE_ASCII16       0x0010
#define IS_TEXT_UNICODE_STATISTICS            0x0002
#define IS_TEXT_UNICODE_REVERSE_STATISTICS    0x0020
#define IS_TEXT_UNICODE_CONTROLS              0x0004
#define IS_TEXT_UNICODE_REVERSE_CONTROLS      0x0040
#define IS_TEXT_UNICODE_SIGNATURE             0x0008
#define IS_TEXT_UNICODE_REVERSE_SIGNATURE     0x0080
#define IS_TEXT_UNICODE_ILLEGAL_CHARS         0x0100
#define IS_TEXT_UNICODE_ODD_LENGTH            0x0200
#define IS_TEXT_UNICODE_DBCS_LEADBYTE         0x0400
#define IS_TEXT_UNICODE_NULL_BYTES            0x1000
#define IS_TEXT_UNICODE_UNICODE_MASK          0x000F
#define IS_TEXT_UNICODE_REVERSE_MASK          0x00F0
#define IS_TEXT_UNICODE_NOT_UNICODE_MASK      0x0F00
#define IS_TEXT_UNICODE_NOT_ASCII_MASK        0xF000
#define COMPRESSION_FORMAT_NONE          0x0000
#define COMPRESSION_FORMAT_DEFAULT       0x0001
#define COMPRESSION_FORMAT_LZNT1         0x0002
#define COMPRESSION_ENGINE_STANDARD      0x0000
#define COMPRESSION_ENGINE_MAXIMUM       0x0100
#define COMPRESSION_ENGINE_HIBER         0x0200
extern WINAPI "kernel32.dll"{
//	SIZE_T RtlCompareMemory(dword Source1,dword Source2,SIZE_T Length);
//	VOID RtlCopyMemory(dword Destination,dword Source,SIZE_T Length);
//	VOID RtlCopyMemory32(dword Destination,dword Source,DWORD Length);
	VOID RtlMoveMemory(dword Destination,dword Source,SIZE_T Length);
	VOID RtlFillMemory(dword Destination,SIZE_T Length,BYTE Fill);
	VOID RtlZeroMemory(dword Destination,SIZE_T Length);
}
struct MESSAGE_RESOURCE_ENTRY {
  WORD   Length;
  WORD   Flags;
  BYTE  Text[1];
};

#define MESSAGE_RESOURCE_UNICODE 0x0001

struct MESSAGE_RESOURCE_BLOCK {
  DWORD LowId;
  DWORD HighId;
  DWORD OffsetToEntries;
};

struct MESSAGE_RESOURCE_DATA {
  DWORD NumberOfBlocks;
  MESSAGE_RESOURCE_BLOCK Blocks[ 1 ];
};

struct OSVERSIONINFOA {
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  CHAR   szCSDVersion[ 128 ];     // Maintenance string for PSS usage
};

struct OSVERSIONINFOW {
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  WCHAR  szCSDVersion[ 128 ];     // Maintenance string for PSS usage
};
#ifdef UNICODE
#define OSVERSIONINFO OSVERSIONINFOW
#else
#define OSVERSIONINFO OSVERSIONINFOA
#endif // UNICODE

struct OSVERSIONINFOEXA {
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  CHAR   szCSDVersion[ 128 ];     // Maintenance string for PSS usage
  WORD   wServicePackMajor;
  WORD   wServicePackMinor;
  WORD   wSuiteMask;
  BYTE  wProductType;
  BYTE  wReserved;
};
struct OSVERSIONINFOEXW {
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  WCHAR  szCSDVersion[ 128 ];     // Maintenance string for PSS usage
  WORD   wServicePackMajor;
  WORD   wServicePackMinor;
  WORD   wSuiteMask;
  BYTE  wProductType;
  BYTE  wReserved;
};
#ifdef UNICODE
#define OSVERSIONINFOEX OSVERSIONINFOEXW
#else
#define OSVERSIONINFOEX OSVERSIONINFOEXA
#endif // UNICODE

// RtlVerifyVersionInfo() conditions
#define VER_EQUAL                       1
#define VER_GREATER                     2
#define VER_GREATER_EQUAL               3
#define VER_LESS                        4
#define VER_LESS_EQUAL                  5
#define VER_AND                         6
#define VER_OR                          7
#define VER_CONDITION_MASK              7
#define VER_NUM_BITS_PER_CONDITION_MASK 3

// RtlVerifyVersionInfo() type mask bits
#define VER_MINORVERSION                0x0000001
#define VER_MAJORVERSION                0x0000002
#define VER_BUILDNUMBER                 0x0000004
#define VER_PLATFORMID                  0x0000008
#define VER_SERVICEPACKMINOR            0x0000010
#define VER_SERVICEPACKMAJOR            0x0000020
#define VER_SUITENAME                   0x0000040
#define VER_PRODUCT_TYPE                0x0000080

// RtlVerifyVersionInfo() os product type values
#define VER_NT_WORKSTATION              0x0000001
#define VER_NT_DOMAIN_CONTROLLER        0x0000002
#define VER_NT_SERVER                   0x0000003

// dwPlatformId defines:
#define VER_PLATFORM_WIN32s             0
#define VER_PLATFORM_WIN32_WINDOWS      1
#define VER_PLATFORM_WIN32_NT           2

// VerifyVersionInfo() macro to set the condition mask
// For documentation sakes here's the old version of the macro that got
// changed to call an API
// #define VER_SET_CONDITION(_m_,_t_,_c_)  _m_=(_m_|(_c_<<(1<<_t_)))
//#define VER_SET_CONDITION(_m_,_t_,_c_)  _m_=VerSetConditionMask(_m_,_t_,_c_)
//ULONGLONG VerSetConditionMask(ULONGLONG ConditionMask,DWORD TypeMask,BYTE Condition);

struct RTL_CRITICAL_SECTION_DEBUG {
  WORD   Type;
  WORD   CreatorBackTraceIndex;
  dword CriticalSection;
  LIST_ENTRY ProcessLocksList;
  DWORD EntryCount;
  DWORD ContentionCount;
  DWORD Spare[ 2 ];
};

#define RTL_CRITSECT_TYPE 0
#define RTL_RESOURCE_TYPE 1

struct RTL_CRITICAL_SECTION {
  dword DebugInfo;
  //  The following three fields control entering and exiting the critical
  //  section for the resource
  LONG LockCount;
  LONG RecursionCount;
  HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
  HANDLE LockSemaphore;
  dword SpinCount;        // force size on 64-bit systems when packed
};

struct RTL_VERIFIER_THUNK_DESCRIPTOR {
  PCHAR ThunkName;
  dword ThunkOldAddress;
  dword ThunkNewAddress;
};

struct RTL_VERIFIER_DLL_DESCRIPTOR {
  PWCHAR DllName;
  DWORD DllFlags;
  dword DllAddress;
  dword DllThunks;
};

struct RTL_VERIFIER_PROVIDER_DESCRIPTOR {
  // Filled by verifier provider DLL
  DWORD Length;
  dword ProviderDlls;
  dword ProviderDllLoadCallback;
  dword ProviderDllUnloadCallback;
  // Filled by verifier engine
  dword VerifierImage;
  DWORD VerifierFlags;
  DWORD VerifierDebug;
};

// Application verifier standard flags
#define RTL_VRF_FLG_FULL_PAGE_HEAP     0x0001
#define RTL_VRF_FLG_LOCK_CHECKS        0x0002
#define RTL_VRF_FLG_HANDLE_CHECKS      0x0004
#define RTL_VRF_FLG_STACK_CHECKS       0x0008
#define RTL_VRF_FLG_APPCOMPAT_CHECKS   0x0010

// Application verifier standard stop codes
#define APPLICATION_VERIFIER_INTERNAL_ERROR               0x80000000
#define APPLICATION_VERIFIER_INTERNAL_WARNING             0x40000000
#define APPLICATION_VERIFIER_NO_BREAK                     0x20000000
#define APPLICATION_VERIFIER_RESERVED_BIT_28              0x10000000
#define APPLICATION_VERIFIER_UNKNOWN_ERROR                0x0001
#define APPLICATION_VERIFIER_ACCESS_VIOLATION             0x0002
#define APPLICATION_VERIFIER_UNSYNCHRONIZED_ACCESS        0x0003
#define APPLICATION_VERIFIER_EXTREME_SIZE_REQUEST         0x0004
#define APPLICATION_VERIFIER_BAD_HEAP_HANDLE              0x0005
#define APPLICATION_VERIFIER_SWITCHED_HEAP_HANDLE         0x0006
#define APPLICATION_VERIFIER_DOUBLE_FREE                  0x0007
#define APPLICATION_VERIFIER_CORRUPTED_HEAP_BLOCK         0x0008
#define APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP         0x0009
#define APPLICATION_VERIFIER_UNEXPECTED_EXCEPTION         0x000A
#define APPLICATION_VERIFIER_STACK_OVERFLOW               0x000B
#define APPLICATION_VERIFIER_TERMINATE_THREAD_CALL        0x0100
#define APPLICATION_VERIFIER_EXIT_THREAD_OWNS_LOCK        0x0200
#define APPLICATION_VERIFIER_LOCK_IN_UNLOADED_DLL         0x0201
#define APPLICATION_VERIFIER_LOCK_IN_FREED_HEAP           0x0202
#define APPLICATION_VERIFIER_LOCK_DOUBLE_INITIALIZE       0x0203
#define APPLICATION_VERIFIER_LOCK_IN_FREED_MEMORY         0x0204
#define APPLICATION_VERIFIER_LOCK_CORRUPTED               0x0205
#define APPLICATION_VERIFIER_LOCK_INVALID_OWNER           0x0206
#define APPLICATION_VERIFIER_LOCK_INVALID_RECURSION_COUNT 0x0207
#define APPLICATION_VERIFIER_LOCK_INVALID_LOCK_COUNT      0x0208
#define APPLICATION_VERIFIER_LOCK_OVER_RELEASED           0x0209
#define APPLICATION_VERIFIER_LOCK_NOT_INITIALIZED         0x0210
#define APPLICATION_VERIFIER_INVALID_HANDLE               0x0300
/*
#define VERIFIER_STOP(Code,Msg,P1,S1,P2,S2,P3,S3,P4,S4) {  \
        RtlApplicationVerifierStop(Code,Msg,P1,S1,P2,S2,P3,S3,P4,S4);          \
  }
VOID RtlApplicationVerifierStop(dword Code,PCHAR Message,dword Param1, PCHAR Description1,
    dword Param2,PCHAR Description2,dword Param3,PCHAR Description3,
    dword Param4,PCHAR Description4);
	*/
#define SEF_DACL_AUTO_INHERIT             0x01
#define SEF_SACL_AUTO_INHERIT             0x02
#define SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT 0x04
#define SEF_AVOID_PRIVILEGE_CHECK         0x08
#define SEF_AVOID_OWNER_CHECK             0x10
#define SEF_DEFAULT_OWNER_FROM_PARENT     0x20
#define SEF_DEFAULT_GROUP_FROM_PARENT     0x40

enum HEAP_INFORMATION_CLASS{
  HeapCompatibilityInformation
};
/*
DWORD RtlSetHeapInformation(dword HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,
     dword HeapInformation OPTIONAL,SIZE_T HeapInformationLength OPTIONAL);

DWORD RtlQueryHeapInformation(dword HeapHandle,HEAP_INFORMATION_CLASS HeapInformationClass,
     dword HeapInformation OPTIONAL,SIZE_T HeapInformationLength OPTIONAL,PSIZE_T ReturnLength OPTIONAL);
*/
#define WT_EXECUTEDEFAULT       0x00000000
#define WT_EXECUTEINIOTHREAD    0x00000001
#define WT_EXECUTEINUITHREAD    0x00000002
#define WT_EXECUTEINWAITTHREAD  0x00000004
#define WT_EXECUTEONLYONCE      0x00000008
#define WT_EXECUTEINTIMERTHREAD 0x00000020
#define WT_EXECUTELONGFUNCTION  0x00000010
#define WT_EXECUTEINPERSISTENTIOTHREAD  0x00000040
#define WT_EXECUTEINPERSISTENTTHREAD 0x00000080
#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit)  Flags|=Limit<<16
#define WT_EXECUTEINLONGTHREAD  0x00000010
#define WT_EXECUTEDELETEWAIT    0x00000008

enum ACTIVATION_CONTEXT_INFO_CLASS{
  ActivationContextBasicInformation                       = 1,
  ActivationContextDetailedInformation                    = 2,
  AssemblyDetailedInformationInActivationContext          = 3,
  FileInformationInAssemblyOfAssemblyInActivationContext  = 4,
  MaxActivationContextInfoClass,
  // compatibility with old names
  AssemblyDetailedInformationInActivationContxt           = 3,
  FileInformationInAssemblyOfAssemblyInActivationContxt   = 4
};

#define ACTIVATIONCONTEXTINFOCLASS ACTIVATION_CONTEXT_INFO_CLASS

struct ACTIVATION_CONTEXT_QUERY_INDEX {
  DWORD ulAssemblyIndex;
  DWORD ulFileIndexInAssembly;
};

#define ACTIVATION_CONTEXT_PATH_TYPE_NONE 1
#define ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE 2
#define ACTIVATION_CONTEXT_PATH_TYPE_URL 3
#define ACTIVATION_CONTEXT_PATH_TYPE_ASSEMBLYREF 4

struct ASSEMBLY_FILE_DETAILED_INFORMATION {
  DWORD ulFlags;
  DWORD ulFilenameLength;
  DWORD ulPathLength;
  dword lpFileName;
  dword lpFilePath;
};

// compatibility with old names
// The new names use "file" consistently.
#define  _ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION  ASSEMBLY_FILE_DETAILED_INFORMATION
#define   ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION  ASSEMBLY_FILE_DETAILED_INFORMATION

struct ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION {
  DWORD ulFlags;
  DWORD ulEncodedAssemblyIdentityLength;      // in bytes
  DWORD ulManifestPathType;                   // ACTIVATION_CONTEXT_PATH_TYPE_*
  DWORD ulManifestPathLength;                 // in bytes
  LARGE_INTEGER liManifestLastWriteTime;      // FILETIME
  DWORD ulPolicyPathType;                     // ACTIVATION_CONTEXT_PATH_TYPE_*
  DWORD ulPolicyPathLength;                   // in bytes
  LARGE_INTEGER liPolicyLastWriteTime;        // FILETIME
  DWORD ulMetadataSatelliteRosterIndex;
  DWORD ulManifestVersionMajor;               // 1
  DWORD ulManifestVersionMinor;               // 0
  DWORD ulPolicyVersionMajor;                 // 0
  DWORD ulPolicyVersionMinor;                 // 0
  DWORD ulAssemblyDirectoryNameLength;        // in bytes
  dword lpAssemblyEncodedAssemblyIdentity;
  dword lpAssemblyManifestPath;
  dword lpAssemblyPolicyPath;
  dword lpAssemblyDirectoryName;
  DWORD  ulFileCount;
};

struct ACTIVATION_CONTEXT_DETAILED_INFORMATION {
  DWORD dwFlags;
  DWORD ulFormatVersion;
  DWORD ulAssemblyCount;
  DWORD ulRootManifestPathType;
  DWORD ulRootManifestPathChars;
  DWORD ulRootConfigurationPathType;
  DWORD ulRootConfigurationPathChars;
  DWORD ulAppDirPathType;
  DWORD ulAppDirPathChars;
  dword lpRootManifestPath;
  dword lpRootConfigurationPath;
  dword lpAppDirPath;
};

#define DLL_PROCESS_ATTACH   1
#define DLL_THREAD_ATTACH    2
#define DLL_THREAD_DETACH    3
#define DLL_PROCESS_DETACH   0
#define DLL_PROCESS_VERIFIER 4

// Defines for the READ flags for Eventlogging
#define EVENTLOG_SEQUENTIAL_READ        0x0001
#define EVENTLOG_SEEK_READ              0x0002
#define EVENTLOG_FORWARDS_READ          0x0004
#define EVENTLOG_BACKWARDS_READ         0x0008

// The types of events that can be logged.
#define EVENTLOG_SUCCESS                0x0000
#define EVENTLOG_ERROR_TYPE             0x0001
#define EVENTLOG_WARNING_TYPE           0x0002
#define EVENTLOG_INFORMATION_TYPE       0x0004
#define EVENTLOG_AUDIT_SUCCESS          0x0008
#define EVENTLOG_AUDIT_FAILURE          0x0010

// Defines for the WRITE flags used by Auditing for paired events
// These are not implemented in Product 1
#define EVENTLOG_START_PAIRED_EVENT    0x0001
#define EVENTLOG_END_PAIRED_EVENT      0x0002
#define EVENTLOG_END_ALL_PAIRED_EVENTS 0x0004
#define EVENTLOG_PAIRED_EVENT_ACTIVE   0x0008
#define EVENTLOG_PAIRED_EVENT_INACTIVE 0x0010

// Structure that defines the header of the Eventlog record. This is the
// fixed-sized portion before all the variable-length strings, binary
// data and pad bytes.
// TimeGenerated is the time it was generated at the client.
// TimeWritten is the time it was put into the log at the server end.
struct EVENTLOGRECORD {
  DWORD  Length;        // Length of full record
  DWORD  Reserved;      // Used by the service
  DWORD  RecordNumber;  // Absolute record number
  DWORD  TimeGenerated; // Seconds since 1-1-1970
  DWORD  TimeWritten;   // Seconds since 1-1-1970
  DWORD  EventID;
  WORD   EventType;
  WORD   NumStrings;
  WORD   EventCategory;
  WORD   ReservedFlags; // For use with paired events (auditing)
  DWORD  ClosingRecordNumber; // For use with paired events (auditing)
  DWORD  StringOffset;  // Offset from beginning of record
  DWORD  UserSidLength;
  DWORD  UserSidOffset;
  DWORD  DataLength;
  DWORD  DataOffset;    // Offset from beginning of record
  // Then follow:
  // WCHAR SourceName[]
  // WCHAR Computername[]
  // SID   UserSid
  // WCHAR Strings[]
  // BYTE  Data[]
  // CHAR  Pad[]
  // DWORD Length;
};

//SS: start of changes to support clustering
//SS: ideally the
#define MAXLOGICALLOGNAMESIZE   256

struct EVENTSFORLOGFILE{
	DWORD			ulSize;
  WCHAR  		szLogicalLogFile[MAXLOGICALLOGNAMESIZE];        //name of the logical file-security/application/system
  DWORD			ulNumRecords;
	EVENTLOGRECORD 	pEventLogRecords;
};

struct PACKEDEVENTINFO{
  DWORD               ulSize;  //total size of the structure
  DWORD               ulNumEventsForLogFile; //number of EventsForLogFile structure that follow
  DWORD 				ulOffsets;           //the offsets from the start of this structure to the EVENTSFORLOGFILE structure
};
//SS: end of changes to support clustering

// begin_ntddk begin_wdm begin_nthal
// 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_WOW64_32KEY         0x0200
#define KEY_WOW64_64KEY         0x0100
#define KEY_WOW64_RES           0x0300

#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
#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

// Key creation/open disposition
#define REG_CREATED_NEW_KEY         0x00000001L   // New Registry Key created
#define REG_OPENED_EXISTING_KEY     0x00000002L   // Existing Key opened

// hive format to be used by Reg(Nt)SaveKeyEx
#define REG_STANDARD_FORMAT     1
#define REG_LATEST_FORMAT       2
#define REG_NO_COMPRESSION      4

// 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
#define REG_FORCE_RESTORE           0x00000008L   // Force the restore process even when we have open handles on subkeys
// end_ntddk end_wdm end_nthal

// Notify filter values
#define REG_NOTIFY_CHANGE_NAME          0x00000001L // Create or delete (child)
#define REG_NOTIFY_CHANGE_ATTRIBUTES    0x00000002L
#define REG_NOTIFY_CHANGE_LAST_SET      0x00000004L // time stamp
#define REG_NOTIFY_CHANGE_SECURITY      0x00000008L

#define REG_LEGAL_CHANGE_FILTER                 \
                REG_NOTIFY_CHANGE_NAME          |\
                 REG_NOTIFY_CHANGE_ATTRIBUTES    |\
                 REG_NOTIFY_CHANGE_LAST_SET      |\
                 REG_NOTIFY_CHANGE_SECURITY

// 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
#define REG_QWORD                   11  // 64-bit number
#define REG_QWORD_LITTLE_ENDIAN     11  // 64-bit number (same as REG_QWORD)
// end_ntddk end_wdm end_nthal

// begin_ntddk begin_wdm begin_nthal
// Service Types (Bit Mask)
#define SERVICE_KERNEL_DRIVER          0x00000001
#define SERVICE_FILE_SYSTEM_DRIVER     0x00000002
#define SERVICE_ADAPTER                0x00000004
#define SERVICE_RECOGNIZER_DRIVER      0x00000008
#define SERVICE_DRIVER                 SERVICE_KERNEL_DRIVER | \
                                        SERVICE_FILE_SYSTEM_DRIVER | \
                                        SERVICE_RECOGNIZER_DRIVER
#define SERVICE_WIN32_OWN_PROCESS      0x00000010
#define SERVICE_WIN32_SHARE_PROCESS    0x00000020
#define SERVICE_WIN32                  SERVICE_WIN32_OWN_PROCESS | \
                                        SERVICE_WIN32_SHARE_PROCESS
#define SERVICE_INTERACTIVE_PROCESS    0x00000100
#define SERVICE_TYPE_ALL               SERVICE_WIN32  | \
                                        SERVICE_ADAPTER | \
                                        SERVICE_DRIVER  | \
                                        SERVICE_INTERACTIVE_PROCESS

// Start Type
#define SERVICE_BOOT_START             0x00000000
#define SERVICE_SYSTEM_START           0x00000001
#define SERVICE_AUTO_START             0x00000002
#define SERVICE_DEMAND_START           0x00000003
#define SERVICE_DISABLED               0x00000004

// Error control type
#define SERVICE_ERROR_IGNORE           0x00000000
#define SERVICE_ERROR_NORMAL           0x00000001
#define SERVICE_ERROR_SEVERE           0x00000002
#define SERVICE_ERROR_CRITICAL         0x00000003

// Define the registry driver node enumerations
enum SERVICE_NODE_TYPE{
  DriverType               = SERVICE_KERNEL_DRIVER,
  FileSystemType           = SERVICE_FILE_SYSTEM_DRIVER,
  Win32ServiceOwnProcess   = SERVICE_WIN32_OWN_PROCESS,
  Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS,
  AdapterType              = SERVICE_ADAPTER,
  RecognizerType           = SERVICE_RECOGNIZER_DRIVER
};

enum SERVICE_LOAD_TYPE{
  BootLoad    = SERVICE_BOOT_START,
  SystemLoad  = SERVICE_SYSTEM_START,
  AutoLoad    = SERVICE_AUTO_START,
  DemandLoad  = SERVICE_DEMAND_START,
  DisableLoad = SERVICE_DISABLED
};

enum SERVICE_ERROR_TYPE{
  IgnoreError   = SERVICE_ERROR_IGNORE,
  NormalError   = SERVICE_ERROR_NORMAL,
  SevereError   = SERVICE_ERROR_SEVERE,
  CriticalError = SERVICE_ERROR_CRITICAL
};

// IOCTL_TAPE_ERASE definitions
#define TAPE_ERASE_SHORT            0L
#define TAPE_ERASE_LONG             1L

struct TAPE_ERASE {
  DWORD Type;
  BOOLEAN Immediate;
};

// IOCTL_TAPE_PREPARE definitions
#define TAPE_LOAD                   0L
#define TAPE_UNLOAD                 1L
#define TAPE_TENSION                2L
#define TAPE_LOCK                   3L
#define TAPE_UNLOCK                 4L
#define TAPE_FORMAT                 5L

struct TAPE_PREPARE {
  DWORD Operation;
  BOOLEAN Immediate;
};

// IOCTL_TAPE_WRITE_MARKS definitions
#define TAPE_SETMARKS               0L
#define TAPE_FILEMARKS              1L
#define TAPE_SHORT_FILEMARKS        2L
#define TAPE_LONG_FILEMARKS         3L

struct TAPE_WRITE_MARKS {
  DWORD Type;
  DWORD Count;
  BOOLEAN Immediate;
};

// IOCTL_TAPE_GET_POSITION definitions
#define TAPE_ABSOLUTE_POSITION       0L
#define TAPE_LOGICAL_POSITION        1L
#define TAPE_PSEUDO_LOGICAL_POSITION 2L

struct TAPE_GET_POSITION {
  DWORD Type;
  DWORD Partition;
  LARGE_INTEGER Offset;
};

// IOCTL_TAPE_SET_POSITION definitions
#define TAPE_REWIND                 0L
#define TAPE_ABSOLUTE_BLOCK         1L
#define TAPE_LOGICAL_BLOCK          2L
#define TAPE_PSEUDO_LOGICAL_BLOCK   3L
#define TAPE_SPACE_END_OF_DATA      4L
#define TAPE_SPACE_RELATIVE_BLOCKS  5L
#define TAPE_SPACE_FILEMARKS        6L
#define TAPE_SPACE_SEQUENTIAL_FMKS  7L
#define TAPE_SPACE_SETMARKS         8L
#define TAPE_SPACE_SEQUENTIAL_SMKS  9L

struct TAPE_SET_POSITION {
  DWORD Method;
  DWORD Partition;
  LARGE_INTEGER Offset;
  BOOLEAN Immediate;
};

// IOCTL_TAPE_GET_DRIVE_PARAMS definitions
// Definitions for FeaturesLow parameter
#define TAPE_DRIVE_FIXED            0x00000001
#define TAPE_DRIVE_SELECT           0x00000002
#define TAPE_DRIVE_INITIATOR        0x00000004
#define TAPE_DRIVE_ERASE_SHORT      0x00000010
#define TAPE_DRIVE_ERASE_LONG       0x00000020
#define TAPE_DRIVE_ERASE_BOP_ONLY   0x00000040
#define TAPE_DRIVE_ERASE_IMMEDIATE  0x00000080
#define TAPE_DRIVE_TAPE_CAPACITY    0x00000100
#define TAPE_DRIVE_TAPE_REMAINING   0x00000200
#define TAPE_DRIVE_FIXED_BLOCK      0x00000400
#define TAPE_DRIVE_VARIABLE_BLOCK   0x00000800
#define TAPE_DRIVE_WRITE_PROTECT    0x00001000
#define TAPE_DRIVE_EOT_WZ_SIZE      0x00002000
#define TAPE_DRIVE_ECC              0x00010000
#define TAPE_DRIVE_COMPRESSION      0x00020000
#define TAPE_DRIVE_PADDING          0x00040000
#define TAPE_DRIVE_REPORT_SMKS      0x00080000
#define TAPE_DRIVE_GET_ABSOLUTE_BLK 0x00100000
#define TAPE_DRIVE_GET_LOGICAL_BLK  0x00200000
#define TAPE_DRIVE_SET_EOT_WZ_SIZE  0x00400000
#define TAPE_DRIVE_EJECT_MEDIA      0x01000000
#define TAPE_DRIVE_CLEAN_REQUESTS   0x02000000
#define TAPE_DRIVE_SET_CMP_BOP_ONLY 0x04000000
#define TAPE_DRIVE_RESERVED_BIT     0x80000000  //don't use this bit!
//                                              //can't be a low features bit!
//                                              //reserved; high features only

// Definitions for FeaturesHigh parameter
#define TAPE_DRIVE_LOAD_UNLOAD      0x80000001
#define TAPE_DRIVE_TENSION          0x80000002
#define TAPE_DRIVE_LOCK_UNLOCK      0x80000004
#define TAPE_DRIVE_REWIND_IMMEDIATE 0x80000008
#define TAPE_DRIVE_SET_BLOCK_SIZE   0x80000010
#define TAPE_DRIVE_LOAD_UNLD_IMMED  0x80000020
#define TAPE_DRIVE_TENSION_IMMED    0x80000040
#define TAPE_DRIVE_LOCK_UNLK_IMMED  0x80000080
#define TAPE_DRIVE_SET_ECC          0x80000100
#define TAPE_DRIVE_SET_COMPRESSION  0x80000200
#define TAPE_DRIVE_SET_PADDING      0x80000400
#define TAPE_DRIVE_SET_REPORT_SMKS  0x80000800
#define TAPE_DRIVE_ABSOLUTE_BLK     0x80001000
#define TAPE_DRIVE_ABS_BLK_IMMED    0x80002000
#define TAPE_DRIVE_LOGICAL_BLK      0x80004000
#define TAPE_DRIVE_LOG_BLK_IMMED    0x80008000
#define TAPE_DRIVE_END_OF_DATA      0x80010000
#define TAPE_DRIVE_RELATIVE_BLKS    0x80020000
#define TAPE_DRIVE_FILEMARKS        0x80040000
#define TAPE_DRIVE_SEQUENTIAL_FMKS  0x80080000
#define TAPE_DRIVE_SETMARKS         0x80100000
#define TAPE_DRIVE_SEQUENTIAL_SMKS  0x80200000
#define TAPE_DRIVE_REVERSE_POSITION 0x80400000
#define TAPE_DRIVE_SPACE_IMMEDIATE  0x80800000
#define TAPE_DRIVE_WRITE_SETMARKS   0x81000000
#define TAPE_DRIVE_WRITE_FILEMARKS  0x82000000
#define TAPE_DRIVE_WRITE_SHORT_FMKS 0x84000000
#define TAPE_DRIVE_WRITE_LONG_FMKS  0x88000000
#define TAPE_DRIVE_WRITE_MARK_IMMED 0x90000000
#define TAPE_DRIVE_FORMAT           0xA0000000
#define TAPE_DRIVE_FORMAT_IMMEDIATE 0xC0000000
#define TAPE_DRIVE_HIGH_FEATURES    0x80000000  //mask for high features flag

struct TAPE_GET_DRIVE_PARAMETERS {
  BOOLEAN ECC;
  BOOLEAN Compression;
  BOOLEAN DataPadding;
  BOOLEAN ReportSetmarks;
  DWORD DefaultBlockSize;
  DWORD MaximumBlockSize;
  DWORD MinimumBlockSize;
  DWORD MaximumPartitionCount;
  DWORD FeaturesLow;
  DWORD FeaturesHigh;
  DWORD EOTWarningZoneSize;
};

// IOCTL_TAPE_SET_DRIVE_PARAMETERS definitions
struct TAPE_SET_DRIVE_PARAMETERS {
  BOOLEAN ECC;
  BOOLEAN Compression;
  BOOLEAN DataPadding;
  BOOLEAN ReportSetmarks;
  DWORD EOTWarningZoneSize;
};

// IOCTL_TAPE_GET_MEDIA_PARAMETERS definitions
struct TAPE_GET_MEDIA_PARAMETERS {
  LARGE_INTEGER Capacity;
  LARGE_INTEGER Remaining;
  DWORD BlockSize;
  DWORD PartitionCount;
  BOOLEAN WriteProtected;
};

// IOCTL_TAPE_SET_MEDIA_PARAMETERS definitions
struct TAPE_SET_MEDIA_PARAMETERS {
  DWORD BlockSize;
};

// IOCTL_TAPE_CREATE_PARTITION definitions
#define TAPE_FIXED_PARTITIONS       0L
#define TAPE_SELECT_PARTITIONS      1L
#define TAPE_INITIATOR_PARTITIONS   2L

struct TAPE_CREATE_PARTITION {
  DWORD Method;
  DWORD Count;
  DWORD Size;
};

// WMI Methods
#define TAPE_QUERY_DRIVE_PARAMETERS       0L
#define TAPE_QUERY_MEDIA_CAPACITY         1L
#define TAPE_CHECK_FOR_DRIVE_PROBLEM      2L
#define TAPE_QUERY_IO_ERROR_DATA          3L
#define TAPE_QUERY_DEVICE_ERROR_DATA      4L

struct TAPE_WMI_OPERATIONS {
  DWORD Method;
  DWORD DataBufferSize;
  dword DataBuffer;
};

// Type of drive errors
enum TAPE_DRIVE_PROBLEM_TYPE{
  TapeDriveProblemNone, TapeDriveReadWriteWarning,
  TapeDriveReadWriteError, TapeDriveReadWarning,
  TapeDriveWriteWarning, TapeDriveReadError,
  TapeDriveWriteError, TapeDriveHardwareError,
  TapeDriveUnsupportedMedia, TapeDriveScsiConnectionError,
  TapeDriveTimetoClean, TapeDriveCleanDriveNow,
  TapeDriveMediaLifeExpired, TapeDriveSnappedTape
};

#define ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION         1
#define ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION              2
#define ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION     3
#define ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION       4
#define ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION    5
#define ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION 6
#define ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION       7
#define ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE   8

#endif /* _WINNT_ */
