/*
The contents of this file are subject to the Mozilla Public License Version 1.1
(the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
specific language governing rights and limitations under the License.

The Original Code is Lepton.

The Initial Developer of the Original Code is Chauvin-Arnoux.
Portions created by Chauvin-Arnoux are Copyright (C) 2011. All Rights Reserved.

Alternatively, the contents of this file may be used under the terms of the eCos GPL license
(the  [eCos GPL] License), in which case the provisions of [eCos GPL] License are applicable
instead of those above. If you wish to allow use of your version of this file only under the
terms of the [eCos GPL] License and not to allow others to use your version of this file under
the MPL, indicate your decision by deleting  the provisions above and replace
them with the notice and other provisions required by the [eCos GPL] License.
If you do not delete the provisions above, a recipient may use your version of this file under
either the MPL or the [eCos GPL] License."
*/

#ifndef _WINNT_
#define _WINNT_

#ifdef __cplusplus
extern "C" {
#endif

//lepton patch
//WIN32
#ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
   #define _WCHAR_T_DEFINED
#endif

#ifndef _MAC
   #ifndef _WCTYPE_T_DEFINED
typedef wchar_t wint_t;
typedef wchar_t wctype_t;
      #define _WCTYPE_T_DEFINED
   #endif

   #ifndef WEOF
      #define WEOF (wint_t)(0xFFFF)
   #endif
#endif  /* ndef _MAC */
//WIN32
//#include "ctype/ctype.h"
#include  <ctype.h>
//endof lepton patch

#define ANYSIZE_ARRAY 1

#if defined(_M_MRX000) && !(defined(MIDL_PASS) || defined(RC_INVOKED)) && defined(ENABLE_RESTRICTED)
   #define RESTRICTED_POINTER __restrict
#else
   #define RESTRICTED_POINTER
#endif

#if defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) || (defined(_M_IA64) && \
   !defined(__ICL))
   #define UNALIGNED __unaligned
#else
   #define UNALIGNED
#endif

#if defined(_M_IA64) && defined(_GENIA64_)
   #define __ptr64
#endif

#if defined(_WIN64) || defined(_M_ALPHA)
   #define MAX_NATURAL_ALIGNMENT sizeof(ULONGLONG)
#else
   #define MAX_NATURAL_ALIGNMENT sizeof(DWORD)
#endif

//
// TYPE_ALIGNMENT will return the alignment requirements of a given type for
// the current platform.
//

#ifndef __cplusplus

   #pragma warning(disable:4116)
   #define TYPE_ALIGNMENT( t ) \
   FIELD_OFFSET( struct { char x; t test; }, test )

#endif

//
// C_ASSERT() can be used to perform many compile-time assertions:
//            type sizes, field offsets, etc.
//
// An assertion failure results in error C2118: negative subscript.
//

#define C_ASSERT(e) typedef char __C_ASSERT__[(e) ? 1 : -1]

#if !defined(_MAC) && (defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_IA64)) && (_MSC_VER >= \
                                                                                        1100) && \
   !(defined(MIDL_PASS) || defined(RC_INVOKED))
   #define POINTER_64 __ptr64
typedef unsigned __int64 POINTER_64_INT;
   #if defined(_AXP64_)
      #define POINTER_32 __ptr32
   #else
      #define POINTER_32
   #endif
#else
   #if defined(_MAC) && defined(_MAC_INT_64)
      #define POINTER_64 __ptr64
typedef unsigned __int64 POINTER_64_INT;
   #else
      #define POINTER_64
typedef unsigned long POINTER_64_INT;
   #endif
   #define POINTER_32
#endif

#include <basetsd.h>


#if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC) || \
   defined(_M_IA64)) && !defined(MIDL_PASS)
   #define DECLSPEC_IMPORT __declspec(dllimport)
#else
   #define DECLSPEC_IMPORT
#endif

#if (_MSC_VER >= 1200)
   #define DECLSPEC_NORETURN __declspec(noreturn)
#else
   #define DECLSPEC_NORETURN
#endif

typedef void *PVOID;
typedef void * POINTER_64 PVOID64;


#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
   #define NTAPI __stdcall
#else
   #define _cdecl
   #define NTAPI
#endif

//
// Define API decoration for direct importing system DLL references.
//

#if !defined(_NTSYSTEM_)
   #define NTSYSAPI DECLSPEC_IMPORT
#else
   #define NTSYSAPI
#endif


//
// Basics
//

#ifndef VOID
   #define VOID void
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
#endif

//
// UNICODE (Wide Character) types
//

#ifndef _MAC
typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR;    // wc,   16-bit UNICODE character
#endif

typedef WCHAR *PWCHAR;
typedef WCHAR *LPWCH, *PWCH;
typedef CONST WCHAR *LPCWCH, *PCWCH;
typedef WCHAR *NWPSTR;
typedef WCHAR *LPWSTR, *PWSTR;

typedef CONST WCHAR *LPCWSTR, *PCWSTR;

//
// ANSI (Multi-byte Character) types
//
typedef CHAR *PCHAR;
typedef CHAR *LPCH, *PCH;

typedef CONST CHAR *LPCCH, *PCCH;
typedef CHAR *NPSTR;
typedef CHAR *LPSTR, *PSTR;
typedef CONST CHAR *LPCSTR, *PCSTR;

//
// Neutral ANSI/UNICODE types and macros
//
#ifdef  UNICODE                     // r_winnt

   #ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE, *PTBYTE;
      #define _TCHAR_DEFINED
   #endif /* !_TCHAR_DEFINED */

typedef LPWSTR LPTCH, PTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR LPCTSTR;
typedef LPWSTR LP;
   #define __TEXT(quote) L ## quote   // r_winnt

#else /* UNICODE */                 // r_winnt

   #ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE, *PTBYTE;
      #define _TCHAR_DEFINED
   #endif /* !_TCHAR_DEFINED */

typedef LPSTR LPTCH, PTCH;
typedef LPSTR PTSTR, LPTSTR;
typedef LPCSTR LPCTSTR;
   #define __TEXT(quote) quote      // r_winnt

#endif /* UNICODE */                // r_winnt
#define TEXT(quote) __TEXT(quote)   // r_winnt


typedef SHORT *PSHORT;
typedef LONG *PLONG;

#ifdef STRICT
typedef void *HANDLE;
   #define DECLARE_HANDLE(name) struct name ## __ { int unused; }; typedef struct name ## __ *name
#else
typedef PVOID HANDLE;
   #define DECLARE_HANDLE(name) typedef HANDLE name
#endif
typedef HANDLE *PHANDLE;

//
// Flag (bit) fields
//

typedef BYTE FCHAR;
typedef WORD FSHORT;
typedef DWORD FLONG;

// Component Object Model defines, and macros

#ifndef _HRESULT_DEFINED
   #define _HRESULT_DEFINED
typedef LONG HRESULT;

#endif // !_HRESULT_DEFINED

#ifdef __cplusplus
   #define EXTERN_C    extern "C"
#else
   #define EXTERN_C    extern
#endif

#if defined(_WIN32) || defined(_MPPC_)

// Win32 doesn't support __export

   #ifdef _68K_
      #define STDMETHODCALLTYPE       __cdecl
   #else
      #define STDMETHODCALLTYPE       __stdcall
   #endif
   #define STDMETHODVCALLTYPE      __cdecl

   #define STDAPICALLTYPE          __stdcall
   #define STDAPIVCALLTYPE         __cdecl

#else

   #define STDMETHODCALLTYPE       __export __stdcall
   #define STDMETHODVCALLTYPE      __export __cdecl

   #define STDAPICALLTYPE          __export __stdcall
   #define STDAPIVCALLTYPE         __export __cdecl

#endif


#define STDAPI                  EXTERN_C HRESULT STDAPICALLTYPE
#define STDAPI_(type)           EXTERN_C type STDAPICALLTYPE

#define STDMETHODIMP            HRESULT STDMETHODCALLTYPE
#define STDMETHODIMP_(type)     type STDMETHODCALLTYPE

// The 'V' versions allow Variable Argument lists.

#define STDAPIV                 EXTERN_C HRESULT STDAPIVCALLTYPE
#define STDAPIV_(type)          EXTERN_C type STDAPIVCALLTYPE

#define STDMETHODIMPV           HRESULT STDMETHODVCALLTYPE
#define STDMETHODIMPV_(type)    type STDMETHODVCALLTYPE

typedef char CCHAR;
typedef DWORD LCID;
typedef PDWORD PLCID;
typedef WORD LANGID;
/*lint -e624 */
/*lint +e624 */
#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
//

// *** TBD **** when compiler support is available:
// typedef __float80 FLOAT128;
// For we define a 128 bit structure and use force_align pragma to
// align to 128 bits.
//

typedef struct _FLOAT128 {
   __int64 LowPart;
   __int64 HighPart;
} FLOAT128;

typedef FLOAT128 *PFLOAT128;


#if defined(_M_IA64)

   #pragma force_align _FLOAT128 16

#endif // _M_IA64


//
// __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 _ULONGLONG_
#if (!defined (_MAC) && (!defined(MIDL_PASS) || defined(__midl)) && (!defined(_M_IX86) || \
   (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)))
typedef __int64 LONGLONG;
typedef unsigned __int64 ULONGLONG;

   #define MAXLONGLONG                      (0x7fffffffffffffff)
#else

   #if defined(_MAC) && defined(_MAC_INT_64)
typedef __int64 LONGLONG;
typedef unsigned __int64 ULONGLONG;

      #define MAXLONGLONG                      (0x7fffffffffffffff)
   #else
typedef double LONGLONG;
typedef double ULONGLONG;
   #endif //_MAC and int64

#endif

typedef LONGLONG *PLONGLONG;
typedef ULONGLONG *PULONGLONG;

// Update Sequence Number

typedef LONGLONG USN;

#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
   struct {
      DWORD LowPart;
      LONG HighPart;
   };
   struct {
      DWORD LowPart;
      LONG HighPart;
   } u;
#endif //MIDL_PASS
   LONGLONG QuadPart;
} LARGE_INTEGER;

typedef LARGE_INTEGER *PLARGE_INTEGER;


#if defined(MIDL_PASS)
typedef struct _ULARGE_INTEGER {
#else // MIDL_PASS
typedef union _ULARGE_INTEGER {
   struct {
      DWORD LowPart;
      DWORD HighPart;
   };
   struct {
      DWORD LowPart;
      DWORD HighPart;
   } u;
#endif //MIDL_PASS
   ULONGLONG QuadPart;
} ULARGE_INTEGER;

typedef ULARGE_INTEGER *PULARGE_INTEGER;

// end_ntminiport end_ntndis end_ntminitape


//
// Locally Unique Identifier
//

typedef struct _LUID {
   DWORD LowPart;
   LONG HighPart;
} LUID, *PLUID;

#define _DWORDLONG_
typedef ULONGLONG DWORDLONG;
typedef DWORDLONG *PDWORDLONG;


//
// Define operations to logically shift an int64 by 0..31 bits and to multiply
// 32-bits by 32-bits to form a 64-bit product.
//

#if defined(MIDL_PASS) || defined(RC_INVOKED)

//
// Midl does not understand inline assembler. Therefore, the Rtl functions
// are used for shifts by 0.31 and multiplies of 32-bits times 32-bits to
// form a 64-bit product.
//

   #define Int32x32To64(a, b) ((LONGLONG)((LONG)(a)) * (LONGLONG)((LONG)(b)))
   #define UInt32x32To64(a, b) ((ULONGLONG)((DWORD)(a)) * (ULONGLONG)((DWORD)(b)))

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

#elif defined(_M_MRX000)

//
// MIPS uses intrinsic functions to perform shifts by 0..31 and multiplies of
// 32-bits times 32-bits to 64-bits.
//

   #define Int32x32To64 __emul
   #define UInt32x32To64 __emulu

   #define Int64ShllMod32 __ll_lshift
   #define Int64ShraMod32 __ll_rshift
   #define Int64ShrlMod32 __ull_rshift

   #if defined (__cplusplus)
extern "C" {
   #endif

LONGLONG
NTAPI
Int32x32To64 (
   LONG Multiplier,
   LONG Multiplicand
   );

ULONGLONG
NTAPI
UInt32x32To64 (
   DWORD Multiplier,
   DWORD Multiplicand
   );

ULONGLONG
NTAPI
Int64ShllMod32 (
   ULONGLONG Value,
   DWORD ShiftCount
   );

LONGLONG
NTAPI
Int64ShraMod32 (
   LONGLONG Value,
   DWORD ShiftCount
   );

ULONGLONG
NTAPI
Int64ShrlMod32 (
   ULONGLONG Value,
   DWORD ShiftCount
   );

   #if defined (__cplusplus)
};
   #endif

   #pragma intrinsic(__emul)
   #pragma intrinsic(__emulu)

   #pragma intrinsic(__ll_lshift)
   #pragma intrinsic(__ll_rshift)
   #pragma intrinsic(__ull_rshift)

#elif defined(_M_IX86)

//
// The x86 C compiler understands inline assembler. Therefore, inline functions
// that employ inline assembler are used for shifts of 0..31.  The multiplies
// rely on the compiler recognizing the cast of the multiplicand to int64 to
// generate the optimal code inline.
//

   #define Int32x32To64( a, b ) (LONGLONG)((LONGLONG)(LONG)(a) * (LONG)(b))
   #define UInt32x32To64( a, b ) (ULONGLONG)((ULONGLONG)(DWORD)(a) * (DWORD)(b))

ULONGLONG
NTAPI
Int64ShllMod32 (
   ULONGLONG Value,
   DWORD ShiftCount
   );

LONGLONG
NTAPI
Int64ShraMod32 (
   LONGLONG Value,
   DWORD ShiftCount
   );

ULONGLONG
NTAPI
Int64ShrlMod32 (
   ULONGLONG Value,
   DWORD ShiftCount
   );

   #pragma warning(disable:4035) // re-enable below

__inline ULONGLONG
NTAPI
Int64ShllMod32 (
   ULONGLONG Value,
   DWORD ShiftCount
   )
{
   __asm    {
      mov ecx, ShiftCount
      mov eax, dword ptr [Value]
      mov edx, dword ptr [Value+4]
      shld edx, eax, cl
      shl eax, cl
   }
}

__inline LONGLONG
NTAPI
Int64ShraMod32 (
   LONGLONG Value,
   DWORD ShiftCount
   )
{
   __asm {
      mov ecx, ShiftCount
      mov eax, dword ptr [Value]
      mov edx, dword ptr [Value+4]
      shrd eax, edx, cl
      sar edx, cl
   }
}

__inline ULONGLONG
NTAPI
Int64ShrlMod32 (
   ULONGLONG Value,
   DWORD ShiftCount
   )
{
   __asm    {
      mov ecx, ShiftCount
      mov eax, dword ptr [Value]
      mov edx, dword ptr [Value+4]
      shrd eax, edx, cl
      shr edx, cl
   }
}

   #pragma warning(default:4035)

#elif defined(_M_ALPHA)

//
// Alpha has native 64-bit operations that are just as fast as their 32-bit
// counter parts. Therefore, the int64 data type is used directly to form
// shifts of 0..31 and multiplies of 32-bits times 32-bits to form a 64-bit
// product.
//

   #define Int32x32To64(a, b) ((LONGLONG)((LONG)(a)) * (LONGLONG)((LONG)(b)))
   #define UInt32x32To64(a, b) ((ULONGLONG)((DWORD)(a)) * (ULONGLONG)((DWORD)(b)))

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


#elif defined(_M_PPC)

   #define Int32x32To64(a, b) ((LONGLONG)((LONG)(a)) * (LONGLONG)((LONG)(b)))
   #define UInt32x32To64(a, b) ((ULONGLONG)((DWORD)(a)) * (ULONGLONG)((DWORD)(b)))

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

#elif defined(_68K_) || defined(_MPPC_)

//
// The Macintosh 68K and PowerPC compilers do not currently support int64.
//

   #define Int32x32To64(a, b) ((LONGLONG)((LONG)(a)) * (LONGLONG)((LONG)(b)))
   #define UInt32x32To64(a, b) ((DWORDLONG)((DWORD)(a)) * (DWORDLONG)((DWORD)(b)))

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

#elif defined(_M_IA64)

//
// IA64 has native 64-bit operations that are just as fast as their 32-bit
// counter parts. Therefore, the int64 data type is used directly to form
// shifts of 0..31 and multiplies of 32-bits times 32-bits to form a 64-bit
// product.
//

   #define Int32x32To64(a, b) ((LONGLONG)((LONG)(a)) * (LONGLONG)((LONG)(b)))
   #define UInt32x32To64(a, b) ((ULONGLONG)((DWORD)(a)) * (ULONGLONG)((DWORD)(b)))

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

#else

   #error Must define a target architecture.

#endif

#define ANSI_NULL ((CHAR)0)
#define UNICODE_NULL ((WCHAR)0)
typedef BYTE BOOLEAN;
typedef BOOLEAN *PBOOLEAN;
//
//  Doubly linked list structure.  Can be used as either a list head, or
//  as link words.
//

typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;

//
//  Singly linked list structure. Can be used as either a list head, or
//  as link words.
//

typedef struct _SINGLE_LIST_ENTRY {
   struct _SINGLE_LIST_ENTRY *Next;
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;

//
// Base data structures for OLE support
//

#ifndef GUID_DEFINED
   #define GUID_DEFINED

typedef struct _GUID {          // size is 16
   DWORD Data1;
   WORD Data2;
   WORD Data3;
   BYTE Data4[8];
} GUID;

#endif // !GUID_DEFINED

#ifndef __OBJECTID_DEFINED
   #define __OBJECTID_DEFINED

typedef struct  _OBJECTID {     // size is 20
   GUID Lineage;
   DWORD Uniquifier;
} OBJECTID;
#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)    ((LONG)(INT_PTR)&(((type *)0)->field))


//
// Calculate the address of the base of the structure given its type, and an
// address of a field within the structure.
//

#define CONTAINING_RECORD(address, type, field) ((type *)( \
                                                    (PCHAR)(address) - \
                                                    (UINT_PTR)(&((type *)0)->field)))


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

