windows-nt/Source/XPSP1/NT/base/ntos/inc/ntosdef.h

553 lines
15 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++ 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_
// begin_ntosp
//
// 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
// end_ntddk end_wdm end_nthal end_ntifs end_ntosp
//
// 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 begin_ntosp
extern ULONG NtGlobalFlag;
#define IF_NTOS_DEBUG( FlagName ) \
if (NtGlobalFlag & (FLG_ ## FlagName))
#else
#define IF_NTOS_DEBUG( FlagName ) if (FALSE)
#endif
//
// Kernel definitions that need to be here for forward reference purposes
//
// begin_ntndis
//
// Processor modes.
//
typedef CCHAR KPROCESSOR_MODE;
typedef enum _MODE {
KernelMode,
UserMode,
MaximumMode
} MODE;
// end_ntndis
//
// APC function types
//
//
// Put in an empty definition for the KAPC so that the
// routines can reference it before it is declared.
//
struct _KAPC;
typedef
VOID
(*PKNORMAL_ROUTINE) (
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
typedef
VOID
(*PKKERNEL_ROUTINE) (
IN struct _KAPC *Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
);
typedef
VOID
(*PKRUNDOWN_ROUTINE) (
IN struct _KAPC *Apc
);
typedef
BOOLEAN
(*PKSYNCHRONIZE_ROUTINE) (
IN PVOID SynchronizeContext
);
typedef
BOOLEAN
(*PKTRANSFER_ROUTINE) (
VOID
);
//
//
// Asynchronous Procedure Call (APC) object
//
//
typedef struct _KAPC {
CSHORT Type;
CSHORT Size;
ULONG Spare0;
struct _KTHREAD *Thread;
LIST_ENTRY ApcListEntry;
PKKERNEL_ROUTINE KernelRoutine;
PKRUNDOWN_ROUTINE RundownRoutine;
PKNORMAL_ROUTINE NormalRoutine;
PVOID NormalContext;
//
// N.B. The following two members MUST be together.
//
PVOID SystemArgument1;
PVOID SystemArgument2;
CCHAR ApcStateIndex;
KPROCESSOR_MODE ApcMode;
BOOLEAN Inserted;
} KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC;
// begin_ntndis
//
// DPC routine
//
struct _KDPC;
typedef
VOID
(*PKDEFERRED_ROUTINE) (
IN struct _KDPC *Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
//
// Define DPC importance.
//
// LowImportance - Queue DPC at end of target DPC queue.
// MediumImportance - Queue DPC at end of target DPC queue.
// HighImportance - Queue DPC at front of target DPC DPC queue.
//
// If there is currently a DPC active on the target processor, or a DPC
// interrupt has already been requested on the target processor when a
// DPC is queued, then no further action is necessary. The DPC will be
// executed on the target processor when its queue entry is processed.
//
// If there is not a DPC active on the target processor and a DPC interrupt
// has not been requested on the target processor, then the exact treatment
// of the DPC is dependent on whether the host system is a UP system or an
// MP system.
//
// UP system.
//
// If the DPC is of medium or high importance, the current DPC queue depth
// is greater than the maximum target depth, or current DPC request rate is
// less the minimum target rate, then a DPC interrupt is requested on the
// host processor and the DPC will be processed when the interrupt occurs.
// Otherwise, no DPC interupt is requested and the DPC execution will be
// delayed until the DPC queue depth is greater that the target depth or the
// minimum DPC rate is less than the target rate.
//
// MP system.
//
// If the DPC is being queued to another processor and the depth of the DPC
// queue on the target processor is greater than the maximum target depth or
// the DPC is of high importance, then a DPC interrupt is requested on the
// target processor and the DPC will be processed when the interrupt occurs.
// Otherwise, the DPC execution will be delayed on the target processor until
// the DPC queue depth on the target processor is greater that the maximum
// target depth or the minimum DPC rate on the target processor is less than
// the target mimimum rate.
//
// If the DPC is being queued to the current processor and the DPC is not of
// low importance, the current DPC queue depth is greater than the maximum
// target depth, or the minimum DPC rate is less than the minimum target rate,
// then a DPC interrupt is request on the current processor and the DPV will
// be processed whne the interrupt occurs. Otherwise, no DPC interupt is
// requested and the DPC execution will be delayed until the DPC queue depth
// is greater that the target depth or the minimum DPC rate is less than the
// target rate.
//
typedef enum _KDPC_IMPORTANCE {
LowImportance,
MediumImportance,
HighImportance
} KDPC_IMPORTANCE;
//
// Deferred Procedure Call (DPC) object
//
typedef struct _KDPC {
CSHORT Type;
UCHAR Number;
UCHAR Importance;
LIST_ENTRY DpcListEntry;
PKDEFERRED_ROUTINE DeferredRoutine;
PVOID DeferredContext;
PVOID SystemArgument1;
PVOID SystemArgument2;
PULONG_PTR Lock;
} KDPC, *PKDPC, *RESTRICTED_POINTER PRKDPC;
//
// Interprocessor interrupt worker routine function prototype.
//
typedef PVOID PKIPI_CONTEXT;
typedef
VOID
(*PKIPI_WORKER)(
IN PKIPI_CONTEXT PacketContext,
IN PVOID Parameter1,
IN PVOID Parameter2,
IN PVOID Parameter3
);
//
// Define interprocessor interrupt performance counters.
//
typedef struct _KIPI_COUNTS {
ULONG Freeze;
ULONG Packet;
ULONG DPC;
ULONG APC;
ULONG FlushSingleTb;
ULONG FlushMultipleTb;
ULONG FlushEntireTb;
ULONG GenericCall;
ULONG ChangeColor;
ULONG SweepDcache;
ULONG SweepIcache;
ULONG SweepIcacheRange;
ULONG FlushIoBuffers;
ULONG GratuitousDPC;
} KIPI_COUNTS, *PKIPI_COUNTS;
#if defined(NT_UP)
#define HOT_STATISTIC(a) a
#else
#define HOT_STATISTIC(a) (KeGetCurrentPrcb()->a)
#endif
//
// I/O system definitions.
//
// Define a Memory Descriptor List (MDL)
//
// An MDL describes pages in a virtual buffer in terms of physical pages. The
// pages associated with the buffer are described in an array that is allocated
// just after the MDL header structure itself. In a future compiler this will
// be placed at:
//
// ULONG Pages[];
//
// Until this declaration is permitted, however, one simply calculates the
// base of the array by adding one to the base MDL pointer:
//
// Pages = (PULONG) (Mdl + 1);
//
// Notice that while in the context of the subject thread, the base virtual
// address of a buffer mapped by an MDL may be referenced using the following:
//
// Mdl->StartVa | Mdl->ByteOffset
//
typedef struct _MDL {
struct _MDL *Next;
CSHORT Size;
CSHORT MdlFlags;
struct _EPROCESS *Process;
PVOID MappedSystemVa;
PVOID StartVa;
ULONG ByteCount;
ULONG ByteOffset;
} MDL, *PMDL;
#define MDL_MAPPED_TO_SYSTEM_VA 0x0001
#define MDL_PAGES_LOCKED 0x0002
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
#define MDL_ALLOCATED_FIXED_SIZE 0x0008
#define MDL_PARTIAL 0x0010
#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
#define MDL_IO_PAGE_READ 0x0040
#define MDL_WRITE_OPERATION 0x0080
#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
#define MDL_FREE_EXTRA_PTES 0x0200
#define MDL_IO_SPACE 0x0800
#define MDL_NETWORK_HEADER 0x1000
#define MDL_MAPPING_CAN_FAIL 0x2000
#define MDL_ALLOCATED_MUST_SUCCEED 0x4000
#define MDL_MAPPING_FLAGS (MDL_MAPPED_TO_SYSTEM_VA | \
MDL_PAGES_LOCKED | \
MDL_SOURCE_IS_NONPAGED_POOL | \
MDL_PARTIAL_HAS_BEEN_MAPPED | \
MDL_PARENT_MAPPED_SYSTEM_VA | \
MDL_SYSTEM_VA | \
MDL_IO_SPACE )
// end_ntndis
//
// switch to DBG when appropriate
//
#if DBG
#define PAGED_CODE() \
{ if (KeGetCurrentIrql() > APC_LEVEL) { \
KdPrint(( "EX: Pageable code called at IRQL %d\n", KeGetCurrentIrql() )); \
ASSERT(FALSE); \
} \
}
#else
#define PAGED_CODE() NOP_FUNCTION;
#endif
// end_ntddk end_wdm end_nthal end_ntifs end_ntosp
// begin_ntifs begin_ntosp
//
// 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.
//
// end_ntifs end_ntosp
//
// Define function decoration depending on whether a driver, a file system,
// or a kernel component is being built.
//
#if (defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTHAL_) || defined(_NTOSP_)) && !defined(_BLDR_)
// begin_ntosp
#if defined(_NTSYSTEM_)
#define NTKERNELAPI
#else
#define NTKERNELAPI DECLSPEC_IMPORT // wdm ntddk nthal ntndis ntifs
#endif
// end_ntosp
#else
#define NTKERNELAPI
#endif
//
// Define function decoration depending on whether the HAL or other kernel
// component is being build.
// begin_ntddk
#if !defined(_NTHAL_) && !defined(_BLDR_)
#define NTHALAPI DECLSPEC_IMPORT // wdm ntndis ntifs ntosp
#else
#define NTHALAPI // nthal
#endif
// end_ntddk
// begin_ntddk begin_wdm begin_nthal begin_ntifs begin_ntndis begin_ntosp
//
// Common dispatcher object header
//
// N.B. The size field contains the number of dwords in the structure.
//
typedef struct _DISPATCHER_HEADER {
UCHAR Type;
UCHAR Absolute;
UCHAR Size;
UCHAR Inserted;
LONG SignalState;
LIST_ENTRY WaitListHead;
} DISPATCHER_HEADER;
//
// Event object
//
typedef struct _KEVENT {
DISPATCHER_HEADER Header;
} KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT;
//
// Timer object
//
typedef struct _KTIMER {
DISPATCHER_HEADER Header;
ULARGE_INTEGER DueTime;
LIST_ENTRY TimerListEntry;
struct _KDPC *Dpc;
LONG Period;
} KTIMER, *PKTIMER, *RESTRICTED_POINTER PRKTIMER;
// end_ntddk end_wdm end_nthal end_ntifs end_ntndis end_ntosp
#endif // _NTOSDEF_