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