//
//  Primary language IDs.
//

#define LANG_NEUTRAL                     0x00

#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_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_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_LATVIAN                     0x26
#define LANG_LITHUANIAN                  0x27
#define LANG_MACEDONIAN                  0x2f
#define LANG_MALAY                       0x3e
#define LANG_MALAYALAM                   0x4c
#define LANG_MANIPURI                    0x58
#define LANG_MARATHI                     0x4e
#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_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 Region)
#define SUBLANG_CHINESE_SIMPLIFIED       0x02    // Chinese (PR China)
#define SUBLANG_CHINESE_HONGKONG         0x03    // Chinese (Hong Kong)
#define SUBLANG_CHINESE_SINGAPORE        0x04    // Chinese (Singapore)
#define SUBLANG_CHINESE_MACAU            0x05    // Chinese (Macau)
#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_INDIA           0x02    // Kashmiri (India)
#define SUBLANG_KOREAN                   0x01    // Korean (Extended Wansung)
#define SUBLANG_LITHUANIAN               0x01    // Lithuanian
#define SUBLANG_LITHUANIAN_CLASSIC       0x02    // Lithuanian (Classic)
#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)       ((((WORD  )(s)) << 10) | (WORD  )(p))
#define PRIMARYLANGID(lgid)    ((WORD  )(lgid) & 0x3ff)
#define SUBLANGID(lgid)        ((WORD  )(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)  ((DWORD)((((DWORD)((WORD  )(srtid))) << 16) |  \
                                        ((DWORD)((WORD  )(lgid)))))
#define MAKESORTLCID(lgid, srtid, ver)                                            \
   ((DWORD)((MAKELCID(lgid, srtid)) |             \
            (((DWORD)((WORD  )(ver))) << 20)))
#define LANGIDFROMLCID(lcid)   ((WORD  )(lcid))
#define SORTIDFROMLCID(lcid)   ((WORD  )((((DWORD)(lcid)) >> 16) & 0xf))
#define SORTVERSIONFROMLCID(lcid)  ((WORD  )((((DWORD)(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))


// begin_ntminiport begin_ntndis begin_ntminitape

//
// Macros used to eliminate compiler warning generated when formal
// parameters or local variables are not declared.
//
// Use DBG_UNREFERENCED_PARAMETER() when a parameter is not yet
// referenced but will be once the module is completely developed.
//
// Use DBG_UNREFERENCED_LOCAL_VARIABLE() when a local variable is not yet
// referenced but will be once the module is completely developed.
//
// Use UNREFERENCED_PARAMETER() if a parameter will never be referenced.
//
// DBG_UNREFERENCED_PARAMETER and DBG_UNREFERENCED_LOCAL_VARIABLE will
// eventually be made into a null macro to help determine whether there
// is unfinished work.
//

#if !(defined(lint) || defined(_lint))
   #define UNREFERENCED_PARAMETER(P)          (P)
   #define DBG_UNREFERENCED_PARAMETER(P)      (P)
   #define DBG_UNREFERENCED_LOCAL_VARIABLE(V) (V)

#else // lint or _lint

// Note: lint -e530 says don't complain about uninitialized variables for
// this.  line +e530 turns that checking back on.  Error 527 has to do with
// unreachable code.

   #define UNREFERENCED_PARAMETER(P)          \
   /*lint -e527 -e530 */ \
   { \
      (P) = (P); \
   } \
   /*lint +e527 +e530 */
   #define DBG_UNREFERENCED_PARAMETER(P)      \
   /*lint -e527 -e530 */ \
   { \
      (P) = (P); \
   } \
   /*lint +e527 +e530 */
   #define DBG_UNREFERENCED_LOCAL_VARIABLE(V) \
   /*lint -e527 -e530 */ \
   { \
      (V) = (V); \
   } \
   /*lint +e527 +e530 */

#endif // lint or _lint


#ifndef WIN32_NO_STATUS
/*lint -save -e767 */
   #define STATUS_WAIT_0                    ((DWORD   )0x00000000L)
   #define STATUS_ABANDONED_WAIT_0          ((DWORD   )0x00000080L)
   #define STATUS_USER_APC                  ((DWORD   )0x000000C0L)
   #define STATUS_TIMEOUT                   ((DWORD   )0x00000102L)
   #define STATUS_PENDING                   ((DWORD   )0x00000103L)
   #define STATUS_SEGMENT_NOTIFICATION      ((DWORD   )0x40000005L)
   #define STATUS_GUARD_PAGE_VIOLATION      ((DWORD   )0x80000001L)
   #define STATUS_DATATYPE_MISALIGNMENT     ((DWORD   )0x80000002L)
   #define STATUS_BREAKPOINT                ((DWORD   )0x80000003L)
   #define STATUS_SINGLE_STEP               ((DWORD   )0x80000004L)
   #define STATUS_ACCESS_VIOLATION          ((DWORD   )0xC0000005L)
   #define STATUS_IN_PAGE_ERROR             ((DWORD   )0xC0000006L)
   #define STATUS_INVALID_HANDLE            ((DWORD   )0xC0000008L)
   #define STATUS_NO_MEMORY                 ((DWORD   )0xC0000017L)
   #define STATUS_ILLEGAL_INSTRUCTION       ((DWORD   )0xC000001DL)
   #define STATUS_NONCONTINUABLE_EXCEPTION  ((DWORD   )0xC0000025L)
   #define STATUS_INVALID_DISPOSITION       ((DWORD   )0xC0000026L)
   #define STATUS_ARRAY_BOUNDS_EXCEEDED     ((DWORD   )0xC000008CL)
   #define STATUS_FLOAT_DENORMAL_OPERAND    ((DWORD   )0xC000008DL)
   #define STATUS_FLOAT_DIVIDE_BY_ZERO      ((DWORD   )0xC000008EL)
   #define STATUS_FLOAT_INEXACT_RESULT      ((DWORD   )0xC000008FL)
   #define STATUS_FLOAT_INVALID_OPERATION   ((DWORD   )0xC0000090L)
   #define STATUS_FLOAT_OVERFLOW            ((DWORD   )0xC0000091L)
   #define STATUS_FLOAT_STACK_CHECK         ((DWORD   )0xC0000092L)
   #define STATUS_FLOAT_UNDERFLOW           ((DWORD   )0xC0000093L)
   #define STATUS_INTEGER_DIVIDE_BY_ZERO    ((DWORD   )0xC0000094L)
   #define STATUS_INTEGER_OVERFLOW          ((DWORD   )0xC0000095L)
   #define STATUS_PRIVILEGED_INSTRUCTION    ((DWORD   )0xC0000096L)
   #define STATUS_STACK_OVERFLOW            ((DWORD   )0xC00000FDL)
   #define STATUS_CONTROL_C_EXIT            ((DWORD   )0xC000013AL)
   #define STATUS_FLOAT_MULTIPLE_FAULTS     ((DWORD   )0xC00002B4L)
   #define STATUS_FLOAT_MULTIPLE_TRAPS      ((DWORD   )0xC00002B5L)
   #define STATUS_ILLEGAL_VLM_REFERENCE     ((DWORD   )0xC00002C0L)
/*lint -restore */
#endif
#define MAXIMUM_WAIT_OBJECTS 64     // Maximum number of wait objects

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

typedef UINT_PTR KSPIN_LOCK;
typedef KSPIN_LOCK *PKSPIN_LOCK;

//
// Define function to return the current Thread Environment Block
//

#ifdef _ALPHA_                          // winnt
void *_rdteb(void);                     // winnt
   #if defined(_M_ALPHA)                // winnt
      #pragma intrinsic(_rdteb) // winnt
   #endif                               // winnt
#endif                                  // winnt

#if defined(_M_ALPHA)
   #define NtCurrentTeb() ((struct _TEB *)_rdteb())
#else
struct _TEB *
NtCurrentTeb(void);
#endif

//
// Define functions to get the address of the current fiber and the
// current fiber data.
//

#ifdef _ALPHA_

   #define GetCurrentFiber() (((PNT_TIB)NtCurrentTeb())->FiberData)
   #define GetFiberData() (*(PVOID *)(GetCurrentFiber()))

// begin_ntddk begin_nthal
//
// The following flags control the contents of the CONTEXT structure.
//

   #if !defined(RC_INVOKED)

      #define CONTEXT_PORTABLE_32BIT     0x00100000
      #define CONTEXT_ALPHA              0x00020000

      #define CONTEXT_CONTROL         (CONTEXT_ALPHA | 0x00000001L)
      #define CONTEXT_FLOATING_POINT  (CONTEXT_ALPHA | 0x00000002L)
      #define CONTEXT_INTEGER         (CONTEXT_ALPHA | 0x00000004L)

      #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)

   #endif

   #ifndef _PORTABLE_32BIT_CONTEXT

//
// Context Frame
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) it is used to construct a call frame for APC delivery,
//  3) it is used to construct a call frame for exception dispatching
//  in user mode, 4) it is used in the user level thread creation
//  routines, and 5) it is used to to pass thread state to debuggers.
//
//  N.B. Because this record is used as a call frame, it must be EXACTLY
//  a multiple of 16 bytes in length.
//
//  There are two variations of the context structure. This is the real one.
//

typedef struct _CONTEXT {

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_FLOATING_POINT.
   //

   ULONGLONG FltF0;
   ULONGLONG FltF1;
   ULONGLONG FltF2;
   ULONGLONG FltF3;
   ULONGLONG FltF4;
   ULONGLONG FltF5;
   ULONGLONG FltF6;
   ULONGLONG FltF7;
   ULONGLONG FltF8;
   ULONGLONG FltF9;
   ULONGLONG FltF10;
   ULONGLONG FltF11;
   ULONGLONG FltF12;
   ULONGLONG FltF13;
   ULONGLONG FltF14;
   ULONGLONG FltF15;
   ULONGLONG FltF16;
   ULONGLONG FltF17;
   ULONGLONG FltF18;
   ULONGLONG FltF19;
   ULONGLONG FltF20;
   ULONGLONG FltF21;
   ULONGLONG FltF22;
   ULONGLONG FltF23;
   ULONGLONG FltF24;
   ULONGLONG FltF25;
   ULONGLONG FltF26;
   ULONGLONG FltF27;
   ULONGLONG FltF28;
   ULONGLONG FltF29;
   ULONGLONG FltF30;
   ULONGLONG FltF31;

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_INTEGER.
   //
   // N.B. The registers gp, sp, and ra are defined in this section, but are
   //  considered part of the control context rather than part of the integer
   //  context.
   //

   ULONGLONG IntV0;     //  $0: return value register, v0
   ULONGLONG IntT0;     //  $1: temporary registers, t0 - t7
   ULONGLONG IntT1;     //  $2:
   ULONGLONG IntT2;     //  $3:
   ULONGLONG IntT3;     //  $4:
   ULONGLONG IntT4;     //  $5:
   ULONGLONG IntT5;     //  $6:
   ULONGLONG IntT6;     //  $7:
   ULONGLONG IntT7;     //  $8:
   ULONGLONG IntS0;     //  $9: nonvolatile registers, s0 - s5
   ULONGLONG IntS1;     // $10:
   ULONGLONG IntS2;     // $11:
   ULONGLONG IntS3;     // $12:
   ULONGLONG IntS4;     // $13:
   ULONGLONG IntS5;     // $14:
   ULONGLONG IntFp;     // $15: frame pointer register, fp/s6
   ULONGLONG IntA0;     // $16: argument registers, a0 - a5
   ULONGLONG IntA1;     // $17:
   ULONGLONG IntA2;     // $18:
   ULONGLONG IntA3;     // $19:
   ULONGLONG IntA4;     // $20:
   ULONGLONG IntA5;     // $21:
   ULONGLONG IntT8;     // $22: temporary registers, t8 - t11
   ULONGLONG IntT9;     // $23:
   ULONGLONG IntT10;    // $24:
   ULONGLONG IntT11;    // $25:
   ULONGLONG IntRa;     // $26: return address register, ra
   ULONGLONG IntT12;    // $27: temporary register, t12
   ULONGLONG IntAt;     // $28: assembler temp register, at
   ULONGLONG IntGp;     // $29: global pointer register, gp
   ULONGLONG IntSp;     // $30: stack pointer register, sp
   ULONGLONG IntZero;   // $31: zero register, zero

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_FLOATING_POINT.
   //

   ULONGLONG Fpcr;      // floating point control register
   ULONGLONG SoftFpcr;  // software extension to FPCR

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_CONTROL.
   //
   // N.B. The registers gp, sp, and ra are defined in the integer section,
   //   but are considered part of the control context rather than part of
   //   the integer context.
   //

   ULONGLONG Fir;       // (fault instruction) continuation address
   DWORD Psr;           // processor status

   //
   // 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 thread's 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;
   DWORD Fill[4];       // padding for 16-byte stack frame alignment

} CONTEXT, *PCONTEXT;

   #else

//
// 32-bit Context Frame
//
//  This alternate version of the Alpha context structure parallels that
//  of MIPS and IX86 in style for the first 64 entries: 32-bit machines
//  can operate on the fields, and a value declared as a pointer to an
//  array of int's can be used to index into the fields.  This makes life
//  with windbg and ntsd vastly easier.
//
//  There are two parts: the first contains the lower 32-bits of each
//  element in the 64-bit definition above.  The second part contains
//  the upper 32-bits of each 64-bit element above.
//
//  The names in the first part are identical to the 64-bit names.
//  The second part names are prefixed with "High".
//
//  1st half: at 32 bits each, (containing the low parts of 64-bit values)
//      32 floats, 32 ints, fpcrs, fir, psr, contextflags
//  2nd half: at 32 bits each
//      32 floats, 32 ints, fpcrs, fir, fill
//
//  There is no external support for the 32-bit version of the context
//  structure.  It is only used internally by windbg and ntsd.
//
//  This structure must be the same size as the 64-bit version above.
//

