581 lines
16 KiB
C
581 lines
16 KiB
C
/*++ BUILD Version: 0003 // Increment this if a change has global effects
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ntosdef.h
|
||
|
||
Abstract:
|
||
|
||
Common type definitions for the NTOS component that are private to
|
||
NTOS, but shared between NTOS sub-components.
|
||
|
||
Author:
|
||
|
||
Steve Wood (stevewo) 08-May-1989
|
||
|
||
Revision History:
|
||
|
||
*/
|
||
|
||
#ifndef _NTOSDEF_
|
||
#define _NTOSDEF_
|
||
|
||
|
||
// Define interlocked sequenced list structure.
|
||
|
||
// begin_ntddk begin_wdm begin_nthal begin_ntifs begin_ntndis
|
||
|
||
#if defined(_WIN64)
|
||
|
||
typedef union _SLIST_HEADER {
|
||
ULONGLONG Alignment;
|
||
struct {
|
||
ULONGLONG Depth : 16;
|
||
ULONGLONG Sequence : 8;
|
||
ULONGLONG Next : 40;
|
||
};
|
||
} SLIST_HEADER, *PSLIST_HEADER;
|
||
|
||
#else
|
||
|
||
typedef union _SLIST_HEADER {
|
||
ULONGLONG Alignment;
|
||
struct {
|
||
SINGLE_LIST_ENTRY Next;
|
||
USHORT Depth;
|
||
USHORT Sequence;
|
||
};
|
||
} SLIST_HEADER, *PSLIST_HEADER;
|
||
|
||
#endif
|
||
|
||
// end_ntddk end_wdm end_nthal end_ntifs end_ntndis
|
||
|
||
|
||
// Define per processor nonpaged lookaside list descriptor structure.
|
||
|
||
|
||
struct _NPAGED_LOOKASIDE_LIST;
|
||
|
||
typedef struct _PP_LOOKASIDE_LIST {
|
||
struct _NPAGED_LOOKASIDE_LIST *P;
|
||
struct _NPAGED_LOOKASIDE_LIST *L;
|
||
} PP_LOOKASIDE_LIST, *PPP_LOOKASIDE_LIST;
|
||
|
||
// begin_nthal
|
||
|
||
|
||
// Define per processor lock queue structure.
|
||
|
||
// N.B. The lock field of the spin lock queue structure contains the address
|
||
// of the associated kernel spin lock, an owner bit, and a lock bit. Bit
|
||
// 0 of the spin lock address is the wait bit and bit 1 is the owner bit.
|
||
// The use of this field is such that the bits can be set and cleared
|
||
// noninterlocked, however, the back pointer must be preserved.
|
||
|
||
// The lock wait bit is set when a processor enqueues itself on the lock
|
||
// queue and it is not the only entry in the queue. The processor will
|
||
// spin on this bit waiting for the lock to be granted.
|
||
|
||
// The owner bit is set when the processor owns the respective lock.
|
||
|
||
// The next field of the spin lock queue structure is used to line the
|
||
// queued lock structures together in fifo order. It also can set set and
|
||
// cleared noninterlocked.
|
||
|
||
|
||
#define LOCK_QUEUE_WAIT 1
|
||
#define LOCK_QUEUE_OWNER 2
|
||
|
||
typedef enum _KSPIN_LOCK_QUEUE_NUMBER {
|
||
LockQueueDispatcherLock,
|
||
LockQueueContextSwapLock,
|
||
LockQueuePfnLock,
|
||
LockQueueSystemSpaceLock,
|
||
LockQueueVacbLock,
|
||
LockQueueMasterLock,
|
||
LockQueueMaximumLock
|
||
} KSPIN_LOCK_QUEUE_NUMBER, *PKSPIN_LOCK_QUEUE_NUMBER;
|
||
|
||
typedef struct _KSPIN_LOCK_QUEUE {
|
||
struct _KSPIN_LOCK_QUEUE *Next;
|
||
PKSPIN_LOCK Lock;
|
||
} KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;
|
||
|
||
// end_nthal
|
||
|
||
|
||
// 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 8
|
||
|
||
// 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
|
||
|
||
// end_ntddk end_wdm end_nthal end_ntifs
|
||
|
||
// Global flag set by NtPartyByNumber(6) controls behaviour of
|
||
// NT. See \nt\sdk\inc\ntexapi.h for flag definitions
|
||
|
||
// begin_ntddk begin_wdm begin_nthal begin_ntifs
|
||
|
||
extern ULONG NtGlobalFlag;
|
||
|
||
#define IF_NTOS_DEBUG( FlagName ) \
|
||
if (NtGlobalFlag & (FLG_ ## FlagName))
|
||
|
||
#else
|
||
#define IF_NTOS_DEBUG( FlagName ) if (FALSE)
|
||
#endif
|
||
|
||
|
||
// Kernel definitions that need to be here for forward reference purposes
|
||
|
||
|
||
// begin_ntndis
|
||
|
||
// Processor modes.
|
||
|
||
|
||
typedef CCHAR KPROCESSOR_MODE;
|
||
|
||
typedef enum _MODE {
|
||
KernelMode,
|
||
UserMode,
|
||
MaximumMode
|
||
} MODE;
|
||
|
||
// end_ntndis
|
||
|
||
// APC function types
|
||
|
||
|
||
|
||
// Put in an empty definition for the KAPC so that the
|
||
// routines can reference it before it is declared.
|
||
|
||
|
||
struct _KAPC;
|
||
|
||
typedef
|
||
VOID
|
||
(*PKNORMAL_ROUTINE) (
|
||
IN PVOID NormalContext,
|
||
IN PVOID SystemArgument1,
|
||
IN PVOID SystemArgument2
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PKKERNEL_ROUTINE) (
|
||
IN struct _KAPC *Apc,
|
||
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
|
||
IN OUT PVOID *NormalContext,
|
||
IN OUT PVOID *SystemArgument1,
|
||
IN OUT PVOID *SystemArgument2
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PKRUNDOWN_ROUTINE) (
|
||
IN struct _KAPC *Apc
|
||
);
|
||
|
||
typedef
|
||
BOOLEAN
|
||
(*PKSYNCHRONIZE_ROUTINE) (
|
||
IN PVOID SynchronizeContext
|
||
);
|
||
|
||
typedef
|
||
BOOLEAN
|
||
(*PKTRANSFER_ROUTINE) (
|
||
VOID
|
||
);
|
||
|
||
|
||
|
||
// Asynchronous Procedure Call (APC) object
|
||
|
||
|
||
typedef struct _KAPC {
|
||
CSHORT Type;
|
||
CSHORT Size;
|
||
ULONG Spare0;
|
||
struct _KTHREAD *Thread;
|
||
LIST_ENTRY ApcListEntry;
|
||
PKKERNEL_ROUTINE KernelRoutine;
|
||
PKRUNDOWN_ROUTINE RundownRoutine;
|
||
PKNORMAL_ROUTINE NormalRoutine;
|
||
PVOID NormalContext;
|
||
|
||
|
||
// N.B. The following two members MUST be together.
|
||
|
||
|
||
PVOID SystemArgument1;
|
||
PVOID SystemArgument2;
|
||
CCHAR ApcStateIndex;
|
||
KPROCESSOR_MODE ApcMode;
|
||
BOOLEAN Inserted;
|
||
} KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC;
|
||
|
||
// begin_ntndis
|
||
|
||
// DPC routine
|
||
|
||
|
||
struct _KDPC;
|
||
|
||
typedef
|
||
VOID
|
||
(*PKDEFERRED_ROUTINE) (
|
||
IN struct _KDPC *Dpc,
|
||
IN PVOID DeferredContext,
|
||
IN PVOID SystemArgument1,
|
||
IN PVOID SystemArgument2
|
||
);
|
||
|
||
|
||
// Define DPC importance.
|
||
|
||
// LowImportance - Queue DPC at end of target DPC queue.
|
||
// MediumImportance - Queue DPC at end of target DPC queue.
|
||
// HighImportance - Queue DPC at front of target DPC DPC queue.
|
||
|
||
// If there is currently a DPC active on the target processor, or a DPC
|
||
// interrupt has already been requested on the target processor when a
|
||
// DPC is queued, then no further action is necessary. The DPC will be
|
||
// executed on the target processor when its queue entry is processed.
|
||
|
||
// If there is not a DPC active on the target processor and a DPC interrupt
|
||
// has not been requested on the target processor, then the exact treatment
|
||
// of the DPC is dependent on whether the host system is a UP system or an
|
||
// MP system.
|
||
|
||
// UP system.
|
||
|
||
// If the DPC is of medium or high importance, the current DPC queue depth
|
||
// is greater than the maximum target depth, or current DPC request rate is
|
||
// less the minimum target rate, then a DPC interrupt is requested on the
|
||
// host processor and the DPC will be processed when the interrupt occurs.
|
||
// Otherwise, no DPC interupt is requested and the DPC execution will be
|
||
// delayed until the DPC queue depth is greater that the target depth or the
|
||
// minimum DPC rate is less than the target rate.
|
||
|
||
// MP system.
|
||
|
||
// If the DPC is being queued to another processor and the depth of the DPC
|
||
// queue on the target processor is greater than the maximum target depth or
|
||
// the DPC is of high importance, then a DPC interrupt is requested on the
|
||
// target processor and the DPC will be processed when the interrupt occurs.
|
||
// Otherwise, the DPC execution will be delayed on the target processor until
|
||
// the DPC queue depth on the target processor is greater that the maximum
|
||
// target depth or the minimum DPC rate on the target processor is less than
|
||
// the target mimimum rate.
|
||
|
||
// If the DPC is being queued to the current processor and the DPC is not of
|
||
// low importance, the current DPC queue depth is greater than the maximum
|
||
// target depth, or the minimum DPC rate is less than the minimum target rate,
|
||
// then a DPC interrupt is request on the current processor and the DPV will
|
||
// be processed whne the interrupt occurs. Otherwise, no DPC interupt is
|
||
// requested and the DPC execution will be delayed until the DPC queue depth
|
||
// is greater that the target depth or the minimum DPC rate is less than the
|
||
// target rate.
|
||
|
||
|
||
typedef enum _KDPC_IMPORTANCE {
|
||
LowImportance,
|
||
MediumImportance,
|
||
HighImportance
|
||
} KDPC_IMPORTANCE;
|
||
|
||
|
||
// Deferred Procedure Call (DPC) object
|
||
|
||
|
||
typedef struct _KDPC {
|
||
CSHORT Type;
|
||
UCHAR Number;
|
||
UCHAR Importance;
|
||
LIST_ENTRY DpcListEntry;
|
||
PKDEFERRED_ROUTINE DeferredRoutine;
|
||
PVOID DeferredContext;
|
||
PVOID SystemArgument1;
|
||
PVOID SystemArgument2;
|
||
PULONG_PTR Lock;
|
||
} KDPC, *PKDPC, *RESTRICTED_POINTER PRKDPC;
|
||
|
||
|
||
// Interprocessor interrupt worker routine function prototype.
|
||
|
||
|
||
typedef PVOID PKIPI_CONTEXT;
|
||
|
||
typedef
|
||
VOID
|
||
(*PKIPI_WORKER)(
|
||
IN PKIPI_CONTEXT PacketContext,
|
||
IN PVOID Parameter1,
|
||
IN PVOID Parameter2,
|
||
IN PVOID Parameter3
|
||
);
|
||
|
||
|
||
// Define interprocessor interrupt performance counters.
|
||
|
||
|
||
typedef struct _KIPI_COUNTS {
|
||
ULONG Freeze;
|
||
ULONG Packet;
|
||
ULONG DPC;
|
||
ULONG APC;
|
||
ULONG FlushSingleTb;
|
||
ULONG FlushMultipleTb;
|
||
ULONG FlushEntireTb;
|
||
ULONG GenericCall;
|
||
ULONG ChangeColor;
|
||
ULONG SweepDcache;
|
||
ULONG SweepIcache;
|
||
ULONG SweepIcacheRange;
|
||
ULONG FlushIoBuffers;
|
||
ULONG GratuitousDPC;
|
||
} KIPI_COUNTS, *PKIPI_COUNTS;
|
||
|
||
#if defined(NT_UP)
|
||
|
||
#define HOT_STATISTIC(a) a
|
||
|
||
#else
|
||
|
||
#define HOT_STATISTIC(a) (KeGetCurrentPrcb()->a)
|
||
|
||
#endif
|
||
|
||
|
||
// I/O system definitions.
|
||
|
||
// Define a Memory Descriptor List (MDL)
|
||
|
||
// An MDL describes pages in a virtual buffer in terms of physical pages. The
|
||
// pages associated with the buffer are described in an array that is allocated
|
||
// just after the MDL header structure itself. In a future compiler this will
|
||
// be placed at:
|
||
|
||
// ULONG Pages[];
|
||
|
||
// Until this declaration is permitted, however, one simply calculates the
|
||
// base of the array by adding one to the base MDL pointer:
|
||
|
||
// Pages = (PULONG) (Mdl + 1);
|
||
|
||
// Notice that while in the context of the subject thread, the base virtual
|
||
// address of a buffer mapped by an MDL may be referenced using the following:
|
||
|
||
// Mdl->StartVa | Mdl->ByteOffset
|
||
|
||
|
||
|
||
typedef struct _MDL {
|
||
struct _MDL *Next;
|
||
CSHORT Size;
|
||
CSHORT MdlFlags;
|
||
struct _EPROCESS *Process;
|
||
PVOID MappedSystemVa;
|
||
PVOID StartVa;
|
||
ULONG ByteCount;
|
||
ULONG ByteOffset;
|
||
} MDL, *PMDL;
|
||
|
||
#define MDL_MAPPED_TO_SYSTEM_VA 0x0001
|
||
#define MDL_PAGES_LOCKED 0x0002
|
||
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
|
||
#define MDL_ALLOCATED_FIXED_SIZE 0x0008
|
||
#define MDL_PARTIAL 0x0010
|
||
#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
|
||
#define MDL_IO_PAGE_READ 0x0040
|
||
#define MDL_WRITE_OPERATION 0x0080
|
||
#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
|
||
#define MDL_LOCK_HELD 0x0200
|
||
#define MDL_PHYSICAL_VIEW 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_LOCK_HELD | \
|
||
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()
|
||
#endif
|
||
|
||
// end_ntddk end_wdm end_nthal end_ntifs
|
||
|
||
|
||
// begin_ntifs
|
||
|
||
// 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;
|
||
|
||
// end_ntifs
|
||
|
||
|
||
// 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.
|
||
|
||
|
||
// begin_ntddk begin_wdm begin_nthal begin_ntndis begin_ntifs
|
||
|
||
// Define function decoration depending on whether a driver, a file system,
|
||
// or a kernel component is being built.
|
||
|
||
// end_wdm
|
||
|
||
#if (defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_)) && !defined(_BLDR_)
|
||
|
||
#define NTKERNELAPI DECLSPEC_IMPORT // wdm
|
||
|
||
#else
|
||
|
||
#define NTKERNELAPI
|
||
|
||
#endif
|
||
|
||
|
||
// Define function decoration depending on whether the HAL or other kernel
|
||
// component is being build.
|
||
|
||
|
||
#if !defined(_NTHAL_) && !defined(_BLDR_)
|
||
|
||
#define NTHALAPI DECLSPEC_IMPORT // wdm
|
||
|
||
#else
|
||
|
||
#define NTHALAPI
|
||
|
||
#endif
|
||
|
||
// end_ntddk end_nthal end_ntndis end_ntifs
|
||
|
||
#endif // _NTOSDEF_
|