/*++ BUILD Version: 0133 // Increment this if a change has global effects Copyright (c) Microsoft Corporation. All rights reserved. Module Name: ntosp.h Abstract: This module defines the NT types, constants, and functions that are exposed to external projects like Windows and Termsrv Revision History: --*/ #ifndef _NTOSP_ #define _NTOSP_ #ifdef _NTDDK_ #error "Can't include ntddk.h and ntosp.h" #else #define _NTDDK_ #endif #include #include #include #include #include #include #include // // Kernel Mutex Level Numbers (must be globallly assigned within executive) // The third token in the name is the sub-component name that defines and // uses the level number. // // // Used by Vdm for protecting io simulation structures // #define MUTEX_LEVEL_VDM_IO (ULONG)0x00000001 #define MUTEX_LEVEL_EX_PROFILE (ULONG)0x00000040 // // The LANMAN Redirector uses the file system major function, but defines // it's own mutex levels. We can do this safely because we know that the // local filesystem will never call the remote filesystem and vice versa. // #define MUTEX_LEVEL_RDR_FILESYS_DATABASE (ULONG)0x10100000 #define MUTEX_LEVEL_RDR_FILESYS_SECURITY (ULONG)0x10100001 // // File System levels. // #define MUTEX_LEVEL_FILESYSTEM_RAW_VCB (ULONG)0x11000006 // // In the NT STREAMS environment, a mutex is used to serialize open, close // and Scheduler threads executing in a subsystem-parallelized stack. // #define MUTEX_LEVEL_STREAMS_SUBSYS (ULONG)0x11001001 // // Mutex level used by LDT support on x86 // #define MUTEX_LEVEL_PS_LDT (ULONG)0x1F000000 #ifdef __cplusplus extern "C" { // extern "C" #endif // // Define types that are not exported. // typedef struct _ACCESS_STATE *PACCESS_STATE; typedef struct _BUS_HANDLER *PBUS_HANDLER; typedef struct _EJOB *PEJOB; typedef struct _EPROCESS *PEPROCESS; typedef struct _ERESOURCE *PERESOURCE; typedef struct _ETHREAD *PETHREAD; typedef struct _IO_TIMER *PIO_TIMER; typedef struct _IRP *PIRP; typedef struct _KPROCESS *PKPROCESS, *RESTRICTED_POINTER PRKPROCESS; typedef struct _KTHREAD *PKTHREAD, *PRKTHREAD; typedef struct _KTRAP_FRAME *PKTRAP_FRAME; typedef struct _LOADER_PARAMETER_BLOCK *PLOADER_PARAMETER_BLOCK; typedef struct _TRANSLATOR_INTERFACE *PTRANSLATOR_INTERFACE; typedef struct _HANDLE_TABLE *PHANDLE_TABLE; // // Define macros to fix up structure references // #define PEProcessToPKProcess(P) ((PKPROCESS)P) #if defined(_M_AMD64) PKTHREAD NTAPI KeGetCurrentThread( VOID ); #endif // defined(_M_AMD64) #if defined(_M_IX86) PKTHREAD NTAPI KeGetCurrentThread(); #endif // defined(_M_IX86) #if defined(_M_IA64) // // Define Address of Processor Control Registers. // #define KIPCR ((ULONG_PTR)(KADDRESS_BASE + 0xffff0000)) // kernel address of first PCR // // Define Pointer to Processor Control Registers. // #define PCR ((volatile KPCR * const)KIPCR) PKTHREAD NTAPI KeGetCurrentThread(); #endif // defined(_M_IA64) // // Define per processor nonpaged lookaside list descriptor structure. // struct _NPAGED_LOOKASIDE_LIST; typedef struct _PP_LOOKASIDE_LIST { struct _GENERAL_LOOKASIDE *P; struct _GENERAL_LOOKASIDE *L; } PP_LOOKASIDE_LIST, *PPP_LOOKASIDE_LIST; // // Define the number of small pool lists. // // N.B. This value is used in pool.h and is used to allocate single entry // lookaside lists in the processor block of each processor. #define POOL_SMALL_LISTS 32 // begin_ntddk begin_wdm begin_nthal begin_ntifs // // Define alignment macros to align structure sizes and pointers up and down. // #define ALIGN_DOWN(length, type) \ ((ULONG)(length) & ~(sizeof(type) - 1)) #define ALIGN_UP(length, type) \ (ALIGN_DOWN(((ULONG)(length) + sizeof(type) - 1), type)) #define ALIGN_DOWN_POINTER(address, type) \ ((PVOID)((ULONG_PTR)(address) & ~((ULONG_PTR)sizeof(type) - 1))) #define ALIGN_UP_POINTER(address, type) \ (ALIGN_DOWN_POINTER(((ULONG_PTR)(address) + sizeof(type) - 1), type)) #define POOL_TAGGING 1 #ifndef DBG #define DBG 0 #endif #if DBG #define IF_DEBUG if (TRUE) #else #define IF_DEBUG if (FALSE) #endif #if DEVL extern ULONG NtGlobalFlag; #define IF_NTOS_DEBUG( FlagName ) \ if (NtGlobalFlag & (FLG_ ## FlagName)) #else #define IF_NTOS_DEBUG( FlagName ) if (FALSE) #endif // // Kernel definitions that need to be here for forward reference purposes // // begin_ntndis // // Processor modes. // typedef CCHAR KPROCESSOR_MODE; typedef enum _MODE { KernelMode, UserMode, MaximumMode } MODE; // end_ntndis // // APC function types // // // Put in an empty definition for the KAPC so that the // routines can reference it before it is declared. // struct _KAPC; typedef VOID (*PKNORMAL_ROUTINE) ( IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); typedef VOID (*PKKERNEL_ROUTINE) ( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 ); typedef VOID (*PKRUNDOWN_ROUTINE) ( IN struct _KAPC *Apc ); typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE) ( IN PVOID SynchronizeContext ); typedef BOOLEAN (*PKTRANSFER_ROUTINE) ( VOID ); // // // Asynchronous Procedure Call (APC) object // // typedef struct _KAPC { CSHORT Type; CSHORT Size; ULONG Spare0; struct _KTHREAD *Thread; LIST_ENTRY ApcListEntry; PKKERNEL_ROUTINE KernelRoutine; PKRUNDOWN_ROUTINE RundownRoutine; PKNORMAL_ROUTINE NormalRoutine; PVOID NormalContext; // // N.B. The following two members MUST be together. // PVOID SystemArgument1; PVOID SystemArgument2; CCHAR ApcStateIndex; KPROCESSOR_MODE ApcMode; BOOLEAN Inserted; } KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC; // begin_ntndis // // DPC routine // struct _KDPC; typedef VOID (*PKDEFERRED_ROUTINE) ( IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); // // Define DPC importance. // // LowImportance - Queue DPC at end of target DPC queue. // MediumImportance - Queue DPC at end of target DPC queue. // HighImportance - Queue DPC at front of target DPC DPC queue. // // If there is currently a DPC active on the target processor, or a DPC // interrupt has already been requested on the target processor when a // DPC is queued, then no further action is necessary. The DPC will be // executed on the target processor when its queue entry is processed. // // If there is not a DPC active on the target processor and a DPC interrupt // has not been requested on the target processor, then the exact treatment // of the DPC is dependent on whether the host system is a UP system or an // MP system. // // UP system. // // If the DPC is of medium or high importance, the current DPC queue depth // is greater than the maximum target depth, or current DPC request rate is // less the minimum target rate, then a DPC interrupt is requested on the // host processor and the DPC will be processed when the interrupt occurs. // Otherwise, no DPC interupt is requested and the DPC execution will be // delayed until the DPC queue depth is greater that the target depth or the // minimum DPC rate is less than the target rate. // // MP system. // // If the DPC is being queued to another processor and the depth of the DPC // queue on the target processor is greater than the maximum target depth or // the DPC is of high importance, then a DPC interrupt is requested on the // target processor and the DPC will be processed when the interrupt occurs. // Otherwise, the DPC execution will be delayed on the target processor until // the DPC queue depth on the target processor is greater that the maximum // target depth or the minimum DPC rate on the target processor is less than // the target mimimum rate. // // If the DPC is being queued to the current processor and the DPC is not of // low importance, the current DPC queue depth is greater than the maximum // target depth, or the minimum DPC rate is less than the minimum target rate, // then a DPC interrupt is request on the current processor and the DPV will // be processed whne the interrupt occurs. Otherwise, no DPC interupt is // requested and the DPC execution will be delayed until the DPC queue depth // is greater that the target depth or the minimum DPC rate is less than the // target rate. // typedef enum _KDPC_IMPORTANCE { LowImportance, MediumImportance, HighImportance } KDPC_IMPORTANCE; // // Deferred Procedure Call (DPC) object // typedef struct _KDPC { CSHORT Type; UCHAR Number; UCHAR Importance; LIST_ENTRY DpcListEntry; PKDEFERRED_ROUTINE DeferredRoutine; PVOID DeferredContext; PVOID SystemArgument1; PVOID SystemArgument2; PULONG_PTR Lock; } KDPC, *PKDPC, *RESTRICTED_POINTER PRKDPC; // // Interprocessor interrupt worker routine function prototype. // typedef PVOID PKIPI_CONTEXT; typedef VOID (*PKIPI_WORKER)( IN PKIPI_CONTEXT PacketContext, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3 ); // // Define interprocessor interrupt performance counters. // typedef struct _KIPI_COUNTS { ULONG Freeze; ULONG Packet; ULONG DPC; ULONG APC; ULONG FlushSingleTb; ULONG FlushMultipleTb; ULONG FlushEntireTb; ULONG GenericCall; ULONG ChangeColor; ULONG SweepDcache; ULONG SweepIcache; ULONG SweepIcacheRange; ULONG FlushIoBuffers; ULONG GratuitousDPC; } KIPI_COUNTS, *PKIPI_COUNTS; #if defined(NT_UP) #define HOT_STATISTIC(a) a #else #define HOT_STATISTIC(a) (KeGetCurrentPrcb()->a) #endif // // I/O system definitions. // // Define a Memory Descriptor List (MDL) // // An MDL describes pages in a virtual buffer in terms of physical pages. The // pages associated with the buffer are described in an array that is allocated // just after the MDL header structure itself. In a future compiler this will // be placed at: // // ULONG Pages[]; // // Until this declaration is permitted, however, one simply calculates the // base of the array by adding one to the base MDL pointer: // // Pages = (PULONG) (Mdl + 1); // // Notice that while in the context of the subject thread, the base virtual // address of a buffer mapped by an MDL may be referenced using the following: // // Mdl->StartVa | Mdl->ByteOffset // typedef struct _MDL { struct _MDL *Next; CSHORT Size; CSHORT MdlFlags; struct _EPROCESS *Process; PVOID MappedSystemVa; PVOID StartVa; ULONG ByteCount; ULONG ByteOffset; } MDL, *PMDL; #define MDL_MAPPED_TO_SYSTEM_VA 0x0001 #define MDL_PAGES_LOCKED 0x0002 #define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 #define MDL_ALLOCATED_FIXED_SIZE 0x0008 #define MDL_PARTIAL 0x0010 #define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 #define MDL_IO_PAGE_READ 0x0040 #define MDL_WRITE_OPERATION 0x0080 #define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 #define MDL_FREE_EXTRA_PTES 0x0200 #define MDL_IO_SPACE 0x0800 #define MDL_NETWORK_HEADER 0x1000 #define MDL_MAPPING_CAN_FAIL 0x2000 #define MDL_ALLOCATED_MUST_SUCCEED 0x4000 #define MDL_MAPPING_FLAGS (MDL_MAPPED_TO_SYSTEM_VA | \ MDL_PAGES_LOCKED | \ MDL_SOURCE_IS_NONPAGED_POOL | \ MDL_PARTIAL_HAS_BEEN_MAPPED | \ MDL_PARENT_MAPPED_SYSTEM_VA | \ MDL_SYSTEM_VA | \ MDL_IO_SPACE ) // end_ntndis // // switch to DBG when appropriate // #if DBG #define PAGED_CODE() \ { if (KeGetCurrentIrql() > APC_LEVEL) { \ KdPrint(( "EX: Pageable code called at IRQL %d\n", KeGetCurrentIrql() )); \ ASSERT(FALSE); \ } \ } #else #define PAGED_CODE() NOP_FUNCTION; #endif // // Data structure used to represent client security context for a thread. // This data structure is used to support impersonation. // // THE FIELDS OF THIS DATA STRUCTURE SHOULD BE CONSIDERED OPAQUE // BY ALL EXCEPT THE SECURITY ROUTINES. // typedef struct _SECURITY_CLIENT_CONTEXT { SECURITY_QUALITY_OF_SERVICE SecurityQos; PACCESS_TOKEN ClientToken; BOOLEAN DirectlyAccessClientToken; BOOLEAN DirectAccessEffectiveOnly; BOOLEAN ServerIsRemote; TOKEN_CONTROL ClientTokenControl; } SECURITY_CLIENT_CONTEXT, *PSECURITY_CLIENT_CONTEXT; // // where // // SecurityQos - is the security quality of service information in effect // for this client. This information is used when directly accessing // the client's token. In this case, the information here over-rides // the information in the client's token. If a copy of the client's // token is requested, it must be generated using this information, // not the information in the client's token. In all cases, this // information may not provide greater access than the information // in the client's token. In particular, if the client's token is // an impersonation token with an impersonation level of // "SecurityDelegation", but the information in this field indicates // an impersonation level of "SecurityIdentification", then // the server may only get a copy of the token with an Identification // level of impersonation. // // ClientToken - If the DirectlyAccessClientToken field is FALSE, // then this field contains a pointer to a duplicate of the // client's token. Otherwise, this field points directly to // the client's token. // // DirectlyAccessClientToken - This boolean flag indicates whether the // token pointed to by ClientToken is a copy of the client's token // or is a direct reference to the client's token. A value of TRUE // indicates the client's token is directly accessed, FALSE indicates // a copy has been made. // // DirectAccessEffectiveOnly - This boolean flag indicates whether the // the disabled portions of the token that is currently directly // referenced may be enabled. This field is only valid if the // DirectlyAccessClientToken field is TRUE. In that case, this // value supersedes the EffectiveOnly value in the SecurityQos // FOR THE CURRENT TOKEN ONLY! If the client changes to impersonate // another client, this value may change. This value is always // minimized by the EffectiveOnly flag in the SecurityQos field. // // ServerIsRemote - If TRUE indicates that the server of the client's // request is remote. This is used for determining the legitimacy // of certain levels of impersonation and to determine how to // track context. // // ClientTokenControl - If the ServerIsRemote flag is TRUE, and the // tracking mode is DYNAMIC, then this field contains a copy of // the TOKEN_SOURCE from the client's token to assist in deciding // whether the information at the remote server needs to be // updated to match the current state of the client's security // context. // // // NOTE: At some point, we may find it worthwhile to keep an array of // elements in this data structure, where each element of the // array contains {ClientToken, ClientTokenControl} fields. // This would allow efficient handling of the case where a client // thread was constantly switching between a couple different // contexts - presumably impersonating client's of its own. // #if defined(_NTSYSTEM_) #define NTKERNELAPI #else #define NTKERNELAPI DECLSPEC_IMPORT // wdm ntddk nthal ntndis ntifs #endif #define NTHALAPI DECLSPEC_IMPORT // // Common dispatcher object header // // N.B. The size field contains the number of dwords in the structure. // typedef struct _DISPATCHER_HEADER { UCHAR Type; UCHAR Absolute; UCHAR Size; UCHAR Inserted; LONG SignalState; LIST_ENTRY WaitListHead; } DISPATCHER_HEADER; // // Event object // typedef struct _KEVENT { DISPATCHER_HEADER Header; } KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT; // // Timer object // typedef struct _KTIMER { DISPATCHER_HEADER Header; ULARGE_INTEGER DueTime; LIST_ENTRY TimerListEntry; struct _KDPC *Dpc; LONG Period; } KTIMER, *PKTIMER, *RESTRICTED_POINTER PRKTIMER; #ifndef _SLIST_HEADER_ #define _SLIST_HEADER_ #define SLIST_ENTRY SINGLE_LIST_ENTRY #define _SLIST_ENTRY _SINGLE_LIST_ENTRY #define PSLIST_ENTRY PSINGLE_LIST_ENTRY #if defined(_WIN64) typedef struct DECLSPEC_ALIGN(16) _SLIST_HEADER { ULONGLONG Alignment; ULONGLONG Region; } SLIST_HEADER; typedef struct _SLIST_HEADER *PSLIST_HEADER; #else typedef union _SLIST_HEADER { ULONGLONG Alignment; struct { SLIST_ENTRY Next; USHORT Depth; USHORT Sequence; }; } SLIST_HEADER, *PSLIST_HEADER; #endif #endif // // Some simple Rtl routines for IP address <-> string literal conversion // struct in_addr; struct in6_addr; NTSYSAPI PSTR NTAPI RtlIpv4AddressToStringA ( IN const struct in_addr *Addr, OUT PSTR S ); NTSYSAPI PSTR NTAPI RtlIpv6AddressToStringA ( IN const struct in6_addr *Addr, OUT PSTR S ); NTSYSAPI PWSTR NTAPI RtlIpv4AddressToStringW ( IN const struct in_addr *Addr, OUT PWSTR S ); NTSYSAPI PWSTR NTAPI RtlIpv6AddressToStringW ( IN const struct in6_addr *Addr, OUT PWSTR S ); NTSYSAPI NTSTATUS NTAPI RtlIpv4StringToAddressA ( IN PCSTR S, IN BOOLEAN Strict, OUT PCSTR *Terminator, OUT struct in_addr *Addr ); NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressA ( IN PCSTR S, OUT PCSTR *Terminator, OUT struct in6_addr *Addr ); NTSYSAPI NTSTATUS NTAPI RtlIpv4StringToAddressW ( IN PCWSTR S, IN BOOLEAN Strict, OUT LPCWSTR *Terminator, OUT struct in_addr *Addr ); NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressW ( IN PCWSTR S, OUT PCWSTR *Terminator, OUT struct in6_addr *Addr ); #ifdef UNICODE #define RtlIpv4AddressToString RtlIpv4AddressToStringW #define RtlIpv6AddressToString RtlIpv6AddressToStringW #define RtlIpv4StringToAddress RtlIpv4StringToAddressW #define RtlIpv6StringToAddress RtlIpv6StringToAddressW #else #define RtlIpv4AddressToString RtlIpv4AddressToStringA #define RtlIpv6AddressToString RtlIpv6AddressToStringA #define RtlIpv4StringToAddress RtlIpv4StringToAddressA #define RtlIpv6StringToAddress RtlIpv6StringToAddressA #endif // UNICODE // // Structures used by the kernel drivers to describe which ports must be // hooked out directly from the V86 emulator to the driver. // typedef enum _EMULATOR_PORT_ACCESS_TYPE { Uchar, Ushort, Ulong } EMULATOR_PORT_ACCESS_TYPE, *PEMULATOR_PORT_ACCESS_TYPE; // // Access Modes // #define EMULATOR_READ_ACCESS 0x01 #define EMULATOR_WRITE_ACCESS 0x02 typedef struct _EMULATOR_ACCESS_ENTRY { ULONG BasePort; ULONG NumConsecutivePorts; EMULATOR_PORT_ACCESS_TYPE AccessType; UCHAR AccessMode; UCHAR StringSupport; PVOID Routine; } EMULATOR_ACCESS_ENTRY, *PEMULATOR_ACCESS_ENTRY; // end_ntminiport // // These are the various function prototypes of the routines that are // provided by the kernel driver to hook out access to io ports. // typedef NTSTATUS (*PDRIVER_IO_PORT_UCHAR ) ( IN ULONG_PTR Context, IN ULONG Port, IN UCHAR AccessMode, IN OUT PUCHAR Data ); typedef NTSTATUS (*PDRIVER_IO_PORT_UCHAR_STRING ) ( IN ULONG_PTR Context, IN ULONG Port, IN UCHAR AccessMode, IN OUT PUCHAR Data, IN ULONG DataLength ); typedef NTSTATUS (*PDRIVER_IO_PORT_USHORT ) ( IN ULONG_PTR Context, IN ULONG Port, IN UCHAR AccessMode, IN OUT PUSHORT Data ); typedef NTSTATUS (*PDRIVER_IO_PORT_USHORT_STRING ) ( IN ULONG_PTR Context, IN ULONG Port, IN UCHAR AccessMode, IN OUT PUSHORT Data, IN ULONG DataLength // number of words ); typedef NTSTATUS (*PDRIVER_IO_PORT_ULONG ) ( IN ULONG_PTR Context, IN ULONG Port, IN UCHAR AccessMode, IN OUT PULONG Data ); typedef NTSTATUS (*PDRIVER_IO_PORT_ULONG_STRING ) ( IN ULONG_PTR Context, IN ULONG Port, IN UCHAR AccessMode, IN OUT PULONG Data, IN ULONG DataLength // number of dwords ); #if defined(_X86_) // // Types to use to contain PFNs and their counts. // typedef ULONG PFN_COUNT; typedef LONG SPFN_NUMBER, *PSPFN_NUMBER; typedef ULONG PFN_NUMBER, *PPFN_NUMBER; // // Define maximum size of flush multiple TB request. // #define FLUSH_MULTIPLE_MAXIMUM 16 // // Indicate that the i386 compiler supports the pragma textout construct. // #define ALLOC_PRAGMA 1 // // Indicate that the i386 compiler supports the DATA_SEG("INIT") and // DATA_SEG("PAGE") pragmas // #define ALLOC_DATA_PRAGMA 1 // // Interrupt Request Level definitions // #define PASSIVE_LEVEL 0 // Passive release level #define LOW_LEVEL 0 // Lowest interrupt level #define APC_LEVEL 1 // APC interrupt level #define DISPATCH_LEVEL 2 // Dispatcher level #define PROFILE_LEVEL 27 // timer used for profiling. #define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86 #define CLOCK2_LEVEL 28 // Interval clock 2 level #define IPI_LEVEL 29 // Interprocessor interrupt level #define POWER_LEVEL 30 // Power failure level #define HIGH_LEVEL 31 // Highest interrupt level #if defined(NT_UP) #define SYNCH_LEVEL DISPATCH_LEVEL // synchronization level - UP system #else #define SYNCH_LEVEL (IPI_LEVEL-1) // synchronization level - MP system #endif #define MODE_MASK 1 // // I/O space read and write macros. // // These have to be actual functions on the 386, because we need // to use assembler, but cannot return a value if we inline it. // // The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space. // (Use x86 move instructions, with LOCK prefix to force correct behavior // w.r.t. caches and write buffers.) // // The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space. // (Use x86 in/out instructions.) // NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR( PUCHAR Register ); NTKERNELAPI USHORT NTAPI READ_REGISTER_USHORT( PUSHORT Register ); NTKERNELAPI ULONG NTAPI READ_REGISTER_ULONG( PULONG Register ); NTKERNELAPI VOID NTAPI READ_REGISTER_BUFFER_UCHAR( PUCHAR Register, PUCHAR Buffer, ULONG Count ); NTKERNELAPI VOID NTAPI READ_REGISTER_BUFFER_USHORT( PUSHORT Register, PUSHORT Buffer, ULONG Count ); NTKERNELAPI VOID NTAPI READ_REGISTER_BUFFER_ULONG( PULONG Register, PULONG Buffer, ULONG Count ); NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR( PUCHAR Register, UCHAR Value ); NTKERNELAPI VOID NTAPI WRITE_REGISTER_USHORT( PUSHORT Register, USHORT Value ); NTKERNELAPI VOID NTAPI WRITE_REGISTER_ULONG( PULONG Register, ULONG Value ); NTKERNELAPI VOID NTAPI WRITE_REGISTER_BUFFER_UCHAR( PUCHAR Register, PUCHAR Buffer, ULONG Count ); NTKERNELAPI VOID NTAPI WRITE_REGISTER_BUFFER_USHORT( PUSHORT Register, PUSHORT Buffer, ULONG Count ); NTKERNELAPI VOID NTAPI WRITE_REGISTER_BUFFER_ULONG( PULONG Register, PULONG Buffer, ULONG Count ); NTHALAPI UCHAR NTAPI READ_PORT_UCHAR( PUCHAR Port ); NTHALAPI USHORT NTAPI READ_PORT_USHORT( PUSHORT Port ); NTHALAPI ULONG NTAPI READ_PORT_ULONG( PULONG Port ); NTHALAPI VOID NTAPI READ_PORT_BUFFER_UCHAR( PUCHAR Port, PUCHAR Buffer, ULONG Count ); NTHALAPI VOID NTAPI READ_PORT_BUFFER_USHORT( PUSHORT Port, PUSHORT Buffer, ULONG Count ); NTHALAPI VOID NTAPI READ_PORT_BUFFER_ULONG( PULONG Port, PULONG Buffer, ULONG Count ); NTHALAPI VOID NTAPI WRITE_PORT_UCHAR( PUCHAR Port, UCHAR Value ); NTHALAPI VOID NTAPI WRITE_PORT_USHORT( PUSHORT Port, USHORT Value ); NTHALAPI VOID NTAPI WRITE_PORT_ULONG( PULONG Port, ULONG Value ); NTHALAPI VOID NTAPI WRITE_PORT_BUFFER_UCHAR( PUCHAR Port, PUCHAR Buffer, ULONG Count ); NTHALAPI VOID NTAPI WRITE_PORT_BUFFER_USHORT( PUSHORT Port, PUSHORT Buffer, ULONG Count ); NTHALAPI VOID NTAPI WRITE_PORT_BUFFER_ULONG( PULONG Port, PULONG Buffer, ULONG Count ); // end_ntndis // // Get data cache fill size. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(KeGetDcacheFillSize) // Use GetDmaAlignment #endif #define KeGetDcacheFillSize() 1L #define KeFlushIoBuffers(Mdl, ReadOperation, DmaOperation) #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock) #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock) #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // begin_wdm #define KeQueryTickCount(CurrentCount ) { \ volatile PKSYSTEM_TIME _TickCount = *((PKSYSTEM_TIME *)(&KeTickCount)); \ while (TRUE) { \ (CurrentCount)->HighPart = _TickCount->High1Time; \ (CurrentCount)->LowPart = _TickCount->LowPart; \ if ((CurrentCount)->HighPart == _TickCount->High2Time) break; \ _asm { rep nop } \ } \ } // end_wdm #else VOID NTAPI KeQueryTickCount ( OUT PLARGE_INTEGER CurrentCount ); #endif // defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // // 386 hardware structures // // // A Page Table Entry on an Intel 386/486 has the following definition. // // **** NOTE A PRIVATE COPY OF THIS EXISTS IN THE MM\I386 DIRECTORY! **** // **** ANY CHANGES NEED TO BE MADE TO BOTH HEADER FILES. **** // typedef struct _HARDWARE_PTE_X86 { ULONG Valid : 1; ULONG Write : 1; ULONG Owner : 1; ULONG WriteThrough : 1; ULONG CacheDisable : 1; ULONG Accessed : 1; ULONG Dirty : 1; ULONG LargePage : 1; ULONG Global : 1; ULONG CopyOnWrite : 1; // software field ULONG Prototype : 1; // software field ULONG reserved : 1; // software field ULONG PageFrameNumber : 20; } HARDWARE_PTE_X86, *PHARDWARE_PTE_X86; typedef struct _HARDWARE_PTE_X86PAE { union { struct { ULONGLONG Valid : 1; ULONGLONG Write : 1; ULONGLONG Owner : 1; ULONGLONG WriteThrough : 1; ULONGLONG CacheDisable : 1; ULONGLONG Accessed : 1; ULONGLONG Dirty : 1; ULONGLONG LargePage : 1; ULONGLONG Global : 1; ULONGLONG CopyOnWrite : 1; // software field ULONGLONG Prototype : 1; // software field ULONGLONG reserved0 : 1; // software field ULONGLONG PageFrameNumber : 26; ULONGLONG reserved1 : 26; // software field }; struct { ULONG LowPart; ULONG HighPart; }; }; } HARDWARE_PTE_X86PAE, *PHARDWARE_PTE_X86PAE; // // Special check to work around mspdb limitation // #if defined (_NTSYM_HARDWARE_PTE_SYMBOL_) #if !defined (_X86PAE_) typedef struct _HARDWARE_PTE { ULONG Valid : 1; ULONG Write : 1; ULONG Owner : 1; ULONG WriteThrough : 1; ULONG CacheDisable : 1; ULONG Accessed : 1; ULONG Dirty : 1; ULONG LargePage : 1; ULONG Global : 1; ULONG CopyOnWrite : 1; // software field ULONG Prototype : 1; // software field ULONG reserved : 1; // software field ULONG PageFrameNumber : 20; } HARDWARE_PTE, *PHARDWARE_PTE; #else typedef struct _HARDWARE_PTE { union { struct { ULONGLONG Valid : 1; ULONGLONG Write : 1; ULONGLONG Owner : 1; ULONGLONG WriteThrough : 1; ULONGLONG CacheDisable : 1; ULONGLONG Accessed : 1; ULONGLONG Dirty : 1; ULONGLONG LargePage : 1; ULONGLONG Global : 1; ULONGLONG CopyOnWrite : 1; // software field ULONGLONG Prototype : 1; // software field ULONGLONG reserved0 : 1; // software field ULONGLONG PageFrameNumber : 26; ULONGLONG reserved1 : 26; // software field }; struct { ULONG LowPart; ULONG HighPart; }; }; } HARDWARE_PTE, *PHARDWARE_PTE; #endif #else #if !defined (_X86PAE_) typedef HARDWARE_PTE_X86 HARDWARE_PTE; typedef PHARDWARE_PTE_X86 PHARDWARE_PTE; #else typedef HARDWARE_PTE_X86PAE HARDWARE_PTE; typedef PHARDWARE_PTE_X86PAE PHARDWARE_PTE; #endif #endif // // GDT Entry // typedef struct _KGDTENTRY { USHORT LimitLow; USHORT BaseLow; union { struct { UCHAR BaseMid; UCHAR Flags1; // Declare as bytes to avoid alignment UCHAR Flags2; // Problems. UCHAR BaseHi; } Bytes; struct { ULONG BaseMid : 8; ULONG Type : 5; ULONG Dpl : 2; ULONG Pres : 1; ULONG LimitHi : 4; ULONG Sys : 1; ULONG Reserved_0 : 1; ULONG Default_Big : 1; ULONG Granularity : 1; ULONG BaseHi : 8; } Bits; } HighWord; } KGDTENTRY, *PKGDTENTRY; #define TYPE_CODE 0x10 // 11010 = Code, Readable, NOT Conforming, Accessed #define TYPE_DATA 0x12 // 10010 = Data, ReadWrite, NOT Expanddown, Accessed #define TYPE_TSS 0x01 // 01001 = NonBusy TSS #define TYPE_LDT 0x02 // 00010 = LDT #define DPL_USER 3 #define DPL_SYSTEM 0 #define GRAN_BYTE 0 #define GRAN_PAGE 1 #define SELECTOR_TABLE_INDEX 0x04 // // Entry of Interrupt Descriptor Table (IDTENTRY) // typedef struct _KIDTENTRY { USHORT Offset; USHORT Selector; USHORT Access; USHORT ExtendedOffset; } KIDTENTRY; typedef KIDTENTRY *PKIDTENTRY; // // TSS (Task switch segment) NT only uses to control stack switches. // // The only fields we actually care about are Esp0, Ss0, the IoMapBase // and the IoAccessMaps themselves. // // // N.B. Size of TSS must be <= 0xDFFF // // // The interrupt direction bitmap is used on Pentium to allow // the processor to emulate V86 mode software interrupts for us. // There is one for each IOPM. It is located by subtracting // 32 from the IOPM base in the Tss. // #define INT_DIRECTION_MAP_SIZE 32 typedef UCHAR KINT_DIRECTION_MAP[INT_DIRECTION_MAP_SIZE]; #define IOPM_COUNT 1 // Number of i/o access maps that // exist (in addition to // IO_ACCESS_MAP_NONE) #define IO_ACCESS_MAP_NONE 0 #define IOPM_SIZE 8192 // Size of map callers can set. #define PIOPM_SIZE 8196 // Size of structure we must allocate // to hold it. typedef UCHAR KIO_ACCESS_MAP[IOPM_SIZE]; typedef KIO_ACCESS_MAP *PKIO_ACCESS_MAP; typedef struct _KiIoAccessMap { KINT_DIRECTION_MAP DirectionMap; UCHAR IoMap[PIOPM_SIZE]; } KIIO_ACCESS_MAP; typedef struct _KTSS { USHORT Backlink; USHORT Reserved0; ULONG Esp0; USHORT Ss0; USHORT Reserved1; ULONG NotUsed1[4]; ULONG CR3; ULONG Eip; ULONG EFlags; ULONG Eax; ULONG Ecx; ULONG Edx; ULONG Ebx; ULONG Esp; ULONG Ebp; ULONG Esi; ULONG Edi; USHORT Es; USHORT Reserved2; USHORT Cs; USHORT Reserved3; USHORT Ss; USHORT Reserved4; USHORT Ds; USHORT Reserved5; USHORT Fs; USHORT Reserved6; USHORT Gs; USHORT Reserved7; USHORT LDT; USHORT Reserved8; USHORT Flags; USHORT IoMapBase; KIIO_ACCESS_MAP IoMaps[IOPM_COUNT]; // // This is the Software interrupt direction bitmap associated with // IO_ACCESS_MAP_NONE // KINT_DIRECTION_MAP IntDirectionMap; } KTSS, *PKTSS; #define KiComputeIopmOffset(MapNumber) \ (MapNumber == IO_ACCESS_MAP_NONE) ? \ (USHORT)(sizeof(KTSS)) : \ (USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap)) // begin_windbgkd // // Special Registers for i386 // #ifdef _X86_ typedef struct _DESCRIPTOR { USHORT Pad; USHORT Limit; ULONG Base; } KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KSPECIAL_REGISTERS { ULONG Cr0; ULONG Cr2; ULONG Cr3; ULONG Cr4; ULONG KernelDr0; ULONG KernelDr1; ULONG KernelDr2; ULONG KernelDr3; ULONG KernelDr6; ULONG KernelDr7; KDESCRIPTOR Gdtr; KDESCRIPTOR Idtr; USHORT Tr; USHORT Ldtr; ULONG Reserved[6]; } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; // // Processor State frame: Before a processor freezes itself, it // dumps the processor state to the processor state frame for // debugger to examine. // typedef struct _KPROCESSOR_STATE { struct _CONTEXT ContextFrame; struct _KSPECIAL_REGISTERS SpecialRegisters; } KPROCESSOR_STATE, *PKPROCESSOR_STATE; #endif // _X86_ // end_windbgkd // // Processor Control Block (PRCB) // #define PRCB_MAJOR_VERSION 1 #define PRCB_MINOR_VERSION 1 #define PRCB_BUILD_DEBUG 0x0001 #define PRCB_BUILD_UNIPROCESSOR 0x0002 typedef struct _KPRCB { // // Start of the architecturally defined section of the PRCB. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // USHORT MinorVersion; USHORT MajorVersion; struct _KTHREAD *CurrentThread; struct _KTHREAD *NextThread; struct _KTHREAD *IdleThread; CCHAR Number; CCHAR Reserved; USHORT BuildType; KAFFINITY SetMember; CCHAR CpuType; CCHAR CpuID; USHORT CpuStep; struct _KPROCESSOR_STATE ProcessorState; ULONG KernelReserved[16]; // For use by the kernel ULONG HalReserved[16]; // For use by Hal // // Per processor lock queue entries. // // N.B. The following padding is such that the first lock entry falls in the // last eight bytes of a cache line. This makes the dispatcher lock and // the context swap lock lie in separate cache lines. // UCHAR PrcbPad0[28 + 64]; KSPIN_LOCK_QUEUE LockQueue[16]; UCHAR PrcbPad1[8]; // End of the architecturally defined section of the PRCB. } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB; // // Processor Control Region Structure Definition // #define PCR_MINOR_VERSION 1 #define PCR_MAJOR_VERSION 1 typedef struct _KPCR { // // Start of the architecturally defined section of the PCR. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // NT_TIB NtTib; struct _KPCR *SelfPcr; // flat address of this PCR struct _KPRCB *Prcb; // pointer to Prcb KIRQL Irql; ULONG IRR; ULONG IrrActive; ULONG IDR; PVOID KdVersionBlock; struct _KIDTENTRY *IDT; struct _KGDTENTRY *GDT; struct _KTSS *TSS; USHORT MajorVersion; USHORT MinorVersion; KAFFINITY SetMember; ULONG StallScaleFactor; UCHAR DebugActive; UCHAR Number; } KPCR, *PKPCR; #define EFLAGS_TF 0x00000100L #define EFLAGS_INTERRUPT_MASK 0x00000200L #define EFLAGS_DF_MASK 0x00000400L #define EFLAGS_V86_MASK 0x00020000L #define EFLAGS_ALIGN_CHECK 0x00040000L #define EFLAGS_IOPL_MASK 0x00003000L #define EFLAGS_VIF 0x00080000L #define EFLAGS_VIP 0x00100000L #define EFLAGS_USER_SANITIZE 0x003e0dd7L // end_nthal // // Sanitize segCS and eFlags based on a processor mode. // // If kernel mode, // force CPL == 0 // // If user mode, // force CPL == 3 // #define SANITIZE_SEG(segCS, mode) (\ ((mode) == KernelMode ? \ ((0x00000000L) | ((segCS) & 0xfffc)) : \ ((0x00000003L) | ((segCS) & 0xffff)))) // // If kernel mode, then // let caller specify Carry, Parity, AuxCarry, Zero, Sign, Trap, // Direction, Overflow, Interrupt, AlignCheck. // // If user mode, then // let caller specify Carry, Parity, AuxCarry, Zero, Sign, Trap, // Direction, Overflow, AlignCheck. // force Interrupts on. // #define SANITIZE_FLAGS(eFlags, mode) (\ ((mode) == KernelMode ? \ ((0x00000000L) | ((eFlags) & 0x003e0fd7)) : \ ((((eFlags) & EFLAGS_V86_MASK) && KeI386VdmIoplAllowed) ? \ (((eFlags) & KeI386EFlagsAndMaskV86) | KeI386EFlagsOrMaskV86) : \ ((EFLAGS_INTERRUPT_MASK) | ((eFlags) & EFLAGS_USER_SANITIZE))))) // // Masks for Dr7 and sanitize macros for various Dr registers. // #define DR6_LEGAL 0x0000e00f #define DR7_LEGAL 0xffff0155 // R/W, LEN for Dr0-Dr4, // Local enable for Dr0-Dr4, // Le for "perfect" trapping #define DR7_ACTIVE 0x00000055 // If any of these bits are set, a Dr is active #define SANITIZE_DR6(Dr6, mode) ((Dr6 & DR6_LEGAL)); #define SANITIZE_DR7(Dr7, mode) ((Dr7 & DR7_LEGAL)); #define SANITIZE_DRADDR(DrReg, mode) ( \ (mode) == KernelMode ? \ (DrReg) : \ (((PVOID)DrReg <= MM_HIGHEST_USER_ADDRESS) ? \ (DrReg) : \ (0) \ ) \ ) // // Define macro to clear reserved bits from MXCSR so that we don't // GP fault when doing an FRSTOR // extern ULONG KiMXCsrMask; #define SANITIZE_MXCSR(_mxcsr_) ((_mxcsr_) & KiMXCsrMask) // // Nonvolatile context pointers // // bryanwi 21 feb 90 - This is bogus. The 386 doesn't have // enough nonvolatile context to make this // structure worthwhile. Can't declare a // field to be void, so declare a Junk structure // instead. typedef struct _KNONVOLATILE_CONTEXT_POINTERS { ULONG Junk; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; // begin_nthal // // Trap frame // // NOTE - We deal only with 32bit registers, so the assembler equivalents // are always the extended forms. // // NOTE - Unless you want to run like slow molasses everywhere in the // the system, this structure must be of DWORD length, DWORD // aligned, and its elements must all be DWORD aligned. // // NOTE WELL - // // The i386 does not build stack frames in a consistent format, the // frames vary depending on whether or not a privilege transition // was involved. // // In order to make NtContinue work for both user mode and kernel // mode callers, we must force a canonical stack. // // If we're called from kernel mode, this structure is 8 bytes longer // than the actual frame! // // WARNING: // // KTRAP_FRAME_LENGTH needs to be 16byte integral (at present.) // typedef struct _KTRAP_FRAME { // // Following 4 values are only used and defined for DBG systems, // but are always allocated to make switching from DBG to non-DBG // and back quicker. They are not DEVL because they have a non-0 // performance impact. // ULONG DbgEbp; // Copy of User EBP set up so KB will work. ULONG DbgEip; // EIP of caller to system call, again, for KB. ULONG DbgArgMark; // Marker to show no args here. ULONG DbgArgPointer; // Pointer to the actual args // // Temporary values used when frames are edited. // // // NOTE: Any code that want's ESP must materialize it, since it // is not stored in the frame for kernel mode callers. // // And code that sets ESP in a KERNEL mode frame, must put // the new value in TempEsp, make sure that TempSegCs holds // the real SegCs value, and put a special marker value into SegCs. // ULONG TempSegCs; ULONG TempEsp; // // Debug registers. // ULONG Dr0; ULONG Dr1; ULONG Dr2; ULONG Dr3; ULONG Dr6; ULONG Dr7; // // Segment registers // ULONG SegGs; ULONG SegEs; ULONG SegDs; // // Volatile registers // ULONG Edx; ULONG Ecx; ULONG Eax; // // Nesting state, not part of context record // ULONG PreviousPreviousMode; PEXCEPTION_REGISTRATION_RECORD ExceptionList; // Trash if caller was user mode. // Saved exception list if caller // was kernel mode or we're in // an interrupt. // // FS is TIB/PCR pointer, is here to make save sequence easy // ULONG SegFs; // // Non-volatile registers // ULONG Edi; ULONG Esi; ULONG Ebx; ULONG Ebp; // // Control registers // ULONG ErrCode; ULONG Eip; ULONG SegCs; ULONG EFlags; ULONG HardwareEsp; // WARNING - segSS:esp are only here for stacks ULONG HardwareSegSs; // that involve a ring transition. ULONG V86Es; // these will be present for all transitions from ULONG V86Ds; // V86 mode ULONG V86Fs; ULONG V86Gs; } KTRAP_FRAME; typedef KTRAP_FRAME *PKTRAP_FRAME; typedef KTRAP_FRAME *PKEXCEPTION_FRAME; #define KTRAP_FRAME_LENGTH (sizeof(KTRAP_FRAME)) #define KTRAP_FRAME_ALIGN (sizeof(ULONG)) #define KTRAP_FRAME_ROUND (KTRAP_FRAME_ALIGN-1) // // Bits forced to 0 in SegCs if Esp has been edited. // #define FRAME_EDITED 0xfff8 // end_nthal // // The frame saved by KiCallUserMode is defined here to allow // the kernel debugger to trace the entire kernel stack // when usermode callouts are pending. // typedef struct _KCALLOUT_FRAME { ULONG InStk; // saved initial stack address ULONG TrFr; // saved callback trap frame ULONG CbStk; // saved callback stack address ULONG Edi; // saved nonvolatile registers ULONG Esi; // ULONG Ebx; // ULONG Ebp; // ULONG Ret; // saved return address ULONG OutBf; // address to store output buffer ULONG OutLn; // address to store output length } KCALLOUT_FRAME; typedef KCALLOUT_FRAME *PKCALLOUT_FRAME; // // Switch Frame // // 386 doesn't have an "exception frame", and doesn't normally make // any use of nonvolatile context register structures. // // However, swapcontext in ctxswap.c and KeInitializeThread in // thredini.c need to share common stack structure used at thread // startup and switch time. // // This is that structure. // typedef struct _KSWITCHFRAME { ULONG ExceptionList; ULONG Eflags; ULONG RetAddr; } KSWITCHFRAME, *PKSWITCHFRAME; // // Various 387 defines // #define I386_80387_NP_VECTOR 0x07 // trap 7 when hardware not present // begin_ntddk begin_wdm // // The non-volatile 387 state // typedef struct _KFLOATING_SAVE { ULONG ControlWord; ULONG StatusWord; ULONG ErrorOffset; ULONG ErrorSelector; ULONG DataOffset; // Not used in wdm ULONG DataSelector; ULONG Cr0NpxState; ULONG Spare1; // Not used in wdm } KFLOATING_SAVE, *PKFLOATING_SAVE; // // i386 Specific portions of mm component // // // Define the page size for the Intel 386 as 4096 (0x1000). // #define PAGE_SIZE 0x1000 // // Define the number of trailing zeroes in a page aligned virtual address. // This is used as the shift count when shifting virtual addresses to // virtual page numbers. // #define PAGE_SHIFT 12L // end_ntndis end_wdm // // Define the number of bits to shift to right justify the Page Directory Index // field of a PTE. // #define PDI_SHIFT_X86 22 #define PDI_SHIFT_X86PAE 21 #if !defined (_X86PAE_) #define PDI_SHIFT PDI_SHIFT_X86 #else #define PDI_SHIFT PDI_SHIFT_X86PAE #define PPI_SHIFT 30 #endif // // Define the number of bits to shift to right justify the Page Table Index // field of a PTE. // #define PTI_SHIFT 12 // // Define the highest user address and user probe address. // extern PVOID *MmHighestUserAddress; extern PVOID *MmSystemRangeStart; extern ULONG *MmUserProbeAddress; #define MM_HIGHEST_USER_ADDRESS *MmHighestUserAddress #define MM_SYSTEM_RANGE_START *MmSystemRangeStart #define MM_USER_PROBE_ADDRESS *MmUserProbeAddress // // The lowest user address reserves the low 64k. // #define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 // // The lowest address for system space. // #if !defined (_X86PAE_) #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000 #else #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0C00000 #endif // begin_wdm #define MmGetProcedureAddress(Address) (Address) #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address) // end_ntddk end_wdm // // Define the number of bits to shift to right justify the Page Directory Index // field of a PTE. // #define PDI_SHIFT_X86 22 #define PDI_SHIFT_X86PAE 21 #if !defined (_X86PAE_) #define PDI_SHIFT PDI_SHIFT_X86 #else #define PDI_SHIFT PDI_SHIFT_X86PAE #define PPI_SHIFT 30 #endif // // Define the number of bits to shift to right justify the Page Table Index // field of a PTE. // #define PTI_SHIFT 12 // // Define page directory and page base addresses. // #define PDE_BASE_X86 0xc0300000 #define PDE_BASE_X86PAE 0xc0600000 #define PTE_TOP_X86 0xC03FFFFF #define PDE_TOP_X86 0xC0300FFF #define PTE_TOP_X86PAE 0xC07FFFFF #define PDE_TOP_X86PAE 0xC0603FFF #if !defined (_X86PAE_) #define PDE_BASE PDE_BASE_X86 #define PTE_TOP PTE_TOP_X86 #define PDE_TOP PDE_TOP_X86 #else #define PDE_BASE PDE_BASE_X86PAE #define PTE_TOP PTE_TOP_X86PAE #define PDE_TOP PDE_TOP_X86PAE #endif #define PTE_BASE 0xc0000000 #define KIP0PCRADDRESS 0xffdff000 #define KI_USER_SHARED_DATA 0xffdf0000 #define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA) // // Result type definition for i386. (Machine specific enumerate type // which is return type for portable exinterlockedincrement/decrement // procedures.) In general, you should use the enumerated type defined // in ex.h instead of directly referencing these constants. // // Flags loaded into AH by LAHF instruction #define EFLAG_SIGN 0x8000 #define EFLAG_ZERO 0x4000 #define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO) #define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) #define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT) #define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT) // // Convert various portable ExInterlock APIs into their architectural // equivalents. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInterlockedIncrementLong) // Use InterlockedIncrement #pragma deprecated(ExInterlockedDecrementLong) // Use InterlockedDecrement #pragma deprecated(ExInterlockedExchangeUlong) // Use InterlockedExchange #endif #define ExInterlockedIncrementLong(Addend,Lock) \ Exfi386InterlockedIncrementLong(Addend) #define ExInterlockedDecrementLong(Addend,Lock) \ Exfi386InterlockedDecrementLong(Addend) #define ExInterlockedExchangeUlong(Target,Value,Lock) \ Exfi386InterlockedExchangeUlong(Target,Value) // begin_wdm #define ExInterlockedAddUlong ExfInterlockedAddUlong #define ExInterlockedInsertHeadList ExfInterlockedInsertHeadList #define ExInterlockedInsertTailList ExfInterlockedInsertTailList #define ExInterlockedRemoveHeadList ExfInterlockedRemoveHeadList #define ExInterlockedPopEntryList ExfInterlockedPopEntryList #define ExInterlockedPushEntryList ExfInterlockedPushEntryList // end_wdm // // Prototypes for architectural specific versions of Exi386 Api // // // Interlocked result type is portable, but its values are machine specific. // Constants for value are in i386.h, mips.h, etc. // typedef enum _INTERLOCKED_RESULT { ResultNegative = RESULT_NEGATIVE, ResultZero = RESULT_ZERO, ResultPositive = RESULT_POSITIVE } INTERLOCKED_RESULT; NTKERNELAPI INTERLOCKED_RESULT FASTCALL Exfi386InterlockedIncrementLong ( IN PLONG Addend ); NTKERNELAPI INTERLOCKED_RESULT FASTCALL Exfi386InterlockedDecrementLong ( IN PLONG Addend ); NTKERNELAPI ULONG FASTCALL Exfi386InterlockedExchangeUlong ( IN PULONG Target, IN ULONG Value ); #if !defined(_WINBASE_) && !defined(NONTOSPINTERLOCK) #if !defined(MIDL_PASS) // wdm #if defined(NO_INTERLOCKED_INTRINSICS) || defined(_CROSS_PLATFORM_) // begin_wdm NTKERNELAPI LONG FASTCALL InterlockedIncrement( IN LONG volatile *Addend ); NTKERNELAPI LONG FASTCALL InterlockedDecrement( IN LONG volatile *Addend ); NTKERNELAPI LONG FASTCALL InterlockedExchange( IN OUT LONG volatile *Target, IN LONG Value ); #define InterlockedExchangePointer(Target, Value) \ (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value)) LONG FASTCALL InterlockedExchangeAdd( IN OUT LONG volatile *Addend, IN LONG Increment ); NTKERNELAPI LONG FASTCALL InterlockedCompareExchange( IN OUT LONG volatile *Destination, IN LONG ExChange, IN LONG Comperand ); #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \ (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand) #define InterlockedCompareExchange64(Destination, ExChange, Comperand) \ ExfInterlockedCompareExchange64(Destination, &(ExChange), &(Comperand)) NTKERNELAPI LONGLONG FASTCALL ExfInterlockedCompareExchange64( IN OUT LONGLONG volatile *Destination, IN PLONGLONG ExChange, IN PLONGLONG Comperand ); // end_wdm #else // NO_INTERLOCKED_INCREMENTS || _CROSS_PLATFORM_ #define InterlockedExchangePointer(Target, Value) \ (PVOID)InterlockedExchange((PLONG)Target, (LONG)Value) #if (_MSC_FULL_VER > 13009037) LONG __cdecl _InterlockedExchange( IN OUT LONG volatile *Target, IN LONG Value ); #pragma intrinsic (_InterlockedExchange) #define InterlockedExchange _InterlockedExchange #else FORCEINLINE LONG FASTCALL InterlockedExchange( IN OUT LONG volatile *Target, IN LONG Value ) { __asm { mov eax, Value mov ecx, Target xchg [ecx], eax } } #endif #if (_MSC_FULL_VER > 13009037) LONG __cdecl _InterlockedIncrement( IN LONG volatile *Addend ); #pragma intrinsic (_InterlockedIncrement) #define InterlockedIncrement _InterlockedIncrement #else #define InterlockedIncrement(Addend) (InterlockedExchangeAdd (Addend, 1)+1) #endif #if (_MSC_FULL_VER > 13009037) LONG __cdecl _InterlockedDecrement( IN LONG volatile *Addend ); #pragma intrinsic (_InterlockedDecrement) #define InterlockedDecrement _InterlockedDecrement #else #define InterlockedDecrement(Addend) (InterlockedExchangeAdd (Addend, -1)-1) #endif #if (_MSC_FULL_VER > 13009037) LONG __cdecl _InterlockedExchangeAdd( IN OUT LONG volatile *Addend, IN LONG Increment ); #pragma intrinsic (_InterlockedExchangeAdd) #define InterlockedExchangeAdd _InterlockedExchangeAdd #else // begin_wdm FORCEINLINE LONG FASTCALL InterlockedExchangeAdd( IN OUT LONG volatile *Addend, IN LONG Increment ) { __asm { mov eax, Increment mov ecx, Addend lock xadd [ecx], eax } } // end_wdm #endif #if (_MSC_FULL_VER > 13009037) LONG __cdecl _InterlockedCompareExchange ( IN OUT LONG volatile *Destination, IN LONG ExChange, IN LONG Comperand ); #pragma intrinsic (_InterlockedCompareExchange) #define InterlockedCompareExchange (LONG)_InterlockedCompareExchange #else FORCEINLINE LONG FASTCALL InterlockedCompareExchange( IN OUT LONG volatile *Destination, IN LONG Exchange, IN LONG Comperand ) { __asm { mov eax, Comperand mov ecx, Destination mov edx, Exchange lock cmpxchg [ecx], edx } } #endif #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \ (PVOID)InterlockedCompareExchange((PLONG)Destination, (LONG)ExChange, (LONG)Comperand) #define InterlockedCompareExchange64(Destination, ExChange, Comperand) \ ExfInterlockedCompareExchange64(Destination, &(ExChange), &(Comperand)) NTKERNELAPI LONGLONG FASTCALL ExfInterlockedCompareExchange64( IN OUT LONGLONG volatile *Destination, IN PLONGLONG ExChange, IN PLONGLONG Comperand ); #endif // INTERLOCKED_INTRINSICS || _CROSS_PLATFORM_ // begin_wdm #endif // MIDL_PASS #endif // __WINBASE__ && !NONTOSPINTERLOCK typedef struct _PROCESS_IO_PORT_HANDLER_INFORMATION { BOOLEAN Install; // true if handlers to be installed ULONG NumEntries; ULONG Context; PEMULATOR_ACCESS_ENTRY EmulatorAccessEntries; } PROCESS_IO_PORT_HANDLER_INFORMATION, *PPROCESS_IO_PORT_HANDLER_INFORMATION; // // Vdm Objects and Io handling structure // typedef struct _VDM_IO_HANDLER_FUNCTIONS { PDRIVER_IO_PORT_ULONG UlongIo; PDRIVER_IO_PORT_ULONG_STRING UlongStringIo; PDRIVER_IO_PORT_USHORT UshortIo[2]; PDRIVER_IO_PORT_USHORT_STRING UshortStringIo[2]; PDRIVER_IO_PORT_UCHAR UcharIo[4]; PDRIVER_IO_PORT_UCHAR_STRING UcharStringIo[4]; } VDM_IO_HANDLER_FUNCTIONS, *PVDM_IO_HANDLER_FUNCTIONS; typedef struct _VDM_IO_HANDLER { struct _VDM_IO_HANDLER *Next; ULONG PortNumber; VDM_IO_HANDLER_FUNCTIONS IoFunctions[2]; } VDM_IO_HANDLER, *PVDM_IO_HANDLER; // begin_nthal begin_ntddk begin_wdm #if !defined(MIDL_PASS) && defined(_M_IX86) // // i386 function definitions // #pragma warning(disable:4035) // re-enable below // end_wdm #if NT_UP #define _PCR ds:[KIP0PCRADDRESS] #else #define _PCR fs:[0] #endif // // Get address of current processor block. // // WARNING: This inline macro can only be used by the kernel or hal // FORCEINLINE PKPRCB NTAPI KeGetCurrentPrcb (VOID) { __asm { mov eax, _PCR KPCR.Prcb } } // begin_ntddk begin_wdm // // Get current IRQL. // // On x86 this function resides in the HAL // NTHALAPI KIRQL NTAPI KeGetCurrentIrql(); // end_wdm // // Get the current processor number // FORCEINLINE ULONG NTAPI KeGetCurrentProcessorNumber(VOID) { __asm { movzx eax, _PCR KPCR.Number } } #pragma warning(default:4035) // begin_wdm #endif // !defined(MIDL_PASS) && defined(_M_IX86) NTKERNELAPI NTSTATUS NTAPI KeSaveFloatingPointState ( OUT PKFLOATING_SAVE FloatSave ); NTKERNELAPI NTSTATUS NTAPI KeRestoreFloatingPointState ( IN PKFLOATING_SAVE FloatSave ); // end_ntddk end_wdm // begin_nthal NTKERNELAPI VOID NTAPI KeProfileInterruptWithSource ( IN struct _KTRAP_FRAME *TrapFrame, IN KPROFILE_SOURCE ProfileSource ); #endif // defined(_X86_) #ifdef _X86_ VOID NTAPI Ke386SetLdtProcess ( struct _KPROCESS *Process, PLDT_ENTRY Ldt, ULONG Limit ); VOID NTAPI Ke386SetDescriptorProcess ( struct _KPROCESS *Process, ULONG Offset, LDT_ENTRY LdtEntry ); VOID NTAPI Ke386GetGdtEntryThread ( struct _KTHREAD *Thread, ULONG Offset, PKGDTENTRY Descriptor ); BOOLEAN NTAPI Ke386SetIoAccessMap ( ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap ); BOOLEAN NTAPI Ke386QueryIoAccessMap ( ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap ); BOOLEAN NTAPI Ke386IoSetAccessProcess ( struct _KPROCESS *Process, ULONG MapNumber ); VOID NTAPI Ke386SetIOPL( struct _KPROCESS *Process ); NTSTATUS NTAPI Ke386CallBios ( IN ULONG BiosCommand, IN OUT PCONTEXT BiosArguments ); VOID NTAPI KiEditIopmDpc ( IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); BOOLEAN NTAPI Ki386GetSelectorParameters( IN USHORT Selector, OUT PULONG Flags, OUT PULONG Base, OUT PULONG Limit ); ULONG Ki386DispatchOpcodeV86 ( IN PKTRAP_FRAME TrapFrame ); NTSTATUS NTAPI Ke386SetVdmInterruptHandler ( IN struct _KPROCESS *Process, IN ULONG Interrupt, IN USHORT Selector, IN ULONG Offset, IN BOOLEAN Gate32 ); #endif //_X86_ #define INIT_SYSTEMROOT_LINKNAME "\\SystemRoot" #define INIT_SYSTEMROOT_DLLPATH "\\SystemRoot\\System32" #define INIT_SYSTEMROOT_BINPATH "\\SystemRoot\\System32" extern ULONG NtBuildNumber; #if defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS) // // Define intrinsic function to do in's and out's. // #ifdef __cplusplus extern "C" { #endif UCHAR __inbyte ( IN USHORT Port ); USHORT __inword ( IN USHORT Port ); ULONG __indword ( IN USHORT Port ); VOID __outbyte ( IN USHORT Port, IN UCHAR Data ); VOID __outword ( IN USHORT Port, IN USHORT Data ); VOID __outdword ( IN USHORT Port, IN ULONG Data ); VOID __inbytestring ( IN USHORT Port, IN PUCHAR Buffer, IN ULONG Count ); VOID __inwordstring ( IN USHORT Port, IN PUSHORT Buffer, IN ULONG Count ); VOID __indwordstring ( IN USHORT Port, IN PULONG Buffer, IN ULONG Count ); VOID __outbytestring ( IN USHORT Port, IN PUCHAR Buffer, IN ULONG Count ); VOID __outwordstring ( IN USHORT Port, IN PUSHORT Buffer, IN ULONG Count ); VOID __outdwordstring ( IN USHORT Port, IN PULONG Buffer, IN ULONG Count ); #ifdef __cplusplus } #endif #pragma intrinsic(__inbyte) #pragma intrinsic(__inword) #pragma intrinsic(__indword) #pragma intrinsic(__outbyte) #pragma intrinsic(__outword) #pragma intrinsic(__outdword) #pragma intrinsic(__inbytestring) #pragma intrinsic(__inwordstring) #pragma intrinsic(__indwordstring) #pragma intrinsic(__outbytestring) #pragma intrinsic(__outwordstring) #pragma intrinsic(__outdwordstring) // // Interlocked intrinsic functions. // #define InterlockedAnd _InterlockedAnd #define InterlockedOr _InterlockedOr #define InterlockedXor _InterlockedXor #define InterlockedIncrement _InterlockedIncrement #define InterlockedDecrement _InterlockedDecrement #define InterlockedAdd _InterlockedAdd #define InterlockedExchange _InterlockedExchange #define InterlockedExchangeAdd _InterlockedExchangeAdd #define InterlockedCompareExchange _InterlockedCompareExchange #define InterlockedAnd64 _InterlockedAnd64 #define InterlockedOr64 _InterlockedOr64 #define InterlockedXor64 _InterlockedXor64 #define InterlockedIncrement64 _InterlockedIncrement64 #define InterlockedDecrement64 _InterlockedDecrement64 #define InterlockedAdd64 _InterlockedAdd64 #define InterlockedExchange64 _InterlockedExchange64 #define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 #define InterlockedCompareExchange64 _InterlockedCompareExchange64 #define InterlockedExchangePointer _InterlockedExchangePointer #define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer #ifdef __cplusplus extern "C" { #endif LONG InterlockedAnd ( IN OUT LONG volatile *Destination, IN LONG Value ); LONG InterlockedOr ( IN OUT LONG volatile *Destination, IN LONG Value ); LONG InterlockedXor ( IN OUT LONG volatile *Destination, IN LONG Value ); LONG64 InterlockedAnd64 ( IN OUT LONG64 volatile *Destination, IN LONG64 Value ); LONG64 InterlockedOr64 ( IN OUT LONG64 volatile *Destination, IN LONG64 Value ); LONG64 InterlockedXor64 ( IN OUT LONG64 volatile *Destination, IN LONG64 Value ); LONG InterlockedIncrement( IN OUT LONG volatile *Addend ); LONG InterlockedDecrement( IN OUT LONG volatile *Addend ); LONG InterlockedExchange( IN OUT LONG volatile *Target, IN LONG Value ); LONG InterlockedExchangeAdd( IN OUT LONG volatile *Addend, IN LONG Value ); #if !defined(_X86AMD64_) __forceinline LONG InterlockedAdd( IN OUT LONG volatile *Addend, IN LONG Value ) { return InterlockedExchangeAdd(Addend, Value) + Value; } #endif LONG InterlockedCompareExchange ( IN OUT LONG volatile *Destination, IN LONG ExChange, IN LONG Comperand ); LONG64 InterlockedIncrement64( IN OUT LONG64 volatile *Addend ); LONG64 InterlockedDecrement64( IN OUT LONG64 volatile *Addend ); LONG64 InterlockedExchange64( IN OUT LONG64 volatile *Target, IN LONG64 Value ); LONG64 InterlockedExchangeAdd64( IN OUT LONG64 volatile *Addend, IN LONG64 Value ); #if !defined(_X86AMD64_) __forceinline LONG64 InterlockedAdd64( IN OUT LONG64 volatile *Addend, IN LONG64 Value ) { return InterlockedExchangeAdd64(Addend, Value) + Value; } #endif LONG64 InterlockedCompareExchange64 ( IN OUT LONG64 volatile *Destination, IN LONG64 ExChange, IN LONG64 Comperand ); PVOID InterlockedCompareExchangePointer ( IN OUT PVOID volatile *Destination, IN PVOID Exchange, IN PVOID Comperand ); PVOID InterlockedExchangePointer( IN OUT PVOID volatile *Target, IN PVOID Value ); #pragma intrinsic(_InterlockedAnd) #pragma intrinsic(_InterlockedOr) #pragma intrinsic(_InterlockedXor) #pragma intrinsic(_InterlockedIncrement) #pragma intrinsic(_InterlockedDecrement) #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedXor64) #pragma intrinsic(_InterlockedIncrement64) #pragma intrinsic(_InterlockedDecrement64) #pragma intrinsic(_InterlockedExchange64) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangePointer) #pragma intrinsic(_InterlockedCompareExchangePointer) #ifdef __cplusplus } #endif #endif // defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS) #if defined(_AMD64_) // // Types to use to contain PFNs and their counts. // typedef ULONG PFN_COUNT; typedef LONG64 SPFN_NUMBER, *PSPFN_NUMBER; typedef ULONG64 PFN_NUMBER, *PPFN_NUMBER; // // Define maximum size of flush multiple TB request. // #define FLUSH_MULTIPLE_MAXIMUM 16 // // Indicate that the AMD64 compiler supports the allocate pragmas. // #define ALLOC_PRAGMA 1 #define ALLOC_DATA_PRAGMA 1 // // Define constants for bits in CR0. // #define CR0_PE 0x00000001 // protection enable #define CR0_MP 0x00000002 // math present #define CR0_EM 0x00000004 // emulate math coprocessor #define CR0_TS 0x00000008 // task switched #define CR0_ET 0x00000010 // extension type (80387) #define CR0_NE 0x00000020 // numeric error #define CR0_WP 0x00010000 // write protect #define CR0_AM 0x00040000 // alignment mask #define CR0_NW 0x20000000 // not write-through #define CR0_CD 0x40000000 // cache disable #define CR0_PG 0x80000000 // paging // // Define functions to read and write CR0. // #ifdef __cplusplus extern "C" { #endif #define ReadCR0() __readcr0() ULONG64 __readcr0 ( VOID ); #define WriteCR0(Data) __writecr0(Data) VOID __writecr0 ( IN ULONG64 Data ); #pragma intrinsic(__readcr0) #pragma intrinsic(__writecr0) // // Define functions to read and write CR3. // #define ReadCR3() __readcr3() ULONG64 __readcr3 ( VOID ); #define WriteCR3(Data) __writecr3(Data) VOID __writecr3 ( IN ULONG64 Data ); #pragma intrinsic(__readcr3) #pragma intrinsic(__writecr3) // // Define constants for bits in CR4. // #define CR4_VME 0x00000001 // V86 mode extensions #define CR4_PVI 0x00000002 // Protected mode virtual interrupts #define CR4_TSD 0x00000004 // Time stamp disable #define CR4_DE 0x00000008 // Debugging Extensions #define CR4_PSE 0x00000010 // Page size extensions #define CR4_PAE 0x00000020 // Physical address extensions #define CR4_MCE 0x00000040 // Machine check enable #define CR4_PGE 0x00000080 // Page global enable #define CR4_FXSR 0x00000200 // FXSR used by OS #define CR4_XMMEXCPT 0x00000400 // XMMI used by OS // // Define functions to read and write CR4. // #define ReadCR4() __readcr4() ULONG64 __readcr4 ( VOID ); #define WriteCR4(Data) __writecr4(Data) VOID __writecr4 ( IN ULONG64 Data ); #pragma intrinsic(__readcr4) #pragma intrinsic(__writecr4) // // Define functions to read and write CR8. // // CR8 is the APIC TPR register. // #define ReadCR8() __readcr8() ULONG64 __readcr8 ( VOID ); #define WriteCR8(Data) __writecr8(Data) VOID __writecr8 ( IN ULONG64 Data ); #pragma intrinsic(__readcr8) #pragma intrinsic(__writecr8) #ifdef __cplusplus } #endif // // Interrupt Request Level definitions // #define PASSIVE_LEVEL 0 // Passive release level #define LOW_LEVEL 0 // Lowest interrupt level #define APC_LEVEL 1 // APC interrupt level #define DISPATCH_LEVEL 2 // Dispatcher level #define CLOCK_LEVEL 13 // Interval clock level #define IPI_LEVEL 14 // Interprocessor interrupt level #define POWER_LEVEL 14 // Power failure level #define PROFILE_LEVEL 15 // timer used for profiling. #define HIGH_LEVEL 15 // Highest interrupt level #if defined(NT_UP) #define SYNCH_LEVEL DISPATCH_LEVEL // synchronization level #else #define SYNCH_LEVEL (IPI_LEVEL - 1) // synchronization level #endif #define IRQL_VECTOR_OFFSET 2 // offset from IRQL to vector / 16 #define MODE_MASK 1 // // I/O space read and write macros. // // The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space. // (Use move instructions, with LOCK prefix to force correct behavior // w.r.t. caches and write buffers.) // // The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space. // (Use in/out instructions.) // __forceinline UCHAR READ_REGISTER_UCHAR ( volatile UCHAR *Register ) { return *Register; } __forceinline USHORT READ_REGISTER_USHORT ( volatile USHORT *Register ) { return *Register; } __forceinline ULONG READ_REGISTER_ULONG ( volatile ULONG *Register ) { return *Register; } __forceinline VOID READ_REGISTER_BUFFER_UCHAR ( PUCHAR Register, PUCHAR Buffer, ULONG Count ) { __movsb(Register, Buffer, Count); return; } __forceinline VOID READ_REGISTER_BUFFER_USHORT ( PUSHORT Register, PUSHORT Buffer, ULONG Count ) { __movsw(Register, Buffer, Count); return; } __forceinline VOID READ_REGISTER_BUFFER_ULONG ( PULONG Register, PULONG Buffer, ULONG Count ) { __movsd(Register, Buffer, Count); return; } __forceinline VOID WRITE_REGISTER_UCHAR ( PUCHAR Register, UCHAR Value ) { LONG Synch; *Register = Value; InterlockedOr(&Synch, 1); return; } __forceinline VOID WRITE_REGISTER_USHORT ( PUSHORT Register, USHORT Value ) { LONG Synch; *Register = Value; InterlockedOr(&Synch, 1); return; } __forceinline VOID WRITE_REGISTER_ULONG ( PULONG Register, ULONG Value ) { LONG Synch; *Register = Value; InterlockedOr(&Synch, 1); return; } __forceinline VOID WRITE_REGISTER_BUFFER_UCHAR ( PUCHAR Register, PUCHAR Buffer, ULONG Count ) { LONG Synch; __movsb(Register, Buffer, Count); InterlockedOr(&Synch, 1); return; } __forceinline VOID WRITE_REGISTER_BUFFER_USHORT ( PUSHORT Register, PUSHORT Buffer, ULONG Count ) { LONG Synch; __movsw(Register, Buffer, Count); InterlockedOr(&Synch, 1); return; } __forceinline VOID WRITE_REGISTER_BUFFER_ULONG ( PULONG Register, PULONG Buffer, ULONG Count ) { LONG Synch; __movsd(Register, Buffer, Count); InterlockedOr(&Synch, 1); return; } __forceinline UCHAR READ_PORT_UCHAR ( PUCHAR Port ) { return __inbyte((USHORT)((ULONG64)Port)); } __forceinline USHORT READ_PORT_USHORT ( PUSHORT Port ) { return __inword((USHORT)((ULONG64)Port)); } __forceinline ULONG READ_PORT_ULONG ( PULONG Port ) { return __indword((USHORT)((ULONG64)Port)); } __forceinline VOID READ_PORT_BUFFER_UCHAR ( PUCHAR Port, PUCHAR Buffer, ULONG Count ) { __inbytestring((USHORT)((ULONG64)Port), Buffer, Count); return; } __forceinline VOID READ_PORT_BUFFER_USHORT ( PUSHORT Port, PUSHORT Buffer, ULONG Count ) { __inwordstring((USHORT)((ULONG64)Port), Buffer, Count); return; } __forceinline VOID READ_PORT_BUFFER_ULONG ( PULONG Port, PULONG Buffer, ULONG Count ) { __indwordstring((USHORT)((ULONG64)Port), Buffer, Count); return; } __forceinline VOID WRITE_PORT_UCHAR ( PUCHAR Port, UCHAR Value ) { __outbyte((USHORT)((ULONG64)Port), Value); return; } __forceinline VOID WRITE_PORT_USHORT ( PUSHORT Port, USHORT Value ) { __outword((USHORT)((ULONG64)Port), Value); return; } __forceinline VOID WRITE_PORT_ULONG ( PULONG Port, ULONG Value ) { __outdword((USHORT)((ULONG64)Port), Value); return; } __forceinline VOID WRITE_PORT_BUFFER_UCHAR ( PUCHAR Port, PUCHAR Buffer, ULONG Count ) { __outbytestring((USHORT)((ULONG64)Port), Buffer, Count); return; } __forceinline VOID WRITE_PORT_BUFFER_USHORT ( PUSHORT Port, PUSHORT Buffer, ULONG Count ) { __outwordstring((USHORT)((ULONG64)Port), Buffer, Count); return; } __forceinline VOID WRITE_PORT_BUFFER_ULONG ( PULONG Port, PULONG Buffer, ULONG Count ) { __outdwordstring((USHORT)((ULONG64)Port), Buffer, Count); return; } // end_ntndis // // Get data cache fill size. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(KeGetDcacheFillSize) // Use GetDmaAlignment #endif #define KeGetDcacheFillSize() 1L #define KeFlushIoBuffers(Mdl, ReadOperation, DmaOperation) #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock) #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock) #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // begin_wdm #define KeQueryTickCount(CurrentCount ) \ *(PULONG64)(CurrentCount) = **((volatile ULONG64 **)(&KeTickCount)); // end_wdm #else VOID KeQueryTickCount ( OUT PLARGE_INTEGER CurrentCount ); #endif // defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // // AMD64 hardware structures // // A Page Table Entry on an AMD64 has the following definition. // #define _HARDWARE_PTE_WORKING_SET_BITS 11 typedef struct _HARDWARE_PTE { ULONG64 Valid : 1; ULONG64 Write : 1; // UP version ULONG64 Owner : 1; ULONG64 WriteThrough : 1; ULONG64 CacheDisable : 1; ULONG64 Accessed : 1; ULONG64 Dirty : 1; ULONG64 LargePage : 1; ULONG64 Global : 1; ULONG64 CopyOnWrite : 1; // software field ULONG64 Prototype : 1; // software field ULONG64 reserved0 : 1; // software field ULONG64 PageFrameNumber : 28; ULONG64 reserved1 : 24 - (_HARDWARE_PTE_WORKING_SET_BITS+1); ULONG64 SoftwareWsIndex : _HARDWARE_PTE_WORKING_SET_BITS; ULONG64 NoExecute : 1; } HARDWARE_PTE, *PHARDWARE_PTE; // // Define macro to initialize directory table base. // #define INITIALIZE_DIRECTORY_TABLE_BASE(dirbase,pfn) \ *((PULONG64)(dirbase)) = (((ULONG64)(pfn)) << PAGE_SHIFT) // // Define Global Descriptor Table (GDT) entry structure and constants. // // Define descriptor type codes. // #define TYPE_CODE 0x1A // 11010 = code, read only #define TYPE_DATA 0x12 // 10010 = data, read and write #define TYPE_TSS64 0x09 // 01001 = task state segment // // Define descriptor privilege levels for user and system. // #define DPL_USER 3 #define DPL_SYSTEM 0 // // Define limit granularity. // #define GRANULARITY_BYTE 0 #define GRANULARITY_PAGE 1 #define SELECTOR_TABLE_INDEX 0x04 typedef union _KGDTENTRY64 { struct { USHORT LimitLow; USHORT BaseLow; union { struct { UCHAR BaseMiddle; UCHAR Flags1; UCHAR Flags2; UCHAR BaseHigh; } Bytes; struct { ULONG BaseMiddle : 8; ULONG Type : 5; ULONG Dpl : 2; ULONG Present : 1; ULONG LimitHigh : 4; ULONG System : 1; ULONG LongMode : 1; ULONG DefaultBig : 1; ULONG Granularity : 1; ULONG BaseHigh : 8; } Bits; }; ULONG BaseUpper; ULONG MustBeZero; }; ULONG64 Alignment; } KGDTENTRY64, *PKGDTENTRY64; // // Define Interrupt Descriptor Table (IDT) entry structure and constants. // typedef union _KIDTENTRY64 { struct { USHORT OffsetLow; USHORT Selector; USHORT IstIndex : 3; USHORT Reserved0 : 5; USHORT Type : 5; USHORT Dpl : 2; USHORT Present : 1; USHORT OffsetMiddle; ULONG OffsetHigh; ULONG Reserved1; }; ULONG64 Alignment; } KIDTENTRY64, *PKIDTENTRY64; // // Define two union definitions used for parsing addresses into the // component fields required by a GDT. // typedef union _KGDT_BASE { struct { USHORT BaseLow; UCHAR BaseMiddle; UCHAR BaseHigh; ULONG BaseUpper; }; ULONG64 Base; } KGDT_BASE, *PKGDT_BASE; C_ASSERT(sizeof(KGDT_BASE) == sizeof(ULONG64)); typedef union _KGDT_LIMIT { struct { USHORT LimitLow; USHORT LimitHigh : 4; USHORT MustBeZero : 12; }; ULONG Limit; } KGDT_LIMIT, *PKGDT_LIMIT; C_ASSERT(sizeof(KGDT_LIMIT) == sizeof(ULONG)); // // Define Task State Segment (TSS) structure and constants. // // Task switches are not supported by the AMD64, but a task state segment // must be present to define the kernel stack pointer and I/O map base. // // N.B. This structure is misaligned as per the AMD64 specification. // // N.B. The size of TSS must be <= 0xDFFF. // #define IOPM_SIZE 8192 typedef UCHAR KIO_ACCESS_MAP[IOPM_SIZE]; typedef KIO_ACCESS_MAP *PKIO_ACCESS_MAP; #pragma pack(push, 4) typedef struct _KTSS64 { ULONG Reserved0; ULONG64 Rsp0; ULONG64 Rsp1; ULONG64 Rsp2; // // Element 0 of the Ist is reserved // ULONG64 Ist[8]; ULONG64 Reserved1; USHORT IoMapBase; KIO_ACCESS_MAP IoMap; ULONG IoMapEnd; ULONG Reserved2; } KTSS64, *PKTSS64; #pragma pack(pop) C_ASSERT((sizeof(KTSS64) % sizeof(PVOID)) == 0); #define TSS_IST_RESERVED 0 #define TSS_IST_PANIC 1 #define TSS_IST_MCA 2 #define IO_ACCESS_MAP_NONE FALSE #define KiComputeIopmOffset(Enable) \ ((Enable == FALSE) ? \ (USHORT)(sizeof(KTSS64)) : (USHORT)(FIELD_OFFSET(KTSS64, IoMap[0]))) // begin_windbgkd #if defined(_AMD64_) // // Define pseudo descriptor structures for both 64- and 32-bit mode. // typedef struct _KDESCRIPTOR { USHORT Pad[3]; USHORT Limit; PVOID Base; } KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KDESCRIPTOR32 { USHORT Pad[3]; USHORT Limit; ULONG Base; } KDESCRIPTOR32, *PKDESCRIPTOR32; // // Define special kernel registers and the initial MXCSR value. // typedef struct _KSPECIAL_REGISTERS { ULONG64 Cr0; ULONG64 Cr2; ULONG64 Cr3; ULONG64 Cr4; ULONG64 KernelDr0; ULONG64 KernelDr1; ULONG64 KernelDr2; ULONG64 KernelDr3; ULONG64 KernelDr6; ULONG64 KernelDr7; KDESCRIPTOR Gdtr; KDESCRIPTOR Idtr; USHORT Tr; USHORT Ldtr; ULONG MxCsr; } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; // // Define processor state structure. // typedef struct _KPROCESSOR_STATE { KSPECIAL_REGISTERS SpecialRegisters; CONTEXT ContextFrame; } KPROCESSOR_STATE, *PKPROCESSOR_STATE; #endif // _AMD64_ // end_windbgkd // // Processor Control Block (PRCB) // #define PRCB_MAJOR_VERSION 1 #define PRCB_MINOR_VERSION 1 #define PRCB_BUILD_DEBUG 0x1 #define PRCB_BUILD_UNIPROCESSOR 0x2 typedef struct _KPRCB { // // Start of the architecturally defined section of the PRCB. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // USHORT MinorVersion; USHORT MajorVersion; CCHAR Number; CCHAR Reserved; USHORT BuildType; struct _KTHREAD *CurrentThread; struct _KTHREAD *NextThread; struct _KTHREAD *IdleThread; KAFFINITY SetMember; KAFFINITY NotSetMember; KPROCESSOR_STATE ProcessorState; CCHAR CpuType; CCHAR CpuID; USHORT CpuStep; ULONG KernelReserved[16]; ULONG HalReserved[16]; UCHAR PrcbPad0[88 + 112]; // // End of the architecturally defined section of the PRCB. // } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB; // // Processor Control Region Structure Definition // #define PCR_MINOR_VERSION 1 #define PCR_MAJOR_VERSION 1 typedef struct _KPCR { // // Start of the architecturally defined section of the PCR. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // NT_TIB NtTib; struct _KPRCB *CurrentPrcb; ULONG64 SavedRcx; ULONG64 SavedR11; KIRQL Irql; UCHAR SecondLevelCacheAssociativity; UCHAR Number; UCHAR Fill0; ULONG Irr; ULONG IrrActive; ULONG Idr; USHORT MajorVersion; USHORT MinorVersion; ULONG StallScaleFactor; union _KIDTENTRY64 *IdtBase; union _KGDTENTRY64 *GdtBase; struct _KTSS64 *TssBase; } KPCR, *PKPCR; // // Define legacy floating status word bit masks. // #define FSW_INVALID_OPERATION 0x1 #define FSW_DENORMAL 0x2 #define FSW_ZERO_DIVIDE 0x4 #define FSW_OVERFLOW 0x8 #define FSW_UNDERFLOW 0x10 #define FSW_PRECISION 0x20 #define FSW_STACK_FAULT 0x40 #define FSW_CONDITION_CODE_0 0x100 #define FSW_CONDITION_CODE_1 0x200 #define FSW_CONDITION_CODE_2 0x400 #define FSW_CONDITION_CODE_3 0x4000 #define FSW_ERROR_MASK (FSW_INVALID_OPERATION | FSW_DENORMAL | \ FSW_ZERO_DIVIDE | FSW_OVERFLOW | FSW_UNDERFLOW | \ FSW_PRECISION | FSW_STACK_FAULT) // // Define MxCsr floating control/status word bit masks. // // No flush to zero, round to nearest, and all exception masked. // #define INITIAL_MXCSR 0x1f80 // initial MXCSR vlaue #define XSW_INVALID_OPERATION 0x1 #define XSW_DENORMAL 0x2 #define XSW_ZERO_DIVIDE 0x4 #define XSW_OVERFLOW 0x8 #define XSW_UNDERFLOW 0x10 #define XSW_PRECISION 0x20 #define XSW_ERROR_MASK (XSW_INVALID_OPERATION | XSW_DENORMAL | \ XSW_ZERO_DIVIDE | XSW_OVERFLOW | XSW_UNDERFLOW | \ XSW_PRECISION) #define XSW_ERROR_SHIFT 7 #define XCW_INVALID_OPERATION 0x80 #define XCW_DENORMAL 0x100 #define XCW_ZERO_DIVIDE 0x200 #define XCW_OVERFLOW 0x400 #define XCW_UNDERFLOW 0x800 #define XCW_PRECISION 0x1000 #define XCW_ROUND_CONTROL 0x6000 #define XCW_FLUSH_ZERO 0x8000 // // Define EFLAG bit masks and shift offsets. // #define EFLAGS_CF_MASK 0x00000001 // carry flag #define EFLAGS_PF_MASK 0x00000004 // parity flag #define EFALGS_AF_MASK 0x00000010 // auxiliary carry flag #define EFLAGS_ZF_MASK 0x00000040 // zero flag #define EFLAGS_SF_MASK 0x00000080 // sign flag #define EFLAGS_TF_MASK 0x00000100 // trap flag #define EFLAGS_IF_MASK 0x00000200 // interrupt flag #define EFLAGS_DF_MASK 0x00000400 // direction flag #define EFLAGS_OF_MASK 0x00000800 // overflow flag #define EFLAGS_IOPL_MASK 0x00003000 // I/O privilege level #define EFLAGS_NT_MASK 0x00004000 // nested task #define EFLAGS_RF_MASK 0x00010000 // resume flag #define EFLAGS_VM_MASK 0x00020000 // virtual 8086 mode #define EFLAGS_AC_MASK 0x00040000 // alignment check #define EFLAGS_VIF_MASK 0x00080000 // virtual interrupt flag #define EFLAGS_VIP_MASK 0x00100000 // virtual interrupt pending #define EFLAGS_ID_MASK 0x00200000 // identification flag #define EFLAGS_TF_SHIFT 8 // trap #define EFLAGS_IF_SHIFT 9 // interrupt enable // end_nthal // // Define sanitize EFLAGS macro. // // If kernel mode, then // caller can specify Carry, Parity, AuxCarry, Zero, Sign, Trap, // Interrupt, Direction, Overflow, Align Check, identification. // // If user mode, then // caller can specify Carry, Parity, AuxCarry, Zero, Sign, Trap, // Direction, Overflow, Align Check, and force Interrupt on. // #define EFLAGS_KERNEL_SANITIZE 0x00240fd5L #define EFLAGS_USER_SANITIZE 0x00040dd5L #define SANITIZE_EFLAGS(eFlags, mode) ( \ ((mode) == KernelMode ? \ ((eFlags) & EFLAGS_KERNEL_SANITIZE) : \ (((eFlags) & EFLAGS_USER_SANITIZE) | EFLAGS_IF_MASK))) // // Define sanitize debug register macros. // // Define control register settable bits and active mask. // #define DR7_LEGAL 0xffff0155 #define DR7_ACTIVE 0x00000055 // // Define macro to sanitize the debug control register. // #define SANITIZE_DR7(Dr7, mode) ((Dr7 & DR7_LEGAL)); // // Define macro to santitize debug address registers. // #define SANITIZE_DRADDR(DrReg, mode) \ ((mode) == KernelMode ? \ (DrReg) : \ (((PVOID)(DrReg) <= MM_HIGHEST_USER_ADDRESS) ? (DrReg) : 0)) \ // // Define macro to clear reserved bits from MXCSR. // #define SANITIZE_MXCSR(_mxcsr_) ((_mxcsr_) & 0xffbf) // // Define macro to clear reserved bits for legacy FP control word. // #define SANITIZE_FCW(_fcw_) ((_fcw_) & 0x1f37) // begin_nthal // // Exception frame // // This frame is established when handling an exception. It provides a place // to save all nonvolatile registers. The volatile registers will already // have been saved in a trap frame. // typedef struct _KEXCEPTION_FRAME { // // Home address for the parameter registers. // ULONG64 P1Home; ULONG64 P2Home; ULONG64 P3Home; ULONG64 P4Home; ULONG64 P5; // // Kernel callout initial stack value. // ULONG64 InitialStack; // // Saved nonvolatile floating registers. // M128 Xmm6; M128 Xmm7; M128 Xmm8; M128 Xmm9; M128 Xmm10; M128 Xmm11; M128 Xmm12; M128 Xmm13; M128 Xmm14; M128 Xmm15; // // Kernel callout frame variables. // ULONG64 TrapFrame; ULONG64 CallbackStack; ULONG64 OutputBuffer; ULONG64 OutputLength; // // Saved nonvolatile register - not always saved. // ULONG64 Fill1; ULONG64 Rbp; // // Saved nonvolatile registers. // ULONG64 Rbx; ULONG64 Rdi; ULONG64 Rsi; ULONG64 R12; ULONG64 R13; ULONG64 R14; ULONG64 R15; // // EFLAGS and return address. // ULONG64 Return; } KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; #define KEXCEPTION_FRAME_LENGTH sizeof(KEXCEPTION_FRAME) C_ASSERT((sizeof(KEXCEPTION_FRAME) & STACK_ROUND) == 0); #define EXCEPTION_RECORD_LENGTH \ ((sizeof(EXCEPTION_RECORD) + STACK_ROUND) & ~STACK_ROUND) // // Machine Frame // // This frame is established by code that trampolines to user mode (e.g. user // APC, user callback, dispatch user exception, etc.). The purpose of this // frame is to allow unwinding through these callbacks if an exception occurs. // // N.B. This frame is identical to the frame that is pushed for a trap without // an error code and is identical to the hardware part of a trap frame. // typedef struct _MACHINE_FRAME { ULONG64 Rip; USHORT SegCs; USHORT Fill1[3]; ULONG EFlags; ULONG Fill2; ULONG64 Rsp; USHORT SegSs; USHORT Fill3[3]; } MACHINE_FRAME, *PMACHINE_FRAME; #define MACHINE_FRAME_LENGTH sizeof(MACHINE_FRAME) C_ASSERT((sizeof(MACHINE_FRAME) & STACK_ROUND) == 8); // // Switch Frame // // This frame is established by the code that switches context from one // thread to the next and is used by the thread initialization code to // construct a stack that will start the execution of a thread in the // thread start up code. // typedef struct _KSWITCH_FRAME { ULONG64 Fill0; ULONG MxCsr; KIRQL ApcBypass; BOOLEAN NpxSave; UCHAR Fill1[2]; ULONG64 Rbp; ULONG64 Return; } KSWITCH_FRAME, *PKSWITCH_FRAME; #define KSWITCH_FRAME_LENGTH sizeof(KSWITCH_FRAME) C_ASSERT((sizeof(KSWITCH_FRAME) & STACK_ROUND) == 0); // // Trap frame // // This frame is established when handling a trap. It provides a place to // save all volatile registers. The nonvolatile registers are saved in an // exception frame or through the normal C calling conventions for saved // registers. // typedef struct _KTRAP_FRAME { // // Home address for the parameter registers. // ULONG64 P1Home; ULONG64 P2Home; ULONG64 P3Home; ULONG64 P4Home; ULONG64 P5; // // Previous processor mode (system services only) and previous IRQL // (interrupts only). // KPROCESSOR_MODE PreviousMode; KIRQL PreviousIrql; UCHAR Fill0[2]; // // Floating point state. // ULONG MxCsr; // // Volatile registers. // // N.B. These registers are only saved on exceptions and interrupts. They // are not saved for system calls. // ULONG64 Rax; ULONG64 Rcx; ULONG64 Rdx; ULONG64 R8; ULONG64 R9; ULONG64 R10; ULONG64 R11; ULONG64 Spare0; // // Volatile floating registers. // // N.B. These registers are only saved on exceptions and interrupts. They // are not saved for system calls. // M128 Xmm0; M128 Xmm1; M128 Xmm2; M128 Xmm3; M128 Xmm4; M128 Xmm5; // // Debug registers. // ULONG64 Dr0; ULONG64 Dr1; ULONG64 Dr2; ULONG64 Dr3; ULONG64 Dr6; ULONG64 Dr7; // // Segment registers // USHORT SegDs; USHORT SegEs; USHORT SegFs; USHORT SegGs; // // Previous trap frame address. // ULONG64 TrapFrame; // // Exception record for exceptions. // UCHAR ExceptionRecord[(sizeof(EXCEPTION_RECORD) + 15) & (~15)]; // // Saved nonvolatile registers RBX, RDI and RSI. These registers are only // saved in system service trap frames. // ULONG64 Rbx; ULONG64 Rdi; ULONG64 Rsi; // // Saved nonvolatile register RBP. This register is used as a frame // pointer during trap processing and is saved in all trap frames. // ULONG64 Rbp; // // Information pushed by hardware. // // N.B. The error code is not always pushed by hardware. For those cases // where it is not pushed by hardware a dummy error code is allocated // on the stack. // ULONG64 ErrorCode; ULONG64 Rip; USHORT SegCs; USHORT Fill1[3]; ULONG EFlags; ULONG Fill2; ULONG64 Rsp; USHORT SegSs; USHORT Fill3[3]; } KTRAP_FRAME, *PKTRAP_FRAME; #define KTRAP_FRAME_LENGTH sizeof(KTRAP_FRAME) C_ASSERT((sizeof(KTRAP_FRAME) & STACK_ROUND) == 0); // // IPI, profile, update run time, and update system time interrupt routines. // NTKERNELAPI VOID KeIpiInterrupt ( IN PKTRAP_FRAME TrapFrame ); NTKERNELAPI VOID KeProfileInterruptWithSource ( IN PKTRAP_FRAME TrapFrame, IN KPROFILE_SOURCE ProfileSource ); NTKERNELAPI VOID KeUpdateRunTime ( IN PKTRAP_FRAME TrapFrame ); NTKERNELAPI VOID KeUpdateSystemTime ( IN PKTRAP_FRAME TrapFrame, IN ULONG64 Increment ); // end_nthal // // The frame saved by the call out to user mode code is defined here to allow // the kernel debugger to trace the entire kernel stack when user mode callouts // are active. // // N.B. The kernel callout frame is the same as an exception frame. // typedef KEXCEPTION_FRAME KCALLOUT_FRAME; typedef PKEXCEPTION_FRAME PKCALLOUT_FRAME; typedef struct _UCALLOUT_FRAME { ULONG64 P1Home; ULONG64 P2Home; ULONG64 P3Home; ULONG64 P4Home; PVOID Buffer; ULONG Length; ULONG ApiNumber; MACHINE_FRAME MachineFrame; } UCALLOUT_FRAME, *PUCALLOUT_FRAME; #define UCALLOUT_FRAME_LENGTH sizeof(UCALLOUT_FRAME) C_ASSERT((sizeof(UCALLOUT_FRAME) & STACK_ROUND) == 8); // begin_ntddk begin_wdm // // The nonvolatile floating state // typedef struct _KFLOATING_SAVE { ULONG MxCsr; } KFLOATING_SAVE, *PKFLOATING_SAVE; // // AMD64 Specific portions of mm component. // // Define the page size for the AMD64 as 4096 (0x1000). // #define PAGE_SIZE 0x1000 // // Define the number of trailing zeroes in a page aligned virtual address. // This is used as the shift count when shifting virtual addresses to // virtual page numbers. // #define PAGE_SHIFT 12L // end_ntndis end_wdm #define PXE_BASE 0xFFFFF6FB7DBED000UI64 #define PXE_SELFMAP 0xFFFFF6FB7DBEDF68UI64 #define PPE_BASE 0xFFFFF6FB7DA00000UI64 #define PDE_BASE 0xFFFFF6FB40000000UI64 #define PTE_BASE 0xFFFFF68000000000UI64 #define PXE_TOP 0xFFFFF6FB7DBEDFFFUI64 #define PPE_TOP 0xFFFFF6FB7DBFFFFFUI64 #define PDE_TOP 0xFFFFF6FB7FFFFFFFUI64 #define PTE_TOP 0xFFFFF6FFFFFFFFFFUI64 #define PDE_KTBASE_AMD64 PPE_BASE #define PTI_SHIFT 12 #define PDI_SHIFT 21 #define PPI_SHIFT 30 #define PXI_SHIFT 39 #define PTE_PER_PAGE 512 #define PDE_PER_PAGE 512 #define PPE_PER_PAGE 512 #define PXE_PER_PAGE 512 #define PTI_MASK_AMD64 (PTE_PER_PAGE - 1) #define PDI_MASK_AMD64 (PDE_PER_PAGE - 1) #define PPI_MASK (PPE_PER_PAGE - 1) #define PXI_MASK (PXE_PER_PAGE - 1) // // Define the highest user address and user probe address. // extern PVOID *MmHighestUserAddress; extern PVOID *MmSystemRangeStart; extern ULONG64 *MmUserProbeAddress; #define MM_HIGHEST_USER_ADDRESS *MmHighestUserAddress #define MM_SYSTEM_RANGE_START *MmSystemRangeStart #define MM_USER_PROBE_ADDRESS *MmUserProbeAddress // // The lowest user address reserves the low 64k. // #define MM_LOWEST_USER_ADDRESS (PVOID)0x10000 // // The lowest address for system space. // #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xFFFF080000000000 // begin_wdm #define MmGetProcedureAddress(Address) (Address) #define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address) #define KI_USER_SHARED_DATA 0xFFFFF78000000000UI64 #define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA) // // Intrinsic functions // // begin_wdm #if defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS) // end_wdm // // The following routines are provided for backward compatibility with old // code. They are no longer the preferred way to accomplish these functions. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInterlockedIncrementLong) // Use InterlockedIncrement #pragma deprecated(ExInterlockedDecrementLong) // Use InterlockedDecrement #pragma deprecated(ExInterlockedExchangeUlong) // Use InterlockedExchange #endif #define RESULT_ZERO 0 #define RESULT_NEGATIVE 1 #define RESULT_POSITIVE 2 typedef enum _INTERLOCKED_RESULT { ResultNegative = RESULT_NEGATIVE, ResultZero = RESULT_ZERO, ResultPositive = RESULT_POSITIVE } INTERLOCKED_RESULT; #define ExInterlockedDecrementLong(Addend, Lock) \ _ExInterlockedDecrementLong(Addend) __forceinline LONG _ExInterlockedDecrementLong ( IN OUT PLONG Addend ) { LONG Result; Result = InterlockedDecrement(Addend); if (Result < 0) { return ResultNegative; } else if (Result > 0) { return ResultPositive; } else { return ResultZero; } } #define ExInterlockedIncrementLong(Addend, Lock) \ _ExInterlockedIncrementLong(Addend) __forceinline LONG _ExInterlockedIncrementLong ( IN OUT PLONG Addend ) { LONG Result; Result = InterlockedIncrement(Addend); if (Result < 0) { return ResultNegative; } else if (Result > 0) { return ResultPositive; } else { return ResultZero; } } #define ExInterlockedExchangeUlong(Target, Value, Lock) \ _ExInterlockedExchangeUlong(Target, Value) __forceinline _ExInterlockedExchangeUlong ( IN OUT PULONG Target, IN ULONG Value ) { return (ULONG)InterlockedExchange((PLONG)Target, (LONG)Value); } // begin_wdm #endif // defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS) #if !defined(MIDL_PASS) && defined(_M_AMD64) // // AMD646 function prototype definitions // // end_wdm // // Get address of current processor block. // __forceinline PKPRCB KeGetCurrentPrcb ( VOID ) { return (PKPRCB)__readgsqword(FIELD_OFFSET(KPCR, CurrentPrcb)); } // begin_ntddk // // Get the current processor number // __forceinline ULONG KeGetCurrentProcessorNumber ( VOID ) { return (ULONG)__readgsbyte(FIELD_OFFSET(KPCR, Number)); } // begin_wdm #endif // !defined(MIDL_PASS) && defined(_M_AMD64) NTKERNELAPI NTSTATUS KeSaveFloatingPointState ( OUT PKFLOATING_SAVE SaveArea ); NTKERNELAPI NTSTATUS KeRestoreFloatingPointState ( IN PKFLOATING_SAVE SaveArea ); #endif // defined(_AMD64_) #ifdef _AMD64_ VOID KeSetIoAccessMap ( PKIO_ACCESS_MAP IoAccessMap ); VOID KeQueryIoAccessMap ( PKIO_ACCESS_MAP IoAccessMap ); VOID KeSetIoAccessProcess ( struct _KPROCESS *Process, BOOLEAN Enable ); VOID KiEditIopmDpc ( IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); #endif //_AMD64_ // // Platform specific kernel fucntions to raise and lower IRQL. // // These functions are imported for ntddk, ntifs, and wdm. They are // inlined for nthal, ntosp, and the system. // #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_WDMDDK_) // begin_ntddk begin_wdm #if defined(_AMD64_) NTKERNELAPI KIRQL KeGetCurrentIrql ( VOID ); NTKERNELAPI VOID KeLowerIrql ( IN KIRQL NewIrql ); #define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a) NTKERNELAPI KIRQL KfRaiseIrql ( IN KIRQL NewIrql ); // end_wdm NTKERNELAPI KIRQL KeRaiseIrqlToDpcLevel ( VOID ); NTKERNELAPI KIRQL KeRaiseIrqlToSynchLevel ( VOID ); // begin_wdm #endif // defined(_AMD64_) // end_ntddk end_wdm #else // begin_nthal #if defined(_AMD64_) && !defined(MIDL_PASS) __forceinline KIRQL KeGetCurrentIrql ( VOID ) /*++ Routine Description: This function return the current IRQL. Arguments: None. Return Value: The current IRQL is returned as the function value. --*/ { return (KIRQL)ReadCR8(); } __forceinline VOID KeLowerIrql ( IN KIRQL NewIrql ) /*++ Routine Description: This function lowers the IRQL to the specified value. Arguments: NewIrql - Supplies the new IRQL value. Return Value: None. --*/ { ASSERT(KeGetCurrentIrql() >= NewIrql); WriteCR8(NewIrql); return; } #define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a) __forceinline KIRQL KfRaiseIrql ( IN KIRQL NewIrql ) /*++ Routine Description: This function raises the current IRQL to the specified value and returns the previous IRQL. Arguments: NewIrql (cl) - Supplies the new IRQL value. Return Value: The previous IRQL is retured as the function value. --*/ { KIRQL OldIrql; OldIrql = KeGetCurrentIrql(); ASSERT(OldIrql <= NewIrql); WriteCR8(NewIrql); return OldIrql; } __forceinline KIRQL KeRaiseIrqlToDpcLevel ( VOID ) /*++ Routine Description: This function raises the current IRQL to DPC_LEVEL and returns the previous IRQL. Arguments: None. Return Value: The previous IRQL is retured as the function value. --*/ { KIRQL OldIrql; OldIrql = KeGetCurrentIrql(); ASSERT(OldIrql <= DISPATCH_LEVEL); WriteCR8(DISPATCH_LEVEL); return OldIrql; } __forceinline KIRQL KeRaiseIrqlToSynchLevel ( VOID ) /*++ Routine Description: This function raises the current IRQL to SYNCH_LEVEL and returns the previous IRQL. Arguments: Return Value: The previous IRQL is retured as the function value. --*/ { KIRQL OldIrql; OldIrql = KeGetCurrentIrql(); ASSERT(OldIrql <= SYNCH_LEVEL); WriteCR8(SYNCH_LEVEL); return OldIrql; } #endif // defined(_AMD64_) && !defined(MIDL_PASS) // end_nthal #endif // defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_WDMDDK_) #if defined(_IA64_) // // Types to use to contain PFNs and their counts. // typedef ULONG PFN_COUNT; typedef LONG_PTR SPFN_NUMBER, *PSPFN_NUMBER; typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER; // // Define maximum size of flush multiple TB request. // #define FLUSH_MULTIPLE_MAXIMUM 100 // // Indicate that the IA64 compiler supports the pragma textout construct. // #define ALLOC_PRAGMA 1 // // Define intrinsic calls and their prototypes // #include "ia64reg.h" #ifdef __cplusplus extern "C" { #endif unsigned __int64 __getReg (int); void __setReg (int, unsigned __int64); void __isrlz (void); void __dsrlz (void); void __fwb (void); void __mf (void); void __mfa (void); void __synci (void); __int64 __thash (__int64); __int64 __ttag (__int64); void __ptcl (__int64, __int64); void __ptcg (__int64, __int64); void __ptcga (__int64, __int64); void __ptri (__int64, __int64); void __ptrd (__int64, __int64); void __invalat (void); void __break (int); void __fc (__int64); void __sum (int); void __rsm (int); void _ReleaseSpinLock( unsigned __int64 *); #ifdef _M_IA64 #pragma intrinsic (__getReg) #pragma intrinsic (__setReg) #pragma intrinsic (__isrlz) #pragma intrinsic (__dsrlz) #pragma intrinsic (__fwb) #pragma intrinsic (__mf) #pragma intrinsic (__mfa) #pragma intrinsic (__synci) #pragma intrinsic (__thash) #pragma intrinsic (__ttag) #pragma intrinsic (__ptcl) #pragma intrinsic (__ptcg) #pragma intrinsic (__ptcga) #pragma intrinsic (__ptri) #pragma intrinsic (__ptrd) #pragma intrinsic (__invalat) #pragma intrinsic (__break) #pragma intrinsic (__fc) #pragma intrinsic (__sum) #pragma intrinsic (__rsm) #pragma intrinsic (_ReleaseSpinLock) #endif // _M_IA64 #ifdef __cplusplus } #endif // end_wdm end_ntndis // // Define macro to generate import names. // #define IMPORT_NAME(name) __imp_##name // begin_wdm // // Define length of interrupt vector table. // #define MAXIMUM_VECTOR 256 // end_wdm // // IA64 specific interlocked operation result values. // #define RESULT_ZERO 0 #define RESULT_NEGATIVE 1 #define RESULT_POSITIVE 2 // // Interlocked result type is portable, but its values are machine specific. // Constants for values are in i386.h, mips.h, etc. // typedef enum _INTERLOCKED_RESULT { ResultNegative = RESULT_NEGATIVE, ResultZero = RESULT_ZERO, ResultPositive = RESULT_POSITIVE } INTERLOCKED_RESULT; // // Convert portable interlock interfaces to architecture specific interfaces. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInterlockedIncrementLong) // Use InterlockedIncrement #pragma deprecated(ExInterlockedDecrementLong) // Use InterlockedDecrement #pragma deprecated(ExInterlockedExchangeUlong) // Use InterlockedExchange #endif #define ExInterlockedIncrementLong(Addend, Lock) \ ExIa64InterlockedIncrementLong(Addend) #define ExInterlockedDecrementLong(Addend, Lock) \ ExIa64InterlockedDecrementLong(Addend) #define ExInterlockedExchangeUlong(Target, Value, Lock) \ ExIa64InterlockedExchangeUlong(Target, Value) NTKERNELAPI INTERLOCKED_RESULT ExIa64InterlockedIncrementLong ( IN PLONG Addend ); NTKERNELAPI INTERLOCKED_RESULT ExIa64InterlockedDecrementLong ( IN PLONG Addend ); NTKERNELAPI ULONG ExIa64InterlockedExchangeUlong ( IN PULONG Target, IN ULONG Value ); // begin_wdm // // IA64 Interrupt Definitions. // // Define length of interrupt object dispatch code in longwords. // #define DISPATCH_LENGTH 2*2 // Length of dispatch code template in 32-bit words // // Begin of a block of definitions that must be synchronized with kxia64.h. // // // Define Interrupt Request Levels. // #define PASSIVE_LEVEL 0 // Passive release level #define LOW_LEVEL 0 // Lowest interrupt level #define APC_LEVEL 1 // APC interrupt level #define DISPATCH_LEVEL 2 // Dispatcher level #define CMC_LEVEL 3 // Correctable machine check level #define DEVICE_LEVEL_BASE 4 // 4 - 11 - Device IRQLs #define PC_LEVEL 12 // Performance Counter IRQL #define IPI_LEVEL 14 // IPI IRQL #define CLOCK_LEVEL 13 // Clock Timer IRQL #define POWER_LEVEL 15 // Power failure level #define PROFILE_LEVEL 15 // Profiling level #define HIGH_LEVEL 15 // Highest interrupt level #if defined(NT_UP) #define SYNCH_LEVEL DISPATCH_LEVEL // Synchronization level - UP #else #define SYNCH_LEVEL (IPI_LEVEL-1) // Synchronization level - MP #endif // // The current IRQL is maintained in the TPR.mic field. The // shift count is the number of bits to shift right to extract the // IRQL from the TPR. See the GET/SET_IRQL macros. // #define TPR_MIC 4 #define TPR_IRQL_SHIFT TPR_MIC // To go from vector number <-> IRQL we just do a shift #define VECTOR_IRQL_SHIFT TPR_IRQL_SHIFT // // Interrupt Vector Definitions // #define APC_VECTOR APC_LEVEL << VECTOR_IRQL_SHIFT #define DISPATCH_VECTOR DISPATCH_LEVEL << VECTOR_IRQL_SHIFT // // End of a block of definitions that must be synchronized with kxia64.h. // // // Define profile intervals. // #define DEFAULT_PROFILE_COUNT 0x40000000 // ~= 20 seconds @50mhz #define DEFAULT_PROFILE_INTERVAL (10 * 500) // 500 microseconds #define MAXIMUM_PROFILE_INTERVAL (10 * 1000 * 1000) // 1 second #define MINIMUM_PROFILE_INTERVAL (10 * 40) // 40 microseconds #if defined(_M_IA64) && !defined(RC_INVOKED) #define InterlockedAdd _InterlockedAdd #define InterlockedIncrement _InterlockedIncrement #define InterlockedDecrement _InterlockedDecrement #define InterlockedExchange _InterlockedExchange #define InterlockedExchangeAdd _InterlockedExchangeAdd #define InterlockedAdd64 _InterlockedAdd64 #define InterlockedIncrement64 _InterlockedIncrement64 #define InterlockedDecrement64 _InterlockedDecrement64 #define InterlockedExchange64 _InterlockedExchange64 #define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 #define InterlockedCompareExchange64 _InterlockedCompareExchange64 #define InterlockedCompareExchange _InterlockedCompareExchange #define InterlockedExchangePointer _InterlockedExchangePointer #define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer #ifdef __cplusplus extern "C" { #endif LONG __cdecl InterlockedAdd ( LONG volatile *Addend, LONG Value ); LONGLONG __cdecl InterlockedAdd64 ( LONGLONG volatile *Addend, LONGLONG Value ); LONG __cdecl InterlockedIncrement( IN OUT LONG volatile *Addend ); LONG __cdecl InterlockedDecrement( IN OUT LONG volatile *Addend ); LONG __cdecl InterlockedExchange( IN OUT LONG volatile *Target, IN LONG Value ); LONG __cdecl InterlockedExchangeAdd( IN OUT LONG volatile *Addend, IN LONG Value ); LONG __cdecl InterlockedCompareExchange ( IN OUT LONG volatile *Destination, IN LONG ExChange, IN LONG Comperand ); LONGLONG __cdecl InterlockedIncrement64( IN OUT LONGLONG volatile *Addend ); LONGLONG __cdecl InterlockedDecrement64( IN OUT LONGLONG volatile *Addend ); LONGLONG __cdecl InterlockedExchange64( IN OUT LONGLONG volatile *Target, IN LONGLONG Value ); LONGLONG __cdecl InterlockedExchangeAdd64( IN OUT LONGLONG volatile *Addend, IN LONGLONG Value ); LONGLONG __cdecl InterlockedCompareExchange64 ( IN OUT LONGLONG volatile *Destination, IN LONGLONG ExChange, IN LONGLONG Comperand ); PVOID __cdecl InterlockedCompareExchangePointer ( IN OUT PVOID volatile *Destination, IN PVOID Exchange, IN PVOID Comperand ); PVOID __cdecl InterlockedExchangePointer( IN OUT PVOID volatile *Target, IN PVOID Value ); #pragma intrinsic(_InterlockedAdd) #pragma intrinsic(_InterlockedIncrement) #pragma intrinsic(_InterlockedDecrement) #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedAdd64) #pragma intrinsic(_InterlockedIncrement64) #pragma intrinsic(_InterlockedDecrement64) #pragma intrinsic(_InterlockedExchange64) #pragma intrinsic(_InterlockedCompareExchange64) #pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchangePointer) #pragma intrinsic(_InterlockedCompareExchangePointer) #ifdef __cplusplus } #endif #endif // defined(_M_IA64) && !defined(RC_INVOKED) #define KI_USER_SHARED_DATA ((ULONG_PTR)(KADDRESS_BASE + 0xFFFE0000)) #define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA) // // Prototype for get current IRQL. **** TBD (read TPR) // NTKERNELAPI KIRQL KeGetCurrentIrql(); // end_wdm // // Get address of current processor block. // #define KeGetCurrentPrcb() PCR->Prcb // // Get address of processor control region. // #define KeGetPcr() PCR // // Get address of current kernel thread object. // #if defined(_M_IA64) #define KeGetCurrentThread() PCR->CurrentThread #endif // // Get current processor number. // #define KeGetCurrentProcessorNumber() PCR->Number // // Get data cache fill size. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(KeGetDcacheFillSize) // Use GetDmaAlignment #endif #define KeGetDcacheFillSize() PCR->DcacheFillSize #define KeSaveFloatingPointState(a) STATUS_SUCCESS #define KeRestoreFloatingPointState(a) STATUS_SUCCESS // // Define the page size // #define PAGE_SIZE 0x2000 // // Define the number of trailing zeroes in a page aligned virtual address. // This is used as the shift count when shifting virtual addresses to // virtual page numbers. // #define PAGE_SHIFT 13L // // Cache and write buffer flush functions. // NTKERNELAPI VOID KeFlushIoBuffers ( IN PMDL Mdl, IN BOOLEAN ReadOperation, IN BOOLEAN DmaOperation ); #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock) #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock) #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // begin_wdm #define KeQueryTickCount(CurrentCount ) \ *(PULONGLONG)(CurrentCount) = **((volatile ULONGLONG **)(&KeTickCount)); // end_wdm #else NTKERNELAPI VOID KeQueryTickCount ( OUT PLARGE_INTEGER CurrentCount ); #endif // defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // // I/O space read and write macros. // NTHALAPI UCHAR READ_PORT_UCHAR ( PUCHAR RegisterAddress ); NTHALAPI USHORT READ_PORT_USHORT ( PUSHORT RegisterAddress ); NTHALAPI ULONG READ_PORT_ULONG ( PULONG RegisterAddress ); NTHALAPI VOID READ_PORT_BUFFER_UCHAR ( PUCHAR portAddress, PUCHAR readBuffer, ULONG readCount ); NTHALAPI VOID READ_PORT_BUFFER_USHORT ( PUSHORT portAddress, PUSHORT readBuffer, ULONG readCount ); NTHALAPI VOID READ_PORT_BUFFER_ULONG ( PULONG portAddress, PULONG readBuffer, ULONG readCount ); NTHALAPI VOID WRITE_PORT_UCHAR ( PUCHAR portAddress, UCHAR Data ); NTHALAPI VOID WRITE_PORT_USHORT ( PUSHORT portAddress, USHORT Data ); NTHALAPI VOID WRITE_PORT_ULONG ( PULONG portAddress, ULONG Data ); NTHALAPI VOID WRITE_PORT_BUFFER_UCHAR ( PUCHAR portAddress, PUCHAR writeBuffer, ULONG writeCount ); NTHALAPI VOID WRITE_PORT_BUFFER_USHORT ( PUSHORT portAddress, PUSHORT writeBuffer, ULONG writeCount ); NTHALAPI VOID WRITE_PORT_BUFFER_ULONG ( PULONG portAddress, PULONG writeBuffer, ULONG writeCount ); #define READ_REGISTER_UCHAR(x) \ (__mf(), *(volatile UCHAR * const)(x)) #define READ_REGISTER_USHORT(x) \ (__mf(), *(volatile USHORT * const)(x)) #define READ_REGISTER_ULONG(x) \ (__mf(), *(volatile ULONG * const)(x)) #define READ_REGISTER_BUFFER_UCHAR(x, y, z) { \ PUCHAR registerBuffer = x; \ PUCHAR readBuffer = y; \ ULONG readCount; \ __mf(); \ for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \ *readBuffer = *(volatile UCHAR * const)(registerBuffer); \ } \ } #define READ_REGISTER_BUFFER_USHORT(x, y, z) { \ PUSHORT registerBuffer = x; \ PUSHORT readBuffer = y; \ ULONG readCount; \ __mf(); \ for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \ *readBuffer = *(volatile USHORT * const)(registerBuffer); \ } \ } #define READ_REGISTER_BUFFER_ULONG(x, y, z) { \ PULONG registerBuffer = x; \ PULONG readBuffer = y; \ ULONG readCount; \ __mf(); \ for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \ *readBuffer = *(volatile ULONG * const)(registerBuffer); \ } \ } #define WRITE_REGISTER_UCHAR(x, y) { \ *(volatile UCHAR * const)(x) = y; \ KeFlushWriteBuffer(); \ } #define WRITE_REGISTER_USHORT(x, y) { \ *(volatile USHORT * const)(x) = y; \ KeFlushWriteBuffer(); \ } #define WRITE_REGISTER_ULONG(x, y) { \ *(volatile ULONG * const)(x) = y; \ KeFlushWriteBuffer(); \ } #define WRITE_REGISTER_BUFFER_UCHAR(x, y, z) { \ PUCHAR registerBuffer = x; \ PUCHAR writeBuffer = y; \ ULONG writeCount; \ for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \ *(volatile UCHAR * const)(registerBuffer) = *writeBuffer; \ } \ KeFlushWriteBuffer(); \ } #define WRITE_REGISTER_BUFFER_USHORT(x, y, z) { \ PUSHORT registerBuffer = x; \ PUSHORT writeBuffer = y; \ ULONG writeCount; \ for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \ *(volatile USHORT * const)(registerBuffer) = *writeBuffer; \ } \ KeFlushWriteBuffer(); \ } #define WRITE_REGISTER_BUFFER_ULONG(x, y, z) { \ PULONG registerBuffer = x; \ PULONG writeBuffer = y; \ ULONG writeCount; \ for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \ *(volatile ULONG * const)(registerBuffer) = *writeBuffer; \ } \ KeFlushWriteBuffer(); \ } // // Non-volatile floating point state // typedef struct _KFLOATING_SAVE { ULONG Reserved; } KFLOATING_SAVE, *PKFLOATING_SAVE; // // Processor Control Block (PRCB) // #define PRCB_MINOR_VERSION 1 #define PRCB_MAJOR_VERSION 1 #define PRCB_BUILD_DEBUG 0x0001 #define PRCB_BUILD_UNIPROCESSOR 0x0002 struct _RESTART_BLOCK; typedef struct _KPRCB { // // Major and minor version numbers of the PCR. // USHORT MinorVersion; USHORT MajorVersion; // // Start of the architecturally defined section of the PRCB. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // // struct _KTHREAD *CurrentThread; struct _KTHREAD *RESTRICTED_POINTER NextThread; struct _KTHREAD *IdleThread; CCHAR Number; CCHAR WakeIdle; USHORT BuildType; KAFFINITY SetMember; struct _RESTART_BLOCK *RestartBlock; ULONG_PTR PcrPage; ULONG Spare0[4]; // // Processor Idendification Registers. // ULONG ProcessorModel; ULONG ProcessorRevision; ULONG ProcessorFamily; ULONG ProcessorArchRev; ULONGLONG ProcessorSerialNumber; ULONGLONG ProcessorFeatureBits; UCHAR ProcessorVendorString[16]; // // Space reserved for the system. // ULONGLONG SystemReserved[8]; // // Space reserved for the HAL. // ULONGLONG HalReserved[16]; // // End of the architecturally defined section of the PRCB. } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB; // begin_ntndis // // OS_MCA, OS_INIT HandOff State definitions // // Note: The following definitions *must* match the definiions of the // corresponding SAL Revision Hand-Off structures. // typedef struct _SAL_HANDOFF_STATE { ULONGLONG PalProcEntryPoint; ULONGLONG SalProcEntryPoint; ULONGLONG SalGlobalPointer; LONGLONG RendezVousResult; ULONGLONG SalReturnAddress; ULONGLONG MinStateSavePtr; } SAL_HANDOFF_STATE, *PSAL_HANDOFF_STATE; typedef struct _OS_HANDOFF_STATE { ULONGLONG Result; ULONGLONG SalGlobalPointer; ULONGLONG MinStateSavePtr; ULONGLONG SalReturnAddress; ULONGLONG NewContextFlag; } OS_HANDOFF_STATE, *POS_HANDOFF_STATE; // // per processor OS_MCA and OS_INIT resource structure // #define SER_EVENT_STACK_FRAME_ENTRIES 8 typedef struct _SAL_EVENT_RESOURCES { SAL_HANDOFF_STATE SalToOsHandOff; OS_HANDOFF_STATE OsToSalHandOff; PVOID StateDump; ULONGLONG StateDumpPhysical; PVOID BackStore; ULONGLONG BackStoreLimit; PVOID Stack; ULONGLONG StackLimit; PULONGLONG PTOM; ULONGLONG StackFrame[SER_EVENT_STACK_FRAME_ENTRIES]; PVOID EventPool; ULONG EventPoolSize; } SAL_EVENT_RESOURCES, *PSAL_EVENT_RESOURCES; // // PAL Mini-save area, used by MCA and INIT // typedef struct _PAL_MINI_SAVE_AREA { ULONGLONG IntNats; // Nat bits for r1-r31 // r1-r31 in bits 1 thru 31. ULONGLONG IntGp; // r1, volatile ULONGLONG IntT0; // r2-r3, volatile ULONGLONG IntT1; // ULONGLONG IntS0; // r4-r7, preserved ULONGLONG IntS1; ULONGLONG IntS2; ULONGLONG IntS3; ULONGLONG IntV0; // r8, volatile ULONGLONG IntT2; // r9-r11, volatile ULONGLONG IntT3; ULONGLONG IntT4; ULONGLONG IntSp; // stack pointer (r12), special ULONGLONG IntTeb; // teb (r13), special ULONGLONG IntT5; // r14-r31, volatile ULONGLONG IntT6; ULONGLONG B0R16; // Bank 0 registers 16-31 ULONGLONG B0R17; ULONGLONG B0R18; ULONGLONG B0R19; ULONGLONG B0R20; ULONGLONG B0R21; ULONGLONG B0R22; ULONGLONG B0R23; ULONGLONG B0R24; ULONGLONG B0R25; ULONGLONG B0R26; ULONGLONG B0R27; ULONGLONG B0R28; ULONGLONG B0R29; ULONGLONG B0R30; ULONGLONG B0R31; ULONGLONG IntT7; // Bank 1 registers 16-31 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 Preds; // predicates, preserved ULONGLONG BrRp; // return pointer, b0, preserved ULONGLONG RsRSC; // RSE configuration, volatile ULONGLONG StIIP; // Interruption IP ULONGLONG StIPSR; // Interruption Processor Status ULONGLONG StIFS; // Interruption Function State ULONGLONG XIP; // Event IP ULONGLONG XPSR; // Event Processor Status ULONGLONG XFS; // Event Function State } PAL_MINI_SAVE_AREA, *PPAL_MINI_SAVE_AREA; // // Define Processor Control Region Structure. // #define PCR_MINOR_VERSION 1 #define PCR_MAJOR_VERSION 1 typedef struct _KPCR { // // Major and minor version numbers of the PCR. // ULONG MinorVersion; ULONG MajorVersion; // // Start of the architecturally defined section of the PCR. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // // // First and second level cache parameters. // ULONG FirstLevelDcacheSize; ULONG FirstLevelDcacheFillSize; ULONG FirstLevelIcacheSize; ULONG FirstLevelIcacheFillSize; ULONG SecondLevelDcacheSize; ULONG SecondLevelDcacheFillSize; ULONG SecondLevelIcacheSize; ULONG SecondLevelIcacheFillSize; // // Data cache alignment and fill size used for cache flushing and alignment. // These fields are set to the larger of the first and second level data // cache fill sizes. // ULONG DcacheAlignment; ULONG DcacheFillSize; // // Instruction cache alignment and fill size used for cache flushing and // alignment. These fields are set to the larger of the first and second // level data cache fill sizes. // ULONG IcacheAlignment; ULONG IcacheFillSize; // // Processor identification from PrId register. // ULONG ProcessorId; // // Profiling data. // ULONG ProfileInterval; ULONG ProfileCount; // // Stall execution count and scale factor. // ULONG StallExecutionCount; ULONG StallScaleFactor; ULONG InterruptionCount; // // Space reserved for the system. // ULONGLONG SystemReserved[6]; // // Space reserved for the HAL // ULONGLONG HalReserved[64]; // // IRQL mapping tables. // UCHAR IrqlMask[64]; UCHAR IrqlTable[64]; // // External Interrupt vectors. // PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR]; // // Reserved interrupt vector mask. // ULONG ReservedVectors; // // Processor affinity mask. // KAFFINITY SetMember; // // Complement of the processor affinity mask. // KAFFINITY NotMember; // // Pointer to processor control block. // struct _KPRCB *Prcb; // // Shadow copy of Prcb->CurrentThread for fast access // struct _KTHREAD *CurrentThread; // // Processor number. // CCHAR Number; // Processor Number UCHAR DebugActive; // debug register active in user flag UCHAR KernelDebugActive; // debug register active in kernel flag UCHAR CurrentIrql; // Current IRQL union { USHORT SoftwareInterruptPending; // Software Interrupt Pending Flag struct { UCHAR ApcInterrupt; // 0x01 if APC int pending UCHAR DispatchInterrupt; // 0x01 if dispatch int pending }; }; // // Address of per processor SAPIC EOI Table // PVOID EOITable; // // IA-64 Machine Check Events trackers // UCHAR InOsMca; UCHAR InOsInit; UCHAR InOsCmc; UCHAR InOsCpe; ULONG InOsULONG_Spare; // Spare ULONG PSAL_EVENT_RESOURCES OsMcaResourcePtr; PSAL_EVENT_RESOURCES OsInitResourcePtr; // // End of the architecturally defined section of the PCR. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. // // end_nthal end_ntddk // // OS Part // // // Address of the thread who currently owns the high fp register set // struct _KTHREAD *HighFpOwner; // Per processor kernel (ntoskrnl.exe) global pointer ULONGLONG KernelGP; // Per processor initial kernel stack for current thread ULONGLONG InitialStack; // Per processor pointer to kernel BSP ULONGLONG InitialBStore; // Per processor kernel stack limit ULONGLONG StackLimit; // Per processor kernel backing store limit ULONGLONG BStoreLimit; // Per processor panic kernel stack ULONGLONG PanicStack; // // Save area for kernel entry/exit // ULONGLONG SavedIIM; ULONGLONG SavedIFA; ULONGLONG ForwardProgressBuffer[16]; PVOID Pcb; // holds KPROCESS for MP region synchronization // // Nt page table base addresses // ULONGLONG PteUbase; ULONGLONG PteKbase; ULONGLONG PteSbase; ULONGLONG PdeUbase; ULONGLONG PdeKbase; ULONGLONG PdeSbase; ULONGLONG PdeUtbase; ULONGLONG PdeKtbase; ULONGLONG PdeStbase; // // The actual resources for the OS_INIT and OS_MCA handlers // are placed at the end of the PCR structure so that auto // can be used to get to get between the public and private // sections of the PCR in the traps and context routines. // SAL_EVENT_RESOURCES OsMcaResource; SAL_EVENT_RESOURCES OsInitResource; // begin_nthal begin_ntddk } KPCR, *PKPCR; // // The highest user address reserves 64K bytes for a guard page. This // the probing of address from kernel mode to only have to check the // starting address for structures of 64k bytes or less. // extern NTKERNELAPI PVOID MmHighestUserAddress; extern NTKERNELAPI PVOID MmSystemRangeStart; extern NTKERNELAPI ULONG_PTR MmUserProbeAddress; #define MM_HIGHEST_USER_ADDRESS MmHighestUserAddress #define MM_USER_PROBE_ADDRESS MmUserProbeAddress #define MM_SYSTEM_RANGE_START MmSystemRangeStart // // The lowest user address reserves the low 64k. // #define MM_LOWEST_USER_ADDRESS (PVOID)((ULONG_PTR)(UADDRESS_BASE+0x00010000)) // begin_wdm #define MmGetProcedureAddress(Address) (Address) #define MmLockPagableCodeSection(PLabelAddress) \ MmLockPagableDataSection((PVOID)(*((PULONGLONG)PLabelAddress))) #define VRN_MASK 0xE000000000000000UI64 // Virtual Region Number mask #endif // defined(_IA64_) // // Define structure of boot driver list. // typedef struct _BOOT_DRIVER_LIST_ENTRY { LIST_ENTRY Link; UNICODE_STRING FilePath; UNICODE_STRING RegistryPath; PKLDR_DATA_TABLE_ENTRY LdrEntry; } BOOT_DRIVER_LIST_ENTRY, *PBOOT_DRIVER_LIST_ENTRY; #define THREAD_WAIT_OBJECTS 3 // Builtin usable wait blocks // #if defined(_X86_) #define PAUSE_PROCESSOR _asm { rep nop } #else #define PAUSE_PROCESSOR #endif // // Define macro to generate an affinity mask. // #define AFFINITY_MASK(n) ((ULONG_PTR)1 << (n)) typedef enum _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment, InsertApcEnvironment } KAPC_ENVIRONMENT; // begin_ntddk begin_wdm begin_nthal begin_ntminiport begin_ntifs begin_ntndis // // Interrupt modes. // typedef enum _KINTERRUPT_MODE { LevelSensitive, Latched } KINTERRUPT_MODE; // // Wait reasons // typedef enum _KWAIT_REASON { Executive, FreePage, PageIn, PoolAllocation, DelayExecution, Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, WrKernel, MaximumWaitReason } KWAIT_REASON; // end_ntddk end_wdm end_nthal // // Miscellaneous type definitions // // APC state // typedef struct _KAPC_STATE { LIST_ENTRY ApcListHead[MaximumMode]; struct _KPROCESS *Process; BOOLEAN KernelApcInProgress; BOOLEAN KernelApcPending; BOOLEAN UserApcPending; } KAPC_STATE, *PKAPC_STATE, *RESTRICTED_POINTER PRKAPC_STATE; typedef struct _KWAIT_BLOCK { LIST_ENTRY WaitListEntry; struct _KTHREAD *RESTRICTED_POINTER Thread; PVOID Object; struct _KWAIT_BLOCK *RESTRICTED_POINTER NextWaitBlock; USHORT WaitKey; USHORT WaitType; } KWAIT_BLOCK, *PKWAIT_BLOCK, *RESTRICTED_POINTER PRKWAIT_BLOCK; // // Thread start function // typedef VOID (*PKSTART_ROUTINE) ( IN PVOID StartContext ); // // Kernel object structure definitions // // // Device Queue object and entry // typedef struct _KDEVICE_QUEUE { CSHORT Type; CSHORT Size; LIST_ENTRY DeviceListHead; KSPIN_LOCK Lock; BOOLEAN Busy; } KDEVICE_QUEUE, *PKDEVICE_QUEUE, *RESTRICTED_POINTER PRKDEVICE_QUEUE; typedef struct _KDEVICE_QUEUE_ENTRY { LIST_ENTRY DeviceListEntry; ULONG SortKey; BOOLEAN Inserted; } KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY, *RESTRICTED_POINTER PRKDEVICE_QUEUE_ENTRY; // // Define the interrupt service function type and the empty struct // type. // typedef BOOLEAN (*PKSERVICE_ROUTINE) ( IN struct _KINTERRUPT *Interrupt, IN PVOID ServiceContext ); typedef struct _KINTERRUPT *PKINTERRUPT, *RESTRICTED_POINTER PRKINTERRUPT; // // Mutant object // typedef struct _KMUTANT { DISPATCHER_HEADER Header; LIST_ENTRY MutantListEntry; struct _KTHREAD *RESTRICTED_POINTER OwnerThread; BOOLEAN Abandoned; UCHAR ApcDisable; } KMUTANT, *PKMUTANT, *RESTRICTED_POINTER PRKMUTANT, KMUTEX, *PKMUTEX, *RESTRICTED_POINTER PRKMUTEX; typedef struct _KQUEUE { DISPATCHER_HEADER Header; LIST_ENTRY EntryListHead; ULONG CurrentCount; ULONG MaximumCount; LIST_ENTRY ThreadListHead; } KQUEUE, *PKQUEUE, *RESTRICTED_POINTER PRKQUEUE; // // // Semaphore object // typedef struct _KSEMAPHORE { DISPATCHER_HEADER Header; LONG Limit; } KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE; NTKERNELAPI VOID KeInitializeApc ( IN PRKAPC Apc, IN PRKTHREAD Thread, IN KAPC_ENVIRONMENT Environment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, IN KPROCESSOR_MODE ProcessorMode OPTIONAL, IN PVOID NormalContext OPTIONAL ); PLIST_ENTRY KeFlushQueueApc ( IN PKTHREAD Thread, IN KPROCESSOR_MODE ProcessorMode ); NTKERNELAPI BOOLEAN KeInsertQueueApc ( IN PRKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY Increment ); BOOLEAN KeRemoveQueueApc ( IN PKAPC Apc ); // // DPC object // NTKERNELAPI VOID KeInitializeDpc ( IN PRKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext ); NTKERNELAPI BOOLEAN KeInsertQueueDpc ( IN PRKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2 ); NTKERNELAPI BOOLEAN KeRemoveQueueDpc ( IN PRKDPC Dpc ); // end_wdm NTKERNELAPI VOID KeSetImportanceDpc ( IN PRKDPC Dpc, IN KDPC_IMPORTANCE Importance ); NTKERNELAPI VOID KeSetTargetProcessorDpc ( IN PRKDPC Dpc, IN CCHAR Number ); // begin_wdm NTKERNELAPI VOID KeFlushQueuedDpcs ( VOID ); // // Device queue object // NTKERNELAPI VOID KeInitializeDeviceQueue ( IN PKDEVICE_QUEUE DeviceQueue ); NTKERNELAPI BOOLEAN KeInsertDeviceQueue ( IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry ); NTKERNELAPI BOOLEAN KeInsertByKeyDeviceQueue ( IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN ULONG SortKey ); NTKERNELAPI PKDEVICE_QUEUE_ENTRY KeRemoveDeviceQueue ( IN PKDEVICE_QUEUE DeviceQueue ); NTKERNELAPI PKDEVICE_QUEUE_ENTRY KeRemoveByKeyDeviceQueue ( IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey ); NTKERNELAPI PKDEVICE_QUEUE_ENTRY KeRemoveByKeyDeviceQueueIfBusy ( IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey ); NTKERNELAPI BOOLEAN KeRemoveEntryDeviceQueue ( IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry ); NTKERNELAPI BOOLEAN KeSynchronizeExecution ( IN PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext ); NTKERNELAPI KIRQL KeAcquireInterruptSpinLock ( IN PKINTERRUPT Interrupt ); NTKERNELAPI VOID KeReleaseInterruptSpinLock ( IN PKINTERRUPT Interrupt, IN KIRQL OldIrql ); // // Kernel dispatcher object functions // // Event Object // NTKERNELAPI VOID KeInitializeEvent ( IN PRKEVENT Event, IN EVENT_TYPE Type, IN BOOLEAN State ); NTKERNELAPI VOID KeClearEvent ( IN PRKEVENT Event ); NTKERNELAPI LONG KePulseEvent ( IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait ); NTKERNELAPI LONG KeReadStateEvent ( IN PRKEVENT Event ); NTKERNELAPI LONG KeResetEvent ( IN PRKEVENT Event ); NTKERNELAPI LONG KeSetEvent ( IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait ); // // Mutex object // NTKERNELAPI VOID KeInitializeMutex ( IN PRKMUTEX Mutex, IN ULONG Level ); NTKERNELAPI LONG KeReadStateMutex ( IN PRKMUTEX Mutex ); NTKERNELAPI LONG KeReleaseMutex ( IN PRKMUTEX Mutex, IN BOOLEAN Wait ); // end_ntddk end_wdm // // Queue Object. // NTKERNELAPI VOID KeInitializeQueue ( IN PRKQUEUE Queue, IN ULONG Count OPTIONAL ); NTKERNELAPI LONG KeReadStateQueue ( IN PRKQUEUE Queue ); NTKERNELAPI LONG KeInsertQueue ( IN PRKQUEUE Queue, IN PLIST_ENTRY Entry ); NTKERNELAPI LONG KeInsertHeadQueue ( IN PRKQUEUE Queue, IN PLIST_ENTRY Entry ); NTKERNELAPI PLIST_ENTRY KeRemoveQueue ( IN PRKQUEUE Queue, IN KPROCESSOR_MODE WaitMode, IN PLARGE_INTEGER Timeout OPTIONAL ); PLIST_ENTRY KeRundownQueue ( IN PRKQUEUE Queue ); // begin_ntddk begin_wdm // // Semaphore object // NTKERNELAPI VOID KeInitializeSemaphore ( IN PRKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit ); NTKERNELAPI LONG KeReadStateSemaphore ( IN PRKSEMAPHORE Semaphore ); NTKERNELAPI LONG KeReleaseSemaphore ( IN PRKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait ); NTKERNELAPI VOID KeAttachProcess ( IN PRKPROCESS Process ); NTKERNELAPI VOID KeDetachProcess ( VOID ); NTKERNELAPI VOID KeStackAttachProcess ( IN PRKPROCESS PROCESS, OUT PRKAPC_STATE ApcState ); NTKERNELAPI VOID KeUnstackDetachProcess ( IN PRKAPC_STATE ApcState ); NTKERNELAPI BOOLEAN KeIsAttachedProcess( VOID ); NTKERNELAPI // ntddk wdm nthal ntifs NTSTATUS // ntddk wdm nthal ntifs KeDelayExecutionThread ( // ntddk wdm nthal ntifs IN KPROCESSOR_MODE WaitMode, // ntddk wdm nthal ntifs IN BOOLEAN Alertable, // ntddk wdm nthal ntifs IN PLARGE_INTEGER Interval // ntddk wdm nthal ntifs ); // ntddk wdm nthal ntifs // ntddk wdm nthal ntifs VOID KeRevertToUserAffinityThread ( VOID ); VOID KeSetSystemAffinityThread ( IN KAFFINITY Affinity ); NTKERNELAPI BOOLEAN KeSetKernelStackSwapEnable ( IN BOOLEAN Enable ); // end_ntifs NTKERNELAPI // ntddk wdm nthal ntifs KPRIORITY // ntddk wdm nthal ntifs KeSetPriorityThread ( // ntddk wdm nthal ntifs IN PKTHREAD Thread, // ntddk wdm nthal ntifs IN KPRIORITY Priority // ntddk wdm nthal ntifs ); // ntddk wdm nthal ntifs // ntddk wdm nthal ntifs #if ((defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) ||defined(_NTHAL_)) && !defined(_NTSYSTEM_DRIVER_) || defined(_NTOSP_)) // begin_wdm NTKERNELAPI VOID KeEnterCriticalRegion ( VOID ); NTKERNELAPI VOID KeLeaveCriticalRegion ( VOID ); NTKERNELAPI BOOLEAN KeAreApcsDisabled( VOID ); // end_wdm #else //++ // // VOID // KeEnterCriticalRegion ( // VOID // ) // // // Routine Description: // // This function disables kernel APC's. // // N.B. The following code does not require any interlocks. There are // two cases of interest: 1) On an MP system, the thread cannot // be running on two processors as once, and 2) if the thread is // is interrupted to deliver a kernel mode APC which also calls // this routine, the values read and stored will stack and unstack // properly. // // Arguments: // // None. // // Return Value: // // None. //-- #define KeEnterCriticalRegion() KeGetCurrentThread()->KernelApcDisable -= 1 //++ // // VOID // KeEnterCriticalRegionThread ( // PKTHREAD CurrentThread // ) // // // Routine Description: // // This function disables kernel APC's for the current thread only. // // N.B. The following code does not require any interlocks. There are // two cases of interest: 1) On an MP system, the thread cannot // be running on two processors as once, and 2) if the thread is // is interrupted to deliver a kernel mode APC which also calls // this routine, the values read and stored will stack and unstack // properly. // // Arguments: // // CurrentThread - Current thread thats executing. This must be the // current thread. // // Return Value: // // None. //-- #define KeEnterCriticalRegionThread(CurrentThread) { \ ASSERT (CurrentThread == KeGetCurrentThread ()); \ (CurrentThread)->KernelApcDisable -= 1; \ } //++ // // VOID // KeLeaveCriticalRegion ( // VOID // ) // // // Routine Description: // // This function enables kernel APC's. // // N.B. The following code does not require any interlocks. There are // two cases of interest: 1) On an MP system, the thread cannot // be running on two processors as once, and 2) if the thread is // is interrupted to deliver a kernel mode APC which also calls // this routine, the values read and stored will stack and unstack // properly. // // Arguments: // // None. // // Return Value: // // None. //-- #define KeLeaveCriticalRegion() KiLeaveCriticalRegion() //++ // // VOID // KeLeaveCriticalRegionThread ( // PKTHREAD CurrentThread // ) // // // Routine Description: // // This function enables kernel APC's for the current thread. // // N.B. The following code does not require any interlocks. There are // two cases of interest: 1) On an MP system, the thread cannot // be running on two processors as once, and 2) if the thread is // is interrupted to deliver a kernel mode APC which also calls // this routine, the values read and stored will stack and unstack // properly. // // Arguments: // // CurrentThread - Current thread thats executing. This must be the // current thread. // // Return Value: // // None. //-- #define KeLeaveCriticalRegionThread(CurrentThread) { \ ASSERT (CurrentThread == KeGetCurrentThread ()); \ KiLeaveCriticalRegionThread(CurrentThread); \ } #define KeAreApcsDisabled() (KeGetCurrentThread()->KernelApcDisable != 0); //++ // // KPROCESSOR_MODE // KeGetPReviousMode ( // VOID // ) // // // Routine Description: // // This function gets the threads previous mode from the trap frame // // // Arguments: // // None. // // Return Value: // // KPROCESSOR_MODE - Previous mode for this thread //-- #define KeGetPreviousMode() (KeGetCurrentThread()->PreviousMode) //++ // // KPROCESSOR_MODE // KeGetPReviousModeByThread ( // PKTHREAD xxCurrentThread // ) // // // Routine Description: // // This function gets the threads previous mode from the trap frame. // // // Arguments: // // xxCurrentThread - Current thread. This can not be a cross thread reference // // Return Value: // // KPROCESSOR_MODE - Previous mode for this thread //-- #define KeGetPreviousModeByThread(xxCurrentThread) (ASSERT (xxCurrentThread == KeGetCurrentThread ()),\ (xxCurrentThread)->PreviousMode) #endif // begin_wdm // // Timer object // NTKERNELAPI VOID KeInitializeTimer ( IN PKTIMER Timer ); NTKERNELAPI VOID KeInitializeTimerEx ( IN PKTIMER Timer, IN TIMER_TYPE Type ); NTKERNELAPI BOOLEAN KeCancelTimer ( IN PKTIMER ); NTKERNELAPI BOOLEAN KeReadStateTimer ( PKTIMER Timer ); NTKERNELAPI BOOLEAN KeSetTimer ( IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL ); NTKERNELAPI BOOLEAN KeSetTimerEx ( IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period OPTIONAL, IN PKDPC Dpc OPTIONAL ); #define KeWaitForMutexObject KeWaitForSingleObject NTKERNELAPI NTSTATUS KeWaitForMultipleObjects ( IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, IN PKWAIT_BLOCK WaitBlockArray OPTIONAL ); NTKERNELAPI NTSTATUS KeWaitForSingleObject ( IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL ); // // On X86 the following routines are defined in the HAL and imported by // all other modules. // #if defined(_X86_) && !defined(_NTHAL_) #define _DECL_HAL_KE_IMPORT __declspec(dllimport) #else #define _DECL_HAL_KE_IMPORT #endif _DECL_HAL_KE_IMPORT KIRQL FASTCALL KeAcquireQueuedSpinLock ( IN KSPIN_LOCK_QUEUE_NUMBER Number ); _DECL_HAL_KE_IMPORT VOID FASTCALL KeReleaseQueuedSpinLock ( IN KSPIN_LOCK_QUEUE_NUMBER Number, IN KIRQL OldIrql ); _DECL_HAL_KE_IMPORT LOGICAL FASTCALL KeTryToAcquireQueuedSpinLock( IN KSPIN_LOCK_QUEUE_NUMBER Number, IN PKIRQL OldIrql ); // // spin lock functions // NTKERNELAPI VOID NTAPI KeInitializeSpinLock ( IN PKSPIN_LOCK SpinLock ); #if defined(_X86_) NTKERNELAPI VOID FASTCALL KefAcquireSpinLockAtDpcLevel ( IN PKSPIN_LOCK SpinLock ); NTKERNELAPI VOID FASTCALL KefReleaseSpinLockFromDpcLevel ( IN PKSPIN_LOCK SpinLock ); #define KeAcquireSpinLockAtDpcLevel(a) KefAcquireSpinLockAtDpcLevel(a) #define KeReleaseSpinLockFromDpcLevel(a) KefReleaseSpinLockFromDpcLevel(a) _DECL_HAL_KE_IMPORT KIRQL FASTCALL KfAcquireSpinLock ( IN PKSPIN_LOCK SpinLock ); _DECL_HAL_KE_IMPORT VOID FASTCALL KfReleaseSpinLock ( IN PKSPIN_LOCK SpinLock, IN KIRQL NewIrql ); // end_wdm _DECL_HAL_KE_IMPORT KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch ( IN PKSPIN_LOCK SpinLock ); // begin_wdm #define KeAcquireSpinLock(a,b) *(b) = KfAcquireSpinLock(a) #define KeReleaseSpinLock(a,b) KfReleaseSpinLock(a,b) #else NTKERNELAPI KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch ( IN PKSPIN_LOCK SpinLock ); NTKERNELAPI VOID KeAcquireSpinLockAtDpcLevel ( IN PKSPIN_LOCK SpinLock ); NTKERNELAPI VOID KeReleaseSpinLockFromDpcLevel ( IN PKSPIN_LOCK SpinLock ); NTKERNELAPI KIRQL KeAcquireSpinLockRaiseToDpc ( IN PKSPIN_LOCK SpinLock ); #define KeAcquireSpinLock(SpinLock, OldIrql) \ *(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock) NTKERNELAPI VOID KeReleaseSpinLock ( IN PKSPIN_LOCK SpinLock, IN KIRQL NewIrql ); #endif NTKERNELAPI BOOLEAN FASTCALL KeTryToAcquireSpinLockAtDpcLevel ( IN PKSPIN_LOCK SpinLock ); #if defined(_X86_) _DECL_HAL_KE_IMPORT VOID FASTCALL KfLowerIrql ( IN KIRQL NewIrql ); _DECL_HAL_KE_IMPORT KIRQL FASTCALL KfRaiseIrql ( IN KIRQL NewIrql ); // end_wdm _DECL_HAL_KE_IMPORT KIRQL KeRaiseIrqlToDpcLevel( VOID ); _DECL_HAL_KE_IMPORT KIRQL KeRaiseIrqlToSynchLevel( VOID ); // begin_wdm #define KeLowerIrql(a) KfLowerIrql(a) #define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a) // end_wdm // begin_wdm #elif defined(_ALPHA_) #define KeLowerIrql(a) __swpirql(a) #define KeRaiseIrql(a,b) *(b) = __swpirql(a) // end_wdm extern ULONG KiSynchIrql; #define KfRaiseIrql(a) __swpirql(a) #define KeRaiseIrqlToDpcLevel() __swpirql(DISPATCH_LEVEL) #define KeRaiseIrqlToSynchLevel() __swpirql((UCHAR)KiSynchIrql) // begin_wdm #elif defined(_IA64_) VOID KeLowerIrql ( IN KIRQL NewIrql ); VOID KeRaiseIrql ( IN KIRQL NewIrql, OUT PKIRQL OldIrql ); // end_wdm KIRQL KfRaiseIrql ( IN KIRQL NewIrql ); KIRQL KeRaiseIrqlToDpcLevel ( VOID ); KIRQL KeRaiseIrqlToSynchLevel ( VOID ); // begin_wdm #elif defined(_AMD64_) // // These function are defined in amd64.h for the AMD64 platform. // #else #error "no target architecture" #endif // // Queued spin lock functions for "in stack" lock handles. // // The following three functions RAISE and LOWER IRQL when a queued // in stack spin lock is acquired or released using these routines. // _DECL_HAL_KE_IMPORT VOID FASTCALL KeAcquireInStackQueuedSpinLock ( IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle ); _DECL_HAL_KE_IMPORT VOID FASTCALL KeReleaseInStackQueuedSpinLock ( IN PKLOCK_QUEUE_HANDLE LockHandle ); // // The following two functions do NOT raise or lower IRQL when a queued // in stack spin lock is acquired or released using these functions. // NTKERNELAPI VOID FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel ( IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle ); NTKERNELAPI VOID FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel ( IN PKLOCK_QUEUE_HANDLE LockHandle ); // // Miscellaneous kernel functions // typedef enum _KBUGCHECK_BUFFER_DUMP_STATE { BufferEmpty, BufferInserted, BufferStarted, BufferFinished, BufferIncomplete } KBUGCHECK_BUFFER_DUMP_STATE; typedef VOID (*PKBUGCHECK_CALLBACK_ROUTINE) ( IN PVOID Buffer, IN ULONG Length ); typedef struct _KBUGCHECK_CALLBACK_RECORD { LIST_ENTRY Entry; PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine; PVOID Buffer; ULONG Length; PUCHAR Component; ULONG_PTR Checksum; UCHAR State; } KBUGCHECK_CALLBACK_RECORD, *PKBUGCHECK_CALLBACK_RECORD; #define KeInitializeCallbackRecord(CallbackRecord) \ (CallbackRecord)->State = BufferEmpty NTKERNELAPI BOOLEAN KeDeregisterBugCheckCallback ( IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord ); NTKERNELAPI BOOLEAN KeRegisterBugCheckCallback ( IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord, IN PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Buffer, IN ULONG Length, IN PUCHAR Component ); typedef enum _KBUGCHECK_CALLBACK_REASON { KbCallbackInvalid, KbCallbackReserved1, KbCallbackSecondaryDumpData, KbCallbackDumpIo, } KBUGCHECK_CALLBACK_REASON; typedef VOID (*PKBUGCHECK_REASON_CALLBACK_ROUTINE) ( IN KBUGCHECK_CALLBACK_REASON Reason, IN struct _KBUGCHECK_REASON_CALLBACK_RECORD* Record, IN OUT PVOID ReasonSpecificData, IN ULONG ReasonSpecificDataLength ); typedef struct _KBUGCHECK_REASON_CALLBACK_RECORD { LIST_ENTRY Entry; PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine; PUCHAR Component; ULONG_PTR Checksum; KBUGCHECK_CALLBACK_REASON Reason; UCHAR State; } KBUGCHECK_REASON_CALLBACK_RECORD, *PKBUGCHECK_REASON_CALLBACK_RECORD; typedef struct _KBUGCHECK_SECONDARY_DUMP_DATA { IN PVOID InBuffer; IN ULONG InBufferLength; IN ULONG MaximumAllowed; OUT GUID Guid; OUT PVOID OutBuffer; OUT ULONG OutBufferLength; } KBUGCHECK_SECONDARY_DUMP_DATA, *PKBUGCHECK_SECONDARY_DUMP_DATA; typedef enum _KBUGCHECK_DUMP_IO_TYPE { KbDumpIoInvalid, KbDumpIoHeader, KbDumpIoBody, KbDumpIoSecondaryData, KbDumpIoComplete } KBUGCHECK_DUMP_IO_TYPE; typedef struct _KBUGCHECK_DUMP_IO { IN ULONG64 Offset; IN PVOID Buffer; IN ULONG BufferLength; IN KBUGCHECK_DUMP_IO_TYPE Type; } KBUGCHECK_DUMP_IO, *PKBUGCHECK_DUMP_IO; NTKERNELAPI BOOLEAN KeDeregisterBugCheckReasonCallback ( IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord ); NTKERNELAPI BOOLEAN KeRegisterBugCheckReasonCallback ( IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, IN KBUGCHECK_CALLBACK_REASON Reason, IN PUCHAR Component ); // end_wdm NTKERNELAPI DECLSPEC_NORETURN VOID NTAPI KeBugCheck ( IN ULONG BugCheckCode ); NTKERNELAPI DECLSPEC_NORETURN VOID KeBugCheckEx( IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4 ); #define WIN32K_SERVICE_INDEX 1 #define IIS_SERVICE_INDEX 2 NTKERNELAPI BOOLEAN KeAddSystemServiceTable( IN PULONG_PTR Base, IN PULONG Count OPTIONAL, IN ULONG Limit, IN PUCHAR Number, IN ULONG Index ); NTKERNELAPI BOOLEAN KeRemoveSystemServiceTable( IN ULONG Index ); NTKERNELAPI ULONGLONG KeQueryInterruptTime ( VOID ); NTKERNELAPI VOID KeQuerySystemTime ( OUT PLARGE_INTEGER CurrentTime ); NTKERNELAPI ULONG KeQueryTimeIncrement ( VOID ); NTKERNELAPI ULONG KeGetRecommendedSharedDataAlignment ( VOID ); // end_wdm NTKERNELAPI KAFFINITY KeQueryActiveProcessors ( VOID ); // // Define the firmware routine types // typedef enum _FIRMWARE_REENTRY { HalHaltRoutine, HalPowerDownRoutine, HalRestartRoutine, HalRebootRoutine, HalInteractiveModeRoutine, HalMaximumRoutine } FIRMWARE_REENTRY, *PFIRMWARE_REENTRY; NTKERNELAPI NTSTATUS KeUserModeCallback ( IN ULONG ApiNumber, IN PVOID InputBuffer, IN ULONG InputLength, OUT PVOID *OutputBuffer, OUT PULONG OutputLength ); // // Time update notify routine. // typedef VOID (FASTCALL *PTIME_UPDATE_NOTIFY_ROUTINE)( IN HANDLE ThreadId, IN KPROCESSOR_MODE Mode ); NTKERNELAPI VOID FASTCALL KeSetTimeUpdateNotifyRoutine( IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine ); extern PLOADER_PARAMETER_BLOCK KeLoaderBlock; extern NTSYSAPI CCHAR KeNumberProcessors; #if defined(_AMD64_) || defined(_ALPHA_) || defined(_IA64_) extern volatile LARGE_INTEGER KeTickCount; #else extern volatile KSYSTEM_TIME KeTickCount; #endif typedef enum _MEMORY_CACHING_TYPE_ORIG { MmFrameBufferCached = 2 } MEMORY_CACHING_TYPE_ORIG; typedef enum _MEMORY_CACHING_TYPE { MmNonCached = FALSE, MmCached = TRUE, MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, MmNonCachedUnordered, // IA64 MmUSWCCached, MmMaximumCacheType } MEMORY_CACHING_TYPE; // // Pool Allocation routines (in pool.c) // typedef enum _POOL_TYPE { NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS, MaxPoolType // end_wdm , // // Note these per session types are carefully chosen so that the appropriate // masking still applies as well as MaxPoolType above. // NonPagedPoolSession = 32, PagedPoolSession = NonPagedPoolSession + 1, NonPagedPoolMustSucceedSession = PagedPoolSession + 1, DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1, // begin_wdm } POOL_TYPE; #define POOL_COLD_ALLOCATION 256 // Note this cannot encode into the header. // end_ntddk end_wdm end_nthal end_ntifs end_ntndis begin_ntosp // // The following two definitions control the raising of exceptions on quota // and allocation failures. // #define POOL_QUOTA_FAIL_INSTEAD_OF_RAISE 8 #define POOL_RAISE_IF_ALLOCATION_FAILURE 16 // ntifs NTKERNELAPI PVOID ExAllocatePool( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes ); NTKERNELAPI PVOID ExAllocatePoolWithQuota( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes ); NTKERNELAPI PVOID NTAPI ExAllocatePoolWithTag( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag ); // // _EX_POOL_PRIORITY_ provides a method for the system to handle requests // intelligently in low resource conditions. // // LowPoolPriority should be used when it is acceptable to the driver for the // mapping request to fail if the system is low on resources. An example of // this could be for a non-critical network connection where the driver can // handle the failure case when system resources are close to being depleted. // // NormalPoolPriority should be used when it is acceptable to the driver for the // mapping request to fail if the system is very low on resources. An example // of this could be for a non-critical local filesystem request. // // HighPoolPriority should be used when it is unacceptable to the driver for the // mapping request to fail unless the system is completely out of resources. // An example of this would be the paging file path in a driver. // // SpecialPool can be specified to bound the allocation at a page end (or // beginning). This should only be done on systems being debugged as the // memory cost is expensive. // // N.B. These values are very carefully chosen so that the pool allocation // code can quickly crack the priority request. // typedef enum _EX_POOL_PRIORITY { LowPoolPriority, LowPoolPrioritySpecialPoolOverrun = 8, LowPoolPrioritySpecialPoolUnderrun = 9, NormalPoolPriority = 16, NormalPoolPrioritySpecialPoolOverrun = 24, NormalPoolPrioritySpecialPoolUnderrun = 25, HighPoolPriority = 32, HighPoolPrioritySpecialPoolOverrun = 40, HighPoolPrioritySpecialPoolUnderrun = 41 } EX_POOL_PRIORITY; NTKERNELAPI PVOID NTAPI ExAllocatePoolWithTagPriority( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag, IN EX_POOL_PRIORITY Priority ); #ifndef POOL_TAGGING #define ExAllocatePoolWithTag(a,b,c) ExAllocatePool(a,b) #endif //POOL_TAGGING NTKERNELAPI PVOID ExAllocatePoolWithQuotaTag( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag ); #ifndef POOL_TAGGING #define ExAllocatePoolWithQuotaTag(a,b,c) ExAllocatePoolWithQuota(a,b) #endif //POOL_TAGGING NTKERNELAPI VOID NTAPI ExFreePool( IN PVOID P ); // end_wdm #if defined(POOL_TAGGING) #define ExFreePool(a) ExFreePoolWithTag(a,0) #endif // // If high order bit in Pool tag is set, then must use ExFreePoolWithTag to free // #define PROTECTED_POOL 0x80000000 // begin_wdm NTKERNELAPI VOID ExFreePoolWithTag( IN PVOID P, IN ULONG Tag ); // end_ntddk end_wdm end_nthal end_ntifs #ifndef POOL_TAGGING #define ExFreePoolWithTag(a,b) ExFreePool(a) #endif //POOL_TAGGING NTKERNELAPI // ntifs SIZE_T // ntifs ExQueryPoolBlockSize ( // ntifs IN PVOID PoolBlock, // ntifs OUT PBOOLEAN QuotaCharged // ntifs ); // ntifs // // Routines to support fast mutexes. // typedef struct _FAST_MUTEX { LONG Count; PKTHREAD Owner; ULONG Contention; KEVENT Event; ULONG OldIrql; } FAST_MUTEX, *PFAST_MUTEX; #define ExInitializeFastMutex(_FastMutex) \ (_FastMutex)->Count = 1; \ (_FastMutex)->Owner = NULL; \ (_FastMutex)->Contention = 0; \ KeInitializeEvent(&(_FastMutex)->Event, \ SynchronizationEvent, \ FALSE); NTKERNELAPI VOID FASTCALL ExAcquireFastMutexUnsafe ( IN PFAST_MUTEX FastMutex ); NTKERNELAPI VOID FASTCALL ExReleaseFastMutexUnsafe ( IN PFAST_MUTEX FastMutex ); #if defined(_ALPHA_) || defined(_IA64_) || defined(_AMD64_) NTKERNELAPI VOID FASTCALL ExAcquireFastMutex ( IN PFAST_MUTEX FastMutex ); NTKERNELAPI VOID FASTCALL ExReleaseFastMutex ( IN PFAST_MUTEX FastMutex ); NTKERNELAPI BOOLEAN FASTCALL ExTryToAcquireFastMutex ( IN PFAST_MUTEX FastMutex ); #elif defined(_X86_) NTHALAPI VOID FASTCALL ExAcquireFastMutex ( IN PFAST_MUTEX FastMutex ); NTHALAPI VOID FASTCALL ExReleaseFastMutex ( IN PFAST_MUTEX FastMutex ); NTHALAPI BOOLEAN FASTCALL ExTryToAcquireFastMutex ( IN PFAST_MUTEX FastMutex ); #else #error "Target architecture not defined" #endif // NTKERNELAPI VOID FASTCALL ExInterlockedAddLargeStatistic ( IN PLARGE_INTEGER Addend, IN ULONG Increment ); // end_ntndis NTKERNELAPI LARGE_INTEGER ExInterlockedAddLargeInteger ( IN PLARGE_INTEGER Addend, IN LARGE_INTEGER Increment, IN PKSPIN_LOCK Lock ); NTKERNELAPI ULONG FASTCALL ExInterlockedAddUlong ( IN PULONG Addend, IN ULONG Increment, IN PKSPIN_LOCK Lock ); #if defined(_AMD64_) || defined(_AXP64_) || defined(_IA64_) #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \ InterlockedCompareExchange64(Destination, *(Exchange), *(Comperand)) #elif defined(_ALPHA_) #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \ ExpInterlockedCompareExchange64(Destination, Exchange, Comperand) #else #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \ ExfInterlockedCompareExchange64(Destination, Exchange, Comperand) #endif NTKERNELAPI PLIST_ENTRY FASTCALL ExInterlockedInsertHeadList ( IN PLIST_ENTRY ListHead, IN PLIST_ENTRY ListEntry, IN PKSPIN_LOCK Lock ); NTKERNELAPI PLIST_ENTRY FASTCALL ExInterlockedInsertTailList ( IN PLIST_ENTRY ListHead, IN PLIST_ENTRY ListEntry, IN PKSPIN_LOCK Lock ); NTKERNELAPI PLIST_ENTRY FASTCALL ExInterlockedRemoveHeadList ( IN PLIST_ENTRY ListHead, IN PKSPIN_LOCK Lock ); NTKERNELAPI PSINGLE_LIST_ENTRY FASTCALL ExInterlockedPopEntryList ( IN PSINGLE_LIST_ENTRY ListHead, IN PKSPIN_LOCK Lock ); NTKERNELAPI PSINGLE_LIST_ENTRY FASTCALL ExInterlockedPushEntryList ( IN PSINGLE_LIST_ENTRY ListHead, IN PSINGLE_LIST_ENTRY ListEntry, IN PKSPIN_LOCK Lock ); // // Define interlocked sequenced listhead functions. // // A sequenced interlocked list is a singly linked list with a header that // contains the current depth and a sequence number. Each time an entry is // inserted or removed from the list the depth is updated and the sequence // number is incremented. This enables AMD64, IA64, and Pentium and later // machines to insert and remove from the list without the use of spinlocks. // #if !defined(_WINBASE_) /*++ Routine Description: This function initializes a sequenced singly linked listhead. Arguments: SListHead - Supplies a pointer to a sequenced singly linked listhead. Return Value: None. --*/ #if defined(_WIN64) && (defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || defined(_NTOSP_)) NTKERNELAPI VOID InitializeSListHead ( IN PSLIST_HEADER SListHead ); #else __inline VOID InitializeSListHead ( IN PSLIST_HEADER SListHead ) { #ifdef _WIN64 // // Slist headers must be 16 byte aligned. // if ((ULONG_PTR) SListHead & 0x0f) { DbgPrint( "InitializeSListHead unaligned Slist header. Address = %p, Caller = %p\n", SListHead, _ReturnAddress()); RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT); } #endif SListHead->Alignment = 0; // // For IA-64 we save the region number of the elements of the list in a // separate field. This imposes the requirement that all elements stored // in the list are from the same region. #if defined(_IA64_) SListHead->Region = (ULONG_PTR)SListHead & VRN_MASK; #elif defined(_AMD64_) SListHead->Region = 0; #endif return; } #endif #endif // !defined(_WINBASE_) #define ExInitializeSListHead InitializeSListHead PSLIST_ENTRY FirstEntrySList ( IN const SLIST_HEADER *SListHead ); /*++ Routine Description: This function queries the current number of entries contained in a sequenced single linked list. Arguments: SListHead - Supplies a pointer to the sequenced listhead which is be queried. Return Value: The current number of entries in the sequenced singly linked list is returned as the function value. --*/ #if defined(_WIN64) #if (defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || defined(_NTOSP_)) NTKERNELAPI USHORT ExQueryDepthSList ( IN PSLIST_HEADER SListHead ); #else __inline USHORT ExQueryDepthSList ( IN PSLIST_HEADER SListHead ) { return (USHORT)(SListHead->Alignment & 0xffff); } #endif #else #define ExQueryDepthSList(_listhead_) (_listhead_)->Depth #endif #if defined(_WIN64) #define ExInterlockedPopEntrySList(Head, Lock) \ ExpInterlockedPopEntrySList(Head) #define ExInterlockedPushEntrySList(Head, Entry, Lock) \ ExpInterlockedPushEntrySList(Head, Entry) #define ExInterlockedFlushSList(Head) \ ExpInterlockedFlushSList(Head) #if !defined(_WINBASE_) #define InterlockedPopEntrySList(Head) \ ExpInterlockedPopEntrySList(Head) #define InterlockedPushEntrySList(Head, Entry) \ ExpInterlockedPushEntrySList(Head, Entry) #define InterlockedFlushSList(Head) \ ExpInterlockedFlushSList(Head) #define QueryDepthSList(Head) \ ExQueryDepthSList(Head) #endif // !defined(_WINBASE_) NTKERNELAPI PSLIST_ENTRY ExpInterlockedPopEntrySList ( IN PSLIST_HEADER ListHead ); NTKERNELAPI PSLIST_ENTRY ExpInterlockedPushEntrySList ( IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry ); NTKERNELAPI PSLIST_ENTRY ExpInterlockedFlushSList ( IN PSLIST_HEADER ListHead ); #else #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_) NTKERNELAPI PSLIST_ENTRY FASTCALL ExInterlockedPopEntrySList ( IN PSLIST_HEADER ListHead, IN PKSPIN_LOCK Lock ); NTKERNELAPI PSLIST_ENTRY FASTCALL ExInterlockedPushEntrySList ( IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry, IN PKSPIN_LOCK Lock ); #else #define ExInterlockedPopEntrySList(ListHead, Lock) \ InterlockedPopEntrySList(ListHead) #define ExInterlockedPushEntrySList(ListHead, ListEntry, Lock) \ InterlockedPushEntrySList(ListHead, ListEntry) #endif NTKERNELAPI PSLIST_ENTRY FASTCALL ExInterlockedFlushSList ( IN PSLIST_HEADER ListHead ); #if !defined(_WINBASE_) NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPopEntrySList ( IN PSLIST_HEADER ListHead ); NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList ( IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry ); #define InterlockedFlushSList(Head) \ ExInterlockedFlushSList(Head) #define QueryDepthSList(Head) \ ExQueryDepthSList(Head) #endif // !defined(_WINBASE_) #endif // defined(_WIN64) typedef PVOID (*PALLOCATE_FUNCTION) ( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag ); typedef VOID (*PFREE_FUNCTION) ( IN PVOID Buffer ); #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_)) typedef struct _GENERAL_LOOKASIDE { #else typedef struct DECLSPEC_CACHEALIGN _GENERAL_LOOKASIDE { #endif SLIST_HEADER ListHead; USHORT Depth; USHORT MaximumDepth; ULONG TotalAllocates; union { ULONG AllocateMisses; ULONG AllocateHits; }; ULONG TotalFrees; union { ULONG FreeMisses; ULONG FreeHits; }; POOL_TYPE Type; ULONG Tag; ULONG Size; PALLOCATE_FUNCTION Allocate; PFREE_FUNCTION Free; LIST_ENTRY ListEntry; ULONG LastTotalAllocates; union { ULONG LastAllocateMisses; ULONG LastAllocateHits; }; ULONG Future[2]; } GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE; #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_)) typedef struct _NPAGED_LOOKASIDE_LIST { #else typedef struct DECLSPEC_CACHEALIGN _NPAGED_LOOKASIDE_LIST { #endif GENERAL_LOOKASIDE L; #if !defined(_AMD64_) && !defined(_IA64_) KSPIN_LOCK Lock__ObsoleteButDoNotDelete; #endif } NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST; NTKERNELAPI VOID ExInitializeNPagedLookasideList ( IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate, IN PFREE_FUNCTION Free, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth ); NTKERNELAPI VOID ExDeleteNPagedLookasideList ( IN PNPAGED_LOOKASIDE_LIST Lookaside ); __inline PVOID ExAllocateFromNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside ) /*++ Routine Description: This function removes (pops) the first entry from the specified nonpaged lookaside list. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Return Value: If an entry is removed from the specified lookaside list, then the address of the entry is returned as the function value. Otherwise, NULL is returned. --*/ { PVOID Entry; Lookaside->L.TotalAllocates += 1; #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_) Entry = ExInterlockedPopEntrySList(&Lookaside->L.ListHead, &Lookaside->Lock__ObsoleteButDoNotDelete); #else Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); #endif if (Entry == NULL) { Lookaside->L.AllocateMisses += 1; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } return Entry; } __inline VOID ExFreeToNPagedLookasideList( IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry ) /*++ Routine Description: This function inserts (pushes) the specified entry into the specified nonpaged lookaside list. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Entry - Supples a pointer to the entry that is inserted in the lookaside list. Return Value: None. --*/ { Lookaside->L.TotalFrees += 1; if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { Lookaside->L.FreeMisses += 1; (Lookaside->L.Free)(Entry); } else { #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_) ExInterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry, &Lookaside->Lock__ObsoleteButDoNotDelete); #else InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); #endif } return; } // end_ntndis #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_)) typedef struct _PAGED_LOOKASIDE_LIST { #else typedef struct DECLSPEC_CACHEALIGN _PAGED_LOOKASIDE_LIST { #endif GENERAL_LOOKASIDE L; #if !defined(_AMD64_) && !defined(_IA64_) FAST_MUTEX Lock__ObsoleteButDoNotDelete; #endif } PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST; NTKERNELAPI VOID ExInitializePagedLookasideList ( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate, IN PFREE_FUNCTION Free, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth ); NTKERNELAPI VOID ExDeletePagedLookasideList ( IN PPAGED_LOOKASIDE_LIST Lookaside ); #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_) NTKERNELAPI PVOID ExAllocateFromPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside ); #else __inline PVOID ExAllocateFromPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside ) /*++ Routine Description: This function removes (pops) the first entry from the specified paged lookaside list. Arguments: Lookaside - Supplies a pointer to a paged lookaside list structure. Return Value: If an entry is removed from the specified lookaside list, then the address of the entry is returned as the function value. Otherwise, NULL is returned. --*/ { PVOID Entry; Lookaside->L.TotalAllocates += 1; Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (Entry == NULL) { Lookaside->L.AllocateMisses += 1; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } return Entry; } #endif #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_) NTKERNELAPI VOID ExFreeToPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry ); #else __inline VOID ExFreeToPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry ) /*++ Routine Description: This function inserts (pushes) the specified entry into the specified paged lookaside list. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Entry - Supples a pointer to the entry that is inserted in the lookaside list. Return Value: None. --*/ { Lookaside->L.TotalFrees += 1; if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { Lookaside->L.FreeMisses += 1; (Lookaside->L.Free)(Entry); } else { InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); } return; } #endif NTKERNELAPI VOID NTAPI ProbeForRead( IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment ); // Probe function definitions // // Probe for read functions. // //++ // // VOID // ProbeForRead( // IN PVOID Address, // IN ULONG Length, // IN ULONG Alignment // ) // //-- #define ProbeForRead(Address, Length, Alignment) \ ASSERT(((Alignment) == 1) || ((Alignment) == 2) || \ ((Alignment) == 4) || ((Alignment) == 8) || \ ((Alignment) == 16)); \ \ if ((Length) != 0) { \ if (((ULONG_PTR)(Address) & ((Alignment) - 1)) != 0) { \ ExRaiseDatatypeMisalignment(); \ \ } \ if ((((ULONG_PTR)(Address) + (Length)) < (ULONG_PTR)(Address)) || \ (((ULONG_PTR)(Address) + (Length)) > (ULONG_PTR)MM_USER_PROBE_ADDRESS)) { \ ExRaiseAccessViolation(); \ } \ } //++ // // VOID // ProbeForReadSmallStructure( // IN PVOID Address, // IN ULONG Length, // IN ULONG Alignment // ) // //-- #define ProbeForReadSmallStructure(Address,Size,Alignment) { \ ASSERT(((Alignment) == 1) || ((Alignment) == 2) || \ ((Alignment) == 4) || ((Alignment) == 8) || \ ((Alignment) == 16)); \ if (Size == 0 || Size > 0x10000) { \ ASSERT (0); \ ProbeForRead (Address,Size,Alignment); \ } else { \ if (((ULONG_PTR)(Address) & ((Alignment) - 1)) != 0) { \ ExRaiseDatatypeMisalignment(); \ } \ if ((ULONG_PTR)(Address) >= (ULONG_PTR)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ } \ } //++ // // BOOLEAN // ProbeAndReadBoolean( // IN PBOOLEAN Address // ) // //-- #define ProbeAndReadBoolean(Address) \ (((Address) >= (BOOLEAN * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile BOOLEAN * const)MM_USER_PROBE_ADDRESS) : (*(volatile BOOLEAN *)(Address))) //++ // // CHAR // ProbeAndReadChar( // IN PCHAR Address // ) // //-- #define ProbeAndReadChar(Address) \ (((Address) >= (CHAR * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile CHAR * const)MM_USER_PROBE_ADDRESS) : (*(volatile CHAR *)(Address))) //++ // // UCHAR // ProbeAndReadUchar( // IN PUCHAR Address // ) // //-- #define ProbeAndReadUchar(Address) \ (((Address) >= (UCHAR * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile UCHAR * const)MM_USER_PROBE_ADDRESS) : (*(volatile UCHAR *)(Address))) //++ // // SHORT // ProbeAndReadShort( // IN PSHORT Address // ) // //-- #define ProbeAndReadShort(Address) \ (((Address) >= (SHORT * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile SHORT * const)MM_USER_PROBE_ADDRESS) : (*(volatile SHORT *)(Address))) //++ // // USHORT // ProbeAndReadUshort( // IN PUSHORT Address // ) // //-- #define ProbeAndReadUshort(Address) \ (((Address) >= (USHORT * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile USHORT * const)MM_USER_PROBE_ADDRESS) : (*(volatile USHORT *)(Address))) //++ // // HANDLE // ProbeAndReadHandle( // IN PHANDLE Address // ) // //-- #define ProbeAndReadHandle(Address) \ (((Address) >= (HANDLE * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile HANDLE * const)MM_USER_PROBE_ADDRESS) : (*(volatile HANDLE *)(Address))) //++ // // PVOID // ProbeAndReadPointer( // IN PVOID *Address // ) // //-- #define ProbeAndReadPointer(Address) \ (((Address) >= (PVOID * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile PVOID * const)MM_USER_PROBE_ADDRESS) : (*(volatile PVOID *)(Address))) //++ // // LONG // ProbeAndReadLong( // IN PLONG Address // ) // //-- #define ProbeAndReadLong(Address) \ (((Address) >= (LONG * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile LONG * const)MM_USER_PROBE_ADDRESS) : (*(volatile LONG *)(Address))) //++ // // ULONG // ProbeAndReadUlong( // IN PULONG Address // ) // //-- #define ProbeAndReadUlong(Address) \ (((Address) >= (ULONG * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile ULONG * const)MM_USER_PROBE_ADDRESS) : (*(volatile ULONG *)(Address))) //++ // // ULONG_PTR // ProbeAndReadUlong_ptr( // IN PULONG_PTR Address // ) // //-- #define ProbeAndReadUlong_ptr(Address) \ (((Address) >= (ULONG_PTR * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile ULONG_PTR * const)MM_USER_PROBE_ADDRESS) : (*(volatile ULONG_PTR *)(Address))) //++ // // QUAD // ProbeAndReadQuad( // IN PQUAD Address // ) // //-- #define ProbeAndReadQuad(Address) \ (((Address) >= (QUAD * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile QUAD * const)MM_USER_PROBE_ADDRESS) : (*(volatile QUAD *)(Address))) //++ // // UQUAD // ProbeAndReadUquad( // IN PUQUAD Address // ) // //-- #define ProbeAndReadUquad(Address) \ (((Address) >= (UQUAD * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile UQUAD * const)MM_USER_PROBE_ADDRESS) : (*(volatile UQUAD *)(Address))) //++ // // LARGE_INTEGER // ProbeAndReadLargeInteger( // IN PLARGE_INTEGER Source // ) // //-- #define ProbeAndReadLargeInteger(Source) \ (((Source) >= (LARGE_INTEGER * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile LARGE_INTEGER * const)MM_USER_PROBE_ADDRESS) : (*(volatile LARGE_INTEGER *)(Source))) //++ // // ULARGE_INTEGER // ProbeAndReadUlargeInteger( // IN PULARGE_INTEGER Source // ) // //-- #define ProbeAndReadUlargeInteger(Source) \ (((Source) >= (ULARGE_INTEGER * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile ULARGE_INTEGER * const)MM_USER_PROBE_ADDRESS) : (*(volatile ULARGE_INTEGER *)(Source))) //++ // // UNICODE_STRING // ProbeAndReadUnicodeString( // IN PUNICODE_STRING Source // ) // //-- #define ProbeAndReadUnicodeString(Source) \ (((Source) >= (UNICODE_STRING * const)MM_USER_PROBE_ADDRESS) ? \ (*(volatile UNICODE_STRING * const)MM_USER_PROBE_ADDRESS) : (*(volatile UNICODE_STRING *)(Source))) //++ // // // ProbeAndReadStructure( // IN P Source // // ) // //-- #define ProbeAndReadStructure(Source,STRUCTURE) \ (((Source) >= (STRUCTURE * const)MM_USER_PROBE_ADDRESS) ? \ (*(STRUCTURE * const)MM_USER_PROBE_ADDRESS) : (*(STRUCTURE *)(Source))) // // Probe for write functions definitions. // //++ // // VOID // ProbeForWriteBoolean( // IN PBOOLEAN Address // ) // //-- #define ProbeForWriteBoolean(Address) { \ if ((Address) >= (BOOLEAN * const)MM_USER_PROBE_ADDRESS) { \ *(volatile BOOLEAN * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile BOOLEAN *)(Address) = *(volatile BOOLEAN *)(Address); \ } //++ // // VOID // ProbeForWriteChar( // IN PCHAR Address // ) // //-- #define ProbeForWriteChar(Address) { \ if ((Address) >= (CHAR * const)MM_USER_PROBE_ADDRESS) { \ *(volatile CHAR * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile CHAR *)(Address) = *(volatile CHAR *)(Address); \ } //++ // // VOID // ProbeForWriteUchar( // IN PUCHAR Address // ) // //-- #define ProbeForWriteUchar(Address) { \ if ((Address) >= (UCHAR * const)MM_USER_PROBE_ADDRESS) { \ *(volatile UCHAR * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile UCHAR *)(Address) = *(volatile UCHAR *)(Address); \ } //++ // // VOID // ProbeForWriteIoStatus( // IN PIO_STATUS_BLOCK Address // ) // //-- #define ProbeForWriteIoStatus(Address) { \ if ((Address) >= (IO_STATUS_BLOCK * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile IO_STATUS_BLOCK *)(Address) = *(volatile IO_STATUS_BLOCK *)(Address); \ } #ifdef _WIN64 #define ProbeForWriteIoStatusEx(Address, Cookie) { \ if ((Address) >= (IO_STATUS_BLOCK * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ if ((ULONG_PTR)(Cookie) & (ULONG)1) { \ *(volatile IO_STATUS_BLOCK32 *)(Address) = *(volatile IO_STATUS_BLOCK32 *)(Address);\ } else { \ *(volatile IO_STATUS_BLOCK *)(Address) = *(volatile IO_STATUS_BLOCK *)(Address); \ } \ } #else #define ProbeForWriteIoStatusEx(Address, Cookie) ProbeForWriteIoStatus(Address) #endif //++ // // VOID // ProbeForWriteShort( // IN PSHORT Address // ) // //-- #define ProbeForWriteShort(Address) { \ if ((Address) >= (SHORT * const)MM_USER_PROBE_ADDRESS) { \ *(volatile SHORT * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile SHORT *)(Address) = *(volatile SHORT *)(Address); \ } //++ // // VOID // ProbeForWriteUshort( // IN PUSHORT Address // ) // //-- #define ProbeForWriteUshort(Address) { \ if ((Address) >= (USHORT * const)MM_USER_PROBE_ADDRESS) { \ *(volatile USHORT * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile USHORT *)(Address) = *(volatile USHORT *)(Address); \ } //++ // // VOID // ProbeForWriteHandle( // IN PHANDLE Address // ) // //-- #define ProbeForWriteHandle(Address) { \ if ((Address) >= (HANDLE * const)MM_USER_PROBE_ADDRESS) { \ *(volatile HANDLE * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile HANDLE *)(Address) = *(volatile HANDLE *)(Address); \ } //++ // // VOID // ProbeAndZeroHandle( // IN PHANDLE Address // ) // //-- #define ProbeAndZeroHandle(Address) { \ if ((Address) >= (HANDLE * const)MM_USER_PROBE_ADDRESS) { \ *(volatile HANDLE * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile HANDLE *)(Address) = 0; \ } //++ // // VOID // ProbeForWritePointer( // IN PVOID Address // ) // //-- #define ProbeForWritePointer(Address) { \ if ((PVOID *)(Address) >= (PVOID * const)MM_USER_PROBE_ADDRESS) { \ *(volatile PVOID * const)MM_USER_PROBE_ADDRESS = NULL; \ } \ \ *(volatile PVOID *)(Address) = *(volatile PVOID *)(Address); \ } //++ // // VOID // ProbeAndNullPointer( // IN PVOID *Address // ) // //-- #define ProbeAndNullPointer(Address) { \ if ((PVOID *)(Address) >= (PVOID * const)MM_USER_PROBE_ADDRESS) { \ *(volatile PVOID * const)MM_USER_PROBE_ADDRESS = NULL; \ } \ \ *(volatile PVOID *)(Address) = NULL; \ } //++ // // VOID // ProbeForWriteLong( // IN PLONG Address // ) // //-- #define ProbeForWriteLong(Address) { \ if ((Address) >= (LONG * const)MM_USER_PROBE_ADDRESS) { \ *(volatile LONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile LONG *)(Address) = *(volatile LONG *)(Address); \ } //++ // // VOID // ProbeForWriteUlong( // IN PULONG Address // ) // //-- #define ProbeForWriteUlong(Address) { \ if ((Address) >= (ULONG * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile ULONG *)(Address) = *(volatile ULONG *)(Address); \ } //++ // // VOID // ProbeForWriteUlong_ptr( // IN PULONG_PTR Address // ) // //-- #define ProbeForWriteUlong_ptr(Address) { \ if ((Address) >= (ULONG_PTR * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG_PTR * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile ULONG_PTR *)(Address) = *(volatile ULONG_PTR *)(Address); \ } //++ // // VOID // ProbeForWriteQuad( // IN PQUAD Address // ) // //-- #define ProbeForWriteQuad(Address) { \ if ((Address) >= (QUAD * const)MM_USER_PROBE_ADDRESS) { \ *(volatile LONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile QUAD *)(Address) = *(volatile QUAD *)(Address); \ } //++ // // VOID // ProbeForWriteUquad( // IN PUQUAD Address // ) // //-- #define ProbeForWriteUquad(Address) { \ if ((Address) >= (QUAD * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(volatile UQUAD *)(Address) = *(volatile UQUAD *)(Address); \ } // // Probe and write functions definitions. // //++ // // VOID // ProbeAndWriteBoolean( // IN PBOOLEAN Address, // IN BOOLEAN Value // ) // //-- #define ProbeAndWriteBoolean(Address, Value) { \ if ((Address) >= (BOOLEAN * const)MM_USER_PROBE_ADDRESS) { \ *(volatile BOOLEAN * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteChar( // IN PCHAR Address, // IN CHAR Value // ) // //-- #define ProbeAndWriteChar(Address, Value) { \ if ((Address) >= (CHAR * const)MM_USER_PROBE_ADDRESS) { \ *(volatile CHAR * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteUchar( // IN PUCHAR Address, // IN UCHAR Value // ) // //-- #define ProbeAndWriteUchar(Address, Value) { \ if ((Address) >= (UCHAR * const)MM_USER_PROBE_ADDRESS) { \ *(volatile UCHAR * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteShort( // IN PSHORT Address, // IN SHORT Value // ) // //-- #define ProbeAndWriteShort(Address, Value) { \ if ((Address) >= (SHORT * const)MM_USER_PROBE_ADDRESS) { \ *(volatile SHORT * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteUshort( // IN PUSHORT Address, // IN USHORT Value // ) // //-- #define ProbeAndWriteUshort(Address, Value) { \ if ((Address) >= (USHORT * const)MM_USER_PROBE_ADDRESS) { \ *(volatile USHORT * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteHandle( // IN PHANDLE Address, // IN HANDLE Value // ) // //-- #define ProbeAndWriteHandle(Address, Value) { \ if ((Address) >= (HANDLE * const)MM_USER_PROBE_ADDRESS) { \ *(volatile HANDLE * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteLong( // IN PLONG Address, // IN LONG Value // ) // //-- #define ProbeAndWriteLong(Address, Value) { \ if ((Address) >= (LONG * const)MM_USER_PROBE_ADDRESS) { \ *(volatile LONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteUlong( // IN PULONG Address, // IN ULONG Value // ) // //-- #define ProbeAndWriteUlong(Address, Value) { \ if ((Address) >= (ULONG * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteQuad( // IN PQUAD Address, // IN QUAD Value // ) // //-- #define ProbeAndWriteQuad(Address, Value) { \ if ((Address) >= (QUAD * const)MM_USER_PROBE_ADDRESS) { \ *(volatile LONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteUquad( // IN PUQUAD Address, // IN UQUAD Value // ) // //-- #define ProbeAndWriteUquad(Address, Value) { \ if ((Address) >= (UQUAD * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } //++ // // VOID // ProbeAndWriteSturcture( // IN P Address, // IN Value, // // ) // //-- #define ProbeAndWriteStructure(Address, Value,STRUCTURE) { \ if ((STRUCTURE * const)(Address) >= (STRUCTURE * const)MM_USER_PROBE_ADDRESS) { \ *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \ } \ \ *(Address) = (Value); \ } // begin_ntifs begin_ntddk begin_wdm begin_ntosp // // Common probe for write functions. // NTKERNELAPI VOID NTAPI ProbeForWrite ( IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment ); // // Worker Thread // typedef enum _WORK_QUEUE_TYPE { CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, MaximumWorkQueue } WORK_QUEUE_TYPE; typedef VOID (*PWORKER_THREAD_ROUTINE)( IN PVOID Parameter ); typedef struct _WORK_QUEUE_ITEM { LIST_ENTRY List; PWORKER_THREAD_ROUTINE WorkerRoutine; PVOID Parameter; } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM; #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInitializeWorkItem) // Use IoAllocateWorkItem #endif #define ExInitializeWorkItem(Item, Routine, Context) \ (Item)->WorkerRoutine = (Routine); \ (Item)->Parameter = (Context); \ (Item)->List.Flink = NULL; DECLSPEC_DEPRECATED_DDK // Use IoQueueWorkItem NTKERNELAPI VOID ExQueueWorkItem( IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType ); NTKERNELAPI BOOLEAN ExIsProcessorFeaturePresent( ULONG ProcessorFeature ); // // Zone Allocation // typedef struct _ZONE_SEGMENT_HEADER { SINGLE_LIST_ENTRY SegmentList; PVOID Reserved; } ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER; typedef struct _ZONE_HEADER { SINGLE_LIST_ENTRY FreeList; SINGLE_LIST_ENTRY SegmentList; ULONG BlockSize; ULONG TotalSegmentSize; } ZONE_HEADER, *PZONE_HEADER; DECLSPEC_DEPRECATED_DDK NTKERNELAPI NTSTATUS ExInitializeZone( IN PZONE_HEADER Zone, IN ULONG BlockSize, IN PVOID InitialSegment, IN ULONG InitialSegmentSize ); DECLSPEC_DEPRECATED_DDK NTKERNELAPI NTSTATUS ExExtendZone( IN PZONE_HEADER Zone, IN PVOID Segment, IN ULONG SegmentSize ); DECLSPEC_DEPRECATED_DDK NTKERNELAPI NTSTATUS ExInterlockedExtendZone( IN PZONE_HEADER Zone, IN PVOID Segment, IN ULONG SegmentSize, IN PKSPIN_LOCK Lock ); //++ // // PVOID // ExAllocateFromZone( // IN PZONE_HEADER Zone // ) // // Routine Description: // // This routine removes an entry from the zone and returns a pointer to it. // // Arguments: // // Zone - Pointer to the zone header controlling the storage from which the // entry is to be allocated. // // Return Value: // // The function value is a pointer to the storage allocated from the zone. // //-- #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExAllocateFromZone) #endif #define ExAllocateFromZone(Zone) \ (PVOID)((Zone)->FreeList.Next); \ if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next //++ // // PVOID // ExFreeToZone( // IN PZONE_HEADER Zone, // IN PVOID Block // ) // // Routine Description: // // This routine places the specified block of storage back onto the free // list in the specified zone. // // Arguments: // // Zone - Pointer to the zone header controlling the storage to which the // entry is to be inserted. // // Block - Pointer to the block of storage to be freed back to the zone. // // Return Value: // // Pointer to previous block of storage that was at the head of the free // list. NULL implies the zone went from no available free blocks to // at least one free block. // //-- #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExFreeToZone) #endif #define ExFreeToZone(Zone,Block) \ ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \ (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \ ((PSINGLE_LIST_ENTRY)(Block))->Next \ ) //++ // // BOOLEAN // ExIsFullZone( // IN PZONE_HEADER Zone // ) // // Routine Description: // // This routine determines if the specified zone is full or not. A zone // is considered full if the free list is empty. // // Arguments: // // Zone - Pointer to the zone header to be tested. // // Return Value: // // TRUE if the zone is full and FALSE otherwise. // //-- #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExIsFullZone) #endif #define ExIsFullZone(Zone) \ ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL ) //++ // // PVOID // ExInterlockedAllocateFromZone( // IN PZONE_HEADER Zone, // IN PKSPIN_LOCK Lock // ) // // Routine Description: // // This routine removes an entry from the zone and returns a pointer to it. // The removal is performed with the specified lock owned for the sequence // to make it MP-safe. // // Arguments: // // Zone - Pointer to the zone header controlling the storage from which the // entry is to be allocated. // // Lock - Pointer to the spin lock which should be obtained before removing // the entry from the allocation list. The lock is released before // returning to the caller. // // Return Value: // // The function value is a pointer to the storage allocated from the zone. // //-- #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInterlockedAllocateFromZone) #endif #define ExInterlockedAllocateFromZone(Zone,Lock) \ (PVOID) ExInterlockedPopEntryList( &(Zone)->FreeList, Lock ) //++ // // PVOID // ExInterlockedFreeToZone( // IN PZONE_HEADER Zone, // IN PVOID Block, // IN PKSPIN_LOCK Lock // ) // // Routine Description: // // This routine places the specified block of storage back onto the free // list in the specified zone. The insertion is performed with the lock // owned for the sequence to make it MP-safe. // // Arguments: // // Zone - Pointer to the zone header controlling the storage to which the // entry is to be inserted. // // Block - Pointer to the block of storage to be freed back to the zone. // // Lock - Pointer to the spin lock which should be obtained before inserting // the entry onto the free list. The lock is released before returning // to the caller. // // Return Value: // // Pointer to previous block of storage that was at the head of the free // list. NULL implies the zone went from no available free blocks to // at least one free block. // //-- #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInterlockedFreeToZone) #endif #define ExInterlockedFreeToZone(Zone,Block,Lock) \ ExInterlockedPushEntryList( &(Zone)->FreeList, ((PSINGLE_LIST_ENTRY) (Block)), Lock ) //++ // // BOOLEAN // ExIsObjectInFirstZoneSegment( // IN PZONE_HEADER Zone, // IN PVOID Object // ) // // Routine Description: // // This routine determines if the specified pointer lives in the zone. // // Arguments: // // Zone - Pointer to the zone header controlling the storage to which the // object may belong. // // Object - Pointer to the object in question. // // Return Value: // // TRUE if the Object came from the first segment of zone. // //-- #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExIsObjectInFirstZoneSegment) #endif #define ExIsObjectInFirstZoneSegment(Zone,Object) ((BOOLEAN) \ (((PUCHAR)(Object) >= (PUCHAR)(Zone)->SegmentList.Next) && \ ((PUCHAR)(Object) < (PUCHAR)(Zone)->SegmentList.Next + \ (Zone)->TotalSegmentSize)) \ ) // // Define executive resource data structures. // typedef ULONG_PTR ERESOURCE_THREAD; typedef ERESOURCE_THREAD *PERESOURCE_THREAD; typedef struct _OWNER_ENTRY { ERESOURCE_THREAD OwnerThread; union { LONG OwnerCount; ULONG TableSize; }; } OWNER_ENTRY, *POWNER_ENTRY; typedef struct _ERESOURCE { LIST_ENTRY SystemResourcesList; POWNER_ENTRY OwnerTable; SHORT ActiveCount; USHORT Flag; PKSEMAPHORE SharedWaiters; PKEVENT ExclusiveWaiters; OWNER_ENTRY OwnerThreads[2]; ULONG ContentionCount; USHORT NumberOfSharedWaiters; USHORT NumberOfExclusiveWaiters; union { PVOID Address; ULONG_PTR CreatorBackTraceIndex; }; KSPIN_LOCK SpinLock; } ERESOURCE, *PERESOURCE; // // Values for ERESOURCE.Flag // #define ResourceNeverExclusive 0x10 #define ResourceReleaseByOtherThread 0x20 #define ResourceOwnedExclusive 0x80 #define RESOURCE_HASH_TABLE_SIZE 64 typedef struct _RESOURCE_HASH_ENTRY { LIST_ENTRY ListEntry; PVOID Address; ULONG ContentionCount; ULONG Number; } RESOURCE_HASH_ENTRY, *PRESOURCE_HASH_ENTRY; typedef struct _RESOURCE_PERFORMANCE_DATA { ULONG ActiveResourceCount; ULONG TotalResourceCount; ULONG ExclusiveAcquire; ULONG SharedFirstLevel; ULONG SharedSecondLevel; ULONG StarveFirstLevel; ULONG StarveSecondLevel; ULONG WaitForExclusive; ULONG OwnerTableExpands; ULONG MaximumTableExpand; LIST_ENTRY HashTable[RESOURCE_HASH_TABLE_SIZE]; } RESOURCE_PERFORMANCE_DATA, *PRESOURCE_PERFORMANCE_DATA; // // Define executive resource function prototypes. // NTKERNELAPI NTSTATUS ExInitializeResourceLite( IN PERESOURCE Resource ); NTKERNELAPI NTSTATUS ExReinitializeResourceLite( IN PERESOURCE Resource ); NTKERNELAPI BOOLEAN ExAcquireResourceSharedLite( IN PERESOURCE Resource, IN BOOLEAN Wait ); NTKERNELAPI BOOLEAN ExAcquireResourceExclusiveLite( IN PERESOURCE Resource, IN BOOLEAN Wait ); NTKERNELAPI BOOLEAN ExAcquireSharedStarveExclusive( IN PERESOURCE Resource, IN BOOLEAN Wait ); NTKERNELAPI BOOLEAN ExAcquireSharedWaitForExclusive( IN PERESOURCE Resource, IN BOOLEAN Wait ); NTKERNELAPI BOOLEAN ExTryToAcquireResourceExclusiveLite( IN PERESOURCE Resource ); // // VOID // ExReleaseResource( // IN PERESOURCE Resource // ); // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExReleaseResource) // Use ExReleaseResourceLite #endif #define ExReleaseResource(R) (ExReleaseResourceLite(R)) NTKERNELAPI VOID FASTCALL ExReleaseResourceLite( IN PERESOURCE Resource ); NTKERNELAPI VOID ExReleaseResourceForThreadLite( IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId ); NTKERNELAPI VOID ExSetResourceOwnerPointer( IN PERESOURCE Resource, IN PVOID OwnerPointer ); NTKERNELAPI VOID ExConvertExclusiveToSharedLite( IN PERESOURCE Resource ); NTKERNELAPI NTSTATUS ExDeleteResourceLite ( IN PERESOURCE Resource ); NTKERNELAPI ULONG ExGetExclusiveWaiterCount ( IN PERESOURCE Resource ); NTKERNELAPI ULONG ExGetSharedWaiterCount ( IN PERESOURCE Resource ); // // ERESOURCE_THREAD // ExGetCurrentResourceThread( // ); // #define ExGetCurrentResourceThread() ((ULONG_PTR)PsGetCurrentThread()) NTKERNELAPI BOOLEAN ExIsResourceAcquiredExclusiveLite ( IN PERESOURCE Resource ); NTKERNELAPI ULONG ExIsResourceAcquiredSharedLite ( IN PERESOURCE Resource ); // // An acquired resource is always owned shared, as shared ownership is a subset // of exclusive ownership. // #define ExIsResourceAcquiredLite ExIsResourceAcquiredSharedLite // end_wdm // // ntddk.h stole the entrypoints we wanted so fix them up here. // #if PRAGMA_DEPRECATED_DDK #pragma deprecated(ExInitializeResource) // use ExInitializeResourceLite #pragma deprecated(ExAcquireResourceShared) // use ExAcquireResourceSharedLite #pragma deprecated(ExAcquireResourceExclusive) // use ExAcquireResourceExclusiveLite #pragma deprecated(ExReleaseResourceForThread) // use ExReleaseResourceForThreadLite #pragma deprecated(ExConvertExclusiveToShared) // use ExConvertExclusiveToSharedLite #pragma deprecated(ExDeleteResource) // use ExDeleteResourceLite #pragma deprecated(ExIsResourceAcquiredExclusive) // use ExIsResourceAcquiredExclusiveLite #pragma deprecated(ExIsResourceAcquiredShared) // use ExIsResourceAcquiredSharedLite #pragma deprecated(ExIsResourceAcquired) // use ExIsResourceAcquiredSharedLite #endif #define ExInitializeResource ExInitializeResourceLite #define ExAcquireResourceShared ExAcquireResourceSharedLite #define ExAcquireResourceExclusive ExAcquireResourceExclusiveLite #define ExReleaseResourceForThread ExReleaseResourceForThreadLite #define ExConvertExclusiveToShared ExConvertExclusiveToSharedLite #define ExDeleteResource ExDeleteResourceLite #define ExIsResourceAcquiredExclusive ExIsResourceAcquiredExclusiveLite #define ExIsResourceAcquiredShared ExIsResourceAcquiredSharedLite #define ExIsResourceAcquired ExIsResourceAcquiredSharedLite // // Push lock definitions // typedef struct _EX_PUSH_LOCK { #define EX_PUSH_LOCK_WAITING 0x1 #define EX_PUSH_LOCK_EXCLUSIVE 0x2 #define EX_PUSH_LOCK_SHARE_INC 0x4 union { struct { ULONG_PTR Waiting : 1; ULONG_PTR Exclusive : 1; ULONG_PTR Shared : sizeof (ULONG_PTR) * 8 - 2; }; ULONG_PTR Value; PVOID Ptr; }; } EX_PUSH_LOCK, *PEX_PUSH_LOCK; #if defined (NT_UP) #define EX_CACHE_LINE_SIZE 16 #define EX_PUSH_LOCK_FANNED_COUNT 1 #else #define EX_CACHE_LINE_SIZE 128 #define EX_PUSH_LOCK_FANNED_COUNT (PAGE_SIZE/EX_CACHE_LINE_SIZE) #endif // // Define a fan out structure for n push locks each in its own cache line // typedef struct _EX_PUSH_LOCK_CACHE_AWARE { PEX_PUSH_LOCK Locks[EX_PUSH_LOCK_FANNED_COUNT]; } EX_PUSH_LOCK_CACHE_AWARE, *PEX_PUSH_LOCK_CACHE_AWARE; // // Define structure thats a push lock padded to the size of a cache line // typedef struct _EX_PUSH_LOCK_CACHE_AWARE_PADDED { EX_PUSH_LOCK Lock; union { UCHAR Pad[EX_CACHE_LINE_SIZE - sizeof (EX_PUSH_LOCK)]; BOOLEAN Single; }; } EX_PUSH_LOCK_CACHE_AWARE_PADDED, *PEX_PUSH_LOCK_CACHE_AWARE_PADDED; // // Rundown protection structure // typedef struct _EX_RUNDOWN_REF { #define EX_RUNDOWN_ACTIVE 0x1 #define EX_RUNDOWN_COUNT_SHIFT 0x1 #define EX_RUNDOWN_COUNT_INC (1<Count = 0; } // // Reset a rundown protection block // NTKERNELAPI VOID FASTCALL ExReInitializeRundownProtection ( IN PEX_RUNDOWN_REF RunRef ); // // Acquire rundown protection // NTKERNELAPI BOOLEAN FASTCALL ExAcquireRundownProtection ( IN PEX_RUNDOWN_REF RunRef ); NTKERNELAPI BOOLEAN FASTCALL ExAcquireRundownProtectionEx ( IN PEX_RUNDOWN_REF RunRef, IN ULONG Count ); // // Release rundown protection // NTKERNELAPI VOID FASTCALL ExReleaseRundownProtection ( IN PEX_RUNDOWN_REF RunRef ); NTKERNELAPI VOID FASTCALL ExReleaseRundownProtectionEx ( IN PEX_RUNDOWN_REF RunRef, IN ULONG Count ); // // Mark rundown block as rundown having been completed. // NTKERNELAPI VOID FASTCALL ExRundownCompleted ( IN PEX_RUNDOWN_REF RunRef ); // // Wait for all protected acquires to exit // NTKERNELAPI VOID FASTCALL ExWaitForRundownProtectionRelease ( IN PEX_RUNDOWN_REF RunRef ); // // Define external data. // because of indirection for all drivers external to ntoskrnl these are actually ptrs // #if defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || defined(_WDMDDK_) || defined(_NTOSP_) extern PBOOLEAN KdDebuggerNotPresent; extern PBOOLEAN KdDebuggerEnabled; #define KD_DEBUGGER_ENABLED *KdDebuggerEnabled #define KD_DEBUGGER_NOT_PRESENT *KdDebuggerNotPresent #else extern BOOLEAN KdDebuggerNotPresent; extern BOOLEAN KdDebuggerEnabled; #define KD_DEBUGGER_ENABLED KdDebuggerEnabled #define KD_DEBUGGER_NOT_PRESENT KdDebuggerNotPresent #endif // // Priority increment definitions. The comment for each definition gives // the names of the system services that use the definition when satisfying // a wait. // // // Priority increment used when satisfying a wait on an executive event // (NtPulseEvent and NtSetEvent) // #define EVENT_INCREMENT 1 // // Priority increment when no I/O has been done. This is used by device // and file system drivers when completing an IRP (IoCompleteRequest). // #define IO_NO_INCREMENT 0 // // Priority increment for completing CD-ROM I/O. This is used by CD-ROM device // and file system drivers when completing an IRP (IoCompleteRequest) // #define IO_CD_ROM_INCREMENT 1 // // Priority increment for completing disk I/O. This is used by disk device // and file system drivers when completing an IRP (IoCompleteRequest) // #define IO_DISK_INCREMENT 1 // end_ntifs // // Priority increment for completing keyboard I/O. This is used by keyboard // device drivers when completing an IRP (IoCompleteRequest) // #define IO_KEYBOARD_INCREMENT 6 // begin_ntifs // // Priority increment for completing mailslot I/O. This is used by the mail- // slot file system driver when completing an IRP (IoCompleteRequest). // #define IO_MAILSLOT_INCREMENT 2 // end_ntifs // // Priority increment for completing mouse I/O. This is used by mouse device // drivers when completing an IRP (IoCompleteRequest) // #define IO_MOUSE_INCREMENT 6 // begin_ntifs // // Priority increment for completing named pipe I/O. This is used by the // named pipe file system driver when completing an IRP (IoCompleteRequest). // #define IO_NAMED_PIPE_INCREMENT 2 // // Priority increment for completing network I/O. This is used by network // device and network file system drivers when completing an IRP // (IoCompleteRequest). // #define IO_NETWORK_INCREMENT 2 // end_ntifs // // Priority increment for completing parallel I/O. This is used by parallel // device drivers when completing an IRP (IoCompleteRequest) // #define IO_PARALLEL_INCREMENT 1 // // Priority increment for completing serial I/O. This is used by serial device // drivers when completing an IRP (IoCompleteRequest) // #define IO_SERIAL_INCREMENT 2 // // Priority increment for completing sound I/O. This is used by sound device // drivers when completing an IRP (IoCompleteRequest) // #define IO_SOUND_INCREMENT 8 // // Priority increment for completing video I/O. This is used by video device // drivers when completing an IRP (IoCompleteRequest) // #define IO_VIDEO_INCREMENT 1 // end_ntddk end_wdm // // Priority increment used when satisfying a wait on an executive mutant // (NtReleaseMutant) // #define MUTANT_INCREMENT 1 // begin_ntddk begin_wdm begin_ntifs // // Priority increment used when satisfying a wait on an executive semaphore // (NtReleaseSemaphore) // #define SEMAPHORE_INCREMENT 1 // // Define I/O system data structure type codes. Each major data structure in // the I/O system has a type code The type field in each structure is at the // same offset. The following values can be used to determine which type of // data structure a pointer refers to. // #define IO_TYPE_ADAPTER 0x00000001 #define IO_TYPE_CONTROLLER 0x00000002 #define IO_TYPE_DEVICE 0x00000003 #define IO_TYPE_DRIVER 0x00000004 #define IO_TYPE_FILE 0x00000005 #define IO_TYPE_IRP 0x00000006 #define IO_TYPE_MASTER_ADAPTER 0x00000007 #define IO_TYPE_OPEN_PACKET 0x00000008 #define IO_TYPE_TIMER 0x00000009 #define IO_TYPE_VPB 0x0000000a #define IO_TYPE_ERROR_LOG 0x0000000b #define IO_TYPE_ERROR_MESSAGE 0x0000000c #define IO_TYPE_DEVICE_OBJECT_EXTENSION 0x0000000d // // Define the major function codes for IRPs. // #define IRP_MJ_CREATE 0x00 #define IRP_MJ_CREATE_NAMED_PIPE 0x01 #define IRP_MJ_CLOSE 0x02 #define IRP_MJ_READ 0x03 #define IRP_MJ_WRITE 0x04 #define IRP_MJ_QUERY_INFORMATION 0x05 #define IRP_MJ_SET_INFORMATION 0x06 #define IRP_MJ_QUERY_EA 0x07 #define IRP_MJ_SET_EA 0x08 #define IRP_MJ_FLUSH_BUFFERS 0x09 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a #define IRP_MJ_SET_VOLUME_INFORMATION 0x0b #define IRP_MJ_DIRECTORY_CONTROL 0x0c #define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d #define IRP_MJ_DEVICE_CONTROL 0x0e #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f #define IRP_MJ_SHUTDOWN 0x10 #define IRP_MJ_LOCK_CONTROL 0x11 #define IRP_MJ_CLEANUP 0x12 #define IRP_MJ_CREATE_MAILSLOT 0x13 #define IRP_MJ_QUERY_SECURITY 0x14 #define IRP_MJ_SET_SECURITY 0x15 #define IRP_MJ_POWER 0x16 #define IRP_MJ_SYSTEM_CONTROL 0x17 #define IRP_MJ_DEVICE_CHANGE 0x18 #define IRP_MJ_QUERY_QUOTA 0x19 #define IRP_MJ_SET_QUOTA 0x1a #define IRP_MJ_PNP 0x1b #define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... #define IRP_MJ_MAXIMUM_FUNCTION 0x1b // // Make the Scsi major code the same as internal device control. // #define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL // // Define the minor function codes for IRPs. The lower 128 codes, from 0x00 to // 0x7f are reserved to Microsoft. The upper 128 codes, from 0x80 to 0xff, are // reserved to customers of Microsoft. // // end_wdm end_ntndis // // Directory control minor function codes // #define IRP_MN_QUERY_DIRECTORY 0x01 #define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 // // File system control minor function codes. Note that "user request" is // assumed to be zero by both the I/O system and file systems. Do not change // this value. // #define IRP_MN_USER_FS_REQUEST 0x00 #define IRP_MN_MOUNT_VOLUME 0x01 #define IRP_MN_VERIFY_VOLUME 0x02 #define IRP_MN_LOAD_FILE_SYSTEM 0x03 #define IRP_MN_TRACK_LINK 0x04 // To be obsoleted soon #define IRP_MN_KERNEL_CALL 0x04 // // Lock control minor function codes // #define IRP_MN_LOCK 0x01 #define IRP_MN_UNLOCK_SINGLE 0x02 #define IRP_MN_UNLOCK_ALL 0x03 #define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 // // Read and Write minor function codes for file systems supporting Lan Manager // software. All of these subfunction codes are invalid if the file has been // opened with FO_NO_INTERMEDIATE_BUFFERING. They are also invalid in combi- // nation with synchronous calls (Irp Flag or file open option). // // Note that "normal" is assumed to be zero by both the I/O system and file // systems. Do not change this value. // #define IRP_MN_NORMAL 0x00 #define IRP_MN_DPC 0x01 #define IRP_MN_MDL 0x02 #define IRP_MN_COMPLETE 0x04 #define IRP_MN_COMPRESSED 0x08 #define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) #define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) #define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) // begin_wdm // // Device Control Request minor function codes for SCSI support. Note that // user requests are assumed to be zero. // #define IRP_MN_SCSI_CLASS 0x01 // // PNP minor function codes. // #define IRP_MN_START_DEVICE 0x00 #define IRP_MN_QUERY_REMOVE_DEVICE 0x01 #define IRP_MN_REMOVE_DEVICE 0x02 #define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 #define IRP_MN_STOP_DEVICE 0x04 #define IRP_MN_QUERY_STOP_DEVICE 0x05 #define IRP_MN_CANCEL_STOP_DEVICE 0x06 #define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 #define IRP_MN_QUERY_INTERFACE 0x08 #define IRP_MN_QUERY_CAPABILITIES 0x09 #define IRP_MN_QUERY_RESOURCES 0x0A #define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B #define IRP_MN_QUERY_DEVICE_TEXT 0x0C #define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D #define IRP_MN_READ_CONFIG 0x0F #define IRP_MN_WRITE_CONFIG 0x10 #define IRP_MN_EJECT 0x11 #define IRP_MN_SET_LOCK 0x12 #define IRP_MN_QUERY_ID 0x13 #define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 #define IRP_MN_QUERY_BUS_INFORMATION 0x15 #define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 #define IRP_MN_SURPRISE_REMOVAL 0x17 // end_wdm #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 // begin_wdm // // POWER minor function codes // #define IRP_MN_WAIT_WAKE 0x00 #define IRP_MN_POWER_SEQUENCE 0x01 #define IRP_MN_SET_POWER 0x02 #define IRP_MN_QUERY_POWER 0x03 // begin_ntminiport // // WMI minor function codes under IRP_MJ_SYSTEM_CONTROL // #define IRP_MN_QUERY_ALL_DATA 0x00 #define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 #define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 #define IRP_MN_CHANGE_SINGLE_ITEM 0x03 #define IRP_MN_ENABLE_EVENTS 0x04 #define IRP_MN_DISABLE_EVENTS 0x05 #define IRP_MN_ENABLE_COLLECTION 0x06 #define IRP_MN_DISABLE_COLLECTION 0x07 #define IRP_MN_REGINFO 0x08 #define IRP_MN_EXECUTE_METHOD 0x09 // Minor code 0x0a is reserved #define IRP_MN_REGINFO_EX 0x0b // end_ntminiport // // Define option flags for IoCreateFile. Note that these values must be // exactly the same as the SL_... flags for a create function. Note also // that there are flags that may be passed to IoCreateFile that are not // placed in the stack location for the create IRP. These flags start in // the next byte. // #define IO_FORCE_ACCESS_CHECK 0x0001 #define IO_NO_PARAMETER_CHECKING 0x0100 // // Define Information fields for whether or not a REPARSE or a REMOUNT has // occurred in the file system. // #define IO_REPARSE 0x0 #define IO_REMOUNT 0x1 // end_ntddk end_wdm #define IO_CHECK_CREATE_PARAMETERS 0x0200 #define IO_ATTACH_DEVICE 0x0400 // // This flag is only meaning full to IoCreateFileSpecifyDeviceObjectHint. // FileHandles created using IoCreateFileSpecifyDeviceObjectHint with this // flag set will bypass ShareAccess checks on this file. // #define IO_IGNORE_SHARE_ACCESS_CHECK 0x0800 // Ignores share access checks on opens. typedef VOID (*PSTALL_ROUTINE) ( IN ULONG Delay ); // // Define the interfaces for the dump driver's routines. // typedef BOOLEAN (*PDUMP_DRIVER_OPEN) ( IN LARGE_INTEGER PartitionOffset ); typedef NTSTATUS (*PDUMP_DRIVER_WRITE) ( IN PLARGE_INTEGER DiskByteOffset, IN PMDL Mdl ); // // Actions accepted by DRIVER_WRITE_PENDING // #define IO_DUMP_WRITE_FULFILL 0 // fulfill IO request as if DRIVER_WAIT #define IO_DUMP_WRITE_START 1 // start new IO #define IO_DUMP_WRITE_RESUME 2 // resume pending IO #define IO_DUMP_WRITE_FINISH 3 // finish pending IO #define IO_DUMP_WRITE_INIT 4 // initialize locals // size of data used by WRITE_PENDING that should be preserved // between the calls #define IO_DUMP_WRITE_DATA_PAGES 2 #define IO_DUMP_WRITE_DATA_SIZE (IO_DUMP_WRITE_DATA_PAGES << PAGE_SHIFT) typedef NTSTATUS (*PDUMP_DRIVER_WRITE_PENDING) ( IN LONG Action, IN PLARGE_INTEGER DiskByteOffset, IN PMDL Mdl, IN PVOID LocalData ); typedef VOID (*PDUMP_DRIVER_FINISH) ( VOID ); struct _ADAPTER_OBJECT; // // This is the information passed from the system to the disk dump driver // during the driver's initialization. // typedef struct _DUMP_INITIALIZATION_CONTEXT { ULONG Length; ULONG Reserved; // Was MBR Checksum. Should be zero now. PVOID MemoryBlock; PVOID CommonBuffer[2]; PHYSICAL_ADDRESS PhysicalAddress[2]; PSTALL_ROUTINE StallRoutine; PDUMP_DRIVER_OPEN OpenRoutine; PDUMP_DRIVER_WRITE WriteRoutine; PDUMP_DRIVER_FINISH FinishRoutine; struct _ADAPTER_OBJECT *AdapterObject; PVOID MappedRegisterBase; PVOID PortConfiguration; BOOLEAN CrashDump; ULONG MaximumTransferSize; ULONG CommonBufferSize; PVOID TargetAddress; //Opaque pointer to target address structure PDUMP_DRIVER_WRITE_PENDING WritePendingRoutine; ULONG PartitionStyle; union { struct { ULONG Signature; ULONG CheckSum; } Mbr; struct { GUID DiskId; } Gpt; } DiskInfo; } DUMP_INITIALIZATION_CONTEXT, *PDUMP_INITIALIZATION_CONTEXT; // begin_ntddk // // Define callout routine type for use in IoQueryDeviceDescription(). // typedef NTSTATUS (*PIO_QUERY_DEVICE_ROUTINE)( IN PVOID Context, IN PUNICODE_STRING PathName, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN PKEY_VALUE_FULL_INFORMATION *BusInformation, IN CONFIGURATION_TYPE ControllerType, IN ULONG ControllerNumber, IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, IN CONFIGURATION_TYPE PeripheralType, IN ULONG PeripheralNumber, IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation ); // Defines the order of the information in the array of // PKEY_VALUE_FULL_INFORMATION. // typedef enum _IO_QUERY_DEVICE_DATA_FORMAT { IoQueryDeviceIdentifier = 0, IoQueryDeviceConfigurationData, IoQueryDeviceComponentInformation, IoQueryDeviceMaxData } IO_QUERY_DEVICE_DATA_FORMAT, *PIO_QUERY_DEVICE_DATA_FORMAT; // begin_wdm begin_ntifs // // Define the objects that can be created by IoCreateFile. // typedef enum _CREATE_FILE_TYPE { CreateFileTypeNone, CreateFileTypeNamedPipe, CreateFileTypeMailslot } CREATE_FILE_TYPE; // end_ntddk end_wdm end_ntifs // // Define the named pipe create parameters structure used for internal calls // to IoCreateFile when a named pipe is being created. This structure allows // code invoking this routine to pass information specific to this function // when creating a named pipe. // typedef struct _NAMED_PIPE_CREATE_PARAMETERS { ULONG NamedPipeType; ULONG ReadMode; ULONG CompletionMode; ULONG MaximumInstances; ULONG InboundQuota; ULONG OutboundQuota; LARGE_INTEGER DefaultTimeout; BOOLEAN TimeoutSpecified; } NAMED_PIPE_CREATE_PARAMETERS, *PNAMED_PIPE_CREATE_PARAMETERS; // // Define the structures used by the I/O system // // // Define empty typedefs for the _IRP, _DEVICE_OBJECT, and _DRIVER_OBJECT // structures so they may be referenced by function types before they are // actually defined. // struct _DEVICE_DESCRIPTION; struct _DEVICE_OBJECT; struct _DMA_ADAPTER; struct _DRIVER_OBJECT; struct _DRIVE_LAYOUT_INFORMATION; struct _DISK_PARTITION; struct _FILE_OBJECT; struct _IRP; struct _SCSI_REQUEST_BLOCK; struct _SCATTER_GATHER_LIST; // // Define the I/O version of a DPC routine. // typedef VOID (*PIO_DPC_ROUTINE) ( IN PKDPC Dpc, IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp, IN PVOID Context ); // // Define driver timer routine type. // typedef VOID (*PIO_TIMER_ROUTINE) ( IN struct _DEVICE_OBJECT *DeviceObject, IN PVOID Context ); // // Define driver initialization routine type. // typedef NTSTATUS (*PDRIVER_INITIALIZE) ( IN struct _DRIVER_OBJECT *DriverObject, IN PUNICODE_STRING RegistryPath ); // end_wdm // // Define driver reinitialization routine type. // typedef VOID (*PDRIVER_REINITIALIZE) ( IN struct _DRIVER_OBJECT *DriverObject, IN PVOID Context, IN ULONG Count ); // begin_wdm begin_ntndis // // Define driver cancel routine type. // typedef VOID (*PDRIVER_CANCEL) ( IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp ); // // Define driver dispatch routine type. // typedef NTSTATUS (*PDRIVER_DISPATCH) ( IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp ); // // Define driver start I/O routine type. // typedef VOID (*PDRIVER_STARTIO) ( IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp ); // // Define driver unload routine type. // typedef VOID (*PDRIVER_UNLOAD) ( IN struct _DRIVER_OBJECT *DriverObject ); // // Define driver AddDevice routine type. // typedef NTSTATUS (*PDRIVER_ADD_DEVICE) ( IN struct _DRIVER_OBJECT *DriverObject, IN struct _DEVICE_OBJECT *PhysicalDeviceObject ); // // Define fast I/O procedure prototypes. // // Fast I/O read and write procedures. // typedef BOOLEAN (*PFAST_IO_CHECK_IF_POSSIBLE) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_READ) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_WRITE) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); // // Fast I/O query basic and standard information procedures. // typedef BOOLEAN (*PFAST_IO_QUERY_BASIC_INFO) ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_QUERY_STANDARD_INFO) ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); // // Fast I/O lock and unlock procedures. // typedef BOOLEAN (*PFAST_IO_LOCK) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_UNLOCK_SINGLE) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_UNLOCK_ALL) ( IN struct _FILE_OBJECT *FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_UNLOCK_ALL_BY_KEY) ( IN struct _FILE_OBJECT *FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); // // Fast I/O device control procedure. // typedef BOOLEAN (*PFAST_IO_DEVICE_CONTROL) ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); // // Define callbacks for NtCreateSection to synchronize correctly with // the file system. It pre-acquires the resources that will be needed // when calling to query and set file/allocation size in the file system. // typedef VOID (*PFAST_IO_ACQUIRE_FILE) ( IN struct _FILE_OBJECT *FileObject ); typedef VOID (*PFAST_IO_RELEASE_FILE) ( IN struct _FILE_OBJECT *FileObject ); // // Define callback for drivers that have device objects attached to lower- // level drivers' device objects. This callback is made when the lower-level // driver is deleting its device object. // typedef VOID (*PFAST_IO_DETACH_DEVICE) ( IN struct _DEVICE_OBJECT *SourceDevice, IN struct _DEVICE_OBJECT *TargetDevice ); // // This structure is used by the server to quickly get the information needed // to service a server open call. It is takes what would be two fast io calls // one for basic information and the other for standard information and makes // it into one call. // typedef BOOLEAN (*PFAST_IO_QUERY_NETWORK_OPEN_INFO) ( IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, OUT struct _IO_STATUS_BLOCK *IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); // // Define Mdl-based routines for the server to call // typedef BOOLEAN (*PFAST_IO_MDL_READ) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_MDL_READ_COMPLETE) ( IN struct _FILE_OBJECT *FileObject, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_PREPARE_MDL_WRITE) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_MDL_WRITE_COMPLETE) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ); // // If this routine is present, it will be called by FsRtl // to acquire the file for the mapped page writer. // typedef NTSTATUS (*PFAST_IO_ACQUIRE_FOR_MOD_WRITE) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER EndingOffset, OUT struct _ERESOURCE **ResourceToRelease, IN struct _DEVICE_OBJECT *DeviceObject ); typedef NTSTATUS (*PFAST_IO_RELEASE_FOR_MOD_WRITE) ( IN struct _FILE_OBJECT *FileObject, IN struct _ERESOURCE *ResourceToRelease, IN struct _DEVICE_OBJECT *DeviceObject ); // // If this routine is present, it will be called by FsRtl // to acquire the file for the mapped page writer. // typedef NTSTATUS (*PFAST_IO_ACQUIRE_FOR_CCFLUSH) ( IN struct _FILE_OBJECT *FileObject, IN struct _DEVICE_OBJECT *DeviceObject ); typedef NTSTATUS (*PFAST_IO_RELEASE_FOR_CCFLUSH) ( IN struct _FILE_OBJECT *FileObject, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_READ_COMPRESSED) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PVOID Buffer, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_WRITE_COMPRESSED) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, IN PVOID Buffer, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_MDL_READ_COMPLETE_COMPRESSED) ( IN struct _FILE_OBJECT *FileObject, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED) ( IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject ); typedef BOOLEAN (*PFAST_IO_QUERY_OPEN) ( IN struct _IRP *Irp, OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, IN struct _DEVICE_OBJECT *DeviceObject ); // // Define the structure to describe the Fast I/O dispatch routines. Any // additions made to this structure MUST be added monotonically to the end // of the structure, and fields CANNOT be removed from the middle. // typedef struct _FAST_IO_DISPATCH { ULONG SizeOfFastIoDispatch; PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible; PFAST_IO_READ FastIoRead; PFAST_IO_WRITE FastIoWrite; PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo; PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo; PFAST_IO_LOCK FastIoLock; PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle; PFAST_IO_UNLOCK_ALL FastIoUnlockAll; PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey; PFAST_IO_DEVICE_CONTROL FastIoDeviceControl; PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection; PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection; PFAST_IO_DETACH_DEVICE FastIoDetachDevice; PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo; PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite; PFAST_IO_MDL_READ MdlRead; PFAST_IO_MDL_READ_COMPLETE MdlReadComplete; PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite; PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete; PFAST_IO_READ_COMPRESSED FastIoReadCompressed; PFAST_IO_WRITE_COMPRESSED FastIoWriteCompressed; PFAST_IO_MDL_READ_COMPLETE_COMPRESSED MdlReadCompleteCompressed; PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED MdlWriteCompleteCompressed; PFAST_IO_QUERY_OPEN FastIoQueryOpen; PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite; PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush; PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush; } FAST_IO_DISPATCH, *PFAST_IO_DISPATCH; // // Define the actions that a driver execution routine may request of the // adapter/controller allocation routines upon return. // typedef enum _IO_ALLOCATION_ACTION { KeepObject = 1, DeallocateObject, DeallocateObjectKeepRegisters } IO_ALLOCATION_ACTION, *PIO_ALLOCATION_ACTION; // // Define device driver adapter/controller execution routine. // typedef IO_ALLOCATION_ACTION (*PDRIVER_CONTROL) ( IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp, IN PVOID MapRegisterBase, IN PVOID Context ); // // Define the I/O system's security context type for use by file system's // when checking access to volumes, files, and directories. // typedef struct _IO_SECURITY_CONTEXT { PSECURITY_QUALITY_OF_SERVICE SecurityQos; PACCESS_STATE AccessState; ACCESS_MASK DesiredAccess; ULONG FullCreateOptions; } IO_SECURITY_CONTEXT, *PIO_SECURITY_CONTEXT; // // Define Volume Parameter Block (VPB) flags. // #define VPB_MOUNTED 0x00000001 #define VPB_LOCKED 0x00000002 #define VPB_PERSISTENT 0x00000004 #define VPB_REMOVE_PENDING 0x00000008 #define VPB_RAW_MOUNT 0x00000010 // // Volume Parameter Block (VPB) // #define MAXIMUM_VOLUME_LABEL_LENGTH (32 * sizeof(WCHAR)) // 32 characters typedef struct _VPB { CSHORT Type; CSHORT Size; USHORT Flags; USHORT VolumeLabelLength; // in bytes struct _DEVICE_OBJECT *DeviceObject; struct _DEVICE_OBJECT *RealDevice; ULONG SerialNumber; ULONG ReferenceCount; WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)]; } VPB, *PVPB; #if defined(_WIN64) // // Use __inline DMA macros (hal.h) // #ifndef USE_DMA_MACROS #define USE_DMA_MACROS #endif // // Only PnP drivers! // #ifndef NO_LEGACY_DRIVERS #define NO_LEGACY_DRIVERS #endif #endif // _WIN64 #if defined(USE_DMA_MACROS) && (defined(_NTDDK_) || defined(_NTDRIVER_) || defined(_NTOSP_)) // begin_wdm // // Define object type specific fields of various objects used by the I/O system // typedef struct _DMA_ADAPTER *PADAPTER_OBJECT; // end_wdm #else // // Define object type specific fields of various objects used by the I/O system // typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT; // ntndis #endif // USE_DMA_MACROS && (_NTDDK_ || _NTDRIVER_ || _NTOSP_) // begin_wdm // // Define Wait Context Block (WCB) // typedef struct _WAIT_CONTEXT_BLOCK { KDEVICE_QUEUE_ENTRY WaitQueueEntry; PDRIVER_CONTROL DeviceRoutine; PVOID DeviceContext; ULONG NumberOfMapRegisters; PVOID DeviceObject; PVOID CurrentIrp; PKDPC BufferChainingDpc; } WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK; // end_wdm typedef struct _CONTROLLER_OBJECT { CSHORT Type; CSHORT Size; PVOID ControllerExtension; KDEVICE_QUEUE DeviceWaitQueue; ULONG Spare1; LARGE_INTEGER Spare2; } CONTROLLER_OBJECT, *PCONTROLLER_OBJECT; // begin_wdm // // Define Device Object (DO) flags // // end_wdm end_ntddk end_nthal end_ntifs #define DO_VERIFY_VOLUME 0x00000002 // ntddk nthal ntifs #define DO_BUFFERED_IO 0x00000004 // ntddk nthal ntifs wdm #define DO_EXCLUSIVE 0x00000008 // ntddk nthal ntifs wdm #define DO_DIRECT_IO 0x00000010 // ntddk nthal ntifs wdm #define DO_MAP_IO_BUFFER 0x00000020 // ntddk nthal ntifs wdm #define DO_DEVICE_HAS_NAME 0x00000040 // ntddk nthal ntifs #define DO_DEVICE_INITIALIZING 0x00000080 // ntddk nthal ntifs wdm #define DO_SYSTEM_BOOT_PARTITION 0x00000100 // ntddk nthal ntifs #define DO_LONG_TERM_REQUESTS 0x00000200 // ntddk nthal ntifs #define DO_NEVER_LAST_DEVICE 0x00000400 // ntddk nthal ntifs #define DO_SHUTDOWN_REGISTERED 0x00000800 // ntddk nthal ntifs wdm #define DO_BUS_ENUMERATED_DEVICE 0x00001000 // ntddk nthal ntifs wdm #define DO_POWER_PAGABLE 0x00002000 // ntddk nthal ntifs wdm #define DO_POWER_INRUSH 0x00004000 // ntddk nthal ntifs wdm #define DO_POWER_NOOP 0x00008000 #define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 // ntddk nthal ntifs #define DO_XIP 0x00020000 // begin_wdm begin_ntddk begin_nthal begin_ntifs // // Device Object structure definition // typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT { CSHORT Type; USHORT Size; LONG ReferenceCount; struct _DRIVER_OBJECT *DriverObject; struct _DEVICE_OBJECT *NextDevice; struct _DEVICE_OBJECT *AttachedDevice; struct _IRP *CurrentIrp; PIO_TIMER Timer; ULONG Flags; // See above: DO_... ULONG Characteristics; // See ntioapi: FILE_... PVPB Vpb; PVOID DeviceExtension; DEVICE_TYPE DeviceType; CCHAR StackSize; union { LIST_ENTRY ListEntry; WAIT_CONTEXT_BLOCK Wcb; } Queue; ULONG AlignmentRequirement; KDEVICE_QUEUE DeviceQueue; KDPC Dpc; // // The following field is for exclusive use by the filesystem to keep // track of the number of Fsp threads currently using the device // ULONG ActiveThreadCount; PSECURITY_DESCRIPTOR SecurityDescriptor; KEVENT DeviceLock; USHORT SectorSize; USHORT Spare1; struct _DEVOBJ_EXTENSION *DeviceObjectExtension; PVOID Reserved; } DEVICE_OBJECT; typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT; // ntndis struct _DEVICE_OBJECT_POWER_EXTENSION; typedef struct _DEVOBJ_EXTENSION { CSHORT Type; USHORT Size; // // Public part of the DeviceObjectExtension structure // PDEVICE_OBJECT DeviceObject; // owning device object } DEVOBJ_EXTENSION, *PDEVOBJ_EXTENSION; // // Define Driver Object (DRVO) flags // #define DRVO_UNLOAD_INVOKED 0x00000001 #define DRVO_LEGACY_DRIVER 0x00000002 #define DRVO_BUILTIN_DRIVER 0x00000004 // Driver objects for Hal, PnP Mgr // end_wdm #define DRVO_REINIT_REGISTERED 0x00000008 #define DRVO_INITIALIZED 0x00000010 #define DRVO_BOOTREINIT_REGISTERED 0x00000020 #define DRVO_LEGACY_RESOURCES 0x00000040 // begin_wdm typedef struct _DRIVER_EXTENSION { // // Back pointer to Driver Object // struct _DRIVER_OBJECT *DriverObject; // // The AddDevice entry point is called by the Plug & Play manager // to inform the driver when a new device instance arrives that this // driver must control. // PDRIVER_ADD_DEVICE AddDevice; // // The count field is used to count the number of times the driver has // had its registered reinitialization routine invoked. // ULONG Count; // // The service name field is used by the pnp manager to determine // where the driver related info is stored in the registry. // UNICODE_STRING ServiceKeyName; // // Note: any new shared fields get added here. // } DRIVER_EXTENSION, *PDRIVER_EXTENSION; typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; // // The following links all of the devices created by a single driver // together on a list, and the Flags word provides an extensible flag // location for driver objects. // PDEVICE_OBJECT DeviceObject; ULONG Flags; // // The following section describes where the driver is loaded. The count // field is used to count the number of times the driver has had its // registered reinitialization routine invoked. // PVOID DriverStart; ULONG DriverSize; PVOID DriverSection; PDRIVER_EXTENSION DriverExtension; // // The driver name field is used by the error log thread // determine the name of the driver that an I/O request is/was bound. // UNICODE_STRING DriverName; // // The following section is for registry support. Thise is a pointer // to the path to the hardware information in the registry // PUNICODE_STRING HardwareDatabase; // // The following section contains the optional pointer to an array of // alternate entry points to a driver for "fast I/O" support. Fast I/O // is performed by invoking the driver routine directly with separate // parameters, rather than using the standard IRP call mechanism. Note // that these functions may only be used for synchronous I/O, and when // the file is cached. // PFAST_IO_DISPATCH FastIoDispatch; // // The following section describes the entry points to this particular // driver. Note that the major function dispatch table must be the last // field in the object so that it remains extensible. // PDRIVER_INITIALIZE DriverInit; PDRIVER_STARTIO DriverStartIo; PDRIVER_UNLOAD DriverUnload; PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; } DRIVER_OBJECT; typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; // ntndis // // The following structure is pointed to by the SectionObject pointer field // of a file object, and is allocated by the various NT file systems. // typedef struct _SECTION_OBJECT_POINTERS { PVOID DataSectionObject; PVOID SharedCacheMap; PVOID ImageSectionObject; } SECTION_OBJECT_POINTERS; typedef SECTION_OBJECT_POINTERS *PSECTION_OBJECT_POINTERS; // // Define the format of a completion message. // typedef struct _IO_COMPLETION_CONTEXT { PVOID Port; PVOID Key; } IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT; // // Define File Object (FO) flags // #define FO_FILE_OPEN 0x00000001 #define FO_SYNCHRONOUS_IO 0x00000002 #define FO_ALERTABLE_IO 0x00000004 #define FO_NO_INTERMEDIATE_BUFFERING 0x00000008 #define FO_WRITE_THROUGH 0x00000010 #define FO_SEQUENTIAL_ONLY 0x00000020 #define FO_CACHE_SUPPORTED 0x00000040 #define FO_NAMED_PIPE 0x00000080 #define FO_STREAM_FILE 0x00000100 #define FO_MAILSLOT 0x00000200 #define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400 #define FO_DIRECT_DEVICE_OPEN 0x00000800 #define FO_FILE_MODIFIED 0x00001000 #define FO_FILE_SIZE_CHANGED 0x00002000 #define FO_CLEANUP_COMPLETE 0x00004000 #define FO_TEMPORARY_FILE 0x00008000 #define FO_DELETE_ON_CLOSE 0x00010000 #define FO_OPENED_CASE_SENSITIVE 0x00020000 #define FO_HANDLE_CREATED 0x00040000 #define FO_FILE_FAST_IO_READ 0x00080000 #define FO_RANDOM_ACCESS 0x00100000 #define FO_FILE_OPEN_CANCELLED 0x00200000 #define FO_VOLUME_OPEN 0x00400000 #define FO_FILE_OBJECT_HAS_EXTENSION 0x00800000 #define FO_REMOTE_ORIGIN 0x01000000 typedef struct _FILE_OBJECT { CSHORT Type; CSHORT Size; PDEVICE_OBJECT DeviceObject; PVPB Vpb; PVOID FsContext; PVOID FsContext2; PSECTION_OBJECT_POINTERS SectionObjectPointer; PVOID PrivateCacheMap; NTSTATUS FinalStatus; struct _FILE_OBJECT *RelatedFileObject; BOOLEAN LockOperation; BOOLEAN DeletePending; BOOLEAN ReadAccess; BOOLEAN WriteAccess; BOOLEAN DeleteAccess; BOOLEAN SharedRead; BOOLEAN SharedWrite; BOOLEAN SharedDelete; ULONG Flags; UNICODE_STRING FileName; LARGE_INTEGER CurrentByteOffset; ULONG Waiters; ULONG Busy; PVOID LastLock; KEVENT Lock; KEVENT Event; PIO_COMPLETION_CONTEXT CompletionContext; } FILE_OBJECT; typedef struct _FILE_OBJECT *PFILE_OBJECT; // ntndis // // Define I/O Request Packet (IRP) flags // #define IRP_NOCACHE 0x00000001 #define IRP_PAGING_IO 0x00000002 #define IRP_MOUNT_COMPLETION 0x00000002 #define IRP_SYNCHRONOUS_API 0x00000004 #define IRP_ASSOCIATED_IRP 0x00000008 #define IRP_BUFFERED_IO 0x00000010 #define IRP_DEALLOCATE_BUFFER 0x00000020 #define IRP_INPUT_OPERATION 0x00000040 #define IRP_SYNCHRONOUS_PAGING_IO 0x00000040 #define IRP_CREATE_OPERATION 0x00000080 #define IRP_READ_OPERATION 0x00000100 #define IRP_WRITE_OPERATION 0x00000200 #define IRP_CLOSE_OPERATION 0x00000400 // end_wdm #define IRP_DEFER_IO_COMPLETION 0x00000800 #define IRP_OB_QUERY_NAME 0x00001000 #define IRP_HOLD_DEVICE_QUEUE 0x00002000 #define IRP_RETRY_IO_COMPLETION 0x00004000 #define IRP_CLASS_CACHE_OPERATION 0x00008000 #define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION // begin_wdm // // Define I/O request packet (IRP) alternate flags for allocation control. // #define IRP_QUOTA_CHARGED 0x01 #define IRP_ALLOCATED_MUST_SUCCEED 0x02 #define IRP_ALLOCATED_FIXED_SIZE 0x04 #define IRP_LOOKASIDE_ALLOCATION 0x08 // // I/O Request Packet (IRP) definition // typedef struct _IRP { CSHORT Type; USHORT Size; // // Define the common fields used to control the IRP. // // // Define a pointer to the Memory Descriptor List (MDL) for this I/O // request. This field is only used if the I/O is "direct I/O". // PMDL MdlAddress; // // Flags word - used to remember various flags. // ULONG Flags; // // The following union is used for one of three purposes: // // 1. This IRP is an associated IRP. The field is a pointer to a master // IRP. // // 2. This is the master IRP. The field is the count of the number of // IRPs which must complete (associated IRPs) before the master can // complete. // // 3. This operation is being buffered and the field is the address of // the system space buffer. // union { struct _IRP *MasterIrp; LONG IrpCount; PVOID SystemBuffer; } AssociatedIrp; // // Thread list entry - allows queueing the IRP to the thread pending I/O // request packet list. // LIST_ENTRY ThreadListEntry; // // I/O status - final status of operation. // IO_STATUS_BLOCK IoStatus; // // Requestor mode - mode of the original requestor of this operation. // KPROCESSOR_MODE RequestorMode; // // Pending returned - TRUE if pending was initially returned as the // status for this packet. // BOOLEAN PendingReturned; // // Stack state information. // CHAR StackCount; CHAR CurrentLocation; // // Cancel - packet has been canceled. // BOOLEAN Cancel; // // Cancel Irql - Irql at which the cancel spinlock was acquired. // KIRQL CancelIrql; // // ApcEnvironment - Used to save the APC environment at the time that the // packet was initialized. // CCHAR ApcEnvironment; // // Allocation control flags. // UCHAR AllocationFlags; // // User parameters. // PIO_STATUS_BLOCK UserIosb; PKEVENT UserEvent; union { struct { PIO_APC_ROUTINE UserApcRoutine; PVOID UserApcContext; } AsynchronousParameters; LARGE_INTEGER AllocationSize; } Overlay; // // CancelRoutine - Used to contain the address of a cancel routine supplied // by a device driver when the IRP is in a cancelable state. // PDRIVER_CANCEL CancelRoutine; // // Note that the UserBuffer parameter is outside of the stack so that I/O // completion can copy data back into the user's address space without // having to know exactly which service was being invoked. The length // of the copy is stored in the second half of the I/O status block. If // the UserBuffer field is NULL, then no copy is performed. // PVOID UserBuffer; // // Kernel structures // // The following section contains kernel structures which the IRP needs // in order to place various work information in kernel controller system // queues. Because the size and alignment cannot be controlled, they are // placed here at the end so they just hang off and do not affect the // alignment of other fields in the IRP. // union { struct { union { // // DeviceQueueEntry - The device queue entry field is used to // queue the IRP to the device driver device queue. // KDEVICE_QUEUE_ENTRY DeviceQueueEntry; struct { // // The following are available to the driver to use in // whatever manner is desired, while the driver owns the // packet. // PVOID DriverContext[4]; } ; } ; // // Thread - pointer to caller's Thread Control Block. // PETHREAD Thread; // // Auxiliary buffer - pointer to any auxiliary buffer that is // required to pass information to a driver that is not contained // in a normal buffer. // PCHAR AuxiliaryBuffer; // // The following unnamed structure must be exactly identical // to the unnamed structure used in the minipacket header used // for completion queue entries. // struct { // // List entry - used to queue the packet to completion queue, among // others. // LIST_ENTRY ListEntry; union { // // Current stack location - contains a pointer to the current // IO_STACK_LOCATION structure in the IRP stack. This field // should never be directly accessed by drivers. They should // use the standard functions. // struct _IO_STACK_LOCATION *CurrentStackLocation; // // Minipacket type. // ULONG PacketType; }; }; // // Original file object - pointer to the original file object // that was used to open the file. This field is owned by the // I/O system and should not be used by any other drivers. // PFILE_OBJECT OriginalFileObject; } Overlay; // // APC - This APC control block is used for the special kernel APC as // well as for the caller's APC, if one was specified in the original // argument list. If so, then the APC is reused for the normal APC for // whatever mode the caller was in and the "special" routine that is // invoked before the APC gets control simply deallocates the IRP. // KAPC Apc; // // CompletionKey - This is the key that is used to distinguish // individual I/O operations initiated on a single file handle. // PVOID CompletionKey; } Tail; } IRP, *PIRP; // // Define completion routine types for use in stack locations in an IRP // typedef NTSTATUS (*PIO_COMPLETION_ROUTINE) ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); // // Define stack location control flags // #define SL_PENDING_RETURNED 0x01 #define SL_INVOKE_ON_CANCEL 0x20 #define SL_INVOKE_ON_SUCCESS 0x40 #define SL_INVOKE_ON_ERROR 0x80 // // Define flags for various functions // // // Create / Create Named Pipe // // The following flags must exactly match those in the IoCreateFile call's // options. The case sensitive flag is added in later, by the parse routine, // and is not an actual option to open. Rather, it is part of the object // manager's attributes structure. // #define SL_FORCE_ACCESS_CHECK 0x01 #define SL_OPEN_PAGING_FILE 0x02 #define SL_OPEN_TARGET_DIRECTORY 0x04 #define SL_CASE_SENSITIVE 0x80 // // Read / Write // #define SL_KEY_SPECIFIED 0x01 #define SL_OVERRIDE_VERIFY_VOLUME 0x02 #define SL_WRITE_THROUGH 0x04 #define SL_FT_SEQUENTIAL_WRITE 0x08 // // Device I/O Control // // // Same SL_OVERRIDE_VERIFY_VOLUME as for read/write above. // #define SL_READ_ACCESS_GRANTED 0x01 #define SL_WRITE_ACCESS_GRANTED 0x04 // Gap for SL_OVERRIDE_VERIFY_VOLUME // // Lock // #define SL_FAIL_IMMEDIATELY 0x01 #define SL_EXCLUSIVE_LOCK 0x02 // // QueryDirectory / QueryEa / QueryQuota // #define SL_RESTART_SCAN 0x01 #define SL_RETURN_SINGLE_ENTRY 0x02 #define SL_INDEX_SPECIFIED 0x04 // // NotifyDirectory // #define SL_WATCH_TREE 0x01 // // FileSystemControl // // minor: mount/verify volume // #define SL_ALLOW_RAW_MOUNT 0x01 // // Define PNP/POWER types required by IRP_MJ_PNP/IRP_MJ_POWER. // typedef enum _DEVICE_RELATION_TYPE { BusRelations, EjectionRelations, PowerRelations, RemovalRelations, TargetDeviceRelation, SingleBusRelations } DEVICE_RELATION_TYPE, *PDEVICE_RELATION_TYPE; typedef struct _DEVICE_RELATIONS { ULONG Count; PDEVICE_OBJECT Objects[1]; // variable length } DEVICE_RELATIONS, *PDEVICE_RELATIONS; typedef enum _DEVICE_USAGE_NOTIFICATION_TYPE { DeviceUsageTypeUndefined, DeviceUsageTypePaging, DeviceUsageTypeHibernation, DeviceUsageTypeDumpFile } DEVICE_USAGE_NOTIFICATION_TYPE; // begin_ntminiport // workaround overloaded definition (rpc generated headers all define INTERFACE // to match the class name). #undef INTERFACE typedef struct _INTERFACE { USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // interface specific entries go here } INTERFACE, *PINTERFACE; // end_ntminiport typedef struct _DEVICE_CAPABILITIES { USHORT Size; USHORT Version; // the version documented here is version 1 ULONG DeviceD1:1; ULONG DeviceD2:1; ULONG LockSupported:1; ULONG EjectSupported:1; // Ejectable in S0 ULONG Removable:1; ULONG DockDevice:1; ULONG UniqueID:1; ULONG SilentInstall:1; ULONG RawDeviceOK:1; ULONG SurpriseRemovalOK:1; ULONG WakeFromD0:1; ULONG WakeFromD1:1; ULONG WakeFromD2:1; ULONG WakeFromD3:1; ULONG HardwareDisabled:1; ULONG NonDynamic:1; ULONG WarmEjectSupported:1; ULONG NoDisplayInUI:1; ULONG Reserved:14; ULONG Address; ULONG UINumber; DEVICE_POWER_STATE DeviceState[POWER_SYSTEM_MAXIMUM]; SYSTEM_POWER_STATE SystemWake; DEVICE_POWER_STATE DeviceWake; ULONG D1Latency; ULONG D2Latency; ULONG D3Latency; } DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES; typedef struct _POWER_SEQUENCE { ULONG SequenceD1; ULONG SequenceD2; ULONG SequenceD3; } POWER_SEQUENCE, *PPOWER_SEQUENCE; typedef enum { BusQueryDeviceID = 0, // \ BusQueryHardwareIDs = 1, // Hardware ids BusQueryCompatibleIDs = 2, // compatible device ids BusQueryInstanceID = 3, // persistent id for this instance of the device BusQueryDeviceSerialNumber = 4 // serial number for this device } BUS_QUERY_ID_TYPE, *PBUS_QUERY_ID_TYPE; typedef ULONG PNP_DEVICE_STATE, *PPNP_DEVICE_STATE; #define PNP_DEVICE_DISABLED 0x00000001 #define PNP_DEVICE_DONT_DISPLAY_IN_UI 0x00000002 #define PNP_DEVICE_FAILED 0x00000004 #define PNP_DEVICE_REMOVED 0x00000008 #define PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED 0x00000010 #define PNP_DEVICE_NOT_DISABLEABLE 0x00000020 typedef enum { DeviceTextDescription = 0, // DeviceDesc property DeviceTextLocationInformation = 1 // DeviceLocation property } DEVICE_TEXT_TYPE, *PDEVICE_TEXT_TYPE; // // Define I/O Request Packet (IRP) stack locations // #if !defined(_AMD64_) && !defined(_IA64_) #include "pshpack4.h" #endif // begin_ntndis #if defined(_WIN64) #define POINTER_ALIGNMENT DECLSPEC_ALIGN(8) #else #define POINTER_ALIGNMENT #endif // end_ntndis typedef struct _IO_STACK_LOCATION { UCHAR MajorFunction; UCHAR MinorFunction; UCHAR Flags; UCHAR Control; // // The following user parameters are based on the service that is being // invoked. Drivers and file systems can determine which set to use based // on the above major and minor function codes. // union { // // System service parameters for: NtCreateFile // struct { PIO_SECURITY_CONTEXT SecurityContext; ULONG Options; USHORT POINTER_ALIGNMENT FileAttributes; USHORT ShareAccess; ULONG POINTER_ALIGNMENT EaLength; } Create; // // System service parameters for: NtReadFile // struct { ULONG Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } Read; // // System service parameters for: NtWriteFile // struct { ULONG Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } Write; // end_ntddk end_wdm end_nthal // // System service parameters for: NtQueryDirectoryFile // struct { ULONG Length; PSTRING FileName; FILE_INFORMATION_CLASS FileInformationClass; ULONG POINTER_ALIGNMENT FileIndex; } QueryDirectory; // // System service parameters for: NtNotifyChangeDirectoryFile // struct { ULONG Length; ULONG POINTER_ALIGNMENT CompletionFilter; } NotifyDirectory; // begin_ntddk begin_wdm begin_nthal // // System service parameters for: NtQueryInformationFile // struct { ULONG Length; FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; } QueryFile; // // System service parameters for: NtSetInformationFile // struct { ULONG Length; FILE_INFORMATION_CLASS POINTER_ALIGNMENT FileInformationClass; PFILE_OBJECT FileObject; union { struct { BOOLEAN ReplaceIfExists; BOOLEAN AdvanceOnly; }; ULONG ClusterCount; HANDLE DeleteHandle; }; } SetFile; // // System service parameters for: NtQueryVolumeInformationFile // struct { ULONG Length; FS_INFORMATION_CLASS POINTER_ALIGNMENT FsInformationClass; } QueryVolume; // // System service parameters for: NtFsControlFile // // Note that the user's output buffer is stored in the UserBuffer field // and the user's input buffer is stored in the SystemBuffer field. // struct { ULONG OutputBufferLength; ULONG POINTER_ALIGNMENT InputBufferLength; ULONG POINTER_ALIGNMENT FsControlCode; PVOID Type3InputBuffer; } FileSystemControl; // // System service parameters for: NtLockFile/NtUnlockFile // struct { PLARGE_INTEGER Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } LockControl; // begin_ntddk begin_wdm begin_nthal // // System service parameters for: NtFlushBuffersFile // // No extra user-supplied parameters. // // end_ntddk end_wdm end_nthal // // System service parameters for: NtDeviceIoControlFile // // Note that the user's output buffer is stored in the UserBuffer field // and the user's input buffer is stored in the SystemBuffer field. // struct { ULONG OutputBufferLength; ULONG POINTER_ALIGNMENT InputBufferLength; ULONG POINTER_ALIGNMENT IoControlCode; PVOID Type3InputBuffer; } DeviceIoControl; // end_wdm // // System service parameters for: NtQuerySecurityObject // struct { SECURITY_INFORMATION SecurityInformation; ULONG POINTER_ALIGNMENT Length; } QuerySecurity; // // System service parameters for: NtSetSecurityObject // struct { SECURITY_INFORMATION SecurityInformation; PSECURITY_DESCRIPTOR SecurityDescriptor; } SetSecurity; // begin_wdm // // Non-system service parameters. // // Parameters for MountVolume // struct { PVPB Vpb; PDEVICE_OBJECT DeviceObject; } MountVolume; // // Parameters for VerifyVolume // struct { PVPB Vpb; PDEVICE_OBJECT DeviceObject; } VerifyVolume; // // Parameters for Scsi with internal device contorl. // struct { struct _SCSI_REQUEST_BLOCK *Srb; } Scsi; // // Parameters for IRP_MN_QUERY_DEVICE_RELATIONS // struct { DEVICE_RELATION_TYPE Type; } QueryDeviceRelations; // // Parameters for IRP_MN_QUERY_INTERFACE // struct { CONST GUID *InterfaceType; USHORT Size; USHORT Version; PINTERFACE Interface; PVOID InterfaceSpecificData; } QueryInterface; // end_ntifs // // Parameters for IRP_MN_QUERY_CAPABILITIES // struct { PDEVICE_CAPABILITIES Capabilities; } DeviceCapabilities; // // Parameters for IRP_MN_FILTER_RESOURCE_REQUIREMENTS // struct { PIO_RESOURCE_REQUIREMENTS_LIST IoResourceRequirementList; } FilterResourceRequirements; // // Parameters for IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG // struct { ULONG WhichSpace; PVOID Buffer; ULONG Offset; ULONG POINTER_ALIGNMENT Length; } ReadWriteConfig; // // Parameters for IRP_MN_SET_LOCK // struct { BOOLEAN Lock; } SetLock; // // Parameters for IRP_MN_QUERY_ID // struct { BUS_QUERY_ID_TYPE IdType; } QueryId; // // Parameters for IRP_MN_QUERY_DEVICE_TEXT // struct { DEVICE_TEXT_TYPE DeviceTextType; LCID POINTER_ALIGNMENT LocaleId; } QueryDeviceText; // // Parameters for IRP_MN_DEVICE_USAGE_NOTIFICATION // struct { BOOLEAN InPath; BOOLEAN Reserved[3]; DEVICE_USAGE_NOTIFICATION_TYPE POINTER_ALIGNMENT Type; } UsageNotification; // // Parameters for IRP_MN_WAIT_WAKE // struct { SYSTEM_POWER_STATE PowerState; } WaitWake; // // Parameter for IRP_MN_POWER_SEQUENCE // struct { PPOWER_SEQUENCE PowerSequence; } PowerSequence; // // Parameters for IRP_MN_SET_POWER and IRP_MN_QUERY_POWER // struct { ULONG SystemContext; POWER_STATE_TYPE POINTER_ALIGNMENT Type; POWER_STATE POINTER_ALIGNMENT State; POWER_ACTION POINTER_ALIGNMENT ShutdownType; } Power; // // Parameters for StartDevice // struct { PCM_RESOURCE_LIST AllocatedResources; PCM_RESOURCE_LIST AllocatedResourcesTranslated; } StartDevice; // begin_ntifs // // Parameters for Cleanup // // No extra parameters supplied // // // WMI Irps // struct { ULONG_PTR ProviderId; PVOID DataPath; ULONG BufferSize; PVOID Buffer; } WMI; // // Others - driver-specific // struct { PVOID Argument1; PVOID Argument2; PVOID Argument3; PVOID Argument4; } Others; } Parameters; // // Save a pointer to this device driver's device object for this request // so it can be passed to the completion routine if needed. // PDEVICE_OBJECT DeviceObject; // // The following location contains a pointer to the file object for this // PFILE_OBJECT FileObject; // // The following routine is invoked depending on the flags in the above // flags field. // PIO_COMPLETION_ROUTINE CompletionRoutine; // // The following is used to store the address of the context parameter // that should be passed to the CompletionRoutine. // PVOID Context; } IO_STACK_LOCATION, *PIO_STACK_LOCATION; #if !defined(_AMD64_) && !defined(_IA64_) #include "poppack.h" #endif // // Define the share access structure used by file systems to determine // whether or not another accessor may open the file. // typedef struct _SHARE_ACCESS { ULONG OpenCount; ULONG Readers; ULONG Writers; ULONG Deleters; ULONG SharedRead; ULONG SharedWrite; ULONG SharedDelete; } SHARE_ACCESS, *PSHARE_ACCESS; // end_wdm // // The following structure is used by drivers that are initializing to // determine the number of devices of a particular type that have already // been initialized. It is also used to track whether or not the AtDisk // address range has already been claimed. Finally, it is used by the // NtQuerySystemInformation system service to return device type counts. // typedef struct _CONFIGURATION_INFORMATION { // // This field indicates the total number of disks in the system. This // number should be used by the driver to determine the name of new // disks. This field should be updated by the driver as it finds new // disks. // ULONG DiskCount; // Count of hard disks thus far ULONG FloppyCount; // Count of floppy disks thus far ULONG CdRomCount; // Count of CD-ROM drives thus far ULONG TapeCount; // Count of tape drives thus far ULONG ScsiPortCount; // Count of SCSI port adapters thus far ULONG SerialCount; // Count of serial devices thus far ULONG ParallelCount; // Count of parallel devices thus far // // These next two fields indicate ownership of one of the two IO address // spaces that are used by WD1003-compatable disk controllers. // BOOLEAN AtDiskPrimaryAddressClaimed; // 0x1F0 - 0x1FF BOOLEAN AtDiskSecondaryAddressClaimed; // 0x170 - 0x17F // // Indicates the structure version, as anything value belong this will have been added. // Use the structure size as the version. // ULONG Version; // // Indicates the total number of medium changer devices in the system. // This field will be updated by the drivers as it determines that // new devices have been found and will be supported. // ULONG MediumChangerCount; } CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; // // Public I/O routine definitions // NTKERNELAPI VOID IoAcquireCancelSpinLock( OUT PKIRQL Irql ); DECLSPEC_DEPRECATED_DDK // Use AllocateAdapterChannel NTKERNELAPI NTSTATUS IoAllocateAdapterChannel( IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context ); NTKERNELAPI VOID IoAllocateController( IN PCONTROLLER_OBJECT ControllerObject, IN PDEVICE_OBJECT DeviceObject, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context ); // begin_wdm NTKERNELAPI NTSTATUS IoAllocateDriverObjectExtension( IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension ); // begin_ntifs NTKERNELAPI PVOID IoAllocateErrorLogEntry( IN PVOID IoObject, IN UCHAR EntrySize ); NTKERNELAPI PIRP IoAllocateIrp( IN CCHAR StackSize, IN BOOLEAN ChargeQuota ); NTKERNELAPI PMDL IoAllocateMdl( IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN OUT PIRP Irp OPTIONAL ); // end_wdm end_ntifs //++ // // VOID // IoAssignArcName( // IN PUNICODE_STRING ArcName, // IN PUNICODE_STRING DeviceName // ) // // Routine Description: // // This routine is invoked by drivers of bootable media to create a symbolic // link between the ARC name of their device and its NT name. This allows // the system to determine which device in the system was actually booted // from since the ARC firmware only deals in ARC names, and NT only deals // in NT names. // // Arguments: // // ArcName - Supplies the Unicode string representing the ARC name. // // DeviceName - Supplies the name to which the ARCname refers. // // Return Value: // // None. // //-- #define IoAssignArcName( ArcName, DeviceName ) ( \ IoCreateSymbolicLink( (ArcName), (DeviceName) ) ) DECLSPEC_DEPRECATED_DDK // Use Pnp or IoReprtDetectedDevice NTKERNELAPI NTSTATUS IoAssignResources ( IN PUNICODE_STRING RegistryPath, IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, IN OUT PCM_RESOURCE_LIST *AllocatedResources ); NTKERNELAPI NTSTATUS IoAttachDevice( IN PDEVICE_OBJECT SourceDevice, IN PUNICODE_STRING TargetDevice, OUT PDEVICE_OBJECT *AttachedDevice ); // end_wdm DECLSPEC_DEPRECATED_DDK // Use IoAttachDeviceToDeviceStack NTKERNELAPI NTSTATUS IoAttachDeviceByPointer( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice ); // begin_wdm NTKERNELAPI PDEVICE_OBJECT IoAttachDeviceToDeviceStack( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice ); NTKERNELAPI PIRP IoBuildAsynchronousFsdRequest( IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG Length OPTIONAL, IN PLARGE_INTEGER StartingOffset OPTIONAL, IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL ); NTKERNELAPI PIRP IoBuildDeviceIoControlRequest( IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, OUT PIO_STATUS_BLOCK IoStatusBlock ); NTKERNELAPI VOID IoBuildPartialMdl( IN PMDL SourceMdl, IN OUT PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length ); typedef struct _BOOTDISK_INFORMATION { LONGLONG BootPartitionOffset; LONGLONG SystemPartitionOffset; ULONG BootDeviceSignature; ULONG SystemDeviceSignature; } BOOTDISK_INFORMATION, *PBOOTDISK_INFORMATION; // // This structure should follow the previous structure field for field. // typedef struct _BOOTDISK_INFORMATION_EX { LONGLONG BootPartitionOffset; LONGLONG SystemPartitionOffset; ULONG BootDeviceSignature; ULONG SystemDeviceSignature; GUID BootDeviceGuid; GUID SystemDeviceGuid; BOOLEAN BootDeviceIsGpt; BOOLEAN SystemDeviceIsGpt; } BOOTDISK_INFORMATION_EX, *PBOOTDISK_INFORMATION_EX; NTKERNELAPI NTSTATUS IoGetBootDiskInformation( IN OUT PBOOTDISK_INFORMATION BootDiskInformation, IN ULONG Size ); NTKERNELAPI PIRP IoBuildSynchronousFsdRequest( IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG Length OPTIONAL, IN PLARGE_INTEGER StartingOffset OPTIONAL, IN PKEVENT Event, OUT PIO_STATUS_BLOCK IoStatusBlock ); NTKERNELAPI NTSTATUS FASTCALL IofCallDriver( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ); #define IoCallDriver(a,b) \ IofCallDriver(a,b) NTKERNELAPI BOOLEAN IoCancelIrp( IN PIRP Irp ); NTKERNELAPI NTSTATUS IoCheckShareAccess( IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN OUT PFILE_OBJECT FileObject, IN OUT PSHARE_ACCESS ShareAccess, IN BOOLEAN Update ); // // This value should be returned from completion routines to continue // completing the IRP upwards. Otherwise, STATUS_MORE_PROCESSING_REQUIRED // should be returned. // #define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS // // Completion routines can also use this enumeration in place of status codes. // typedef enum _IO_COMPLETION_ROUTINE_RESULT { ContinueCompletion = STATUS_CONTINUE_COMPLETION, StopCompletion = STATUS_MORE_PROCESSING_REQUIRED } IO_COMPLETION_ROUTINE_RESULT, *PIO_COMPLETION_ROUTINE_RESULT; NTKERNELAPI VOID FASTCALL IofCompleteRequest( IN PIRP Irp, IN CCHAR PriorityBoost ); #define IoCompleteRequest(a,b) \ IofCompleteRequest(a,b) // end_ntifs NTKERNELAPI NTSTATUS IoConnectInterrupt( OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock OPTIONAL, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave ); // end_wdm NTKERNELAPI PCONTROLLER_OBJECT IoCreateController( IN ULONG Size ); // begin_wdm begin_ntifs NTKERNELAPI NTSTATUS IoCreateDevice( IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName OPTIONAL, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject ); #define WDM_MAJORVERSION 0x01 #define WDM_MINORVERSION 0x20 NTKERNELAPI BOOLEAN IoIsWdmVersionAvailable( IN UCHAR MajorVersion, IN UCHAR MinorVersion ); // end_nthal NTKERNELAPI NTSTATUS IoCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options ); NTKERNELAPI PKEVENT IoCreateNotificationEvent( IN PUNICODE_STRING EventName, OUT PHANDLE EventHandle ); NTKERNELAPI NTSTATUS IoCreateSymbolicLink( IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName ); NTKERNELAPI PKEVENT IoCreateSynchronizationEvent( IN PUNICODE_STRING EventName, OUT PHANDLE EventHandle ); NTKERNELAPI NTSTATUS IoCreateUnprotectedSymbolicLink( IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName ); // end_wdm //++ // // VOID // IoDeassignArcName( // IN PUNICODE_STRING ArcName // ) // // Routine Description: // // This routine is invoked by drivers to deassign an ARC name that they // created to a device. This is generally only called if the driver is // deleting the device object, which means that the driver is probably // unloading. // // Arguments: // // ArcName - Supplies the ARC name to be removed. // // Return Value: // // None. // //-- #define IoDeassignArcName( ArcName ) ( \ IoDeleteSymbolicLink( (ArcName) ) ) // end_ntifs NTKERNELAPI VOID IoDeleteController( IN PCONTROLLER_OBJECT ControllerObject ); // begin_wdm begin_ntifs NTKERNELAPI VOID IoDeleteDevice( IN PDEVICE_OBJECT DeviceObject ); NTKERNELAPI NTSTATUS IoDeleteSymbolicLink( IN PUNICODE_STRING SymbolicLinkName ); NTKERNELAPI VOID IoDetachDevice( IN OUT PDEVICE_OBJECT TargetDevice ); // end_ntifs NTKERNELAPI VOID IoDisconnectInterrupt( IN PKINTERRUPT InterruptObject ); // end_ntddk end_wdm end_nthal NTKERNELAPI VOID IoEnqueueIrp( IN PIRP Irp ); NTKERNELAPI VOID IoFreeController( IN PCONTROLLER_OBJECT ControllerObject ); // begin_wdm begin_ntifs NTKERNELAPI VOID IoFreeIrp( IN PIRP Irp ); NTKERNELAPI VOID IoFreeMdl( IN PMDL Mdl ); NTKERNELAPI PDEVICE_OBJECT IoGetAttachedDevice( IN PDEVICE_OBJECT DeviceObject ); NTKERNELAPI // ntddk wdm nthal PDEVICE_OBJECT // ntddk wdm nthal IoGetAttachedDeviceReference( // ntddk wdm nthal IN PDEVICE_OBJECT DeviceObject // ntddk wdm nthal ); // ntddk wdm nthal // ntddk wdm nthal NTKERNELAPI PDEVICE_OBJECT IoGetBaseFileSystemDeviceObject( IN PFILE_OBJECT FileObject ); NTKERNELAPI // ntddk nthal ntosp PCONFIGURATION_INFORMATION // ntddk nthal ntosp IoGetConfigurationInformation( VOID ); // ntddk nthal ntosp // begin_ntddk begin_wdm begin_nthal //++ // // PIO_STACK_LOCATION // IoGetCurrentIrpStackLocation( // IN PIRP Irp // ) // // Routine Description: // // This routine is invoked to return a pointer to the current stack location // in an I/O Request Packet (IRP). // // Arguments: // // Irp - Pointer to the I/O Request Packet. // // Return Value: // // The function value is a pointer to the current stack location in the // packet. // //-- #define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation ) // end_nthal end_wdm NTKERNELAPI PDEVICE_OBJECT IoGetDeviceToVerify( IN PETHREAD Thread ); // begin_wdm NTKERNELAPI PVOID IoGetDriverObjectExtension( IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress ); NTKERNELAPI PEPROCESS IoGetCurrentProcess( VOID ); // begin_nthal NTKERNELAPI NTSTATUS IoGetDeviceObjectPointer( IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject ); NTKERNELAPI struct _DMA_ADAPTER * IoGetDmaAdapter( IN PDEVICE_OBJECT PhysicalDeviceObject, OPTIONAL // required for PnP drivers IN struct _DEVICE_DESCRIPTION *DeviceDescription, IN OUT PULONG NumberOfMapRegisters ); NTKERNELAPI BOOLEAN IoForwardIrpSynchronously( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); #define IoForwardAndCatchIrp IoForwardIrpSynchronously // end_wdm NTKERNELAPI PGENERIC_MAPPING IoGetFileObjectGenericMapping( VOID ); // end_nthal // begin_wdm //++ // // ULONG // IoGetFunctionCodeFromCtlCode( // IN ULONG ControlCode // ) // // Routine Description: // // This routine extracts the function code from IOCTL and FSCTL function // control codes. // This routine should only be used by kernel mode code. // // Arguments: // // ControlCode - A function control code (IOCTL or FSCTL) from which the // function code must be extracted. // // Return Value: // // The extracted function code. // // Note: // // The CTL_CODE macro, used to create IOCTL and FSCTL function control // codes, is defined in ntioapi.h // //-- #define IoGetFunctionCodeFromCtlCode( ControlCode ) (\ ( ControlCode >> 2) & 0x00000FFF ) // begin_nthal NTKERNELAPI PVOID IoGetInitialStack( VOID ); NTKERNELAPI VOID IoGetStackLimits ( OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit ); // // The following function is used to tell the caller how much stack is available // FORCEINLINE ULONG_PTR IoGetRemainingStackSize ( VOID ) { ULONG_PTR Top; ULONG_PTR Bottom; IoGetStackLimits( &Bottom, &Top ); return((ULONG_PTR)(&Top) - Bottom ); } //++ // // PIO_STACK_LOCATION // IoGetNextIrpStackLocation( // IN PIRP Irp // ) // // Routine Description: // // This routine is invoked to return a pointer to the next stack location // in an I/O Request Packet (IRP). // // Arguments: // // Irp - Pointer to the I/O Request Packet. // // Return Value: // // The function value is a pointer to the next stack location in the packet. // //-- #define IoGetNextIrpStackLocation( Irp ) (\ (Irp)->Tail.Overlay.CurrentStackLocation - 1 ) NTKERNELAPI PDEVICE_OBJECT IoGetRelatedDeviceObject( IN PFILE_OBJECT FileObject ); // end_ntddk end_wdm end_nthal NTKERNELAPI ULONG IoGetRequestorProcessId( IN PIRP Irp ); NTKERNELAPI PEPROCESS IoGetRequestorProcess( IN PIRP Irp ); //++ // // VOID // IoInitializeDpcRequest( // IN PDEVICE_OBJECT DeviceObject, // IN PIO_DPC_ROUTINE DpcRoutine // ) // // Routine Description: // // This routine is invoked to initialize the DPC in a device object for a // device driver during its initialization routine. The DPC is used later // when the driver interrupt service routine requests that a DPC routine // be queued for later execution. // // Arguments: // // DeviceObject - Pointer to the device object that the request is for. // // DpcRoutine - Address of the driver's DPC routine to be executed when // the DPC is dequeued for processing. // // Return Value: // // None. // //-- #define IoInitializeDpcRequest( DeviceObject, DpcRoutine ) (\ KeInitializeDpc( &(DeviceObject)->Dpc, \ (PKDEFERRED_ROUTINE) (DpcRoutine), \ (DeviceObject) ) ) NTKERNELAPI VOID IoInitializeIrp( IN OUT PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize ); NTKERNELAPI NTSTATUS IoInitializeTimer( IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context ); NTKERNELAPI VOID IoReuseIrp( IN OUT PIRP Irp, IN NTSTATUS Iostatus ); // end_wdm NTKERNELAPI VOID IoCancelFileOpen( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject ); //++ // // BOOLEAN // IoIsErrorUserInduced( // IN NTSTATUS Status // ) // // Routine Description: // // This routine is invoked to determine if an error was as a // result of user actions. Typically these error are related // to removable media and will result in a pop-up. // // Arguments: // // Status - The status value to check. // // Return Value: // The function value is TRUE if the user induced the error, // otherwise FALSE is returned. // //-- #define IoIsErrorUserInduced( Status ) ((BOOLEAN) \ (((Status) == STATUS_DEVICE_NOT_READY) || \ ((Status) == STATUS_IO_TIMEOUT) || \ ((Status) == STATUS_MEDIA_WRITE_PROTECTED) || \ ((Status) == STATUS_NO_MEDIA_IN_DEVICE) || \ ((Status) == STATUS_VERIFY_REQUIRED) || \ ((Status) == STATUS_UNRECOGNIZED_MEDIA) || \ ((Status) == STATUS_WRONG_VOLUME))) NTKERNELAPI PIRP IoMakeAssociatedIrp( IN PIRP Irp, IN CCHAR StackSize ); // begin_wdm //++ // // VOID // IoMarkIrpPending( // IN OUT PIRP Irp // ) // // Routine Description: // // This routine marks the specified I/O Request Packet (IRP) to indicate // that an initial status of STATUS_PENDING was returned to the caller. // This is used so that I/O completion can determine whether or not to // fully complete the I/O operation requested by the packet. // // Arguments: // // Irp - Pointer to the I/O Request Packet to be marked pending. // // Return Value: // // None. // //-- #define IoMarkIrpPending( Irp ) ( \ IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED ) DECLSPEC_DEPRECATED_DDK // Use IoGetDeviceProperty NTKERNELAPI NTSTATUS IoQueryDeviceDescription( IN PINTERFACE_TYPE BusType OPTIONAL, IN PULONG BusNumber OPTIONAL, IN PCONFIGURATION_TYPE ControllerType OPTIONAL, IN PULONG ControllerNumber OPTIONAL, IN PCONFIGURATION_TYPE PeripheralType OPTIONAL, IN PULONG PeripheralNumber OPTIONAL, IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, IN PVOID Context ); NTKERNELAPI VOID IoQueueThreadIrp( IN PIRP Irp ); NTKERNELAPI VOID IoRaiseHardError( IN PIRP Irp, IN PVPB Vpb OPTIONAL, IN PDEVICE_OBJECT RealDeviceObject ); NTKERNELAPI BOOLEAN IoRaiseInformationalHardError( IN NTSTATUS ErrorStatus, IN PUNICODE_STRING String OPTIONAL, IN PKTHREAD Thread OPTIONAL ); NTKERNELAPI BOOLEAN IoSetThreadHardErrorMode( IN BOOLEAN EnableHardErrors ); NTKERNELAPI VOID IoRegisterBootDriverReinitialization( IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, IN PVOID Context ); NTKERNELAPI VOID IoRegisterDriverReinitialization( IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE DriverReinitializationRoutine, IN PVOID Context ); NTKERNELAPI NTSTATUS IoRegisterShutdownNotification( IN PDEVICE_OBJECT DeviceObject ); NTKERNELAPI NTSTATUS IoRegisterLastChanceShutdownNotification( IN PDEVICE_OBJECT DeviceObject ); // begin_wdm NTKERNELAPI VOID IoReleaseCancelSpinLock( IN KIRQL Irql ); NTKERNELAPI VOID IoRemoveShareAccess( IN PFILE_OBJECT FileObject, IN OUT PSHARE_ACCESS ShareAccess ); DECLSPEC_DEPRECATED_DDK // Use IoReportResourceForDetection NTKERNELAPI NTSTATUS IoReportResourceUsage( IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PCM_RESOURCE_LIST DriverList OPTIONAL, IN ULONG DriverListSize OPTIONAL, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST DeviceList OPTIONAL, IN ULONG DeviceListSize OPTIONAL, IN BOOLEAN OverrideConflict, OUT PBOOLEAN ConflictDetected ); // begin_wdm //++ // // VOID // IoRequestDpc( // IN PDEVICE_OBJECT DeviceObject, // IN PIRP Irp, // IN PVOID Context // ) // // Routine Description: // // This routine is invoked by the device driver's interrupt service routine // to request that a DPC routine be queued for later execution at a lower // IRQL. // // Arguments: // // DeviceObject - Device object for which the request is being processed. // // Irp - Pointer to the current I/O Request Packet (IRP) for the specified // device. // // Context - Provides a general context parameter to be passed to the // DPC routine. // // Return Value: // // None. // //-- #define IoRequestDpc( DeviceObject, Irp, Context ) ( \ KeInsertQueueDpc( &(DeviceObject)->Dpc, (Irp), (Context) ) ) //++ // // PDRIVER_CANCEL // IoSetCancelRoutine( // IN PIRP Irp, // IN PDRIVER_CANCEL CancelRoutine // ) // // Routine Description: // // This routine is invoked to set the address of a cancel routine which // is to be invoked when an I/O packet has been canceled. // // Arguments: // // Irp - Pointer to the I/O Request Packet itself. // // CancelRoutine - Address of the cancel routine that is to be invoked // if the IRP is cancelled. // // Return Value: // // Previous value of CancelRoutine field in the IRP. // //-- #define IoSetCancelRoutine( Irp, NewCancelRoutine ) ( \ (PDRIVER_CANCEL) InterlockedExchangePointer( (PVOID *) &(Irp)->CancelRoutine, (PVOID) (NewCancelRoutine) ) ) //++ // // VOID // IoSetCompletionRoutine( // IN PIRP Irp, // IN PIO_COMPLETION_ROUTINE CompletionRoutine, // IN PVOID Context, // IN BOOLEAN InvokeOnSuccess, // IN BOOLEAN InvokeOnError, // IN BOOLEAN InvokeOnCancel // ) // // Routine Description: // // This routine is invoked to set the address of a completion routine which // is to be invoked when an I/O packet has been completed by a lower-level // driver. // // Arguments: // // Irp - Pointer to the I/O Request Packet itself. // // CompletionRoutine - Address of the completion routine that is to be // invoked once the next level driver completes the packet. // // Context - Specifies a context parameter to be passed to the completion // routine. // // InvokeOnSuccess - Specifies that the completion routine is invoked when the // operation is successfully completed. // // InvokeOnError - Specifies that the completion routine is invoked when the // operation completes with an error status. // // InvokeOnCancel - Specifies that the completion routine is invoked when the // operation is being canceled. // // Return Value: // // None. // //-- #define IoSetCompletionRoutine( Irp, Routine, CompletionContext, Success, Error, Cancel ) { \ PIO_STACK_LOCATION __irpSp; \ ASSERT( (Success) | (Error) | (Cancel) ? (Routine) != NULL : TRUE ); \ __irpSp = IoGetNextIrpStackLocation( (Irp) ); \ __irpSp->CompletionRoutine = (Routine); \ __irpSp->Context = (CompletionContext); \ __irpSp->Control = 0; \ if ((Success)) { __irpSp->Control = SL_INVOKE_ON_SUCCESS; } \ if ((Error)) { __irpSp->Control |= SL_INVOKE_ON_ERROR; } \ if ((Cancel)) { __irpSp->Control |= SL_INVOKE_ON_CANCEL; } } NTSTATUS IoSetCompletionRoutineEx( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_COMPLETION_ROUTINE CompletionRoutine, IN PVOID Context, IN BOOLEAN InvokeOnSuccess, IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel ); NTKERNELAPI VOID IoSetHardErrorOrVerifyDevice( IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject ); // end_ntddk end_nthal NTKERNELAPI NTSTATUS IoSetInformation( IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation ); //++ // // VOID // IoSetNextIrpStackLocation ( // IN OUT PIRP Irp // ) // // Routine Description: // // This routine is invoked to set the current IRP stack location to // the next stack location, i.e. it "pushes" the stack. // // Arguments: // // Irp - Pointer to the I/O Request Packet (IRP). // // Return Value: // // None. // //-- #define IoSetNextIrpStackLocation( Irp ) { \ (Irp)->CurrentLocation--; \ (Irp)->Tail.Overlay.CurrentStackLocation--; } //++ // // VOID // IoCopyCurrentIrpStackLocationToNext( // IN PIRP Irp // ) // // Routine Description: // // This routine is invoked to copy the IRP stack arguments and file // pointer from the current IrpStackLocation to the next // in an I/O Request Packet (IRP). // // If the caller wants to call IoCallDriver with a completion routine // but does not wish to change the arguments otherwise, // the caller first calls IoCopyCurrentIrpStackLocationToNext, // then IoSetCompletionRoutine, then IoCallDriver. // // Arguments: // // Irp - Pointer to the I/O Request Packet. // // Return Value: // // None. // //-- #define IoCopyCurrentIrpStackLocationToNext( Irp ) { \ PIO_STACK_LOCATION __irpSp; \ PIO_STACK_LOCATION __nextIrpSp; \ __irpSp = IoGetCurrentIrpStackLocation( (Irp) ); \ __nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \ RtlCopyMemory( __nextIrpSp, __irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \ __nextIrpSp->Control = 0; } //++ // // VOID // IoSkipCurrentIrpStackLocation ( // IN PIRP Irp // ) // // Routine Description: // // This routine is invoked to increment the current stack location of // a given IRP. // // If the caller wishes to call the next driver in a stack, and does not // wish to change the arguments, nor does he wish to set a completion // routine, then the caller first calls IoSkipCurrentIrpStackLocation // and the calls IoCallDriver. // // Arguments: // // Irp - Pointer to the I/O Request Packet. // // Return Value: // // None // //-- #define IoSkipCurrentIrpStackLocation( Irp ) { \ (Irp)->CurrentLocation++; \ (Irp)->Tail.Overlay.CurrentStackLocation++; } NTKERNELAPI VOID IoSetShareAccess( IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN OUT PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess ); typedef struct _IO_REMOVE_LOCK_TRACKING_BLOCK * PIO_REMOVE_LOCK_TRACKING_BLOCK; typedef struct _IO_REMOVE_LOCK_COMMON_BLOCK { BOOLEAN Removed; BOOLEAN Reserved [3]; LONG IoCount; KEVENT RemoveEvent; } IO_REMOVE_LOCK_COMMON_BLOCK; typedef struct _IO_REMOVE_LOCK_DBG_BLOCK { LONG Signature; LONG HighWatermark; LONGLONG MaxLockedTicks; LONG AllocateTag; LIST_ENTRY LockList; KSPIN_LOCK Spin; LONG LowMemoryCount; ULONG Reserved1[4]; PVOID Reserved2; PIO_REMOVE_LOCK_TRACKING_BLOCK Blocks; } IO_REMOVE_LOCK_DBG_BLOCK; typedef struct _IO_REMOVE_LOCK { IO_REMOVE_LOCK_COMMON_BLOCK Common; #if DBG IO_REMOVE_LOCK_DBG_BLOCK Dbg; #endif } IO_REMOVE_LOCK, *PIO_REMOVE_LOCK; #define IoInitializeRemoveLock(Lock, Tag, Maxmin, HighWater) \ IoInitializeRemoveLockEx (Lock, Tag, Maxmin, HighWater, sizeof (IO_REMOVE_LOCK)) NTSYSAPI VOID NTAPI IoInitializeRemoveLockEx( IN PIO_REMOVE_LOCK Lock, IN ULONG AllocateTag, // Used only on checked kernels IN ULONG MaxLockedMinutes, // Used only on checked kernels IN ULONG HighWatermark, // Used only on checked kernels IN ULONG RemlockSize // are we checked or free ); // // Initialize a remove lock. // // Note: Allocation for remove locks needs to be within the device extension, // so that the memory for this structure stays allocated until such time as the // device object itself is deallocated. // #define IoAcquireRemoveLock(RemoveLock, Tag) \ IoAcquireRemoveLockEx(RemoveLock, Tag, __FILE__, __LINE__, sizeof (IO_REMOVE_LOCK)) NTSYSAPI NTSTATUS NTAPI IoAcquireRemoveLockEx ( IN PIO_REMOVE_LOCK RemoveLock, IN OPTIONAL PVOID Tag, // Optional IN PCSTR File, IN ULONG Line, IN ULONG RemlockSize // are we checked or free ); // // Routine Description: // // This routine is called to acquire the remove lock for a device object. // While the lock is held, the caller can assume that no pending pnp REMOVE // requests will be completed. // // The lock should be acquired immediately upon entering a dispatch routine. // It should also be acquired before creating any new reference to the // device object if there's a chance of releasing the reference before the // new one is done, in addition to references to the driver code itself, // which is removed from memory when the last device object goes. // // Arguments: // // RemoveLock - A pointer to an initialized REMOVE_LOCK structure. // // Tag - Used for tracking lock allocation and release. The same tag // specified when acquiring the lock must be used to release the lock. // Tags are only checked in checked versions of the driver. // // File - set to __FILE__ as the location in the code where the lock was taken. // // Line - set to __LINE__. // // Return Value: // // Returns whether or not the remove lock was obtained. // If successful the caller should continue with work calling // IoReleaseRemoveLock when finished. // // If not successful the lock was not obtained. The caller should abort the // work but not call IoReleaseRemoveLock. // #define IoReleaseRemoveLock(RemoveLock, Tag) \ IoReleaseRemoveLockEx(RemoveLock, Tag, sizeof (IO_REMOVE_LOCK)) NTSYSAPI VOID NTAPI IoReleaseRemoveLockEx( IN PIO_REMOVE_LOCK RemoveLock, IN PVOID Tag, // Optional IN ULONG RemlockSize // are we checked or free ); // // // Routine Description: // // This routine is called to release the remove lock on the device object. It // must be called when finished using a previously locked reference to the // device object. If an Tag was specified when acquiring the lock then the // same Tag must be specified when releasing the lock. // // When the lock count reduces to zero, this routine will signal the waiting // event to release the waiting thread deleting the device object protected // by this lock. // // Arguments: // // DeviceObject - the device object to lock // // Tag - The TAG (if any) specified when acquiring the lock. This is used // for lock tracking purposes // // Return Value: // // none // #define IoReleaseRemoveLockAndWait(RemoveLock, Tag) \ IoReleaseRemoveLockAndWaitEx(RemoveLock, Tag, sizeof (IO_REMOVE_LOCK)) NTSYSAPI VOID NTAPI IoReleaseRemoveLockAndWaitEx( IN PIO_REMOVE_LOCK RemoveLock, IN PVOID Tag, IN ULONG RemlockSize // are we checked or free ); // // // Routine Description: // // This routine is called when the client would like to delete the // remove-locked resource. This routine will block until all the remove // locks have released. // // This routine MUST be called after acquiring the lock. // // Arguments: // // RemoveLock // // Return Value: // // none // //++ // // USHORT // IoSizeOfIrp( // IN CCHAR StackSize // ) // // Routine Description: // // Determines the size of an IRP given the number of stack locations // the IRP will have. // // Arguments: // // StackSize - Number of stack locations for the IRP. // // Return Value: // // Size in bytes of the IRP. // //-- #define IoSizeOfIrp( StackSize ) \ ((USHORT) (sizeof( IRP ) + ((StackSize) * (sizeof( IO_STACK_LOCATION ))))) // end_ntifs NTKERNELAPI VOID IoStartNextPacket( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable ); NTKERNELAPI VOID IoStartNextPacketByKey( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable, IN ULONG Key ); NTKERNELAPI VOID IoStartPacket( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key OPTIONAL, IN PDRIVER_CANCEL CancelFunction OPTIONAL ); VOID IoSetStartIoAttributes( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DeferredStartIo, IN BOOLEAN NonCancelable ); // begin_ntifs NTKERNELAPI VOID IoStartTimer( IN PDEVICE_OBJECT DeviceObject ); NTKERNELAPI VOID IoStopTimer( IN PDEVICE_OBJECT DeviceObject ); NTKERNELAPI PEPROCESS IoThreadToProcess( IN PETHREAD Thread ); NTKERNELAPI VOID IoUnregisterShutdownNotification( IN PDEVICE_OBJECT DeviceObject ); // end_wdm NTKERNELAPI VOID IoUpdateShareAccess( IN PFILE_OBJECT FileObject, IN OUT PSHARE_ACCESS ShareAccess ); // end_ntddk end_nthal NTKERNELAPI NTSTATUS IoVerifyVolume( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount ); NTKERNELAPI // ntddk wdm nthal VOID // ntddk wdm nthal IoWriteErrorLogEntry( // ntddk wdm nthal IN PVOID ElEntry // ntddk wdm nthal ); // ntddk wdm nthal NTKERNELAPI NTSTATUS IoCreateDriver ( IN PUNICODE_STRING DriverName, OPTIONAL IN PDRIVER_INITIALIZE InitializationFunction ); NTKERNELAPI VOID IoDeleteDriver ( IN PDRIVER_OBJECT DriverObject ); typedef struct _IO_WORKITEM *PIO_WORKITEM; typedef VOID (*PIO_WORKITEM_ROUTINE) ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ); PIO_WORKITEM IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject ); VOID IoFreeWorkItem( PIO_WORKITEM IoWorkItem ); VOID IoQueueWorkItem( IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context ); NTKERNELAPI NTSTATUS IoWMIRegistrationControl( IN PDEVICE_OBJECT DeviceObject, IN ULONG Action ); // // Action code for IoWMIRegistrationControl api // #define WMIREG_ACTION_REGISTER 1 #define WMIREG_ACTION_DEREGISTER 2 #define WMIREG_ACTION_REREGISTER 3 #define WMIREG_ACTION_UPDATE_GUIDS 4 #define WMIREG_ACTION_BLOCK_IRPS 5 // // Code passed in IRP_MN_REGINFO WMI irp // #define WMIREGISTER 0 #define WMIUPDATE 1 NTKERNELAPI NTSTATUS IoWMIAllocateInstanceIds( IN GUID *Guid, IN ULONG InstanceCount, OUT ULONG *FirstInstanceId ); NTKERNELAPI NTSTATUS IoWMISuggestInstanceName( IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN PUNICODE_STRING SymbolicLinkName OPTIONAL, IN BOOLEAN CombineNames, OUT PUNICODE_STRING SuggestedInstanceName ); NTKERNELAPI NTSTATUS IoWMIWriteEvent( IN PVOID WnodeEventItem ); #if defined(_WIN64) NTKERNELAPI ULONG IoWMIDeviceObjectToProviderId( PDEVICE_OBJECT DeviceObject ); #else #define IoWMIDeviceObjectToProviderId(DeviceObject) ((ULONG)(DeviceObject)) #endif NTKERNELAPI NTSTATUS IoWMIOpenBlock( IN GUID *DataBlockGuid, IN ULONG DesiredAccess, OUT PVOID *DataBlockObject ); NTKERNELAPI NTSTATUS IoWMIQueryAllData( IN PVOID DataBlockObject, IN OUT ULONG *InOutBufferSize, OUT /* non paged */ PVOID OutBuffer ); NTKERNELAPI NTSTATUS IoWMIQueryAllDataMultiple( IN PVOID *DataBlockObjectList, IN ULONG ObjectCount, IN OUT ULONG *InOutBufferSize, OUT /* non paged */ PVOID OutBuffer ); NTKERNELAPI NTSTATUS IoWMIQuerySingleInstance( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, IN OUT ULONG *InOutBufferSize, OUT /* non paged */ PVOID OutBuffer ); NTKERNELAPI NTSTATUS IoWMIQuerySingleInstanceMultiple( IN PVOID *DataBlockObjectList, IN PUNICODE_STRING InstanceNames, IN ULONG ObjectCount, IN OUT ULONG *InOutBufferSize, OUT /* non paged */ PVOID OutBuffer ); NTKERNELAPI NTSTATUS IoWMISetSingleInstance( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, IN ULONG Version, IN ULONG ValueBufferSize, IN PVOID ValueBuffer ); NTKERNELAPI NTSTATUS IoWMISetSingleItem( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, IN ULONG DataItemId, IN ULONG Version, IN ULONG ValueBufferSize, IN PVOID ValueBuffer ); NTKERNELAPI NTSTATUS IoWMIExecuteMethod( IN PVOID DataBlockObject, IN PUNICODE_STRING InstanceName, IN ULONG MethodId, IN ULONG InBufferSize, IN OUT PULONG OutBufferSize, IN OUT PUCHAR InOutBuffer ); typedef VOID (*WMI_NOTIFICATION_CALLBACK)( PVOID Wnode, PVOID Context ); NTKERNELAPI NTSTATUS IoWMISetNotificationCallback( IN PVOID Object, IN WMI_NOTIFICATION_CALLBACK Callback, IN PVOID Context ); NTKERNELAPI NTSTATUS IoWMIHandleToInstanceName( IN PVOID DataBlockObject, IN HANDLE FileHandle, OUT PUNICODE_STRING InstanceName ); NTKERNELAPI NTSTATUS IoWMIDeviceObjectToInstanceName( IN PVOID DataBlockObject, IN PDEVICE_OBJECT DeviceObject, OUT PUNICODE_STRING InstanceName ); NTKERNELAPI NTSTATUS IoSetIoCompletion ( IN PVOID IoCompletion, IN PVOID KeyContext, IN PVOID ApcContext, IN NTSTATUS IoStatus, IN ULONG_PTR IoStatusInformation, IN BOOLEAN Quota ); #if defined(_WIN64) BOOLEAN IoIs32bitProcess( IN PIRP Irp ); #endif NTKERNELAPI VOID FASTCALL IoAssignDriveLetters( PLOADER_PARAMETER_BLOCK LoaderBlock, PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString ); DECLSPEC_DEPRECATED_DDK // Use IoWritePartitionTableEx NTKERNELAPI NTSTATUS FASTCALL IoWritePartitionTable( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer ); NTKERNELAPI NTSTATUS IoCreateDisk( IN PDEVICE_OBJECT DeviceObject, IN struct _CREATE_DISK* Disk ); NTKERNELAPI NTSTATUS IoReadPartitionTableEx( IN PDEVICE_OBJECT DeviceObject, IN struct _DRIVE_LAYOUT_INFORMATION_EX** DriveLayout ); NTKERNELAPI NTSTATUS IoWritePartitionTableEx( IN PDEVICE_OBJECT DeviceObject, IN struct _DRIVE_LAYOUT_INFORMATION_EX* DriveLayout ); NTKERNELAPI NTSTATUS IoSetPartitionInformationEx( IN PDEVICE_OBJECT DeviceObject, IN ULONG PartitionNumber, IN struct _SET_PARTITION_INFORMATION_EX* PartitionInfo ); NTKERNELAPI NTSTATUS IoUpdateDiskGeometry( IN PDEVICE_OBJECT DeviceObject, IN struct _DISK_GEOMETRY_EX* OldDiskGeometry, IN struct _DISK_GEOMETRY_EX* NewDiskGeometry ); NTKERNELAPI NTSTATUS IoVerifyPartitionTable( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN FixErrors ); typedef struct _DISK_SIGNATURE { ULONG PartitionStyle; union { struct { ULONG Signature; ULONG CheckSum; } Mbr; struct { GUID DiskId; } Gpt; }; } DISK_SIGNATURE, *PDISK_SIGNATURE; NTKERNELAPI NTSTATUS IoReadDiskSignature( IN PDEVICE_OBJECT DeviceObject, IN ULONG BytesPerSector, OUT PDISK_SIGNATURE Signature ); NTSTATUS IoVolumeDeviceToDosName( IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName ); NTSTATUS IoEnumerateDeviceObjectList( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT *DeviceObjectList, IN ULONG DeviceObjectListSize, OUT PULONG ActualNumberDeviceObjects ); PDEVICE_OBJECT IoGetLowerDeviceObject( IN PDEVICE_OBJECT DeviceObject ); PDEVICE_OBJECT IoGetDeviceAttachmentBaseRef( IN PDEVICE_OBJECT DeviceObject ); NTSTATUS IoGetDiskDeviceObject( IN PDEVICE_OBJECT FileSystemDeviceObject, OUT PDEVICE_OBJECT *DiskDeviceObject ); NTSTATUS IoSetSystemPartition( PUNICODE_STRING VolumeNameString ); // begin_wdm VOID IoFreeErrorLogEntry( PVOID ElEntry ); // Cancel SAFE API set start // // The following APIs are to help ease the pain of writing queue packages that // handle the cancellation race well. The idea of this set of APIs is to not // force a single queue data structure but allow the cancel logic to be hidden // from the drivers. A driver implements a queue and as part of its header // includes the IO_CSQ structure. In its initialization routine it calls // IoInitializeCsq. Then in the dispatch routine when the driver wants to // insert an IRP into the queue it calls IoCsqInsertIrp. When the driver wants // to remove something from the queue it calls IoCsqRemoveIrp. Note that Insert // can fail if the IRP was cancelled in the meantime. Remove can also fail if // the IRP was already cancelled. // // There are typically two modes where drivers queue IRPs. These two modes are // covered by the cancel safe queue API set. // // Mode 1: // One is where the driver queues the IRP and at some later // point in time dequeues an IRP and issues the IO request. // For this mode the driver should use IoCsqInsertIrp and IoCsqRemoveNextIrp. // The driver in this case is expected to pass NULL to the irp context // parameter in IoInsertIrp. // // Mode 2: // In this the driver queues theIRP, issues the IO request (like issuing a DMA // request or writing to a register) and when the IO request completes (either // using a DPC or timer) the driver dequeues the IRP and completes it. For this // mode the driver should use IoCsqInsertIrp and IoCsqRemoveIrp. In this case // the driver should allocate an IRP context and pass it in to IoCsqInsertIrp. // The cancel API code creates an association between the IRP and the context // and thus ensures that when the time comes to remove the IRP it can ascertain // correctly. // // Note that the cancel API set assumes that the field DriverContext[3] is // always available for use and that the driver does not use it. // // // Bookkeeping structure. This should be opaque to drivers. // Drivers typically include this as part of their queue headers. // Given a CSQ pointer the driver should be able to get its // queue header using CONTAINING_RECORD macro // typedef struct _IO_CSQ IO_CSQ, *PIO_CSQ; #define IO_TYPE_CSQ_IRP_CONTEXT 1 #define IO_TYPE_CSQ 2 // // IRP context structure. This structure is necessary if the driver is using // the second mode. // typedef struct _IO_CSQ_IRP_CONTEXT { ULONG Type; PIRP Irp; PIO_CSQ Csq; } IO_CSQ_IRP_CONTEXT, *PIO_CSQ_IRP_CONTEXT; // // Routines that insert/remove IRP // typedef VOID (*PIO_CSQ_INSERT_IRP)( IN struct _IO_CSQ *Csq, IN PIRP Irp ); typedef VOID (*PIO_CSQ_REMOVE_IRP)( IN PIO_CSQ Csq, IN PIRP Irp ); // // Retrieves next entry after Irp from the queue. // Returns NULL if there are no entries in the queue. // If Irp is NUL, returns the entry in the head of the queue. // This routine does not remove the IRP from the queue. // typedef PIRP (*PIO_CSQ_PEEK_NEXT_IRP)( IN PIO_CSQ Csq, IN PIRP Irp, IN PVOID PeekContext ); // // Lock routine that protects the cancel safe queue. // typedef VOID (*PIO_CSQ_ACQUIRE_LOCK)( IN PIO_CSQ Csq, OUT PKIRQL Irql ); typedef VOID (*PIO_CSQ_RELEASE_LOCK)( IN PIO_CSQ Csq, IN KIRQL Irql ); // // Completes the IRP with STATUS_CANCELLED. IRP is guaranteed to be valid // In most cases this routine just calls IoCompleteRequest(Irp, STATUS_CANCELLED); // typedef VOID (*PIO_CSQ_COMPLETE_CANCELED_IRP)( IN PIO_CSQ Csq, IN PIRP Irp ); // // Bookkeeping structure. This should be opaque to drivers. // Drivers typically include this as part of their queue headers. // Given a CSQ pointer the driver should be able to get its // queue header using CONTAINING_RECORD macro // typedef struct _IO_CSQ { ULONG Type; PIO_CSQ_INSERT_IRP CsqInsertIrp; PIO_CSQ_REMOVE_IRP CsqRemoveIrp; PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp; PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock; PIO_CSQ_RELEASE_LOCK CsqReleaseLock; PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp; PVOID ReservePointer; // Future expansion } IO_CSQ, *PIO_CSQ; // // Initializes the cancel queue structure. // NTSTATUS IoCsqInitialize( IN PIO_CSQ Csq, IN PIO_CSQ_INSERT_IRP CsqInsertIrp, IN PIO_CSQ_REMOVE_IRP CsqRemoveIrp, IN PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, IN PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, IN PIO_CSQ_RELEASE_LOCK CsqReleaseLock, IN PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp ); // // The caller calls this routine to insert the IRP and return STATUS_PENDING. // VOID IoCsqInsertIrp( IN PIO_CSQ Csq, IN PIRP Irp, IN PIO_CSQ_IRP_CONTEXT Context ); // // Returns an IRP if one can be found. NULL otherwise. // PIRP IoCsqRemoveNextIrp( IN PIO_CSQ Csq, IN PVOID PeekContext ); // // This routine is called from timeout or DPCs. // The context is presumably part of the DPC or timer context. // If succesfull returns the IRP associated with context. // PIRP IoCsqRemoveIrp( IN PIO_CSQ Csq, IN PIO_CSQ_IRP_CONTEXT Context ); // Cancel SAFE API set end NTSTATUS IoCreateFileSpecifyDeviceObjectHint( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options, IN PVOID DeviceObject ); NTSTATUS IoAttachDeviceToDeviceStackSafe( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice, OUT PDEVICE_OBJECT *AttachedToDeviceObject ); NTSTATUS IoValidateDeviceIoControlAccess( IN PIRP Irp, IN ULONG RequiredAccess ); // // Define PnP Device Property for IoGetDeviceProperty // typedef enum { DevicePropertyDeviceDescription, DevicePropertyHardwareID, DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, DevicePropertyBootConfigurationTranslated, DevicePropertyClassName, DevicePropertyClassGuid, DevicePropertyDriverKeyName, DevicePropertyManufacturer, DevicePropertyFriendlyName, DevicePropertyLocationInformation, DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, DevicePropertyLegacyBusType, DevicePropertyBusNumber, DevicePropertyEnumeratorName, DevicePropertyAddress, DevicePropertyUINumber, DevicePropertyInstallState, DevicePropertyRemovalPolicy } DEVICE_REGISTRY_PROPERTY; typedef BOOLEAN (*PTRANSLATE_BUS_ADDRESS)( IN PVOID Context, IN PHYSICAL_ADDRESS BusAddress, IN ULONG Length, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress ); typedef struct _DMA_ADAPTER *(*PGET_DMA_ADAPTER)( IN PVOID Context, IN struct _DEVICE_DESCRIPTION *DeviceDescriptor, OUT PULONG NumberOfMapRegisters ); typedef ULONG (*PGET_SET_DEVICE_DATA)( IN PVOID Context, IN ULONG DataType, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ); typedef enum _DEVICE_INSTALL_STATE { InstallStateInstalled, InstallStateNeedsReinstall, InstallStateFailedInstall, InstallStateFinishInstall } DEVICE_INSTALL_STATE, *PDEVICE_INSTALL_STATE; // // Define structure returned in response to IRP_MN_QUERY_BUS_INFORMATION by a // PDO indicating the type of bus the device exists on. // typedef struct _PNP_BUS_INFORMATION { GUID BusTypeGuid; INTERFACE_TYPE LegacyBusType; ULONG BusNumber; } PNP_BUS_INFORMATION, *PPNP_BUS_INFORMATION; // // Define structure returned in response to IRP_MN_QUERY_LEGACY_BUS_INFORMATION // by an FDO indicating the type of bus it is. This is normally the same bus // type as the device's children (i.e., as retrieved from the child PDO's via // IRP_MN_QUERY_BUS_INFORMATION) except for cases like CardBus, which can // support both 16-bit (PCMCIABus) and 32-bit (PCIBus) cards. // typedef struct _LEGACY_BUS_INFORMATION { GUID BusTypeGuid; INTERFACE_TYPE LegacyBusType; ULONG BusNumber; } LEGACY_BUS_INFORMATION, *PLEGACY_BUS_INFORMATION; // // Defines for IoGetDeviceProperty(DevicePropertyRemovalPolicy). // typedef enum _DEVICE_REMOVAL_POLICY { RemovalPolicyExpectNoRemoval = 1, RemovalPolicyExpectOrderlyRemoval = 2, RemovalPolicyExpectSurpriseRemoval = 3 } DEVICE_REMOVAL_POLICY, *PDEVICE_REMOVAL_POLICY; typedef struct _BUS_INTERFACE_STANDARD { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // standard bus interfaces // PTRANSLATE_BUS_ADDRESS TranslateBusAddress; PGET_DMA_ADAPTER GetDmaAdapter; PGET_SET_DEVICE_DATA SetBusData; PGET_SET_DEVICE_DATA GetBusData; } BUS_INTERFACE_STANDARD, *PBUS_INTERFACE_STANDARD; // // The following definitions are used in ACPI QueryInterface // typedef BOOLEAN (* PGPE_SERVICE_ROUTINE) ( PVOID, PVOID); typedef NTSTATUS (* PGPE_CONNECT_VECTOR) ( PDEVICE_OBJECT, ULONG, KINTERRUPT_MODE, BOOLEAN, PGPE_SERVICE_ROUTINE, PVOID, PVOID); typedef NTSTATUS (* PGPE_DISCONNECT_VECTOR) ( PVOID); typedef NTSTATUS (* PGPE_ENABLE_EVENT) ( PDEVICE_OBJECT, PVOID); typedef NTSTATUS (* PGPE_DISABLE_EVENT) ( PDEVICE_OBJECT, PVOID); typedef NTSTATUS (* PGPE_CLEAR_STATUS) ( PDEVICE_OBJECT, PVOID); typedef VOID (* PDEVICE_NOTIFY_CALLBACK) ( PVOID, ULONG); typedef NTSTATUS (* PREGISTER_FOR_DEVICE_NOTIFICATIONS) ( PDEVICE_OBJECT, PDEVICE_NOTIFY_CALLBACK, PVOID); typedef void (* PUNREGISTER_FOR_DEVICE_NOTIFICATIONS) ( PDEVICE_OBJECT, PDEVICE_NOTIFY_CALLBACK); typedef struct _ACPI_INTERFACE_STANDARD { // // Generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // ACPI interfaces // PGPE_CONNECT_VECTOR GpeConnectVector; PGPE_DISCONNECT_VECTOR GpeDisconnectVector; PGPE_ENABLE_EVENT GpeEnableEvent; PGPE_DISABLE_EVENT GpeDisableEvent; PGPE_CLEAR_STATUS GpeClearStatus; PREGISTER_FOR_DEVICE_NOTIFICATIONS RegisterForDeviceNotifications; PUNREGISTER_FOR_DEVICE_NOTIFICATIONS UnregisterForDeviceNotifications; } ACPI_INTERFACE_STANDARD, *PACPI_INTERFACE_STANDARD; // end_wdm end_ntddk typedef enum _ACPI_REG_TYPE { PM1a_ENABLE, PM1b_ENABLE, PM1a_STATUS, PM1b_STATUS, PM1a_CONTROL, PM1b_CONTROL, GP_STATUS, GP_ENABLE, SMI_CMD, MaxRegType } ACPI_REG_TYPE, *PACPI_REG_TYPE; typedef USHORT (*PREAD_ACPI_REGISTER) ( IN ACPI_REG_TYPE AcpiReg, IN ULONG Register); typedef VOID (*PWRITE_ACPI_REGISTER) ( IN ACPI_REG_TYPE AcpiReg, IN ULONG Register, IN USHORT Value ); typedef struct ACPI_REGS_INTERFACE_STANDARD { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // READ/WRITE_ACPI_REGISTER functions // PREAD_ACPI_REGISTER ReadAcpiRegister; PWRITE_ACPI_REGISTER WriteAcpiRegister; } ACPI_REGS_INTERFACE_STANDARD, *PACPI_REGS_INTERFACE_STANDARD; typedef NTSTATUS (*PHAL_QUERY_ALLOCATE_PORT_RANGE) ( IN BOOLEAN IsSparse, IN BOOLEAN PrimaryIsMmio, IN PVOID VirtBaseAddr OPTIONAL, IN PHYSICAL_ADDRESS PhysBaseAddr, // Only valid if PrimaryIsMmio = TRUE IN ULONG Length, // Only valid if PrimaryIsMmio = TRUE OUT PUSHORT NewRangeId ); typedef VOID (*PHAL_FREE_PORT_RANGE)( IN USHORT RangeId ); typedef struct _HAL_PORT_RANGE_INTERFACE { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // QueryAllocateRange/FreeRange functions // PHAL_QUERY_ALLOCATE_PORT_RANGE QueryAllocateRange; PHAL_FREE_PORT_RANGE FreeRange; } HAL_PORT_RANGE_INTERFACE, *PHAL_PORT_RANGE_INTERFACE; // // describe the CMOS HAL interface // typedef enum _CMOS_DEVICE_TYPE { CmosTypeStdPCAT, CmosTypeIntelPIIX4, CmosTypeDal1501 } CMOS_DEVICE_TYPE; typedef ULONG (*PREAD_ACPI_CMOS) ( IN CMOS_DEVICE_TYPE CmosType, IN ULONG SourceAddress, IN PUCHAR DataBuffer, IN ULONG ByteCount ); typedef ULONG (*PWRITE_ACPI_CMOS) ( IN CMOS_DEVICE_TYPE CmosType, IN ULONG SourceAddress, IN PUCHAR DataBuffer, IN ULONG ByteCount ); typedef struct _ACPI_CMOS_INTERFACE_STANDARD { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // READ/WRITE_ACPI_CMOS functions // PREAD_ACPI_CMOS ReadCmos; PWRITE_ACPI_CMOS WriteCmos; } ACPI_CMOS_INTERFACE_STANDARD, *PACPI_CMOS_INTERFACE_STANDARD; // // These definitions are used for getting PCI Interrupt Routing interfaces // typedef struct { PVOID LinkNode; ULONG StaticVector; UCHAR Flags; } ROUTING_TOKEN, *PROUTING_TOKEN; // // Flag indicating that the device supports // MSI interrupt routing or that the provided token contains // MSI routing information // #define PCI_MSI_ROUTING 0x1 #define PCI_STATIC_ROUTING 0x2 typedef NTSTATUS (*PGET_INTERRUPT_ROUTING)( IN PDEVICE_OBJECT Pdo, OUT ULONG *Bus, OUT ULONG *PciSlot, OUT UCHAR *InterruptLine, OUT UCHAR *InterruptPin, OUT UCHAR *ClassCode, OUT UCHAR *SubClassCode, OUT PDEVICE_OBJECT *ParentPdo, OUT ROUTING_TOKEN *RoutingToken, OUT UCHAR *Flags ); typedef NTSTATUS (*PSET_INTERRUPT_ROUTING_TOKEN)( IN PDEVICE_OBJECT Pdo, IN PROUTING_TOKEN RoutingToken ); typedef VOID (*PUPDATE_INTERRUPT_LINE)( IN PDEVICE_OBJECT Pdo, IN UCHAR LineRegister ); typedef struct _INT_ROUTE_INTERFACE_STANDARD { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // standard bus interfaces // PGET_INTERRUPT_ROUTING GetInterruptRouting; PSET_INTERRUPT_ROUTING_TOKEN SetInterruptRoutingToken; PUPDATE_INTERRUPT_LINE UpdateInterruptLine; } INT_ROUTE_INTERFACE_STANDARD, *PINT_ROUTE_INTERFACE_STANDARD; // Some well-known interface versions supported by the PCI Bus Driver #define PCI_INT_ROUTE_INTRF_STANDARD_VER 1 NTKERNELAPI NTSTATUS IoSynchronousInvalidateDeviceRelations( PDEVICE_OBJECT DeviceObject, DEVICE_RELATION_TYPE Type ); // begin_ntddk begin_nthal begin_ntifs NTKERNELAPI NTSTATUS IoReportDetectedDevice( IN PDRIVER_OBJECT DriverObject, IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PCM_RESOURCE_LIST ResourceList, IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL, IN BOOLEAN ResourceAssigned, IN OUT PDEVICE_OBJECT *DeviceObject ); // begin_wdm NTKERNELAPI VOID IoInvalidateDeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type ); NTKERNELAPI VOID IoRequestDeviceEject( IN PDEVICE_OBJECT PhysicalDeviceObject ); NTKERNELAPI NTSTATUS IoGetDeviceProperty( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength ); // // The following definitions are used in IoOpenDeviceRegistryKey // #define PLUGPLAY_REGKEY_DEVICE 1 #define PLUGPLAY_REGKEY_DRIVER 2 #define PLUGPLAY_REGKEY_CURRENT_HWPROFILE 4 NTKERNELAPI NTSTATUS IoOpenDeviceRegistryKey( IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey ); NTKERNELAPI NTSTATUS NTAPI IoRegisterDeviceInterface( IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString, OPTIONAL OUT PUNICODE_STRING SymbolicLinkName ); NTKERNELAPI NTSTATUS IoOpenDeviceInterfaceRegistryKey( IN PUNICODE_STRING SymbolicLinkName, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DeviceInterfaceKey ); NTKERNELAPI NTSTATUS IoSetDeviceInterfaceState( IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable ); NTKERNELAPI NTSTATUS NTAPI IoGetDeviceInterfaces( IN CONST GUID *InterfaceClassGuid, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN ULONG Flags, OUT PWSTR *SymbolicLinkList ); #define DEVICE_INTERFACE_INCLUDE_NONACTIVE 0x00000001 NTKERNELAPI NTSTATUS NTAPI IoGetDeviceInterfaceAlias( IN PUNICODE_STRING SymbolicLinkName, IN CONST GUID *AliasInterfaceClassGuid, OUT PUNICODE_STRING AliasSymbolicLinkName ); // // Define PnP notification event categories // typedef enum _IO_NOTIFICATION_EVENT_CATEGORY { EventCategoryReserved, EventCategoryHardwareProfileChange, EventCategoryDeviceInterfaceChange, EventCategoryTargetDeviceChange } IO_NOTIFICATION_EVENT_CATEGORY; // // Define flags that modify the behavior of IoRegisterPlugPlayNotification // for the various event categories... // #define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES 0x00000001 typedef NTSTATUS (*PDRIVER_NOTIFICATION_CALLBACK_ROUTINE) ( IN PVOID NotificationStructure, IN PVOID Context ); NTKERNELAPI NTSTATUS IoRegisterPlugPlayNotification( IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN ULONG EventCategoryFlags, IN PVOID EventCategoryData OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Context, OUT PVOID *NotificationEntry ); NTKERNELAPI NTSTATUS IoUnregisterPlugPlayNotification( IN PVOID NotificationEntry ); NTKERNELAPI NTSTATUS IoReportTargetDeviceChange( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure // always begins with a PLUGPLAY_NOTIFICATION_HEADER ); typedef VOID (*PDEVICE_CHANGE_COMPLETE_CALLBACK)( IN PVOID Context ); NTKERNELAPI VOID IoInvalidateDeviceState( IN PDEVICE_OBJECT PhysicalDeviceObject ); #define IoAdjustPagingPathCount(_count_,_paging_) { \ if (_paging_) { \ InterlockedIncrement(_count_); \ } else { \ InterlockedDecrement(_count_); \ } \ } NTKERNELAPI NTSTATUS IoReportTargetDeviceChangeAsynchronous( IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, // always begins with a PLUGPLAY_NOTIFICATION_HEADER IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback, OPTIONAL IN PVOID Context OPTIONAL ); NTKERNELAPI NTSTATUS IoReportResourceForDetection( IN PDRIVER_OBJECT DriverObject, IN PCM_RESOURCE_LIST DriverList OPTIONAL, IN ULONG DriverListSize OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PCM_RESOURCE_LIST DeviceList OPTIONAL, IN ULONG DeviceListSize OPTIONAL, OUT PBOOLEAN ConflictDetected ); typedef enum _RESOURCE_TRANSLATION_DIRECTION { TranslateChildToParent, TranslateParentToChild } RESOURCE_TRANSLATION_DIRECTION; typedef NTSTATUS (*PTRANSLATE_RESOURCE_HANDLER)( IN PVOID Context, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, IN RESOURCE_TRANSLATION_DIRECTION Direction, IN ULONG AlternativesCount, OPTIONAL IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL IN PDEVICE_OBJECT PhysicalDeviceObject, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target ); typedef NTSTATUS (*PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER)( IN PVOID Context, IN PIO_RESOURCE_DESCRIPTOR Source, IN PDEVICE_OBJECT PhysicalDeviceObject, OUT PULONG TargetCount, OUT PIO_RESOURCE_DESCRIPTOR *Target ); // // Translator Interface // typedef struct _TRANSLATOR_INTERFACE { USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; PTRANSLATE_RESOURCE_HANDLER TranslateResources; PTRANSLATE_RESOURCE_REQUIREMENTS_HANDLER TranslateResourceRequirements; } TRANSLATOR_INTERFACE, *PTRANSLATOR_INTERFACE; // // Header structure for all Plug&Play notification events... // typedef struct _PLUGPLAY_NOTIFICATION_HEADER { USHORT Version; // presently at version 1. USHORT Size; // size (in bytes) of header + event-specific data. GUID Event; // // Event-specific stuff starts here. // } PLUGPLAY_NOTIFICATION_HEADER, *PPLUGPLAY_NOTIFICATION_HEADER; // // Notification structure for all EventCategoryHardwareProfileChange events... // typedef struct _HWPROFILE_CHANGE_NOTIFICATION { USHORT Version; USHORT Size; GUID Event; // // (No event-specific data) // } HWPROFILE_CHANGE_NOTIFICATION, *PHWPROFILE_CHANGE_NOTIFICATION; // // Notification structure for all EventCategoryDeviceInterfaceChange events... // typedef struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION { USHORT Version; USHORT Size; GUID Event; // // Event-specific data // GUID InterfaceClassGuid; PUNICODE_STRING SymbolicLinkName; } DEVICE_INTERFACE_CHANGE_NOTIFICATION, *PDEVICE_INTERFACE_CHANGE_NOTIFICATION; // // Notification structures for EventCategoryTargetDeviceChange... // // // The following structure is used for TargetDeviceQueryRemove, // TargetDeviceRemoveCancelled, and TargetDeviceRemoveComplete: // typedef struct _TARGET_DEVICE_REMOVAL_NOTIFICATION { USHORT Version; USHORT Size; GUID Event; // // Event-specific data // PFILE_OBJECT FileObject; } TARGET_DEVICE_REMOVAL_NOTIFICATION, *PTARGET_DEVICE_REMOVAL_NOTIFICATION; // // The following structure header is used for all other (i.e., 3rd-party) // target device change events. The structure accommodates both a // variable-length binary data buffer, and a variable-length unicode text // buffer. The header must indicate where the text buffer begins, so that // the data can be delivered in the appropriate format (ANSI or Unicode) // to user-mode recipients (i.e., that have registered for handle-based // notification via RegisterDeviceNotification). // typedef struct _TARGET_DEVICE_CUSTOM_NOTIFICATION { USHORT Version; USHORT Size; GUID Event; // // Event-specific data // PFILE_OBJECT FileObject; // This field must be set to NULL by callers of // IoReportTargetDeviceChange. Clients that // have registered for target device change // notification on the affected PDO will be // called with this field set to the file object // they specified during registration. // LONG NameBufferOffset; // offset (in bytes) from beginning of // CustomDataBuffer where text begins (-1 if none) // UCHAR CustomDataBuffer[1]; // variable-length buffer, containing (optionally) // a binary data at the start of the buffer, // followed by an optional unicode text buffer // (word-aligned). // } TARGET_DEVICE_CUSTOM_NOTIFICATION, *PTARGET_DEVICE_CUSTOM_NOTIFICATION; ULONG IoPnPDeliverServicePowerNotification( IN POWER_ACTION PowerOperation, IN ULONG PowerNotificationCode, IN ULONG PowerNotificationData, IN BOOLEAN Synchronous ); // // Define OEM bitmapped font check values. // #define OEM_FONT_VERSION 0x200 #define OEM_FONT_TYPE 0 #define OEM_FONT_ITALIC 0 #define OEM_FONT_UNDERLINE 0 #define OEM_FONT_STRIKEOUT 0 #define OEM_FONT_CHARACTER_SET 255 #define OEM_FONT_FAMILY (3 << 4) // // Define OEM bitmapped font file header structure. // // N.B. this is a packed structure. // #include "pshpack1.h" typedef struct _OEM_FONT_FILE_HEADER { USHORT Version; ULONG FileSize; UCHAR Copyright[60]; USHORT Type; USHORT Points; USHORT VerticleResolution; USHORT HorizontalResolution; USHORT Ascent; USHORT InternalLeading; USHORT ExternalLeading; UCHAR Italic; UCHAR Underline; UCHAR StrikeOut; USHORT Weight; UCHAR CharacterSet; USHORT PixelWidth; USHORT PixelHeight; UCHAR Family; USHORT AverageWidth; USHORT MaximumWidth; UCHAR FirstCharacter; UCHAR LastCharacter; UCHAR DefaultCharacter; UCHAR BreakCharacter; USHORT WidthInBytes; ULONG Device; ULONG Face; ULONG BitsPointer; ULONG BitsOffset; UCHAR Filler; struct { USHORT Width; USHORT Offset; } Map[1]; } OEM_FONT_FILE_HEADER, *POEM_FONT_FILE_HEADER; #include "poppack.h" // // Define the device description structure. // typedef struct _DEVICE_DESCRIPTION { ULONG Version; BOOLEAN Master; BOOLEAN ScatterGather; BOOLEAN DemandMode; BOOLEAN AutoInitialize; BOOLEAN Dma32BitAddresses; BOOLEAN IgnoreCount; BOOLEAN Reserved1; // must be false BOOLEAN Dma64BitAddresses; ULONG BusNumber; // unused for WDM ULONG DmaChannel; INTERFACE_TYPE InterfaceType; DMA_WIDTH DmaWidth; DMA_SPEED DmaSpeed; ULONG MaximumLength; ULONG DmaPort; } DEVICE_DESCRIPTION, *PDEVICE_DESCRIPTION; // // Define the supported version numbers for the device description structure. // #define DEVICE_DESCRIPTION_VERSION 0 #define DEVICE_DESCRIPTION_VERSION1 1 #define DEVICE_DESCRIPTION_VERSION2 2 // end_ntddk end_wdm // // Boot record disk partition table entry structure format. // typedef struct _PARTITION_DESCRIPTOR { UCHAR ActiveFlag; // Bootable or not UCHAR StartingTrack; // Not used UCHAR StartingCylinderLsb; // Not used UCHAR StartingCylinderMsb; // Not used UCHAR PartitionType; // 12 bit FAT, 16 bit FAT etc. UCHAR EndingTrack; // Not used UCHAR EndingCylinderLsb; // Not used UCHAR EndingCylinderMsb; // Not used UCHAR StartingSectorLsb0; // Hidden sectors UCHAR StartingSectorLsb1; UCHAR StartingSectorMsb0; UCHAR StartingSectorMsb1; UCHAR PartitionLengthLsb0; // Sectors in this partition UCHAR PartitionLengthLsb1; UCHAR PartitionLengthMsb0; UCHAR PartitionLengthMsb1; } PARTITION_DESCRIPTOR, *PPARTITION_DESCRIPTOR; // // Number of partition table entries // #define NUM_PARTITION_TABLE_ENTRIES 4 // // Partition table record and boot signature offsets in 16-bit words. // #define PARTITION_TABLE_OFFSET (0x1be / 2) #define BOOT_SIGNATURE_OFFSET ((0x200 / 2) - 1) // // Boot record signature value. // #define BOOT_RECORD_SIGNATURE (0xaa55) // // Initial size of the Partition list structure. // #define PARTITION_BUFFER_SIZE 2048 // // Partition active flag - i.e., boot indicator // #define PARTITION_ACTIVE_FLAG 0x80 // // Get and set environment variable values. // NTHALAPI ARC_STATUS HalGetEnvironmentVariable ( IN PCHAR Variable, IN USHORT Length, OUT PCHAR Buffer ); NTHALAPI ARC_STATUS HalSetEnvironmentVariable ( IN PCHAR Variable, IN PCHAR Value ); NTHALAPI NTSTATUS HalGetEnvironmentVariableEx ( IN PWSTR VariableName, IN LPGUID VendorGuid, OUT PVOID Value, IN OUT PULONG ValueLength, OUT PULONG Attributes OPTIONAL ); NTSTATUS HalSetEnvironmentVariableEx ( IN PWSTR VariableName, IN LPGUID VendorGuid, IN PVOID Value, IN ULONG ValueLength, IN ULONG Attributes ); NTSTATUS HalEnumerateEnvironmentVariablesEx ( IN ULONG InformationClass, OUT PVOID Buffer, IN OUT PULONG BufferLength ); #if defined(_ALPHA_) || defined(_IA64_) NTHALAPI VOID HalFlushIoBuffers ( IN PMDL Mdl, IN BOOLEAN ReadOperation, IN BOOLEAN DmaOperation ); // begin_ntddk begin_ntifs begin_ntndis DECLSPEC_DEPRECATED_DDK // Use GetDmaRequirement NTHALAPI ULONG HalGetDmaAlignmentRequirement ( VOID ); #endif #if defined(_M_IX86) || defined(_M_AMD64) #define HalGetDmaAlignmentRequirement() 1L #endif NTHALAPI // ntddk ntifs wdm ntndis VOID // ntddk ntifs wdm ntndis KeFlushWriteBuffer ( // ntddk ntifs wdm ntndis VOID // ntddk ntifs wdm ntndis ); // ntddk ntifs wdm ntndis // ntddk ntifs wdm ntndis #if defined(_ALPHA_) NTHALAPI PVOID HalCreateQva( IN PHYSICAL_ADDRESS PhysicalAddress, IN PVOID VirtualAddress ); NTHALAPI PVOID HalDereferenceQva( PVOID Qva, INTERFACE_TYPE InterfaceType, ULONG BusNumber ); #endif #if !defined(_X86_) NTHALAPI BOOLEAN HalCallBios ( IN ULONG BiosCommand, IN OUT PULONG Eax, IN OUT PULONG Ebx, IN OUT PULONG Ecx, IN OUT PULONG Edx, IN OUT PULONG Esi, IN OUT PULONG Edi, IN OUT PULONG Ebp ); #endif NTHALAPI BOOLEAN HalQueryRealTimeClock ( OUT PTIME_FIELDS TimeFields ); // // Firmware interface functions. // NTHALAPI VOID HalReturnToFirmware ( IN FIRMWARE_REENTRY Routine ); // // System interrupts functions. // NTHALAPI VOID HalDisableSystemInterrupt ( IN ULONG Vector, IN KIRQL Irql ); NTHALAPI BOOLEAN HalEnableSystemInterrupt ( IN ULONG Vector, IN KIRQL Irql, IN KINTERRUPT_MODE InterruptMode ); // begin_ntddk // // I/O driver configuration functions. // #if !defined(NO_LEGACY_DRIVERS) DECLSPEC_DEPRECATED_DDK // Use Pnp or IoReportDetectedDevice NTHALAPI NTSTATUS HalAssignSlotResources ( IN PUNICODE_STRING RegistryPath, IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN ULONG SlotNumber, IN OUT PCM_RESOURCE_LIST *AllocatedResources ); DECLSPEC_DEPRECATED_DDK // Use Pnp or IoReportDetectedDevice NTHALAPI ULONG HalGetInterruptVector( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN ULONG BusInterruptLevel, IN ULONG BusInterruptVector, OUT PKIRQL Irql, OUT PKAFFINITY Affinity ); DECLSPEC_DEPRECATED_DDK // Use IRP_MN_QUERY_INTERFACE and IRP_MN_READ_CONFIG NTHALAPI ULONG HalSetBusData( IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length ); #endif // NO_LEGACY_DRIVERS DECLSPEC_DEPRECATED_DDK // Use IRP_MN_QUERY_INTERFACE and IRP_MN_READ_CONFIG NTHALAPI ULONG HalSetBusDataByOffset( IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ); DECLSPEC_DEPRECATED_DDK // Use IRP_MN_QUERY_INTERFACE and IRP_MN_READ_CONFIG NTHALAPI BOOLEAN HalTranslateBusAddress( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress ); // // Values for AddressSpace parameter of HalTranslateBusAddress // // 0x0 - Memory space // 0x1 - Port space // 0x2 - 0x1F - Address spaces specific for Alpha // 0x2 - UserMode view of memory space // 0x3 - UserMode view of port space // 0x4 - Dense memory space // 0x5 - reserved // 0x6 - UserMode view of dense memory space // 0x7 - 0x1F - reserved // NTHALAPI PVOID HalAllocateCrashDumpRegisters( IN PADAPTER_OBJECT AdapterObject, IN OUT PULONG NumberOfMapRegisters ); #if !defined(NO_LEGACY_DRIVERS) DECLSPEC_DEPRECATED_DDK // Use IRP_MN_QUERY_INTERFACE and IRP_MN_READ_CONFIG NTHALAPI ULONG HalGetBusData( IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length ); #endif // NO_LEGACY_DRIVERS DECLSPEC_DEPRECATED_DDK // Use IRP_MN_QUERY_INTERFACE and IRP_MN_READ_CONFIG NTHALAPI ULONG HalGetBusDataByOffset( IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ); DECLSPEC_DEPRECATED_DDK // Use IoGetDmaAdapter NTHALAPI PADAPTER_OBJECT HalGetAdapter( IN PDEVICE_DESCRIPTION DeviceDescription, IN OUT PULONG NumberOfMapRegisters ); // // System beep functions. // #if !defined(NO_LEGACY_DRIVERS) NTHALAPI BOOLEAN HalMakeBeep( IN ULONG Frequency ); #endif // NO_LEGACY_DRIVERS // // The following function prototypes are for HAL routines with a prefix of Io. // // DMA adapter object functions. // // // Performance counter function. // NTHALAPI LARGE_INTEGER KeQueryPerformanceCounter ( OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL ); // begin_ntndis // // Stall processor execution function. // NTHALAPI VOID KeStallExecutionProcessor ( IN ULONG MicroSeconds ); typedef PBUS_HANDLER (FASTCALL *pHalHandlerForBus) ( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber ); typedef VOID (FASTCALL *pHalReferenceBusHandler) ( IN PBUS_HANDLER BusHandler ); //***************************************************************************** // HAL Function dispatch // typedef enum _HAL_QUERY_INFORMATION_CLASS { HalInstalledBusInformation, HalProfileSourceInformation, HalInformationClassUnused1, HalPowerInformation, HalProcessorSpeedInformation, HalCallbackInformation, HalMapRegisterInformation, HalMcaLogInformation, // Machine Check Abort Information HalFrameBufferCachingInformation, HalDisplayBiosInformation, HalProcessorFeatureInformation, HalNumaTopologyInterface, HalErrorInformation, // General MCA, CMC, CPE Error Information. HalCmcLogInformation, // Processor Corrected Machine Check Information HalCpeLogInformation, // Corrected Platform Error Information HalQueryMcaInterface, HalQueryAMLIIllegalIOPortAddresses, HalQueryMaxHotPlugMemoryAddress, HalPartitionIpiInterface, HalPlatformInformation // information levels >= 0x8000000 reserved for OEM use } HAL_QUERY_INFORMATION_CLASS, *PHAL_QUERY_INFORMATION_CLASS; typedef enum _HAL_SET_INFORMATION_CLASS { HalProfileSourceInterval, HalProfileSourceInterruptHandler, HalMcaRegisterDriver, // Registring Machine Check Abort driver HalKernelErrorHandler, HalCmcRegisterDriver, // Registring Processor Corrected Machine Check driver HalCpeRegisterDriver, // Registring Corrected Platform Error driver HalMcaLog, HalCmcLog, HalCpeLog, } HAL_SET_INFORMATION_CLASS, *PHAL_SET_INFORMATION_CLASS; typedef NTSTATUS (*pHalQuerySystemInformation)( IN HAL_QUERY_INFORMATION_CLASS InformationClass, IN ULONG BufferSize, IN OUT PVOID Buffer, OUT PULONG ReturnedLength ); NTSTATUS HaliQuerySystemInformation( IN HAL_SET_INFORMATION_CLASS InformationClass, IN ULONG BufferSize, IN OUT PVOID Buffer, OUT PULONG ReturnedLength ); NTSTATUS HaliHandlePCIConfigSpaceAccess( IN BOOLEAN Read, IN ULONG Addr, IN ULONG Size, IN OUT PULONG pData ); typedef NTSTATUS (*pHalSetSystemInformation)( IN HAL_SET_INFORMATION_CLASS InformationClass, IN ULONG BufferSize, IN PVOID Buffer ); NTSTATUS HaliSetSystemInformation( IN HAL_SET_INFORMATION_CLASS InformationClass, IN ULONG BufferSize, IN PVOID Buffer ); typedef VOID (FASTCALL *pHalExamineMBR)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MBRTypeIdentifier, OUT PVOID *Buffer ); typedef VOID (FASTCALL *pHalIoAssignDriveLetters)( IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, IN PSTRING NtDeviceName, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString ); typedef NTSTATUS (FASTCALL *pHalIoReadPartitionTable)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer ); typedef NTSTATUS (FASTCALL *pHalIoSetPartitionInformation)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType ); typedef NTSTATUS (FASTCALL *pHalIoWritePartitionTable)( IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer ); typedef NTSTATUS (*pHalQueryBusSlots)( IN PBUS_HANDLER BusHandler, IN ULONG BufferSize, OUT PULONG SlotNumbers, OUT PULONG ReturnedLength ); typedef NTSTATUS (*pHalInitPnpDriver)( VOID ); NTSTATUS HaliInitPnpDriver( VOID ); typedef struct _PM_DISPATCH_TABLE { ULONG Signature; ULONG Version; PVOID Function[1]; } PM_DISPATCH_TABLE, *PPM_DISPATCH_TABLE; typedef NTSTATUS (*pHalInitPowerManagement)( IN PPM_DISPATCH_TABLE PmDriverDispatchTable, OUT PPM_DISPATCH_TABLE *PmHalDispatchTable ); NTSTATUS HaliInitPowerManagement( IN PPM_DISPATCH_TABLE PmDriverDispatchTable, IN OUT PPM_DISPATCH_TABLE *PmHalDispatchTable ); typedef struct _DMA_ADAPTER * (*pHalGetDmaAdapter)( IN PVOID Context, IN struct _DEVICE_DESCRIPTION *DeviceDescriptor, OUT PULONG NumberOfMapRegisters ); struct _DMA_ADAPTER * HaliGetDmaAdapter( IN PVOID Context, IN struct _DEVICE_DESCRIPTION *DeviceDescriptor, OUT PULONG NumberOfMapRegisters ); typedef NTSTATUS (*pHalGetInterruptTranslator)( IN INTERFACE_TYPE ParentInterfaceType, IN ULONG ParentBusNumber, IN INTERFACE_TYPE BridgeInterfaceType, IN USHORT Size, IN USHORT Version, OUT PTRANSLATOR_INTERFACE Translator, OUT PULONG BridgeBusNumber ); NTSTATUS HaliGetInterruptTranslator( IN INTERFACE_TYPE ParentInterfaceType, IN ULONG ParentBusNumber, IN INTERFACE_TYPE BridgeInterfaceType, IN USHORT Size, IN USHORT Version, OUT PTRANSLATOR_INTERFACE Translator, OUT PULONG BridgeBusNumber ); typedef BOOLEAN (*pHalTranslateBusAddress)( IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress ); typedef NTSTATUS (*pHalAssignSlotResources) ( IN PUNICODE_STRING RegistryPath, IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN ULONG SlotNumber, IN OUT PCM_RESOURCE_LIST *AllocatedResources ); typedef VOID (*pHalHaltSystem) ( VOID ); typedef VOID (*pHalResetDisplay) ( VOID ); typedef UCHAR (*pHalVectorToIDTEntry) ( ULONG Vector ); typedef BOOLEAN (*pHalFindBusAddressTranslation) ( IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress, IN OUT PULONG_PTR Context, IN BOOLEAN NextBus ); typedef NTSTATUS (*pHalStartMirroring)( VOID ); typedef NTSTATUS (*pHalEndMirroring)( IN ULONG PassNumber ); typedef NTSTATUS (*pHalMirrorPhysicalMemory)( IN PHYSICAL_ADDRESS PhysicalAddress, IN LARGE_INTEGER NumberOfBytes ); typedef NTSTATUS (*pHalMirrorVerify)( IN PHYSICAL_ADDRESS PhysicalAddress, IN LARGE_INTEGER NumberOfBytes ); typedef struct { UCHAR Type; //CmResourceType BOOLEAN Valid; UCHAR Reserved[2]; PUCHAR TranslatedAddress; ULONG Length; } DEBUG_DEVICE_ADDRESS, *PDEBUG_DEVICE_ADDRESS; typedef struct { PHYSICAL_ADDRESS Start; PHYSICAL_ADDRESS MaxEnd; PVOID VirtualAddress; ULONG Length; BOOLEAN Cached; BOOLEAN Aligned; } DEBUG_MEMORY_REQUIREMENTS, *PDEBUG_MEMORY_REQUIREMENTS; typedef struct { ULONG Bus; ULONG Slot; USHORT VendorID; USHORT DeviceID; UCHAR BaseClass; UCHAR SubClass; UCHAR ProgIf; BOOLEAN Initialized; DEBUG_DEVICE_ADDRESS BaseAddress[6]; DEBUG_MEMORY_REQUIREMENTS Memory; } DEBUG_DEVICE_DESCRIPTOR, *PDEBUG_DEVICE_DESCRIPTOR; typedef NTSTATUS (*pKdSetupPciDeviceForDebugging)( IN PVOID LoaderBlock, OPTIONAL IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice ); typedef NTSTATUS (*pKdReleasePciDeviceForDebugging)( IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice ); typedef PVOID (*pKdGetAcpiTablePhase0)( IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, IN ULONG Signature ); typedef VOID (*pKdCheckPowerButton)( VOID ); typedef VOID (*pHalEndOfBoot)( VOID ); typedef PVOID (*pKdMapPhysicalMemory64)( IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG NumberPages ); typedef VOID (*pKdUnmapVirtualAddress)( IN PVOID VirtualAddress, IN ULONG NumberPages ); typedef struct { ULONG Version; pHalQuerySystemInformation HalQuerySystemInformation; pHalSetSystemInformation HalSetSystemInformation; pHalQueryBusSlots HalQueryBusSlots; ULONG Spare1; pHalExamineMBR HalExamineMBR; pHalIoAssignDriveLetters HalIoAssignDriveLetters; pHalIoReadPartitionTable HalIoReadPartitionTable; pHalIoSetPartitionInformation HalIoSetPartitionInformation; pHalIoWritePartitionTable HalIoWritePartitionTable; pHalHandlerForBus HalReferenceHandlerForBus; pHalReferenceBusHandler HalReferenceBusHandler; pHalReferenceBusHandler HalDereferenceBusHandler; pHalInitPnpDriver HalInitPnpDriver; pHalInitPowerManagement HalInitPowerManagement; pHalGetDmaAdapter HalGetDmaAdapter; pHalGetInterruptTranslator HalGetInterruptTranslator; pHalStartMirroring HalStartMirroring; pHalEndMirroring HalEndMirroring; pHalMirrorPhysicalMemory HalMirrorPhysicalMemory; pHalEndOfBoot HalEndOfBoot; pHalMirrorVerify HalMirrorVerify; } HAL_DISPATCH, *PHAL_DISPATCH; #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) extern PHAL_DISPATCH HalDispatchTable; #define HALDISPATCH HalDispatchTable #else extern HAL_DISPATCH HalDispatchTable; #define HALDISPATCH (&HalDispatchTable) #endif #define HAL_DISPATCH_VERSION 3 #define HalDispatchTableVersion HALDISPATCH->Version #define HalQuerySystemInformation HALDISPATCH->HalQuerySystemInformation #define HalSetSystemInformation HALDISPATCH->HalSetSystemInformation #define HalQueryBusSlots HALDISPATCH->HalQueryBusSlots #define HalReferenceHandlerForBus HALDISPATCH->HalReferenceHandlerForBus #define HalReferenceBusHandler HALDISPATCH->HalReferenceBusHandler #define HalDereferenceBusHandler HALDISPATCH->HalDereferenceBusHandler #define HalInitPnpDriver HALDISPATCH->HalInitPnpDriver #define HalInitPowerManagement HALDISPATCH->HalInitPowerManagement #define HalGetDmaAdapter HALDISPATCH->HalGetDmaAdapter #define HalGetInterruptTranslator HALDISPATCH->HalGetInterruptTranslator #define HalStartMirroring HALDISPATCH->HalStartMirroring #define HalEndMirroring HALDISPATCH->HalEndMirroring #define HalMirrorPhysicalMemory HALDISPATCH->HalMirrorPhysicalMemory #define HalEndOfBoot HALDISPATCH->HalEndOfBoot #define HalMirrorVerify HALDISPATCH->HalMirrorVerify // // HAL System Information Structures. // // for the information class "HalInstalledBusInformation" typedef struct _HAL_BUS_INFORMATION{ INTERFACE_TYPE BusType; BUS_DATA_TYPE ConfigurationType; ULONG BusNumber; ULONG Reserved; } HAL_BUS_INFORMATION, *PHAL_BUS_INFORMATION; // for the information class "HalProfileSourceInformation" typedef struct _HAL_PROFILE_SOURCE_INFORMATION { KPROFILE_SOURCE Source; BOOLEAN Supported; ULONG Interval; } HAL_PROFILE_SOURCE_INFORMATION, *PHAL_PROFILE_SOURCE_INFORMATION; typedef struct _HAL_PROFILE_SOURCE_INFORMATION_EX { KPROFILE_SOURCE Source; BOOLEAN Supported; ULONG_PTR Interval; ULONG_PTR DefInterval; ULONG_PTR MaxInterval; ULONG_PTR MinInterval; } HAL_PROFILE_SOURCE_INFORMATION_EX, *PHAL_PROFILE_SOURCE_INFORMATION_EX; // for the information class "HalProfileSourceInterval" typedef struct _HAL_PROFILE_SOURCE_INTERVAL { KPROFILE_SOURCE Source; ULONG_PTR Interval; } HAL_PROFILE_SOURCE_INTERVAL, *PHAL_PROFILE_SOURCE_INTERVAL; // for the information class "HalDispayBiosInformation" typedef enum _HAL_DISPLAY_BIOS_INFORMATION { HalDisplayInt10Bios, HalDisplayEmulatedBios, HalDisplayNoBios } HAL_DISPLAY_BIOS_INFORMATION, *PHAL_DISPLAY_BIOS_INFORMATION; // for the information class "HalPowerInformation" typedef struct _HAL_POWER_INFORMATION { ULONG TBD; } HAL_POWER_INFORMATION, *PHAL_POWER_INFORMATION; // for the information class "HalProcessorSpeedInformation" typedef struct _HAL_PROCESSOR_SPEED_INFO { ULONG ProcessorSpeed; } HAL_PROCESSOR_SPEED_INFORMATION, *PHAL_PROCESSOR_SPEED_INFORMATION; // for the information class "HalCallbackInformation" typedef struct _HAL_CALLBACKS { PCALLBACK_OBJECT SetSystemInformation; PCALLBACK_OBJECT BusCheck; } HAL_CALLBACKS, *PHAL_CALLBACKS; // for the information class "HalProcessorFeatureInformation" typedef struct _HAL_PROCESSOR_FEATURE { ULONG UsableFeatureBits; } HAL_PROCESSOR_FEATURE; // for the information class "HalNumaTopologyInterface" typedef ULONG HALNUMAPAGETONODE; typedef HALNUMAPAGETONODE (*PHALNUMAPAGETONODE)( IN ULONG_PTR PhysicalPageNumber ); typedef NTSTATUS (*PHALNUMAQUERYPROCESSORNODE)( IN ULONG ProcessorNumber, OUT PUSHORT Identifier, OUT PUCHAR Node ); typedef struct _HAL_NUMA_TOPOLOGY_INTERFACE { ULONG NumberOfNodes; PHALNUMAQUERYPROCESSORNODE QueryProcessorNode; PHALNUMAPAGETONODE PageToNode; } HAL_NUMA_TOPOLOGY_INTERFACE; typedef NTSTATUS (*PHALIOREADWRITEHANDLER)( IN BOOLEAN fRead, IN ULONG dwAddr, IN ULONG dwSize, IN OUT PULONG pdwData ); // for the information class "HalQueryIllegalIOPortAddresses" typedef struct _HAL_AMLI_BAD_IO_ADDRESS_LIST { ULONG BadAddrBegin; ULONG BadAddrSize; ULONG OSVersionTrigger; PHALIOREADWRITEHANDLER IOHandler; } HAL_AMLI_BAD_IO_ADDRESS_LIST, *PHAL_AMLI_BAD_IO_ADDRESS_LIST; typedef struct _SCATTER_GATHER_ELEMENT { PHYSICAL_ADDRESS Address; ULONG Length; ULONG_PTR Reserved; } SCATTER_GATHER_ELEMENT, *PSCATTER_GATHER_ELEMENT; #pragma warning(disable:4200) typedef struct _SCATTER_GATHER_LIST { ULONG NumberOfElements; ULONG_PTR Reserved; SCATTER_GATHER_ELEMENT Elements[]; } SCATTER_GATHER_LIST, *PSCATTER_GATHER_LIST; #pragma warning(default:4200) // end_ntndis typedef struct _DMA_OPERATIONS *PDMA_OPERATIONS; typedef struct _DMA_ADAPTER { USHORT Version; USHORT Size; PDMA_OPERATIONS DmaOperations; // Private Bus Device Driver data follows, } DMA_ADAPTER, *PDMA_ADAPTER; typedef VOID (*PPUT_DMA_ADAPTER)( PDMA_ADAPTER DmaAdapter ); typedef PVOID (*PALLOCATE_COMMON_BUFFER)( IN PDMA_ADAPTER DmaAdapter, IN ULONG Length, OUT PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled ); typedef VOID (*PFREE_COMMON_BUFFER)( IN PDMA_ADAPTER DmaAdapter, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled ); typedef NTSTATUS (*PALLOCATE_ADAPTER_CHANNEL)( IN PDMA_ADAPTER DmaAdapter, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context ); typedef BOOLEAN (*PFLUSH_ADAPTER_BUFFERS)( IN PDMA_ADAPTER DmaAdapter, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice ); typedef VOID (*PFREE_ADAPTER_CHANNEL)( IN PDMA_ADAPTER DmaAdapter ); typedef VOID (*PFREE_MAP_REGISTERS)( IN PDMA_ADAPTER DmaAdapter, PVOID MapRegisterBase, ULONG NumberOfMapRegisters ); typedef PHYSICAL_ADDRESS (*PMAP_TRANSFER)( IN PDMA_ADAPTER DmaAdapter, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice ); typedef ULONG (*PGET_DMA_ALIGNMENT)( IN PDMA_ADAPTER DmaAdapter ); typedef ULONG (*PREAD_DMA_COUNTER)( IN PDMA_ADAPTER DmaAdapter ); typedef VOID (*PDRIVER_LIST_CONTROL)( IN struct _DEVICE_OBJECT *DeviceObject, IN struct _IRP *Irp, IN PSCATTER_GATHER_LIST ScatterGather, IN PVOID Context ); typedef NTSTATUS (*PGET_SCATTER_GATHER_LIST)( IN PDMA_ADAPTER DmaAdapter, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice ); typedef VOID (*PPUT_SCATTER_GATHER_LIST)( IN PDMA_ADAPTER DmaAdapter, IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice ); typedef NTSTATUS (*PCALCULATE_SCATTER_GATHER_LIST_SIZE)( IN PDMA_ADAPTER DmaAdapter, IN OPTIONAL PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, OUT PULONG ScatterGatherListSize, OUT OPTIONAL PULONG pNumberOfMapRegisters ); typedef NTSTATUS (*PBUILD_SCATTER_GATHER_LIST)( IN PDMA_ADAPTER DmaAdapter, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice, IN PVOID ScatterGatherBuffer, IN ULONG ScatterGatherLength ); typedef NTSTATUS (*PBUILD_MDL_FROM_SCATTER_GATHER_LIST)( IN PDMA_ADAPTER DmaAdapter, IN PSCATTER_GATHER_LIST ScatterGather, IN PMDL OriginalMdl, OUT PMDL *TargetMdl ); typedef struct _DMA_OPERATIONS { ULONG Size; PPUT_DMA_ADAPTER PutDmaAdapter; PALLOCATE_COMMON_BUFFER AllocateCommonBuffer; PFREE_COMMON_BUFFER FreeCommonBuffer; PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel; PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers; PFREE_ADAPTER_CHANNEL FreeAdapterChannel; PFREE_MAP_REGISTERS FreeMapRegisters; PMAP_TRANSFER MapTransfer; PGET_DMA_ALIGNMENT GetDmaAlignment; PREAD_DMA_COUNTER ReadDmaCounter; PGET_SCATTER_GATHER_LIST GetScatterGatherList; PPUT_SCATTER_GATHER_LIST PutScatterGatherList; PCALCULATE_SCATTER_GATHER_LIST_SIZE CalculateScatterGatherList; PBUILD_SCATTER_GATHER_LIST BuildScatterGatherList; PBUILD_MDL_FROM_SCATTER_GATHER_LIST BuildMdlFromScatterGatherList; } DMA_OPERATIONS; // end_wdm #if defined(_WIN64) // // Use __inline DMA macros (hal.h) // #ifndef USE_DMA_MACROS #define USE_DMA_MACROS #endif // // Only PnP drivers! // #ifndef NO_LEGACY_DRIVERS #define NO_LEGACY_DRIVERS #endif #endif // _WIN64 #if defined(USE_DMA_MACROS) && (defined(_NTDDK_) || defined(_NTDRIVER_)) // begin_wdm DECLSPEC_DEPRECATED_DDK // Use AllocateCommonBuffer FORCEINLINE PVOID HalAllocateCommonBuffer( IN PDMA_ADAPTER DmaAdapter, IN ULONG Length, OUT PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled ){ PALLOCATE_COMMON_BUFFER allocateCommonBuffer; PVOID commonBuffer; allocateCommonBuffer = *(DmaAdapter)->DmaOperations->AllocateCommonBuffer; ASSERT( allocateCommonBuffer != NULL ); commonBuffer = allocateCommonBuffer( DmaAdapter, Length, LogicalAddress, CacheEnabled ); return commonBuffer; } DECLSPEC_DEPRECATED_DDK // Use FreeCommonBuffer FORCEINLINE VOID HalFreeCommonBuffer( IN PDMA_ADAPTER DmaAdapter, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled ){ PFREE_COMMON_BUFFER freeCommonBuffer; freeCommonBuffer = *(DmaAdapter)->DmaOperations->FreeCommonBuffer; ASSERT( freeCommonBuffer != NULL ); freeCommonBuffer( DmaAdapter, Length, LogicalAddress, VirtualAddress, CacheEnabled ); } DECLSPEC_DEPRECATED_DDK // Use AllocateAdapterChannel FORCEINLINE NTSTATUS IoAllocateAdapterChannel( IN PDMA_ADAPTER DmaAdapter, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context ){ PALLOCATE_ADAPTER_CHANNEL allocateAdapterChannel; NTSTATUS status; allocateAdapterChannel = *(DmaAdapter)->DmaOperations->AllocateAdapterChannel; ASSERT( allocateAdapterChannel != NULL ); status = allocateAdapterChannel( DmaAdapter, DeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context ); return status; } DECLSPEC_DEPRECATED_DDK // Use FlushAdapterBuffers FORCEINLINE BOOLEAN IoFlushAdapterBuffers( IN PDMA_ADAPTER DmaAdapter, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice ){ PFLUSH_ADAPTER_BUFFERS flushAdapterBuffers; BOOLEAN result; flushAdapterBuffers = *(DmaAdapter)->DmaOperations->FlushAdapterBuffers; ASSERT( flushAdapterBuffers != NULL ); result = flushAdapterBuffers( DmaAdapter, Mdl, MapRegisterBase, CurrentVa, Length, WriteToDevice ); return result; } DECLSPEC_DEPRECATED_DDK // Use FreeAdapterChannel FORCEINLINE VOID IoFreeAdapterChannel( IN PDMA_ADAPTER DmaAdapter ){ PFREE_ADAPTER_CHANNEL freeAdapterChannel; freeAdapterChannel = *(DmaAdapter)->DmaOperations->FreeAdapterChannel; ASSERT( freeAdapterChannel != NULL ); freeAdapterChannel( DmaAdapter ); } DECLSPEC_DEPRECATED_DDK // Use FreeMapRegisters FORCEINLINE VOID IoFreeMapRegisters( IN PDMA_ADAPTER DmaAdapter, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters ){ PFREE_MAP_REGISTERS freeMapRegisters; freeMapRegisters = *(DmaAdapter)->DmaOperations->FreeMapRegisters; ASSERT( freeMapRegisters != NULL ); freeMapRegisters( DmaAdapter, MapRegisterBase, NumberOfMapRegisters ); } DECLSPEC_DEPRECATED_DDK // Use MapTransfer FORCEINLINE PHYSICAL_ADDRESS IoMapTransfer( IN PDMA_ADAPTER DmaAdapter, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice ){ PHYSICAL_ADDRESS physicalAddress; PMAP_TRANSFER mapTransfer; mapTransfer = *(DmaAdapter)->DmaOperations->MapTransfer; ASSERT( mapTransfer != NULL ); physicalAddress = mapTransfer( DmaAdapter, Mdl, MapRegisterBase, CurrentVa, Length, WriteToDevice ); return physicalAddress; } DECLSPEC_DEPRECATED_DDK // Use GetDmaAlignment FORCEINLINE ULONG HalGetDmaAlignment( IN PDMA_ADAPTER DmaAdapter ) { PGET_DMA_ALIGNMENT getDmaAlignment; ULONG alignment; getDmaAlignment = *(DmaAdapter)->DmaOperations->GetDmaAlignment; ASSERT( getDmaAlignment != NULL ); alignment = getDmaAlignment( DmaAdapter ); return alignment; } DECLSPEC_DEPRECATED_DDK // Use ReadDmaCounter FORCEINLINE ULONG HalReadDmaCounter( IN PDMA_ADAPTER DmaAdapter ) { PREAD_DMA_COUNTER readDmaCounter; ULONG counter; readDmaCounter = *(DmaAdapter)->DmaOperations->ReadDmaCounter; ASSERT( readDmaCounter != NULL ); counter = readDmaCounter( DmaAdapter ); return counter; } // end_wdm #else // // DMA adapter object functions. // NTHALAPI NTSTATUS HalAllocateAdapterChannel( IN PADAPTER_OBJECT AdapterObject, IN PWAIT_CONTEXT_BLOCK Wcb, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine ); DECLSPEC_DEPRECATED_DDK // Use AllocateCommonBuffer NTHALAPI PVOID HalAllocateCommonBuffer( IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, OUT PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled ); DECLSPEC_DEPRECATED_DDK // Use FreeCommonBuffer NTHALAPI VOID HalFreeCommonBuffer( IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled ); DECLSPEC_DEPRECATED_DDK // Use ReadDmaCounter NTHALAPI ULONG HalReadDmaCounter( IN PADAPTER_OBJECT AdapterObject ); DECLSPEC_DEPRECATED_DDK // Use FlushAdapterBuffers NTHALAPI BOOLEAN IoFlushAdapterBuffers( IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice ); DECLSPEC_DEPRECATED_DDK // Use FreeAdapterChannel NTHALAPI VOID IoFreeAdapterChannel( IN PADAPTER_OBJECT AdapterObject ); DECLSPEC_DEPRECATED_DDK // Use FreeMapRegisters NTHALAPI VOID IoFreeMapRegisters( IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters ); DECLSPEC_DEPRECATED_DDK // Use MapTransfer NTHALAPI PHYSICAL_ADDRESS IoMapTransfer( IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice ); #endif // USE_DMA_MACROS && (_NTDDK_ || _NTDRIVER_) NTSTATUS HalGetScatterGatherList ( IN PADAPTER_OBJECT DmaAdapter, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice ); VOID HalPutScatterGatherList ( IN PADAPTER_OBJECT DmaAdapter, IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice ); VOID HalPutDmaAdapter( IN PADAPTER_OBJECT DmaAdapter ); // // Define maximum disk transfer size to be used by MM and Cache Manager, // so that packet-oriented disk drivers can optimize their packet allocation // to this size. // #define MM_MAXIMUM_DISK_IO_SIZE (0x10000) //++ // // ULONG_PTR // ROUND_TO_PAGES ( // IN ULONG_PTR Size // ) // // Routine Description: // // The ROUND_TO_PAGES macro takes a size in bytes and rounds it up to a // multiple of the page size. // // NOTE: This macro fails for values 0xFFFFFFFF - (PAGE_SIZE - 1). // // Arguments: // // Size - Size in bytes to round up to a page multiple. // // Return Value: // // Returns the size rounded up to a multiple of the page size. // //-- #define ROUND_TO_PAGES(Size) (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) //++ // // ULONG // BYTES_TO_PAGES ( // IN ULONG Size // ) // // Routine Description: // // The BYTES_TO_PAGES macro takes the size in bytes and calculates the // number of pages required to contain the bytes. // // Arguments: // // Size - Size in bytes. // // Return Value: // // Returns the number of pages required to contain the specified size. // //-- #define BYTES_TO_PAGES(Size) ((ULONG)((ULONG_PTR)(Size) >> PAGE_SHIFT) + \ (((ULONG)(Size) & (PAGE_SIZE - 1)) != 0)) //++ // // ULONG // BYTE_OFFSET ( // IN PVOID Va // ) // // Routine Description: // // The BYTE_OFFSET macro takes a virtual address and returns the byte offset // of that address within the page. // // Arguments: // // Va - Virtual address. // // Return Value: // // Returns the byte offset portion of the virtual address. // //-- #define BYTE_OFFSET(Va) ((ULONG)((LONG_PTR)(Va) & (PAGE_SIZE - 1))) //++ // // PVOID // PAGE_ALIGN ( // IN PVOID Va // ) // // Routine Description: // // The PAGE_ALIGN macro takes a virtual address and returns a page-aligned // virtual address for that page. // // Arguments: // // Va - Virtual address. // // Return Value: // // Returns the page aligned virtual address. // //-- #define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) //++ // // ULONG // ADDRESS_AND_SIZE_TO_SPAN_PAGES ( // IN PVOID Va, // IN ULONG Size // ) // // Routine Description: // // The ADDRESS_AND_SIZE_TO_SPAN_PAGES macro takes a virtual address and // size and returns the number of pages spanned by the size. // // Arguments: // // Va - Virtual address. // // Size - Size in bytes. // // Return Value: // // Returns the number of pages spanned by the size. // //-- #define ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va,Size) \ ((ULONG)((((ULONG_PTR)(Va) & (PAGE_SIZE -1)) + (Size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) #if PRAGMA_DEPRECATED_DDK #pragma deprecated(COMPUTE_PAGES_SPANNED) // Use ADDRESS_AND_SIZE_TO_SPAN_PAGES #endif #define COMPUTE_PAGES_SPANNED(Va, Size) ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va,Size) #define IS_SYSTEM_ADDRESS(VA) ((VA) >= MM_SYSTEM_RANGE_START) //++ // PPFN_NUMBER // MmGetMdlPfnArray ( // IN PMDL Mdl // ) // // Routine Description: // // The MmGetMdlPfnArray routine returns the virtual address of the // first element of the array of physical page numbers associated with // the MDL. // // Arguments: // // Mdl - Pointer to an MDL. // // Return Value: // // Returns the virtual address of the first element of the array of // physical page numbers associated with the MDL. // //-- #define MmGetMdlPfnArray(Mdl) ((PPFN_NUMBER)(Mdl + 1)) //++ // // PVOID // MmGetMdlVirtualAddress ( // IN PMDL Mdl // ) // // Routine Description: // // The MmGetMdlVirtualAddress returns the virtual address of the buffer // described by the Mdl. // // Arguments: // // Mdl - Pointer to an MDL. // // Return Value: // // Returns the virtual address of the buffer described by the Mdl // //-- #define MmGetMdlVirtualAddress(Mdl) \ ((PVOID) ((PCHAR) ((Mdl)->StartVa) + (Mdl)->ByteOffset)) //++ // // ULONG // MmGetMdlByteCount ( // IN PMDL Mdl // ) // // Routine Description: // // The MmGetMdlByteCount returns the length in bytes of the buffer // described by the Mdl. // // Arguments: // // Mdl - Pointer to an MDL. // // Return Value: // // Returns the byte count of the buffer described by the Mdl // //-- #define MmGetMdlByteCount(Mdl) ((Mdl)->ByteCount) //++ // // ULONG // MmGetMdlByteOffset ( // IN PMDL Mdl // ) // // Routine Description: // // The MmGetMdlByteOffset returns the byte offset within the page // of the buffer described by the Mdl. // // Arguments: // // Mdl - Pointer to an MDL. // // Return Value: // // Returns the byte offset within the page of the buffer described by the Mdl // //-- #define MmGetMdlByteOffset(Mdl) ((Mdl)->ByteOffset) //++ // // PVOID // MmGetMdlStartVa ( // IN PMDL Mdl // ) // // Routine Description: // // The MmGetMdlBaseVa returns the virtual address of the buffer // described by the Mdl rounded down to the nearest page. // // Arguments: // // Mdl - Pointer to an MDL. // // Return Value: // // Returns the returns the starting virtual address of the MDL. // // //-- #define MmGetMdlBaseVa(Mdl) ((Mdl)->StartVa) typedef enum _MM_SYSTEM_SIZE { MmSmallSystem, MmMediumSystem, MmLargeSystem } MM_SYSTEMSIZE; NTKERNELAPI MM_SYSTEMSIZE MmQuerySystemSize( VOID ); // end_wdm NTKERNELAPI BOOLEAN MmIsThisAnNtAsSystem( VOID ); // begin_wdm typedef enum _LOCK_OPERATION { IoReadAccess, IoWriteAccess, IoModifyAccess } LOCK_OPERATION; NTKERNELAPI NTSTATUS MmGrowKernelStack ( IN PVOID CurrentStack ); NTKERNELAPI NTSTATUS MmAdjustWorkingSetSize ( IN SIZE_T WorkingSetMinimum, IN SIZE_T WorkingSetMaximum, IN ULONG SystemCache, IN BOOLEAN IncreaseOkay ); NTKERNELAPI NTSTATUS MmCreateSection ( OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT File OPTIONAL ); NTKERNELAPI NTSTATUS MmMapViewOfSection( IN PVOID SectionToMap, IN PEPROCESS Process, IN OUT PVOID *CapturedBase, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset, IN OUT PSIZE_T CapturedViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect ); NTKERNELAPI NTSTATUS MmUnmapViewOfSection( IN PEPROCESS Process, IN PVOID BaseAddress ); NTSTATUS MmIsVerifierEnabled ( OUT PULONG VerifierFlags ); NTSTATUS MmAddVerifierThunks ( IN PVOID ThunkBuffer, IN ULONG ThunkBufferSize ); NTKERNELAPI VOID MmProbeAndLockProcessPages ( IN OUT PMDL MemoryDescriptorList, IN PEPROCESS Process, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation ); // begin_nthal // // I/O support routines. // NTKERNELAPI VOID MmProbeAndLockPages ( IN OUT PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation ); NTKERNELAPI VOID MmUnlockPages ( IN PMDL MemoryDescriptorList ); NTKERNELAPI VOID MmBuildMdlForNonPagedPool ( IN OUT PMDL MemoryDescriptorList ); NTKERNELAPI PVOID MmMapLockedPages ( IN PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode ); NTKERNELAPI PVOID MmGetSystemRoutineAddress ( IN PUNICODE_STRING SystemRoutineName ); NTKERNELAPI NTSTATUS MmAdvanceMdl ( IN PMDL Mdl, IN ULONG NumberOfBytes ); // end_wdm NTKERNELAPI NTSTATUS MmMapUserAddressesToPage ( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN PVOID PageAddress ); // begin_wdm NTKERNELAPI NTSTATUS MmProtectMdlSystemAddress ( IN PMDL MemoryDescriptorList, IN ULONG NewProtect ); // // _MM_PAGE_PRIORITY_ provides a method for the system to handle requests // intelligently in low resource conditions. // // LowPagePriority should be used when it is acceptable to the driver for the // mapping request to fail if the system is low on resources. An example of // this could be for a non-critical network connection where the driver can // handle the failure case when system resources are close to being depleted. // // NormalPagePriority should be used when it is acceptable to the driver for the // mapping request to fail if the system is very low on resources. An example // of this could be for a non-critical local filesystem request. // // HighPagePriority should be used when it is unacceptable to the driver for the // mapping request to fail unless the system is completely out of resources. // An example of this would be the paging file path in a driver. // // begin_ntndis typedef enum _MM_PAGE_PRIORITY { LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 } MM_PAGE_PRIORITY; // end_ntndis // // Note: This function is not available in WDM 1.0 // NTKERNELAPI PVOID MmMapLockedPagesSpecifyCache ( IN PMDL MemoryDescriptorList, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN MM_PAGE_PRIORITY Priority ); NTKERNELAPI VOID MmUnmapLockedPages ( IN PVOID BaseAddress, IN PMDL MemoryDescriptorList ); PVOID MmAllocateMappingAddress ( IN SIZE_T NumberOfBytes, IN ULONG PoolTag ); VOID MmFreeMappingAddress ( IN PVOID BaseAddress, IN ULONG PoolTag ); PVOID MmMapLockedPagesWithReservedMapping ( IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType ); VOID MmUnmapReservedMapping ( IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList ); // end_wdm typedef struct _PHYSICAL_MEMORY_RANGE { PHYSICAL_ADDRESS BaseAddress; LARGE_INTEGER NumberOfBytes; } PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; NTKERNELAPI NTSTATUS MmAddPhysicalMemory ( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes ); NTKERNELAPI NTSTATUS MmAddPhysicalMemoryEx ( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes, IN ULONG Flags ); NTKERNELAPI NTSTATUS MmRemovePhysicalMemory ( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes ); NTKERNELAPI NTSTATUS MmRemovePhysicalMemoryEx ( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes, IN ULONG Flags ); NTKERNELAPI PPHYSICAL_MEMORY_RANGE MmGetPhysicalMemoryRanges ( VOID ); NTSTATUS MmMarkPhysicalMemoryAsGood ( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes ); NTSTATUS MmMarkPhysicalMemoryAsBad ( IN PPHYSICAL_ADDRESS StartAddress, IN OUT PLARGE_INTEGER NumberOfBytes ); // begin_wdm NTKERNELAPI PMDL MmAllocatePagesForMdl ( IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes ); NTKERNELAPI VOID MmFreePagesFromMdl ( IN PMDL MemoryDescriptorList ); NTKERNELAPI PVOID MmMapIoSpace ( IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType ); NTKERNELAPI VOID MmUnmapIoSpace ( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes ); NTKERNELAPI PVOID MmMapVideoDisplay ( IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType ); NTKERNELAPI VOID MmUnmapVideoDisplay ( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes ); NTKERNELAPI PHYSICAL_ADDRESS MmGetPhysicalAddress ( IN PVOID BaseAddress ); NTKERNELAPI PVOID MmGetVirtualForPhysical ( IN PHYSICAL_ADDRESS PhysicalAddress ); NTKERNELAPI PVOID MmAllocateContiguousMemory ( IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress ); NTKERNELAPI PVOID MmAllocateContiguousMemorySpecifyCache ( IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType ); NTKERNELAPI VOID MmFreeContiguousMemory ( IN PVOID BaseAddress ); NTKERNELAPI VOID MmFreeContiguousMemorySpecifyCache ( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType ); NTKERNELAPI PVOID MmAllocateNonCachedMemory ( IN SIZE_T NumberOfBytes ); NTKERNELAPI VOID MmFreeNonCachedMemory ( IN PVOID BaseAddress, IN SIZE_T NumberOfBytes ); NTKERNELAPI BOOLEAN MmIsAddressValid ( IN PVOID VirtualAddress ); DECLSPEC_DEPRECATED_DDK NTKERNELAPI BOOLEAN MmIsNonPagedSystemAddressValid ( IN PVOID VirtualAddress ); // begin_wdm NTKERNELAPI SIZE_T MmSizeOfMdl( IN PVOID Base, IN SIZE_T Length ); DECLSPEC_DEPRECATED_DDK // Use IoCreateMdl NTKERNELAPI PMDL MmCreateMdl( IN PMDL MemoryDescriptorList OPTIONAL, IN PVOID Base, IN SIZE_T Length ); NTKERNELAPI PVOID MmLockPagableDataSection( IN PVOID AddressWithinSection ); // end_wdm NTKERNELAPI VOID MmLockPagableSectionByHandle ( IN PVOID ImageSectionHandle ); NTKERNELAPI VOID MmResetDriverPaging ( IN PVOID AddressWithinSection ); NTKERNELAPI PVOID MmPageEntireDriver ( IN PVOID AddressWithinSection ); NTKERNELAPI VOID MmUnlockPagableImageSection( IN PVOID ImageSectionHandle ); NTKERNELAPI HANDLE MmSecureVirtualMemory ( IN PVOID Address, IN SIZE_T Size, IN ULONG ProbeMode ); NTKERNELAPI VOID MmUnsecureVirtualMemory ( IN HANDLE SecureHandle ); NTKERNELAPI NTSTATUS MmMapViewInSessionSpace ( IN PVOID Section, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize ); NTKERNELAPI NTSTATUS MmUnmapViewInSessionSpace ( IN PVOID MappedBase ); //++ // // VOID // MmInitializeMdl ( // IN PMDL MemoryDescriptorList, // IN PVOID BaseVa, // IN SIZE_T Length // ) // // Routine Description: // // This routine initializes the header of a Memory Descriptor List (MDL). // // Arguments: // // MemoryDescriptorList - Pointer to the MDL to initialize. // // BaseVa - Base virtual address mapped by the MDL. // // Length - Length, in bytes, of the buffer mapped by the MDL. // // Return Value: // // None. // //-- #define MmInitializeMdl(MemoryDescriptorList, BaseVa, Length) { \ (MemoryDescriptorList)->Next = (PMDL) NULL; \ (MemoryDescriptorList)->Size = (CSHORT)(sizeof(MDL) + \ (sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES((BaseVa), (Length)))); \ (MemoryDescriptorList)->MdlFlags = 0; \ (MemoryDescriptorList)->StartVa = (PVOID) PAGE_ALIGN((BaseVa)); \ (MemoryDescriptorList)->ByteOffset = BYTE_OFFSET((BaseVa)); \ (MemoryDescriptorList)->ByteCount = (ULONG)(Length); \ } //++ // // PVOID // MmGetSystemAddressForMdlSafe ( // IN PMDL MDL, // IN MM_PAGE_PRIORITY PRIORITY // ) // // Routine Description: // // This routine returns the mapped address of an MDL. If the // Mdl is not already mapped or a system address, it is mapped. // // Arguments: // // MemoryDescriptorList - Pointer to the MDL to map. // // Priority - Supplies an indication as to how important it is that this // request succeed under low available PTE conditions. // // Return Value: // // Returns the base address where the pages are mapped. The base address // has the same offset as the virtual address in the MDL. // // Unlike MmGetSystemAddressForMdl, Safe guarantees that it will always // return NULL on failure instead of bugchecking the system. // // This macro is not usable by WDM 1.0 drivers as 1.0 did not include // MmMapLockedPagesSpecifyCache. The solution for WDM 1.0 drivers is to // provide synchronization and set/reset the MDL_MAPPING_CAN_FAIL bit. // //-- #define MmGetSystemAddressForMdlSafe(MDL, PRIORITY) \ (((MDL)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \ MDL_SOURCE_IS_NONPAGED_POOL)) ? \ ((MDL)->MappedSystemVa) : \ (MmMapLockedPagesSpecifyCache((MDL), \ KernelMode, \ MmCached, \ NULL, \ FALSE, \ (PRIORITY)))) //++ // // PVOID // MmGetSystemAddressForMdl ( // IN PMDL MDL // ) // // Routine Description: // // This routine returns the mapped address of an MDL, if the // Mdl is not already mapped or a system address, it is mapped. // // Arguments: // // MemoryDescriptorList - Pointer to the MDL to map. // // Return Value: // // Returns the base address where the pages are mapped. The base address // has the same offset as the virtual address in the MDL. // //-- //#define MmGetSystemAddressForMdl(MDL) // (((MDL)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA)) ? // ((MDL)->MappedSystemVa) : // ((((MDL)->MdlFlags & (MDL_SOURCE_IS_NONPAGED_POOL)) ? // ((PVOID)((ULONG)(MDL)->StartVa | (MDL)->ByteOffset)) : // (MmMapLockedPages((MDL),KernelMode))))) #if PRAGMA_DEPRECATED_DDK #pragma deprecated(MmGetSystemAddressForMdl) // Use MmGetSystemAddressForMdlSafe #endif #define MmGetSystemAddressForMdl(MDL) \ (((MDL)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \ MDL_SOURCE_IS_NONPAGED_POOL)) ? \ ((MDL)->MappedSystemVa) : \ (MmMapLockedPages((MDL),KernelMode))) //++ // // VOID // MmPrepareMdlForReuse ( // IN PMDL MDL // ) // // Routine Description: // // This routine will take all of the steps necessary to allow an MDL to be // re-used. // // Arguments: // // MemoryDescriptorList - Pointer to the MDL that will be re-used. // // Return Value: // // None. // //-- #define MmPrepareMdlForReuse(MDL) \ if (((MDL)->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { \ ASSERT(((MDL)->MdlFlags & MDL_PARTIAL) != 0); \ MmUnmapLockedPages( (MDL)->MappedSystemVa, (MDL) ); \ } else if (((MDL)->MdlFlags & MDL_PARTIAL) == 0) { \ ASSERT(((MDL)->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0); \ } typedef NTSTATUS (*PMM_DLL_INITIALIZE)( IN PUNICODE_STRING RegistryPath ); typedef NTSTATUS (*PMM_DLL_UNLOAD)( VOID ); // // Define an empty typedef for the _DRIVER_OBJECT structure so it may be // referenced by function types before it is actually defined. // struct _DRIVER_OBJECT; NTKERNELAPI LOGICAL MmIsDriverVerifying ( IN struct _DRIVER_OBJECT *DriverObject ); VOID MmMapMemoryDumpMdl( IN OUT PMDL MemoryDumpMdl ); // begin_ntminiport // // Graphics support routines. // typedef VOID (*PBANKED_SECTION_ROUTINE) ( IN ULONG ReadBank, IN ULONG WriteBank, IN PVOID Context ); // end_ntminiport NTSTATUS MmSetBankedSection ( IN HANDLE ProcessHandle, IN PVOID VirtualAddress, IN ULONG BankLength, IN BOOLEAN ReadWriteBank, IN PBANKED_SECTION_ROUTINE BankRoutine, IN PVOID Context); // // Security operation codes // typedef enum _SECURITY_OPERATION_CODE { SetSecurityDescriptor, QuerySecurityDescriptor, DeleteSecurityDescriptor, AssignSecurityDescriptor } SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE; // // Data structure used to capture subject security context // for access validations and auditing. // // THE FIELDS OF THIS DATA STRUCTURE SHOULD BE CONSIDERED OPAQUE // BY ALL EXCEPT THE SECURITY ROUTINES. // typedef struct _SECURITY_SUBJECT_CONTEXT { PACCESS_TOKEN ClientToken; SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; PACCESS_TOKEN PrimaryToken; PVOID ProcessAuditId; } SECURITY_SUBJECT_CONTEXT, *PSECURITY_SUBJECT_CONTEXT; /////////////////////////////////////////////////////////////////////////////// // // // ACCESS_STATE and related structures // // // /////////////////////////////////////////////////////////////////////////////// // // Initial Privilege Set - Room for three privileges, which should // be enough for most applications. This structure exists so that // it can be imbedded in an ACCESS_STATE structure. Use PRIVILEGE_SET // for all other references to Privilege sets. // #define INITIAL_PRIVILEGE_COUNT 3 typedef struct _INITIAL_PRIVILEGE_SET { ULONG PrivilegeCount; ULONG Control; LUID_AND_ATTRIBUTES Privilege[INITIAL_PRIVILEGE_COUNT]; } INITIAL_PRIVILEGE_SET, * PINITIAL_PRIVILEGE_SET; // // Combine the information that describes the state // of an access-in-progress into a single structure // typedef struct _ACCESS_STATE { LUID OperationID; BOOLEAN SecurityEvaluated; BOOLEAN GenerateAudit; BOOLEAN GenerateOnClose; BOOLEAN PrivilegesAllocated; ULONG Flags; ACCESS_MASK RemainingDesiredAccess; ACCESS_MASK PreviouslyGrantedAccess; ACCESS_MASK OriginalDesiredAccess; SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; PSECURITY_DESCRIPTOR SecurityDescriptor; PVOID AuxData; union { INITIAL_PRIVILEGE_SET InitialPrivilegeSet; PRIVILEGE_SET PrivilegeSet; } Privileges; BOOLEAN AuditPrivileges; UNICODE_STRING ObjectName; UNICODE_STRING ObjectTypeName; } ACCESS_STATE, *PACCESS_STATE; typedef struct _AUX_ACCESS_DATA { PPRIVILEGE_SET PrivilegesUsed; GENERIC_MAPPING GenericMapping; ACCESS_MASK AccessesToAudit; ACCESS_MASK MaximumAuditMask; } AUX_ACCESS_DATA, *PAUX_ACCESS_DATA; typedef struct _SE_EXPORTS { // // Privilege values // LUID SeCreateTokenPrivilege; LUID SeAssignPrimaryTokenPrivilege; LUID SeLockMemoryPrivilege; LUID SeIncreaseQuotaPrivilege; LUID SeUnsolicitedInputPrivilege; LUID SeTcbPrivilege; LUID SeSecurityPrivilege; LUID SeTakeOwnershipPrivilege; LUID SeLoadDriverPrivilege; LUID SeCreatePagefilePrivilege; LUID SeIncreaseBasePriorityPrivilege; LUID SeSystemProfilePrivilege; LUID SeSystemtimePrivilege; LUID SeProfileSingleProcessPrivilege; LUID SeCreatePermanentPrivilege; LUID SeBackupPrivilege; LUID SeRestorePrivilege; LUID SeShutdownPrivilege; LUID SeDebugPrivilege; LUID SeAuditPrivilege; LUID SeSystemEnvironmentPrivilege; LUID SeChangeNotifyPrivilege; LUID SeRemoteShutdownPrivilege; // // Universally defined Sids // PSID SeNullSid; PSID SeWorldSid; PSID SeLocalSid; PSID SeCreatorOwnerSid; PSID SeCreatorGroupSid; // // Nt defined Sids // PSID SeNtAuthoritySid; PSID SeDialupSid; PSID SeNetworkSid; PSID SeBatchSid; PSID SeInteractiveSid; PSID SeLocalSystemSid; PSID SeAliasAdminsSid; PSID SeAliasUsersSid; PSID SeAliasGuestsSid; PSID SeAliasPowerUsersSid; PSID SeAliasAccountOpsSid; PSID SeAliasSystemOpsSid; PSID SeAliasPrintOpsSid; PSID SeAliasBackupOpsSid; // // New Sids defined for NT5 // PSID SeAuthenticatedUsersSid; PSID SeRestrictedSid; PSID SeAnonymousLogonSid; // // New Privileges defined for NT5 // LUID SeUndockPrivilege; LUID SeSyncAgentPrivilege; LUID SeEnableDelegationPrivilege; // // New Sids defined for post-Windows 2000 PSID SeLocalServiceSid; PSID SeNetworkServiceSid; // // New Privileges defined for post-Windows 2000 // LUID SeManageVolumePrivilege; } SE_EXPORTS, *PSE_EXPORTS; #define SeDeleteClientSecurity(C) { \ if (SeTokenType((C)->ClientToken) == TokenPrimary) { \ PsDereferencePrimaryToken( (C)->ClientToken ); \ } else { \ PsDereferenceImpersonationToken( (C)->ClientToken ); \ } \ } // end_ntifs //++ //VOID //SeStopImpersonatingClient() // ///*++ // //Routine Description: // // This service is used to stop impersonating a client using an // impersonation token. This service must be called in the context // of the server thread which wishes to stop impersonating its // client. // // //Arguments: // // None. // //Return Value: // // None. // //--*/ //-- #define SeStopImpersonatingClient() PsRevertToSelf() NTKERNELAPI NTSTATUS SeCaptureSecurityDescriptor ( IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, IN KPROCESSOR_MODE RequestorMode, IN POOL_TYPE PoolType, IN BOOLEAN ForceCapture, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor ); NTKERNELAPI VOID SeReleaseSecurityDescriptor ( IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN ForceCapture ); // begin_ntifs NTKERNELAPI VOID SeCaptureSubjectContext ( OUT PSECURITY_SUBJECT_CONTEXT SubjectContext ); NTKERNELAPI VOID SeLockSubjectContext( IN PSECURITY_SUBJECT_CONTEXT SubjectContext ); NTKERNELAPI VOID SeUnlockSubjectContext( IN PSECURITY_SUBJECT_CONTEXT SubjectContext ); NTKERNELAPI VOID SeReleaseSubjectContext ( IN PSECURITY_SUBJECT_CONTEXT SubjectContext ); NTKERNELAPI NTSTATUS SeAssignSecurity ( IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ExplicitDescriptor, OUT PSECURITY_DESCRIPTOR *NewDescriptor, IN BOOLEAN IsDirectoryObject, IN PSECURITY_SUBJECT_CONTEXT SubjectContext, IN PGENERIC_MAPPING GenericMapping, IN POOL_TYPE PoolType ); NTKERNELAPI NTSTATUS SeAssignSecurityEx ( IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, OUT PSECURITY_DESCRIPTOR *NewDescriptor, IN GUID *ObjectType OPTIONAL, IN BOOLEAN IsDirectoryObject, IN ULONG AutoInheritFlags, IN PSECURITY_SUBJECT_CONTEXT SubjectContext, IN PGENERIC_MAPPING GenericMapping, IN POOL_TYPE PoolType ); NTKERNELAPI NTSTATUS SeDeassignSecurity ( IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor ); NTKERNELAPI BOOLEAN SeAccessCheck ( IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN BOOLEAN SubjectContextLocked, IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK PreviouslyGrantedAccess, OUT PPRIVILEGE_SET *Privileges OPTIONAL, IN PGENERIC_MAPPING GenericMapping, IN KPROCESSOR_MODE AccessMode, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus ); #ifdef SE_NTFS_WORLD_CACHE VOID SeGetWorldRights ( IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PGENERIC_MAPPING GenericMapping, OUT PACCESS_MASK GrantedAccess ); #endif NTKERNELAPI BOOLEAN SePrivilegeCheck( IN OUT PPRIVILEGE_SET RequiredPrivileges, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN KPROCESSOR_MODE AccessMode ); NTKERNELAPI VOID SeFreePrivileges( IN PPRIVILEGE_SET Privileges ); NTKERNELAPI VOID SePrivilegeObjectAuditAlarm( IN HANDLE Handle, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN ACCESS_MASK DesiredAccess, IN PPRIVILEGE_SET Privileges, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode ); NTKERNELAPI // ntifs TOKEN_TYPE // ntifs SeTokenType( // ntifs IN PACCESS_TOKEN Token // ntifs ); // ntifs SECURITY_IMPERSONATION_LEVEL SeTokenImpersonationLevel( IN PACCESS_TOKEN Token ); NTKERNELAPI // ntifs BOOLEAN // ntifs SeTokenIsAdmin( // ntifs IN PACCESS_TOKEN Token // ntifs ); // ntifs NTKERNELAPI // ntifs BOOLEAN // ntifs SeTokenIsRestricted( // ntifs IN PACCESS_TOKEN Token // ntifs ); // ntifs NTKERNELAPI NTSTATUS SeQueryAuthenticationIdToken( IN PACCESS_TOKEN Token, OUT PLUID AuthenticationId ); NTKERNELAPI NTSTATUS SeCreateClientSecurity ( IN PETHREAD ClientThread, IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos, IN BOOLEAN RemoteSession, OUT PSECURITY_CLIENT_CONTEXT ClientContext ); NTKERNELAPI NTSTATUS SeImpersonateClientEx( IN PSECURITY_CLIENT_CONTEXT ClientContext, IN PETHREAD ServerThread OPTIONAL ); NTKERNELAPI NTSTATUS SeCreateAccessState( IN PACCESS_STATE AccessState, IN PAUX_ACCESS_DATA AuxData, IN ACCESS_MASK DesiredAccess, IN PGENERIC_MAPPING GenericMapping ); NTKERNELAPI VOID SeDeleteAccessState( IN PACCESS_STATE AccessState ); NTKERNELAPI NTSTATUS SeQuerySecurityDescriptorInfo ( IN PSECURITY_INFORMATION SecurityInformation, OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG Length, IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor ); NTKERNELAPI NTSTATUS SeSetSecurityDescriptorInfo ( IN PVOID Object OPTIONAL, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping ); NTKERNELAPI NTSTATUS SeSetSecurityDescriptorInfoEx ( IN PVOID Object OPTIONAL, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR ModificationDescriptor, IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, IN ULONG AutoInheritFlags, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping ); NTKERNELAPI NTSTATUS SeAppendPrivileges( PACCESS_STATE AccessState, PPRIVILEGE_SET Privileges ); NTKERNELAPI BOOLEAN SeSinglePrivilegeCheck( LUID PrivilegeValue, KPROCESSOR_MODE PreviousMode ); NTKERNELAPI NTSTATUS SeQueryInformationToken ( IN PACCESS_TOKEN Token, IN TOKEN_INFORMATION_CLASS TokenInformationClass, OUT PVOID *TokenInformation ); // // Grants access to SeExports structure // extern NTKERNELAPI PSE_EXPORTS SeExports; NTKERNELAPI VOID PoSetSystemState ( IN EXECUTION_STATE Flags ); // begin_ntifs NTKERNELAPI PVOID PoRegisterSystemState ( IN PVOID StateHandle, IN EXECUTION_STATE Flags ); // end_ntifs typedef VOID (*PREQUEST_POWER_COMPLETE) ( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ); NTKERNELAPI NTSTATUS PoRequestPowerIrp ( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PREQUEST_POWER_COMPLETE CompletionFunction, IN PVOID Context, OUT PIRP *Irp OPTIONAL ); NTKERNELAPI NTSTATUS PoRequestShutdownEvent ( OUT PVOID *Event ); NTKERNELAPI NTSTATUS PoRequestShutdownWait ( IN PETHREAD Thread ); // begin_ntifs NTKERNELAPI VOID PoUnregisterSystemState ( IN PVOID StateHandle ); // begin_nthal NTKERNELAPI POWER_STATE PoSetPowerState ( IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State ); NTKERNELAPI NTSTATUS PoCallDriver ( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ); NTKERNELAPI VOID PoStartNextPowerIrp( IN PIRP Irp ); NTKERNELAPI PULONG PoRegisterDeviceForIdleDetection ( IN PDEVICE_OBJECT DeviceObject, IN ULONG ConservationIdleTime, IN ULONG PerformanceIdleTime, IN DEVICE_POWER_STATE State ); #define PoSetDeviceBusy(IdlePointer) \ *IdlePointer = 0 // // \Callback\PowerState values // #define PO_CB_SYSTEM_POWER_POLICY 0 #define PO_CB_AC_STATUS 1 #define PO_CB_BUTTON_COLLISION 2 #define PO_CB_SYSTEM_STATE_LOCK 3 #define PO_CB_LID_SWITCH_STATE 4 #define PO_CB_PROCESSOR_POWER_POLICY 5 // end_ntddk end_wdm end_nthal // Used for queuing work items to be performed at shutdown time. Same // rules apply as per Ex work queues. NTKERNELAPI NTSTATUS PoQueueShutdownWorkItem( IN PWORK_QUEUE_ITEM WorkItem ); PKTHREAD FORCEINLINE PsGetKernelThread( IN PETHREAD ThreadObject ) { return (PKTHREAD)ThreadObject; } PKPROCESS FORCEINLINE PsGetKernelProcess( IN PEPROCESS ProcessObject ) { return (PKPROCESS)ProcessObject; } NTSTATUS PsGetContextThread( IN PETHREAD Thread, IN OUT PCONTEXT ThreadContext, IN KPROCESSOR_MODE Mode ); NTSTATUS PsSetContextThread( IN PETHREAD Thread, IN PCONTEXT ThreadContext, IN KPROCESSOR_MODE Mode ); NTKERNELAPI PEPROCESS PsGetCurrentProcess( VOID ); NTKERNELAPI PETHREAD PsGetCurrentThread( VOID ); // // System Thread and Process Creation and Termination // NTKERNELAPI NTSTATUS PsCreateSystemThread( OUT PHANDLE ThreadHandle, IN ULONG DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ProcessHandle OPTIONAL, OUT PCLIENT_ID ClientId OPTIONAL, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext ); NTKERNELAPI NTSTATUS PsTerminateSystemThread( IN NTSTATUS ExitStatus ); NTKERNELAPI PACCESS_TOKEN PsReferencePrimaryToken( IN PEPROCESS Process ); VOID PsDereferencePrimaryToken( IN PACCESS_TOKEN PrimaryToken ); VOID PsDereferenceImpersonationToken( IN PACCESS_TOKEN ImpersonationToken ); // end_ntifs // begin_ntifs NTKERNELAPI PACCESS_TOKEN PsReferenceImpersonationToken( IN PETHREAD Thread, OUT PBOOLEAN CopyOnOpen, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel ); // end_ntifs PACCESS_TOKEN PsReferenceEffectiveToken( IN PETHREAD Thread, OUT PTOKEN_TYPE TokenType, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel ); // begin_ntifs LARGE_INTEGER PsGetProcessExitTime( VOID ); // end_ntifs BOOLEAN PsIsThreadTerminating( IN PETHREAD Thread ); NTSTATUS PsImpersonateClient( IN PETHREAD Thread, IN PACCESS_TOKEN Token, IN BOOLEAN CopyOnOpen, IN BOOLEAN EffectiveOnly, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel ); NTKERNELAPI VOID PsRevertToSelf( VOID ); NTKERNELAPI VOID PsRevertThreadToSelf( PETHREAD Thread ); NTKERNELAPI NTSTATUS PsLookupProcessByProcessId( IN HANDLE ProcessId, OUT PEPROCESS *Process ); NTKERNELAPI NTSTATUS PsLookupThreadByThreadId( IN HANDLE ThreadId, OUT PETHREAD *Thread ); // begin_ntifs // // Quota Operations // VOID PsChargePoolQuota( IN PEPROCESS Process, IN POOL_TYPE PoolType, IN ULONG_PTR Amount ); NTSTATUS PsChargeProcessPoolQuota( IN PEPROCESS Process, IN POOL_TYPE PoolType, IN ULONG_PTR Amount ); VOID PsReturnPoolQuota( IN PEPROCESS Process, IN POOL_TYPE PoolType, IN ULONG_PTR Amount ); // end_ntifs typedef NTSTATUS (*PKWIN32_PROCESS_CALLOUT) ( IN PEPROCESS Process, IN BOOLEAN Initialize ); typedef enum _PSW32JOBCALLOUTTYPE { PsW32JobCalloutSetInformation, PsW32JobCalloutAddProcess, PsW32JobCalloutTerminate } PSW32JOBCALLOUTTYPE; typedef struct _WIN32_JOBCALLOUT_PARAMETERS { PVOID Job; PSW32JOBCALLOUTTYPE CalloutType; IN PVOID Data; } WIN32_JOBCALLOUT_PARAMETERS, *PKWIN32_JOBCALLOUT_PARAMETERS; typedef NTSTATUS (*PKWIN32_JOB_CALLOUT) ( IN PKWIN32_JOBCALLOUT_PARAMETERS Parm ); typedef enum _PSW32THREADCALLOUTTYPE { PsW32ThreadCalloutInitialize, PsW32ThreadCalloutExit } PSW32THREADCALLOUTTYPE; typedef NTSTATUS (*PKWIN32_THREAD_CALLOUT) ( IN PETHREAD Thread, IN PSW32THREADCALLOUTTYPE CalloutType ); typedef enum _PSPOWEREVENTTYPE { PsW32FullWake, PsW32EventCode, PsW32PowerPolicyChanged, PsW32SystemPowerState, PsW32SystemTime, PsW32DisplayState, PsW32CapabilitiesChanged, PsW32SetStateFailed, PsW32GdiOff, PsW32GdiOn } PSPOWEREVENTTYPE; typedef struct _WIN32_POWEREVENT_PARAMETERS { PSPOWEREVENTTYPE EventNumber; ULONG_PTR Code; } WIN32_POWEREVENT_PARAMETERS, *PKWIN32_POWEREVENT_PARAMETERS; typedef enum _POWERSTATETASK { PowerState_BlockSessionSwitch, PowerState_Init, PowerState_QueryApps, PowerState_QueryFailed, PowerState_SuspendApps, PowerState_ShowUI, PowerState_NotifyWL, PowerState_ResumeApps, PowerState_UnBlockSessionSwitch } POWERSTATETASK; typedef struct _WIN32_POWERSTATE_PARAMETERS { BOOLEAN Promotion; POWER_ACTION SystemAction; SYSTEM_POWER_STATE MinSystemState; ULONG Flags; BOOLEAN fQueryDenied; POWERSTATETASK PowerStateTask; } WIN32_POWERSTATE_PARAMETERS, *PKWIN32_POWERSTATE_PARAMETERS; typedef NTSTATUS (*PKWIN32_POWEREVENT_CALLOUT) ( IN PKWIN32_POWEREVENT_PARAMETERS Parm ); typedef NTSTATUS (*PKWIN32_POWERSTATE_CALLOUT) ( IN PKWIN32_POWERSTATE_PARAMETERS Parm ); typedef NTSTATUS (*PKWIN32_OBJECT_CALLOUT) ( IN PVOID Parm ); typedef struct _WIN32_CALLOUTS_FPNS { PKWIN32_PROCESS_CALLOUT ProcessCallout; PKWIN32_THREAD_CALLOUT ThreadCallout; PKWIN32_GLOBALATOMTABLE_CALLOUT GlobalAtomTableCallout; PKWIN32_POWEREVENT_CALLOUT PowerEventCallout; PKWIN32_POWERSTATE_CALLOUT PowerStateCallout; PKWIN32_JOB_CALLOUT JobCallout; PVOID BatchFlushRoutine; PKWIN32_OBJECT_CALLOUT DesktopOpenProcedure; PKWIN32_OBJECT_CALLOUT DesktopOkToCloseProcedure; PKWIN32_OBJECT_CALLOUT DesktopCloseProcedure; PKWIN32_OBJECT_CALLOUT DesktopDeleteProcedure; PKWIN32_OBJECT_CALLOUT WindowStationOkToCloseProcedure; PKWIN32_OBJECT_CALLOUT WindowStationCloseProcedure; PKWIN32_OBJECT_CALLOUT WindowStationDeleteProcedure; PKWIN32_OBJECT_CALLOUT WindowStationParseProcedure; PKWIN32_OBJECT_CALLOUT WindowStationOpenProcedure; } WIN32_CALLOUTS_FPNS, *PKWIN32_CALLOUTS_FPNS; NTKERNELAPI VOID PsEstablishWin32Callouts( IN PKWIN32_CALLOUTS_FPNS pWin32Callouts ); typedef enum _PSPROCESSPRIORITYMODE { PsProcessPriorityBackground, PsProcessPriorityForeground, PsProcessPrioritySpinning } PSPROCESSPRIORITYMODE; NTKERNELAPI VOID PsSetProcessPriorityByClass( IN PEPROCESS Process, IN PSPROCESSPRIORITYMODE PriorityMode ); HANDLE PsGetCurrentProcessId( VOID ); HANDLE PsGetCurrentThreadId( VOID ); NTKERNELAPI ULONG PsGetCurrentProcessSessionId( VOID ); NTKERNELAPI PVOID PsGetCurrentThreadStackLimit( VOID ); NTKERNELAPI PVOID PsGetCurrentThreadStackBase( VOID ); NTKERNELAPI CCHAR PsGetCurrentThreadPreviousMode( VOID ); NTKERNELAPI PERESOURCE PsGetJobLock( PEJOB Job ); NTKERNELAPI ULONG PsGetJobSessionId( PEJOB Job ); NTKERNELAPI ULONG PsGetJobUIRestrictionsClass( PEJOB Job ); NTKERNELAPI LONGLONG PsGetProcessCreateTimeQuadPart( PEPROCESS Process ); NTKERNELAPI PVOID PsGetProcessDebugPort( PEPROCESS Process ); BOOLEAN PsIsProcessBeingDebugged( PEPROCESS Process ); NTKERNELAPI BOOLEAN PsGetProcessExitProcessCalled( PEPROCESS Process ); NTKERNELAPI NTSTATUS PsGetProcessExitStatus( PEPROCESS Process ); NTKERNELAPI HANDLE PsGetProcessId( PEPROCESS Process ); NTKERNELAPI UCHAR * PsGetProcessImageFileName( PEPROCESS Process ); #define PsGetCurrentProcessImageFileName() PsGetProcessImageFileName(PsGetCurrentProcess()) NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId( PEPROCESS Process ); NTKERNELAPI PEJOB PsGetProcessJob( PEPROCESS Process ); NTKERNELAPI ULONG PsGetProcessSessionId( PEPROCESS Process ); NTKERNELAPI PVOID PsGetProcessSectionBaseAddress( PEPROCESS Process ); #define PsGetProcessPcb(Process) ((PKPROCESS)(Process)) NTKERNELAPI PPEB PsGetProcessPeb( PEPROCESS Process ); NTKERNELAPI UCHAR PsGetProcessPriorityClass( PEPROCESS Process ); NTKERNELAPI HANDLE PsGetProcessWin32WindowStation( PEPROCESS Process ); #define PsGetCurrentProcessWin32WindowStation() PsGetProcessWin32WindowStation(PsGetCurrentProcess()) NTKERNELAPI PVOID PsGetProcessWin32Process( PEPROCESS Process ); #define PsGetCurrentProcessWin32Process() PsGetProcessWin32Process(PsGetCurrentProcess()) #if defined(_WIN64) NTKERNELAPI PVOID PsGetProcessWow64Process( PEPROCESS Process ); #endif NTKERNELAPI HANDLE PsGetThreadId( PETHREAD Thread ); NTKERNELAPI CCHAR PsGetThreadFreezeCount( PETHREAD Thread ); NTKERNELAPI BOOLEAN PsGetThreadHardErrorsAreDisabled( PETHREAD Thread); NTKERNELAPI PEPROCESS PsGetThreadProcess( PETHREAD Thread ); #define PsGetCurrentThreadProcess() PsGetThreadProcess(PsGetCurrentThread()) NTKERNELAPI HANDLE PsGetThreadProcessId( PETHREAD Thread ); #define PsGetCurrentThreadProcessId() PsGetThreadProcessId(PsGetCurrentThread()) NTKERNELAPI ULONG PsGetThreadSessionId( PETHREAD Thread ); #define PsGetThreadTcb(Thread) ((PKTHREAD)(Thread)) NTKERNELAPI PVOID PsGetThreadTeb( PETHREAD Thread ); #define PsGetCurrentThreadTeb() PsGetThreadTeb(PsGetCurrentThread()) NTKERNELAPI PVOID PsGetThreadWin32Thread( PETHREAD Thread ); #define PsGetCurrentThreadWin32Thread() PsGetThreadWin32Thread(PsGetCurrentThread()) NTKERNELAPI //ntifs BOOLEAN //ntifs PsIsSystemThread( //ntifs PETHREAD Thread //ntifs ); //ntifs NTKERNELAPI BOOLEAN PsIsThreadImpersonating ( IN PETHREAD Thread ); NTSTATUS PsReferenceProcessFilePointer ( IN PEPROCESS Process, OUT PVOID *pFilePointer ); NTKERNELAPI VOID PsSetJobUIRestrictionsClass( PEJOB Job, ULONG UIRestrictionsClass ); NTKERNELAPI VOID PsSetProcessPriorityClass( PEPROCESS Process, UCHAR PriorityClass ); NTKERNELAPI NTSTATUS PsSetProcessWin32Process( PEPROCESS Process, PVOID Win32Process, PVOID PrevWin32Proces ); NTKERNELAPI VOID PsSetProcessWindowStation( PEPROCESS Process, HANDLE Win32WindowStation ); NTKERNELAPI VOID PsSetThreadHardErrorsAreDisabled( PETHREAD Thread, BOOLEAN HardErrorsAreDisabled ); NTKERNELAPI VOID PsSetThreadWin32Thread( PETHREAD Thread, PVOID Win32Thread, PVOID PrevWin32Thread ); NTKERNELAPI PVOID PsGetProcessSecurityPort( PEPROCESS Process ); NTKERNELAPI NTSTATUS PsSetProcessSecurityPort( PEPROCESS Process, PVOID Port ); typedef NTSTATUS (*PROCESS_ENUM_ROUTINE)( IN PEPROCESS Process, IN PVOID Context ); typedef NTSTATUS (*THREAD_ENUM_ROUTINE)( IN PEPROCESS Process, IN PETHREAD Thread, IN PVOID Context ); NTSTATUS PsEnumProcesses ( IN PROCESS_ENUM_ROUTINE CallBack, IN PVOID Context ); NTSTATUS PsEnumProcessThreads ( IN PEPROCESS Process, IN THREAD_ENUM_ROUTINE CallBack, IN PVOID Context ); PEPROCESS PsGetNextProcess ( IN PEPROCESS Process ); PETHREAD PsGetNextProcessThread ( IN PEPROCESS Process, IN PETHREAD Thread ); VOID PsQuitNextProcess ( IN PEPROCESS Process ); VOID PsQuitNextProcessThread ( IN PETHREAD Thread ); PEJOB PsGetNextJob ( IN PEJOB Job ); PEPROCESS PsGetNextJobProcess ( IN PEJOB Job, IN PEPROCESS Process ); VOID PsQuitNextJob ( IN PEJOB Job ); VOID PsQuitNextJobProcess ( IN PEPROCESS Process ); NTSTATUS PsSuspendProcess ( IN PEPROCESS Process ); NTSTATUS PsResumeProcess ( IN PEPROCESS Process ); NTSTATUS PsTerminateProcess( IN PEPROCESS Process, IN NTSTATUS Status ); NTSTATUS PsSuspendThread ( IN PETHREAD Thread, OUT PULONG PreviousSuspendCount OPTIONAL ); NTSTATUS PsResumeThread ( IN PETHREAD Thread, OUT PULONG PreviousSuspendCount OPTIONAL ); // // Object Manager types // typedef struct _OBJECT_HANDLE_INFORMATION { ULONG HandleAttributes; ACCESS_MASK GrantedAccess; } OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION; // end_ntddk end_wdm end_nthal end_ntifs typedef struct _OBJECT_DUMP_CONTROL { PVOID Stream; ULONG Detail; } OB_DUMP_CONTROL, *POB_DUMP_CONTROL; typedef VOID (*OB_DUMP_METHOD)( IN PVOID Object, IN POB_DUMP_CONTROL Control OPTIONAL ); typedef enum _OB_OPEN_REASON { ObCreateHandle, ObOpenHandle, ObDuplicateHandle, ObInheritHandle, ObMaxOpenReason } OB_OPEN_REASON; typedef NTSTATUS (*OB_OPEN_METHOD)( IN OB_OPEN_REASON OpenReason, IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount ); typedef BOOLEAN (*OB_OKAYTOCLOSE_METHOD)( IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN HANDLE Handle, IN KPROCESSOR_MODE PreviousMode ); typedef VOID (*OB_CLOSE_METHOD)( IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount ); typedef VOID (*OB_DELETE_METHOD)( IN PVOID Object ); typedef NTSTATUS (*OB_PARSE_METHOD)( IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object ); typedef NTSTATUS (*OB_SECURITY_METHOD)( IN PVOID Object, IN SECURITY_OPERATION_CODE OperationCode, IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG CapturedLength, IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping ); typedef NTSTATUS (*OB_QUERYNAME_METHOD)( IN PVOID Object, IN BOOLEAN HasObjectName, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength ); /* A security method and its caller must obey the following w.r.t. capturing and probing parameters: For a query operation, the caller must pass a kernel space address for CapturedLength. The caller should be able to assume that it points to valid data that will not change. In addition, the SecurityDescriptor parameter (which will receive the result of the query operation) must be probed for write up to the length given in CapturedLength. The security method itself must always write to the SecurityDescriptor buffer in a try clause in case the caller de-allocates it. For a set operation, the SecurityDescriptor parameter must have been captured via SeCaptureSecurityDescriptor. This parameter is not optional, and therefore may not be NULL. */ // // Prototypes for Win32 WindowStation and Desktop object callout routines // typedef struct _WIN32_OPENMETHOD_PARAMETERS { OB_OPEN_REASON OpenReason; PEPROCESS Process; PVOID Object; ACCESS_MASK GrantedAccess; ULONG HandleCount; } WIN32_OPENMETHOD_PARAMETERS, *PKWIN32_OPENMETHOD_PARAMETERS; typedef NTSTATUS (*PKWIN32_OPENMETHOD_CALLOUT) ( PKWIN32_OPENMETHOD_PARAMETERS ); extern PKWIN32_OPENMETHOD_CALLOUT ExDesktopOpenProcedureCallout; extern PKWIN32_OPENMETHOD_CALLOUT ExWindowStationOpenProcedureCallout; typedef struct _WIN32_OKAYTOCLOSEMETHOD_PARAMETERS { PEPROCESS Process; PVOID Object; HANDLE Handle; KPROCESSOR_MODE PreviousMode; } WIN32_OKAYTOCLOSEMETHOD_PARAMETERS, *PKWIN32_OKAYTOCLOSEMETHOD_PARAMETERS; typedef NTSTATUS (*PKWIN32_OKTOCLOSEMETHOD_CALLOUT) ( PKWIN32_OKAYTOCLOSEMETHOD_PARAMETERS ); extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExDesktopOkToCloseProcedureCallout; extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExWindowStationOkToCloseProcedureCallout; typedef struct _WIN32_CLOSEMETHOD_PARAMETERS { PEPROCESS Process; PVOID Object; ACCESS_MASK GrantedAccess; ULONG ProcessHandleCount; ULONG SystemHandleCount; } WIN32_CLOSEMETHOD_PARAMETERS, *PKWIN32_CLOSEMETHOD_PARAMETERS; typedef NTSTATUS (*PKWIN32_CLOSEMETHOD_CALLOUT) ( PKWIN32_CLOSEMETHOD_PARAMETERS ); extern PKWIN32_CLOSEMETHOD_CALLOUT ExDesktopCloseProcedureCallout; extern PKWIN32_CLOSEMETHOD_CALLOUT ExWindowStationCloseProcedureCallout; typedef struct _WIN32_DELETEMETHOD_PARAMETERS { PVOID Object; } WIN32_DELETEMETHOD_PARAMETERS, *PKWIN32_DELETEMETHOD_PARAMETERS; typedef NTSTATUS (*PKWIN32_DELETEMETHOD_CALLOUT) ( PKWIN32_DELETEMETHOD_PARAMETERS ); extern PKWIN32_DELETEMETHOD_CALLOUT ExDesktopDeleteProcedureCallout; extern PKWIN32_DELETEMETHOD_CALLOUT ExWindowStationDeleteProcedureCallout; typedef struct _WIN32_PARSEMETHOD_PARAMETERS { PVOID ParseObject; PVOID ObjectType; PACCESS_STATE AccessState; KPROCESSOR_MODE AccessMode; ULONG Attributes; PUNICODE_STRING CompleteName; PUNICODE_STRING RemainingName; PVOID Context OPTIONAL; PSECURITY_QUALITY_OF_SERVICE SecurityQos; PVOID *Object; } WIN32_PARSEMETHOD_PARAMETERS, *PKWIN32_PARSEMETHOD_PARAMETERS; typedef NTSTATUS (*PKWIN32_PARSEMETHOD_CALLOUT) ( PKWIN32_PARSEMETHOD_PARAMETERS ); extern PKWIN32_PARSEMETHOD_CALLOUT ExWindowStationParseProcedureCallout; // // Object Type Structure // typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; BOOLEAN UseDefaultObject; BOOLEAN CaseInsensitive; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; BOOLEAN MaintainTypeList; POOL_TYPE PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; OB_DUMP_METHOD DumpProcedure; OB_OPEN_METHOD OpenProcedure; OB_CLOSE_METHOD CloseProcedure; OB_DELETE_METHOD DeleteProcedure; OB_PARSE_METHOD ParseProcedure; OB_SECURITY_METHOD SecurityProcedure; OB_QUERYNAME_METHOD QueryNameProcedure; OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure; } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; #define OBJECT_LOCK_COUNT 4 typedef struct _OBJECT_TYPE { ERESOURCE Mutex; LIST_ENTRY TypeList; UNICODE_STRING Name; // Copy from object header for convenience PVOID DefaultObject; ULONG Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; #ifdef POOL_TAGGING ULONG Key; #endif //POOL_TAGGING ERESOURCE ObjectLocks[ OBJECT_LOCK_COUNT ]; } OBJECT_TYPE, *POBJECT_TYPE; // // Object Directory Structure // #define NUMBER_HASH_BUCKETS 37 typedef struct _OBJECT_DIRECTORY { struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ]; EX_PUSH_LOCK Lock; struct _DEVICE_MAP *DeviceMap; USHORT Reserved; USHORT SymbolicLinkUsageCount; } OBJECT_DIRECTORY, *POBJECT_DIRECTORY; typedef struct _OBJECT_CREATE_INFORMATION *POBJECT_CREATE_INFORMATION;; typedef struct _OBJECT_HEADER { LONG PointerCount; union { LONG HandleCount; PVOID NextToFree; }; POBJECT_TYPE Type; UCHAR NameInfoOffset; UCHAR HandleInfoOffset; UCHAR QuotaInfoOffset; UCHAR Flags; union { POBJECT_CREATE_INFORMATION ObjectCreateInfo; PVOID QuotaBlockCharged; }; PSECURITY_DESCRIPTOR SecurityDescriptor; QUAD Body; } OBJECT_HEADER, *POBJECT_HEADER; typedef struct _OBJECT_HEADER_NAME_INFO { POBJECT_DIRECTORY Directory; UNICODE_STRING Name; ULONG QueryReferences; #if DBG ULONG Reserved2; LONG DbgDereferenceCount; #ifdef _WIN64 ULONG64 Reserved3; // Win64 requires these structures to be 16 byte aligned. #endif #endif } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO; #define OBJECT_TO_OBJECT_HEADER( o ) \ CONTAINING_RECORD( (o), OBJECT_HEADER, Body ) #define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \ ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset))) #define OBJECT_HEADER_TO_CREATOR_INFO( oh ) ((POBJECT_HEADER_CREATOR_INFO) \ (((oh)->Flags & OB_FLAG_CREATOR_INFO) == 0 ? NULL : ((PCHAR)(oh) - sizeof(OBJECT_HEADER_CREATOR_INFO)))) NTKERNELAPI NTSTATUS ObCreateObjectType( IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, OUT POBJECT_TYPE *ObjectType ); NTKERNELAPI NTSTATUS ObCreateObject( IN KPROCESSOR_MODE ProbeMode, IN POBJECT_TYPE ObjectType, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE OwnershipMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectBodySize, IN ULONG PagedPoolCharge, IN ULONG NonPagedPoolCharge, OUT PVOID *Object ); // // These inlines correct an issue where the compiler refetches // the output object over and over again because it thinks its // a possible alias for other stores. // FORCEINLINE NTSTATUS _ObCreateObject( IN KPROCESSOR_MODE ProbeMode, IN POBJECT_TYPE ObjectType, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE OwnershipMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectBodySize, IN ULONG PagedPoolCharge, IN ULONG NonPagedPoolCharge, OUT PVOID *pObject ) { PVOID Object; NTSTATUS Status; Status = ObCreateObject (ProbeMode, ObjectType, ObjectAttributes, OwnershipMode, ParseContext, ObjectBodySize, PagedPoolCharge, NonPagedPoolCharge, &Object); *pObject = Object; return Status; } #define ObCreateObject _ObCreateObject NTKERNELAPI NTSTATUS ObInsertObject( IN PVOID Object, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle OPTIONAL ); // end_nthal NTKERNELAPI // ntddk wdm nthal ntifs NTSTATUS // ntddk wdm nthal ntifs ObReferenceObjectByHandle( // ntddk wdm nthal ntifs IN HANDLE Handle, // ntddk wdm nthal ntifs IN ACCESS_MASK DesiredAccess, // ntddk wdm nthal ntifs IN POBJECT_TYPE ObjectType OPTIONAL, // ntddk wdm nthal ntifs IN KPROCESSOR_MODE AccessMode, // ntddk wdm nthal ntifs OUT PVOID *Object, // ntddk wdm nthal ntifs OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL // ntddk wdm nthal ntifs ); // ntddk wdm nthal ntifs FORCEINLINE NTSTATUS _ObReferenceObjectByHandle( IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType OPTIONAL, IN KPROCESSOR_MODE AccessMode, OUT PVOID *pObject, OUT POBJECT_HANDLE_INFORMATION pHandleInformation OPTIONAL ) { PVOID Object; NTSTATUS Status; Status = ObReferenceObjectByHandle (Handle, DesiredAccess, ObjectType, AccessMode, &Object, pHandleInformation); *pObject = Object; return Status; } #define ObReferenceObjectByHandle _ObReferenceObjectByHandle NTKERNELAPI NTSTATUS ObReferenceFileObjectForWrite( IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode, OUT PVOID *FileObject, OUT POBJECT_HANDLE_INFORMATION HandleInformation ); NTKERNELAPI NTSTATUS ObOpenObjectByName( IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN OUT PVOID ParseContext OPTIONAL, OUT PHANDLE Handle ); NTKERNELAPI // ntifs NTSTATUS // ntifs ObOpenObjectByPointer( // ntifs IN PVOID Object, // ntifs IN ULONG HandleAttributes, // ntifs IN PACCESS_STATE PassedAccessState OPTIONAL, // ntifs IN ACCESS_MASK DesiredAccess OPTIONAL, // ntifs IN POBJECT_TYPE ObjectType OPTIONAL, // ntifs IN KPROCESSOR_MODE AccessMode, // ntifs OUT PHANDLE Handle // ntifs ); // ntifs NTSTATUS ObReferenceObjectByName( IN PUNICODE_STRING ObjectName, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, OUT PVOID *Object ); NTKERNELAPI BOOLEAN ObFindHandleForObject( IN PEPROCESS Process, IN PVOID Object, IN POBJECT_TYPE ObjectType OPTIONAL, IN POBJECT_HANDLE_INFORMATION MatchCriteria OPTIONAL, OUT PHANDLE Handle ); // begin_ntddk begin_wdm begin_nthal begin_ntifs #define ObDereferenceObject(a) \ ObfDereferenceObject(a) #define ObReferenceObject(Object) ObfReferenceObject(Object) NTKERNELAPI LONG FASTCALL ObfReferenceObject( IN PVOID Object ); NTKERNELAPI NTSTATUS ObReferenceObjectByPointer( IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode ); NTKERNELAPI LONG FASTCALL ObfDereferenceObject( IN PVOID Object ); NTKERNELAPI NTSTATUS ObQueryNameString( IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength ); NTSTATUS ObGetObjectSecurity( IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated ); VOID ObReleaseObjectSecurity( IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated ); NTKERNELAPI BOOLEAN ObCheckCreateObjectAccess( IN PVOID DirectoryObject, IN ACCESS_MASK CreateAccess, IN PACCESS_STATE AccessState OPTIONAL, IN PUNICODE_STRING ComponentName, IN BOOLEAN TypeMutexLocked, IN KPROCESSOR_MODE PreviousMode, OUT PNTSTATUS AccessStatus ); NTKERNELAPI BOOLEAN ObCheckObjectAccess( IN PVOID Object, IN PACCESS_STATE AccessState, IN BOOLEAN TypeMutexLocked, IN KPROCESSOR_MODE AccessMode, OUT PNTSTATUS AccessStatus ); NTKERNELAPI NTSTATUS ObAssignSecurity( IN PACCESS_STATE AccessState, IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PVOID Object, IN POBJECT_TYPE ObjectType ); NTSTATUS ObSetSecurityObjectByPointer ( IN PVOID Object, IN SECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor ); NTSTATUS ObSetHandleAttributes ( IN HANDLE Handle, IN POBJECT_HANDLE_FLAG_INFORMATION HandleFlags, IN KPROCESSOR_MODE PreviousMode ); NTSTATUS ObCloseHandle ( IN HANDLE Handle, IN KPROCESSOR_MODE PreviousMode ); NTKERNELAPI NTSTATUS ObSetSecurityDescriptorInfo( IN PVOID Object, IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping ); // // A PCI driver can read the complete 256 bytes of configuration // information for any PCI device by calling: // // ULONG // HalGetBusData ( // IN BUS_DATA_TYPE PCIConfiguration, // IN ULONG PciBusNumber, // IN PCI_SLOT_NUMBER VirtualSlotNumber, // IN PPCI_COMMON_CONFIG &PCIDeviceConfig, // IN ULONG sizeof (PCIDeviceConfig) // ); // // A return value of 0 means that the specified PCI bus does not exist. // // A return value of 2, with a VendorID of PCI_INVALID_VENDORID means // that the PCI bus does exist, but there is no device at the specified // VirtualSlotNumber (PCI Device/Function number). // // // begin_wdm begin_ntminiport begin_ntndis typedef struct _PCI_SLOT_NUMBER { union { struct { ULONG DeviceNumber:5; ULONG FunctionNumber:3; ULONG Reserved:24; } bits; ULONG AsULONG; } u; } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER; #define PCI_TYPE0_ADDRESSES 6 #define PCI_TYPE1_ADDRESSES 2 #define PCI_TYPE2_ADDRESSES 5 typedef struct _PCI_COMMON_CONFIG { USHORT VendorID; // (ro) USHORT DeviceID; // (ro) USHORT Command; // Device control USHORT Status; UCHAR RevisionID; // (ro) UCHAR ProgIf; // (ro) UCHAR SubClass; // (ro) UCHAR BaseClass; // (ro) UCHAR CacheLineSize; // (ro+) UCHAR LatencyTimer; // (ro+) UCHAR HeaderType; // (ro) UCHAR BIST; // Built in self test union { struct _PCI_HEADER_TYPE_0 { ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; ULONG CIS; USHORT SubVendorID; USHORT SubSystemID; ULONG ROMBaseAddress; UCHAR CapabilitiesPtr; UCHAR Reserved1[3]; ULONG Reserved2; UCHAR InterruptLine; // UCHAR InterruptPin; // (ro) UCHAR MinimumGrant; // (ro) UCHAR MaximumLatency; // (ro) } type0; // end_wdm end_ntminiport end_ntndis // // PCI to PCI Bridge // struct _PCI_HEADER_TYPE_1 { ULONG BaseAddresses[PCI_TYPE1_ADDRESSES]; UCHAR PrimaryBus; UCHAR SecondaryBus; UCHAR SubordinateBus; UCHAR SecondaryLatency; UCHAR IOBase; UCHAR IOLimit; USHORT SecondaryStatus; USHORT MemoryBase; USHORT MemoryLimit; USHORT PrefetchBase; USHORT PrefetchLimit; ULONG PrefetchBaseUpper32; ULONG PrefetchLimitUpper32; USHORT IOBaseUpper16; USHORT IOLimitUpper16; UCHAR CapabilitiesPtr; UCHAR Reserved1[3]; ULONG ROMBaseAddress; UCHAR InterruptLine; UCHAR InterruptPin; USHORT BridgeControl; } type1; // // PCI to CARDBUS Bridge // struct _PCI_HEADER_TYPE_2 { ULONG SocketRegistersBaseAddress; UCHAR CapabilitiesPtr; UCHAR Reserved; USHORT SecondaryStatus; UCHAR PrimaryBus; UCHAR SecondaryBus; UCHAR SubordinateBus; UCHAR SecondaryLatency; struct { ULONG Base; ULONG Limit; } Range[PCI_TYPE2_ADDRESSES-1]; UCHAR InterruptLine; UCHAR InterruptPin; USHORT BridgeControl; } type2; // begin_wdm begin_ntminiport begin_ntndis } u; UCHAR DeviceSpecific[192]; } PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG; #define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific)) #define PCI_MAX_DEVICES 32 #define PCI_MAX_FUNCTION 8 #define PCI_MAX_BRIDGE_NUMBER 0xFF #define PCI_INVALID_VENDORID 0xFFFF // // Bit encodings for PCI_COMMON_CONFIG.HeaderType // #define PCI_MULTIFUNCTION 0x80 #define PCI_DEVICE_TYPE 0x00 #define PCI_BRIDGE_TYPE 0x01 #define PCI_CARDBUS_BRIDGE_TYPE 0x02 #define PCI_CONFIGURATION_TYPE(PciData) \ (((PPCI_COMMON_CONFIG)(PciData))->HeaderType & ~PCI_MULTIFUNCTION) #define PCI_MULTIFUNCTION_DEVICE(PciData) \ ((((PPCI_COMMON_CONFIG)(PciData))->HeaderType & PCI_MULTIFUNCTION) != 0) // // Bit encodings for PCI_COMMON_CONFIG.Command // #define PCI_ENABLE_IO_SPACE 0x0001 #define PCI_ENABLE_MEMORY_SPACE 0x0002 #define PCI_ENABLE_BUS_MASTER 0x0004 #define PCI_ENABLE_SPECIAL_CYCLES 0x0008 #define PCI_ENABLE_WRITE_AND_INVALIDATE 0x0010 #define PCI_ENABLE_VGA_COMPATIBLE_PALETTE 0x0020 #define PCI_ENABLE_PARITY 0x0040 // (ro+) #define PCI_ENABLE_WAIT_CYCLE 0x0080 // (ro+) #define PCI_ENABLE_SERR 0x0100 // (ro+) #define PCI_ENABLE_FAST_BACK_TO_BACK 0x0200 // (ro) // // Bit encodings for PCI_COMMON_CONFIG.Status // #define PCI_STATUS_CAPABILITIES_LIST 0x0010 // (ro) #define PCI_STATUS_66MHZ_CAPABLE 0x0020 // (ro) #define PCI_STATUS_UDF_SUPPORTED 0x0040 // (ro) #define PCI_STATUS_FAST_BACK_TO_BACK 0x0080 // (ro) #define PCI_STATUS_DATA_PARITY_DETECTED 0x0100 #define PCI_STATUS_DEVSEL 0x0600 // 2 bits wide #define PCI_STATUS_SIGNALED_TARGET_ABORT 0x0800 #define PCI_STATUS_RECEIVED_TARGET_ABORT 0x1000 #define PCI_STATUS_RECEIVED_MASTER_ABORT 0x2000 #define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000 #define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000 // // The NT PCI Driver uses a WhichSpace parameter on its CONFIG_READ/WRITE // routines. The following values are defined- // #define PCI_WHICHSPACE_CONFIG 0x0 #define PCI_WHICHSPACE_ROM 0x52696350 // end_wdm // // PCI Capability IDs // #define PCI_CAPABILITY_ID_POWER_MANAGEMENT 0x01 #define PCI_CAPABILITY_ID_AGP 0x02 #define PCI_CAPABILITY_ID_MSI 0x05 // // All PCI Capability structures have the following header. // // CapabilityID is used to identify the type of the structure (is // one of the PCI_CAPABILITY_ID values above. // // Next is the offset in PCI Configuration space (0x40 - 0xfc) of the // next capability structure in the list, or 0x00 if there are no more // entries. // typedef struct _PCI_CAPABILITIES_HEADER { UCHAR CapabilityID; UCHAR Next; } PCI_CAPABILITIES_HEADER, *PPCI_CAPABILITIES_HEADER; // // Power Management Capability // typedef struct _PCI_PMC { UCHAR Version:3; UCHAR PMEClock:1; UCHAR Rsvd1:1; UCHAR DeviceSpecificInitialization:1; UCHAR Rsvd2:2; struct _PM_SUPPORT { UCHAR Rsvd2:1; UCHAR D1:1; UCHAR D2:1; UCHAR PMED0:1; UCHAR PMED1:1; UCHAR PMED2:1; UCHAR PMED3Hot:1; UCHAR PMED3Cold:1; } Support; } PCI_PMC, *PPCI_PMC; typedef struct _PCI_PMCSR { USHORT PowerState:2; USHORT Rsvd1:6; USHORT PMEEnable:1; USHORT DataSelect:4; USHORT DataScale:2; USHORT PMEStatus:1; } PCI_PMCSR, *PPCI_PMCSR; typedef struct _PCI_PMCSR_BSE { UCHAR Rsvd1:6; UCHAR D3HotSupportsStopClock:1; // B2_B3# UCHAR BusPowerClockControlEnabled:1; // BPCC_EN } PCI_PMCSR_BSE, *PPCI_PMCSR_BSE; typedef struct _PCI_PM_CAPABILITY { PCI_CAPABILITIES_HEADER Header; // // Power Management Capabilities (Offset = 2) // union { PCI_PMC Capabilities; USHORT AsUSHORT; } PMC; // // Power Management Control/Status (Offset = 4) // union { PCI_PMCSR ControlStatus; USHORT AsUSHORT; } PMCSR; // // PMCSR PCI-PCI Bridge Support Extensions // union { PCI_PMCSR_BSE BridgeSupport; UCHAR AsUCHAR; } PMCSR_BSE; // // Optional read only 8 bit Data register. Contents controlled by // DataSelect and DataScale in ControlStatus. // UCHAR Data; } PCI_PM_CAPABILITY, *PPCI_PM_CAPABILITY; // // AGP Capability // typedef struct _PCI_AGP_CAPABILITY { PCI_CAPABILITIES_HEADER Header; USHORT Minor:4; USHORT Major:4; USHORT Rsvd1:8; struct _PCI_AGP_STATUS { ULONG Rate:3; ULONG Rsvd1:1; ULONG FastWrite:1; ULONG FourGB:1; ULONG Rsvd2:3; ULONG SideBandAddressing:1; // SBA ULONG Rsvd3:14; ULONG RequestQueueDepthMaximum:8; // RQ } AGPStatus; struct _PCI_AGP_COMMAND { ULONG Rate:3; ULONG Rsvd1:1; ULONG FastWriteEnable:1; ULONG FourGBEnable:1; ULONG Rsvd2:2; ULONG AGPEnable:1; ULONG SBAEnable:1; ULONG Rsvd3:14; ULONG RequestQueueDepth:8; } AGPCommand; } PCI_AGP_CAPABILITY, *PPCI_AGP_CAPABILITY; #define PCI_AGP_RATE_1X 0x1 #define PCI_AGP_RATE_2X 0x2 #define PCI_AGP_RATE_4X 0x4 // // MSI (Message Signalled Interrupts) Capability // typedef struct _PCI_MSI_CAPABILITY { PCI_CAPABILITIES_HEADER Header; struct _PCI_MSI_MESSAGE_CONTROL { USHORT MSIEnable:1; USHORT MultipleMessageCapable:3; USHORT MultipleMessageEnable:3; USHORT CapableOf64Bits:1; USHORT Reserved:8; } MessageControl; union { struct _PCI_MSI_MESSAGE_ADDRESS { ULONG_PTR Reserved:2; // always zero, DWORD aligned address ULONG_PTR Address:30; } Register; ULONG_PTR Raw; } MessageAddress; // // The rest of the Capability structure differs depending on whether // 32bit or 64bit addressing is being used. // // (The CapableOf64Bits bit above determines this) // union { // For 64 bit devices struct _PCI_MSI_64BIT_DATA { ULONG MessageUpperAddress; USHORT MessageData; } Bit64; // For 32 bit devices struct _PCI_MSI_32BIT_DATA { USHORT MessageData; ULONG Unused; } Bit32; } Data; } PCI_MSI_CAPABILITY, *PPCI_PCI_CAPABILITY; // begin_wdm // // Base Class Code encodings for Base Class (from PCI spec rev 2.1). // #define PCI_CLASS_PRE_20 0x00 #define PCI_CLASS_MASS_STORAGE_CTLR 0x01 #define PCI_CLASS_NETWORK_CTLR 0x02 #define PCI_CLASS_DISPLAY_CTLR 0x03 #define PCI_CLASS_MULTIMEDIA_DEV 0x04 #define PCI_CLASS_MEMORY_CTLR 0x05 #define PCI_CLASS_BRIDGE_DEV 0x06 #define PCI_CLASS_SIMPLE_COMMS_CTLR 0x07 #define PCI_CLASS_BASE_SYSTEM_DEV 0x08 #define PCI_CLASS_INPUT_DEV 0x09 #define PCI_CLASS_DOCKING_STATION 0x0a #define PCI_CLASS_PROCESSOR 0x0b #define PCI_CLASS_SERIAL_BUS_CTLR 0x0c #define PCI_CLASS_WIRELESS_CTLR 0x0d #define PCI_CLASS_INTELLIGENT_IO_CTLR 0x0e #define PCI_CLASS_SATELLITE_COMMS_CTLR 0x0f #define PCI_CLASS_ENCRYPTION_DECRYPTION 0x10 #define PCI_CLASS_DATA_ACQ_SIGNAL_PROC 0x11 // 0d thru fe reserved #define PCI_CLASS_NOT_DEFINED 0xff // // Sub Class Code encodings (PCI rev 2.1). // // Class 00 - PCI_CLASS_PRE_20 #define PCI_SUBCLASS_PRE_20_NON_VGA 0x00 #define PCI_SUBCLASS_PRE_20_VGA 0x01 // Class 01 - PCI_CLASS_MASS_STORAGE_CTLR #define PCI_SUBCLASS_MSC_SCSI_BUS_CTLR 0x00 #define PCI_SUBCLASS_MSC_IDE_CTLR 0x01 #define PCI_SUBCLASS_MSC_FLOPPY_CTLR 0x02 #define PCI_SUBCLASS_MSC_IPI_CTLR 0x03 #define PCI_SUBCLASS_MSC_RAID_CTLR 0x04 #define PCI_SUBCLASS_MSC_OTHER 0x80 // Class 02 - PCI_CLASS_NETWORK_CTLR #define PCI_SUBCLASS_NET_ETHERNET_CTLR 0x00 #define PCI_SUBCLASS_NET_TOKEN_RING_CTLR 0x01 #define PCI_SUBCLASS_NET_FDDI_CTLR 0x02 #define PCI_SUBCLASS_NET_ATM_CTLR 0x03 #define PCI_SUBCLASS_NET_ISDN_CTLR 0x04 #define PCI_SUBCLASS_NET_OTHER 0x80 // Class 03 - PCI_CLASS_DISPLAY_CTLR // N.B. Sub Class 00 could be VGA or 8514 depending on Interface byte #define PCI_SUBCLASS_VID_VGA_CTLR 0x00 #define PCI_SUBCLASS_VID_XGA_CTLR 0x01 #define PCI_SUBLCASS_VID_3D_CTLR 0x02 #define PCI_SUBCLASS_VID_OTHER 0x80 // Class 04 - PCI_CLASS_MULTIMEDIA_DEV #define PCI_SUBCLASS_MM_VIDEO_DEV 0x00 #define PCI_SUBCLASS_MM_AUDIO_DEV 0x01 #define PCI_SUBCLASS_MM_TELEPHONY_DEV 0x02 #define PCI_SUBCLASS_MM_OTHER 0x80 // Class 05 - PCI_CLASS_MEMORY_CTLR #define PCI_SUBCLASS_MEM_RAM 0x00 #define PCI_SUBCLASS_MEM_FLASH 0x01 #define PCI_SUBCLASS_MEM_OTHER 0x80 // Class 06 - PCI_CLASS_BRIDGE_DEV #define PCI_SUBCLASS_BR_HOST 0x00 #define PCI_SUBCLASS_BR_ISA 0x01 #define PCI_SUBCLASS_BR_EISA 0x02 #define PCI_SUBCLASS_BR_MCA 0x03 #define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 #define PCI_SUBCLASS_BR_PCMCIA 0x05 #define PCI_SUBCLASS_BR_NUBUS 0x06 #define PCI_SUBCLASS_BR_CARDBUS 0x07 #define PCI_SUBCLASS_BR_RACEWAY 0x08 #define PCI_SUBCLASS_BR_OTHER 0x80 // Class 07 - PCI_CLASS_SIMPLE_COMMS_CTLR // N.B. Sub Class 00 and 01 additional info in Interface byte #define PCI_SUBCLASS_COM_SERIAL 0x00 #define PCI_SUBCLASS_COM_PARALLEL 0x01 #define PCI_SUBCLASS_COM_MULTIPORT 0x02 #define PCI_SUBCLASS_COM_MODEM 0x03 #define PCI_SUBCLASS_COM_OTHER 0x80 // Class 08 - PCI_CLASS_BASE_SYSTEM_DEV // N.B. See Interface byte for additional info. #define PCI_SUBCLASS_SYS_INTERRUPT_CTLR 0x00 #define PCI_SUBCLASS_SYS_DMA_CTLR 0x01 #define PCI_SUBCLASS_SYS_SYSTEM_TIMER 0x02 #define PCI_SUBCLASS_SYS_REAL_TIME_CLOCK 0x03 #define PCI_SUBCLASS_SYS_GEN_HOTPLUG_CTLR 0x04 #define PCI_SUBCLASS_SYS_OTHER 0x80 // Class 09 - PCI_CLASS_INPUT_DEV #define PCI_SUBCLASS_INP_KEYBOARD 0x00 #define PCI_SUBCLASS_INP_DIGITIZER 0x01 #define PCI_SUBCLASS_INP_MOUSE 0x02 #define PCI_SUBCLASS_INP_SCANNER 0x03 #define PCI_SUBCLASS_INP_GAMEPORT 0x04 #define PCI_SUBCLASS_INP_OTHER 0x80 // Class 0a - PCI_CLASS_DOCKING_STATION #define PCI_SUBCLASS_DOC_GENERIC 0x00 #define PCI_SUBCLASS_DOC_OTHER 0x80 // Class 0b - PCI_CLASS_PROCESSOR #define PCI_SUBCLASS_PROC_386 0x00 #define PCI_SUBCLASS_PROC_486 0x01 #define PCI_SUBCLASS_PROC_PENTIUM 0x02 #define PCI_SUBCLASS_PROC_ALPHA 0x10 #define PCI_SUBCLASS_PROC_POWERPC 0x20 #define PCI_SUBCLASS_PROC_COPROCESSOR 0x40 // Class 0c - PCI_CLASS_SERIAL_BUS_CTLR #define PCI_SUBCLASS_SB_IEEE1394 0x00 #define PCI_SUBCLASS_SB_ACCESS 0x01 #define PCI_SUBCLASS_SB_SSA 0x02 #define PCI_SUBCLASS_SB_USB 0x03 #define PCI_SUBCLASS_SB_FIBRE_CHANNEL 0x04 #define PCI_SUBCLASS_SB_SMBUS 0x05 // Class 0d - PCI_CLASS_WIRELESS_CTLR #define PCI_SUBCLASS_WIRELESS_IRDA 0x00 #define PCI_SUBCLASS_WIRELESS_CON_IR 0x01 #define PCI_SUBCLASS_WIRELESS_RF 0x10 #define PCI_SUBCLASS_WIRELESS_OTHER 0x80 // Class 0e - PCI_CLASS_INTELLIGENT_IO_CTLR #define PCI_SUBCLASS_INTIO_I2O 0x00 // Class 0f - PCI_CLASS_SATELLITE_CTLR #define PCI_SUBCLASS_SAT_TV 0x01 #define PCI_SUBCLASS_SAT_AUDIO 0x02 #define PCI_SUBCLASS_SAT_VOICE 0x03 #define PCI_SUBCLASS_SAT_DATA 0x04 // Class 10 - PCI_CLASS_ENCRYPTION_DECRYPTION #define PCI_SUBCLASS_CRYPTO_NET_COMP 0x00 #define PCI_SUBCLASS_CRYPTO_ENTERTAINMENT 0x10 #define PCI_SUBCLASS_CRYPTO_OTHER 0x80 // Class 11 - PCI_CLASS_DATA_ACQ_SIGNAL_PROC #define PCI_SUBCLASS_DASP_DPIO 0x00 #define PCI_SUBCLASS_DASP_OTHER 0x80 // end_ntndis // // Bit encodes for PCI_COMMON_CONFIG.u.type0.BaseAddresses // #define PCI_ADDRESS_IO_SPACE 0x00000001 // (ro) #define PCI_ADDRESS_MEMORY_TYPE_MASK 0x00000006 // (ro) #define PCI_ADDRESS_MEMORY_PREFETCHABLE 0x00000008 // (ro) #define PCI_ADDRESS_IO_ADDRESS_MASK 0xfffffffc #define PCI_ADDRESS_MEMORY_ADDRESS_MASK 0xfffffff0 #define PCI_ADDRESS_ROM_ADDRESS_MASK 0xfffff800 #define PCI_TYPE_32BIT 0 #define PCI_TYPE_20BIT 2 #define PCI_TYPE_64BIT 4 // // Bit encodes for PCI_COMMON_CONFIG.u.type0.ROMBaseAddresses // #define PCI_ROMADDRESS_ENABLED 0x00000001 // // Reference notes for PCI configuration fields: // // ro these field are read only. changes to these fields are ignored // // ro+ these field are intended to be read only and should be initialized // by the system to their proper values. However, driver may change // these settings. // // --- // // All resources comsumed by a PCI device start as unitialized // under NT. An uninitialized memory or I/O base address can be // determined by checking it's corrisponding enabled bit in the // PCI_COMMON_CONFIG.Command value. An InterruptLine is unitialized // if it contains the value of -1. // // end_wdm end_ntminiport // // Portable portion of HAL & HAL bus extender definitions for BUSHANDLER // BusData for installed PCI buses. // typedef VOID (*PciPin2Line) ( IN struct _BUS_HANDLER *BusHandler, IN struct _BUS_HANDLER *RootHandler, IN PCI_SLOT_NUMBER SlotNumber, IN PPCI_COMMON_CONFIG PciData ); typedef VOID (*PciLine2Pin) ( IN struct _BUS_HANDLER *BusHandler, IN struct _BUS_HANDLER *RootHandler, IN PCI_SLOT_NUMBER SlotNumber, IN PPCI_COMMON_CONFIG PciNewData, IN PPCI_COMMON_CONFIG PciOldData ); typedef VOID (*PciReadWriteConfig) ( IN struct _BUS_HANDLER *BusHandler, IN PCI_SLOT_NUMBER Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ); #define PCI_DATA_TAG ' ICP' #define PCI_DATA_VERSION 1 typedef struct _PCIBUSDATA { ULONG Tag; ULONG Version; PciReadWriteConfig ReadConfig; PciReadWriteConfig WriteConfig; PciPin2Line Pin2Line; PciLine2Pin Line2Pin; PCI_SLOT_NUMBER ParentSlot; PVOID Reserved[4]; } PCIBUSDATA, *PPCIBUSDATA; typedef ULONG (*PCI_READ_WRITE_CONFIG)( IN PVOID Context, IN UCHAR BusOffset, IN ULONG Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ); typedef VOID (*PCI_PIN_TO_LINE)( IN PVOID Context, IN PPCI_COMMON_CONFIG PciData ); typedef VOID (*PCI_LINE_TO_PIN)( IN PVOID Context, IN PPCI_COMMON_CONFIG PciNewData, IN PPCI_COMMON_CONFIG PciOldData ); typedef struct _PCI_BUS_INTERFACE_STANDARD { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // standard PCI bus interfaces // PCI_READ_WRITE_CONFIG ReadConfig; PCI_READ_WRITE_CONFIG WriteConfig; PCI_PIN_TO_LINE PinToLine; PCI_LINE_TO_PIN LineToPin; } PCI_BUS_INTERFACE_STANDARD, *PPCI_BUS_INTERFACE_STANDARD; #define PCI_BUS_INTERFACE_STANDARD_VERSION 1 // begin_wdm #define PCI_DEVICE_PRESENT_INTERFACE_VERSION 1 // // Flags for PCI_DEVICE_PRESENCE_PARAMETERS // #define PCI_USE_SUBSYSTEM_IDS 0x00000001 #define PCI_USE_REVISION 0x00000002 // The following flags are only valid for IsDevicePresentEx #define PCI_USE_VENDEV_IDS 0x00000004 #define PCI_USE_CLASS_SUBCLASS 0x00000008 #define PCI_USE_PROGIF 0x00000010 #define PCI_USE_LOCAL_BUS 0x00000020 #define PCI_USE_LOCAL_DEVICE 0x00000040 // // Search parameters structure for IsDevicePresentEx // typedef struct _PCI_DEVICE_PRESENCE_PARAMETERS { ULONG Size; ULONG Flags; USHORT VendorID; USHORT DeviceID; UCHAR RevisionID; USHORT SubVendorID; USHORT SubSystemID; UCHAR BaseClass; UCHAR SubClass; UCHAR ProgIf; } PCI_DEVICE_PRESENCE_PARAMETERS, *PPCI_DEVICE_PRESENCE_PARAMETERS; typedef BOOLEAN (*PPCI_IS_DEVICE_PRESENT) ( IN USHORT VendorID, IN USHORT DeviceID, IN UCHAR RevisionID, IN USHORT SubVendorID, IN USHORT SubSystemID, IN ULONG Flags ); typedef BOOLEAN (*PPCI_IS_DEVICE_PRESENT_EX) ( IN PVOID Context, IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters ); typedef struct _PCI_DEVICE_PRESENT_INTERFACE { // // generic interface header // USHORT Size; USHORT Version; PVOID Context; PINTERFACE_REFERENCE InterfaceReference; PINTERFACE_DEREFERENCE InterfaceDereference; // // pci device info // PPCI_IS_DEVICE_PRESENT IsDevicePresent; PPCI_IS_DEVICE_PRESENT_EX IsDevicePresentEx; } PCI_DEVICE_PRESENT_INTERFACE, *PPCI_DEVICE_PRESENT_INTERFACE; // // Normal uncompressed Copy and Mdl Apis // NTKERNELAPI BOOLEAN FsRtlCopyRead ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ); NTKERNELAPI BOOLEAN FsRtlCopyWrite ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject ); // end_ntifs NTKERNELAPI BOOLEAN FsRtlMdlRead ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus ); BOOLEAN FsRtlMdlReadComplete ( IN PFILE_OBJECT FileObject, IN PMDL MdlChain ); #define LEGAL_ANSI_CHARACTER_ARRAY (*FsRtlLegalAnsiCharacterArray) #define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo) extern UCHAR const* const LEGAL_ANSI_CHARACTER_ARRAY; extern PUSHORT NLS_OEM_LEAD_BYTE_INFO; // Lead byte info. for ACP // // These following bit values are set in the FsRtlLegalDbcsCharacterArray // #define FSRTL_FAT_LEGAL 0x01 #define FSRTL_HPFS_LEGAL 0x02 #define FSRTL_NTFS_LEGAL 0x04 #define FSRTL_WILD_CHARACTER 0x08 #define FSRTL_OLE_LEGAL 0x10 #define FSRTL_NTFS_STREAM_LEGAL (FSRTL_NTFS_LEGAL | FSRTL_OLE_LEGAL) // // The following macro is used to determine if an Ansi character is wild. // #define FsRtlIsAnsiCharacterWild(C) ( \ FsRtlTestAnsiCharacter((C), FALSE, FALSE, FSRTL_WILD_CHARACTER) \ ) // // The following macro is used to determine if an Ansi character is Fat legal. // #define FsRtlIsAnsiCharacterLegalFat(C,WILD_OK) ( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_FAT_LEGAL) \ ) // // The following macro is used to determine if an Ansi character is Hpfs legal. // #define FsRtlIsAnsiCharacterLegalHpfs(C,WILD_OK) ( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_HPFS_LEGAL) \ ) // // The following macro is used to determine if an Ansi character is Ntfs legal. // #define FsRtlIsAnsiCharacterLegalNtfs(C,WILD_OK) ( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_LEGAL) \ ) // // The following macro is used to determine if an Ansi character is // legal in an Ntfs stream name // #define FsRtlIsAnsiCharacterLegalNtfsStream(C,WILD_OK) ( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_STREAM_LEGAL) \ ) // // The following macro is used to determine if an Ansi character is legal, // according to the caller's specification. // #define FsRtlIsAnsiCharacterLegal(C,FLAGS) ( \ FsRtlTestAnsiCharacter((C), TRUE, FALSE, (FLAGS)) \ ) // // The following macro is used to test attributes of an Ansi character, // according to the caller's specified flags. // #define FsRtlTestAnsiCharacter(C, DEFAULT_RET, WILD_OK, FLAGS) ( \ ((SCHAR)(C) < 0) ? DEFAULT_RET : \ FlagOn( LEGAL_ANSI_CHARACTER_ARRAY[(C)], \ (FLAGS) | \ ((WILD_OK) ? FSRTL_WILD_CHARACTER : 0) ) \ ) // // The following two macros use global data defined in ntos\rtl\nlsdata.c // // BOOLEAN // FsRtlIsLeadDbcsCharacter ( // IN UCHAR DbcsCharacter // ); // // /*++ // // Routine Description: // // This routine takes the first bytes of a Dbcs character and // returns whether it is a lead byte in the system code page. // // Arguments: // // DbcsCharacter - Supplies the input character being examined // // Return Value: // // BOOLEAN - TRUE if the input character is a dbcs lead and // FALSE otherwise // // --*/ // // #define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \ (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \ (NLS_MB_CODE_PAGE_TAG && \ (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \ ) NTKERNELAPI VOID FsRtlDissectDbcs ( IN ANSI_STRING InputName, OUT PANSI_STRING FirstPart, OUT PANSI_STRING RemainingPart ); NTKERNELAPI BOOLEAN FsRtlDoesDbcsContainWildCards ( IN PANSI_STRING Name ); NTKERNELAPI BOOLEAN FsRtlIsDbcsInExpression ( IN PANSI_STRING Expression, IN PANSI_STRING Name ); NTKERNELAPI BOOLEAN FsRtlIsFatDbcsLegal ( IN ANSI_STRING DbcsName, IN BOOLEAN WildCardsPermissible, IN BOOLEAN PathNamePermissible, IN BOOLEAN LeadingBackslashPermissible ); NTKERNELAPI NTSTATUS LpcRequestPort( IN PVOID PortAddress, IN PPORT_MESSAGE RequestMessage ); NTSTATUS LpcRequestWaitReplyPort( IN PVOID PortAddress, IN PPORT_MESSAGE RequestMessage, OUT PPORT_MESSAGE ReplyMessage ); NTSTATUS LpcRequestWaitReplyPortEx ( IN PVOID PortAddress, IN PPORT_MESSAGE RequestMessage, OUT PPORT_MESSAGE ReplyMessage ); NTSTATUS LpcDisconnectPort ( IN PVOID Port ); extern POBJECT_TYPE *ExEventPairObjectType; extern POBJECT_TYPE *IoFileObjectType; extern POBJECT_TYPE *IoDriverObjectType; extern POBJECT_TYPE *PsProcessType; extern POBJECT_TYPE *PsThreadType; extern POBJECT_TYPE *PsJobType; extern POBJECT_TYPE *LpcPortObjectType; extern POBJECT_TYPE *LpcWaitablePortObjectType; extern POBJECT_TYPE MmSectionObjectType; #ifdef __cplusplus } // extern "C" #endif #endif // _NTOSP_