typedef struct _CONTEXT {

   DWORD FltF0;
   DWORD FltF1;
   DWORD FltF2;
   DWORD FltF3;
   DWORD FltF4;
   DWORD FltF5;
   DWORD FltF6;
   DWORD FltF7;
   DWORD FltF8;
   DWORD FltF9;
   DWORD FltF10;
   DWORD FltF11;
   DWORD FltF12;
   DWORD FltF13;
   DWORD FltF14;
   DWORD FltF15;
   DWORD FltF16;
   DWORD FltF17;
   DWORD FltF18;
   DWORD FltF19;
   DWORD FltF20;
   DWORD FltF21;
   DWORD FltF22;
   DWORD FltF23;
   DWORD FltF24;
   DWORD FltF25;
   DWORD FltF26;
   DWORD FltF27;
   DWORD FltF28;
   DWORD FltF29;
   DWORD FltF30;
   DWORD FltF31;

   DWORD IntV0;         //  $0: return value register, v0
   DWORD IntT0;         //  $1: temporary registers, t0 - t7
   DWORD IntT1;         //  $2:
   DWORD IntT2;         //  $3:
   DWORD IntT3;         //  $4:
   DWORD IntT4;         //  $5:
   DWORD IntT5;         //  $6:
   DWORD IntT6;         //  $7:
   DWORD IntT7;         //  $8:
   DWORD IntS0;         //  $9: nonvolatile registers, s0 - s5
   DWORD IntS1;         // $10:
   DWORD IntS2;         // $11:
   DWORD IntS3;         // $12:
   DWORD IntS4;         // $13:
   DWORD IntS5;         // $14:
   DWORD IntFp;         // $15: frame pointer register, fp/s6
   DWORD IntA0;         // $16: argument registers, a0 - a5
   DWORD IntA1;         // $17:
   DWORD IntA2;         // $18:
   DWORD IntA3;         // $19:
   DWORD IntA4;         // $20:
   DWORD IntA5;         // $21:
   DWORD IntT8;         // $22: temporary registers, t8 - t11
   DWORD IntT9;         // $23:
   DWORD IntT10;        // $24:
   DWORD IntT11;        // $25:
   DWORD IntRa;         // $26: return address register, ra
   DWORD IntT12;        // $27: temporary register, t12
   DWORD IntAt;         // $28: assembler temp register, at
   DWORD IntGp;         // $29: global pointer register, gp
   DWORD IntSp;         // $30: stack pointer register, sp
   DWORD IntZero;       // $31: zero register, zero

   DWORD Fpcr;          // floating point control register
   DWORD SoftFpcr;      // software extension to FPCR

   DWORD Fir;           // (fault instruction) continuation address

   DWORD Psr;           // processor status
   DWORD ContextFlags;

   //
   // Beginning of the "second half".
   // The name "High" parallels the HighPart of a LargeInteger.
   //

   DWORD HighFltF0;
   DWORD HighFltF1;
   DWORD HighFltF2;
   DWORD HighFltF3;
   DWORD HighFltF4;
   DWORD HighFltF5;
   DWORD HighFltF6;
   DWORD HighFltF7;
   DWORD HighFltF8;
   DWORD HighFltF9;
   DWORD HighFltF10;
   DWORD HighFltF11;
   DWORD HighFltF12;
   DWORD HighFltF13;
   DWORD HighFltF14;
   DWORD HighFltF15;
   DWORD HighFltF16;
   DWORD HighFltF17;
   DWORD HighFltF18;
   DWORD HighFltF19;
   DWORD HighFltF20;
   DWORD HighFltF21;
   DWORD HighFltF22;
   DWORD HighFltF23;
   DWORD HighFltF24;
   DWORD HighFltF25;
   DWORD HighFltF26;
   DWORD HighFltF27;
   DWORD HighFltF28;
   DWORD HighFltF29;
   DWORD HighFltF30;
   DWORD HighFltF31;

   DWORD HighIntV0;         //  $0: return value register, v0
   DWORD HighIntT0;         //  $1: temporary registers, t0 - t7
   DWORD HighIntT1;         //  $2:
   DWORD HighIntT2;         //  $3:
   DWORD HighIntT3;         //  $4:
   DWORD HighIntT4;         //  $5:
   DWORD HighIntT5;         //  $6:
   DWORD HighIntT6;         //  $7:
   DWORD HighIntT7;         //  $8:
   DWORD HighIntS0;         //  $9: nonvolatile registers, s0 - s5
   DWORD HighIntS1;         // $10:
   DWORD HighIntS2;         // $11:
   DWORD HighIntS3;         // $12:
   DWORD HighIntS4;         // $13:
   DWORD HighIntS5;         // $14:
   DWORD HighIntFp;         // $15: frame pointer register, fp/s6
   DWORD HighIntA0;         // $16: argument registers, a0 - a5
   DWORD HighIntA1;         // $17:
   DWORD HighIntA2;         // $18:
   DWORD HighIntA3;         // $19:
   DWORD HighIntA4;         // $20:
   DWORD HighIntA5;         // $21:
   DWORD HighIntT8;         // $22: temporary registers, t8 - t11
   DWORD HighIntT9;         // $23:
   DWORD HighIntT10;        // $24:
   DWORD HighIntT11;        // $25:
   DWORD HighIntRa;         // $26: return address register, ra
   DWORD HighIntT12;        // $27: temporary register, t12
   DWORD HighIntAt;         // $28: assembler temp register, at
   DWORD HighIntGp;         // $29: global pointer register, gp
   DWORD HighIntSp;         // $30: stack pointer register, sp
   DWORD HighIntZero;       // $31: zero register, zero

   DWORD HighFpcr;          // floating point control register
   DWORD HighSoftFpcr;      // software extension to FPCR
   DWORD HighFir;           // processor status

   double DoNotUseThisField;  // to force quadword structure alignment
   DWORD HighFill[2];       // padding for 16-byte stack frame alignment

} CONTEXT, *PCONTEXT;

//
// These should name the fields in the _PORTABLE_32BIT structure
// that overlay the Psr and ContextFlags in the normal structure.
//

      #define _QUAD_PSR_OFFSET   HighSoftFpcr
      #define _QUAD_FLAGS_OFFSET HighFir

   #endif // _PORTABLE_32BIT_CONTEXT

// end_ntddk end_nthal

#endif // _ALPHA_


#ifdef _ALPHA_

VOID
__jump_unwind (
   PVOID VirtualFramePointer,
   PVOID TargetPc
   );

#endif // _ALPHA_


#ifdef _X86_

//
// Disable these two pramas that evaluate to "sti" "cli" on x86 so that driver
// writers to not leave them inadvertantly in their code.
//

   #if !defined(MIDL_PASS)
      #if !defined(RC_INVOKED)

         #pragma warning(disable:4164) // disable C4164 warning so that apps that
// build with /Od don't get weird errors !
         #ifdef _M_IX86
            #pragma function(_enable)
            #pragma function(_disable)
         #endif

         #pragma warning(default:4164) // reenable C4164 warning

      #endif
   #endif


   #if !defined(MIDL_PASS) && defined(_M_IX86)
      #pragma warning (disable:4035) // disable 4035 (function must return something)
_inline PVOID GetFiberData( void ) {
   __asm {
      mov eax, fs :[0x10]
      mov eax,[eax]
   }
}
_inline PVOID GetCurrentFiber( void ) {
   __asm mov eax, fs :[0x10]
}

      #pragma warning (default:4035) // Reenable it
   #endif

// begin_ntddk begin_wx86

//
//  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.
//

   #if !defined(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

typedef 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;
} FLOATING_SAVE_AREA;

typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;

//
// 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.
//

typedef 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];

} CONTEXT;



typedef CONTEXT *PCONTEXT;

// begin_ntminiport

#endif //_X86_


#ifndef _LDT_ENTRY_DEFINED
   #define _LDT_ENTRY_DEFINED

typedef 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;
} LDT_ENTRY, *PLDT_ENTRY;

#endif


#if defined(_MIPS_)

//
// Define functions to get the address of the current fiber and the
// current fiber data.
//

   #define GetCurrentFiber() ((*(PNT_TIB *)0x7ffff4a8)->FiberData)
   #define GetFiberData() (*(PVOID *)(GetCurrentFiber()))

// begin_ntddk begin_nthal
//
// The following flags control the contents of the CONTEXT structure.
//

   #if !defined(RC_INVOKED)

      #define CONTEXT_R4000   0x00010000 // r4000 context

      #define CONTEXT_CONTROL          (CONTEXT_R4000 | 0x00000001)
      #define CONTEXT_FLOATING_POINT   (CONTEXT_R4000 | 0x00000002)
      #define CONTEXT_INTEGER          (CONTEXT_R4000 | 0x00000004)
      #define CONTEXT_EXTENDED_FLOAT   (CONTEXT_FLOATING_POINT | 0x00000008)
      #define CONTEXT_EXTENDED_INTEGER (CONTEXT_INTEGER | 0x00000010)

      #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | \
                            CONTEXT_INTEGER | CONTEXT_EXTENDED_INTEGER)

   #endif

//
// Context Frame
//
//  N.B. This frame must be exactly a multiple of 16 bytes in length.
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) it is used to constuct a call frame for APC delivery,
//  3) it is used to construct a call frame for exception dispatching
//  in user mode, and 4) it is used in the user level thread creation
//  routines.
//
//  The layout of the record conforms to a standard call frame.
//

typedef struct _CONTEXT {

   //
   // This section is always present and is used as an argument build
   // area.
   //
   // N.B. Context records are 0 mod 8 aligned starting with NT 4.0.
   //

   union {
      DWORD Argument[4];
      ULONGLONG Alignment;
   };

   //
   // The following union defines the 32-bit and 64-bit register context.
   //

   union {

      //
      // 32-bit context.
      //

      struct {

         //
         // This section is specified/returned if the ContextFlags contains
         // the flag CONTEXT_FLOATING_POINT.
         //
         // N.B. This section contains the 16 double floating registers f0,
         //      f2, ..., f30.
         //

         DWORD FltF0;
         DWORD FltF1;
         DWORD FltF2;
         DWORD FltF3;
         DWORD FltF4;
         DWORD FltF5;
         DWORD FltF6;
         DWORD FltF7;
         DWORD FltF8;
         DWORD FltF9;
         DWORD FltF10;
         DWORD FltF11;
         DWORD FltF12;
         DWORD FltF13;
         DWORD FltF14;
         DWORD FltF15;
         DWORD FltF16;
         DWORD FltF17;
         DWORD FltF18;
         DWORD FltF19;
         DWORD FltF20;
         DWORD FltF21;
         DWORD FltF22;
         DWORD FltF23;
         DWORD FltF24;
         DWORD FltF25;
         DWORD FltF26;
         DWORD FltF27;
         DWORD FltF28;
         DWORD FltF29;
         DWORD FltF30;
         DWORD FltF31;

         //
         // This section is specified/returned if the ContextFlags contains
         // the flag CONTEXT_INTEGER.
         //
         // N.B. The registers gp, sp, and ra are defined in this section,
         //      but are considered part of the control context rather than
         //      part of the integer context.
         //
         // N.B. Register zero is not stored in the frame.
         //

         DWORD IntZero;
         DWORD IntAt;
         DWORD IntV0;
         DWORD IntV1;
         DWORD IntA0;
         DWORD IntA1;
         DWORD IntA2;
         DWORD IntA3;
         DWORD IntT0;
         DWORD IntT1;
         DWORD IntT2;
         DWORD IntT3;
         DWORD IntT4;
         DWORD IntT5;
         DWORD IntT6;
         DWORD IntT7;
         DWORD IntS0;
         DWORD IntS1;
         DWORD IntS2;
         DWORD IntS3;
         DWORD IntS4;
         DWORD IntS5;
         DWORD IntS6;
         DWORD IntS7;
         DWORD IntT8;
         DWORD IntT9;
         DWORD IntK0;
         DWORD IntK1;
         DWORD IntGp;
         DWORD IntSp;
         DWORD IntS8;
         DWORD IntRa;
         DWORD IntLo;
         DWORD IntHi;

         //
         // This section is specified/returned if the ContextFlags word contains
         // the flag CONTEXT_FLOATING_POINT.
         //

         DWORD Fsr;

         //
         // This section is specified/returned if the ContextFlags word contains
         // the flag CONTEXT_CONTROL.
         //
         // N.B. The registers gp, sp, and ra are defined in the integer section,
         //   but are considered part of the control context rather than part of
         //   the integer context.
         //

         DWORD Fir;
         DWORD Psr;

         //
         // 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 thread's 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;
      };

      //
      // 64-bit context.
      //

      struct {

         //
         // This section is specified/returned if the ContextFlags contains
         // the flag CONTEXT_EXTENDED_FLOAT.
         //
         // N.B. This section contains the 32 double floating registers f0,
         //      f1, ..., f31.
         //

         ULONGLONG XFltF0;
         ULONGLONG XFltF1;
         ULONGLONG XFltF2;
         ULONGLONG XFltF3;
         ULONGLONG XFltF4;
         ULONGLONG XFltF5;
         ULONGLONG XFltF6;
         ULONGLONG XFltF7;
         ULONGLONG XFltF8;
         ULONGLONG XFltF9;
         ULONGLONG XFltF10;
         ULONGLONG XFltF11;
         ULONGLONG XFltF12;
         ULONGLONG XFltF13;
         ULONGLONG XFltF14;
         ULONGLONG XFltF15;
         ULONGLONG XFltF16;
         ULONGLONG XFltF17;
         ULONGLONG XFltF18;
         ULONGLONG XFltF19;
         ULONGLONG XFltF20;
         ULONGLONG XFltF21;
         ULONGLONG XFltF22;
         ULONGLONG XFltF23;
         ULONGLONG XFltF24;
         ULONGLONG XFltF25;
         ULONGLONG XFltF26;
         ULONGLONG XFltF27;
         ULONGLONG XFltF28;
         ULONGLONG XFltF29;
         ULONGLONG XFltF30;
         ULONGLONG XFltF31;

         //
         // The following sections must exactly overlay the 32-bit context.
         //

         DWORD Fill1;
         DWORD Fill2;

         //
         // This section is specified/returned if the ContextFlags contains
         // the flag CONTEXT_FLOATING_POINT.
         //

         DWORD XFsr;

         //
         // This section is specified/returned if the ContextFlags contains
         // the flag CONTEXT_CONTROL.
         //
         // N.B. The registers gp, sp, and ra are defined in the integer
         //      section, but are considered part of the control context
         //      rather than part of the integer context.
         //

         DWORD XFir;
         DWORD XPsr;

         //
         // 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 thread's 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 XContextFlags;

         //
         // This section is specified/returned if the ContextFlags contains
         // the flag CONTEXT_EXTENDED_INTEGER.
         //
         // N.B. The registers gp, sp, and ra are defined in this section,
         //      but are considered part of the control context rather than
         //      part of the integer  context.
         //
         // N.B. Register zero is not stored in the frame.
         //

         ULONGLONG XIntZero;
         ULONGLONG XIntAt;
         ULONGLONG XIntV0;
         ULONGLONG XIntV1;
         ULONGLONG XIntA0;
         ULONGLONG XIntA1;
         ULONGLONG XIntA2;
         ULONGLONG XIntA3;
         ULONGLONG XIntT0;
         ULONGLONG XIntT1;
         ULONGLONG XIntT2;
         ULONGLONG XIntT3;
         ULONGLONG XIntT4;
         ULONGLONG XIntT5;
         ULONGLONG XIntT6;
         ULONGLONG XIntT7;
         ULONGLONG XIntS0;
         ULONGLONG XIntS1;
         ULONGLONG XIntS2;
         ULONGLONG XIntS3;
         ULONGLONG XIntS4;
         ULONGLONG XIntS5;
         ULONGLONG XIntS6;
         ULONGLONG XIntS7;
         ULONGLONG XIntT8;
         ULONGLONG XIntT9;
         ULONGLONG XIntK0;
         ULONGLONG XIntK1;
         ULONGLONG XIntGp;
         ULONGLONG XIntSp;
         ULONGLONG XIntS8;
         ULONGLONG XIntRa;
         ULONGLONG XIntLo;
         ULONGLONG XIntHi;
      };
   };
} CONTEXT, *PCONTEXT;

// end_ntddk end_nthal

   #define CONTEXT32_LENGTH 0x130       // The original 32-bit Context length (pre NT 4.0)

#endif // MIPS


#if defined(_MIPS_)

