You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
21415 lines
498 KiB
21415 lines
498 KiB
/*++ BUILD Version: 0134 // 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 <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <excpt.h>
|
|
#include <ntdef.h>
|
|
#include <bugcodes.h>
|
|
#include <arc.h>
|
|
#include <arccodes.h>
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// Define DPC type indicies.
|
|
//
|
|
|
|
#define DPC_NORMAL 0
|
|
#define DPC_THREADED 1
|
|
|
|
//
|
|
// 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;
|
|
PVOID DpcData;
|
|
} 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;
|
|
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
// One simply calculates the base of the array by adding one to the base
|
|
// MDL pointer:
|
|
//
|
|
// Pages = (PPFN_NUMBER) (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_DESCRIBES_AWE 0x0400
|
|
#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 {
|
|
union {
|
|
struct {
|
|
UCHAR Type;
|
|
UCHAR Absolute;
|
|
UCHAR Size;
|
|
union {
|
|
UCHAR Inserted;
|
|
BOOLEAN DebugActive;
|
|
};
|
|
};
|
|
|
|
volatile LONG Lock;
|
|
};
|
|
|
|
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;
|
|
|
|
typedef enum _LOCK_OPERATION {
|
|
IoReadAccess,
|
|
IoWriteAccess,
|
|
IoModifyAccess
|
|
} LOCK_OPERATION;
|
|
|
|
|
|
#ifndef _SLIST_HEADER_
|
|
#define _SLIST_HEADER_
|
|
|
|
#if defined(_WIN64)
|
|
|
|
//
|
|
// The type SINGLE_LIST_ENTRY is not suitable for use with SLISTs. For
|
|
// WIN64, an entry on an SLIST is required to be 16-byte aligned, while a
|
|
// SINGLE_LIST_ENTRY structure has only 8 byte alignment.
|
|
//
|
|
// Therefore, all SLIST code should use the SLIST_ENTRY type instead of the
|
|
// SINGLE_LIST_ENTRY type.
|
|
//
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4324) // structure padded due to align()
|
|
typedef struct DECLSPEC_ALIGN(16) _SLIST_ENTRY *PSLIST_ENTRY;
|
|
typedef struct DECLSPEC_ALIGN(16) _SLIST_ENTRY {
|
|
PSLIST_ENTRY Next;
|
|
} SLIST_ENTRY;
|
|
#pragma warning(pop)
|
|
|
|
#else
|
|
|
|
#define SLIST_ENTRY SINGLE_LIST_ENTRY
|
|
#define _SLIST_ENTRY _SINGLE_LIST_ENTRY
|
|
#define PSLIST_ENTRY PSINGLE_LIST_ENTRY
|
|
|
|
#endif
|
|
|
|
#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
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlIpv4AddressToStringExA(
|
|
IN const struct in_addr *Address,
|
|
IN USHORT Port,
|
|
OUT PSTR AddressString,
|
|
IN OUT PULONG AddressStringLength
|
|
);
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlIpv6AddressToStringExA(
|
|
IN const struct in6_addr *Address,
|
|
IN ULONG ScopeId,
|
|
IN USHORT Port,
|
|
OUT PSTR AddressString,
|
|
IN OUT PULONG AddressStringLength
|
|
);
|
|
|
|
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
|
|
RtlIpv4AddressToStringExW(
|
|
IN const struct in_addr *Address,
|
|
IN USHORT Port,
|
|
OUT PWSTR AddressString,
|
|
IN OUT PULONG AddressStringLength
|
|
);
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlIpv6AddressToStringExW(
|
|
IN const struct in6_addr *Address,
|
|
IN ULONG ScopeId,
|
|
IN USHORT Port,
|
|
OUT PWSTR AddressString,
|
|
IN OUT PULONG AddressStringLength
|
|
);
|
|
|
|
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
|
|
RtlIpv4StringToAddressExA (
|
|
IN PCSTR AddressString,
|
|
IN BOOLEAN Strict,
|
|
OUT struct in_addr *Address,
|
|
OUT PUSHORT Port
|
|
);
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlIpv6StringToAddressExA (
|
|
IN PCSTR AddressString,
|
|
OUT struct in6_addr *Address,
|
|
OUT PULONG ScopeId,
|
|
OUT PUSHORT Port
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlIpv4StringToAddressExW (
|
|
IN PCWSTR AddressString,
|
|
IN BOOLEAN Strict,
|
|
OUT struct in_addr *Address,
|
|
OUT PUSHORT Port
|
|
);
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlIpv6StringToAddressExW (
|
|
IN PCWSTR AddressString,
|
|
OUT struct in6_addr *Address,
|
|
OUT PULONG ScopeId,
|
|
OUT PUSHORT Port
|
|
);
|
|
|
|
#ifdef UNICODE
|
|
#define RtlIpv4AddressToString RtlIpv4AddressToStringW
|
|
#define RtlIpv6AddressToString RtlIpv6AddressToStringW
|
|
#define RtlIpv4StringToAddress RtlIpv4StringToAddressW
|
|
#define RtlIpv6StringToAddress RtlIpv6StringToAddressW
|
|
#define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExW
|
|
#define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExW
|
|
#define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExW
|
|
#define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExW
|
|
#else
|
|
#define RtlIpv4AddressToString RtlIpv4AddressToStringA
|
|
#define RtlIpv6AddressToString RtlIpv6AddressToStringA
|
|
#define RtlIpv4StringToAddress RtlIpv4StringToAddressA
|
|
#define RtlIpv6StringToAddress RtlIpv6StringToAddressA
|
|
#define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExA
|
|
#define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExA
|
|
#define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExA
|
|
#define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExA
|
|
#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 32
|
|
|
|
//
|
|
// 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
|
|
|
|
#define SYNCH_LEVEL (IPI_LEVEL-2)
|
|
#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
|
|
|
|
|
|
#define IDT_NMI_VECTOR 2
|
|
#define IDT_DFH_VECTOR 8
|
|
#define NMI_TSS_DESC_OFFSET 0x58
|
|
#define DF_TSS_DESC_OFFSET 0x50
|
|
|
|
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// DPC data structure definition.
|
|
//
|
|
|
|
typedef struct _KDPC_DATA {
|
|
LIST_ENTRY DpcListHead;
|
|
KSPIN_LOCK DpcLock;
|
|
volatile ULONG DpcQueueDepth;
|
|
ULONG DpcCount;
|
|
} KDPC_DATA, *PKDPC_DATA;
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
// Certain fields in the TIB are not used in kernel mode. These include the
|
|
// stack limit, subsystem TIB, fiber data, arbitrary user pointer, and the
|
|
// self address of then PCR itself (another field has been added for that
|
|
// purpose). Therefore, these fields are overlaid with other data to get
|
|
// better cache locality.
|
|
//
|
|
|
|
union {
|
|
NT_TIB NtTib;
|
|
struct {
|
|
struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList;
|
|
PVOID Used_StackBase;
|
|
PVOID PerfGlobalGroupMask;
|
|
PVOID TssCopy;
|
|
ULONG ContextSwitches;
|
|
KAFFINITY SetMemberCopy;
|
|
PVOID Used_Self;
|
|
};
|
|
};
|
|
|
|
struct _KPCR *SelfPcr; // flat address of this PCR
|
|
struct _KPRCB *Prcb; // pointer to Prcb
|
|
KIRQL Irql; // do not use 3 bytes after this as
|
|
// HALs assume they are zero.
|
|
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 SpareUnused;
|
|
UCHAR Number;
|
|
|
|
|
|
} KPCR, *PKPCR;
|
|
|
|
|
|
//
|
|
// bits defined in Eflags
|
|
//
|
|
|
|
#define EFLAGS_CF_MASK 0x00000001L
|
|
#define EFLAGS_PF_MASK 0x00000004L
|
|
#define EFLAGS_AF_MASK 0x00000010L
|
|
#define EFLAGS_ZF_MASK 0x00000040L
|
|
#define EFLAGS_SF_MASK 0x00000080L
|
|
#define EFLAGS_TF 0x00000100L
|
|
#define EFLAGS_INTERRUPT_MASK 0x00000200L
|
|
#define EFLAGS_DF_MASK 0x00000400L
|
|
#define EFLAGS_OF_MASK 0x00000800L
|
|
#define EFLAGS_IOPL_MASK 0x00003000L
|
|
#define EFLAGS_NT 0x00004000L
|
|
#define EFLAGS_RF 0x00010000L
|
|
#define EFLAGS_V86_MASK 0x00020000L
|
|
#define EFLAGS_ALIGN_CHECK 0x00040000L
|
|
#define EFLAGS_VIF 0x00080000L
|
|
#define EFLAGS_VIP 0x00100000L
|
|
#define EFLAGS_ID_MASK 0x00200000L
|
|
|
|
#define EFLAGS_USER_SANITIZE 0x003f4dd7L
|
|
|
|
// 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) & 0x003f0fd7)) : \
|
|
((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 ApcBypassDisable;
|
|
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_INTRINSICS || _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
|
|
|
|
#define InterlockedIncrementAcquire InterlockedIncrement
|
|
#define InterlockedIncrementRelease InterlockedIncrement
|
|
#define InterlockedDecrementAcquire InterlockedDecrement
|
|
#define InterlockedDecrementRelease InterlockedDecrement
|
|
#define InterlockedExchangeAcquire64 InterlockedExchange64
|
|
#define InterlockedCompareExchangeAcquire InterlockedCompareExchange
|
|
#define InterlockedCompareExchangeRelease InterlockedCompareExchange
|
|
#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64
|
|
#define InterlockedCompareExchangeRelease64 InterlockedCompareExchange64
|
|
|
|
#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
|
|
//
|
|
|
|
// end_wdm
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(push)
|
|
#endif
|
|
#pragma warning(disable:4035) // re-enable below
|
|
|
|
#define _PCR fs:[0]
|
|
|
|
//
|
|
// Get address of current processor block.
|
|
//
|
|
// WARNING: This inline macro can only be used by the kernel or hal
|
|
//
|
|
FORCEINLINE
|
|
PKPRCB
|
|
NTAPI
|
|
KeGetCurrentPrcb (VOID)
|
|
{
|
|
#if (_MSC_FULL_VER >= 13012035)
|
|
return (PKPRCB) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, Prcb));
|
|
#else
|
|
__asm { mov eax, _PCR KPCR.Prcb }
|
|
#endif
|
|
}
|
|
|
|
// begin_ntddk begin_wdm
|
|
|
|
//
|
|
// Get current IRQL.
|
|
//
|
|
// On x86 this function resides in the HAL
|
|
//
|
|
|
|
// end_ntddk end_wdm
|
|
|
|
#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || !defined(_APIC_TPR_)
|
|
|
|
// begin_ntddk begin_wdm
|
|
|
|
NTHALAPI
|
|
KIRQL
|
|
NTAPI
|
|
KeGetCurrentIrql();
|
|
|
|
// end_ntddk end_wdm
|
|
|
|
#endif
|
|
|
|
// begin_ntddk begin_wdm
|
|
|
|
// end_wdm
|
|
//
|
|
// Get the current processor number
|
|
//
|
|
|
|
FORCEINLINE
|
|
ULONG
|
|
NTAPI
|
|
KeGetCurrentProcessorNumber(VOID)
|
|
{
|
|
#if (_MSC_FULL_VER >= 13012035)
|
|
return (ULONG) __readfsbyte (FIELD_OFFSET (KPCR, Number));
|
|
#else
|
|
__asm { movzx eax, _PCR KPCR.Number }
|
|
#endif
|
|
}
|
|
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(pop)
|
|
#else
|
|
#pragma warning(default:4035)
|
|
#endif
|
|
|
|
// begin_wdm
|
|
#endif // !defined(MIDL_PASS) && defined(_M_IX86)
|
|
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// KeMemoryBarrier (
|
|
// VOID
|
|
// )
|
|
//
|
|
// VOID
|
|
// KeMemoryBarrierWithoutFence (
|
|
// VOID
|
|
// )
|
|
//
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// These functions order memory accesses as seen by other processors.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
VOID
|
|
_ReadWriteBarrier(
|
|
VOID
|
|
);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#pragma intrinsic (_ReadWriteBarrier)
|
|
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
KeMemoryBarrier (
|
|
VOID
|
|
)
|
|
{
|
|
LONG Barrier;
|
|
__asm {
|
|
xchg Barrier, eax
|
|
}
|
|
}
|
|
|
|
#define KeMemoryBarrierWithoutFence() _ReadWriteBarrier()
|
|
|
|
|
|
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(
|
|
VOID
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
ULONG
|
|
Ki386DispatchOpcode (
|
|
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 InterlockedIncrementAcquire InterlockedIncrement
|
|
#define InterlockedIncrementRelease InterlockedIncrement
|
|
#define InterlockedDecrement _InterlockedDecrement
|
|
#define InterlockedDecrementAcquire InterlockedDecrement
|
|
#define InterlockedDecrementRelease InterlockedDecrement
|
|
#define InterlockedAdd _InterlockedAdd
|
|
#define InterlockedExchange _InterlockedExchange
|
|
#define InterlockedExchangeAdd _InterlockedExchangeAdd
|
|
#define InterlockedCompareExchange _InterlockedCompareExchange
|
|
#define InterlockedCompareExchangeAcquire InterlockedCompareExchange
|
|
#define InterlockedCompareExchangeRelease InterlockedCompareExchange
|
|
|
|
#define InterlockedAnd64 _InterlockedAnd64
|
|
#define InterlockedOr64 _InterlockedOr64
|
|
#define InterlockedXor64 _InterlockedXor64
|
|
#define InterlockedIncrement64 _InterlockedIncrement64
|
|
#define InterlockedDecrement64 _InterlockedDecrement64
|
|
#define InterlockedAdd64 _InterlockedAdd64
|
|
#define InterlockedExchange64 _InterlockedExchange64
|
|
#define InterlockedExchangeAcquire64 InterlockedExchange64
|
|
#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
|
|
#define InterlockedCompareExchange64 _InterlockedCompareExchange64
|
|
#define InterlockedCompareExchangeAcquire64 InterlockedCompareExchange64
|
|
#define InterlockedCompareExchangeRelease64 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 32
|
|
|
|
//
|
|
// 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
|
|
|
|
#define SYNCH_LEVEL (IPI_LEVEL-2)
|
|
#define MODE_MASK 1
|
|
|
|
//
|
|
// I/O space read and write macros.
|
|
//
|
|
// The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space.
|
|
//
|
|
// The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space.
|
|
//
|
|
|
|
__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(Buffer, Register, Count);
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
READ_REGISTER_BUFFER_USHORT (
|
|
PUSHORT Register,
|
|
PUSHORT Buffer,
|
|
ULONG Count
|
|
)
|
|
{
|
|
__movsw(Buffer, Register, Count);
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
READ_REGISTER_BUFFER_ULONG (
|
|
PULONG Register,
|
|
PULONG Buffer,
|
|
ULONG Count
|
|
)
|
|
{
|
|
__movsd(Buffer, Register, Count);
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
WRITE_REGISTER_UCHAR (
|
|
PUCHAR Register,
|
|
UCHAR Value
|
|
)
|
|
{
|
|
|
|
*Register = Value;
|
|
StoreFence();
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
WRITE_REGISTER_USHORT (
|
|
PUSHORT Register,
|
|
USHORT Value
|
|
)
|
|
{
|
|
|
|
*Register = Value;
|
|
StoreFence();
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
WRITE_REGISTER_ULONG (
|
|
PULONG Register,
|
|
ULONG Value
|
|
)
|
|
{
|
|
|
|
*Register = Value;
|
|
StoreFence();
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
WRITE_REGISTER_BUFFER_UCHAR (
|
|
PUCHAR Register,
|
|
PUCHAR Buffer,
|
|
ULONG Count
|
|
)
|
|
{
|
|
|
|
__movsb(Register, Buffer, Count);
|
|
StoreFence();
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
WRITE_REGISTER_BUFFER_USHORT (
|
|
PUSHORT Register,
|
|
PUSHORT Buffer,
|
|
ULONG Count
|
|
)
|
|
{
|
|
|
|
__movsw(Register, Buffer, Count);
|
|
StoreFence();
|
|
return;
|
|
}
|
|
|
|
__forceinline
|
|
VOID
|
|
WRITE_REGISTER_BUFFER_ULONG (
|
|
PULONG Register,
|
|
PULONG Buffer,
|
|
ULONG Count
|
|
)
|
|
{
|
|
|
|
__movsd(Register, Buffer, Count);
|
|
StoreFence();
|
|
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)
|
|
|
|
|
|
#define KI_USER_SHARED_DATA 0xFFFFF78000000000UI64
|
|
|
|
#define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA)
|
|
|
|
#define SharedInterruptTime (KI_USER_SHARED_DATA + 0x8)
|
|
#define SharedSystemTime (KI_USER_SHARED_DATA + 0x14)
|
|
#define SharedTickCount (KI_USER_SHARED_DATA + 0x320)
|
|
|
|
#define KeQueryInterruptTime() *((volatile ULONG64 *)(SharedInterruptTime))
|
|
|
|
#define KeQuerySystemTime(CurrentCount) \
|
|
*((PULONG64)(CurrentCount)) = *((volatile ULONG64 *)(SharedSystemTime))
|
|
|
|
#define KeQueryTickCount(CurrentCount) \
|
|
*((PULONG64)(CurrentCount)) = *((volatile ULONG64 *)(SharedTickCount))
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
#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;
|
|
} 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) (sizeof(KTSS64))
|
|
|
|
// 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;
|
|
ULONG64 DebugControl;
|
|
ULONG64 LastBranchToRip;
|
|
ULONG64 LastBranchFromRip;
|
|
ULONG64 LastExceptionToRip;
|
|
ULONG64 LastExceptionFromRip;
|
|
ULONG64 Cr8;
|
|
ULONG64 MsrGsBase;
|
|
ULONG64 MsrGsSwap;
|
|
ULONG64 MsrStar;
|
|
ULONG64 MsrLStar;
|
|
ULONG64 MsrCStar;
|
|
ULONG64 MsrSyscallMask;
|
|
} 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
|
|
|
|
//
|
|
// DPC data structure definition.
|
|
//
|
|
|
|
typedef struct _KDPC_DATA {
|
|
LIST_ENTRY DpcListHead;
|
|
KSPIN_LOCK DpcLock;
|
|
volatile ULONG DpcQueueDepth;
|
|
ULONG DpcCount;
|
|
} KDPC_DATA, *PKDPC_DATA;
|
|
|
|
//
|
|
// 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;
|
|
KSPIN_LOCK PrcbLock;
|
|
KPROCESSOR_STATE ProcessorState;
|
|
CCHAR CpuType;
|
|
CCHAR CpuID;
|
|
USHORT CpuStep;
|
|
ULONG PrcbPad00;
|
|
ULONG64 HalReserved[8];
|
|
UCHAR PrcbPad0[104];
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
// Certain fields in the TIB are not used in kernel mode. These include the
|
|
// exception list, stack base, stack limit, subsystem TIB, fiber data, and
|
|
// the arbitrary user pointer. Therefore, these fields are overlaid with
|
|
// other data to get better cache locality.
|
|
|
|
union {
|
|
NT_TIB NtTib;
|
|
struct {
|
|
union _KGDTENTRY64 *GdtBase;
|
|
struct _KTSS64 *TssBase;
|
|
PVOID PerfGlobalGroupMask;
|
|
struct _KPCR *Self;
|
|
ULONG ContextSwitches;
|
|
ULONG NotUsed;
|
|
KAFFINITY SetMember;
|
|
PVOID Used_Self;
|
|
};
|
|
};
|
|
|
|
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;
|
|
PVOID Unused1;
|
|
PVOID Unused2;
|
|
|
|
|
|
} 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)
|
|
|
|
//
|
|
// Define legacy floating states.
|
|
//
|
|
|
|
#define LEGACY_STATE_UNUSED 0
|
|
#define LEGACY_STATE_SCRUB 1
|
|
#define LEGACY_STATE_SWITCH 2
|
|
|
|
//
|
|
// Define MxCsr floating control/status word bit masks.
|
|
//
|
|
// No flush to zero, round to nearest, and all exception masked.
|
|
//
|
|
|
|
#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, and identification.
|
|
//
|
|
// If user mode, then
|
|
// caller can specify Carry, Parity, AuxCarry, Zero, Sign, Trap,
|
|
// Direction, Overflow, and force Interrupt on.
|
|
//
|
|
|
|
#define EFLAGS_KERNEL_SANITIZE 0x00210fd5L
|
|
#define EFLAGS_USER_SANITIZE 0x00010dd5L
|
|
|
|
#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 begin_ntddk
|
|
//
|
|
// 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.
|
|
//
|
|
// N.B. The exception frame has a built in exception record capable of
|
|
// storing information for four parameter values. This exception
|
|
// record is used exclusively within the trap handling code.
|
|
//
|
|
|
|
#define EXCEPTION_AREA_SIZE 64
|
|
|
|
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;
|
|
|
|
//
|
|
// Exception record for exceptions.
|
|
//
|
|
|
|
UCHAR ExceptionRecord[EXCEPTION_AREA_SIZE];
|
|
|
|
//
|
|
// 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;
|
|
|
|
// end_ntddk
|
|
|
|
#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)
|
|
|
|
#if !defined(_X86AMD64_)
|
|
|
|
C_ASSERT(EXCEPTION_AREA_SIZE == (FIELD_OFFSET(EXCEPTION_RECORD, ExceptionInformation) + (4 * sizeof(ULONG_PTR))));
|
|
|
|
#endif
|
|
|
|
//
|
|
// 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 P1Home;
|
|
ULONG64 P2Home;
|
|
ULONG64 P3Home;
|
|
ULONG64 P4Home;
|
|
ULONG64 P5Home;
|
|
ULONG MxCsr;
|
|
KIRQL ApcBypass;
|
|
UCHAR Fill1[3];
|
|
ULONG64 Rbp;
|
|
ULONG64 Return;
|
|
} KSWITCH_FRAME, *PKSWITCH_FRAME;
|
|
|
|
#define KSWITCH_FRAME_LENGTH sizeof(KSWITCH_FRAME)
|
|
|
|
C_ASSERT((sizeof(KSWITCH_FRAME) & STACK_ROUND) == 0);
|
|
|
|
//
|
|
// Start system thread frame.
|
|
//
|
|
// This frame is established by the AMD64 specific thread initialization
|
|
// code. It is used to store the initial context for starting a system
|
|
// thread.
|
|
//
|
|
|
|
typedef struct _KSTART_FRAME {
|
|
ULONG64 P1Home;
|
|
ULONG64 P2Home;
|
|
ULONG64 P3Home;
|
|
ULONG64 Return;
|
|
} KSTART_FRAME, *PKSTART_FRAME;
|
|
|
|
#define KSTART_FRAME_LENGTH sizeof(KSTART_FRAME)
|
|
|
|
C_ASSERT((sizeof(KSTART_FRAME) & STACK_ROUND) == 0);
|
|
|
|
// begin_ntddk
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// Page fault load/store indicator.
|
|
//
|
|
|
|
UCHAR FaultIndicator;
|
|
UCHAR Fill0;
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// Page fault address.
|
|
//
|
|
|
|
ULONG64 FaultAddress;
|
|
|
|
//
|
|
// Debug registers.
|
|
//
|
|
|
|
ULONG64 Dr0;
|
|
ULONG64 Dr1;
|
|
ULONG64 Dr2;
|
|
ULONG64 Dr3;
|
|
ULONG64 Dr6;
|
|
ULONG64 Dr7;
|
|
|
|
//
|
|
// Special debug registers.
|
|
//
|
|
|
|
ULONG64 DebugControl;
|
|
ULONG64 LastBranchToRip;
|
|
ULONG64 LastBranchFromRip;
|
|
ULONG64 LastExceptionToRip;
|
|
ULONG64 LastExceptionFromRip;
|
|
|
|
//
|
|
// Segment registers
|
|
//
|
|
|
|
USHORT SegDs;
|
|
USHORT SegEs;
|
|
USHORT SegFs;
|
|
USHORT SegGs;
|
|
|
|
//
|
|
// Previous trap frame address.
|
|
//
|
|
|
|
ULONG64 TrapFrame;
|
|
|
|
//
|
|
// 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;
|
|
|
|
// end_ntddk
|
|
|
|
#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)
|
|
|
|
|
|
//
|
|
// 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)
|
|
|
|
|
|
//++
|
|
//
|
|
//
|
|
// VOID
|
|
// KeMemoryBarrier (
|
|
// VOID
|
|
// )
|
|
//
|
|
// VOID
|
|
// KeMemoryBarrierWithoutFence (
|
|
// VOID
|
|
// )
|
|
//
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// These functions order memory accesses as seen by other processors.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
#if !defined(_CROSS_PLATFORM_)
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
VOID
|
|
_ReadWriteBarrier (
|
|
VOID
|
|
);
|
|
|
|
#pragma intrinsic(_ReadWriteBarrier)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#define KeMemoryBarrier() _ReadWriteBarrier()
|
|
#define KeMemoryBarrierWithoutFence() _ReadWriteBarrier()
|
|
|
|
#else
|
|
|
|
#define KeMemoryBarrier()
|
|
#define KeMemoryBarrierWithoutFence()
|
|
|
|
#endif
|
|
|
|
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
KeSaveFloatingPointState (
|
|
OUT PKFLOATING_SAVE SaveArea
|
|
);
|
|
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
KeRestoreFloatingPointState (
|
|
IN PKFLOATING_SAVE SaveArea
|
|
);
|
|
|
|
|
|
#endif // defined(_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;
|
|
|
|
//
|
|
// 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 __fci (__int64);
|
|
void __sum (int);
|
|
void __rsm (int);
|
|
void _ReleaseSpinLock( unsigned __int64 *);
|
|
void __yield();
|
|
void __lfetch(int, void const *);
|
|
void __lfetchfault(int, void const *);
|
|
|
|
#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 (__fci)
|
|
#pragma intrinsic (__sum)
|
|
#pragma intrinsic (__rsm)
|
|
#pragma intrinsic (_ReleaseSpinLock)
|
|
#pragma intrinsic (__yield)
|
|
#pragma intrinsic (__lfetch)
|
|
#pragma intrinsic (__lfetchfault)
|
|
#endif // _M_IA64
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
// end_ntndis
|
|
|
|
//
|
|
// 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(_M_IA64) && !defined(RC_INVOKED)
|
|
|
|
#define InterlockedAdd _InterlockedAdd
|
|
#define InterlockedIncrement _InterlockedIncrement
|
|
#define InterlockedIncrementAcquire _InterlockedIncrement_acq
|
|
#define InterlockedIncrementRelease _InterlockedIncrement_rel
|
|
#define InterlockedDecrement _InterlockedDecrement
|
|
#define InterlockedDecrementAcquire _InterlockedDecrement_acq
|
|
#define InterlockedDecrementRelease _InterlockedDecrement_rel
|
|
#define InterlockedExchange _InterlockedExchange
|
|
#define InterlockedExchangeAdd _InterlockedExchangeAdd
|
|
|
|
#define InterlockedAdd64 _InterlockedAdd64
|
|
#define InterlockedIncrement64 _InterlockedIncrement64
|
|
#define InterlockedDecrement64 _InterlockedDecrement64
|
|
#define InterlockedExchange64 _InterlockedExchange64
|
|
#define InterlockedExchangeAcquire64 _InterlockedExchange64_acq
|
|
#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
|
|
#define InterlockedCompareExchange64 _InterlockedCompareExchange64
|
|
#define InterlockedCompareExchangeAcquire64 _InterlockedCompareExchange64_acq
|
|
#define InterlockedCompareExchangeRelease64 _InterlockedCompareExchange64_rel
|
|
|
|
#define InterlockedCompareExchange _InterlockedCompareExchange
|
|
#define InterlockedCompareExchangeAcquire _InterlockedCompareExchange_acq
|
|
#define InterlockedCompareExchangeRelease _InterlockedCompareExchange_rel
|
|
#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
|
|
InterlockedIncrementAcquire(
|
|
IN OUT LONG volatile *Addend
|
|
);
|
|
|
|
LONG
|
|
__cdecl
|
|
InterlockedDecrementAcquire(
|
|
IN OUT LONG volatile *Addend
|
|
);
|
|
|
|
LONG
|
|
__cdecl
|
|
InterlockedIncrementRelease(
|
|
IN OUT LONG volatile *Addend
|
|
);
|
|
|
|
LONG
|
|
__cdecl
|
|
InterlockedDecrementRelease(
|
|
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
|
|
);
|
|
|
|
|
|
LONG
|
|
__cdecl
|
|
InterlockedCompareExchangeRelease (
|
|
IN OUT LONG volatile *Destination,
|
|
IN LONG ExChange,
|
|
IN LONG Comperand
|
|
);
|
|
|
|
|
|
LONG
|
|
__cdecl
|
|
InterlockedCompareExchangeAcquire (
|
|
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
|
|
InterlockedExchangeAcquire64(
|
|
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
|
|
);
|
|
|
|
LONGLONG
|
|
__cdecl
|
|
InterlockedCompareExchangeAcquire64 (
|
|
IN OUT LONGLONG volatile *Destination,
|
|
IN LONGLONG ExChange,
|
|
IN LONGLONG Comperand
|
|
);
|
|
|
|
LONGLONG
|
|
__cdecl
|
|
InterlockedCompareExchangeRelease64 (
|
|
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
|
|
);
|
|
|
|
#if !defined (InterlockedAnd64)
|
|
|
|
#define InterlockedAnd64 InterlockedAnd64_Inline
|
|
|
|
LONGLONG
|
|
FORCEINLINE
|
|
InterlockedAnd64_Inline (
|
|
IN OUT LONGLONG volatile *Destination,
|
|
IN LONGLONG Value
|
|
)
|
|
{
|
|
LONGLONG Old;
|
|
|
|
do {
|
|
Old = *Destination;
|
|
} while (InterlockedCompareExchange64(Destination,
|
|
Old & Value,
|
|
Old) != Old);
|
|
|
|
return Old;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if !defined (InterlockedOr64)
|
|
|
|
#define InterlockedOr64 InterlockedOr64_Inline
|
|
|
|
LONGLONG
|
|
FORCEINLINE
|
|
InterlockedOr64_Inline (
|
|
IN OUT LONGLONG volatile *Destination,
|
|
IN LONGLONG Value
|
|
)
|
|
{
|
|
LONGLONG Old;
|
|
|
|
do {
|
|
Old = *Destination;
|
|
} while (InterlockedCompareExchange64(Destination,
|
|
Old | Value,
|
|
Old) != Old);
|
|
|
|
return Old;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#if !defined (InterlockedXor64)
|
|
|
|
#define InterlockedXor64 InterlockedXor64_Inline
|
|
|
|
LONGLONG
|
|
FORCEINLINE
|
|
InterlockedXor64_Inline (
|
|
IN OUT LONGLONG volatile *Destination,
|
|
IN LONGLONG Value
|
|
)
|
|
{
|
|
LONGLONG Old;
|
|
|
|
do {
|
|
Old = *Destination;
|
|
} while (InterlockedCompareExchange64(Destination,
|
|
Old ^ Value,
|
|
Old) != Old);
|
|
|
|
return Old;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#pragma intrinsic(_InterlockedAdd)
|
|
#pragma intrinsic(_InterlockedIncrement)
|
|
#pragma intrinsic(_InterlockedIncrement_acq)
|
|
#pragma intrinsic(_InterlockedIncrement_rel)
|
|
#pragma intrinsic(_InterlockedDecrement)
|
|
#pragma intrinsic(_InterlockedDecrement_acq)
|
|
#pragma intrinsic(_InterlockedDecrement_rel)
|
|
#pragma intrinsic(_InterlockedExchange)
|
|
#pragma intrinsic(_InterlockedCompareExchange)
|
|
#pragma intrinsic(_InterlockedCompareExchange_acq)
|
|
#pragma intrinsic(_InterlockedCompareExchange_rel)
|
|
#pragma intrinsic(_InterlockedExchangeAdd)
|
|
#pragma intrinsic(_InterlockedAdd64)
|
|
#pragma intrinsic(_InterlockedIncrement64)
|
|
#pragma intrinsic(_InterlockedDecrement64)
|
|
#pragma intrinsic(_InterlockedExchange64)
|
|
#pragma intrinsic(_InterlockedExchange64_acq)
|
|
#pragma intrinsic(_InterlockedCompareExchange64)
|
|
#pragma intrinsic(_InterlockedCompareExchange64_acq)
|
|
#pragma intrinsic(_InterlockedCompareExchange64_rel)
|
|
#pragma intrinsic(_InterlockedExchangeAdd64)
|
|
#pragma intrinsic(_InterlockedExchangePointer)
|
|
#pragma intrinsic(_InterlockedCompareExchangePointer)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // defined(_M_IA64) && !defined(RC_INVOKED)
|
|
|
|
// end_wdm
|
|
|
|
__forceinline
|
|
LONG
|
|
InterlockedAnd (
|
|
IN OUT LONG volatile *Target,
|
|
LONG Set
|
|
)
|
|
{
|
|
LONG i;
|
|
LONG j;
|
|
|
|
j = *Target;
|
|
do {
|
|
i = j;
|
|
j = InterlockedCompareExchange(Target,
|
|
i & Set,
|
|
i);
|
|
|
|
} while (i != j);
|
|
|
|
return j;
|
|
}
|
|
|
|
__forceinline
|
|
LONG
|
|
InterlockedOr (
|
|
IN OUT LONG volatile *Target,
|
|
IN LONG Set
|
|
)
|
|
{
|
|
LONG i;
|
|
LONG j;
|
|
|
|
j = *Target;
|
|
do {
|
|
i = j;
|
|
j = InterlockedCompareExchange(Target,
|
|
i | Set,
|
|
i);
|
|
|
|
} while (i != j);
|
|
|
|
return j;
|
|
}
|
|
|
|
__forceinline
|
|
LONG
|
|
InterlockedXor (
|
|
IN OUT LONG volatile *Target,
|
|
IN LONG Set
|
|
)
|
|
{
|
|
LONG i;
|
|
LONG j;
|
|
|
|
j = *Target;
|
|
do {
|
|
i = j;
|
|
j = InterlockedCompareExchange(Target,
|
|
i ^ Set,
|
|
i);
|
|
|
|
} while (i != j);
|
|
|
|
return j;
|
|
}
|
|
|
|
|
|
|
|
#define KI_USER_SHARED_DATA ((ULONG_PTR)(KADDRESS_BASE + 0xFFFE0000))
|
|
#define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA)
|
|
|
|
// end_wdm
|
|
|
|
//
|
|
// 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() ((ULONG)(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
|
|
|
|
|
|
|
|
//
|
|
//
|
|
// VOID
|
|
// KeMemoryBarrierWithoutFence (
|
|
// VOID
|
|
// )
|
|
//
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function cases ordering of memory acceses generated by the compiler.
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//--
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
VOID
|
|
_ReadWriteBarrier (
|
|
VOID
|
|
);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#pragma intrinsic(_ReadWriteBarrier)
|
|
|
|
#define KeMemoryBarrierWithoutFence() _ReadWriteBarrier()
|
|
|
|
//++
|
|
//
|
|
//
|
|
// VOID
|
|
// KeMemoryBarrier (
|
|
// VOID
|
|
// )
|
|
//
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function cases ordering of memory acceses as generated by the compiler and
|
|
// as seen by other processors.
|
|
//
|
|
//
|
|
// Arguments:
|
|
//
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//--
|
|
|
|
#define KE_MEMORY_BARRIER_REQUIRED
|
|
|
|
#define KeMemoryBarrier() {_ReadWriteBarrier();__mf ();_ReadWriteBarrier();}
|
|
|
|
//
|
|
// 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;
|
|
|
|
|
|
//
|
|
// 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
|
|
|
|
|
|
} KPCR, *PKPCR;
|
|
|
|
|
|
|
|
NTKERNELAPI
|
|
KIRQL
|
|
KeGetCurrentIrql();
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeLowerIrql (
|
|
IN KIRQL NewIrql
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeRaiseIrql (
|
|
IN KIRQL NewIrql,
|
|
OUT PKIRQL OldIrql
|
|
);
|
|
|
|
// end_wdm
|
|
|
|
NTKERNELAPI
|
|
KIRQL
|
|
KeRaiseIrqlToDpcLevel (
|
|
VOID
|
|
);
|
|
|
|
NTKERNELAPI
|
|
KIRQL
|
|
KeRaiseIrqlToSynchLevel (
|
|
VOID
|
|
);
|
|
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
#if defined(_NTHAL_) || defined(_NTOSP_)
|
|
|
|
#define AFFINITY_MASK(n) ((ULONG_PTR)1 << (n))
|
|
|
|
#else
|
|
|
|
#if !defined(_WIN64)
|
|
|
|
#define KiAffinityArray KiMask32Array
|
|
|
|
#endif
|
|
|
|
extern const ULONG_PTR KiAffinityArray[];
|
|
|
|
#define AFFINITY_MASK(n) (KiAffinityArray[n])
|
|
|
|
#endif
|
|
|
|
|
|
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,
|
|
WrResource,
|
|
WrPushLock,
|
|
WrMutex,
|
|
WrQuantumEnd,
|
|
WrDispatchInt,
|
|
WrPreempted,
|
|
WrYieldExecution,
|
|
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
|
|
);
|
|
|
|
VOID
|
|
KeGenericCallDpc (
|
|
IN PKDEFERRED_ROUTINE Routine,
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
KeSignalCallDpcDone (
|
|
IN PVOID SystemArgument1
|
|
);
|
|
|
|
LOGICAL
|
|
KeSignalCallDpcSynchronize (
|
|
IN PVOID SystemArgument2
|
|
);
|
|
|
|
//
|
|
// DPC object
|
|
//
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeInitializeDpc (
|
|
IN PRKDPC Dpc,
|
|
IN PKDEFERRED_ROUTINE DeferredRoutine,
|
|
IN PVOID DeferredContext
|
|
);
|
|
|
|
// end_ntddk end_wdm end_nthal end_ntifs
|
|
NTKERNELAPI
|
|
VOID
|
|
KeInitializeThreadedDpc (
|
|
IN PRKDPC Dpc,
|
|
IN PKDEFERRED_ROUTINE DeferredRoutine,
|
|
IN PVOID DeferredContext
|
|
);
|
|
// begin_ntddk begin_wdm begin_nthal begin_ntifs
|
|
|
|
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
|
|
LONG
|
|
KeSetBasePriorityThread (
|
|
IN PKTHREAD Thread,
|
|
IN LONG Increment
|
|
);
|
|
|
|
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
|
|
|
|
#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
|
|
);
|
|
|
|
//
|
|
// Define interprocess interrupt generic call types.
|
|
//
|
|
|
|
typedef
|
|
ULONG_PTR
|
|
(*PKIPI_BROADCAST_WORKER)(
|
|
IN ULONG_PTR Argument
|
|
);
|
|
|
|
ULONG_PTR
|
|
KeIpiGenericCall (
|
|
IN PKIPI_BROADCAST_WORKER BroadcastFunction,
|
|
IN ULONG_PTR Context
|
|
);
|
|
|
|
|
|
//
|
|
// 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
|
|
//
|
|
|
|
#if defined(_X86_) && (defined(_WDMDDK_) || defined(WIN9X_COMPAT_SPINLOCK))
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
NTAPI
|
|
KeInitializeSpinLock (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
#else
|
|
|
|
__inline
|
|
VOID
|
|
NTAPI
|
|
KeInitializeSpinLock (
|
|
IN PKSPIN_LOCK SpinLock
|
|
)
|
|
{
|
|
*SpinLock = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
#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 end_ntddk
|
|
|
|
_DECL_HAL_KE_IMPORT
|
|
KIRQL
|
|
FASTCALL
|
|
KeAcquireSpinLockRaiseToSynch (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
// begin_wdm begin_ntddk
|
|
|
|
#define KeAcquireSpinLock(a,b) *(b) = KfAcquireSpinLock(a)
|
|
#define KeReleaseSpinLock(a,b) KfReleaseSpinLock(a,b)
|
|
|
|
NTKERNELAPI
|
|
BOOLEAN
|
|
FASTCALL
|
|
KeTestSpinLock (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
BOOLEAN
|
|
FASTCALL
|
|
KeTryToAcquireSpinLockAtDpcLevel (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
#else
|
|
|
|
//
|
|
// These functions are imported for IA64, ntddk, ntifs, nthal, ntosp, and wdm.
|
|
// They can be inlined for the system on AMD64.
|
|
//
|
|
|
|
#define KeAcquireSpinLock(SpinLock, OldIrql) \
|
|
*(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock)
|
|
|
|
#if defined(_IA64_) || defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || defined(_NTOSP_) || defined(_WDMDDK_)
|
|
|
|
// end_wdm end_ntddk
|
|
|
|
NTKERNELAPI
|
|
KIRQL
|
|
FASTCALL
|
|
KeAcquireSpinLockRaiseToSynch (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
// begin_wdm begin_ntddk
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeAcquireSpinLockAtDpcLevel (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
KIRQL
|
|
KeAcquireSpinLockRaiseToDpc (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeReleaseSpinLock (
|
|
IN PKSPIN_LOCK SpinLock,
|
|
IN KIRQL NewIrql
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeReleaseSpinLockFromDpcLevel (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
BOOLEAN
|
|
FASTCALL
|
|
KeTestSpinLock (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
BOOLEAN
|
|
FASTCALL
|
|
KeTryToAcquireSpinLockAtDpcLevel (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
#else
|
|
|
|
#if defined(_AMD64_)
|
|
|
|
//
|
|
// The system version of these functions are defined in amd64.h for AMD64.
|
|
//
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
// end_wdm end_ntddk end_nthal end_ntifs
|
|
|
|
NTKERNELAPI
|
|
KIRQL
|
|
FASTCALL
|
|
KeAcquireSpinLockForDpc (
|
|
IN PKSPIN_LOCK SpinLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
KeReleaseSpinLockForDpc (
|
|
IN PKSPIN_LOCK SpinLock,
|
|
IN KIRQL OldIrql
|
|
);
|
|
|
|
|
|
#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
|
|
);
|
|
|
|
// end_ntddk
|
|
|
|
_DECL_HAL_KE_IMPORT
|
|
KIRQL
|
|
KeRaiseIrqlToSynchLevel(
|
|
VOID
|
|
);
|
|
|
|
// begin_wdm begin_ntddk
|
|
|
|
#define KeLowerIrql(a) KfLowerIrql(a)
|
|
#define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a)
|
|
|
|
// end_wdm
|
|
|
|
// begin_wdm
|
|
|
|
#elif defined(_IA64_)
|
|
|
|
//
|
|
// These function are defined in IA64.h for the IA64 platform.
|
|
//
|
|
|
|
|
|
#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
|
|
);
|
|
|
|
// end_ntddk end_nthal end_ntifs
|
|
//
|
|
// The following two functions conditionally raise or lower IRQL when a
|
|
// queued in-stack spin lock is acquired or released using these functions.
|
|
//
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
KeAcquireInStackQueuedSpinLockForDpc (
|
|
IN PKSPIN_LOCK SpinLock,
|
|
IN PKLOCK_QUEUE_HANDLE LockHandle
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
KeReleaseInStackQueuedSpinLockForDpc (
|
|
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
|
|
);
|
|
|
|
typedef
|
|
BOOLEAN
|
|
(*PNMI_CALLBACK)(
|
|
IN PVOID Context,
|
|
IN BOOLEAN Handled
|
|
);
|
|
|
|
NTKERNELAPI
|
|
PVOID
|
|
KeRegisterNmiCallback(
|
|
PNMI_CALLBACK CallbackRoutine,
|
|
PVOID Context
|
|
);
|
|
|
|
NTSTATUS
|
|
KeDeregisterNmiCallback(
|
|
PVOID Handle
|
|
);
|
|
|
|
// 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
|
|
);
|
|
|
|
|
|
#if !defined(_AMD64_)
|
|
|
|
NTKERNELAPI
|
|
ULONGLONG
|
|
KeQueryInterruptTime (
|
|
VOID
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
KeQuerySystemTime (
|
|
OUT PLARGE_INTEGER CurrentTime
|
|
);
|
|
|
|
#endif
|
|
|
|
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
|
|
);
|
|
|
|
extern PLOADER_PARAMETER_BLOCK KeLoaderBlock;
|
|
extern NTSYSAPI CCHAR KeNumberProcessors;
|
|
|
|
#if defined(_IA64_)
|
|
|
|
extern volatile LARGE_INTEGER KeTickCount;
|
|
|
|
#elif defined(_X86_)
|
|
|
|
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
|
|
#define POOL_MM_ALLOCATION 0x80000000 // Note this cannot encode into the header.
|
|
|
|
|
|
|
|
DECLSPEC_DEPRECATED_DDK // Use ExAllocatePoolWithTag
|
|
NTKERNELAPI
|
|
PVOID
|
|
ExAllocatePool(
|
|
IN POOL_TYPE PoolType,
|
|
IN SIZE_T NumberOfBytes
|
|
);
|
|
|
|
DECLSPEC_DEPRECATED_DDK // Use ExAllocatePoolWithQuotaTag
|
|
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(_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
|
|
|
|
//
|
|
|
|
#if defined(_WIN64)
|
|
|
|
#define ExInterlockedAddLargeStatistic(Addend, Increment) \
|
|
(VOID) InterlockedAdd64(&(Addend)->QuadPart, Increment)
|
|
|
|
#else
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
LONG
|
|
_InterlockedAddLargeStatistic (
|
|
IN PLONGLONG Addend,
|
|
IN ULONG Increment
|
|
);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#pragma intrinsic (_InterlockedAddLargeStatistic)
|
|
|
|
#define ExInterlockedAddLargeStatistic(Addend,Increment) \
|
|
(VOID) _InterlockedAddLargeStatistic ((PLONGLONG)&(Addend)->QuadPart, Increment)
|
|
|
|
#endif
|
|
|
|
// 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)))
|
|
//++
|
|
//
|
|
// <STRUCTURE>
|
|
// ProbeAndReadStructure(
|
|
// IN P<STRUCTURE> Source
|
|
// <STRUCTURE>
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#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<STRUCTURE> Address,
|
|
// IN <STRUCTURE> Value,
|
|
// <STRUCTURE>
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#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;
|
|
|
|
//begin_ntifs
|
|
|
|
//
|
|
// 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<<EX_RUNDOWN_COUNT_SHIFT)
|
|
union {
|
|
ULONG_PTR Count;
|
|
PVOID Ptr;
|
|
};
|
|
} EX_RUNDOWN_REF, *PEX_RUNDOWN_REF;
|
|
|
|
//end_ntifs
|
|
|
|
//
|
|
// The Ex/Ob handle table interface package (in handle.c)
|
|
//
|
|
|
|
//
|
|
// The Ex/Ob handle table package uses a common handle definition. The actual
|
|
// type definition for a handle is a pvoid and is declared in sdk/inc. This
|
|
// package uses only the low 32 bits of the pvoid pointer.
|
|
//
|
|
// For simplicity we declare a new typedef called an exhandle
|
|
//
|
|
// The 2 bits of an EXHANDLE is available to the application and is
|
|
// ignored by the system. The next 24 bits store the handle table entry
|
|
// index and is used to refer to a particular entry in a handle table.
|
|
//
|
|
// Note that this format is immutable because there are outside programs with
|
|
// hardwired code that already assumes the format of a handle.
|
|
//
|
|
|
|
typedef struct _EXHANDLE {
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
//
|
|
// Application available tag bits
|
|
//
|
|
|
|
ULONG TagBits : 2;
|
|
|
|
//
|
|
// The handle table entry index
|
|
//
|
|
|
|
ULONG Index : 30;
|
|
|
|
};
|
|
|
|
HANDLE GenericHandleOverlay;
|
|
|
|
#define HANDLE_VALUE_INC 4 // Amount to increment the Value to get to the next handle
|
|
|
|
ULONG_PTR Value;
|
|
};
|
|
|
|
} EXHANDLE, *PEXHANDLE;
|
|
//
|
|
// Get previous mode
|
|
//
|
|
|
|
NTKERNELAPI
|
|
KPROCESSOR_MODE
|
|
ExGetPreviousMode(
|
|
VOID
|
|
);
|
|
//
|
|
// Raise status from kernel mode.
|
|
//
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
NTAPI
|
|
ExRaiseStatus (
|
|
IN NTSTATUS Status
|
|
);
|
|
|
|
// end_wdm
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExRaiseDatatypeMisalignment (
|
|
VOID
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExRaiseAccessViolation (
|
|
VOID
|
|
);
|
|
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
ExRaiseHardError(
|
|
IN NTSTATUS ErrorStatus,
|
|
IN ULONG NumberOfParameters,
|
|
IN ULONG UnicodeStringParameterMask,
|
|
IN PULONG_PTR Parameters,
|
|
IN ULONG ValidResponseOptions,
|
|
OUT PULONG Response
|
|
);
|
|
int
|
|
ExSystemExceptionFilter(
|
|
VOID
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExGetCurrentProcessorCpuUsage(
|
|
IN PULONG CpuUsage
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExGetCurrentProcessorCounts(
|
|
OUT PULONG IdleCount,
|
|
OUT PULONG KernelAndUser,
|
|
OUT PULONG Index
|
|
);
|
|
//
|
|
// Set timer resolution.
|
|
//
|
|
|
|
NTKERNELAPI
|
|
ULONG
|
|
ExSetTimerResolution (
|
|
IN ULONG DesiredTime,
|
|
IN BOOLEAN SetResolution
|
|
);
|
|
|
|
//
|
|
// Subtract time zone bias from system time to get local time.
|
|
//
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExSystemTimeToLocalTime (
|
|
IN PLARGE_INTEGER SystemTime,
|
|
OUT PLARGE_INTEGER LocalTime
|
|
);
|
|
|
|
//
|
|
// Add time zone bias to local time to get system time.
|
|
//
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExLocalTimeToSystemTime (
|
|
IN PLARGE_INTEGER LocalTime,
|
|
OUT PLARGE_INTEGER SystemTime
|
|
);
|
|
|
|
|
|
//
|
|
// Define the type for Callback function.
|
|
//
|
|
|
|
typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT;
|
|
|
|
typedef VOID (*PCALLBACK_FUNCTION ) (
|
|
IN PVOID CallbackContext,
|
|
IN PVOID Argument1,
|
|
IN PVOID Argument2
|
|
);
|
|
|
|
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
ExCreateCallback (
|
|
OUT PCALLBACK_OBJECT *CallbackObject,
|
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|
IN BOOLEAN Create,
|
|
IN BOOLEAN AllowMultipleCallbacks
|
|
);
|
|
|
|
NTKERNELAPI
|
|
PVOID
|
|
ExRegisterCallback (
|
|
IN PCALLBACK_OBJECT CallbackObject,
|
|
IN PCALLBACK_FUNCTION CallbackFunction,
|
|
IN PVOID CallbackContext
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExUnregisterCallback (
|
|
IN PVOID CallbackRegistration
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExNotifyCallback (
|
|
IN PVOID CallbackObject,
|
|
IN PVOID Argument1,
|
|
IN PVOID Argument2
|
|
);
|
|
|
|
|
|
|
|
|
|
typedef
|
|
PVOID
|
|
(*PKWIN32_GLOBALATOMTABLE_CALLOUT) ( void );
|
|
|
|
extern PKWIN32_GLOBALATOMTABLE_CALLOUT ExGlobalAtomTableCallout;
|
|
|
|
|
|
//
|
|
// UUID Generation
|
|
//
|
|
|
|
typedef GUID UUID;
|
|
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
ExUuidCreate(
|
|
OUT UUID *Uuid
|
|
);
|
|
|
|
|
|
//
|
|
// Rundown Locks
|
|
//
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExInitializeRundownProtection (
|
|
IN PEX_RUNDOWN_REF RunRef
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExReInitializeRundownProtection (
|
|
IN PEX_RUNDOWN_REF RunRef
|
|
);
|
|
|
|
NTKERNELAPI
|
|
BOOLEAN
|
|
FASTCALL
|
|
ExAcquireRundownProtection (
|
|
IN PEX_RUNDOWN_REF RunRef
|
|
);
|
|
|
|
NTKERNELAPI
|
|
BOOLEAN
|
|
FASTCALL
|
|
ExAcquireRundownProtectionEx (
|
|
IN PEX_RUNDOWN_REF RunRef,
|
|
IN ULONG Count
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExReleaseRundownProtection (
|
|
IN PEX_RUNDOWN_REF RunRef
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExReleaseRundownProtectionEx (
|
|
IN PEX_RUNDOWN_REF RunRef,
|
|
IN ULONG Count
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExRundownCompleted (
|
|
IN PEX_RUNDOWN_REF RunRef
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExWaitForRundownProtectionRelease (
|
|
IN PEX_RUNDOWN_REF RunRef
|
|
);
|
|
|
|
|
|
#if !defined(NONTOSPINTERLOCK)
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExInitializePushLock (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize a push lock structure
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be initialized
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PushLock->Value = 0;
|
|
}
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExfAcquirePushLockExclusive (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExfAcquirePushLockShared (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
FASTCALL
|
|
ExfReleasePushLock (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
);
|
|
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExAcquirePushLockExclusive (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acquire a push lock exclusively
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be acquired
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
(PVOID)EX_PUSH_LOCK_EXCLUSIVE,
|
|
NULL) != NULL) {
|
|
ExfAcquirePushLockExclusive (PushLock);
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
FORCEINLINE
|
|
ExTryAcquirePushLockExclusive (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Try and acquire a push lock exclusively
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be acquired
|
|
|
|
Return Value:
|
|
|
|
BOOLEAN - TRUE: Acquire was successfull, FALSE: Lock was already acquired
|
|
|
|
--*/
|
|
{
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
(PVOID)EX_PUSH_LOCK_EXCLUSIVE,
|
|
NULL) == NULL) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExAcquirePushLockShared (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acquire a push lock shared
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be acquired
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
EX_PUSH_LOCK OldValue, NewValue;
|
|
|
|
OldValue = *PushLock;
|
|
OldValue.Value &= ~(EX_PUSH_LOCK_EXCLUSIVE | EX_PUSH_LOCK_WAITING);
|
|
NewValue.Value = OldValue.Value + EX_PUSH_LOCK_SHARE_INC;
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
NewValue.Ptr,
|
|
OldValue.Ptr) != OldValue.Ptr) {
|
|
ExfAcquirePushLockShared (PushLock);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExAcquirePushLockSharedAssumeNoOwner (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acquire a push lock shared making the assumption that its not currently owned.
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be acquired
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
(PVOID)EX_PUSH_LOCK_SHARE_INC,
|
|
NULL) != NULL) {
|
|
ExfAcquirePushLockShared (PushLock);
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
FORCEINLINE
|
|
ExTryConvertPushLockSharedToExclusive (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Attempts to convert a shared acquire to exclusive. If other sharers or waiters are present
|
|
the function fails.
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be acquired
|
|
|
|
Return Value:
|
|
|
|
BOOLEAN - TRUE: Conversion worked ok, FALSE: The conversion could not be achieved
|
|
|
|
--*/
|
|
{
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr, (PVOID) EX_PUSH_LOCK_EXCLUSIVE,
|
|
(PVOID) EX_PUSH_LOCK_SHARE_INC) ==
|
|
(PVOID)EX_PUSH_LOCK_SHARE_INC) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExReleasePushLock (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Release a push lock that was acquired exclusively or shared
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be released
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
EX_PUSH_LOCK OldValue, NewValue;
|
|
|
|
OldValue = *PushLock;
|
|
OldValue.Value &= ~EX_PUSH_LOCK_WAITING;
|
|
NewValue.Value = (OldValue.Value - EX_PUSH_LOCK_EXCLUSIVE) &
|
|
~EX_PUSH_LOCK_EXCLUSIVE;
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
NewValue.Ptr,
|
|
OldValue.Ptr) != OldValue.Ptr) {
|
|
ExfReleasePushLock (PushLock);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExReleasePushLockExclusive (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Release a push lock that was acquired exclusively
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be released
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
ASSERT (PushLock->Value & (EX_PUSH_LOCK_WAITING|EX_PUSH_LOCK_EXCLUSIVE));
|
|
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
NULL,
|
|
(PVOID)EX_PUSH_LOCK_EXCLUSIVE) != (PVOID)EX_PUSH_LOCK_EXCLUSIVE) {
|
|
ExfReleasePushLock (PushLock);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExReleasePushLockShared (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Release a push lock that was acquired shared
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be released
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
EX_PUSH_LOCK OldValue, NewValue;
|
|
|
|
OldValue = *PushLock;
|
|
ASSERT (OldValue.Waiting || !OldValue.Exclusive);
|
|
OldValue.Value &= ~EX_PUSH_LOCK_WAITING;
|
|
NewValue.Value = OldValue.Value - EX_PUSH_LOCK_SHARE_INC;
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
NewValue.Ptr,
|
|
OldValue.Ptr) != OldValue.Ptr) {
|
|
ExfReleasePushLock (PushLock);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExReleasePushLockSharedAssumeSingleOwner (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Release a push lock that was acquired shared assuming that we are the only owner
|
|
|
|
Arguments:
|
|
|
|
PushLock - Push lock to be released
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
#if DBG
|
|
EX_PUSH_LOCK OldValue;
|
|
|
|
OldValue = *PushLock;
|
|
|
|
ASSERT (OldValue.Waiting || !OldValue.Exclusive);
|
|
|
|
#endif
|
|
|
|
if (InterlockedCompareExchangePointer (&PushLock->Ptr,
|
|
NULL,
|
|
(PVOID)EX_PUSH_LOCK_SHARE_INC) != (PVOID)EX_PUSH_LOCK_SHARE_INC) {
|
|
ExfReleasePushLock (PushLock);
|
|
}
|
|
}
|
|
|
|
//
|
|
// This is a block held on the local stack of the waiting threads.
|
|
//
|
|
|
|
typedef struct _EX_PUSH_LOCK_WAIT_BLOCK *PEX_PUSH_LOCK_WAIT_BLOCK;
|
|
|
|
typedef struct _EX_PUSH_LOCK_WAIT_BLOCK {
|
|
KEVENT WakeEvent;
|
|
PEX_PUSH_LOCK_WAIT_BLOCK Next;
|
|
PEX_PUSH_LOCK_WAIT_BLOCK Last;
|
|
PEX_PUSH_LOCK_WAIT_BLOCK Previous;
|
|
ULONG ShareCount;
|
|
BOOLEAN Exclusive;
|
|
} EX_PUSH_LOCK_WAIT_BLOCK;
|
|
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExWaitForUnblockPushLock (
|
|
IN PEX_PUSH_LOCK PushLock,
|
|
IN PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock OPTIONAL
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER (PushLock);
|
|
|
|
KeWaitForSingleObject (&WaitBlock->WakeEvent,
|
|
Executive,
|
|
KernelMode,
|
|
FALSE,
|
|
NULL);
|
|
}
|
|
|
|
|
|
NTKERNELAPI
|
|
PEX_PUSH_LOCK_CACHE_AWARE
|
|
ExAllocateCacheAwarePushLock (
|
|
VOID
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExFreeCacheAwarePushLock (
|
|
PEX_PUSH_LOCK_CACHE_AWARE PushLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExAcquireCacheAwarePushLockExclusive (
|
|
IN PEX_PUSH_LOCK_CACHE_AWARE CacheAwarePushLock
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExReleaseCacheAwarePushLockExclusive (
|
|
IN PEX_PUSH_LOCK_CACHE_AWARE CacheAwarePushLock
|
|
);
|
|
|
|
PEX_PUSH_LOCK
|
|
FORCEINLINE
|
|
ExAcquireCacheAwarePushLockShared (
|
|
IN PEX_PUSH_LOCK_CACHE_AWARE CacheAwarePushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acquire a cache aware push lock shared.
|
|
|
|
Arguments:
|
|
|
|
PushLock - Cache aware push lock to be acquired
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PEX_PUSH_LOCK PushLock;
|
|
//
|
|
// Take a single one of the slots in shared mode.
|
|
// Exclusive acquires must obtain all the slots exclusive.
|
|
//
|
|
PushLock = CacheAwarePushLock->Locks[KeGetCurrentProcessorNumber()%EX_PUSH_LOCK_FANNED_COUNT];
|
|
ExAcquirePushLockSharedAssumeNoOwner (PushLock);
|
|
// ExAcquirePushLockShared (PushLock);
|
|
return PushLock;
|
|
}
|
|
|
|
VOID
|
|
FORCEINLINE
|
|
ExReleaseCacheAwarePushLockShared (
|
|
IN PEX_PUSH_LOCK PushLock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Acquire a cache aware push lock shared.
|
|
|
|
Arguments:
|
|
|
|
PushLock - Part of cache aware push lock returned by ExAcquireCacheAwarePushLockShared
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
ExReleasePushLockSharedAssumeSingleOwner (PushLock);
|
|
// ExReleasePushLockShared (PushLock);
|
|
return;
|
|
}
|
|
|
|
#endif // !defined(NONTOSPINTERLOCK)
|
|
|
|
//
|
|
// 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 DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _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 wdm
|
|
#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
|
|
|
|
|
|
// 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 DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _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, // <Enumerator>\<Enumerator-specific device id>
|
|
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;
|
|
PUNICODE_STRING 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
|
|
);
|
|
|
|
typedef enum _IO_PAGING_PRIORITY {
|
|
IoPagingPriorityInvalid, // Returned if a non-paging IO IRP is passed.
|
|
IoPagingPriorityNormal, // For regular paging IO
|
|
IoPagingPriorityHigh, // For high priority paging IO
|
|
IoPagingPriorityReserved1, // Reserved for future use.
|
|
IoPagingPriorityReserved2 // Reserved for future use.
|
|
} IO_PAGING_PRIORITY;
|
|
|
|
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 0x30
|
|
|
|
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
|
|
// )
|
|
//
|
|
// end_ntddk end_wdm end_nthal
|
|
// VOID
|
|
// IoInitializeTheadedDpcRequest(
|
|
// IN PDEVICE_OBJECT DeviceObject,
|
|
// IN PIO_DPC_ROUTINE DpcRoutine
|
|
// )
|
|
//
|
|
// begin_ntddk begin_wdm begin_nthal
|
|
// 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) ) )
|
|
|
|
// end_ntddk end_wdm end_nthal
|
|
#define IoInitializeThreadedDpcRequest( DeviceObject, DpcRoutine ) (\
|
|
KeInitializeThreadedDpc( &(DeviceObject)->Dpc, \
|
|
(PKDEFERRED_ROUTINE) (DpcRoutine), \
|
|
(DeviceObject) ) )
|
|
// begin_ntddk begin_wdm begin_nthal
|
|
|
|
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) (ULONG_PTR) InterlockedExchangePointer( (PVOID *) &(Irp)->CancelRoutine, (PVOID) (ULONG_PTR)(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;
|
|
ULONG 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
|
|
#define IO_TYPE_CSQ_EX 3
|
|
|
|
//
|
|
// 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 NTSTATUS
|
|
(*PIO_CSQ_INSERT_IRP_EX)(
|
|
IN struct _IO_CSQ *Csq,
|
|
IN PIRP Irp,
|
|
IN OUT PVOID InsertContext
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
NTSTATUS
|
|
IoCsqInitializeEx(
|
|
IN PIO_CSQ Csq,
|
|
IN PIO_CSQ_INSERT_IRP_EX 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
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
IoCsqInsertIrpEx(
|
|
IN PIO_CSQ Csq,
|
|
IN PIRP Irp,
|
|
IN PIO_CSQ_IRP_CONTEXT Context,
|
|
IN PVOID InsertContext
|
|
);
|
|
|
|
//
|
|
// 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
|
|
);
|
|
|
|
|
|
|
|
IO_PAGING_PRIORITY
|
|
FASTCALL
|
|
IoGetPagingIoPriority(
|
|
IN PIRP IRP
|
|
);
|
|
|
|
|
|
|
|
//
|
|
// 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;
|
|
|
|
// end_wdm
|
|
typedef struct _AGP_TARGET_BUS_INTERFACE_STANDARD {
|
|
//
|
|
// generic interface header
|
|
//
|
|
USHORT Size;
|
|
USHORT Version;
|
|
PVOID Context;
|
|
PINTERFACE_REFERENCE InterfaceReference;
|
|
PINTERFACE_DEREFERENCE InterfaceDereference;
|
|
|
|
//
|
|
// config munging routines
|
|
//
|
|
PGET_SET_DEVICE_DATA SetBusData;
|
|
PGET_SET_DEVICE_DATA GetBusData;
|
|
UCHAR CapabilityID; // 2 (AGPv2 host) or new 0xE (AGPv3 bridge)
|
|
|
|
} AGP_TARGET_BUS_INTERFACE_STANDARD, *PAGP_TARGET_BUS_INTERFACE_STANDARD;
|
|
// begin_wdm
|
|
|
|
//
|
|
// 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(_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)
|
|
DECLSPEC_DEPRECATED_DDK
|
|
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
|
|
NTSTATUS
|
|
(*PINSTALL_BUS_HANDLER)(
|
|
IN PBUS_HANDLER Bus
|
|
);
|
|
|
|
typedef
|
|
NTSTATUS
|
|
(*pHalRegisterBusHandler)(
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN BUS_DATA_TYPE AssociatedConfigurationSpace,
|
|
IN ULONG BusNumber,
|
|
IN INTERFACE_TYPE ParentBusType,
|
|
IN ULONG ParentBusNumber,
|
|
IN ULONG SizeofBusExtensionData,
|
|
IN PINSTALL_BUS_HANDLER InstallBusHandlers,
|
|
OUT PBUS_HANDLER *BusHandler
|
|
);
|
|
typedef
|
|
PBUS_HANDLER
|
|
(FASTCALL *pHalHandlerForBus) (
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber
|
|
);
|
|
typedef
|
|
PBUS_HANDLER
|
|
(FASTCALL *pHalHandlerForConfigSpace) (
|
|
IN BUS_DATA_TYPE ConfigSpace,
|
|
IN ULONG BusNumber
|
|
);
|
|
typedef
|
|
VOID
|
|
(FASTCALL *pHalReferenceBusHandler) (
|
|
IN PBUS_HANDLER BusHandler
|
|
);
|
|
typedef
|
|
VOID
|
|
(*pHalSetWakeEnable)(
|
|
IN BOOLEAN Enable
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*pHalSetWakeAlarm)(
|
|
IN ULONGLONG WakeTime,
|
|
IN PTIME_FIELDS WakeTimeFields
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*pHalLocateHiberRanges)(
|
|
IN PVOID MemoryMap
|
|
);
|
|
|
|
|
|
// begin_ntddk
|
|
|
|
//*****************************************************************************
|
|
// 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,
|
|
HalQueryProfileSourceList
|
|
// 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,
|
|
HalGenerateCmcInterrupt // Used to test CMC
|
|
} 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
|
|
);
|
|
|
|
// end_ntddk
|
|
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
|
|
);
|
|
//begin_ntddk
|
|
|
|
typedef
|
|
NTSTATUS
|
|
(*pHalSetSystemInformation)(
|
|
IN HAL_SET_INFORMATION_CLASS InformationClass,
|
|
IN ULONG BufferSize,
|
|
IN PVOID Buffer
|
|
);
|
|
|
|
// end_ntddk
|
|
NTSTATUS
|
|
HaliSetSystemInformation(
|
|
IN HAL_SET_INFORMATION_CLASS InformationClass,
|
|
IN ULONG BufferSize,
|
|
IN PVOID Buffer
|
|
);
|
|
// begin_ntddk
|
|
|
|
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
|
|
);
|
|
|
|
// end_ntddk
|
|
NTSTATUS
|
|
HaliInitPnpDriver(
|
|
VOID
|
|
);
|
|
// begin_ntddk
|
|
|
|
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
|
|
);
|
|
|
|
// end_ntddk
|
|
NTSTATUS
|
|
HaliInitPowerManagement(
|
|
IN PPM_DISPATCH_TABLE PmDriverDispatchTable,
|
|
IN OUT PPM_DISPATCH_TABLE *PmHalDispatchTable
|
|
);
|
|
// begin_ntddk
|
|
|
|
typedef
|
|
struct _DMA_ADAPTER *
|
|
(*pHalGetDmaAdapter)(
|
|
IN PVOID Context,
|
|
IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
|
|
OUT PULONG NumberOfMapRegisters
|
|
);
|
|
|
|
// end_ntddk
|
|
struct _DMA_ADAPTER *
|
|
HaliGetDmaAdapter(
|
|
IN PVOID Context,
|
|
IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
|
|
OUT PULONG NumberOfMapRegisters
|
|
);
|
|
// begin_ntddk
|
|
|
|
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
|
|
);
|
|
|
|
// end_ntddk
|
|
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
|
|
);
|
|
// begin_ntddk
|
|
|
|
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
|
|
BOOLEAN
|
|
(*pHalResetDisplay) (
|
|
VOID
|
|
);
|
|
|
|
// begin_ntndis
|
|
typedef struct _MAP_REGISTER_ENTRY {
|
|
PVOID MapRegister;
|
|
BOOLEAN WriteToDevice;
|
|
} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY;
|
|
// end_ntndis
|
|
|
|
// end_ntddk
|
|
typedef
|
|
NTSTATUS
|
|
(*pHalAllocateMapRegisters)(
|
|
IN struct _ADAPTER_OBJECT *DmaAdapter,
|
|
IN ULONG NumberOfMapRegisters,
|
|
IN ULONG BaseAddressCount,
|
|
OUT PMAP_REGISTER_ENTRY MapRegsiterArray
|
|
);
|
|
|
|
NTSTATUS
|
|
HalAllocateMapRegisters(
|
|
IN struct _ADAPTER_OBJECT *DmaAdapter,
|
|
IN ULONG NumberOfMapRegisters,
|
|
IN ULONG BaseAddressCount,
|
|
OUT PMAP_REGISTER_ENTRY MapRegsiterArray
|
|
);
|
|
// begin_ntddk
|
|
|
|
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
|
|
|
|
// end_ntddk
|
|
|
|
typedef struct {
|
|
ULONG Version;
|
|
|
|
pHalHandlerForBus HalHandlerForBus;
|
|
pHalHandlerForConfigSpace HalHandlerForConfigSpace;
|
|
pHalLocateHiberRanges HalLocateHiberRanges;
|
|
|
|
pHalRegisterBusHandler HalRegisterBusHandler;
|
|
|
|
pHalSetWakeEnable HalSetWakeEnable;
|
|
pHalSetWakeAlarm HalSetWakeAlarm;
|
|
|
|
pHalTranslateBusAddress HalPciTranslateBusAddress;
|
|
pHalAssignSlotResources HalPciAssignSlotResources;
|
|
|
|
pHalHaltSystem HalHaltSystem;
|
|
|
|
pHalFindBusAddressTranslation HalFindBusAddressTranslation;
|
|
|
|
pHalResetDisplay HalResetDisplay;
|
|
|
|
pHalAllocateMapRegisters HalAllocateMapRegisters;
|
|
|
|
pKdSetupPciDeviceForDebugging KdSetupPciDeviceForDebugging;
|
|
pKdReleasePciDeviceForDebugging KdReleasePciDeviceForDebugging;
|
|
|
|
pKdGetAcpiTablePhase0 KdGetAcpiTablePhase0;
|
|
pKdCheckPowerButton KdCheckPowerButton;
|
|
|
|
pHalVectorToIDTEntry HalVectorToIDTEntry;
|
|
|
|
pKdMapPhysicalMemory64 KdMapPhysicalMemory64;
|
|
pKdUnmapVirtualAddress KdUnmapVirtualAddress;
|
|
|
|
} HAL_PRIVATE_DISPATCH, *PHAL_PRIVATE_DISPATCH;
|
|
|
|
|
|
#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_)
|
|
|
|
extern PHAL_PRIVATE_DISPATCH HalPrivateDispatchTable;
|
|
#define HALPDISPATCH HalPrivateDispatchTable
|
|
|
|
#else
|
|
|
|
extern HAL_PRIVATE_DISPATCH HalPrivateDispatchTable;
|
|
#define HALPDISPATCH (&HalPrivateDispatchTable)
|
|
|
|
#endif
|
|
|
|
#define HAL_PRIVATE_DISPATCH_VERSION 2
|
|
|
|
#define HalRegisterBusHandler HALPDISPATCH->HalRegisterBusHandler
|
|
#define HalHandlerForBus HALPDISPATCH->HalHandlerForBus
|
|
#define HalHandlerForConfigSpace HALPDISPATCH->HalHandlerForConfigSpace
|
|
#define HalLocateHiberRanges HALPDISPATCH->HalLocateHiberRanges
|
|
#define HalSetWakeEnable HALPDISPATCH->HalSetWakeEnable
|
|
#define HalSetWakeAlarm HALPDISPATCH->HalSetWakeAlarm
|
|
#define HalHaltSystem HALPDISPATCH->HalHaltSystem
|
|
#define HalResetDisplay HALPDISPATCH->HalResetDisplay
|
|
#define HalAllocateMapRegisters HALPDISPATCH->HalAllocateMapRegisters
|
|
#define KdSetupPciDeviceForDebugging HALPDISPATCH->KdSetupPciDeviceForDebugging
|
|
#define KdReleasePciDeviceForDebugging HALPDISPATCH->KdReleasePciDeviceForDebugging
|
|
#define KdGetAcpiTablePhase0 HALPDISPATCH->KdGetAcpiTablePhase0
|
|
#define KdCheckPowerButton HALPDISPATCH->KdCheckPowerButton
|
|
#define HalVectorToIDTEntry HALPDISPATCH->HalVectorToIDTEntry
|
|
#define KdMapPhysicalMemory64 HALPDISPATCH->KdMapPhysicalMemory64
|
|
#define KdUnmapVirtualAddress HALPDISPATCH->KdUnmapVirtualAddress
|
|
|
|
// begin_ntddk
|
|
|
|
//
|
|
// 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;
|
|
|
|
// for the information class "HalProfileSourceInformation"
|
|
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 "HalQueryProfileSourceList"
|
|
typedef struct _HAL_PROFILE_SOURCE_LIST {
|
|
KPROFILE_SOURCE Source;
|
|
PWSTR Description;
|
|
} HAL_PROFILE_SOURCE_LIST, *PHAL_PROFILE_SOURCE_LIST;
|
|
|
|
// 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;
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(push)
|
|
#endif
|
|
#pragma warning(disable:4200)
|
|
typedef struct _SCATTER_GATHER_LIST {
|
|
ULONG NumberOfElements;
|
|
ULONG_PTR Reserved;
|
|
SCATTER_GATHER_ELEMENT Elements[];
|
|
} SCATTER_GATHER_LIST, *PSCATTER_GATHER_LIST;
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(pop)
|
|
#else
|
|
#pragma warning(default:4200)
|
|
#endif
|
|
|
|
// 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.
|
|
//
|
|
DECLSPEC_DEPRECATED_DDK // Use AllocateAdapterChannel
|
|
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_)
|
|
|
|
DECLSPEC_DEPRECATED_DDK
|
|
NTSTATUS
|
|
HalGetScatterGatherList ( // Use GetScatterGatherList
|
|
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
|
|
);
|
|
|
|
DECLSPEC_DEPRECATED_DDK // Use PutScatterGatherList
|
|
VOID
|
|
HalPutScatterGatherList (
|
|
IN PADAPTER_OBJECT DmaAdapter,
|
|
IN PSCATTER_GATHER_LIST ScatterGather,
|
|
IN BOOLEAN WriteToDevice
|
|
);
|
|
|
|
DECLSPEC_DEPRECATED_DDK // Use PutDmaAdapter
|
|
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) (((Size) >> PAGE_SHIFT) + \
|
|
(((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
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
LOGICAL
|
|
MmIsIoSpaceActive (
|
|
IN PHYSICAL_ADDRESS StartAddress,
|
|
IN SIZE_T NumberOfBytes
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
// end_ntddk end_nthal end_ntifs
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
MmAddPhysicalMemoryEx (
|
|
IN PPHYSICAL_ADDRESS StartAddress,
|
|
IN OUT PLARGE_INTEGER NumberOfBytes,
|
|
IN ULONG Flags
|
|
);
|
|
// begin_ntddk begin_nthal begin_ntifs
|
|
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
MmRemovePhysicalMemory (
|
|
IN PPHYSICAL_ADDRESS StartAddress,
|
|
IN OUT PLARGE_INTEGER NumberOfBytes
|
|
);
|
|
|
|
// end_ntddk end_nthal end_ntifs
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
MmRemovePhysicalMemoryEx (
|
|
IN PPHYSICAL_ADDRESS StartAddress,
|
|
IN OUT PLARGE_INTEGER NumberOfBytes,
|
|
IN ULONG Flags
|
|
);
|
|
// begin_ntddk begin_nthal begin_ntifs
|
|
|
|
NTKERNELAPI
|
|
PPHYSICAL_MEMORY_RANGE
|
|
MmGetPhysicalMemoryRanges (
|
|
VOID
|
|
);
|
|
|
|
// end_ntddk end_ntifs
|
|
NTSTATUS
|
|
MmMarkPhysicalMemoryAsGood (
|
|
IN PPHYSICAL_ADDRESS StartAddress,
|
|
IN OUT PLARGE_INTEGER NumberOfBytes
|
|
);
|
|
|
|
NTSTATUS
|
|
MmMarkPhysicalMemoryAsBad (
|
|
IN PPHYSICAL_ADDRESS StartAddress,
|
|
IN OUT PLARGE_INTEGER NumberOfBytes
|
|
);
|
|
|
|
// begin_wdm begin_ntddk begin_ntifs
|
|
|
|
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 IoAllocateMdl
|
|
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
|
|
);
|
|
|
|
|
|
//
|
|
// Note that even though this function prototype
|
|
// says "HANDLE", MmSecureVirtualMemory does NOT return
|
|
// anything resembling a Win32-style handle. The return
|
|
// value from this function can ONLY be used with MmUnsecureVirtualMemory.
|
|
//
|
|
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
|
|
);
|
|
|
|
// end_ntddk end_ntifs
|
|
NTKERNELAPI
|
|
NTSTATUS
|
|
MmCommitSessionMappedView (
|
|
IN PVOID MappedAddress,
|
|
IN SIZE_T ViewSize
|
|
);
|
|
// begin_ntddk begin_ntifs
|
|
|
|
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;
|
|
LUID SeImpersonatePrivilege;
|
|
LUID SeCreateGlobalPrivilege;
|
|
|
|
} SE_EXPORTS, *PSE_EXPORTS;
|
|
|
|
#define SeDeleteClientSecurity(C) { \
|
|
if (SeTokenType((C)->ClientToken) == TokenPrimary) { \
|
|
PsDereferencePrimaryToken( (C)->ClientToken ); \
|
|
} else { \
|
|
PsDereferenceImpersonationToken( (C)->ClientToken ); \
|
|
} \
|
|
}
|
|
|
|
|
|
//++
|
|
//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()
|
|
|
|
|
|
//++
|
|
//
|
|
// PACCESS_TOKEN
|
|
// SeQuerySubjectContextToken(
|
|
// IN PSECURITY_SUBJECT_CONTEXT SubjectContext
|
|
// );
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine returns the effective token from the subject context,
|
|
// either the client token, if present, or the process token.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// SubjectContext - Context to query
|
|
//
|
|
// Return Value:
|
|
//
|
|
// This routine returns the PACCESS_TOKEN for the effective token.
|
|
// The pointer may be passed to SeQueryInformationToken. This routine
|
|
// does not affect the lock status of the token, i.e. the token is not
|
|
// locked. If the SubjectContext has been locked, the token remains locked,
|
|
// if not, the token remains unlocked.
|
|
//
|
|
//--
|
|
|
|
#define SeQuerySubjectContextToken( SubjectContext ) \
|
|
( ARGUMENT_PRESENT( ((PSECURITY_SUBJECT_CONTEXT) SubjectContext)->ClientToken) ? \
|
|
((PSECURITY_SUBJECT_CONTEXT) SubjectContext)->ClientToken : \
|
|
((PSECURITY_SUBJECT_CONTEXT) SubjectContext)->PrimaryToken )
|
|
|
|
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
|
|
);
|
|
|
|
NTSTATUS
|
|
SeCaptureAuditPolicy(
|
|
IN PTOKEN_AUDIT_POLICY Policy,
|
|
IN KPROCESSOR_MODE RequestorMode,
|
|
IN PVOID CaptureBuffer OPTIONAL,
|
|
IN ULONG CaptureBufferLength,
|
|
IN POOL_TYPE PoolType,
|
|
IN BOOLEAN ForceCapture,
|
|
OUT PTOKEN_AUDIT_POLICY *CapturedPolicy
|
|
);
|
|
|
|
VOID
|
|
SeReleaseAuditPolicy (
|
|
IN PTOKEN_AUDIT_POLICY CapturedPolicy,
|
|
IN KPROCESSOR_MODE RequestorMode,
|
|
IN BOOLEAN ForceCapture
|
|
);
|
|
|
|
|
|
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
|
|
);
|
|
extern struct _OBJECT_TYPE *SeTokenObjectType;
|
|
|
|
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
|
|
SeTokenCanImpersonate(
|
|
IN PACCESS_TOKEN ProcessToken,
|
|
IN PACCESS_TOKEN Token,
|
|
IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
|
|
);
|
|
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
|
|
);
|
|
|
|
// end_ntifs
|
|
|
|
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
|
|
ULONG
|
|
PsGetProcessSessionIdEx(
|
|
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
|
|
);
|
|
|
|
#ifndef _WIN64
|
|
NTSTATUS
|
|
PsSetLdtEntries (
|
|
IN ULONG Selector0,
|
|
IN ULONG Entry0Low,
|
|
IN ULONG Entry0Hi,
|
|
IN ULONG Selector1,
|
|
IN ULONG Entry1Low,
|
|
IN ULONG Entry1Hi
|
|
);
|
|
|
|
NTSTATUS
|
|
PsSetProcessLdtInfo (
|
|
IN PPROCESS_LDT_INFORMATION LdtInformation,
|
|
IN ULONG LdtInformationLength
|
|
);
|
|
#endif
|
|
//
|
|
// 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_PTR ProcessHandleCount,
|
|
IN ULONG_PTR 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,
|
|
IN KPROCESSOR_MODE Mode
|
|
);
|
|
|
|
/*
|
|
|
|
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
|
|
#define OBJ_INVALID_SESSION_ID 0xFFFFFFFF
|
|
|
|
typedef struct _OBJECT_DIRECTORY {
|
|
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
|
|
EX_PUSH_LOCK Lock;
|
|
struct _DEVICE_MAP *DeviceMap;
|
|
ULONG SessionId;
|
|
#if 0
|
|
USHORT Reserved;
|
|
USHORT SymbolicLinkUsageCount;
|
|
#endif
|
|
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
|
|
typedef struct _OBJECT_CREATE_INFORMATION *POBJECT_CREATE_INFORMATION;;
|
|
|
|
typedef struct _OBJECT_HEADER {
|
|
LONG_PTR PointerCount;
|
|
union {
|
|
LONG_PTR 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
|
|
);
|
|
|
|
#define OBJ_PROTECT_CLOSE 0x00000001L
|
|
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ObDeleteCapturedInsertInfo(
|
|
IN PVOID Object
|
|
);
|
|
|
|
|
|
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_PTR
|
|
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_PTR
|
|
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
|
|
);
|
|
// end_ntifs end_ntddk end_wdm
|
|
NTSTATUS
|
|
ObLogSecurityDescriptor (
|
|
IN PSECURITY_DESCRIPTOR InputSecurityDescriptor,
|
|
OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
|
|
ULONG RefBias
|
|
);
|
|
|
|
VOID
|
|
ObDereferenceSecurityDescriptor (
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
ULONG Count
|
|
);
|
|
|
|
VOID
|
|
ObReferenceSecurityDescriptor (
|
|
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
IN ULONG Count
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
NTSTATUS
|
|
ObSwapObjectNames (
|
|
IN HANDLE DirectoryHandle,
|
|
IN HANDLE Handle1,
|
|
IN HANDLE Handle2,
|
|
IN ULONG Flags
|
|
);
|
|
|
|
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
|
|
#define PCI_CAPABILITY_ID_AGP_TARGET 0x0E
|
|
|
|
//
|
|
// 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 Agp3Mode:1;
|
|
ULONG FastWrite:1;
|
|
ULONG FourGB:1;
|
|
ULONG HostTransDisable:1;
|
|
ULONG Gart64:1;
|
|
ULONG ITA_Coherent:1;
|
|
ULONG SideBandAddressing:1; // SBA
|
|
ULONG CalibrationCycle:3;
|
|
ULONG AsyncRequestSize:3;
|
|
ULONG Rsvd1:1;
|
|
ULONG Isoch:1;
|
|
ULONG Rsvd2:6;
|
|
ULONG RequestQueueDepthMaximum:8; // RQ
|
|
} AGPStatus;
|
|
|
|
struct _PCI_AGP_COMMAND {
|
|
ULONG Rate:3;
|
|
ULONG Rsvd1:1;
|
|
ULONG FastWriteEnable:1;
|
|
ULONG FourGBEnable:1;
|
|
ULONG Rsvd2:1;
|
|
ULONG Gart64:1;
|
|
ULONG AGPEnable:1;
|
|
ULONG SBAEnable:1;
|
|
ULONG CalibrationCycle:3;
|
|
ULONG AsyncReqSize:3;
|
|
ULONG Rsvd3:8;
|
|
ULONG RequestQueueDepth:8;
|
|
} AGPCommand;
|
|
|
|
} PCI_AGP_CAPABILITY, *PPCI_AGP_CAPABILITY;
|
|
|
|
//
|
|
// An AGPv3 Target must have an extended capability,
|
|
// but it's only present for a Master when the Isoch
|
|
// bit is set in its status register
|
|
//
|
|
typedef enum _EXTENDED_AGP_REGISTER {
|
|
IsochStatus,
|
|
AgpControl,
|
|
ApertureSize,
|
|
AperturePageSize,
|
|
GartLow,
|
|
GartHigh,
|
|
IsochCommand
|
|
} EXTENDED_AGP_REGISTER, *PEXTENDED_AGP_REGISTER;
|
|
|
|
typedef struct _PCI_AGP_ISOCH_STATUS {
|
|
ULONG ErrorCode: 2;
|
|
ULONG Rsvd1: 1;
|
|
ULONG Isoch_L: 3;
|
|
ULONG Isoch_Y: 2;
|
|
ULONG Isoch_N: 8;
|
|
ULONG Rsvd2: 16;
|
|
} PCI_AGP_ISOCH_STATUS, *PPCI_AGP_ISOCH_STATUS;
|
|
|
|
typedef struct _PCI_AGP_CONTROL {
|
|
ULONG Rsvd1: 7;
|
|
ULONG GTLB_Enable: 1;
|
|
ULONG AP_Enable: 1;
|
|
ULONG CAL_Disable: 1;
|
|
ULONG Rsvd2: 22;
|
|
} PCI_AGP_CONTROL, *PPCI_AGP_CONTROL;
|
|
|
|
typedef struct _PCI_AGP_APERTURE_PAGE_SIZE {
|
|
USHORT PageSizeMask: 11;
|
|
USHORT Rsvd1: 1;
|
|
USHORT PageSizeSelect: 4;
|
|
} PCI_AGP_APERTURE_PAGE_SIZE, *PPCI_AGP_APERTURE_PAGE_SIZE;
|
|
|
|
typedef struct _PCI_AGP_ISOCH_COMMAND {
|
|
USHORT Rsvd1: 6;
|
|
USHORT Isoch_Y: 2;
|
|
USHORT Isoch_N: 8;
|
|
} PCI_AGP_ISOCH_COMMAND, *PPCI_AGP_ISOCH_COMMAND;
|
|
|
|
typedef struct PCI_AGP_EXTENDED_CAPABILITY {
|
|
|
|
PCI_AGP_ISOCH_STATUS IsochStatus;
|
|
|
|
//
|
|
// Target only ----------------<<-begin->>
|
|
//
|
|
PCI_AGP_CONTROL AgpControl;
|
|
USHORT ApertureSize;
|
|
PCI_AGP_APERTURE_PAGE_SIZE AperturePageSize;
|
|
ULONG GartLow;
|
|
ULONG GartHigh;
|
|
//
|
|
// ------------------------------<<-end->>
|
|
//
|
|
|
|
PCI_AGP_ISOCH_COMMAND IsochCommand;
|
|
|
|
} PCI_AGP_EXTENDED_CAPABILITY, *PPCI_AGP_EXTENDED_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_
|