VOID
__jump_unwind (
   PVOID Fp,
   PVOID TargetPc
   );

#endif // MIPS


#if defined(_PPC_)


//
// The address of the TEB is placed into GPR 13 at context switch time
// and should never be destroyed.  To get the address of the TEB use
// the compiler intrinsic to access it directly from GPR 13.
//

   #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000)
unsigned __gregister_get( unsigned const regnum );
      #define NtCurrentTeb() ((struct _TEB *)__gregister_get(13))
   #elif defined(_M_PPC)
struct _TEB * __builtin_get_gpr13(VOID);
      #define NtCurrentTeb() ((struct _TEB *)__builtin_get_gpr13())
   #endif


//
// Define functions to get the address of the current fiber and the
// current fiber data.
//

   #define GetCurrentFiber() (((PNT_TIB)NtCurrentTeb())->FiberData)
   #define GetFiberData() (*(PVOID *)(GetCurrentFiber()))

// begin_ntddk begin_nthal
//
// The following flags control the contents of the CONTEXT structure.
//

   #if !defined(RC_INVOKED)

      #define CONTEXT_CONTROL         0x00000001L
      #define CONTEXT_FLOATING_POINT  0x00000002L
      #define CONTEXT_INTEGER         0x00000004L
      #define CONTEXT_DEBUG_REGISTERS 0x00000008L

      #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)

   #endif

//
// Context Frame
//
//  N.B. This frame must be exactly a multiple of 16 bytes in length.
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) it is used to constuct a call frame for APC delivery,
//  3) it is used to construct a call frame for exception dispatching
//  in user mode, and 4) it is used in the user level thread creation
//  routines.
//
//  Requires at least 8-byte alignment (double)
//

typedef struct _CONTEXT {

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_FLOATING_POINT.
   //

   double Fpr0;                         // Floating registers 0..31
   double Fpr1;
   double Fpr2;
   double Fpr3;
   double Fpr4;
   double Fpr5;
   double Fpr6;
   double Fpr7;
   double Fpr8;
   double Fpr9;
   double Fpr10;
   double Fpr11;
   double Fpr12;
   double Fpr13;
   double Fpr14;
   double Fpr15;
   double Fpr16;
   double Fpr17;
   double Fpr18;
   double Fpr19;
   double Fpr20;
   double Fpr21;
   double Fpr22;
   double Fpr23;
   double Fpr24;
   double Fpr25;
   double Fpr26;
   double Fpr27;
   double Fpr28;
   double Fpr29;
   double Fpr30;
   double Fpr31;
   double Fpscr;                        // Floating point status/control reg

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_INTEGER.
   //

   DWORD Gpr0;                          // General registers 0..31
   DWORD Gpr1;
   DWORD Gpr2;
   DWORD Gpr3;
   DWORD Gpr4;
   DWORD Gpr5;
   DWORD Gpr6;
   DWORD Gpr7;
   DWORD Gpr8;
   DWORD Gpr9;
   DWORD Gpr10;
   DWORD Gpr11;
   DWORD Gpr12;
   DWORD Gpr13;
   DWORD Gpr14;
   DWORD Gpr15;
   DWORD Gpr16;
   DWORD Gpr17;
   DWORD Gpr18;
   DWORD Gpr19;
   DWORD Gpr20;
   DWORD Gpr21;
   DWORD Gpr22;
   DWORD Gpr23;
   DWORD Gpr24;
   DWORD Gpr25;
   DWORD Gpr26;
   DWORD Gpr27;
   DWORD Gpr28;
   DWORD Gpr29;
   DWORD Gpr30;
   DWORD Gpr31;

   DWORD Cr;                            // Condition register
   DWORD Xer;                           // Fixed point exception register

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_CONTROL.
   //

   DWORD Msr;                           // Machine status register
   DWORD Iar;                           // Instruction address register
   DWORD Lr;                            // Link register
   DWORD Ctr;                           // Count register

   //
   // 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 thread's 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;

   DWORD Fill[3];                       // Pad out to multiple of 16 bytes

   //
   // 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;                           // Breakpoint Register 1
   DWORD Dr1;                           // Breakpoint Register 2
   DWORD Dr2;                           // Breakpoint Register 3
   DWORD Dr3;                           // Breakpoint Register 4
   DWORD Dr4;                           // Breakpoint Register 5
   DWORD Dr5;                           // Breakpoint Register 6
   DWORD Dr6;                           // Debug Status Register
   DWORD Dr7;                           // Debug Control Register

} CONTEXT, *PCONTEXT;

// end_ntddk end_nthal


//
// Stack frame header
//
//   Order of appearance in stack frame:
//      Header (six words)
//      Parameters (at least eight words)
//      Local variables
//      Saved GPRs
//      Saved FPRs
//
//   Minimum alignment is 8 bytes

typedef struct _STACK_FRAME_HEADER {    // GPR 1 points here
   DWORD BackChain;                     // Addr of previous frame
   DWORD GlueSaved1;                    // Used by glue code
   DWORD GlueSaved2;
   DWORD Reserved1;                     // Reserved
   DWORD Spare1;                        // Used by tracing, profiling, ...
   DWORD Spare2;

   DWORD Parameter0;                    // First 8 parameter words are
   DWORD Parameter1;                    //   always present
   DWORD Parameter2;
   DWORD Parameter3;
   DWORD Parameter4;
   DWORD Parameter5;
   DWORD Parameter6;
   DWORD Parameter7;

} STACK_FRAME_HEADER,*PSTACK_FRAME_HEADER;


VOID
__jump_unwind (
   PVOID Fp,
   PVOID TargetPc
   );

#endif // defined(_PPC_)

#if defined(_MPPC_)


//
// The address of the TEB is placed into GPR 13 at context switch time
// and should never be destroyed.  To get the address of the TEB use
// the compiler intrinsic to access it directly from GPR 13.
//

   #if defined(_M_PPC) && defined(_MSC_VER) && (_MSC_VER>=1000)
unsigned __gregister_get( unsigned const regnum );
      #define NtCurrentTeb() ((struct _TEB *)__gregister_get(13))
   #elif defined(_M_PPC)
struct _TEB * __builtin_get_gpr13(VOID);
      #define NtCurrentTeb() ((struct _TEB *)__builtin_get_gpr13())
   #endif


//
// Define functions to get the address of the current fiber and the
// current fiber data.
//

   #define GetCurrentFiber() (((PNT_TIB)NtCurrentTeb())->FiberData)
   #define GetFiberData() (*(PVOID *)(GetCurrentFiber()))

// begin_ntddk begin_nthal
//
// The following flags control the contents of the CONTEXT structure.
//

   #if !defined(RC_INVOKED)

      #define CONTEXT_CONTROL         0x00000001L
      #define CONTEXT_FLOATING_POINT  0x00000002L
      #define CONTEXT_INTEGER         0x00000004L
      #define CONTEXT_DEBUG_REGISTERS 0x00000008L

      #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)

   #endif

//
// Context Frame
//
//  N.B. This frame must be exactly a multiple of 16 bytes in length.
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) it is used to constuct a call frame for APC delivery,
//  3) it is used to construct a call frame for exception dispatching
//  in user mode, and 4) it is used in the user level thread creation
//  routines.
//
//  Requires at least 8-byte alignment (double)
//

typedef struct _CONTEXT {

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_FLOATING_POINT.
   //

   double Fpr0;                         // Floating registers 0..31
   double Fpr1;
   double Fpr2;
   double Fpr3;
   double Fpr4;
   double Fpr5;
   double Fpr6;
   double Fpr7;
   double Fpr8;
   double Fpr9;
   double Fpr10;
   double Fpr11;
   double Fpr12;
   double Fpr13;
   double Fpr14;
   double Fpr15;
   double Fpr16;
   double Fpr17;
   double Fpr18;
   double Fpr19;
   double Fpr20;
   double Fpr21;
   double Fpr22;
   double Fpr23;
   double Fpr24;
   double Fpr25;
   double Fpr26;
   double Fpr27;
   double Fpr28;
   double Fpr29;
   double Fpr30;
   double Fpr31;
   double Fpscr;                        // Floating point status/control reg

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_INTEGER.
   //

   DWORD Gpr0;                          // General registers 0..31
   DWORD Gpr1;
   DWORD Gpr2;
   DWORD Gpr3;
   DWORD Gpr4;
   DWORD Gpr5;
   DWORD Gpr6;
   DWORD Gpr7;
   DWORD Gpr8;
   DWORD Gpr9;
   DWORD Gpr10;
   DWORD Gpr11;
   DWORD Gpr12;
   DWORD Gpr13;
   DWORD Gpr14;
   DWORD Gpr15;
   DWORD Gpr16;
   DWORD Gpr17;
   DWORD Gpr18;
   DWORD Gpr19;
   DWORD Gpr20;
   DWORD Gpr21;
   DWORD Gpr22;
   DWORD Gpr23;
   DWORD Gpr24;
   DWORD Gpr25;
   DWORD Gpr26;
   DWORD Gpr27;
   DWORD Gpr28;
   DWORD Gpr29;
   DWORD Gpr30;
   DWORD Gpr31;

   DWORD Cr;                            // Condition register
   DWORD Xer;                           // Fixed point exception register

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_CONTROL.
   //

   DWORD Msr;                           // Machine status register
   DWORD Iar;                           // Instruction address register
   DWORD Lr;                            // Link register
   DWORD Ctr;                           // Count register

   //
   // 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 thread's 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;

   DWORD Fill[3];                       // Pad out to multiple of 16 bytes

   //
   // 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;                           // Breakpoint Register 1
   DWORD Dr1;                           // Breakpoint Register 2
   DWORD Dr2;                           // Breakpoint Register 3
   DWORD Dr3;                           // Breakpoint Register 4
   DWORD Dr4;                           // Breakpoint Register 5
   DWORD Dr5;                           // Breakpoint Register 6
   DWORD Dr6;                           // Debug Status Register
   DWORD Dr7;                           // Debug Control Register

} CONTEXT, *PCONTEXT;

// end_ntddk end_nthal


//
// Stack frame header
//
//   Order of appearance in stack frame:
//      Header (six words)
//      Parameters (at least eight words)
//      Local variables
//      Saved GPRs
//      Saved FPRs
//
//   Minimum alignment is 8 bytes

typedef struct _STACK_FRAME_HEADER {    // GPR 1 points here
   DWORD BackChain;                     // Addr of previous frame
   DWORD GlueSaved1;                    // Used by glue code
   DWORD GlueSaved2;
   DWORD Reserved1;                     // Reserved
   DWORD Spare1;                        // Used by tracing, profiling, ...
   DWORD Spare2;

   DWORD Parameter0;                    // First 8 parameter words are
   DWORD Parameter1;                    //   always present
   DWORD Parameter2;
   DWORD Parameter3;
   DWORD Parameter4;
   DWORD Parameter5;
   DWORD Parameter6;
   DWORD Parameter7;

} STACK_FRAME_HEADER,*PSTACK_FRAME_HEADER;


VOID
__jump_unwind (
   PVOID Fp,
   PVOID TargetPc
   );

#endif // defined(_MPPC_)

#if !defined(__midl) && !defined(GENUTIL) && !defined(_GENIA64_) && defined(_M_IA64)

void *_rdteb(void);
   #pragma intrinsic (_rdteb)
   #define NtCurrentTeb()      ((struct _TEB *)_rdteb())

//
// Define functions to get the address of the current fiber and the
// current fiber data.
//

   #define GetCurrentFiber() (((PNT_TIB)NtCurrentTeb())->FiberData)
   #define GetFiberData() (*(PVOID *)(GetCurrentFiber()))

#endif  // !defined(__midl) && !defined(GENUTIL) && !defined(_GENIA64_) && defined(_M_IA64)

#ifdef _IA64_

// begin_ntddk begin_nthal

//
// Pointer swizzling operation: 32-bit pointer to 64-bit pointer
//

   #if !defined(__midl) && !defined(GENUTIL) && !defined(_GENIA64_) && defined(_M_IA64)

      #ifdef _WIN64
         #define P32ToP64(p64)   ( (ULONGLONG)(p64) )
      #else
         #define P32ToP64(p32)   ( (ULONGLONG)_P32ToP64(p32) )
      #endif

extern ULONGLONG _P32ToP64(PVOID);

   #else

      #if defined(_M_IX86) || defined(_M_ALPHA)
         #define P32ToP64(p32)   ( (ULONGLONG)_P32ToP64(p32) )

static ULONGLONG _P32ToP64(DWORD *p)
{
   ULONGLONG P32ToP64Local = (LONG)p;  // sign extend p to 64-bit
   return P32ToP64Local;
}
      #endif //  (_M_IX86 || _M_ALPHA_)

   #endif // !defined(__midl) && !defined(GENUTIL) && !defined(_GENIA64_) && defined(_M_IA64)

//
// The following flags control the contents of the CONTEXT structure.
//

   #if !defined(RC_INVOKED)

      #define CONTEXT_IA64                    0x00080000 // IA64 context

      #define CONTEXT_CONTROL                 (CONTEXT_IA64 | 0x00000001L)
      #define CONTEXT_LOWER_FLOATING_POINT    (CONTEXT_IA64 | 0x00000002L)
      #define CONTEXT_HIGHER_FLOATING_POINT   (CONTEXT_IA64 | 0x00000004L)
      #define CONTEXT_INTEGER                 (CONTEXT_IA64 | 0x00000008L)
      #define CONTEXT_DEBUG                   (CONTEXT_IA64 | 0x00000010L)

      #define CONTEXT_FLOATING_POINT          (CONTEXT_LOWER_FLOATING_POINT | \
                                               CONTEXT_HIGHER_FLOATING_POINT)
      #define CONTEXT_FULL                    (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | \
                                               CONTEXT_INTEGER)

   #endif // !defined(RC_INVOKED)

//
// Context Frame
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) it is used to construct a call frame for APC delivery,
//  3) it is used to construct a call frame for exception dispatching
//  in user mode, 4) it is used in the user level thread creation
//  routines, and 5) it is used to to pass thread state to debuggers.
//
//  N.B. Because this record is used as a call frame, it must be EXACTLY
//  a multiple of 16 bytes in length and aligned on a 16-byte boundary.
//

typedef 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 thread's 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;
   DWORD Fill1[3];          // for alignment of following on 16-byte boundary

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_DEBUG.
   //
   // N.B. CONTEXT_DEBUG is *not* part of CONTEXT_FULL.
   //

   ULONGLONG DbI0;                          // Instruction debug registers *
   ULONGLONG DbI1;
   ULONGLONG DbI2;
   ULONGLONG DbI3;
   ULONGLONG DbI4;
   ULONGLONG DbI5;
   ULONGLONG DbI6;
   ULONGLONG DbI7;

   ULONGLONG DbD0;                          // Data debug registers *
   ULONGLONG DbD1;
   ULONGLONG DbD2;
   ULONGLONG DbD3;
   ULONGLONG DbD4;
   ULONGLONG DbD5;
   ULONGLONG DbD6;
   ULONGLONG DbD7;

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_LOWER_FLOATING_POINT.
   //

   FLOAT128 FltS0;                          // Lower floating point (f2-f5) - saved (preserved)
   FLOAT128 FltS1;
   FLOAT128 FltS2;
   FLOAT128 FltS3;
   FLOAT128 FltT0;                          // Lower floating point (f6-f15) - temporary (volatile)
   FLOAT128 FltT1;
   FLOAT128 FltT2;
   FLOAT128 FltT3;
   FLOAT128 FltT4;
   FLOAT128 FltT5;
   FLOAT128 FltT6;
   FLOAT128 FltT7;
   FLOAT128 FltT8;
   FLOAT128 FltT9;

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_HIGHER_FLOATING_POINT.
   //

   FLOAT128 FltS4;                          // Higher floating point (f16-f31) - saved (preserved)
   FLOAT128 FltS5;
   FLOAT128 FltS6;
   FLOAT128 FltS7;
   FLOAT128 FltS8;
   FLOAT128 FltS9;
   FLOAT128 FltS10;
   FLOAT128 FltS11;
   FLOAT128 FltS12;
   FLOAT128 FltS13;
   FLOAT128 FltS14;
   FLOAT128 FltS15;
   FLOAT128 FltS16;
   FLOAT128 FltS17;
   FLOAT128 FltS18;
   FLOAT128 FltS19;

   FLOAT128 FltF32;                         // Higher floating point (f32-f127) - temporary (volatile)
   FLOAT128 FltF33;
   FLOAT128 FltF34;
   FLOAT128 FltF35;
   FLOAT128 FltF36;
   FLOAT128 FltF37;
   FLOAT128 FltF38;
   FLOAT128 FltF39;

   FLOAT128 FltF40;
   FLOAT128 FltF41;
   FLOAT128 FltF42;
   FLOAT128 FltF43;
   FLOAT128 FltF44;
   FLOAT128 FltF45;
   FLOAT128 FltF46;
   FLOAT128 FltF47;
   FLOAT128 FltF48;
   FLOAT128 FltF49;

   FLOAT128 FltF50;
   FLOAT128 FltF51;
   FLOAT128 FltF52;
   FLOAT128 FltF53;
   FLOAT128 FltF54;
   FLOAT128 FltF55;
   FLOAT128 FltF56;
   FLOAT128 FltF57;
   FLOAT128 FltF58;
   FLOAT128 FltF59;

   FLOAT128 FltF60;
   FLOAT128 FltF61;
   FLOAT128 FltF62;
   FLOAT128 FltF63;
   FLOAT128 FltF64;
   FLOAT128 FltF65;
   FLOAT128 FltF66;
   FLOAT128 FltF67;
   FLOAT128 FltF68;
   FLOAT128 FltF69;

   FLOAT128 FltF70;
   FLOAT128 FltF71;
   FLOAT128 FltF72;
   FLOAT128 FltF73;
   FLOAT128 FltF74;
   FLOAT128 FltF75;
   FLOAT128 FltF76;
   FLOAT128 FltF77;
   FLOAT128 FltF78;
   FLOAT128 FltF79;

   FLOAT128 FltF80;
   FLOAT128 FltF81;
   FLOAT128 FltF82;
   FLOAT128 FltF83;
   FLOAT128 FltF84;
   FLOAT128 FltF85;
   FLOAT128 FltF86;
   FLOAT128 FltF87;
   FLOAT128 FltF88;
   FLOAT128 FltF89;

   FLOAT128 FltF90;
   FLOAT128 FltF91;
   FLOAT128 FltF92;
   FLOAT128 FltF93;
   FLOAT128 FltF94;
   FLOAT128 FltF95;
   FLOAT128 FltF96;
   FLOAT128 FltF97;
   FLOAT128 FltF98;
   FLOAT128 FltF99;

   FLOAT128 FltF100;
   FLOAT128 FltF101;
   FLOAT128 FltF102;
   FLOAT128 FltF103;
   FLOAT128 FltF104;
   FLOAT128 FltF105;
   FLOAT128 FltF106;
   FLOAT128 FltF107;
   FLOAT128 FltF108;
   FLOAT128 FltF109;

   FLOAT128 FltF110;
   FLOAT128 FltF111;
   FLOAT128 FltF112;
   FLOAT128 FltF113;
   FLOAT128 FltF114;
   FLOAT128 FltF115;
   FLOAT128 FltF116;
   FLOAT128 FltF117;
   FLOAT128 FltF118;
   FLOAT128 FltF119;

   FLOAT128 FltF120;
   FLOAT128 FltF121;
   FLOAT128 FltF122;
   FLOAT128 FltF123;
   FLOAT128 FltF124;
   FLOAT128 FltF125;
   FLOAT128 FltF126;
   FLOAT128 FltF127;

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_LOWER_FLOATING_POINT | CONTEXT_HIGHER_FLOATING_POINT | CONTEXT_CONTROL.
   //

   ULONGLONG StFPSR;                        // FP status
   ULONGLONG StFSR;                         // x86 FP status (a copy of AR28)
   ULONGLONG StFIR;                         // x86 FP status (a copy of AR29)
   ULONGLONG StFDR;                         // x86 FP status (a copy of AR30)

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_INTEGER.
   //
   // N.B. The registers gp, sp, rp are part of the control context
   //

   ULONGLONG IntGp;                         // global pointer (r1) - temporary (volatile)
   ULONGLONG IntT0;                         // integer registers (r2-r3) - temporary (volatile)
   ULONGLONG IntT1;
   ULONGLONG IntS0;                         // integer registers (r4-r7) - saved (preserved)
   ULONGLONG IntS1;
   ULONGLONG IntS2;
   ULONGLONG IntS3;
   ULONGLONG IntV0;                         // return value (r8) - temporary (volatile)
   ULONGLONG IntT2;                         // integer registers (r9-r11) - temporary (volatile)
   ULONGLONG IntT3;
   ULONGLONG IntT4;
   ULONGLONG IntSp;                         // stack pointer (r12) - special
   ULONGLONG IntTeb;                        // teb (r13) - special
   ULONGLONG IntT5;                         // integer registers (r14-r31) - temporary (volatile)
   ULONGLONG IntT6;
   ULONGLONG IntT7;
   ULONGLONG IntT8;
   ULONGLONG IntT9;
   ULONGLONG IntT10;
   ULONGLONG IntT11;
   ULONGLONG IntT12;
   ULONGLONG IntT13;
   ULONGLONG IntT14;
   ULONGLONG IntT15;
   ULONGLONG IntT16;
   ULONGLONG IntT17;
   ULONGLONG IntT18;
   ULONGLONG IntT19;
   ULONGLONG IntT20;
   ULONGLONG IntT21;
   ULONGLONG IntT22;

   ULONGLONG IntNats;                       // Nat bits for general registers
                                            // r1-r31 in bit positions 1 to 31.
   ULONGLONG Preds;                         // predicates - saved (preserved)

   ULONGLONG BrRp;                          // return pointer (b0) - saved (preserved)
   ULONGLONG BrS0;                          // branch registers (b1-b5) - saved (preserved)
   ULONGLONG BrS1;
   ULONGLONG BrS2;
   ULONGLONG BrS3;
   ULONGLONG BrS4;
   ULONGLONG BrT0;                          // branch registers (b6-b7) - temporary (volatile)
   ULONGLONG BrT1;
   // iA32 related Interger registers
   ULONGLONG SegCSD;                        // iA32 CSDescriptor (Ar25)
   ULONGLONG SegSSD;                        // iA32 SSDescriptor (Ar26)

   //
   // This section is specified/returned if the ContextFlags word contains
   // the flag CONTEXT_CONTROL.
   //

   // Other application registers
   ULONGLONG ApUNAT;                        // User Nat collection register - saved (preserved)
   ULONGLONG ApLC;                          // Loop counter register - saved (preserved)
   ULONGLONG ApEC;                          // Epilog counter register - saved (preserved)
   ULONGLONG ApCCV;                         // CMPXCHG value register - temporary (volatile)
   ULONGLONG ApDCR;                         // Default control register (TBD)

   // Register stack info
   ULONGLONG RsPFS;                         // Previous function state - saved (preserved)
   ULONGLONG RsBSP;                         // Backing store pointer - saved (preserved)
   ULONGLONG RsBSPSTORE;                    // BSP Store - saved (preserved)
   ULONGLONG RsRSC;                         // RSE configuration - temporary (volatile)
   ULONGLONG RsRNAT;                        // RSE Nat collection register - saved (preserved)
   // iA32 related control registers
   ULONGLONG Eflag;                         // Eflag  copy of Ar24
   ULONGLONG Cflag;                         // Cr0+Cr4 copy of Ar27

   // Trap Status Information
   ULONGLONG StIPSR;                        // Interruption Processor Status
   ULONGLONG StIIP;                         // Interruption IP
   ULONGLONG StIFS;                         // Interruption Function State
} CONTEXT, *PCONTEXT;

//BUGBUG what happens with remote debugging.
//BUGBUG how does the remote side deal with the alignment given that it will be
//BUGBUG compiled with non alignment.  This is a problem because the current
//BUGBUG MS5.0 compiler does not support this pragma623

   #ifdef _M_IA64
      #pragma force_align _CONTEXT 16
   #endif // _IA64_

//
// Followings are the data structures that required to support Legacy x86
//


//
//  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.
//

   #if !defined(RC_INVOKED)

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

      #define CONTEXT86_CONTROL         (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
      #define CONTEXT86_INTEGER         (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
      #define CONTEXT86_SEGMENTS        (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS
      #define CONTEXT86_FLOATING_POINT  (CONTEXT_i386 | 0x00000008L) // 387 state
      #define CONTEXT86_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7

      #define CONTEXT86_FULL (CONTEXT86_CONTROL | CONTEXT86_INTEGER | \
                              CONTEXT86_SEGMENTS) // context corresponding to set flags will be returned.

   #endif // !defined(RC_INVOKED)

typedef 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;
} FLOATING_SAVE_AREA;

typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;

//
// 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.
//

typedef struct _CONTEXT86 {

   //
   // 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;

} CONTEXT86;


   #ifndef _LDT_ENTRY_DEFINED
      #define _LDT_ENTRY_DEFINED

//
//  LDT descriptor entry
//

typedef 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;
} LDT_ENTRY, *PLDT_ENTRY;

   #endif // _LDT_ENTRY_DEFINED


//
// Plabel descriptor structure definition
//

typedef struct _PLABEL_DESCRIPTOR {
   ULONGLONG EntryPoint;
   ULONGLONG GlobalPointer;
} PLABEL_DESCRIPTOR, *PPLABEL_DESCRIPTOR;


#endif // _IA64_


#ifdef _IA64_

//
// Until the VC 6.0 header files get checked in always define CRTAPI.
//

   #ifndef _CRTAPI1
      #define _CRTAPI1 __cdecl
   #endif


/* Define _CRTAPI2 (for compatibility with the NT SDK) */

   #ifndef _CRTAPI2
      #define _CRTAPI2 __cdecl
   #endif



VOID
__jump_unwind (
   ULONGLONG TargetMsFrame,
   ULONGLONG TargetBsFrame,
   ULONGLONG TargetPc
   );

#endif // _IA64_

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

//
// Exception record definition.
//

typedef struct _EXCEPTION_RECORD {
   DWORD ExceptionCode;
   DWORD ExceptionFlags;
   struct _EXCEPTION_RECORD *ExceptionRecord;
   PVOID ExceptionAddress;
   DWORD NumberParameters;
   UINT_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;

typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;

//
// Typedef for pointer returned by exception_info()
//

typedef struct _EXCEPTION_POINTERS {
   PEXCEPTION_RECORD ExceptionRecord;
   PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
typedef PVOID PACCESS_TOKEN;
typedef PVOID PSECURITY_DESCRIPTOR;
typedef PVOID PSID;
////////////////////////////////////////////////////////////////////////
//                                                                    //
//                             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
typedef DWORD ACCESS_MASK;
typedef ACCESS_MASK *PACCESS_MASK;

////////////////////////////////////////////////////////////////////////
//                                                                    //
//                             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.
//

typedef struct _GENERIC_MAPPING {
   ACCESS_MASK GenericRead;
   ACCESS_MASK GenericWrite;
   ACCESS_MASK GenericExecute;
   ACCESS_MASK GenericAll;
} GENERIC_MAPPING;
typedef GENERIC_MAPPING *PGENERIC_MAPPING;



////////////////////////////////////////////////////////////////////////
//                                                                    //
//                        LUID_AND_ATTRIBUTES                         //
//                                                                    //
////////////////////////////////////////////////////////////////////////
//
//


#include <pshpack4.h>

typedef struct _LUID_AND_ATTRIBUTES {
   LUID Luid;
   DWORD Attributes;
} LUID_AND_ATTRIBUTES, * PLUID_AND_ATTRIBUTES;
typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;

#include <poppack.h>


////////////////////////////////////////////////////////////////////////
//                                                                    //
//              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
typedef struct _SID_IDENTIFIER_AUTHORITY {
   BYTE Value[6];
} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
#endif


#ifndef SID_DEFINED
   #define SID_DEFINED
typedef struct _SID {
   BYTE Revision;
   BYTE SubAuthorityCount;
   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
   #ifdef MIDL_PASS
   [size_is(SubAuthorityCount)] DWORD SubAuthority[*];
   #else // MIDL_PASS
   DWORD SubAuthority[ANYSIZE_ARRAY];
   #endif // MIDL_PASS
} SID, *PISID;
#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.

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

typedef struct _SID_AND_ATTRIBUTES {
   PSID Sid;
   DWORD Attributes;
} SID_AND_ATTRIBUTES, * PSID_AND_ATTRIBUTES;

typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY;



/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// 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_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)       //
//                                                                         //
//     (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_LOGON_IDS_RID          (0x00000005L)
#define SECURITY_LOGON_IDS_RID_COUNT    (3L)

#define SECURITY_LOCAL_SYSTEM_RID       (0x00000012L)

#define SECURITY_NT_NON_UNIQUE          (0x00000015L)

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




// 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)


//
// 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 }

// 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)



//
// User attributes
//

// (None yet defined.)




////////////////////////////////////////////////////////////////////////
//                                                                    //
//                         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_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

typedef struct _ACL {
   BYTE AclRevision;
   BYTE Sbz1;
   WORD AclSize;
   WORD AceCount;
   WORD Sbz2;
} ACL;
typedef ACL *PACL;

// end_ntddk

//
//  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.

typedef struct _ACE_HEADER {
   BYTE AceType;
   BYTE AceFlags;
   WORD AceSize;
} ACE_HEADER;
typedef ACE_HEADER *PACE_HEADER;

//
//  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)

//
//  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.


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

typedef ACCESS_ALLOWED_ACE *PACCESS_ALLOWED_ACE;

typedef struct _ACCESS_DENIED_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD SidStart;
} ACCESS_DENIED_ACE;
typedef ACCESS_DENIED_ACE *PACCESS_DENIED_ACE;

typedef struct _SYSTEM_AUDIT_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD SidStart;
} SYSTEM_AUDIT_ACE;
typedef SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE;

typedef struct _SYSTEM_ALARM_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD SidStart;
} SYSTEM_ALARM_ACE;
typedef SYSTEM_ALARM_ACE *PSYSTEM_ALARM_ACE;

// end_ntifs


typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD Flags;
   GUID ObjectType;
   GUID InheritedObjectType;
   DWORD SidStart;
} ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE;

typedef struct _ACCESS_DENIED_OBJECT_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD Flags;
   GUID ObjectType;
   GUID InheritedObjectType;
   DWORD SidStart;
} ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE;

typedef struct _SYSTEM_AUDIT_OBJECT_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD Flags;
   GUID ObjectType;
   GUID InheritedObjectType;
   DWORD SidStart;
} SYSTEM_AUDIT_OBJECT_ACE, *PSYSTEM_AUDIT_OBJECT_ACE;

typedef struct _SYSTEM_ALARM_OBJECT_ACE {
   ACE_HEADER Header;
   ACCESS_MASK Mask;
   DWORD Flags;
   GUID ObjectType;
   GUID InheritedObjectType;
   DWORD SidStart;
} SYSTEM_ALARM_OBJECT_ACE, *PSYSTEM_ALARM_OBJECT_ACE;

//
// 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.
//

typedef enum _ACL_INFORMATION_CLASS {
   AclRevisionInformation = 1,
   AclSizeInformation
} ACL_INFORMATION_CLASS;

//
//  This record is returned/sent if the user is requesting/setting the
//  AclRevisionInformation
//

typedef struct _ACL_REVISION_INFORMATION {
   DWORD AclRevision;
} ACL_REVISION_INFORMATION;
typedef ACL_REVISION_INFORMATION *PACL_REVISION_INFORMATION;

//
//  This record is returned if the user is requesting AclSizeInformation
//

typedef struct _ACL_SIZE_INFORMATION {
   DWORD AceCount;
   DWORD AclBytesInUse;
   DWORD AclBytesFree;
} ACL_SIZE_INFORMATION;
typedef ACL_SIZE_INFORMATION *PACL_SIZE_INFORMATION;


////////////////////////////////////////////////////////////////////////
//                                                                    //
//                             SECURITY_DESCRIPTOR                    //
//                                                                    //
////////////////////////////////////////////////////////////////////////
//
//  Define the Security Descriptor and related data types.
//  This is an opaque data structure.
//

// begin_ntddk begin_ntifs
//
// Current security descriptor revision value
//

#define SECURITY_DESCRIPTOR_REVISION     (1)
#define SECURITY_DESCRIPTOR_REVISION1    (1)

// end_ntddk


#define SECURITY_DESCRIPTOR_MIN_LENGTH   (sizeof(SECURITY_DESCRIPTOR))


typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;

#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_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.
//
//

typedef struct _SECURITY_DESCRIPTOR_RELATIVE {
   BYTE Revision;
   BYTE Sbz1;
   SECURITY_DESCRIPTOR_CONTROL Control;
   DWORD Owner;
   DWORD Group;
   DWORD Sacl;
   DWORD Dacl;
} SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;

typedef struct _SECURITY_DESCRIPTOR {
   BYTE Revision;
   BYTE Sbz1;
   SECURITY_DESCRIPTOR_CONTROL Control;
   PSID Owner;
   PSID Group;
   PACL Sacl;
   PACL Dacl;

} SECURITY_DESCRIPTOR, *PISECURITY_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               //
//                                                                    //
////////////////////////////////////////////////////////////////////////

typedef struct _OBJECT_TYPE_LIST {
   WORD Level;
   WORD Sbz;
   GUID *ObjectType;
} OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;

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

typedef enum _AUDIT_EVENT_TYPE {
   AuditEventObjectAccess,
   AuditEventDirectoryServiceAccess
} AUDIT_EVENT_TYPE, *PAUDIT_EVENT_TYPE;

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

// end_ntsrv

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


// begin_ntddk begin_nthal begin_ntifs
//
// 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)
//

typedef struct _PRIVILEGE_SET {
   DWORD PrivilegeCount;
   DWORD Control;
   LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
} PRIVILEGE_SET, * PPRIVILEGE_SET;


////////////////////////////////////////////////////////////////////////
//                                                                    //
//               NT Defined Privileges                                //
//                                                                    //
////////////////////////////////////////////////////////////////////////

#define SE_CREATE_TOKEN_NAME              TEXT("SeCreateTokenPrivilege")
#define SE_ASSIGNPRIMARYTOKEN_NAME        TEXT("SeAssignPrimaryTokenPrivilege")
#define SE_LOCK_MEMORY_NAME               TEXT("SeLockMemoryPrivilege")
#define SE_INCREASE_QUOTA_NAME            TEXT("SeIncreaseQuotaPrivilege")
#define SE_UNSOLICITED_INPUT_NAME         TEXT("SeUnsolicitedInputPrivilege")
#define SE_MACHINE_ACCOUNT_NAME           TEXT("SeMachineAccountPrivilege")
#define SE_TCB_NAME                       TEXT("SeTcbPrivilege")
#define SE_SECURITY_NAME                  TEXT("SeSecurityPrivilege")
#define SE_TAKE_OWNERSHIP_NAME            TEXT("SeTakeOwnershipPrivilege")
#define SE_LOAD_DRIVER_NAME               TEXT("SeLoadDriverPrivilege")
#define SE_SYSTEM_PROFILE_NAME            TEXT("SeSystemProfilePrivilege")
#define SE_SYSTEMTIME_NAME                TEXT("SeSystemtimePrivilege")
#define SE_PROF_SINGLE_PROCESS_NAME       TEXT("SeProfileSingleProcessPrivilege")
#define SE_INC_BASE_PRIORITY_NAME         TEXT("SeIncreaseBasePriorityPrivilege")
#define SE_CREATE_PAGEFILE_NAME           TEXT("SeCreatePagefilePrivilege")
#define SE_CREATE_PERMANENT_NAME          TEXT("SeCreatePermanentPrivilege")
#define SE_BACKUP_NAME                    TEXT("SeBackupPrivilege")
#define SE_RESTORE_NAME                   TEXT("SeRestorePrivilege")
#define SE_SHUTDOWN_NAME                  TEXT("SeShutdownPrivilege")
#define SE_DEBUG_NAME                     TEXT("SeDebugPrivilege")
#define SE_AUDIT_NAME                     TEXT("SeAuditPrivilege")
#define SE_SYSTEM_ENVIRONMENT_NAME        TEXT("SeSystemEnvironmentPrivilege")
#define SE_CHANGE_NOTIFY_NAME             TEXT("SeChangeNotifyPrivilege")
#define SE_REMOTE_SHUTDOWN_NAME           TEXT("SeRemoteShutdownPrivilege")


////////////////////////////////////////////////////////////////////
//                                                                //
//           Security Quality Of Service                          //
//                                                                //
//                                                                //
////////////////////////////////////////////////////////////////////

// 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.
//

typedef enum _SECURITY_IMPERSONATION_LEVEL {
   SecurityAnonymous,
   SecurityIdentification,
   SecurityImpersonation,
   SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL, * PSECURITY_IMPERSONATION_LEVEL;

#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation

#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation


////////////////////////////////////////////////////////////////////
//                                                                //
//           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 (STANDARD_RIGHTS_REQUIRED  | \
                          TOKEN_ASSIGN_PRIMARY      | \
                          TOKEN_DUPLICATE           | \
                          TOKEN_IMPERSONATE         | \
                          TOKEN_QUERY               | \
                          TOKEN_QUERY_SOURCE        | \
                          TOKEN_ADJUST_PRIVILEGES   | \
                          TOKEN_ADJUST_GROUPS       | \
                          TOKEN_ADJUST_SESSIONID    | \
                          TOKEN_ADJUST_DEFAULT)


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

typedef enum _TOKEN_TYPE {
   TokenPrimary = 1,
   TokenImpersonation
} TOKEN_TYPE;
typedef TOKEN_TYPE *PTOKEN_TYPE;


//
// Token Information Classes.
//


typedef enum _TOKEN_INFORMATION_CLASS {
   TokenUser = 1,
   TokenGroups,
   TokenPrivileges,
   TokenOwner,
   TokenPrimaryGroup,
   TokenDefaultDacl,
   TokenSource,
   TokenType,
   TokenImpersonationLevel,
   TokenStatistics,
   TokenRestrictedSids,
   TokenSessionId
} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS;

//
// Token information class structures
//


typedef struct _TOKEN_USER {
   SID_AND_ATTRIBUTES User;
} TOKEN_USER, *PTOKEN_USER;

typedef struct _TOKEN_GROUPS {
   DWORD GroupCount;
   SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
} TOKEN_GROUPS, *PTOKEN_GROUPS;


typedef struct _TOKEN_PRIVILEGES {
   DWORD PrivilegeCount;
   LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;


typedef struct _TOKEN_OWNER {
   PSID Owner;
} TOKEN_OWNER, *PTOKEN_OWNER;


typedef struct _TOKEN_PRIMARY_GROUP {
   PSID PrimaryGroup;
} TOKEN_PRIMARY_GROUP, *PTOKEN_PRIMARY_GROUP;


typedef struct _TOKEN_DEFAULT_DACL {
   PACL DefaultDacl;
} TOKEN_DEFAULT_DACL, *PTOKEN_DEFAULT_DACL;



#define TOKEN_SOURCE_LENGTH 8

typedef struct _TOKEN_SOURCE {
   CHAR SourceName[TOKEN_SOURCE_LENGTH];
   LUID SourceIdentifier;
} TOKEN_SOURCE, *PTOKEN_SOURCE;


typedef struct _TOKEN_STATISTICS {
   LUID TokenId;
   LUID AuthenticationId;
   LARGE_INTEGER ExpirationTime;
   TOKEN_TYPE TokenType;
   SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
   DWORD DynamicCharged;
   DWORD DynamicAvailable;
   DWORD GroupCount;
   DWORD PrivilegeCount;
   LUID ModifiedId;
} TOKEN_STATISTICS, *PTOKEN_STATISTICS;



typedef struct _TOKEN_CONTROL {
   LUID TokenId;
   LUID AuthenticationId;
   LUID ModifiedId;
   TOKEN_SOURCE TokenSource;
} TOKEN_CONTROL, *PTOKEN_CONTROL;

//
// Security Tracking Mode
//

#define SECURITY_DYNAMIC_TRACKING      (TRUE)
#define SECURITY_STATIC_TRACKING       (FALSE)

typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,
* PSECURITY_CONTEXT_TRACKING_MODE;



//
// Quality Of Service
//

typedef struct _SECURITY_QUALITY_OF_SERVICE {
   DWORD Length;
   SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
   SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
   BOOLEAN EffectiveOnly;
} SECURITY_QUALITY_OF_SERVICE, * PSECURITY_QUALITY_OF_SERVICE;


//
// Used to represent information related to a thread impersonation
//

typedef struct _SE_IMPERSONATION_STATE {
   PACCESS_TOKEN Token;
   BOOLEAN CopyOnOpen;
   BOOLEAN EffectiveOnly;
   SECURITY_IMPERSONATION_LEVEL Level;
} SE_IMPERSONATION_STATE, *PSE_IMPERSONATION_STATE;


typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION;

#define OWNER_SECURITY_INFORMATION       (0X00000001L)
#define GROUP_SECURITY_INFORMATION       (0X00000002L)
#define DACL_SECURITY_INFORMATION        (0X00000004L)
#define SACL_SECURITY_INFORMATION        (0X00000008L)
#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_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
                                   0xFFF)

// end_ntifs

#define MAXIMUM_PROCESSORS 32

#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 )
#define TLS_MINIMUM_AVAILABLE 64

typedef struct _NT_TIB {
   struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
   PVOID StackBase;
   PVOID StackLimit;
   PVOID SubSystemTib;
   union {
      PVOID FiberData;
      DWORD Version;
   };
   PVOID ArbitraryUserPointer;
   struct _NT_TIB *Self;
} NT_TIB;
typedef NT_TIB *PNT_TIB;

#if !defined(_X86_) && !defined(_IA64_)
   #define WX86
#endif

#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

typedef struct _QUOTA_LIMITS {
   SIZE_T PagedPoolLimit;
   SIZE_T NonPagedPoolLimit;
   DWORD MinimumWorkingSetSize;
   DWORD MaximumWorkingSetSize;
   SIZE_T PagefileLimit;
   LARGE_INTEGER TimeLimit;
} QUOTA_LIMITS;
typedef QUOTA_LIMITS *PQUOTA_LIMITS;

//

typedef 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;
} JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, *PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION;

typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION {
   LARGE_INTEGER PerProcessUserTimeLimit;
   LARGE_INTEGER PerJobUserTimeLimit;
   DWORD LimitFlags;
   DWORD MinimumWorkingSetSize;
   DWORD MaximumWorkingSetSize;
   DWORD ActiveProcessLimit;
   DWORD Affinity;
   DWORD PriorityClass;
} JOBOBJECT_BASIC_LIMIT_INFORMATION, *PJOBOBJECT_BASIC_LIMIT_INFORMATION;

typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST {
   DWORD NumberOfAssignedProcesses;
   DWORD NumberOfProcessIdsInList;
   UINT_PTR ProcessIdList[1];
} JOBOBJECT_BASIC_PROCESS_ID_LIST, *PJOBOBJECT_BASIC_PROCESS_ID_LIST;

typedef struct _JOBOBJECT_BASIC_UI_RESTRICTIONS {
   DWORD UIRestrictionsClass;
} JOBOBJECT_BASIC_UI_RESTRICTIONS, *PJOBOBJECT_BASIC_UI_RESTRICTIONS;

typedef struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION {
   DWORD SecurityLimitFlags;
   HANDLE JobToken;
   PTOKEN_GROUPS SidsToDisable;
   PTOKEN_PRIVILEGES PrivilegesToDelete;
   PTOKEN_GROUPS RestrictedSids;
} JOBOBJECT_SECURITY_LIMIT_INFORMATION, *PJOBOBJECT_SECURITY_LIMIT_INFORMATION;

typedef struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION {
   DWORD EndOfJobTimeAction;
} JOBOBJECT_END_OF_JOB_TIME_INFORMATION, *PJOBOBJECT_END_OF_JOB_TIME_INFORMATION;

typedef struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
   PVOID CompletionKey;
   HANDLE CompletionPort;
} JOBOBJECT_ASSOCIATE_COMPLETION_PORT, *PJOBOBJECT_ASSOCIATE_COMPLETION_PORT;

#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_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_VALID_FLAGS        0x0000007f

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

typedef enum _JOBOBJECTINFOCLASS {
   JobObjectBasicAccountingInformation = 1,
   JobObjectBasicLimitInformation,
   JobObjectBasicProcessIdList,
   JobObjectBasicUIRestrictions,
   JobObjectSecurityLimitInformation,
   JobObjectEndOfJobTimeInformation,
   JobObjectAssociateCompletionPortInformation,
   MaxJobObjectInfoClass
} JOBOBJECTINFOCLASS;
//
#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 PROCESSOR_INTEL_386     386
#define PROCESSOR_INTEL_486     486
#define PROCESSOR_INTEL_PENTIUM 586
#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_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_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_AMD3D_INSTRUCTIONS_AVAILABLE     7
#define SYSTEM_FLAG_REMOTE_BOOT_CLIENT 0x00000001
#define SYSTEM_FLAG_DISKLESS_CLIENT    0x00000002
typedef struct _MEMORY_BASIC_INFORMATION {
   PVOID BaseAddress;
   PVOID AllocationBase;
   DWORD AllocationProtect;
   SIZE_T RegionSize;
   DWORD State;
   DWORD Protect;
   DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;

typedef struct _MEMORY_BASIC_INFORMATION_VLM {
   union {
      PVOID64 BaseAddress;
      ULONGLONG BaseAddressAsUlongLong;
   };
   union {
      PVOID64 AllocationBase;
      ULONGLONG AllocationBaseAsUlongLong;
   };
   ULONGLONG RegionSize;
   DWORD AllocationProtect;
   DWORD State;
   DWORD Protect;
   DWORD Type;
} MEMORY_BASIC_INFORMATION_VLM, *PMEMORY_BASIC_INFORMATION_VLM;
#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_4MB_PAGES    0x80000000
#define SEC_FILE           0x800000
#define SEC_IMAGE         0x1000000
#define SEC_VLM           0x2000000
#define SEC_RESERVE       0x4000000
#define SEC_COMMIT        0x8000000
#define SEC_NOCACHE      0x10000000
#define MEM_IMAGE         SEC_IMAGE

//
// 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 | 0x3FF)

#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_ENCRYPTED            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_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             ((DWORD)-1)
#define MAILSLOT_WAIT_FOREVER           ((DWORD)-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 the file notification information structure
//

typedef struct _FILE_NOTIFY_INFORMATION {
   DWORD NextEntryOffset;
   DWORD Action;
   DWORD FileNameLength;
   WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;


//
// Define segement buffer structure for scatter/gather read/write.
//

typedef union _FILE_SEGMENT_ELEMENT {
   PVOID64 Buffer;
   ULONGLONG Alignment;
}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT;

//
// Structures for FSCTL_SET_REPARSE_POINT, FSCTL_GET_REPARSE_POINT, and FSCTL_DELETE_REPARSE_POINT
//

//
// The reparse structure is used by layered drivers to store data in a
// reparse point. The constraints on reparse tags are defined below.
// This version of the reparse data buffer is only for Microsoft tags.
//

typedef struct _REPARSE_DATA_BUFFER {
   DWORD ReparseTag;
   WORD ReparseDataLength;
   WORD Reserved;
   union {
      struct {
         WORD SubstituteNameOffset;
         WORD SubstituteNameLength;
         WORD PrintNameOffset;
         WORD PrintNameLength;
         WCHAR PathBuffer[1];
      } SymbolicLinkReparseBuffer;
      struct {
         WORD SubstituteNameOffset;
         WORD SubstituteNameLength;
         WORD PrintNameOffset;
         WORD PrintNameLength;
         WCHAR PathBuffer[1];
      } MountPointReparseBuffer;
      struct {
         BYTE DataBuffer[1];
      } GenericReparseBuffer;
   };
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

#define REPARSE_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)


//
// 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 uses with this format of the reparse point buffer.
//

typedef struct _REPARSE_GUID_DATA_BUFFER {
   DWORD ReparseTag;
   WORD ReparseDataLength;
   WORD Reserved;
   GUID ReparseGuid;
   struct {
      BYTE DataBuffer[1];
   } GenericReparseBuffer;
} REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;

#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, \
                                                            GenericReparseBuffer)


//
// The reparse information structure is used to return information about
// a reparse point to the caller.
//

typedef struct _REPARSE_POINT_INFORMATION {
   WORD ReparseDataLength;
   WORD UnparsedNameLength;
} REPARSE_POINT_INFORMATION, *PREPARSE_POINT_INFORMATION;

//
// 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|L|N|   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.
//
// L is the high-latency bit. When set to 1, a file with this tag is
//   expected to have a long latency to retrieve the first byte of data.
//
// N is name surrogate. When set to 1, the file represents another named
//   entity in the system.
//
// The M, L, and N bits are OR-able.
// The following macros check for the M, L 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 corresponds to a file
// that is to be displayed with the slow icon overlay.
//

#define IsReparseTagHighLatency(_tag) (            \
      ((_tag) & 0x40000000)   \
      )

//
// Macro to determine whether a reparse point tag corresponds to a file
// that is to be displayed with the slow icon overlay.
//

#define IsReparseTagNameSurrogate(_tag) (          \
      ((_tag) & 0x20000000)   \
      )

//
// The following constant represents the bits that are valid to use in
// reparse tags.
//

#define IO_REPARSE_TAG_VALID_VALUES     (0xE000FFFF)

//
// Macro to determine whether a reparse tag is a valid tag.
//

#define IsReparseTagValid(_tag) (                               \
      !((_tag) & ~IO_REPARSE_TAG_VALID_VALUES) &&   \
      ((_tag) > IO_REPARSE_TAG_RESERVED_RANGE)      \
      )

//
// Microsoft tags for reparse points.
//

#define IO_REPARSE_TAG_SYMBOLIC_LINK      IO_REPARSE_TAG_RESERVED_ZERO
#define IO_REPARSE_TAG_MOUNT_POINT               (0xA0000003)
#define IO_REPARSE_TAG_HSM                       (0xC0000004)
#define IO_REPARSE_TAG_NSS                       (0x80000005)
#define IO_REPARSE_TAG_NSSRECOVER                (0x80000006)
#define IO_REPARSE_TAG_SIS                       (0x80000007)
#define IO_REPARSE_TAG_DFS                       (0x80000008)

#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

#define ES_SYSTEM_REQUIRED  ((DWORD)0x00000001)
#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002)
#define ES_USER_PRESENT     ((DWORD)0x00000004)
#define ES_CONTINUOUS       ((DWORD)0x80000000)

typedef DWORD EXECUTION_STATE;

typedef enum {
   LT_DONT_CARE,
   LT_LOWEST_LATENCY
} LATENCY_TIME;

// wmi
typedef struct _POWER_DEVICE_TIMEOUTS {
   DWORD ConservationIdleTime;
   DWORD PerformanceIdleTime;
} POWER_DEVICE_TIMEOUTS, *PPOWER_DEVICE_TIMEOUTS;



//
// Image Format
//


#ifndef _MAC

   #include "pshpack4.h"                // 4 byte packing is the default

   #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

   #include "pshpack2.h"                // 16 bit headers are 2 byte packed

#else

   #include "pshpack1.h"

   #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

typedef 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
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef 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
} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;

typedef 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
} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER;

#ifndef _MAC
   #include "poppack.h"                 // Back to 4 byte packing
#endif

//
// File header format.
//

typedef struct _IMAGE_FILE_HEADER {
   WORD Machine;
   WORD NumberOfSections;
   DWORD TimeDateStamp;
   DWORD PointerToSymbolTable;
   DWORD NumberOfSymbols;
   WORD SizeOfOptionalHeader;
   WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;


#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_POWERPC           0x01F0  // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian
#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB             0x01c2
#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64
#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64
//
// Directory format.
//

typedef struct _IMAGE_DATA_DIRECTORY {
   DWORD VirtualAddress;
   DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

//
// Optional header format.
//

typedef struct _IMAGE_OPTIONAL_HEADER {
   //
   // 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];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef 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;
} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;

typedef 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];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

#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

#ifdef _WIN64
typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
   #define IMAGE_SIZEOF_NT_OPTIONAL_HEADER     IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
   #define IMAGE_NT_OPTIONAL_HDR_MAGIC         IMAGE_NT_OPTIONAL_HDR64_MAGIC
#else
typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
   #define IMAGE_SIZEOF_NT_OPTIONAL_HEADER     IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
   #define IMAGE_NT_OPTIONAL_HDR_MAGIC         IMAGE_NT_OPTIONAL_HDR32_MAGIC
#endif

typedef struct _IMAGE_NT_HEADERS64 {
   DWORD Signature;
   IMAGE_FILE_HEADER FileHeader;
   IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;

typedef struct _IMAGE_NT_HEADERS {
   DWORD Signature;
   IMAGE_FILE_HEADER FileHeader;
   IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef struct _IMAGE_ROM_HEADERS {
   IMAGE_FILE_HEADER FileHeader;
   IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;

#define IMAGE_FIRST_SECTION64( ntheader ) ((PIMAGE_SECTION_HEADER)        \
                                           ((UINT_PTR)ntheader +                                                  \
                                            FIELD_OFFSET( IMAGE_NT_HEADERS64, OptionalHeader ) +                 \
                                            ((PIMAGE_NT_HEADERS64)(ntheader))->FileHeader. \
                                            SizeOfOptionalHeader   \
                                           ))

#define IMAGE_FIRST_SECTION32( ntheader ) ((PIMAGE_SECTION_HEADER)        \
                                           ((UINT_PTR)ntheader +                                                  \
                                            FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) +                 \
                                            ((PIMAGE_NT_HEADERS32)(ntheader))->FileHeader. \
                                            SizeOfOptionalHeader   \
                                           ))

#ifdef _WIN64
typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
   #define IMAGE_FIRST_SECTION(ntheader)       IMAGE_FIRST_SECTION64(ntheader)
#else
typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
   #define IMAGE_FIRST_SECTION(ntheader)       IMAGE_FIRST_SECTION32(ntheader)
#endif


// 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.

// 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_WDM_DRIVER  0x2000     // Driver uses WDM model

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

//
// Section header format.
//

#define IMAGE_SIZEOF_SHORT_NAME              8

typedef 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;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

#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_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
   #include "pshpack2.h"                    // Symbols, relocs, and linenumbers are 2 byte packed
#endif

//
// Symbol format.
//

typedef struct _IMAGE_SYMBOL {
   union {
      BYTE ShortName[8];
      struct {
         DWORD Short;          // if 0, use LongName
         DWORD Long;           // offset into string table
      } Name;
      PBYTE LongName[2];
   } N;
   DWORD Value;
   SHORT SectionNumber;
   WORD Type;
   BYTE StorageClass;
   BYTE NumberOfAuxSymbols;
} IMAGE_SYMBOL;
typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL;


#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           (SHORT)0          // Symbol is undefined or is common.
#define IMAGE_SYM_ABSOLUTE            (SHORT)-1         // Symbol is an absolute value.
#define IMAGE_SYM_DEBUG               (SHORT)-2         // Symbol is a special debug item.

//
// 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     (BYTE )-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

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

#ifndef INCREF
   #define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK))
#endif
#ifndef DECREF
   #define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
#endif

//
// Auxiliary entry format.
//

typedef 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;
} IMAGE_AUX_SYMBOL;
typedef IMAGE_AUX_SYMBOL UNALIGNED *PIMAGE_AUX_SYMBOL;

#define IMAGE_SIZEOF_AUX_SYMBOL             18

//
// 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.
//

typedef 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;
} IMAGE_RELOCATION;
typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION;

#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_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_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_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_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_SECTION           0x000E  // Section table index
#define IMAGE_REL_ARM_SECREL            0x000F  // Offset within section

//
// 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_LTOFF64          0x000F
#define IMAGE_REL_IA64_DIR32NB          0x0010
#define IMAGE_REL_IA64_RESERVED_11      0x0011
#define IMAGE_REL_IA64_RESERVED_12      0x0012
#define IMAGE_REL_IA64_RESERVED_13      0x0013
#define IMAGE_REL_IA64_RESERVED_14      0x0014
#define IMAGE_REL_IA64_RESERVED_15      0x0015
#define IMAGE_REL_IA64_RESERVED_16      0x0016
#define IMAGE_REL_IA64_ADDEND           0x001F

#define EXT_IMM64(Value, Address, Size, InstPos, ValPos)             \
   Value |= (((ULONGLONG)((*(Address) >> InstPos) & (((ULONGLONG)1 << Size) - 1))) << ValPos)

#define INS_IMM64(Value, Address, Size, InstPos, ValPos)  \
   *(PDWORD)Address = (*(PDWORD)Address & ~(((1 << Size) - 1) << InstPos)) | \
                      ((DWORD)((((ULONGLONG)Value >> \
                                 ValPos) & (((ULONGLONG)1 << Size) - 1))) << InstPos)

#define EMARCH_ENC_I17_IMM7B_INST_WORD_X         3
#define EMARCH_ENC_I17_IMM7B_SIZE_X              7
#define EMARCH_ENC_I17_IMM7B_INST_WORD_POS_X     4
#define EMARCH_ENC_I17_IMM7B_VAL_POS_X           0

#define EMARCH_ENC_I17_IMM9D_INST_WORD_X         3
#define EMARCH_ENC_I17_IMM9D_SIZE_X              9
#define EMARCH_ENC_I17_IMM9D_INST_WORD_POS_X     18
#define EMARCH_ENC_I17_IMM9D_VAL_POS_X           7

#define EMARCH_ENC_I17_IMM5C_INST_WORD_X         3
#define EMARCH_ENC_I17_IMM5C_SIZE_X              5
#define EMARCH_ENC_I17_IMM5C_INST_WORD_POS_X     13
#define EMARCH_ENC_I17_IMM5C_VAL_POS_X           16

#define EMARCH_ENC_I17_IC_INST_WORD_X            3
#define EMARCH_ENC_I17_IC_SIZE_X                 1
#define EMARCH_ENC_I17_IC_INST_WORD_POS_X        12
#define EMARCH_ENC_I17_IC_VAL_POS_X              21

#define EMARCH_ENC_I17_IMM41a_INST_WORD_X        1
#define EMARCH_ENC_I17_IMM41a_SIZE_X             10
#define EMARCH_ENC_I17_IMM41a_INST_WORD_POS_X    14
#define EMARCH_ENC_I17_IMM41a_VAL_POS_X          22

#define EMARCH_ENC_I17_IMM41b_INST_WORD_X        1
#define EMARCH_ENC_I17_IMM41b_SIZE_X             8
#define EMARCH_ENC_I17_IMM41b_INST_WORD_POS_X    24
#define EMARCH_ENC_I17_IMM41b_VAL_POS_X          32

#define EMARCH_ENC_I17_IMM41c_INST_WORD_X        2
#define EMARCH_ENC_I17_IMM41c_SIZE_X             23
#define EMARCH_ENC_I17_IMM41c_INST_WORD_POS_X    0
#define EMARCH_ENC_I17_IMM41c_VAL_POS_X          40

#define EMARCH_ENC_I17_SIGN_INST_WORD_X          3
#define EMARCH_ENC_I17_SIGN_SIZE_X               1
#define EMARCH_ENC_I17_SIGN_INST_WORD_POS_X      27
#define EMARCH_ENC_I17_SIGN_VAL_POS_X            63

//
// Line number format.
//

typedef 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.
} IMAGE_LINENUMBER;
typedef IMAGE_LINENUMBER UNALIGNED *PIMAGE_LINENUMBER;

#define IMAGE_SIZEOF_LINENUMBER              6

#ifndef _MAC
   #include "poppack.h"                     // Back to 4 byte packing
#endif

//
// Based relocation format.
//

typedef struct _IMAGE_BASE_RELOCATION {
   DWORD VirtualAddress;
   DWORD SizeOfBlock;
//  WORD    TypeOffset[1];
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

#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_SECTION               6
#define IMAGE_REL_BASED_REL32                 7

#define IMAGE_REL_BASED_MIPS_JMPADDR16        9
#define IMAGE_REL_BASED_IA64_IMM64            9
#define IMAGE_REL_BASED_DIR64                 10
#define IMAGE_REL_BASED_HIGH3ADJ              11


//
// 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       "//              "

typedef 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.
} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;

#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR      60

//
// DLL support.
//

//
// Export Format
//

typedef 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
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

//
// Import Format
//

typedef struct _IMAGE_IMPORT_BY_NAME {
   WORD Hint;
   BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

#include "pshpack8.h"                       // Use align 8 for the 64-bit IAT.

typedef struct _IMAGE_THUNK_DATA64 {
   union {
      PBYTE ForwarderString;
      PDWORD Function;
      ULONGLONG Ordinal;
      PIMAGE_IMPORT_BY_NAME AddressOfData;
   } u1;
} IMAGE_THUNK_DATA64;
typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64;

#include "poppack.h"                        // Back to 4 byte packing

typedef struct _IMAGE_THUNK_DATA32 {
   union {
      PBYTE ForwarderString;
      PDWORD Function;
      DWORD Ordinal;
      PIMAGE_IMPORT_BY_NAME AddressOfData;
   } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

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

typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK)(
   PVOID DllHandle,
   DWORD Reason,
   PVOID Reserved
   );

typedef struct _IMAGE_TLS_DIRECTORY64 {
   ULONGLONG StartAddressOfRawData;
   ULONGLONG EndAddressOfRawData;
   PDWORD AddressOfIndex;
   PIMAGE_TLS_CALLBACK *AddressOfCallBacks;
   DWORD SizeOfZeroFill;
   DWORD Characteristics;
} IMAGE_TLS_DIRECTORY64;
typedef IMAGE_TLS_DIRECTORY64 * PIMAGE_TLS_DIRECTORY64;

typedef struct _IMAGE_TLS_DIRECTORY32 {
   DWORD StartAddressOfRawData;
   DWORD EndAddressOfRawData;
   PDWORD AddressOfIndex;
   PIMAGE_TLS_CALLBACK *AddressOfCallBacks;
   DWORD SizeOfZeroFill;
   DWORD Characteristics;
} IMAGE_TLS_DIRECTORY32;
typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32;

#ifdef _WIN64
   #define IMAGE_ORDINAL_FLAG              IMAGE_ORDINAL_FLAG64
   #define IMAGE_ORDINAL(Ordinal)          IMAGE_ORDINAL64(Ordinal)
typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA;
typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA;
   #define IMAGE_SNAP_BY_ORDINAL(Ordinal)  IMAGE_SNAP_BY_ORDINAL64(Ordinal)
typedef IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY;
typedef PIMAGE_TLS_DIRECTORY64 PIMAGE_TLS_DIRECTORY;
#else
   #define IMAGE_ORDINAL_FLAG              IMAGE_ORDINAL_FLAG32
   #define IMAGE_ORDINAL(Ordinal)          IMAGE_ORDINAL32(Ordinal)
typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA;
typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA;
   #define IMAGE_SNAP_BY_ORDINAL(Ordinal)  IMAGE_SNAP_BY_ORDINAL32(Ordinal)
typedef IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY;
typedef PIMAGE_TLS_DIRECTORY32 PIMAGE_TLS_DIRECTORY;
#endif

typedef 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)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

//
// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ]
//

typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
   DWORD TimeDateStamp;
   WORD OffsetModuleName;
   WORD NumberOfModuleForwarderRefs;
// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
} IMAGE_BOUND_IMPORT_DESCRIPTOR,  *PIMAGE_BOUND_IMPORT_DESCRIPTOR;

typedef struct _IMAGE_BOUND_FORWARDER_REF {
   DWORD TimeDateStamp;
   WORD OffsetModuleName;
   WORD Reserved;
} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;

//
// Stub structure for IA64 transition stubs
//
#define IMAGE_MIX_ISA_LIMIT 2

typedef struct _IMAGE_STUB_DIRECTORY {
   DWORD SecondaryImportAddressTable;              // RVA of Secondary IAT
   WORD ExpectedISA[IMAGE_MIX_ISA_LIMIT];          // Indicator of available ISA stubs
   DWORD StubAddressTable[IMAGE_MIX_ISA_LIMIT];    // RVA of Stub Address Tables
} IMAGE_STUB_DIRECTORY, *PIMAGE_STUB_DIRECTORY;

#define IA64_STUB_NOT_AVAILABLE     ((PVOID) -1)
#define IA64_JMPE_MASK              0x00ffffff
#define IA64_JMPE_MARKER            0x0035000f

//
// 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.
//

typedef struct _IMAGE_RESOURCE_DIRECTORY {
   DWORD Characteristics;
   DWORD TimeDateStamp;
   WORD MajorVersion;
   WORD MinorVersion;
   WORD NumberOfNamedEntries;
   WORD NumberOfIdEntries;
//  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

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

typedef 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;
      };
   };
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

//
// 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.
//

typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
   WORD Length;
   CHAR NameString[ 1 ];
} IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;


typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
   WORD Length;
   WCHAR NameString[ 1 ];
} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;


//
// 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.
//

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
   DWORD OffsetToData;
   DWORD Size;
   DWORD CodePage;
   DWORD Reserved;
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

//
// Load Configuration Directory Entry
//

typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
   DWORD Characteristics;
   DWORD TimeDateStamp;
   WORD MajorVersion;
   WORD MinorVersion;
   DWORD GlobalFlagsClear;
   DWORD GlobalFlagsSet;
   DWORD CriticalSectionDefaultTimeout;
   DWORD DeCommitFreeBlockThreshold;
   DWORD DeCommitTotalFreeThreshold;
   PVOID LockPrefixTable;
   DWORD MaximumAllocationSize;
   DWORD VirtualMemoryThreshold;
   DWORD ProcessHeapFlags;
   DWORD ProcessAffinityMask;
   WORD CSDVersion;
   WORD Reserved1;
   PVOID EditList;
   DWORD Reserved[ 1 ];
} IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY;


//
// Function table entry format for IA64 images.  Function table is
// pointed to by the IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry.
// This definition duplicates the one in ntia64.h for use by portable
// image file mungers.
//

typedef struct _IMAGE_IA64_RUNTIME_FUNCTION_ENTRY {
   DWORD BeginAddress;
   DWORD EndAddress;
   DWORD UnwindInfoAddress;
} IMAGE_IA64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY;

//
// Function table entry format for ALPHA images.  Function table is
// pointed to by the IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry.
// This definition duplicates ones in ntmips.h and ntalpha.h for use
// by portable image file mungers.
//

typedef struct _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY {
   DWORD BeginAddress;
   DWORD EndAddress;
   DWORD ExceptionHandler;
   DWORD HandlerData;
   DWORD PrologEndAddress;
} IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY;

typedef struct _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY {
   ULONGLONG BeginAddress;
   ULONGLONG EndAddress;
   ULONGLONG ExceptionHandler;
   ULONGLONG HandlerData;
   ULONGLONG PrologEndAddress;
} IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY;

typedef  IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY IMAGE_AXP64_RUNTIME_FUNCTION_ENTRY;
typedef PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY PIMAGE_AXP64_RUNTIME_FUNCTION_ENTRY;

//
// WIN CE Exception table format
//

typedef struct _IMAGE_CE_RUNTIME_FUNCTION_ENTRY {
   DWORD FuncStart;
   DWORD PrologLen : 8;
   DWORD FuncLen : 22;
   DWORD ThirtyTwoBit : 1;
   DWORD ExceptionFlag : 1;
} IMAGE_CE_RUNTIME_FUNCTION_ENTRY, * PIMAGE_CE_RUNTIME_FUNCTION_ENTRY;

#if defined(_IA64_)

typedef  IMAGE_IA64_RUNTIME_FUNCTION_ENTRY IMAGE_RUNTIME_FUNCTION_ENTRY;
typedef PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY PIMAGE_RUNTIME_FUNCTION_ENTRY;

#else

typedef  IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY IMAGE_RUNTIME_FUNCTION_ENTRY;
typedef PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY PIMAGE_RUNTIME_FUNCTION_ENTRY;

#endif

//
// Debug Format
//

typedef struct _IMAGE_DEBUG_DIRECTORY {
   DWORD Characteristics;
   DWORD TimeDateStamp;
   WORD MajorVersion;
   WORD MinorVersion;
   DWORD Type;
   DWORD SizeOfData;
   DWORD AddressOfRawData;
   DWORD PointerToRawData;
} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;

#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


typedef struct _IMAGE_COFF_SYMBOLS_HEADER {
   DWORD NumberOfSymbols;
   DWORD LvaToFirstSymbol;
   DWORD NumberOfLinenumbers;
   DWORD LvaToFirstLinenumber;
   DWORD RvaToFirstByteOfCode;
   DWORD RvaToLastByteOfCode;
   DWORD RvaToFirstByteOfData;
   DWORD RvaToLastByteOfData;
} IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER;

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

typedef 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
} FPO_DATA, *PFPO_DATA;
#define SIZEOF_RFPO_DATA 16


#define IMAGE_DEBUG_MISC_EXENAME    1

typedef 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
} IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC;


//
// 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.
//

#if defined(_IA64_)

typedef struct _IMAGE_FUNCTION_ENTRY {
   DWORD StartingAddress;
   DWORD EndingAddress;
   DWORD UnwindInfoAddress;
} IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY;

#else

typedef struct _IMAGE_FUNCTION_ENTRY {
   DWORD StartingAddress;
   DWORD EndingAddress;
   DWORD EndOfPrologue;
} IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY;

#endif
typedef struct _IMAGE_FUNCTION_ENTRY64 {
   ULONGLONG StartingAddress;
   ULONGLONG EndingAddress;
   ULONGLONG EndOfPrologue;
} IMAGE_FUNCTION_ENTRY64, *PIMAGE_FUNCTION_ENTRY64;

//
// 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.
//

typedef 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];
} IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER;

#ifndef _MAC
   #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
#else
   #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4449
#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.
//

typedef struct _ImageArchitectureHeader {
   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
} IMAGE_ARCHITECTURE_HEADER, *PIMAGE_ARCHITECTURE_HEADER;

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

#include "poppack.h"                // 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

typedef 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.
} IMPORT_OBJECT_HEADER;

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

typedef 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 @
} IMPORT_OBJECT_NAME_TYPE;

//
// End Image Format
//

//
// for move macros
//
#ifdef _MAC
   #ifndef _INC_STRING
      #include <string.h>
   #endif /* _INC_STRING */
#else
   #include <string.h>
#endif // _MAC

#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 ) ((DWORD)((b) + ((o) << 18)))

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

NTSYSAPI
SIZE_T
NTAPI
RtlCompareMemory (
   const VOID *Source1,
   const VOID *Source2,
   SIZE_T Length
   );

#if defined(_M_AXP64) || defined(_M_IA64)

   #define RtlEqualMemory(Source1, Source2, Length) \
   ((Length) == RtlCompareMemory(Source1, Source2, Length))

NTSYSAPI
VOID
NTAPI
RtlCopyMemory (
   VOID UNALIGNED *Destination,
   CONST VOID UNALIGNED *Source,
   SIZE_T Length
   );

NTSYSAPI
VOID
NTAPI
RtlCopyMemory32 (
   VOID UNALIGNED *Destination,
   CONST VOID UNALIGNED *Source,
   DWORD Length
   );

NTSYSAPI
VOID
NTAPI
RtlMoveMemory (
   VOID UNALIGNED *Destination,
   CONST VOID UNALIGNED *Source,
   SIZE_T Length
   );

NTSYSAPI
VOID
NTAPI
RtlFillMemory (
   VOID UNALIGNED *Destination,
   SIZE_T Length,
   BYTE Fill
   );

NTSYSAPI
VOID
NTAPI
RtlZeroMemory (
   VOID UNALIGNED *Destination,
   SIZE_T Length
   );

#else

   #define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
   #define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
   #define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
   #define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
   #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))

#endif


#if (defined(_ALPHA_) || defined(_M_IA64)) && !(defined(MIDL_PASS) || defined(RC_INVOKED))

NTSYSAPI
VOID
NTAPI
RtlMoveMemory64 (
   IN PVOID64 Destination,
   IN PVOID64 Source,
   IN ULONGLONG Length
   );

NTSYSAPI
VOID
NTAPI
RtlFillMemory64 (
   IN PVOID64 Destination,
   IN ULONGLONG Length,
   IN BYTE Fill
   );

NTSYSAPI
VOID
NTAPI
RtlZeroMemory64 (
   IN PVOID64 Destination,
   IN ULONGLONG Length
   );

#endif

typedef struct _MESSAGE_RESOURCE_ENTRY {
   WORD Length;
   WORD Flags;
   BYTE Text[ 1 ];
} MESSAGE_RESOURCE_ENTRY, *PMESSAGE_RESOURCE_ENTRY;

#define MESSAGE_RESOURCE_UNICODE 0x0001

typedef struct _MESSAGE_RESOURCE_BLOCK {
   DWORD LowId;
   DWORD HighId;
   DWORD OffsetToEntries;
} MESSAGE_RESOURCE_BLOCK, *PMESSAGE_RESOURCE_BLOCK;

typedef struct _MESSAGE_RESOURCE_DATA {
   DWORD NumberOfBlocks;
   MESSAGE_RESOURCE_BLOCK Blocks[ 1 ];
} MESSAGE_RESOURCE_DATA, *PMESSAGE_RESOURCE_DATA;


typedef struct _RTL_CRITICAL_SECTION_DEBUG {
   WORD Type;
   WORD CreatorBackTraceIndex;
   struct _RTL_CRITICAL_SECTION *CriticalSection;
   LIST_ENTRY ProcessLocksList;
   DWORD EntryCount;
   DWORD ContentionCount;
   DWORD Spare[ 2 ];
} RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG,
*PRTL_RESOURCE_DEBUG;

#define RTL_CRITSECT_TYPE 0
#define RTL_RESOURCE_TYPE 1

typedef struct _RTL_CRITICAL_SECTION {
   PRTL_CRITICAL_SECTION_DEBUG 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;
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
#define SEF_DACL_AUTO_INHERIT             0x1
#define SEF_SACL_AUTO_INHERIT             0x2
#define SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT 0x4
#define SEF_AVOID_PRIVILEGE_CHECK         0x8
#define WT_EXECUTEDEFAULT      0x00000000
#define WT_EXECUTEINIOTHREAD   0x00000001
#define WT_EXECUTEINUITHREAD   0x00000002
#define WT_EXECUTEINWAITTHREAD 0x00000004
#define WT_EXECUTEDELETEWAIT   0x00000008
#define WT_EXECUTEINLONGTHREAD 0x00000010
typedef VOID (NTAPI * WAITORTIMERCALLBACKFUNC)(PVOID, BOOLEAN );
typedef VOID (NTAPI * WORKERCALLBACKFUNC)(PVOID );
#define DLL_PROCESS_ATTACH 1
#define DLL_THREAD_ATTACH  2
#define DLL_THREAD_DETACH  3
#define DLL_PROCESS_DETACH 0

//
// 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.
//

typedef 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;
   //
} EVENTLOGRECORD, *PEVENTLOGRECORD;

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

#pragma warning(disable : 4200)
typedef struct _EVENTSFORLOGFILE {
   DWORD ulSize;
   WCHAR szLogicalLogFile[MAXLOGICALLOGNAMESIZE];                       //name of the logical file-security/application/system
   DWORD ulNumRecords;
   EVENTLOGRECORD pEventLogRecords[];
}EVENTSFORLOGFILE, *PEVENTSFORLOGFILE;

typedef 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
}PACKEDEVENTINFO, *PPACKEDEVENTINFO;

#pragma warning(default : 4200)
//SS: end of changes to support clustering
#define DBG_CONTINUE                    ((DWORD   )0x00010002L)
#define DBG_TERMINATE_THREAD            ((DWORD   )0x40010003L)
#define DBG_TERMINATE_PROCESS           ((DWORD   )0x40010004L)
#define DBG_CONTROL_C                   ((DWORD   )0x40010005L)
#define DBG_CONTROL_BREAK               ((DWORD   )0x40010008L)
#define DBG_EXCEPTION_NOT_HANDLED       ((DWORD   )0x80010001L)
//

// 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_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

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

// 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 )

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

typedef enum _CM_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
} SERVICE_NODE_TYPE;

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

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



//
// IOCTL_TAPE_ERASE definitions
//

#define TAPE_ERASE_SHORT            0L
#define TAPE_ERASE_LONG             1L

typedef struct _TAPE_ERASE {
   DWORD Type;
   BOOLEAN Immediate;
} TAPE_ERASE, *PTAPE_ERASE;

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

typedef struct _TAPE_PREPARE {
   DWORD Operation;
   BOOLEAN Immediate;
} TAPE_PREPARE, *PTAPE_PREPARE;

//
// IOCTL_TAPE_WRITE_MARKS definitions
//

#define TAPE_SETMARKS               0L
#define TAPE_FILEMARKS              1L
#define TAPE_SHORT_FILEMARKS        2L
#define TAPE_LONG_FILEMARKS         3L

typedef struct _TAPE_WRITE_MARKS {
   DWORD Type;
   DWORD Count;
   BOOLEAN Immediate;
} TAPE_WRITE_MARKS, *PTAPE_WRITE_MARKS;

//
// IOCTL_TAPE_GET_POSITION definitions
//

#define TAPE_ABSOLUTE_POSITION       0L
#define TAPE_LOGICAL_POSITION        1L
#define TAPE_PSEUDO_LOGICAL_POSITION 2L

typedef struct _TAPE_GET_POSITION {
   DWORD Type;
   DWORD Partition;
   LARGE_INTEGER Offset;
} TAPE_GET_POSITION, *PTAPE_GET_POSITION;

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

typedef struct _TAPE_SET_POSITION {
   DWORD Method;
   DWORD Partition;
   LARGE_INTEGER Offset;
   BOOLEAN Immediate;
} TAPE_SET_POSITION, *PTAPE_SET_POSITION;

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

typedef 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;
} TAPE_GET_DRIVE_PARAMETERS, *PTAPE_GET_DRIVE_PARAMETERS;

//
// IOCTL_TAPE_SET_DRIVE_PARAMETERS definitions
//

typedef struct _TAPE_SET_DRIVE_PARAMETERS {
   BOOLEAN ECC;
   BOOLEAN Compression;
   BOOLEAN DataPadding;
   BOOLEAN ReportSetmarks;
   DWORD EOTWarningZoneSize;
} TAPE_SET_DRIVE_PARAMETERS, *PTAPE_SET_DRIVE_PARAMETERS;

//
// IOCTL_TAPE_GET_MEDIA_PARAMETERS definitions
//

typedef struct _TAPE_GET_MEDIA_PARAMETERS {
   LARGE_INTEGER Capacity;
   LARGE_INTEGER Remaining;
   DWORD BlockSize;
   DWORD PartitionCount;
   BOOLEAN WriteProtected;
} TAPE_GET_MEDIA_PARAMETERS, *PTAPE_GET_MEDIA_PARAMETERS;

//
// IOCTL_TAPE_SET_MEDIA_PARAMETERS definitions
//

typedef struct _TAPE_SET_MEDIA_PARAMETERS {
   DWORD BlockSize;
} TAPE_SET_MEDIA_PARAMETERS, *PTAPE_SET_MEDIA_PARAMETERS;

//
// IOCTL_TAPE_CREATE_PARTITION definitions
//

#define TAPE_FIXED_PARTITIONS       0L
#define TAPE_SELECT_PARTITIONS      1L
#define TAPE_INITIATOR_PARTITIONS   2L

typedef struct _TAPE_CREATE_PARTITION {
   DWORD Method;
   DWORD Count;
   DWORD Size;
} TAPE_CREATE_PARTITION, *PTAPE_CREATE_PARTITION;


#ifdef __cplusplus
}
#endif

#endif /* _WINNT_ */
