|
|
1.1 root 1: /*++ BUILD Version: 0166 // Increment this if a change has global effects
2:
3: Copyright (c) 1990-1992 Microsoft Corporation
4:
5: Module Name:
6:
7: ntddk.h
8:
9: Abstract:
10:
11: This module defines the NT types, constants, and functions that are
12: exposed to device drivers.
13:
14: Revision History:
15:
16: --*/
17:
18: #ifndef _NTDDK_
19: #define _NTDDK_
20:
21: #define NT_INCLUDED
22:
23: #include <excpt.h>
24: #include <ntdef.h>
25: #include <ntstatus.h>
26: #include <bugcodes.h>
27: #include <exlevels.h>
28: #include <ntiologc.h>
29:
30: //
31: // Define types that are not exported.
32: //
33:
34: typedef struct _KTHREAD *PKTHREAD;
35: typedef struct _ETHREAD *PETHREAD;
36: typedef struct _EPROCESS *PEPROCESS;
37: typedef struct _PEB *PPEB;
38: typedef struct _KINTERRUPT *PKINTERRUPT;
39: typedef struct _IO_TIMER *PIO_TIMER;
40: typedef struct _OBJECT_TYPE *POBJECT_TYPE;
41:
42: #if defined(_ALPHA_)
43: PKTHREAD KeGetCurrentThread();
44: KIRQL KeGetCurrentIrql();
45: #endif // defined(_ALPHA_)
46:
47: #if defined(MIPS)
48: #define KIPCR 0xfffff000
49: #define PCR ((volatile KPCR * const)KIPCR)
50: #define KeGetCurrentThread() PCR->CurrentThread
51: #define KeGetCurrentIrql() PCR->CurrentIrql
52: #endif // defined(MIPS)
53:
54: #if defined(_M_IX86)
55: PKTHREAD KeGetCurrentThread();
56:
57: KIRQL KeGetCurrentIrql();
58: #endif // defined(_M_IX86)
59:
60: #define PsGetCurrentProcess() IoGetCurrentProcess()
61: #define PsGetCurrentThread() ((PETHREAD) (KeGetCurrentThread()))
62: extern PCCHAR KeNumberProcessors;
63:
64: #ifndef DBG
65: #define DBG 0
66: #endif
67:
68: #if DBG
69: #define IF_DEBUG if (TRUE)
70: #else
71: #define IF_DEBUG if (FALSE)
72: #endif
73:
74: #if DEVL
75: //
76: // Global flag set by NtPartyByNumber(6) controls behaviour of
77: // NT. See \nt\sdk\inc\ntexapi.h for flag definitions
78: //
79:
80: extern ULONG NtGlobalFlag;
81:
82: #define IF_NTOS_DEBUG( FlagName ) \
83: if (NtGlobalFlag & (FLG_ ## FlagName))
84:
85: #else
86: #define IF_NTOS_DEBUG( FlagName ) if (FALSE)
87: #endif
88:
89: //
90: // Kernel definitions that need to be here for forward reference purposes
91: //
92:
93: //
94: // Processor modes.
95: //
96:
97: typedef CCHAR KPROCESSOR_MODE;
98:
99: typedef enum _MODE {
100: KernelMode,
101: UserMode,
102: MaximumMode
103: } MODE;
104:
105: //
106: // APC function types
107: //
108:
109: //
110: // Put in an empty definition for the KAPC so that the
111: // routines can reference it before it is declared.
112: //
113:
114: struct _KAPC;
115:
116: typedef
117: VOID
118: (*PKNORMAL_ROUTINE) (
119: IN PVOID NormalContext,
120: IN PVOID SystemArgument1,
121: IN PVOID SystemArgument2
122: );
123:
124: typedef
125: VOID
126: (*PKKERNEL_ROUTINE) (
127: IN struct _KAPC *Apc,
128: IN OUT PKNORMAL_ROUTINE *NormalRoutine,
129: IN OUT PVOID *NormalContext,
130: IN OUT PVOID *SystemArgument1,
131: IN OUT PVOID *SystemArgument2
132: );
133:
134: typedef
135: VOID
136: (*PKRUNDOWN_ROUTINE) (
137: IN struct _KAPC *Apc
138: );
139:
140: typedef
141: BOOLEAN
142: (*PKSYNCHRONIZE_ROUTINE) (
143: IN PVOID SynchronizeContext
144: );
145:
146: typedef
147: BOOLEAN
148: (*PKTRANSFER_ROUTINE) (
149: VOID
150: );
151:
152: //
153: //
154: // Asynchronous Procedure Call (APC) object
155: //
156:
157: typedef struct _KAPC {
158: CSHORT Type;
159: CSHORT Size;
160: struct _KPROCESS *Process;
161: struct _KTHREAD *Thread;
162: LIST_ENTRY ApcListEntry;
163: PKKERNEL_ROUTINE KernelRoutine;
164: PKRUNDOWN_ROUTINE RundownRoutine;
165: PKNORMAL_ROUTINE NormalRoutine;
166: PVOID NormalContext;
167: PVOID SystemArgument1;
168: PVOID SystemArgument2;
169: CCHAR ApcStateIndex;
170: KPROCESSOR_MODE ApcMode;
171: BOOLEAN Inserted;
172: } KAPC;
173:
174: typedef KAPC *PKAPC;
175:
176: //
177: // DPC routine
178: //
179:
180: struct _KDPC;
181:
182: typedef
183: VOID
184: (*PKDEFERRED_ROUTINE) (
185: IN struct _KDPC *Dpc,
186: IN PVOID DeferredContext,
187: IN PVOID SystemArgument1,
188: IN PVOID SystemArgument2
189: );
190:
191: //
192: // Deferred Procedure Call (DPC) object
193: //
194:
195: typedef struct _KDPC {
196: CSHORT Type;
197: CSHORT Size;
198: LIST_ENTRY DpcListEntry;
199: PKDEFERRED_ROUTINE DeferredRoutine;
200: PVOID DeferredContext;
201: PVOID SystemArgument1;
202: PVOID SystemArgument2;
203: BOOLEAN Inserted;
204: } KDPC;
205:
206: typedef KDPC *PKDPC;
207:
208: //
209: // Power Notify Routine
210: //
211:
212: typedef
213: VOID
214: (*PKNOTIFY_ROUTINE) (
215: IN PVOID NotifyContext
216: );
217:
218: //
219: // I/O system definitions.
220: //
221: // Define a Memory Descriptor List (MDL)
222: //
223: // An MDL describes pages in a virtual buffer in terms of physical pages. The
224: // pages associated with the buffer are described in an array that is allocated
225: // just after the MDL header structure itself. In a future compiler this will
226: // be placed at:
227: //
228: // ULONG Pages[];
229: //
230: // Until this declaration is permitted, however, one simply calculates the
231: // base of the array by adding one to the base MDL pointer:
232: //
233: // Pages = (PULONG) (Mdl + 1);
234: //
235: // Notice that while in the context of the subject thread, the base virtual
236: // address of a buffer mapped by an MDL may be referenced using the following:
237: //
238: // Mdl->StartVa | Mdl->ByteOffset
239: //
240:
241: typedef struct _MDL {
242: struct _MDL *Next;
243: CSHORT Size;
244: CSHORT MdlFlags;
245: struct _EPROCESS *Process;
246: PVOID MappedSystemVa;
247: PVOID StartVa;
248: ULONG ByteCount;
249: ULONG ByteOffset;
250: } MDL, *PMDL;
251:
252: #define MDL_MAPPED_TO_SYSTEM_VA 0x0001
253: #define MDL_PAGES_LOCKED 0x0002
254: #define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
255: #define MDL_ALLOCATED_FROM_ZONE 0x0008
256: #define MDL_PARTIAL 0x0010
257: #define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
258: #define MDL_IO_PAGE_READ 0x0040
259: #define MDL_WRITE_OPERATION 0x0080
260: #define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
261: #define MDL_LOCK_HELD 0x0200
262:
263: #define MDL_MAPPING_FLAGS (MDL_MAPPED_TO_SYSTEM_VA | \
264: MDL_PAGES_LOCKED | \
265: MDL_SOURCE_IS_NONPAGED_POOL | \
266: MDL_PARTIAL_HAS_BEEN_MAPPED | \
267: MDL_PARENT_MAPPED_SYSTEM_VA | \
268: MDL_LOCK_HELD )
269:
270:
271: //
272: // switch to DBG when appropriate
273: //
274:
275: #if DBG
276: #define PAGED_CODE() \
277: if (KeGetCurrentIrql() > APC_LEVEL) { \
278: KdPrint(( "EX: Pageable code called at IRQL %d\n", KeGetCurrentIrql() )); \
279: ASSERT(FALSE); \
280: }
281: #else
282: #define PAGED_CODE()
283: #endif
284:
285: //
286: // Define an access token from a programmer's viewpoint. The structure is
287: // completely opaque and the programer is only allowed to have pointers
288: // to tokens.
289: //
290:
291: typedef PVOID PACCESS_TOKEN; // winnt
292:
293: //
294: // Pointer to a SECURITY_DESCRIPTOR opaque data type.
295: //
296:
297: typedef PVOID PSECURITY_DESCRIPTOR; // winnt
298:
299: //
300: // Define a pointer to the Security ID data type (an opaque data type)
301: //
302:
303: typedef PVOID PSID; // winnt
304:
305: typedef ULONG ACCESS_MASK;
306: typedef ACCESS_MASK *PACCESS_MASK;
307:
308: // end_winnt
309: //
310: // The following are masks for the predefined standard access types
311: //
312:
313: #define DELETE (0x00010000L)
314: #define READ_CONTROL (0x00020000L)
315: #define WRITE_DAC (0x00040000L)
316: #define WRITE_OWNER (0x00080000L)
317: #define SYNCHRONIZE (0x00100000L)
318:
319: #define STANDARD_RIGHTS_REQUIRED (0x000F0000L)
320:
321: #define STANDARD_RIGHTS_READ (READ_CONTROL)
322: #define STANDARD_RIGHTS_WRITE (READ_CONTROL)
323: #define STANDARD_RIGHTS_EXECUTE (READ_CONTROL)
324:
325: #define STANDARD_RIGHTS_ALL (0x001F0000L)
326:
327: #define SPECIFIC_RIGHTS_ALL (0x0000FFFFL)
328:
329: //
330: // AccessSystemAcl access type
331: //
332:
333: #define ACCESS_SYSTEM_SECURITY (0x01000000L)
334:
335: //
336: // MaximumAllowed access type
337: //
338:
339: #define MAXIMUM_ALLOWED (0x02000000L)
340:
341: //
342: // These are the generic rights.
343: //
344:
345: #define GENERIC_READ (0x80000000L)
346: #define GENERIC_WRITE (0x40000000L)
347: #define GENERIC_EXECUTE (0x20000000L)
348: #define GENERIC_ALL (0x10000000L)
349:
350:
351: //
352: // Define the generic mapping array. This is used to denote the
353: // mapping of each generic access right to a specific access mask.
354: //
355:
356: typedef struct _GENERIC_MAPPING {
357: ACCESS_MASK GenericRead;
358: ACCESS_MASK GenericWrite;
359: ACCESS_MASK GenericExecute;
360: ACCESS_MASK GenericAll;
361: } GENERIC_MAPPING;
362: typedef GENERIC_MAPPING *PGENERIC_MAPPING;
363:
364:
365:
366: ////////////////////////////////////////////////////////////////////////
367: // //
368: // LUID_AND_ATTRIBUTES //
369: // //
370: ////////////////////////////////////////////////////////////////////////
371: //
372: //
373:
374:
375: #ifndef RC_INVOKED
376: #pragma pack(4)
377: #endif
378:
379: typedef struct _LUID_AND_ATTRIBUTES {
380: LUID Luid;
381: ULONG Attributes;
382: } LUID_AND_ATTRIBUTES, * PLUID_AND_ATTRIBUTES;
383: typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
384: typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;
385:
386: #ifndef RC_INVOKED
387: #pragma pack()
388: #endif
389:
390: // This is the *current* ACL revision
391:
392: #define ACL_REVISION (2)
393:
394: // This is the history of ACL revisions. Add a new one whenever
395: // ACL_REVISION is updated
396:
397: #define ACL_REVISION1 (1)
398: #define ACL_REVISION2 (2)
399:
400: typedef struct _ACL {
401: UCHAR AclRevision;
402: UCHAR Sbz1;
403: USHORT AclSize;
404: USHORT AceCount;
405: USHORT Sbz2;
406: } ACL;
407: typedef ACL *PACL;
408:
409: //
410: // Current security descriptor revision value
411: //
412:
413: #define SECURITY_DESCRIPTOR_REVISION (1)
414: #define SECURITY_DESCRIPTOR_REVISION1 (1)
415:
416: //
417: // Privilege attributes
418: //
419:
420: #define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)
421: #define SE_PRIVILEGE_ENABLED (0x00000002L)
422: #define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L)
423:
424: //
425: // Privilege Set Control flags
426: //
427:
428: #define PRIVILEGE_SET_ALL_NECESSARY (1)
429:
430: //
431: // Privilege Set - This is defined for a privilege set of one.
432: // If more than one privilege is needed, then this structure
433: // will need to be allocated with more space.
434: //
435: // Note: don't change this structure without fixing the INITIAL_PRIVILEGE_SET
436: // structure (defined in se.h)
437: //
438:
439: typedef struct _PRIVILEGE_SET {
440: ULONG PrivilegeCount;
441: ULONG Control;
442: LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
443: } PRIVILEGE_SET, * PPRIVILEGE_SET;
444:
445: //
446: // These must be converted to LUIDs before use.
447: //
448:
449: #define SE_MIN_WELL_KNOWN_PRIVILEGE (2L)
450: #define SE_CREATE_TOKEN_PRIVILEGE (2L)
451: #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L)
452: #define SE_LOCK_MEMORY_PRIVILEGE (4L)
453: #define SE_INCREASE_QUOTA_PRIVILEGE (5L)
454: #define SE_UNSOLICITED_INPUT_PRIVILEGE (6L)
455: #define SE_TCB_PRIVILEGE (7L)
456: #define SE_SECURITY_PRIVILEGE (8L)
457: #define SE_TAKE_OWNERSHIP_PRIVILEGE (9L)
458: #define SE_LOAD_DRIVER_PRIVILEGE (10L)
459: #define SE_SYSTEM_PROFILE_PRIVILEGE (11L)
460: #define SE_SYSTEMTIME_PRIVILEGE (12L)
461: #define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L)
462: #define SE_INC_BASE_PRIORITY_PRIVILEGE (14L)
463: #define SE_CREATE_PAGEFILE_PRIVILEGE (15L)
464: #define SE_CREATE_PERMANENT_PRIVILEGE (16L)
465: #define SE_BACKUP_PRIVILEGE (17L)
466: #define SE_RESTORE_PRIVILEGE (18L)
467: #define SE_SHUTDOWN_PRIVILEGE (19L)
468: #define SE_DEBUG_PRIVILEGE (20L)
469: #define SE_AUDIT_PRIVILEGE (21L)
470: #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L)
471: #define SE_CHANGE_NOTIFY_PRIVILEGE (23L)
472: #define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L)
473: #define SE_MAX_WELL_KNOWN_PRIVILEGE (SE_REMOTE_SHUTDOWN_PRIVILEGE)
474:
475: //
476: // Impersonation Level
477: //
478: // Impersonation level is represented by a pair of bits in Windows.
479: // If a new impersonation level is added or lowest value is changed from
480: // 0 to something else, fix the Windows CreateFile call.
481: //
482:
483: typedef enum _SECURITY_IMPERSONATION_LEVEL {
484: SecurityAnonymous,
485: SecurityIdentification,
486: SecurityImpersonation,
487: SecurityDelegation
488: } SECURITY_IMPERSONATION_LEVEL, * PSECURITY_IMPERSONATION_LEVEL;
489:
490: #define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation
491:
492: #define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation
493:
494: // end_nthal
495: //
496: // Security Tracking Mode
497: //
498:
499: #define SECURITY_DYNAMIC_TRACKING (TRUE)
500: #define SECURITY_STATIC_TRACKING (FALSE)
501:
502: typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,
503: * PSECURITY_CONTEXT_TRACKING_MODE;
504:
505:
506:
507: //
508: // Quality Of Service
509: //
510:
511: typedef struct _SECURITY_QUALITY_OF_SERVICE {
512: ULONG Length;
513: SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
514: SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
515: BOOLEAN EffectiveOnly;
516: } SECURITY_QUALITY_OF_SERVICE, * PSECURITY_QUALITY_OF_SERVICE;
517:
518:
519: //
520: // Used to represent information related to a thread impersonation
521: //
522:
523: typedef struct _SE_IMPERSONATION_STATE {
524: PACCESS_TOKEN Token;
525: BOOLEAN CopyOnOpen;
526: BOOLEAN EffectiveOnly;
527: SECURITY_IMPERSONATION_LEVEL Level;
528: } SE_IMPERSONATION_STATE, *PSE_IMPERSONATION_STATE;
529:
530:
531: typedef ULONG SECURITY_INFORMATION, *PSECURITY_INFORMATION;
532:
533: #define OWNER_SECURITY_INFORMATION (0X00000001L)
534: #define GROUP_SECURITY_INFORMATION (0X00000002L)
535: #define DACL_SECURITY_INFORMATION (0X00000004L)
536: #define SACL_SECURITY_INFORMATION (0X00000008L)
537:
538: #define LOW_PRIORITY 0 // Lowest thread priority level
539: #define LOW_REALTIME_PRIORITY 16 // Lowest realtime priority level
540: #define HIGH_PRIORITY 31 // Highest thread priority level
541: #define MAXIMUM_PRIORITY 32 // Number of thread priority levels
542: // begin_winnt
543: #define MAXIMUM_WAIT_OBJECTS 64 // Maximum number of wait objects
544:
545: #define MAXIMUM_SUSPEND_COUNT MAXCHAR // Maximum times thread can be suspended
546: // end_winnt
547:
548: //
549: // Thread affinity
550: //
551:
552: typedef ULONG KAFFINITY;
553: typedef KAFFINITY *PKAFFINITY;
554:
555: //
556: // Thread priority
557: //
558:
559: typedef LONG KPRIORITY;
560:
561: //
562: // Spin Lock
563: //
564:
565: typedef ULONG KSPIN_LOCK; // winnt
566:
567: typedef KSPIN_LOCK *PKSPIN_LOCK;
568:
569: //
570: // Interrupt routine (first level dispatch)
571: //
572:
573: typedef
574: VOID
575: (*PKINTERRUPT_ROUTINE) (
576: VOID
577: );
578:
579: // begin_winnt
580: //
581: // for move macros
582: //
583: #include <string.h>
584: // end_winnt
585: //
586: // If debugging support enabled, define an ASSERT macro that works. Otherwise
587: // define the ASSERT macro to expand to an empty expression.
588: //
589:
590: #if DBG
591: VOID
592: NTAPI
593: RtlAssert(
594: PVOID FailedAssertion,
595: PVOID FileName,
596: ULONG LineNumber,
597: PCHAR Message
598: );
599:
600: #define ASSERT( exp ) \
601: if (!(exp)) \
602: RtlAssert( #exp, __FILE__, __LINE__, NULL )
603:
604: #define ASSERTMSG( msg, exp ) \
605: if (!(exp)) \
606: RtlAssert( #exp, __FILE__, __LINE__, msg )
607:
608: #else
609: #define ASSERT( exp )
610: #define ASSERTMSG( msg, exp )
611: #endif // DBG
612:
613: //
614: // Doubly-linked list manipulation routines. Implemented as macros
615: // but logically these are procedures.
616: //
617:
618: //
619: // VOID
620: // InitializeListHead(
621: // PLIST_ENTRY ListHead
622: // );
623: //
624:
625: #define InitializeListHead(ListHead) (\
626: (ListHead)->Flink = (ListHead)->Blink = (ListHead))
627:
628: //
629: // BOOLEAN
630: // IsListEmpty(
631: // PLIST_ENTRY ListHead
632: // );
633: //
634:
635: #define IsListEmpty(ListHead) \
636: ((ListHead)->Flink == (ListHead))
637:
638: //
639: // PLIST_ENTRY
640: // RemoveHeadList(
641: // PLIST_ENTRY ListHead
642: // );
643: //
644:
645: #define RemoveHeadList(ListHead) \
646: (ListHead)->Flink;\
647: {RemoveEntryList((ListHead)->Flink)}
648:
649: //
650: // PLIST_ENTRY
651: // RemoveTailList(
652: // PLIST_ENTRY ListHead
653: // );
654: //
655:
656: #define RemoveTailList(ListHead) \
657: (ListHead)->Blink;\
658: {RemoveEntryList((ListHead)->Blink)}
659:
660: //
661: // VOID
662: // RemoveEntryList(
663: // PLIST_ENTRY Entry
664: // );
665: //
666:
667: #define RemoveEntryList(Entry) {\
668: PLIST_ENTRY _EX_Blink;\
669: PLIST_ENTRY _EX_Flink;\
670: _EX_Flink = (Entry)->Flink;\
671: _EX_Blink = (Entry)->Blink;\
672: _EX_Blink->Flink = _EX_Flink;\
673: _EX_Flink->Blink = _EX_Blink;\
674: }
675:
676: //
677: // VOID
678: // InsertTailList(
679: // PLIST_ENTRY ListHead,
680: // PLIST_ENTRY Entry
681: // );
682: //
683:
684: #define InsertTailList(ListHead,Entry) {\
685: PLIST_ENTRY _EX_Blink;\
686: PLIST_ENTRY _EX_ListHead;\
687: _EX_ListHead = (ListHead);\
688: _EX_Blink = _EX_ListHead->Blink;\
689: (Entry)->Flink = _EX_ListHead;\
690: (Entry)->Blink = _EX_Blink;\
691: _EX_Blink->Flink = (Entry);\
692: _EX_ListHead->Blink = (Entry);\
693: }
694:
695: //
696: // VOID
697: // InsertHeadList(
698: // PLIST_ENTRY ListHead,
699: // PLIST_ENTRY Entry
700: // );
701: //
702:
703: #define InsertHeadList(ListHead,Entry) {\
704: PLIST_ENTRY _EX_Flink;\
705: PLIST_ENTRY _EX_ListHead;\
706: _EX_ListHead = (ListHead);\
707: _EX_Flink = _EX_ListHead->Flink;\
708: (Entry)->Flink = _EX_Flink;\
709: (Entry)->Blink = _EX_ListHead;\
710: _EX_Flink->Blink = (Entry);\
711: _EX_ListHead->Flink = (Entry);\
712: }
713:
714: //
715: //
716: // PSINGLE_LIST_ENTRY
717: // PopEntryList(
718: // PSINGLE_LIST_ENTRY ListHead
719: // );
720: //
721:
722: #define PopEntryList(ListHead) \
723: (ListHead)->Next;\
724: {\
725: PSINGLE_LIST_ENTRY FirstEntry;\
726: FirstEntry = (ListHead)->Next;\
727: if (FirstEntry != NULL) { \
728: (ListHead)->Next = FirstEntry->Next;\
729: } \
730: }
731:
732:
733: //
734: // VOID
735: // PushEntryList(
736: // PSINGLE_LIST_ENTRY ListHead,
737: // PSINGLE_LIST_ENTRY Entry
738: // );
739: //
740:
741: #define PushEntryList(ListHead,Entry) \
742: (Entry)->Next = (ListHead)->Next; \
743: (ListHead)->Next = (Entry)
744:
745: //
746: // Subroutines for dealing with the Registry
747: //
748:
749: typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(
750: IN PWSTR ValueName,
751: IN ULONG ValueType,
752: IN PVOID ValueData,
753: IN ULONG ValueLength,
754: IN PVOID Context,
755: IN PVOID EntryContext
756: );
757:
758: typedef struct _RTL_QUERY_REGISTRY_TABLE {
759: PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
760: ULONG Flags;
761: PWSTR Name;
762: PVOID EntryContext;
763: ULONG DefaultType;
764: PVOID DefaultData;
765: ULONG DefaultLength;
766:
767: } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
768:
769:
770: //
771: // The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE
772: // entry is interpreted. A NULL name indicates the end of the table.
773: //
774:
775: #define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 // Name is a subkey and remainder of
776: // table or until next subkey are value
777: // names for that subkey to look at.
778:
779: #define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 // Reset current key to original key for
780: // this and all following table entries.
781:
782: #define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 // Fail if no match found for this table
783: // entry.
784:
785: #define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 // Used to mark a table entry that has no
786: // value name, just wants a call out, not
787: // an enumeration of all values.
788:
789: #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 // Used to suppress the expansion of
790: // REG_MULTI_SZ into multiple callouts or
791: // to prevent the expansion of environment
792: // variable values in REG_EXPAND_SZ
793:
794: #define RTL_QUERY_REGISTRY_DIRECT 0x00000020 // QueryRoutine field ignored. EntryContext
795: // field points to location to store value.
796: // For null terminated strings, EntryContext
797: // points to UNICODE_STRING structure that
798: // that describes maximum size of buffer.
799: // If .Buffer field is NULL then a buffer is
800: // allocated.
801: //
802:
803: #define RTL_QUERY_REGISTRY_DELETE 0x00000040 // Used to delete value keys after they
804: // are queried.
805:
806: NTSTATUS
807: NTAPI
808: RtlQueryRegistryValues(
809: IN ULONG RelativeTo,
810: IN PWSTR Path,
811: IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
812: IN PVOID Context,
813: IN PVOID Environment OPTIONAL
814: );
815:
816: NTSTATUS
817: NTAPI
818: RtlWriteRegistryValue(
819: IN ULONG RelativeTo,
820: IN PWSTR Path,
821: IN PWSTR ValueName,
822: IN ULONG ValueType,
823: IN PVOID ValueData,
824: IN ULONG ValueLength
825: );
826:
827: NTSTATUS
828: NTAPI
829: RtlDeleteRegistryValue(
830: IN ULONG RelativeTo,
831: IN PWSTR Path,
832: IN PWSTR ValueName
833: );
834:
835: NTSTATUS
836: NTAPI
837: RtlCreateRegistryKey(
838: IN ULONG RelativeTo,
839: IN PWSTR Path
840: );
841:
842: NTSTATUS
843: NTAPI
844: RtlCheckRegistryKey(
845: IN ULONG RelativeTo,
846: IN PWSTR Path
847: );
848:
849: //
850: // The following values for the RelativeTo parameter determine what the
851: // Path parameter to RtlQueryRegistryValues is relative to.
852: //
853:
854: #define RTL_REGISTRY_ABSOLUTE 0 // Path is a full path
855: #define RTL_REGISTRY_SERVICES 1 // \Registry\Machine\System\CurrentControlSet\Services
856: #define RTL_REGISTRY_CONTROL 2 // \Registry\Machine\System\CurrentControlSet\Control
857: #define RTL_REGISTRY_WINDOWS_NT 3 // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
858: #define RTL_REGISTRY_DEVICEMAP 4 // \Registry\Machine\Hardware\DeviceMap
859: #define RTL_REGISTRY_USER 5 // \Registry\User\CurrentUser
860: #define RTL_REGISTRY_MAXIMUM 6
861: #define RTL_REGISTRY_HANDLE 0x40000000 // Low order bits are registry handle
862: #define RTL_REGISTRY_OPTIONAL 0x80000000 // Indicates the key node is optional
863:
864: NTSTATUS
865: RtlIntegerToUnicodeString (
866: ULONG Value,
867: ULONG Base,
868: PUNICODE_STRING String
869: );
870: //
871: // String manipulation routines
872: //
873:
874: VOID
875: NTAPI
876: RtlInitString(
877: PSTRING DestinationString,
878: PCSZ SourceString
879: );
880:
881: VOID
882: NTAPI
883: RtlInitAnsiString(
884: PANSI_STRING DestinationString,
885: PCSZ SourceString
886: );
887:
888: VOID
889: NTAPI
890: RtlInitUnicodeString(
891: PUNICODE_STRING DestinationString,
892: PCWSTR SourceString
893: );
894:
895:
896: VOID
897: NTAPI
898: RtlCopyString(
899: PSTRING DestinationString,
900: PSTRING SourceString
901: );
902:
903:
904: BOOLEAN
905: NTAPI
906: RtlEqualString(
907: PSTRING String1,
908: PSTRING String2,
909: BOOLEAN CaseInSensitive
910: );
911:
912:
913: VOID
914: NTAPI
915: RtlUpperString(
916: PSTRING DestinationString,
917: PSTRING SourceString
918: );
919:
920: //
921: // NLS String functions
922: //
923:
924: NTSTATUS
925: NTAPI
926: RtlAnsiStringToUnicodeString(
927: PUNICODE_STRING DestinationString,
928: PANSI_STRING SourceString,
929: BOOLEAN AllocateDestinationString
930: );
931:
932:
933: NTSTATUS
934: NTAPI
935: RtlUnicodeStringToAnsiString(
936: PANSI_STRING DestinationString,
937: PUNICODE_STRING SourceString,
938: BOOLEAN AllocateDestinationString
939: );
940:
941:
942: LONG
943: NTAPI
944: RtlCompareUnicodeString(
945: PUNICODE_STRING String1,
946: PUNICODE_STRING String2,
947: BOOLEAN CaseInSensitive
948: );
949:
950:
951: BOOLEAN
952: NTAPI
953: RtlEqualUnicodeString(
954: PUNICODE_STRING String1,
955: PUNICODE_STRING String2,
956: BOOLEAN CaseInSensitive
957: );
958:
959:
960: NTSTATUS
961: NTAPI
962: RtlUpcaseUnicodeString(
963: PUNICODE_STRING DestinationString,
964: PUNICODE_STRING SourceString,
965: BOOLEAN AllocateDestinationString
966: );
967:
968:
969: VOID
970: NTAPI
971: RtlCopyUnicodeString(
972: PUNICODE_STRING DestinationString,
973: PUNICODE_STRING SourceString
974: );
975:
976: NTSTATUS
977: NTAPI
978: RtlAppendUnicodeStringToString (
979: PUNICODE_STRING Destination,
980: PUNICODE_STRING Source
981: );
982:
983: NTSTATUS
984: NTAPI
985: RtlAppendUnicodeToString (
986: PUNICODE_STRING Destination,
987: PWSTR Source
988: );
989:
990:
991: VOID
992: NTAPI
993: RtlFreeUnicodeString(
994: PUNICODE_STRING UnicodeString
995: );
996:
997: VOID
998: NTAPI
999: RtlFreeAnsiString(
1000: PANSI_STRING AnsiString
1001: );
1002:
1003:
1004: ULONG
1005: NTAPI
1006: RtlAnsiStringToUnicodeSize(
1007: PANSI_STRING AnsiString
1008: );
1009:
1010: //
1011: // Fast primitives to compare, move, and zero memory
1012: //
1013:
1014: // begin_winnt
1015: #ifdef _M_IX86
1016: #define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
1017: #define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
1018: #define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
1019: #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
1020: #else
1021: #define RtlCopyMemory(Destination,Source,Length) RtlMoveMemory((Destination),(Source),(Length))
1022: VOID
1023: NTAPI
1024: RtlMoveMemory (
1025: PVOID Destination,
1026: CONST VOID *Source,
1027: ULONG Length
1028: );
1029:
1030: VOID
1031: NTAPI
1032: RtlFillMemory (
1033: PVOID Destination,
1034: ULONG Length,
1035: UCHAR Fill
1036: );
1037:
1038: VOID
1039: NTAPI
1040: RtlZeroMemory (
1041: PVOID Destination,
1042: ULONG Length
1043: );
1044: #endif
1045: // end_winnt
1046:
1047: ULONG
1048: NTAPI
1049: RtlCompareMemory (
1050: PVOID Source1,
1051: PVOID Source2,
1052: ULONG Length
1053: );
1054:
1055:
1056: VOID
1057: DbgBreakPoint(
1058: VOID
1059: );
1060: //
1061: // Define kernel debugger print prototypes and macros.
1062: //
1063:
1064: #if DBG
1065:
1066: #define KdPrint(_x_) DbgPrint _x_
1067:
1068: #else
1069:
1070: #define KdPrint(_x_)
1071:
1072: #endif
1073:
1074: #ifndef _DBGNT_
1075: ULONG
1076: DbgPrint(
1077: PCH Format,
1078: ...
1079: );
1080: #endif // _DBGNT_
1081: //
1082: // Large integer arithmetic routines.
1083: //
1084:
1085: //
1086: // Large integer add - 64-bits + 64-bits -> 64-bits
1087: //
1088:
1089: LARGE_INTEGER
1090: NTAPI
1091: RtlLargeIntegerAdd (
1092: LARGE_INTEGER Addend1,
1093: LARGE_INTEGER Addend2
1094: );
1095:
1096: //
1097: // Enlarged integer multiply - 32-bits * 32-bits -> 64-bits
1098: //
1099:
1100: LARGE_INTEGER
1101: NTAPI
1102: RtlEnlargedIntegerMultiply (
1103: LONG Multiplicand,
1104: LONG Multiplier
1105: );
1106:
1107: //
1108: // Unsigned enlarged integer multiply - 32-bits * 32-bits -> 64-bits
1109: //
1110:
1111: LARGE_INTEGER
1112: NTAPI
1113: RtlEnlargedUnsignedMultiply (
1114: ULONG Multiplicand,
1115: ULONG Multiplier
1116: );
1117:
1118: //
1119: // Enlarged integer divide - 64-bits / 32-bits > 32-bits
1120: //
1121:
1122: ULONG
1123: NTAPI
1124: RtlEnlargedUnsignedDivide (
1125: IN ULARGE_INTEGER Dividend,
1126: IN ULONG Divisor,
1127: IN PULONG Remainder
1128: );
1129:
1130: //
1131: // Extended large integer magic divide - 64-bits / 32-bits -> 64-bits
1132: //
1133:
1134: LARGE_INTEGER
1135: NTAPI
1136: RtlExtendedMagicDivide (
1137: LARGE_INTEGER Dividend,
1138: LARGE_INTEGER MagicDivisor,
1139: CCHAR ShiftCount
1140: );
1141:
1142: //
1143: // Large Integer divide - 64-bits / 32-bits -> 64-bits
1144: //
1145:
1146: LARGE_INTEGER
1147: NTAPI
1148: RtlExtendedLargeIntegerDivide (
1149: LARGE_INTEGER Dividend,
1150: ULONG Divisor,
1151: PULONG Remainder
1152: );
1153:
1154: //
1155: // Large Integer divide - 64-bits / 32-bits -> 64-bits
1156: //
1157:
1158: LARGE_INTEGER
1159: NTAPI
1160: RtlLargeIntegerDivide (
1161: LARGE_INTEGER Dividend,
1162: LARGE_INTEGER Divisor,
1163: PLARGE_INTEGER Remainder
1164: );
1165:
1166: //
1167: // Extended integer multiply - 32-bits * 64-bits -> 64-bits
1168: //
1169:
1170: LARGE_INTEGER
1171: NTAPI
1172: RtlExtendedIntegerMultiply (
1173: LARGE_INTEGER Multiplicand,
1174: LONG Multiplier
1175: );
1176:
1177: //
1178: // Large integer negation - -(64-bits)
1179: //
1180:
1181: LARGE_INTEGER
1182: NTAPI
1183: RtlLargeIntegerNegate (
1184: LARGE_INTEGER Subtrahend
1185: );
1186:
1187: //
1188: // Large integer subtract - 64-bits - 64-bits -> 64-bits.
1189: //
1190:
1191: LARGE_INTEGER
1192: NTAPI
1193: RtlLargeIntegerSubtract (
1194: LARGE_INTEGER Minuend,
1195: LARGE_INTEGER Subtrahend
1196: );
1197:
1198: //
1199: // Large integer and - 64-bite & 64-bits -> 64-bits.
1200: //
1201:
1202: #define RtlLargeIntegerAnd(Result, Source, Mask) \
1203: { \
1204: Result.HighPart = Source.HighPart & Mask.HighPart; \
1205: Result.LowPart = Source.LowPart & Mask.LowPart; \
1206: }
1207:
1208:
1209: //
1210: // Large integer conversion routines.
1211: //
1212:
1213: //
1214: // Convert signed integer to large integer.
1215: //
1216:
1217: LARGE_INTEGER
1218: NTAPI
1219: RtlConvertLongToLargeInteger (
1220: LONG SignedInteger
1221: );
1222:
1223: //
1224: // Convert unsigned integer to large integer.
1225: //
1226:
1227: LARGE_INTEGER
1228: NTAPI
1229: RtlConvertUlongToLargeInteger (
1230: ULONG UnsignedInteger
1231: );
1232:
1233:
1234: //
1235: // Large integer shift routines.
1236: //
1237:
1238: LARGE_INTEGER
1239: NTAPI
1240: RtlLargeIntegerShiftLeft (
1241: LARGE_INTEGER LargeInteger,
1242: CCHAR ShiftCount
1243: );
1244:
1245: LARGE_INTEGER
1246: NTAPI
1247: RtlLargeIntegerShiftRight (
1248: LARGE_INTEGER LargeInteger,
1249: CCHAR ShiftCount
1250: );
1251:
1252: LARGE_INTEGER
1253: NTAPI
1254: RtlLargeIntegerArithmeticShift (
1255: LARGE_INTEGER LargeInteger,
1256: CCHAR ShiftCount
1257: );
1258:
1259: //
1260: // Large integer comparison routines.
1261: //
1262: // BOOLEAN
1263: // RtlLargeIntegerGreaterThan (
1264: // LARGE_INTEGER Operand1,
1265: // LARGE_INTEGER Operand2
1266: // );
1267: //
1268: // BOOLEAN
1269: // RtlLargeIntegerGreaterThanOrEqualTo (
1270: // LARGE_INTEGER Operand1,
1271: // LARGE_INTEGER Operand2
1272: // );
1273: //
1274: // BOOLEAN
1275: // RtlLargeIntegerEqualTo (
1276: // LARGE_INTEGER Operand1,
1277: // LARGE_INTEGER Operand2
1278: // );
1279: //
1280: // BOOLEAN
1281: // RtlLargeIntegerNotEqualTo (
1282: // LARGE_INTEGER Operand1,
1283: // LARGE_INTEGER Operand2
1284: // );
1285: //
1286: // BOOLEAN
1287: // RtlLargeIntegerLessThan (
1288: // LARGE_INTEGER Operand1,
1289: // LARGE_INTEGER Operand2
1290: // );
1291: //
1292: // BOOLEAN
1293: // RtlLargeIntegerLessThanOrEqualTo (
1294: // LARGE_INTEGER Operand1,
1295: // LARGE_INTEGER Operand2
1296: // );
1297: //
1298: // BOOLEAN
1299: // RtlLargeIntegerGreaterThanZero (
1300: // LARGE_INTEGER Operand
1301: // );
1302: //
1303: // BOOLEAN
1304: // RtlLargeIntegerGreaterOrEqualToZero (
1305: // LARGE_INTEGER Operand
1306: // );
1307: //
1308: // BOOLEAN
1309: // RtlLargeIntegerEqualToZero (
1310: // LARGE_INTEGER Operand
1311: // );
1312: //
1313: // BOOLEAN
1314: // RtlLargeIntegerNotEqualToZero (
1315: // LARGE_INTEGER Operand
1316: // );
1317: //
1318: // BOOLEAN
1319: // RtlLargeIntegerLessThanZero (
1320: // LARGE_INTEGER Operand
1321: // );
1322: //
1323: // BOOLEAN
1324: // RtlLargeIntegerLessOrEqualToZero (
1325: // LARGE_INTEGER Operand
1326: // );
1327: //
1328:
1329: #define RtlLargeIntegerGreaterThan(X,Y) ( \
1330: (((X).HighPart == (Y).HighPart) && ((X).LowPart > (Y).LowPart)) || \
1331: ((X).HighPart > (Y).HighPart) \
1332: )
1333:
1334: #define RtlLargeIntegerGreaterThanOrEqualTo(X,Y) ( \
1335: (((X).HighPart == (Y).HighPart) && ((X).LowPart >= (Y).LowPart)) || \
1336: ((X).HighPart > (Y).HighPart) \
1337: )
1338:
1339: #define RtlLargeIntegerEqualTo(X,Y) ( \
1340: !(((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)) \
1341: )
1342:
1343: #define RtlLargeIntegerNotEqualTo(X,Y) ( \
1344: (((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)) \
1345: )
1346:
1347: #define RtlLargeIntegerLessThan(X,Y) ( \
1348: (((X).HighPart == (Y).HighPart) && ((X).LowPart < (Y).LowPart)) || \
1349: ((X).HighPart < (Y).HighPart) \
1350: )
1351:
1352: #define RtlLargeIntegerLessThanOrEqualTo(X,Y) ( \
1353: (((X).HighPart == (Y).HighPart) && ((X).LowPart <= (Y).LowPart)) || \
1354: ((X).HighPart < (Y).HighPart) \
1355: )
1356:
1357: #define RtlLargeIntegerGreaterThanZero(X) ( \
1358: (((X).HighPart == 0) && ((X).LowPart > 0)) || \
1359: ((X).HighPart > 0 ) \
1360: )
1361:
1362: #define RtlLargeIntegerGreaterOrEqualToZero(X) ( \
1363: (X).HighPart >= 0 \
1364: )
1365:
1366: #define RtlLargeIntegerEqualToZero(X) ( \
1367: !((X).LowPart | (X).HighPart) \
1368: )
1369:
1370: #define RtlLargeIntegerNotEqualToZero(X) ( \
1371: ((X).LowPart | (X).HighPart) \
1372: )
1373:
1374: #define RtlLargeIntegerLessThanZero(X) ( \
1375: ((X).HighPart < 0) \
1376: )
1377:
1378: #define RtlLargeIntegerLessOrEqualToZero(X) ( \
1379: ((X).HighPart < 0) || !((X).LowPart | (X).HighPart) \
1380: )
1381:
1382:
1383: //
1384: // Time conversion routines
1385: //
1386:
1387: typedef struct _TIME_FIELDS {
1388: CSHORT Year; // range [1601...]
1389: CSHORT Month; // range [1..12]
1390: CSHORT Day; // range [1..31]
1391: CSHORT Hour; // range [0..23]
1392: CSHORT Minute; // range [0..59]
1393: CSHORT Second; // range [0..59]
1394: CSHORT Milliseconds;// range [0..999]
1395: CSHORT Weekday; // range [0..6] == [Sunday..Saturday]
1396: } TIME_FIELDS;
1397: typedef TIME_FIELDS *PTIME_FIELDS;
1398:
1399:
1400: VOID
1401: NTAPI
1402: RtlTimeToTimeFields (
1403: PLARGE_INTEGER Time,
1404: PTIME_FIELDS TimeFields
1405: );
1406:
1407: //
1408: // The following macros store and retrieve USHORTS and ULONGS from potentially
1409: // unaligned addresses, avoiding alignment faults. they should probably be
1410: // rewritten in assembler
1411: //
1412:
1413: #define SHORT_SIZE (sizeof(USHORT))
1414: #define SHORT_MASK (SHORT_SIZE - 1)
1415: #define LONG_SIZE (sizeof(LONG))
1416: #define LONG_MASK (LONG_SIZE - 1)
1417: #define LOWBYTE_MASK 0x00FF
1418:
1419: #define FIRSTBYTE(VALUE) (VALUE & LOWBYTE_MASK)
1420: #define SECONDBYTE(VALUE) ((VALUE >> 8) & LOWBYTE_MASK)
1421: #define THIRDBYTE(VALUE) ((VALUE >> 16) & LOWBYTE_MASK)
1422: #define FOURTHBYTE(VALUE) ((VALUE >> 24) & LOWBYTE_MASK)
1423:
1424: //
1425: // if MIPS Big Endian, order of bytes is reversed.
1426: //
1427:
1428: #define SHORT_LEAST_SIGNIFICANT_BIT 0
1429: #define SHORT_MOST_SIGNIFICANT_BIT 1
1430:
1431: #define LONG_LEAST_SIGNIFICANT_BIT 0
1432: #define LONG_3RD_MOST_SIGNIFICANT_BIT 1
1433: #define LONG_2ND_MOST_SIGNIFICANT_BIT 2
1434: #define LONG_MOST_SIGNIFICANT_BIT 3
1435:
1436: //++
1437: //
1438: // VOID
1439: // RtlStoreUshort (
1440: // PUSHORT ADDRESS
1441: // USHORT VALUE
1442: // )
1443: //
1444: // Routine Description:
1445: //
1446: // This macro stores a USHORT value in at a particular address, avoiding
1447: // alignment faults.
1448: //
1449: // Arguments:
1450: //
1451: // ADDRESS - where to store USHORT value
1452: // VALUE - USHORT to store
1453: //
1454: // Return Value:
1455: //
1456: // none.
1457: //
1458: //--
1459:
1460: #define RtlStoreUshort(ADDRESS,VALUE) \
1461: if ((ULONG)ADDRESS & SHORT_MASK) { \
1462: ((PUCHAR) ADDRESS)[SHORT_LEAST_SIGNIFICANT_BIT] = (UCHAR)(FIRSTBYTE(VALUE)); \
1463: ((PUCHAR) ADDRESS)[SHORT_MOST_SIGNIFICANT_BIT ] = (UCHAR)(SECONDBYTE(VALUE)); \
1464: } \
1465: else { \
1466: *((PUSHORT) ADDRESS) = (USHORT) VALUE; \
1467: }
1468:
1469:
1470: //++
1471: //
1472: // VOID
1473: // RtlStoreUlong (
1474: // PULONG ADDRESS
1475: // ULONG VALUE
1476: // )
1477: //
1478: // Routine Description:
1479: //
1480: // This macro stores a ULONG value in at a particular address, avoiding
1481: // alignment faults.
1482: //
1483: // Arguments:
1484: //
1485: // ADDRESS - where to store ULONG value
1486: // VALUE - ULONG to store
1487: //
1488: // Return Value:
1489: //
1490: // none.
1491: //
1492: // Note:
1493: // Depending on the machine, we might want to call storeushort in the
1494: // unaligned case.
1495: //
1496: //--
1497:
1498: #define RtlStoreUlong(ADDRESS,VALUE) \
1499: if ((ULONG)ADDRESS & LONG_MASK) { \
1500: ((PUCHAR) ADDRESS)[LONG_LEAST_SIGNIFICANT_BIT ] = (UCHAR)(FIRSTBYTE(VALUE)); \
1501: ((PUCHAR) ADDRESS)[LONG_3RD_MOST_SIGNIFICANT_BIT ] = (UCHAR)(SECONDBYTE(VALUE)); \
1502: ((PUCHAR) ADDRESS)[LONG_2ND_MOST_SIGNIFICANT_BIT ] = (UCHAR)(THIRDBYTE(VALUE)); \
1503: ((PUCHAR) ADDRESS)[LONG_MOST_SIGNIFICANT_BIT ] = (UCHAR)(FOURTHBYTE(VALUE)); \
1504: } \
1505: else { \
1506: *((PULONG) ADDRESS) = (ULONG) VALUE; \
1507: }
1508:
1509: //++
1510: //
1511: // VOID
1512: // RtlRetrieveUshort (
1513: // PUSHORT DESTINATION_ADDRESS
1514: // PUSHORT SOURCE_ADDRESS
1515: // )
1516: //
1517: // Routine Description:
1518: //
1519: // This macro retrieves a USHORT value from the SOURCE address, avoiding
1520: // alignment faults. The DESTINATION address is assumed to be aligned.
1521: //
1522: // Arguments:
1523: //
1524: // DESTINATION_ADDRESS - where to store USHORT value
1525: // SOURCE_ADDRESS - where to retrieve USHORT value from
1526: //
1527: // Return Value:
1528: //
1529: // none.
1530: //
1531: //--
1532:
1533: #define RtlRetrieveUshort(DEST_ADDRESS,SRC_ADDRESS) \
1534: if ((ULONG)SRC_ADDRESS & SHORT_MASK) { \
1535: ((PUCHAR) DEST_ADDRESS)[0] = ((PUCHAR) SRC_ADDRESS)[0]; \
1536: ((PUCHAR) DEST_ADDRESS)[1] = ((PUCHAR) SRC_ADDRESS)[1]; \
1537: } \
1538: else { \
1539: *((PUSHORT) DEST_ADDRESS) = *((PUSHORT) SRC_ADDRESS); \
1540: } \
1541:
1542: //++
1543: //
1544: // VOID
1545: // RtlRetrieveUlong (
1546: // PULONG DESTINATION_ADDRESS
1547: // PULONG SOURCE_ADDRESS
1548: // )
1549: //
1550: // Routine Description:
1551: //
1552: // This macro retrieves a ULONG value from the SOURCE address, avoiding
1553: // alignment faults. The DESTINATION address is assumed to be aligned.
1554: //
1555: // Arguments:
1556: //
1557: // DESTINATION_ADDRESS - where to store ULONG value
1558: // SOURCE_ADDRESS - where to retrieve ULONG value from
1559: //
1560: // Return Value:
1561: //
1562: // none.
1563: //
1564: // Note:
1565: // Depending on the machine, we might want to call retrieveushort in the
1566: // unaligned case.
1567: //
1568: //--
1569:
1570: #define RtlRetrieveUlong(DEST_ADDRESS,SRC_ADDRESS) \
1571: if ((ULONG)SRC_ADDRESS & LONG_MASK) { \
1572: ((PUCHAR) DEST_ADDRESS)[0] = ((PUCHAR) SRC_ADDRESS)[0]; \
1573: ((PUCHAR) DEST_ADDRESS)[1] = ((PUCHAR) SRC_ADDRESS)[1]; \
1574: ((PUCHAR) DEST_ADDRESS)[2] = ((PUCHAR) SRC_ADDRESS)[2]; \
1575: ((PUCHAR) DEST_ADDRESS)[3] = ((PUCHAR) SRC_ADDRESS)[3]; \
1576: } \
1577: else { \
1578: *((PULONG) DEST_ADDRESS) = *((PULONG) SRC_ADDRESS); \
1579: }
1580: //
1581: // SecurityDescriptor RTL routine definitions
1582: //
1583:
1584: NTSTATUS
1585: NTAPI
1586: RtlCreateSecurityDescriptor (
1587: PSECURITY_DESCRIPTOR SecurityDescriptor,
1588: ULONG Revision
1589: );
1590:
1591: NTSTATUS
1592: NTAPI
1593: RtlSetDaclSecurityDescriptor (
1594: PSECURITY_DESCRIPTOR SecurityDescriptor,
1595: BOOLEAN DaclPresent,
1596: PACL Dacl,
1597: BOOLEAN DaclDefaulted
1598: );
1599:
1600: //
1601: // Define the various device type values. Note that values used by Microsoft
1602: // Corporation are in the range 0-32767, and 32768-65535 are reserved for use
1603: // by customers.
1604: //
1605:
1606: #define DEVICE_TYPE ULONG
1607:
1608: #define FILE_DEVICE_BEEP 0x00000001
1609: #define FILE_DEVICE_CD_ROM 0x00000002
1610: #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
1611: #define FILE_DEVICE_CONTROLLER 0x00000004
1612: #define FILE_DEVICE_DATALINK 0x00000005
1613: #define FILE_DEVICE_DFS 0x00000006
1614: #define FILE_DEVICE_DISK 0x00000007
1615: #define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
1616: #define FILE_DEVICE_FILE_SYSTEM 0x00000009
1617: #define FILE_DEVICE_INPORT_PORT 0x0000000a
1618: #define FILE_DEVICE_KEYBOARD 0x0000000b
1619: #define FILE_DEVICE_MAILSLOT 0x0000000c
1620: #define FILE_DEVICE_MIDI_IN 0x0000000d
1621: #define FILE_DEVICE_MIDI_OUT 0x0000000e
1622: #define FILE_DEVICE_MOUSE 0x0000000f
1623: #define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
1624: #define FILE_DEVICE_NAMED_PIPE 0x00000011
1625: #define FILE_DEVICE_NETWORK 0x00000012
1626: #define FILE_DEVICE_NETWORK_BROWSER 0x00000013
1627: #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
1628: #define FILE_DEVICE_NULL 0x00000015
1629: #define FILE_DEVICE_PARALLEL_PORT 0x00000016
1630: #define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
1631: #define FILE_DEVICE_PRINTER 0x00000018
1632: #define FILE_DEVICE_SCANNER 0x00000019
1633: #define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a
1634: #define FILE_DEVICE_SERIAL_PORT 0x0000001b
1635: #define FILE_DEVICE_SCREEN 0x0000001c
1636: #define FILE_DEVICE_SOUND 0x0000001d
1637: #define FILE_DEVICE_STREAMS 0x0000001e
1638: #define FILE_DEVICE_TAPE 0x0000001f
1639: #define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
1640: #define FILE_DEVICE_TRANSPORT 0x00000021
1641: #define FILE_DEVICE_UNKNOWN 0x00000022
1642: #define FILE_DEVICE_VIDEO 0x00000023
1643: #define FILE_DEVICE_VIRTUAL_DISK 0x00000024
1644: #define FILE_DEVICE_WAVE_IN 0x00000025
1645: #define FILE_DEVICE_WAVE_OUT 0x00000026
1646: #define FILE_DEVICE_8042_PORT 0x00000027
1647: #define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
1648:
1649: //
1650: // Macro definition for defining IOCTL and FSCTL function control codes. Note
1651: // that function codes 0-2047 are reserved for Microsoft Corporation, and
1652: // 2048-4095 are reserved for customers.
1653: //
1654:
1655: #define CTL_CODE( DeviceType, Function, Method, Access ) ( \
1656: ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
1657: )
1658:
1659: //
1660: // Define the method codes for how buffers are passed for I/O and FS controls
1661: //
1662:
1663: #define METHOD_BUFFERED 0
1664: #define METHOD_IN_DIRECT 1
1665: #define METHOD_OUT_DIRECT 2
1666: #define METHOD_NEITHER 3
1667:
1668: //
1669: // Define the access check value for any access
1670: //
1671: //
1672: // The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
1673: // ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
1674: // constants *MUST* always be in sync.
1675: //
1676:
1677:
1678: #define FILE_ANY_ACCESS 0
1679: #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
1680: #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
1681:
1682:
1683: // begin_winnt
1684:
1685: //
1686: // Define access rights to files and directories
1687: //
1688:
1689: //
1690: // The FILE_READ_DATA and FILE_WRITE_DATA constants are also defined in
1691: // devioctl.h as FILE_READ_ACCESS and FILE_WRITE_ACCESS. The values for these
1692: // constants *MUST* always be in sync.
1693: // The values are redefined in devioctl.h because they must be available to
1694: // both DOS and NT.
1695: //
1696:
1697: #define FILE_READ_DATA ( 0x0001 ) // file & pipe
1698: #define FILE_LIST_DIRECTORY ( 0x0001 ) // directory
1699:
1700: #define FILE_WRITE_DATA ( 0x0002 ) // file & pipe
1701: #define FILE_ADD_FILE ( 0x0002 ) // directory
1702:
1703: #define FILE_APPEND_DATA ( 0x0004 ) // file
1704: #define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory
1705: #define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe
1706:
1707: #define FILE_READ_EA ( 0x0008 ) // file & directory
1708:
1709: #define FILE_WRITE_EA ( 0x0010 ) // file & directory
1710:
1711: #define FILE_EXECUTE ( 0x0020 ) // file
1712: #define FILE_TRAVERSE ( 0x0020 ) // directory
1713:
1714: #define FILE_DELETE_CHILD ( 0x0040 ) // directory
1715:
1716: #define FILE_READ_ATTRIBUTES ( 0x0080 ) // all
1717:
1718: #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all
1719:
1720: #define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
1721:
1722:
1723: #define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |\
1724: FILE_READ_DATA |\
1725: FILE_READ_ATTRIBUTES |\
1726: FILE_READ_EA |\
1727: SYNCHRONIZE)
1728:
1729:
1730: #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
1731: FILE_WRITE_DATA |\
1732: FILE_WRITE_ATTRIBUTES |\
1733: FILE_WRITE_EA |\
1734: FILE_APPEND_DATA |\
1735: SYNCHRONIZE)
1736:
1737:
1738: #define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
1739: FILE_READ_ATTRIBUTES |\
1740: FILE_EXECUTE |\
1741: SYNCHRONIZE)
1742:
1743: // end_winnt
1744:
1745:
1746: //
1747: // Define share access rights to files and directories
1748: //
1749:
1750: #define FILE_SHARE_READ 0x00000001 // winnt
1751: #define FILE_SHARE_WRITE 0x00000002 // winnt
1752: #define FILE_SHARE_DELETE 0x00000004
1753: #define FILE_SHARE_VALID_FLAGS 0x00000007
1754:
1755: //
1756: // Define the file attributes values
1757: //
1758: // Note: 0x00000008 is reserved for use for the old DOS VOLID (volume ID)
1759: // and is therefore not considered valid in NT.
1760: //
1761: // Note: 0x00000010 is reserved for use for the old DOS SUBDIRECTORY flag
1762: // and is therefore not considered valid in NT. This flag has
1763: // been disassociated with file attributes since the other flags are
1764: // protected with READ_ and WRITE_ATTRIBUTES access to the file.
1765: //
1766: // Note: Note also that the order of these flags is set to allow both the
1767: // FAT and the Pinball File Systems to directly set the attributes
1768: // flags in attributes words without having to pick each flag out
1769: // individually. The order of these flags should not be changed!
1770: //
1771:
1772: #define FILE_ATTRIBUTE_READONLY 0x00000001 // winnt
1773: #define FILE_ATTRIBUTE_HIDDEN 0x00000002 // winnt
1774: #define FILE_ATTRIBUTE_SYSTEM 0x00000004 // winnt
1775: #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 // winnt
1776: #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 // winnt
1777: #define FILE_ATTRIBUTE_NORMAL 0x00000080 // winnt
1778: #define FILE_ATTRIBUTE_TEMPORARY 0x00000100 // winnt
1779: #define FILE_ATTRIBUTE_ATOMIC_WRITE 0x00000200 // winnt
1780: #define FILE_ATTRIBUTE_XACTION_WRITE 0x00000400 // winnt
1781: #define FILE_ATTRIBUTE_VALID_FLAGS 0x000007b7
1782:
1783: //
1784: // Define the create disposition values
1785: //
1786:
1787: #define FILE_SUPERSEDE 0x00000000
1788: #define FILE_OPEN 0x00000001
1789: #define FILE_CREATE 0x00000002
1790: #define FILE_OPEN_IF 0x00000003
1791: #define FILE_OVERWRITE 0x00000004
1792: #define FILE_OVERWRITE_IF 0x00000005
1793: #define FILE_MAXIMUM_DISPOSITION 0x00000005
1794:
1795: //
1796: // Define the create/open option flags
1797: //
1798:
1799: #define FILE_DIRECTORY_FILE 0x00000001
1800: #define FILE_WRITE_THROUGH 0x00000002
1801: #define FILE_SEQUENTIAL_ONLY 0x00000004
1802: #define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
1803: #define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
1804: #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
1805: #define FILE_NON_DIRECTORY_FILE 0x00000040
1806: #define FILE_CREATE_TREE_CONNECTION 0x00000080
1807: #define FILE_COMPLETE_IF_OPLOCKED 0x00000100
1808: #define FILE_NO_EA_KNOWLEDGE 0x00000200
1809: #define FILE_EIGHT_DOT_THREE_ONLY 0x00000400
1810: #define FILE_RANDOM_ACCESS 0x00000800
1811: #define FILE_DELETE_ON_CLOSE 0x00001000
1812: #define FILE_OPEN_BY_FILE_ID 0x00002000
1813: #define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
1814: #define FILE_VALID_OPTION_FLAGS 0x00007FFF
1815: #define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
1816: #define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
1817: #define FILE_VALID_SET_FLAGS 0x00001036
1818:
1819: //
1820: // Define the I/O status information return values for NtCreateFile/NtOpenFile
1821: //
1822:
1823: #define FILE_SUPERSEDED 0x00000000
1824: #define FILE_OPENED 0x00000001
1825: #define FILE_CREATED 0x00000002
1826: #define FILE_OVERWRITTEN 0x00000003
1827: #define FILE_EXISTS 0x00000004
1828: #define FILE_DOES_NOT_EXIST 0x00000005
1829:
1830: //
1831: // Define special ByteOffset parameters for read and write operations
1832: //
1833:
1834: #define FILE_WRITE_TO_END_OF_FILE 0xffffffff
1835: #define FILE_USE_FILE_POINTER_POSITION 0xfffffffe
1836:
1837: //
1838: // Define alignment requirement values
1839: //
1840:
1841: #define FILE_BYTE_ALIGNMENT 0x00000000
1842: #define FILE_WORD_ALIGNMENT 0x00000001
1843: #define FILE_LONG_ALIGNMENT 0x00000003
1844: #define FILE_QUAD_ALIGNMENT 0x00000007
1845: #define FILE_OCTA_ALIGNMENT 0x0000000f
1846: #define FILE_32_BYTE_ALIGNMENT 0x0000001f
1847: #define FILE_64_BYTE_ALIGNMENT 0x0000003f
1848: #define FILE_128_BYTE_ALIGNMENT 0x0000007f
1849: #define FILE_256_BYTE_ALIGNMENT 0x000000ff
1850: #define FILE_512_BYTE_ALIGNMENT 0x000001ff
1851:
1852: //
1853: // Define the maximum length of a filename string
1854: //
1855:
1856: #define MAXIMUM_FILENAME_LENGTH 256
1857:
1858: //
1859: // Define the various device characteristics flags
1860: //
1861:
1862: #define FILE_REMOVABLE_MEDIA 0x00000001
1863: #define FILE_READ_ONLY_DEVICE 0x00000002
1864: #define FILE_FLOPPY_DISKETTE 0x00000004
1865: #define FILE_WRITE_ONCE_MEDIA 0x00000008
1866: #define FILE_REMOTE_DEVICE 0x00000010
1867: #define FILE_DEVICE_IS_MOUNTED 0x00000020
1868:
1869: //
1870: // Define the base asynchronous I/O argument types
1871: //
1872:
1873: typedef struct _IO_STATUS_BLOCK {
1874: NTSTATUS Status;
1875: ULONG Information;
1876: } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
1877:
1878: //
1879: // Define an Asynchronous Procedure Call from I/O viewpoint
1880: //
1881:
1882: typedef
1883: VOID
1884: (*PIO_APC_ROUTINE) (
1885: IN PVOID ApcContext,
1886: IN PIO_STATUS_BLOCK IoStatusBlock,
1887: IN ULONG Reserved
1888: );
1889:
1890: //
1891: // Define the file information class values
1892: //
1893: // WARNING: The order of the following values are assumed by the I/O system.
1894: // Any changes made here should be reflected there as well.
1895: //
1896:
1897: typedef enum _FILE_INFORMATION_CLASS {
1898: FileDirectoryInformation = 1,
1899: FileFullDirectoryInformation,
1900: FileBothDirectoryInformation,
1901: FileBasicInformation,
1902: FileStandardInformation,
1903: FileInternalInformation,
1904: FileEaInformation,
1905: FileAccessInformation,
1906: FileNameInformation,
1907: FileRenameInformation,
1908: FileLinkInformation,
1909: FileNamesInformation,
1910: FileDispositionInformation,
1911: FilePositionInformation,
1912: FileFullEaInformation,
1913: FileModeInformation,
1914: FileAlignmentInformation,
1915: FileAllInformation,
1916: FileAllocationInformation,
1917: FileEndOfFileInformation,
1918: FileAlternateNameInformation,
1919: FileStreamInformation,
1920: FilePipeInformation,
1921: FilePipeLocalInformation,
1922: FilePipeRemoteInformation,
1923: FileMailslotQueryInformation,
1924: FileMailslotSetInformation,
1925: FileMaximumInformation
1926: } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
1927:
1928: //
1929: // Define the various structures which are returned on query operations
1930: //
1931:
1932: typedef struct _FILE_BASIC_INFORMATION {
1933: LARGE_INTEGER CreationTime;
1934: LARGE_INTEGER LastAccessTime;
1935: LARGE_INTEGER LastWriteTime;
1936: LARGE_INTEGER ChangeTime;
1937: ULONG FileAttributes;
1938: } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
1939:
1940: typedef struct _FILE_STANDARD_INFORMATION {
1941: LARGE_INTEGER AllocationSize;
1942: LARGE_INTEGER EndOfFile;
1943: ULONG NumberOfLinks;
1944: BOOLEAN DeletePending;
1945: BOOLEAN Directory;
1946: } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
1947:
1948: typedef struct _FILE_POSITION_INFORMATION {
1949: LARGE_INTEGER CurrentByteOffset;
1950: } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
1951:
1952:
1953: typedef struct _FILE_FULL_EA_INFORMATION {
1954: ULONG NextEntryOffset;
1955: UCHAR Flags;
1956: UCHAR EaNameLength;
1957: USHORT EaValueLength;
1958: CHAR EaName[1];
1959: } FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
1960:
1961: //
1962: // Define the file system information class values
1963: //
1964: // WARNING: The order of the following values are assumed by the I/O system.
1965: // Any changes made here should be reflected there as well.
1966:
1967: typedef enum _FSINFOCLASS {
1968: FileFsVolumeInformation = 1,
1969: FileFsLabelInformation,
1970: FileFsSizeInformation,
1971: FileFsDeviceInformation,
1972: FileFsAttributeInformation,
1973: FileFsMaximumInformation
1974: } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
1975:
1976: typedef struct _FILE_FS_DEVICE_INFORMATION {
1977: DEVICE_TYPE DeviceType;
1978: ULONG Characteristics;
1979: } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
1980:
1981: //
1982: // Define the I/O bus interface types.
1983: //
1984:
1985: typedef enum _INTERFACE_TYPE {
1986: Internal,
1987: Isa,
1988: Eisa,
1989: MicroChannel,
1990: TurboChannel,
1991: PCIBus,
1992: VMEBus,
1993: NuBus,
1994: PCMCIABus,
1995: CBus,
1996: MPIBus,
1997: MPSABus,
1998: MaximumInterfaceType
1999: }INTERFACE_TYPE, *PINTERFACE_TYPE;
2000:
2001: //
2002: // Define the DMA transfer widths.
2003: //
2004:
2005: typedef enum _DMA_WIDTH {
2006: Width8Bits,
2007: Width16Bits,
2008: Width32Bits,
2009: MaximumDmaWidth
2010: }DMA_WIDTH, *PDMA_WIDTH;
2011:
2012: //
2013: // Define DMA transfer speeds.
2014: //
2015:
2016: typedef enum _DMA_SPEED {
2017: Compatible,
2018: TypeA,
2019: TypeB,
2020: TypeC,
2021: MaximumDmaSpeed
2022: }DMA_SPEED, *PDMA_SPEED;
2023:
2024: //
2025: // Define I/O Driver error log packet structure. This structure is filled in
2026: // by the driver.
2027: //
2028:
2029: typedef struct _IO_ERROR_LOG_PACKET {
2030: UCHAR MajorFunctionCode;
2031: UCHAR RetryCount;
2032: USHORT DumpDataSize;
2033: USHORT NumberOfStrings;
2034: USHORT StringOffset;
2035: USHORT EventCategory;
2036: NTSTATUS ErrorCode;
2037: ULONG UniqueErrorValue;
2038: NTSTATUS FinalStatus;
2039: ULONG SequenceNumber;
2040: ULONG IoControlCode;
2041: LARGE_INTEGER DeviceOffset;
2042: ULONG DumpData[1];
2043: }IO_ERROR_LOG_PACKET, *PIO_ERROR_LOG_PACKET;
2044:
2045: //
2046: // Define the I/O error log message. This message is sent by the error log
2047: // thread over the lpc port.
2048: //
2049:
2050: typedef struct _IO_ERROR_LOG_MESSAGE {
2051: USHORT Type;
2052: USHORT Size;
2053: USHORT DriverNameLength;
2054: LARGE_INTEGER TimeStamp;
2055: ULONG DriverNameOffset;
2056: IO_ERROR_LOG_PACKET EntryData;
2057: }IO_ERROR_LOG_MESSAGE, *PIO_ERROR_LOG_MESSAGE;
2058:
2059: //
2060: // Define the maximum message size that will be sent over the LPC to the
2061: // application reading the error log entries.
2062: //
2063:
2064: #define IO_ERROR_LOG_MESSAGE_LENGTH PORT_MAXIMUM_MESSAGE_LENGTH
2065:
2066: //
2067: // Define the maximum packet size a driver can allocate.
2068: //
2069:
2070: #define ERROR_LOG_MAXIMUM_SIZE (IO_ERROR_LOG_MESSAGE_LENGTH + sizeof(IO_ERROR_LOG_PACKET) - \
2071: sizeof(IO_ERROR_LOG_MESSAGE) - (sizeof(WCHAR) * 40))
2072:
2073: #define PORT_MAXIMUM_MESSAGE_LENGTH 256
2074: //
2075: // Registry Specific Access Rights.
2076: //
2077:
2078: #define KEY_QUERY_VALUE (0x0001)
2079: #define KEY_SET_VALUE (0x0002)
2080: #define KEY_CREATE_SUB_KEY (0x0004)
2081: #define KEY_ENUMERATE_SUB_KEYS (0x0008)
2082: #define KEY_NOTIFY (0x0010)
2083: #define KEY_CREATE_LINK (0x0020)
2084:
2085: #define KEY_READ ((STANDARD_RIGHTS_READ |\
2086: KEY_QUERY_VALUE |\
2087: KEY_ENUMERATE_SUB_KEYS |\
2088: KEY_NOTIFY) \
2089: & \
2090: (~SYNCHRONIZE))
2091:
2092:
2093: #define KEY_WRITE ((STANDARD_RIGHTS_WRITE |\
2094: KEY_SET_VALUE |\
2095: KEY_CREATE_SUB_KEY) \
2096: & \
2097: (~SYNCHRONIZE))
2098:
2099: #define KEY_EXECUTE ((KEY_READ) \
2100: & \
2101: (~SYNCHRONIZE))
2102:
2103: #define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL |\
2104: KEY_QUERY_VALUE |\
2105: KEY_SET_VALUE |\
2106: KEY_CREATE_SUB_KEY |\
2107: KEY_ENUMERATE_SUB_KEYS |\
2108: KEY_NOTIFY |\
2109: KEY_CREATE_LINK) \
2110: & \
2111: (~SYNCHRONIZE))
2112:
2113: //
2114: // Open/Create Options
2115: //
2116:
2117: #define REG_OPTION_RESERVED (0x00000000L) // Parameter is reserved
2118:
2119: #define REG_OPTION_NON_VOLATILE (0x00000000L) // Key is preserved
2120: // when system is rebooted
2121:
2122: #define REG_OPTION_VOLATILE (0x00000001L) // Key is not preserved
2123: // when system is rebooted
2124:
2125: #define REG_OPTION_CREATE_LINK (0x00000002L) // Created key is a
2126: // symbolic link
2127:
2128: #define REG_OPTION_BACKUP_RESTORE (0x00000004L) // open for backup or restore
2129: // special access rules
2130: // privilege required
2131:
2132: #define REG_LEGAL_OPTION \
2133: (REG_OPTION_RESERVED |\
2134: REG_OPTION_NON_VOLATILE |\
2135: REG_OPTION_VOLATILE |\
2136: REG_OPTION_CREATE_LINK |\
2137: REG_OPTION_BACKUP_RESTORE)
2138:
2139: //
2140: // Key creation/open disposition
2141: //
2142:
2143: #define REG_CREATED_NEW_KEY (0x00000001L) // New Registry Key created
2144: #define REG_OPENED_EXISTING_KEY (0x00000002L) // Existing Key opened
2145:
2146: //
2147: // Key restore flags
2148: //
2149:
2150: #define REG_WHOLE_HIVE_VOLATILE (0x00000001L) // Restore whole hive volatile
2151: #define REG_REFRESH_HIVE (0x00000002L) // Unwind changes to last flush
2152:
2153: //
2154: // Key query structures
2155: //
2156:
2157: typedef struct _KEY_BASIC_INFORMATION {
2158: LARGE_INTEGER LastWriteTime;
2159: ULONG TitleIndex;
2160: ULONG NameLength;
2161: WCHAR Name[1]; // Variable length string
2162: } KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
2163:
2164: typedef struct _KEY_NODE_INFORMATION {
2165: LARGE_INTEGER LastWriteTime;
2166: ULONG TitleIndex;
2167: ULONG ClassOffset;
2168: ULONG ClassLength;
2169: ULONG NameLength;
2170: WCHAR Name[1]; // Variable length string
2171: // Class[1]; // Variable length string not declared
2172: } KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
2173:
2174: typedef struct _KEY_FULL_INFORMATION {
2175: LARGE_INTEGER LastWriteTime;
2176: ULONG TitleIndex;
2177: ULONG ClassOffset;
2178: ULONG ClassLength;
2179: ULONG SubKeys;
2180: ULONG MaxNameLen;
2181: ULONG MaxClassLen;
2182: ULONG Values;
2183: ULONG MaxValueNameLen;
2184: ULONG MaxValueDataLen;
2185: WCHAR Class[1]; // Variable length
2186: } KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
2187:
2188: typedef enum _KEY_INFORMATION_CLASS {
2189: KeyBasicInformation,
2190: KeyNodeInformation,
2191: KeyFullInformation
2192: } KEY_INFORMATION_CLASS;
2193:
2194: typedef struct _KEY_WRITE_TIME_INFORMATION {
2195: LARGE_INTEGER LastWriteTime;
2196: } KEY_WRITE_TIME_INFORMATION, *PKEY_WRITE_TIME_INFORMATION;
2197:
2198: typedef enum _KEY_SET_INFORMATION_CLASS {
2199: KeyWriteTimeInformation
2200: } KEY_SET_INFORMATION_CLASS;
2201:
2202: //
2203: // Value entry query structures
2204: //
2205:
2206: typedef struct _KEY_VALUE_BASIC_INFORMATION {
2207: ULONG TitleIndex;
2208: ULONG Type;
2209: ULONG NameLength;
2210: WCHAR Name[1]; // Variable size
2211: } KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
2212:
2213: typedef struct _KEY_VALUE_FULL_INFORMATION {
2214: ULONG TitleIndex;
2215: ULONG Type;
2216: ULONG DataOffset;
2217: ULONG DataLength;
2218: ULONG NameLength;
2219: WCHAR Name[1]; // Variable size
2220: // Data[1]; // Variable size data not declared
2221: } KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
2222:
2223: typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
2224: ULONG TitleIndex;
2225: ULONG Type;
2226: ULONG DataLength;
2227: UCHAR Data[1]; // Variable size
2228: } KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
2229:
2230: typedef enum _KEY_VALUE_INFORMATION_CLASS {
2231: KeyValueBasicInformation,
2232: KeyValueFullInformation,
2233: KeyValuePartialInformation
2234: } KEY_VALUE_INFORMATION_CLASS;
2235:
2236:
2237: #define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
2238:
2239: //
2240: // Object Manager Object Type Specific Access Rights.
2241: //
2242:
2243: #define OBJECT_TYPE_CREATE (0x0001)
2244:
2245: #define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
2246:
2247: //
2248: // Object Manager Directory Specific Access Rights.
2249: //
2250:
2251: #define DIRECTORY_QUERY (0x0001)
2252: #define DIRECTORY_TRAVERSE (0x0002)
2253: #define DIRECTORY_CREATE_OBJECT (0x0004)
2254: #define DIRECTORY_CREATE_SUBDIRECTORY (0x0008)
2255:
2256: #define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
2257:
2258: //
2259: // Object Manager Symbolic Link Specific Access Rights.
2260: //
2261:
2262: #define SYMBOLIC_LINK_QUERY (0x0001)
2263:
2264: #define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
2265:
2266: typedef struct _OBJECT_NAME_INFORMATION {
2267: UNICODE_STRING Name;
2268: } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
2269:
2270: //
2271: // Section Information Structures.
2272: //
2273:
2274: typedef enum _SECTION_INHERIT {
2275: ViewShare = 1,
2276: ViewUnmap = 2
2277: } SECTION_INHERIT;
2278:
2279: //
2280: // Section Access Rights.
2281: //
2282:
2283: // begin_winnt
2284: #define SECTION_QUERY 0x0001
2285: #define SECTION_MAP_WRITE 0x0002
2286: #define SECTION_MAP_READ 0x0004
2287: #define SECTION_MAP_EXECUTE 0x0008
2288: #define SECTION_EXTEND_SIZE 0x0010
2289:
2290: #define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\
2291: SECTION_MAP_WRITE | \
2292: SECTION_MAP_READ | \
2293: SECTION_MAP_EXECUTE | \
2294: SECTION_EXTEND_SIZE)
2295: // end_winnt
2296:
2297: #define SEGMENT_ALL_ACCESS SECTION_ALL_ACCESS
2298:
2299: #define PAGE_NOACCESS 0x01 // winnt
2300: #define PAGE_READONLY 0x02 // winnt
2301: #define PAGE_READWRITE 0x04 // winnt
2302: #define PAGE_WRITECOPY 0x08 // winnt
2303: #define PAGE_EXECUTE 0x10 // winnt
2304: #define PAGE_EXECUTE_READ 0x20 // winnt
2305: #define PAGE_EXECUTE_READWRITE 0x40 // winnt
2306: #define PAGE_EXECUTE_WRITECOPY 0x80 // winnt
2307: #define PAGE_GUARD 0x100 // winnt
2308: #define PAGE_NOCACHE 0x200 // winnt
2309:
2310: #define MEM_TOP_DOWN 0x100000
2311: #define MEM_LARGE_PAGES 0x20000000
2312: #define THREAD_TERMINATE (0x0001) // winnt
2313: #define THREAD_SET_INFORMATION (0x0020) // winnt
2314:
2315: #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
2316: 0x3FF)
2317:
2318: //
2319: // ClientId
2320: //
2321:
2322: typedef struct _CLIENT_ID {
2323: HANDLE UniqueProcess;
2324: HANDLE UniqueThread;
2325: } CLIENT_ID;
2326: typedef CLIENT_ID *PCLIENT_ID;
2327:
2328: #define NtCurrentProcess() ( (HANDLE) -1 )
2329:
2330: #if defined(_X86_)
2331: //
2332: // Indicate that the i386 compiler supports the pragma textout construct.
2333: //
2334:
2335: #define ALLOC_PRAGMA 1
2336: #define NORMAL_DISPATCH_LENGTH 106
2337: #define DISPATCH_LENGTH NORMAL_DISPATCH_LENGTH
2338: //
2339: // Interrupt Request Level definitions
2340: //
2341:
2342: #define PASSIVE_LEVEL 0 // Passive release level
2343: #define LOW_LEVEL 0 // Lowest interrupt level
2344: #define APC_LEVEL 1 // APC interrupt level
2345: #define DISPATCH_LEVEL 2 // Dispatcher level
2346:
2347: #define PROFILE_LEVEL 27 // timer used for profiling.
2348: #define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86
2349: #define CLOCK2_LEVEL 28 // Interval clock 2 level
2350: #define IPI_LEVEL 29 // Interprocessor interrupt level
2351: #define POWER_LEVEL 30 // Power failure level
2352: #define HIGH_LEVEL 31 // Highest interrupt level
2353:
2354: //
2355: // Get data cache fill size.
2356: //
2357:
2358: #define KeGetDcacheFillSize() 1L
2359:
2360:
2361: #define KeFlushIoBuffers(Mdl, ReadOperation, DmaOperation)
2362:
2363: //
2364: // i386 Specific portions of mm component
2365: //
2366:
2367: //
2368: // Define the page size for the Intel 386 as 4096 (0x1000).
2369: //
2370:
2371: #define PAGE_SIZE (ULONG)0x1000
2372:
2373: //
2374: // Define the number of trailing zeroes in a page aligned virtual address.
2375: // This is used as the shift count when shifting virtual addresses to
2376: // virtual page numbers.
2377: //
2378:
2379: #define PAGE_SHIFT 12L
2380:
2381: //
2382: // The highest user address reserves 64K bytes for a guard
2383: // page. This allows the probing of address from kernel mode to
2384: // only have to check the starting address for strucutures of 64k bytes
2385: // or less.
2386: //
2387:
2388: #define MM_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF // temp should be 0xBFFEFFFF
2389:
2390: #define MM_USER_PROBE_ADDRESS 0x7FFF0000 // starting address of guard page
2391:
2392: //
2393: // The lowest user address reserves the low 64k.
2394: //
2395:
2396: #define MM_LOWEST_USER_ADDRESS (PVOID)0x00010000
2397:
2398: //
2399: // The lowest address for system space.
2400: //
2401:
2402: #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000
2403:
2404: //
2405: // Result type definition for i386. (Machine specific enumerate type
2406: // which is return type for portable exinterlockedincrement/decrement
2407: // procedures.) In general, you should use the enumerated type defined
2408: // in ex.h instead of directly referencing these constants.
2409: //
2410:
2411: // Flags loaded into AH by LAHF instruction
2412:
2413: #define EFLAG_SIGN 0x8000
2414: #define EFLAG_ZERO 0x4000
2415: #define EFLAG_SELECT (EFLAG_SIGN | EFLAG_ZERO)
2416:
2417: #define RESULT_NEGATIVE ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT)
2418: #define RESULT_ZERO ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT)
2419: #define RESULT_POSITIVE ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT)
2420:
2421: //
2422: // Convert various portable ExInterlock apis into their architecural
2423: // equivalents.
2424: //
2425:
2426: #define ExInterlockedIncrementLong(Addend,Lock) \
2427: Exi386InterlockedIncrementLong(Addend)
2428:
2429: #define ExInterlockedDecrementLong(Addend,Lock) \
2430: Exi386InterlockedDecrementLong(Addend)
2431:
2432: #define ExInterlockedExchangeUlong(Target,Value,Lock) \
2433: Exi386InterlockedExchangeUlong(Target,Value)
2434:
2435: //
2436: // Prototypes for architecural specific versions of Exi386 api
2437: //
2438:
2439: //
2440: // Interlocked result type is portable, but its values are machine specific.
2441: // Constants for value are in i386.h, mips.h, etc.
2442: //
2443:
2444: typedef enum _INTERLOCKED_RESULT {
2445: ResultNegative = RESULT_NEGATIVE,
2446: ResultZero = RESULT_ZERO,
2447: ResultPositive = RESULT_POSITIVE
2448: } INTERLOCKED_RESULT;
2449:
2450: INTERLOCKED_RESULT
2451: Exi386InterlockedIncrementLong (
2452: IN PLONG Addend
2453: );
2454:
2455: INTERLOCKED_RESULT
2456: Exi386InterlockedDecrementLong (
2457: IN PLONG Addend
2458: );
2459:
2460: ULONG
2461: Exi386InterlockedExchangeUlong (
2462: IN PULONG Target,
2463: IN ULONG Value
2464: );
2465:
2466: VOID
2467: KeRaiseIrql (
2468: IN KIRQL NewIrql,
2469: OUT PKIRQL OldIrql
2470: );
2471:
2472: VOID
2473: KeLowerIrql (
2474: IN KIRQL NewIrql
2475: );
2476:
2477:
2478: #endif // defined(_X86_)
2479:
2480:
2481: #if defined(_MIPS_)
2482:
2483: //
2484: // Indicate that the MIPS compiler supports the pragma textout construct.
2485: //
2486:
2487: #define ALLOC_PRAGMA 1
2488:
2489: //
2490: // MIPS specific interlocked operation result values.
2491: //
2492:
2493: #define RESULT_ZERO 0
2494: #define RESULT_NEGATIVE -2
2495: #define RESULT_POSITIVE -1
2496:
2497: //
2498: // Interlocked result type is portable, but its values are machine specific.
2499: // Constants for value are in i386.h, mips.h, etc.
2500: //
2501:
2502: typedef enum _INTERLOCKED_RESULT {
2503: ResultNegative = RESULT_NEGATIVE,
2504: ResultZero = RESULT_ZERO,
2505: ResultPositive = RESULT_POSITIVE
2506: } INTERLOCKED_RESULT;
2507:
2508: //
2509: // MIPS Interrupt Definitions.
2510: //
2511: // Define length on interupt object dispatch code in longwords.
2512: //
2513:
2514: #define DISPATCH_LENGTH 4 // Length of dispatch code in instructions
2515:
2516: //
2517: // Define Interrupt Request Levels.
2518: //
2519:
2520: #define PASSIVE_LEVEL 0 // Passive release level
2521: #define LOW_LEVEL 0 // Lowest interrupt level
2522: #define APC_LEVEL 1 // APC interrupt level
2523: #define DISPATCH_LEVEL 2 // Dispatcher level
2524: #define IPI_LEVEL 7 // Interprocessor interrupt level
2525: #define POWER_LEVEL 7 // Power failure level
2526: #define FLOAT_LEVEL 8 // Floating interrupt level
2527: #define HIGH_LEVEL 8 // Highest interrupt level
2528:
2529: #if defined(R3000)
2530:
2531: #define PROFILE_LEVEL 7 // Profiling level
2532:
2533: #endif
2534:
2535: #if defined(R4000)
2536:
2537: #define PROFILE_LEVEL 8 // Profiling level
2538:
2539: #endif
2540:
2541: //
2542: // Define profile intervals.
2543: //
2544:
2545: #if defined(R3000)
2546:
2547: #define DEFAULT_PROFILE_INTERVAL (10 * 1000) // 1 millisecond
2548: #define MAXIMUM_PROFILE_INTERVAL (10 * 1000 * 1000) // 1 second
2549: #define MINIMUM_PROFILE_INTERVAL (10 * 1000) // 1 millisecond
2550:
2551: #endif
2552:
2553: #if defined(R4000)
2554:
2555: #define DEFAULT_PROFILE_COUNT 0x40000000 // ~= 20 seconds @50mhz
2556: #define DEFAULT_PROFILE_INTERVAL (10 * 500) // 500 microseconds
2557: #define MAXIMUM_PROFILE_INTERVAL (10 * 1000 * 1000) // 1 second
2558: #define MINIMUM_PROFILE_INTERVAL (10 * 40) // 40 microseconds
2559:
2560: #endif
2561:
2562:
2563: //
2564: // Get data cache fill size.
2565: //
2566:
2567: #define KeGetDcacheFillSize() PCR->DcacheFillSize
2568:
2569: //
2570: // Cache and write buffer flush functions.
2571: //
2572:
2573: VOID
2574: KeFlushIoBuffers (
2575: IN PMDL Mdl,
2576: IN BOOLEAN ReadOperation,
2577: IN BOOLEAN DmaOperation
2578: );
2579:
2580:
2581: VOID
2582: KeLowerIrql (
2583: KIRQL NewIrql
2584: );
2585:
2586: VOID
2587: KeRaiseIrql (
2588: KIRQL NewIrql,
2589: PKIRQL OldIrql
2590: );
2591:
2592: //
2593: // I/O space read and write macros.
2594: //
2595:
2596: #define READ_REGISTER_UCHAR(x) \
2597: *(volatile UCHAR * const)(x)
2598:
2599: #define READ_REGISTER_USHORT(x) \
2600: *(volatile USHORT * const)(x)
2601:
2602: #define READ_REGISTER_ULONG(x) \
2603: *(volatile ULONG * const)(x)
2604:
2605: #define READ_REGISTER_BUFFER_UCHAR(x, y, z) { \
2606: PUCHAR registerBuffer = x; \
2607: PUCHAR readBuffer = y; \
2608: ULONG readCount; \
2609: for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \
2610: *readBuffer = *(volatile UCHAR * const)(registerBuffer); \
2611: } \
2612: }
2613:
2614: #define READ_REGISTER_BUFFER_USHORT(x, y, z) { \
2615: PUSHORT registerBuffer = x; \
2616: PUSHORT readBuffer = y; \
2617: ULONG readCount; \
2618: for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \
2619: *readBuffer = *(volatile USHORT * const)(registerBuffer); \
2620: } \
2621: }
2622:
2623: #define READ_REGISTER_BUFFER_ULONG(x, y, z) { \
2624: PULONG registerBuffer = x; \
2625: PULONG readBuffer = y; \
2626: ULONG readCount; \
2627: for (readCount = z; readCount--; readBuffer++, registerBuffer++) { \
2628: *readBuffer = *(volatile ULONG * const)(registerBuffer); \
2629: } \
2630: }
2631:
2632: #define WRITE_REGISTER_UCHAR(x, y) { \
2633: *(volatile UCHAR * const)(x) = y; \
2634: KeFlushWriteBuffer(); \
2635: }
2636:
2637: #define WRITE_REGISTER_USHORT(x, y) { \
2638: *(volatile USHORT * const)(x) = y; \
2639: KeFlushWriteBuffer(); \
2640: }
2641:
2642: #define WRITE_REGISTER_ULONG(x, y) { \
2643: *(volatile ULONG * const)(x) = y; \
2644: KeFlushWriteBuffer(); \
2645: }
2646:
2647: #define WRITE_REGISTER_BUFFER_UCHAR(x, y, z) { \
2648: PUCHAR registerBuffer = x; \
2649: PUCHAR writeBuffer = y; \
2650: ULONG writeCount; \
2651: for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
2652: *(volatile UCHAR * const)(registerBuffer) = *writeBuffer; \
2653: } \
2654: KeFlushWriteBuffer(); \
2655: }
2656:
2657: #define WRITE_REGISTER_BUFFER_USHORT(x, y, z) { \
2658: PUSHORT registerBuffer = x; \
2659: PUSHORT writeBuffer = y; \
2660: ULONG writeCount; \
2661: for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
2662: *(volatile USHORT * const)(registerBuffer) = *writeBuffer; \
2663: } \
2664: KeFlushWriteBuffer(); \
2665: }
2666:
2667: #define WRITE_REGISTER_BUFFER_ULONG(x, y, z) { \
2668: PULONG registerBuffer = x; \
2669: PULONG writeBuffer = y; \
2670: ULONG writeCount; \
2671: for (writeCount = z; writeCount--; writeBuffer++, registerBuffer++) { \
2672: *(volatile ULONG * const)(registerBuffer) = *writeBuffer; \
2673: } \
2674: KeFlushWriteBuffer(); \
2675: }
2676:
2677:
2678: #define READ_PORT_UCHAR(x) \
2679: *(volatile UCHAR * const)(x)
2680:
2681: #define READ_PORT_USHORT(x) \
2682: *(volatile USHORT * const)(x)
2683:
2684: #define READ_PORT_ULONG(x) \
2685: *(volatile ULONG * const)(x)
2686:
2687: #define READ_PORT_BUFFER_UCHAR(x, y, z) { \
2688: PUCHAR readBuffer = y; \
2689: ULONG readCount; \
2690: for (readCount = 0; readCount < z; readCount++, readBuffer++) { \
2691: *readBuffer = *(volatile UCHAR * const)(x); \
2692: } \
2693: }
2694:
2695: #define READ_PORT_BUFFER_USHORT(x, y, z) { \
2696: PUSHORT readBuffer = y; \
2697: ULONG readCount; \
2698: for (readCount = 0; readCount < z; readCount++, readBuffer++) { \
2699: *readBuffer = *(volatile USHORT * const)(x); \
2700: } \
2701: }
2702:
2703: #define READ_PORT_BUFFER_ULONG(x, y, z) { \
2704: PULONG readBuffer = y; \
2705: ULONG readCount; \
2706: for (readCount = 0; readCount < z; readCount++, readBuffer++) { \
2707: *readBuffer = *(volatile ULONG * const)(x); \
2708: } \
2709: }
2710:
2711: #define WRITE_PORT_UCHAR(x, y) { \
2712: *(volatile UCHAR * const)(x) = y; \
2713: KeFlushWriteBuffer(); \
2714: }
2715:
2716: #define WRITE_PORT_USHORT(x, y) { \
2717: *(volatile USHORT * const)(x) = y; \
2718: KeFlushWriteBuffer(); \
2719: }
2720:
2721: #define WRITE_PORT_ULONG(x, y) { \
2722: *(volatile ULONG * const)(x) = y; \
2723: KeFlushWriteBuffer(); \
2724: }
2725:
2726: #define WRITE_PORT_BUFFER_UCHAR(x, y, z) { \
2727: PUCHAR writeBuffer = y; \
2728: ULONG writeCount; \
2729: for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \
2730: *(volatile UCHAR * const)(x) = *writeBuffer; \
2731: KeFlushWriteBuffer(); \
2732: } \
2733: }
2734:
2735: #define WRITE_PORT_BUFFER_USHORT(x, y, z) { \
2736: PUSHORT writeBuffer = y; \
2737: ULONG writeCount; \
2738: for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \
2739: *(volatile USHORT * const)(x) = *writeBuffer; \
2740: KeFlushWriteBuffer(); \
2741: } \
2742: }
2743:
2744: #define WRITE_PORT_BUFFER_ULONG(x, y, z) { \
2745: PULONG writeBuffer = y; \
2746: ULONG writeCount; \
2747: for (writeCount = 0; writeCount < z; writeCount++, writeBuffer++) { \
2748: *(volatile ULONG * const)(x) = *writeBuffer; \
2749: KeFlushWriteBuffer(); \
2750: } \
2751: }
2752:
2753: //
2754: // Define the page size for the MIPS r3000 and r4000 as 4096 (0x1000).
2755: //
2756:
2757: #define PAGE_SIZE (ULONG)0x1000
2758:
2759: //
2760: // Define the number of trailing zeroes in a page aligned virtual address.
2761: // This is used as the shift count when shifting virtual addresses to
2762: // virtual page numbers.
2763: //
2764:
2765: #define PAGE_SHIFT 12L
2766:
2767: //
2768: // The highest user address reserves 64K bytes for a guard page. This
2769: // the probing of address from kernel mode to only have to check the
2770: // starting address for structures of 64k bytes or less.
2771: //
2772:
2773: #define MM_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF // highest user address
2774: #define MM_USER_PROBE_ADDRESS 0x7FFF0000 // starting address of guard page
2775:
2776: //
2777: // The lowest user address reserves the low 64k.
2778: //
2779:
2780: #define MM_LOWEST_USER_ADDRESS (PVOID)0x00010000
2781:
2782: //
2783: // The lowest address for system space.
2784: //
2785:
2786: #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000
2787: #define SYSTEM_BASE 0xc0800000 // start of system space (no typecast)
2788:
2789: #endif // defined(_MIPS_)
2790:
2791: #if defined(_ALPHA_)
2792:
2793: //
2794: // Include the alpha instruction definitions
2795: //
2796:
2797: #include "alphaops.h"
2798:
2799: //
2800: // Include reference machine definitions.
2801: //
2802:
2803: #include "alpharef.h"
2804:
2805:
2806: //
2807: // Define length of interrupt vector table.
2808: //
2809:
2810: #define MAXIMUM_VECTOR 256
2811:
2812: //
2813: // Define bus error routine type.
2814: //
2815:
2816: struct _EXCEPTION_RECORD;
2817: struct _KEXCEPTION_FRAME;
2818: struct _KTRAP_FRAME;
2819:
2820: typedef
2821: BOOLEAN
2822: (*PKBUS_ERROR_ROUTINE) (
2823: IN struct _EXCEPTION_RECORD *ExceptionRecord,
2824: IN struct _KEXCEPTION_FRAME *ExceptionFrame,
2825: IN struct _KTRAP_FRAME *TrapFrame
2826: );
2827:
2828:
2829: #define PCR_MINOR_VERSION 1
2830: #define PCR_MAJOR_VERSION 1
2831:
2832: typedef struct _KPCR {
2833:
2834: //
2835: // Major and minor version numbers of the PCR.
2836: //
2837:
2838: ULONG MinorVersion;
2839: ULONG MajorVersion;
2840:
2841: //
2842: // Start of the architecturally defined section of the PCR. This section
2843: // may be directly addressed by vendor/platform specific PAL/HAL code and will
2844: // not change from version to version of NT.
2845:
2846: //
2847: // PALcode information.
2848: //
2849:
2850: ULONGLONG PalBaseAddress;
2851: ULONG PalMajorVersion;
2852: ULONG PalMinorVersion;
2853: ULONG PalSequenceVersion;
2854: ULONG PalMajorSpecification;
2855: ULONG PalMinorSpecification;
2856:
2857: //
2858: // Firmware restart information.
2859: //
2860:
2861: ULONGLONG FirmwareRestartAddress;
2862: PVOID RestartBlock;
2863:
2864: //
2865: // Reserved per-processor region for the PAL (3K bytes).
2866: //
2867:
2868: ULONGLONG PalReserved[384];
2869:
2870: //
2871: // Panic Stack Address.
2872: //
2873:
2874: ULONG PanicStack;
2875:
2876: //
2877: // Processor parameters.
2878: //
2879:
2880: ULONG ProcessorType;
2881: ULONG ProcessorRevision;
2882: ULONG PhysicalAddressBits;
2883: ULONG MaximumAddressSpaceNumber;
2884: ULONG PageSize;
2885: ULONG FirstLevelDcacheSize;
2886: ULONG FirstLevelDcacheFillSize;
2887: ULONG FirstLevelIcacheSize;
2888: ULONG FirstLevelIcacheFillSize;
2889:
2890: //
2891: // System Parameters.
2892: //
2893:
2894: ULONG FirmwareRevisionId;
2895: UCHAR SystemType[8];
2896: ULONG SystemVariant;
2897: ULONG SystemRevision;
2898: UCHAR SystemSerialNumber[16];
2899: ULONG CycleClockPeriod;
2900: ULONG SecondLevelCacheSize;
2901: ULONG SecondLevelCacheFillSize;
2902: ULONG ThirdLevelCacheSize;
2903: ULONG ThirdLevelCacheFillSize;
2904: ULONG FourthLevelCacheSize;
2905: ULONG FourthLevelCacheFillSize;
2906:
2907: //
2908: // Pointer to processor control block.
2909: //
2910:
2911: struct _KPRCB *Prcb;
2912:
2913: //
2914: // Processor identification.
2915: //
2916:
2917: CCHAR Number;
2918: KAFFINITY SetMember;
2919:
2920: //
2921: // Reserved per-processor region for the HAL (.5K bytes).
2922: //
2923:
2924: ULONGLONG HalReserved[64];
2925:
2926: //
2927: // IRQL mapping tables.
2928: //
2929:
2930: ULONG IrqlTable[8];
2931:
2932: #define SFW_IMT_ENTRIES 4
2933: #define HDW_IMT_ENTRIES 128
2934:
2935: struct _IRQLMASK {
2936: USHORT IrqlTableIndex; // synchronization irql level
2937: USHORT IDTIndex; // vector in IDT
2938: } IrqlMask[SFW_IMT_ENTRIES + HDW_IMT_ENTRIES];
2939:
2940: //
2941: // Interrupt Dispatch Table (IDT).
2942: //
2943:
2944: PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];
2945:
2946: //
2947: // Reserved vectors mask, these vectors cannot be attached to via
2948: // standard interrupt objects.
2949: //
2950:
2951: ULONG ReservedVectors;
2952:
2953: //
2954: // Profiling data.
2955: //
2956:
2957: PLIST_ENTRY ProfileListHead;
2958: ULONG ProfileInterval;
2959: ULONG ProfileCount;
2960:
2961: //
2962: // Pointer to machine check handler
2963: //
2964:
2965: PKBUS_ERROR_ROUTINE MachineCheckError;
2966:
2967: //
2968: // DPC Stack.
2969: //
2970:
2971: ULONG DpcStack;
2972:
2973: //
2974: // End of the architecturally defined section of the PCR. This section
2975: // may be directly addressed by vendor/platform specific HAL code and will
2976: // not change from version to version of NT. Some of these values are
2977: // reserved for chip-specific palcode.
2978: } KPCR, *PKPCR;
2979: //
2980: // length of dispatch code in interrupt template
2981: //
2982: #define DISPATCH_LENGTH 4
2983:
2984: //
2985: // Define IRQL levels across the architecture.
2986: //
2987:
2988: #define PASSIVE_LEVEL 0
2989: #define LOW_LEVEL 0
2990: #define APC_LEVEL 1
2991: #define DISPATCH_LEVEL 2
2992: #define HIGH_LEVEL 7
2993:
2994:
2995: //
2996: // Define Interlocked operation result values.
2997: //
2998:
2999: #define RESULT_ZERO 0
3000: #define RESULT_NEGATIVE 1
3001: #define RESULT_POSITIVE 2
3002:
3003: //
3004: // Interlocked result type is portable, but its values are machine specific.
3005: // Constants for value are in i386.h, mips.h, etc.
3006: //
3007:
3008: typedef enum _INTERLOCKED_RESULT {
3009: ResultNegative = RESULT_NEGATIVE,
3010: ResultZero = RESULT_ZERO,
3011: ResultPositive = RESULT_POSITIVE
3012: } INTERLOCKED_RESULT;
3013:
3014:
3015: // there is a lot of other stuff that could go in here
3016: // probe macros
3017: // others
3018:
3019: //
3020: // Define the page size for the Alpha ev4 and lca as 8k.
3021: //
3022:
3023: #define PAGE_SIZE (ULONG)0x2000
3024:
3025: //
3026: // Define the number of trailing zeroes in a page aligned virtual address.
3027: // This is used as the shift count when shifting virtual addresses to
3028: // virtual page numbers.
3029: //
3030:
3031: #define PAGE_SHIFT 13L
3032:
3033:
3034: //
3035: // The highest user address reserves 64K bytes for a guard page. This
3036: // the probing of address from kernel mode to only have to check the
3037: // starting address for structures of 64k bytes or less.
3038: //
3039:
3040: #define MM_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF // highest user address
3041: #define MM_USER_PROBE_ADDRESS 0x7FFF0000 // starting address of guard page
3042:
3043: //
3044: // The lowest user address reserves the low 64k.
3045: //
3046:
3047: #define MM_LOWEST_USER_ADDRESS (PVOID)0x00010000
3048:
3049: //
3050: // The lowest address for system space.
3051: //
3052:
3053: #define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000
3054: //
3055: // Cache and write buffer flush functions.
3056: //
3057:
3058: VOID
3059: KeFlushIoBuffers (
3060: IN PMDL Mdl,
3061: IN BOOLEAN ReadOperation,
3062: IN BOOLEAN DmaOperation
3063: );
3064:
3065: VOID
3066: KeRaiseIrql (
3067: IN KIRQL NewIrql,
3068: OUT PKIRQL OldIrql
3069: );
3070:
3071: VOID
3072: KeLowerIrql (
3073: IN KIRQL NewIrql
3074: );
3075:
3076: #endif // _ALPHA_
3077:
3078: #ifdef _X86_
3079:
3080: //
3081: // Disable these two pramas that evaluate to "sti" "cli" on x86 so that driver
3082: // writers to not leave them inadvertantly in their code.
3083: //
3084:
3085: #if !defined(MIDL_PASS)
3086: #if !defined(_CFRONT_PASS_)
3087: #if !defined(RC_INVOKED)
3088:
3089: #pragma warning(disable:4164) // disable C4164 warning so that apps that
3090: // build with /Od don't get weird errors !
3091: #pragma function(_enable)
3092: #pragma function(_disable)
3093:
3094: #pragma warning(default:4164) // reenable C4164 warning
3095:
3096: #endif
3097: #endif
3098: #endif
3099:
3100:
3101: #ifdef _X86_
3102:
3103: // begin_winnt
3104:
3105: //
3106: // Define the size of the 80387 save area, which is in the context frame.
3107: //
3108:
3109: #define SIZE_OF_80387_REGISTERS 80
3110:
3111: //
3112: // The following flags control the contents of the CONTEXT structure.
3113: //
3114:
3115: #define CONTEXT_i386 0x00010000 // this assumes that i386 and
3116: #define CONTEXT_i486 0x00010000 // i486 have identical context records
3117:
3118: #define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
3119: #define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
3120: #define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS
3121: #define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state
3122: #define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7
3123:
3124: #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER |\
3125: CONTEXT_SEGMENTS)
3126:
3127: typedef struct _FLOATING_SAVE_AREA {
3128: ULONG ControlWord;
3129: ULONG StatusWord;
3130: ULONG TagWord;
3131: ULONG ErrorOffset;
3132: ULONG ErrorSelector;
3133: ULONG DataOffset;
3134: ULONG DataSelector;
3135: UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];
3136: ULONG Cr0NpxState;
3137: } FLOATING_SAVE_AREA;
3138:
3139: typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
3140:
3141: //
3142: // Context Frame
3143: //
3144: // This frame has a several purposes: 1) it is used as an argument to
3145: // NtContinue, 2) is is used to constuct a call frame for APC delivery,
3146: // and 3) it is used in the user level thread creation routines.
3147: //
3148: // The layout of the record conforms to a standard call frame.
3149: //
3150:
3151: typedef struct _CONTEXT {
3152:
3153: //
3154: // The flags values within this flag control the contents of
3155: // a CONTEXT record.
3156: //
3157: // If the context record is used as an input parameter, then
3158: // for each portion of the context record controlled by a flag
3159: // whose value is set, it is assumed that that portion of the
3160: // context record contains valid context. If the context record
3161: // is being used to modify a threads context, then only that
3162: // portion of the threads context will be modified.
3163: //
3164: // If the context record is used as an IN OUT parameter to capture
3165: // the context of a thread, then only those portions of the thread's
3166: // context corresponding to set flags will be returned.
3167: //
3168: // The context record is never used as an OUT only parameter.
3169: //
3170:
3171: ULONG ContextFlags;
3172:
3173: //
3174: // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
3175: // set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT
3176: // included in CONTEXT_FULL.
3177: //
3178:
3179: ULONG Dr0;
3180: ULONG Dr1;
3181: ULONG Dr2;
3182: ULONG Dr3;
3183: ULONG Dr6;
3184: ULONG Dr7;
3185:
3186: //
3187: // This section is specified/returned if the
3188: // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
3189: //
3190:
3191: FLOATING_SAVE_AREA FloatSave;
3192:
3193: //
3194: // This section is specified/returned if the
3195: // ContextFlags word contians the flag CONTEXT_SEGMENTS.
3196: //
3197:
3198: ULONG SegGs;
3199: ULONG SegFs;
3200: ULONG SegEs;
3201: ULONG SegDs;
3202:
3203: //
3204: // This section is specified/returned if the
3205: // ContextFlags word contians the flag CONTEXT_INTEGER.
3206: //
3207:
3208: ULONG Edi;
3209: ULONG Esi;
3210: ULONG Ebx;
3211: ULONG Edx;
3212: ULONG Ecx;
3213: ULONG Eax;
3214:
3215: //
3216: // This section is specified/returned if the
3217: // ContextFlags word contians the flag CONTEXT_CONTROL.
3218: //
3219:
3220: ULONG Ebp;
3221: ULONG Eip;
3222: ULONG SegCs; // MUST BE SANITIZED
3223: ULONG EFlags; // MUST BE SANITIZED
3224: ULONG Esp;
3225: ULONG SegSs;
3226:
3227: } CONTEXT;
3228:
3229:
3230:
3231: typedef CONTEXT *PCONTEXT;
3232:
3233: // begin_ntminiport
3234:
3235: #endif //_X86_
3236:
3237: //
3238: // I/O space read and write macros.
3239: //
3240: // These have to be actual functions on the 386, because we need
3241: // to use assembler, but cannot return a value if we inline it.
3242: //
3243: // The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space.
3244: // (Use x86 move instructions, with LOCK prefix to force correct behavior
3245: // w.r.t. caches and write buffers.)
3246: //
3247: // The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space.
3248: // (Use x86 in/out instructions.)
3249: //
3250:
3251: UCHAR
3252: READ_REGISTER_UCHAR(
3253: PUCHAR Register
3254: );
3255:
3256: USHORT
3257: READ_REGISTER_USHORT(
3258: PUSHORT Register
3259: );
3260:
3261: ULONG
3262: READ_REGISTER_ULONG(
3263: PULONG Register
3264: );
3265:
3266: VOID
3267: READ_REGISTER_BUFFER_UCHAR(
3268: PUCHAR Register,
3269: PUCHAR Buffer,
3270: ULONG Count
3271: );
3272:
3273: VOID
3274: READ_REGISTER_BUFFER_USHORT(
3275: PUSHORT Register,
3276: PUSHORT Buffer,
3277: ULONG Count
3278: );
3279:
3280: VOID
3281: READ_REGISTER_BUFFER_ULONG(
3282: PULONG Register,
3283: PULONG Buffer,
3284: ULONG Count
3285: );
3286:
3287:
3288: VOID
3289: WRITE_REGISTER_UCHAR(
3290: PUCHAR Register,
3291: UCHAR Value
3292: );
3293:
3294: VOID
3295: WRITE_REGISTER_USHORT(
3296: PUSHORT Register,
3297: USHORT Value
3298: );
3299:
3300: VOID
3301: WRITE_REGISTER_ULONG(
3302: PULONG Register,
3303: ULONG Value
3304: );
3305:
3306: VOID
3307: WRITE_REGISTER_BUFFER_UCHAR(
3308: PUCHAR Register,
3309: PUCHAR Buffer,
3310: ULONG Count
3311: );
3312:
3313: VOID
3314: WRITE_REGISTER_BUFFER_USHORT(
3315: PUSHORT Register,
3316: PUSHORT Buffer,
3317: ULONG Count
3318: );
3319:
3320: VOID
3321: WRITE_REGISTER_BUFFER_ULONG(
3322: PULONG Register,
3323: PULONG Buffer,
3324: ULONG Count
3325: );
3326:
3327: UCHAR
3328: READ_PORT_UCHAR(
3329: PUCHAR Port
3330: );
3331:
3332: USHORT
3333: READ_PORT_USHORT(
3334: PUSHORT Port
3335: );
3336:
3337: ULONG
3338: READ_PORT_ULONG(
3339: PULONG Port
3340: );
3341:
3342: VOID
3343: READ_PORT_BUFFER_UCHAR(
3344: PUCHAR Port,
3345: PUCHAR Buffer,
3346: ULONG Count
3347: );
3348:
3349: VOID
3350: READ_PORT_BUFFER_USHORT(
3351: PUSHORT Port,
3352: PUSHORT Buffer,
3353: ULONG Count
3354: );
3355:
3356: VOID
3357: READ_PORT_BUFFER_ULONG(
3358: PULONG Port,
3359: PULONG Buffer,
3360: ULONG Count
3361: );
3362:
3363: VOID
3364: WRITE_PORT_UCHAR(
3365: PUCHAR Port,
3366: UCHAR Value
3367: );
3368:
3369: VOID
3370: WRITE_PORT_USHORT(
3371: PUSHORT Port,
3372: USHORT Value
3373: );
3374:
3375: VOID
3376: WRITE_PORT_ULONG(
3377: PULONG Port,
3378: ULONG Value
3379: );
3380:
3381: VOID
3382: WRITE_PORT_BUFFER_UCHAR(
3383: PUCHAR Port,
3384: PUCHAR Buffer,
3385: ULONG Count
3386: );
3387:
3388: VOID
3389: WRITE_PORT_BUFFER_USHORT(
3390: PUSHORT Port,
3391: PUSHORT Buffer,
3392: ULONG Count
3393: );
3394:
3395: VOID
3396: WRITE_PORT_BUFFER_ULONG(
3397: PULONG Port,
3398: PULONG Buffer,
3399: ULONG Count
3400: );
3401:
3402: #endif // _X86_
3403:
3404: #if defined(_MIPS_)
3405: //
3406: // Define unsupported "keywords".
3407: //
3408:
3409: #define _cdecl
3410:
3411: // begin_windbgkd
3412:
3413: #if defined(_MIPS_)
3414:
3415: #endif
3416: //
3417: // Define length of exception code dispatch vector.
3418: //
3419:
3420: #define XCODE_VECTOR_LENGTH 32
3421:
3422: //
3423: // Define length of interrupt vector table.
3424: //
3425:
3426: #define MAXIMUM_VECTOR 256
3427:
3428: //
3429: // Define bus error routine type.
3430: //
3431:
3432: struct _EXCEPTION_RECORD;
3433: struct _KEXCEPTION_FRAME;
3434: struct _KTRAP_FRAME;
3435:
3436: typedef
3437: VOID
3438: (*PKBUS_ERROR_ROUTINE) (
3439: IN struct _EXCEPTION_RECORD *ExceptionRecord,
3440: IN struct _KEXCEPTION_FRAME *ExceptionFrame,
3441: IN struct _KTRAP_FRAME *TrapFrame,
3442: IN PVOID VirtualAddress,
3443: IN PHYSICAL_ADDRESS PhysicalAddress
3444: );
3445:
3446: //
3447: // Define Processor Control Region Structure.
3448: //
3449:
3450: #define PCR_MINOR_VERSION 1
3451: #define PCR_MAJOR_VERSION 1
3452:
3453: typedef struct _KPCR {
3454:
3455: //
3456: // Major and minor version numbers of the PCR.
3457: //
3458:
3459: USHORT MinorVersion;
3460: USHORT MajorVersion;
3461:
3462: //
3463: // Start of the architecturally defined section of the PCR. This section
3464: // may be directly addressed by vendor/platform specific HAL code and will
3465: // not change from version to version of NT.
3466: //
3467: // Interrupt and error exception vectors.
3468: //
3469:
3470: PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];
3471: PVOID XcodeDispatch[XCODE_VECTOR_LENGTH];
3472:
3473: //
3474: // First and second level cache parameters.
3475: //
3476:
3477: ULONG FirstLevelDcacheSize;
3478: ULONG FirstLevelDcacheFillSize;
3479: ULONG FirstLevelIcacheSize;
3480: ULONG FirstLevelIcacheFillSize;
3481: ULONG SecondLevelDcacheSize;
3482: ULONG SecondLevelDcacheFillSize;
3483: ULONG SecondLevelIcacheSize;
3484: ULONG SecondLevelIcacheFillSize;
3485:
3486: //
3487: // Pointer to processor control block.
3488: //
3489:
3490: struct _KPRCB *Prcb;
3491:
3492: //
3493: // Pointer to the thread environment block.
3494: //
3495:
3496: PVOID Teb;
3497:
3498: //
3499: // Data cache alignment and fill size used for cache flushing and alignment.
3500: // These fields are set to the larger of the first and second level data
3501: // cache fill sizes.
3502: //
3503:
3504: ULONG DcacheAlignment;
3505: ULONG DcacheFillSize;
3506:
3507: //
3508: // Instruction cache alignment and fill size used for cache flushing and
3509: // alignment. These fields are set to the larger of the first and second
3510: // level data cache fill sizes.
3511: //
3512:
3513: ULONG IcacheAlignment;
3514: ULONG IcacheFillSize;
3515:
3516: //
3517: // Processor identification from PrId register.
3518: //
3519:
3520: ULONG ProcessorId;
3521:
3522: //
3523: // Profiling data.
3524: //
3525:
3526: ULONG ProfileInterval;
3527: ULONG ProfileCount;
3528:
3529: //
3530: // Stall execution count and scale factor.
3531: //
3532:
3533: ULONG StallExecutionCount;
3534: ULONG StallScaleFactor;
3535:
3536: //
3537: // Spare cell.
3538: //
3539:
3540: ULONG Spare;
3541:
3542: //
3543: // Pointers to bus error and parity error routines.
3544: //
3545:
3546: PKBUS_ERROR_ROUTINE DataBusError;
3547: PKBUS_ERROR_ROUTINE InstructionBusError;
3548:
3549: //
3550: // Cache policy, right justified, as read from the processor configuration
3551: // register at startup.
3552: //
3553:
3554: ULONG CachePolicy;
3555:
3556: //
3557: // IRQL mapping tables.
3558: //
3559:
3560: UCHAR IrqlMask[32];
3561: UCHAR IrqlTable[9];
3562:
3563: //
3564: // Current IRQL.
3565: //
3566:
3567: UCHAR CurrentIrql;
3568:
3569: //
3570: // Processor affinity mask.
3571: //
3572:
3573: KAFFINITY SetMember;
3574:
3575: //
3576: // Reserved interrupt vector mask.
3577: //
3578:
3579: ULONG ReservedVectors;
3580:
3581: //
3582: // Current state parameters.
3583: //
3584:
3585: struct _KTHREAD *CurrentThread;
3586:
3587: //
3588: // Cache policy, PTE field aligned, as read from the processor configuration
3589: // register at startup.
3590: //
3591:
3592: ULONG AlignedCachePolicy;
3593:
3594: //
3595: // Spare cell.
3596: //
3597:
3598: ULONG Spare0;
3599:
3600: //
3601: // Space reserved for the system.
3602: //
3603:
3604: ULONG SystemReserved[16];
3605:
3606: //
3607: // Space reserved for the HAL
3608: //
3609:
3610: ULONG HalReserved[16];
3611:
3612: //
3613: // End of the architecturally defined section of the PCR. This section
3614: // may be directly addressed by vendor/platform specific HAL code and will
3615: // not change from version to version of NT.
3616: //
3617: } KPCR, *PKPCR;
3618: //
3619: // The following flags control the contents of the CONTEXT structure.
3620: //
3621:
3622: #define CONTEXT_R4000 0x00010000 // r4000 context
3623:
3624: #define CONTEXT_CONTROL (CONTEXT_R4000 | 0x00000001L)
3625: #define CONTEXT_FLOATING_POINT (CONTEXT_R4000 | 0x00000002L)
3626: #define CONTEXT_INTEGER (CONTEXT_R4000 | 0x00000004L)
3627:
3628: #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
3629:
3630: //
3631: // Context Frame
3632: //
3633: // N.B. This frame must be exactly a multiple of 16 bytes in length.
3634: //
3635: // This frame has a several purposes: 1) it is used as an argument to
3636: // NtContinue, 2) it is used to constuct a call frame for APC delivery,
3637: // 3) it is used to construct a call frame for exception dispatching
3638: // in user mode, and 4) it is used in the user level thread creation
3639: // routines.
3640: //
3641: // The layout of the record conforms to a standard call frame.
3642: //
3643:
3644: typedef struct _CONTEXT {
3645:
3646: //
3647: // This section is always present and is used as an argument build
3648: // area.
3649: //
3650:
3651: ULONG Argument[4];
3652:
3653: //
3654: // This section is specified/returned if the ContextFlags word contains
3655: // the flag CONTEXT_FLOATING_POINT.
3656: //
3657:
3658: ULONG FltF0;
3659: ULONG FltF1;
3660: ULONG FltF2;
3661: ULONG FltF3;
3662: ULONG FltF4;
3663: ULONG FltF5;
3664: ULONG FltF6;
3665: ULONG FltF7;
3666: ULONG FltF8;
3667: ULONG FltF9;
3668: ULONG FltF10;
3669: ULONG FltF11;
3670: ULONG FltF12;
3671: ULONG FltF13;
3672: ULONG FltF14;
3673: ULONG FltF15;
3674: ULONG FltF16;
3675: ULONG FltF17;
3676: ULONG FltF18;
3677: ULONG FltF19;
3678: ULONG FltF20;
3679: ULONG FltF21;
3680: ULONG FltF22;
3681: ULONG FltF23;
3682: ULONG FltF24;
3683: ULONG FltF25;
3684: ULONG FltF26;
3685: ULONG FltF27;
3686: ULONG FltF28;
3687: ULONG FltF29;
3688: ULONG FltF30;
3689: ULONG FltF31;
3690:
3691: //
3692: // This section is specified/returned if the ContextFlags word contains
3693: // the flag CONTEXT_INTEGER.
3694: //
3695: // N.B. The registers gp, sp, and ra are defined in this section, but are
3696: // considered part of the control context rather than part of the integer
3697: // context.
3698: //
3699: // N.B. Register zero is not stored in the frame.
3700: //
3701:
3702: ULONG IntZero;
3703: ULONG IntAt;
3704: ULONG IntV0;
3705: ULONG IntV1;
3706: ULONG IntA0;
3707: ULONG IntA1;
3708: ULONG IntA2;
3709: ULONG IntA3;
3710: ULONG IntT0;
3711: ULONG IntT1;
3712: ULONG IntT2;
3713: ULONG IntT3;
3714: ULONG IntT4;
3715: ULONG IntT5;
3716: ULONG IntT6;
3717: ULONG IntT7;
3718: ULONG IntS0;
3719: ULONG IntS1;
3720: ULONG IntS2;
3721: ULONG IntS3;
3722: ULONG IntS4;
3723: ULONG IntS5;
3724: ULONG IntS6;
3725: ULONG IntS7;
3726: ULONG IntT8;
3727: ULONG IntT9;
3728: ULONG IntK0;
3729: ULONG IntK1;
3730: ULONG IntGp;
3731: ULONG IntSp;
3732: ULONG IntS8;
3733: ULONG IntRa;
3734: ULONG IntLo;
3735: ULONG IntHi;
3736:
3737: //
3738: // This section is specified/returned if the ContextFlags word contains
3739: // the flag CONTEXT_FLOATING_POINT.
3740: //
3741:
3742: ULONG Fsr;
3743:
3744: //
3745: // This section is specified/returned if the ContextFlags word contains
3746: // the flag CONTEXT_CONTROL.
3747: //
3748: // N.B. The registers gp, sp, and ra are defined in the integer section,
3749: // but are considered part of the control context rather than part of
3750: // the integer context.
3751: //
3752:
3753: ULONG Fir;
3754: ULONG Psr;
3755:
3756: //
3757: // The flags values within this flag control the contents of
3758: // a CONTEXT record.
3759: //
3760: // If the context record is used as an input parameter, then
3761: // for each portion of the context record controlled by a flag
3762: // whose value is set, it is assumed that that portion of the
3763: // context record contains valid context. If the context record
3764: // is being used to modify a thread's context, then only that
3765: // portion of the threads context will be modified.
3766: //
3767: // If the context record is used as an IN OUT parameter to capture
3768: // the context of a thread, then only those portions of the thread's
3769: // context corresponding to set flags will be returned.
3770: //
3771: // The context record is never used as an OUT only parameter.
3772: //
3773:
3774: ULONG ContextFlags;
3775:
3776: ULONG Fill[2];
3777: } CONTEXT, *PCONTEXT;
3778:
3779: #endif // defined(_MIPS_)
3780: #ifdef _ALPHA_
3781: //
3782: // The following flags control the contents of the CONTEXT structure.
3783: //
3784:
3785: #define CONTEXT_PORTABLE_32BIT 0x00100000
3786: #define CONTEXT_ALPHA 0x00020000
3787:
3788: #define CONTEXT_CONTROL (CONTEXT_ALPHA | 0x00000001L)
3789: #define CONTEXT_FLOATING_POINT (CONTEXT_ALPHA | 0x00000002L)
3790: #define CONTEXT_INTEGER (CONTEXT_ALPHA | 0x00000004L)
3791:
3792: #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
3793:
3794: #ifndef _PORTABLE_32BIT_CONTEXT
3795:
3796: //
3797: // Context Frame
3798: //
3799: // This frame has a several purposes: 1) it is used as an argument to
3800: // NtContinue, 2) it is used to construct a call frame for APC delivery,
3801: // 3) it is used to construct a call frame for exception dispatching
3802: // in user mode, 4) it is used in the user level thread creation
3803: // routines, and 5) it is used to to pass thread state to debuggers.
3804: //
3805: // N.B. Because this record is used as a call frame, it must be EXACTLY
3806: // a multiple of 16 bytes in length.
3807: //
3808: // There are two variations of the context structure. This is the real one.
3809: //
3810:
3811: typedef struct _CONTEXT {
3812:
3813: //
3814: // This section is specified/returned if the ContextFlags word contains
3815: // the flag CONTEXT_FLOATING_POINT.
3816: //
3817:
3818: ULONGLONG FltF0;
3819: ULONGLONG FltF1;
3820: ULONGLONG FltF2;
3821: ULONGLONG FltF3;
3822: ULONGLONG FltF4;
3823: ULONGLONG FltF5;
3824: ULONGLONG FltF6;
3825: ULONGLONG FltF7;
3826: ULONGLONG FltF8;
3827: ULONGLONG FltF9;
3828: ULONGLONG FltF10;
3829: ULONGLONG FltF11;
3830: ULONGLONG FltF12;
3831: ULONGLONG FltF13;
3832: ULONGLONG FltF14;
3833: ULONGLONG FltF15;
3834: ULONGLONG FltF16;
3835: ULONGLONG FltF17;
3836: ULONGLONG FltF18;
3837: ULONGLONG FltF19;
3838: ULONGLONG FltF20;
3839: ULONGLONG FltF21;
3840: ULONGLONG FltF22;
3841: ULONGLONG FltF23;
3842: ULONGLONG FltF24;
3843: ULONGLONG FltF25;
3844: ULONGLONG FltF26;
3845: ULONGLONG FltF27;
3846: ULONGLONG FltF28;
3847: ULONGLONG FltF29;
3848: ULONGLONG FltF30;
3849: ULONGLONG FltF31;
3850:
3851: //
3852: // This section is specified/returned if the ContextFlags word contains
3853: // the flag CONTEXT_INTEGER.
3854: //
3855: // N.B. The registers gp, sp, and ra are defined in this section, but are
3856: // considered part of the control context rather than part of the integer
3857: // context.
3858: //
3859:
3860: ULONGLONG IntV0; // $0: return value register, v0
3861: ULONGLONG IntT0; // $1: temporary registers, t0 - t7
3862: ULONGLONG IntT1; // $2:
3863: ULONGLONG IntT2; // $3:
3864: ULONGLONG IntT3; // $4:
3865: ULONGLONG IntT4; // $5:
3866: ULONGLONG IntT5; // $6:
3867: ULONGLONG IntT6; // $7:
3868: ULONGLONG IntT7; // $8:
3869: ULONGLONG IntS0; // $9: nonvolatile registers, s0 - s5
3870: ULONGLONG IntS1; // $10:
3871: ULONGLONG IntS2; // $11:
3872: ULONGLONG IntS3; // $12:
3873: ULONGLONG IntS4; // $13:
3874: ULONGLONG IntS5; // $14:
3875: ULONGLONG IntFp; // $15: frame pointer register, fp/s6
3876: ULONGLONG IntA0; // $16: argument registers, a0 - a5
3877: ULONGLONG IntA1; // $17:
3878: ULONGLONG IntA2; // $18:
3879: ULONGLONG IntA3; // $19:
3880: ULONGLONG IntA4; // $20:
3881: ULONGLONG IntA5; // $21:
3882: ULONGLONG IntT8; // $22: temporary registers, t8 - t11
3883: ULONGLONG IntT9; // $23:
3884: ULONGLONG IntT10; // $24:
3885: ULONGLONG IntT11; // $25:
3886: ULONGLONG IntRa; // $26: return address register, ra
3887: ULONGLONG IntT12; // $27: temporary register, t12
3888: ULONGLONG IntAt; // $28: assembler temp register, at
3889: ULONGLONG IntGp; // $29: global pointer register, gp
3890: ULONGLONG IntSp; // $30: stack pointer register, sp
3891: ULONGLONG IntZero; // $31: zero register, zero
3892:
3893: //
3894: // This section is specified/returned if the ContextFlags word contains
3895: // the flag CONTEXT_FLOATING_POINT.
3896: //
3897:
3898: ULONGLONG Fpcr; // floating point control register
3899: ULONGLONG SoftFpcr; // software extension to FPCR
3900:
3901: //
3902: // This section is specified/returned if the ContextFlags word contains
3903: // the flag CONTEXT_CONTROL.
3904: //
3905: // N.B. The registers gp, sp, and ra are defined in the integer section,
3906: // but are considered part of the control context rather than part of
3907: // the integer context.
3908: //
3909:
3910: ULONGLONG Fir; // (fault instruction) continuation address
3911: ULONG Psr; // processor status
3912:
3913: //
3914: // The flags values within this flag control the contents of
3915: // a CONTEXT record.
3916: //
3917: // If the context record is used as an input parameter, then
3918: // for each portion of the context record controlled by a flag
3919: // whose value is set, it is assumed that that portion of the
3920: // context record contains valid context. If the context record
3921: // is being used to modify a thread's context, then only that
3922: // portion of the threads context will be modified.
3923: //
3924: // If the context record is used as an IN OUT parameter to capture
3925: // the context of a thread, then only those portions of the thread's
3926: // context corresponding to set flags will be returned.
3927: //
3928: // The context record is never used as an OUT only parameter.
3929: //
3930:
3931: ULONG ContextFlags;
3932: ULONG Fill[4]; // padding for 16-byte stack frame alignment
3933:
3934: } CONTEXT, *PCONTEXT;
3935:
3936: #else
3937:
3938: //
3939: // 32-bit Context Frame
3940: //
3941: // This alternate version of the Alpha context structure parallels that
3942: // of MIPS and IX86 in style for the first 64 entries: 32-bit machines
3943: // can operate on the fields, and a value declared as a pointer to an
3944: // array of int's can be used to index into the fields. This makes life
3945: // with windbg and ntsd vastly easier.
3946: //
3947: // There are two parts: the first contains the lower 32-bits of each
3948: // element in the 64-bit definition above. The second part contains
3949: // the upper 32-bits of each 64-bit element above.
3950: //
3951: // The names in the first part are identical to the 64-bit names.
3952: // The second part names are prefixed with "High".
3953: //
3954: // 1st half: at 32 bits each, (containing the low parts of 64-bit values)
3955: // 32 floats, 32 ints, fpcrs, fir, psr, contextflags
3956: // 2nd half: at 32 bits each
3957: // 32 floats, 32 ints, fpcrs, fir, fill
3958: //
3959: // There is no external support for the 32-bit version of the context
3960: // structure. It is only used internally by windbg and ntsd.
3961: //
3962: // This structure must be the same size as the 64-bit version above.
3963: //
3964:
3965: typedef struct _CONTEXT {
3966:
3967: ULONG FltF0;
3968: ULONG FltF1;
3969: ULONG FltF2;
3970: ULONG FltF3;
3971: ULONG FltF4;
3972: ULONG FltF5;
3973: ULONG FltF6;
3974: ULONG FltF7;
3975: ULONG FltF8;
3976: ULONG FltF9;
3977: ULONG FltF10;
3978: ULONG FltF11;
3979: ULONG FltF12;
3980: ULONG FltF13;
3981: ULONG FltF14;
3982: ULONG FltF15;
3983: ULONG FltF16;
3984: ULONG FltF17;
3985: ULONG FltF18;
3986: ULONG FltF19;
3987: ULONG FltF20;
3988: ULONG FltF21;
3989: ULONG FltF22;
3990: ULONG FltF23;
3991: ULONG FltF24;
3992: ULONG FltF25;
3993: ULONG FltF26;
3994: ULONG FltF27;
3995: ULONG FltF28;
3996: ULONG FltF29;
3997: ULONG FltF30;
3998: ULONG FltF31;
3999:
4000: ULONG IntV0; // $0: return value register, v0
4001: ULONG IntT0; // $1: temporary registers, t0 - t7
4002: ULONG IntT1; // $2:
4003: ULONG IntT2; // $3:
4004: ULONG IntT3; // $4:
4005: ULONG IntT4; // $5:
4006: ULONG IntT5; // $6:
4007: ULONG IntT6; // $7:
4008: ULONG IntT7; // $8:
4009: ULONG IntS0; // $9: nonvolatile registers, s0 - s5
4010: ULONG IntS1; // $10:
4011: ULONG IntS2; // $11:
4012: ULONG IntS3; // $12:
4013: ULONG IntS4; // $13:
4014: ULONG IntS5; // $14:
4015: ULONG IntFp; // $15: frame pointer register, fp/s6
4016: ULONG IntA0; // $16: argument registers, a0 - a5
4017: ULONG IntA1; // $17:
4018: ULONG IntA2; // $18:
4019: ULONG IntA3; // $19:
4020: ULONG IntA4; // $20:
4021: ULONG IntA5; // $21:
4022: ULONG IntT8; // $22: temporary registers, t8 - t11
4023: ULONG IntT9; // $23:
4024: ULONG IntT10; // $24:
4025: ULONG IntT11; // $25:
4026: ULONG IntRa; // $26: return address register, ra
4027: ULONG IntT12; // $27: temporary register, t12
4028: ULONG IntAt; // $28: assembler temp register, at
4029: ULONG IntGp; // $29: global pointer register, gp
4030: ULONG IntSp; // $30: stack pointer register, sp
4031: ULONG IntZero; // $31: zero register, zero
4032:
4033: ULONG Fpcr; // floating point control register
4034: ULONG SoftFpcr; // software extension to FPCR
4035:
4036: ULONG Fir; // (fault instruction) continuation address
4037:
4038: ULONG Psr; // processor status
4039: ULONG ContextFlags;
4040:
4041: //
4042: // Beginning of the "second half".
4043: // The name "High" parallels the HighPart of a LargeInteger.
4044: //
4045:
4046: ULONG HighFltF0;
4047: ULONG HighFltF1;
4048: ULONG HighFltF2;
4049: ULONG HighFltF3;
4050: ULONG HighFltF4;
4051: ULONG HighFltF5;
4052: ULONG HighFltF6;
4053: ULONG HighFltF7;
4054: ULONG HighFltF8;
4055: ULONG HighFltF9;
4056: ULONG HighFltF10;
4057: ULONG HighFltF11;
4058: ULONG HighFltF12;
4059: ULONG HighFltF13;
4060: ULONG HighFltF14;
4061: ULONG HighFltF15;
4062: ULONG HighFltF16;
4063: ULONG HighFltF17;
4064: ULONG HighFltF18;
4065: ULONG HighFltF19;
4066: ULONG HighFltF20;
4067: ULONG HighFltF21;
4068: ULONG HighFltF22;
4069: ULONG HighFltF23;
4070: ULONG HighFltF24;
4071: ULONG HighFltF25;
4072: ULONG HighFltF26;
4073: ULONG HighFltF27;
4074: ULONG HighFltF28;
4075: ULONG HighFltF29;
4076: ULONG HighFltF30;
4077: ULONG HighFltF31;
4078:
4079: ULONG HighIntV0; // $0: return value register, v0
4080: ULONG HighIntT0; // $1: temporary registers, t0 - t7
4081: ULONG HighIntT1; // $2:
4082: ULONG HighIntT2; // $3:
4083: ULONG HighIntT3; // $4:
4084: ULONG HighIntT4; // $5:
4085: ULONG HighIntT5; // $6:
4086: ULONG HighIntT6; // $7:
4087: ULONG HighIntT7; // $8:
4088: ULONG HighIntS0; // $9: nonvolatile registers, s0 - s5
4089: ULONG HighIntS1; // $10:
4090: ULONG HighIntS2; // $11:
4091: ULONG HighIntS3; // $12:
4092: ULONG HighIntS4; // $13:
4093: ULONG HighIntS5; // $14:
4094: ULONG HighIntFp; // $15: frame pointer register, fp/s6
4095: ULONG HighIntA0; // $16: argument registers, a0 - a5
4096: ULONG HighIntA1; // $17:
4097: ULONG HighIntA2; // $18:
4098: ULONG HighIntA3; // $19:
4099: ULONG HighIntA4; // $20:
4100: ULONG HighIntA5; // $21:
4101: ULONG HighIntT8; // $22: temporary registers, t8 - t11
4102: ULONG HighIntT9; // $23:
4103: ULONG HighIntT10; // $24:
4104: ULONG HighIntT11; // $25:
4105: ULONG HighIntRa; // $26: return address register, ra
4106: ULONG HighIntT12; // $27: temporary register, t12
4107: ULONG HighIntAt; // $28: assembler temp register, at
4108: ULONG HighIntGp; // $29: global pointer register, gp
4109: ULONG HighIntSp; // $30: stack pointer register, sp
4110: ULONG HighIntZero; // $31: zero register, zero
4111:
4112: ULONG HighFpcr; // floating point control register
4113: ULONG HighSoftFpcr; // software extension to FPCR
4114: ULONG HighFir; // processor status
4115:
4116: double DoNotUseThisField; // to force quadword structure alignment
4117: ULONG HighFill[2]; // padding for 16-byte stack frame alignment
4118:
4119: } CONTEXT, *PCONTEXT;
4120:
4121: //
4122: // These should name the fields in the _PORTABLE_32BIT structure
4123: // that overlay the Psr and ContextFlags in the normal structure.
4124: //
4125:
4126: #define _QUAD_PSR_OFFSET HighSoftFpcr
4127: #define _QUAD_FLAGS_OFFSET HighFir
4128:
4129: #endif // _PORTABLE_32BIT_CONTEXT
4130:
4131: //
4132: // I/O space read and write macros.
4133: //
4134: // These have to be actual functions on Alpha, because we need
4135: // to shift the VA and OR in the BYTE ENABLES.
4136: //
4137: // These can become INLINEs if we require that ALL Alpha systems shift
4138: // the same number of bits and have the SAME byte enables.
4139: //
4140: // The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space?
4141: //
4142: // The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space?
4143: //
4144:
4145: UCHAR
4146: READ_REGISTER_UCHAR(
4147: PUCHAR Register
4148: );
4149:
4150: USHORT
4151: READ_REGISTER_USHORT(
4152: PUSHORT Register
4153: );
4154:
4155: ULONG
4156: READ_REGISTER_ULONG(
4157: PULONG Register
4158: );
4159:
4160: VOID
4161: READ_REGISTER_BUFFER_UCHAR(
4162: PUCHAR Register,
4163: PUCHAR Buffer,
4164: ULONG Count
4165: );
4166:
4167: VOID
4168: READ_REGISTER_BUFFER_USHORT(
4169: PUSHORT Register,
4170: PUSHORT Buffer,
4171: ULONG Count
4172: );
4173:
4174: VOID
4175: READ_REGISTER_BUFFER_ULONG(
4176: PULONG Register,
4177: PULONG Buffer,
4178: ULONG Count
4179: );
4180:
4181:
4182: VOID
4183: WRITE_REGISTER_UCHAR(
4184: PUCHAR Register,
4185: UCHAR Value
4186: );
4187:
4188: VOID
4189: WRITE_REGISTER_USHORT(
4190: PUSHORT Register,
4191: USHORT Value
4192: );
4193:
4194: VOID
4195: WRITE_REGISTER_ULONG(
4196: PULONG Register,
4197: ULONG Value
4198: );
4199:
4200: VOID
4201: WRITE_REGISTER_BUFFER_UCHAR(
4202: PUCHAR Register,
4203: PUCHAR Buffer,
4204: ULONG Count
4205: );
4206:
4207: VOID
4208: WRITE_REGISTER_BUFFER_USHORT(
4209: PUSHORT Register,
4210: PUSHORT Buffer,
4211: ULONG Count
4212: );
4213:
4214: VOID
4215: WRITE_REGISTER_BUFFER_ULONG(
4216: PULONG Register,
4217: PULONG Buffer,
4218: ULONG Count
4219: );
4220:
4221: UCHAR
4222: READ_PORT_UCHAR(
4223: PUCHAR Port
4224: );
4225:
4226: USHORT
4227: READ_PORT_USHORT(
4228: PUSHORT Port
4229: );
4230:
4231: ULONG
4232: READ_PORT_ULONG(
4233: PULONG Port
4234: );
4235:
4236: VOID
4237: READ_PORT_BUFFER_UCHAR(
4238: PUCHAR Port,
4239: PUCHAR Buffer,
4240: ULONG Count
4241: );
4242:
4243: VOID
4244: READ_PORT_BUFFER_USHORT(
4245: PUSHORT Port,
4246: PUSHORT Buffer,
4247: ULONG Count
4248: );
4249:
4250: VOID
4251: READ_PORT_BUFFER_ULONG(
4252: PULONG Port,
4253: PULONG Buffer,
4254: ULONG Count
4255: );
4256:
4257: VOID
4258: WRITE_PORT_UCHAR(
4259: PUCHAR Port,
4260: UCHAR Value
4261: );
4262:
4263: VOID
4264: WRITE_PORT_USHORT(
4265: PUSHORT Port,
4266: USHORT Value
4267: );
4268:
4269: VOID
4270: WRITE_PORT_ULONG(
4271: PULONG Port,
4272: ULONG Value
4273: );
4274:
4275: VOID
4276: WRITE_PORT_BUFFER_UCHAR(
4277: PUCHAR Port,
4278: PUCHAR Buffer,
4279: ULONG Count
4280: );
4281:
4282: VOID
4283: WRITE_PORT_BUFFER_USHORT(
4284: PUSHORT Port,
4285: PUSHORT Buffer,
4286: ULONG Count
4287: );
4288:
4289: VOID
4290: WRITE_PORT_BUFFER_ULONG(
4291: PULONG Port,
4292: PULONG Buffer,
4293: ULONG Count
4294: );
4295:
4296: #endif // _ALPHA_ // ntddk nthal
4297:
4298: // begin_winnt
4299: //
4300: // Predefined Value Types.
4301: //
4302:
4303: #define REG_NONE ( 0 ) // No value type
4304: #define REG_SZ ( 1 ) // Unicode nul terminated string
4305: #define REG_EXPAND_SZ ( 2 ) // Unicode nul terminated string
4306: // (with environment variable references)
4307: #define REG_BINARY ( 3 ) // Free form binary
4308: #define REG_DWORD ( 4 ) // 32-bit number
4309: #define REG_DWORD_LITTLE_ENDIAN ( 4 ) // 32-bit number (same as REG_DWORD)
4310: #define REG_DWORD_BIG_ENDIAN ( 5 ) // 32-bit number
4311: #define REG_LINK ( 6 ) // Symbolic Link (unicode)
4312: #define REG_MULTI_SZ ( 7 ) // Multiple Unicode strings
4313: #define REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map
4314: #define REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description
4315:
4316: //
4317: // Service Types (Bit Mask)
4318: //
4319: #define SERVICE_KERNEL_DRIVER 0x00000001
4320: #define SERVICE_FILE_SYSTEM_DRIVER 0x00000002
4321: #define SERVICE_ADAPTER 0x00000004
4322: #define SERVICE_RECOGNIZER_DRIVER 0x00000008
4323:
4324: #define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER | \
4325: SERVICE_FILE_SYSTEM_DRIVER | \
4326: SERVICE_RECOGNIZER_DRIVER)
4327:
4328: #define SERVICE_WIN32_OWN_PROCESS 0x00000010
4329: #define SERVICE_WIN32_SHARE_PROCESS 0x00000020
4330: #define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS | \
4331: SERVICE_WIN32_SHARE_PROCESS)
4332:
4333: #define SERVICE_TYPE_ALL (SERVICE_WIN32 | \
4334: SERVICE_ADAPTER | \
4335: SERVICE_DRIVER)
4336:
4337: //
4338: // Start Type
4339: //
4340:
4341: #define SERVICE_BOOT_START 0x00000000
4342: #define SERVICE_SYSTEM_START 0x00000001
4343: #define SERVICE_AUTO_START 0x00000002
4344: #define SERVICE_DEMAND_START 0x00000003
4345: #define SERVICE_DISABLED 0x00000004
4346:
4347: //
4348: // Error control type
4349: //
4350: #define SERVICE_ERROR_IGNORE 0x00000000
4351: #define SERVICE_ERROR_NORMAL 0x00000001
4352: #define SERVICE_ERROR_SEVERE 0x00000002
4353: #define SERVICE_ERROR_CRITICAL 0x00000003
4354:
4355: //
4356: //
4357: // Define the registry driver node enumerations
4358: //
4359:
4360: typedef enum _CM_SERVICE_NODE_TYPE {
4361: DriverType = SERVICE_KERNEL_DRIVER,
4362: FileSystemType = SERVICE_FILE_SYSTEM_DRIVER,
4363: Win32ServiceOwnProcess = SERVICE_WIN32_OWN_PROCESS,
4364: Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS,
4365: AdapterType = SERVICE_ADAPTER,
4366: RecognizerType = SERVICE_RECOGNIZER_DRIVER
4367: } SERVICE_NODE_TYPE;
4368:
4369: typedef enum _CM_SERVICE_LOAD_TYPE {
4370: BootLoad = SERVICE_BOOT_START,
4371: SystemLoad = SERVICE_SYSTEM_START,
4372: AutoLoad = SERVICE_AUTO_START,
4373: DemandLoad = SERVICE_DEMAND_START,
4374: DisableLoad = SERVICE_DISABLED
4375: } SERVICE_LOAD_TYPE;
4376:
4377: typedef enum _CM_ERROR_CONTROL_TYPE {
4378: IgnoreError = SERVICE_ERROR_IGNORE,
4379: NormalError = SERVICE_ERROR_NORMAL,
4380: SevereError = SERVICE_ERROR_SEVERE,
4381: CriticalError = SERVICE_ERROR_CRITICAL
4382: } SERVICE_ERROR_TYPE;
4383:
4384: // end_winnt
4385:
4386: //
4387: // Resource List definitions
4388: //
4389:
4390: //
4391: // Defines the Type in the RESOURCE_DESCRIPTOR
4392: //
4393:
4394: typedef enum _CM_RESOURCE_TYPE {
4395: CmResourceTypeNull = 0, // Reserved
4396: CmResourceTypePort,
4397: CmResourceTypeInterrupt,
4398: CmResourceTypeMemory,
4399: CmResourceTypeDma,
4400: CmResourceTypeDeviceSpecific
4401: } CM_RESOURCE_TYPE;
4402:
4403: //
4404: // Defines the ShareDisposition in the RESOURCE_DESCRIPTOR
4405: //
4406:
4407: typedef enum _CM_SHARE_DISPOSITION {
4408: CmResourceShareUndetermined = 0, // Reserved
4409: CmResourceShareDeviceExclusive,
4410: CmResourceShareDriverExclusive,
4411: CmResourceShareShared
4412: } CM_SHARE_DISPOSITION;
4413:
4414: //
4415: // Define the bit masks for Flags when type is CmResourceTypeInterrupt
4416: //
4417:
4418: #define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0
4419: #define CM_RESOURCE_INTERRUPT_LATCHED 1
4420:
4421: //
4422: // Define the bit masks for Flags when type is CmResourceTypeInterrupt
4423: //
4424:
4425: #define CM_RESOURCE_MEMORY_READ_WRITE 0
4426: #define CM_RESOURCE_MEMORY_READ_ONLY 1
4427: #define CM_RESOURCE_MEMORY_WRITE_ONLY 2
4428:
4429: //
4430: // Define the bit masks for Flags when type is CmResourceTypePort
4431: //
4432:
4433: #define CM_RESOURCE_PORT_MEMORY 0
4434: #define CM_RESOURCE_PORT_IO 1
4435:
4436: //
4437: // This structure defines one type of resource used by a driver.
4438: //
4439: // There can only be *1* DeviceSpecificData block. It must be located at
4440: // the end of all resource descriptors in a full descriptor block.
4441: //
4442:
4443: //
4444: // BUGBUG Make sure alignment is made properly by compiler; otherwise move
4445: // flags back to the top of the structure (common to all members of the
4446: // union).
4447: //
4448:
4449: #pragma pack(4)
4450: typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
4451: UCHAR Type;
4452: UCHAR ShareDisposition;
4453: USHORT Flags;
4454: union {
4455:
4456: //
4457: // Range of port numbers, inclusive. These are physical, bus
4458: // relative. The value should be the same as the one passed to
4459: // HalTranslateBusAddress().
4460: //
4461:
4462: struct {
4463: PHYSICAL_ADDRESS Start;
4464: ULONG Length;
4465: } Port;
4466:
4467: //
4468: // IRQL and vector. Should be same values as were passed to
4469: // HalGetInterruptVector().
4470: //
4471:
4472: struct {
4473: ULONG Level;
4474: ULONG Vector;
4475: ULONG Affinity;
4476: } Interrupt;
4477:
4478: //
4479: // Range of memory addresses, inclusive. These are physical, bus
4480: // relative. The value should be the same as the one passed to
4481: // HalTranslateBusAddress().
4482: //
4483:
4484: struct {
4485: PHYSICAL_ADDRESS Start; // 64 bit physical addresses.
4486: ULONG Length;
4487: } Memory;
4488:
4489: //
4490: // Physical DMA channel.
4491: //
4492:
4493: struct {
4494: ULONG Channel;
4495: ULONG Port;
4496: ULONG Reserved1;
4497: } Dma;
4498:
4499: //
4500: // Device Specific information defined by the driver.
4501: // The DataSize field indicates the size of the data in bytes. The
4502: // data is located immediately after the DeviceSpecificData field in
4503: // the structure.
4504: //
4505:
4506: struct {
4507: ULONG DataSize;
4508: ULONG Reserved1;
4509: ULONG Reserved2;
4510: } DeviceSpecificData;
4511: } u;
4512: } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
4513: #pragma pack()
4514:
4515: //
4516: // A Partial Resource List is what can be found in the ARC firmware
4517: // or will be generated by ntdetect.com.
4518: // The configuration manager will transform this structure into a Full
4519: // resource descriptor when it is about to store it in the regsitry.
4520: //
4521: // Note: There must a be a convention to the order of fields of same type,
4522: // (defined on a device by device basis) so that the fields can make sense
4523: // to a driver (i.e. when multiple memory ranges are necessary).
4524: //
4525:
4526: typedef struct _CM_PARTIAL_RESOURCE_LIST {
4527: USHORT Version;
4528: USHORT Revision;
4529: ULONG Count;
4530: CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
4531: } CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
4532:
4533: //
4534: // A Full Resource Descriptor is what can be found in the registry.
4535: // This is what will be returned to a driver when it queries the registry
4536: // to get device information; it will be stored under a key in the hardware
4537: // description tree.
4538: //
4539: // Note: The BusNumber and Type are redundant information, but we will keep
4540: // it since it allows the driver _not_ to append it when it is creating
4541: // a resource list which could possibly span multiple buses.
4542: //
4543: // Note2: There must a be a convention to the order of fields of same type,
4544: // (defined on a device by device basis) so that the fields can make sense
4545: // to a driver (i.e. when multiple memory ranges are necessary).
4546: //
4547:
4548: typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
4549: INTERFACE_TYPE InterfaceType;
4550: ULONG BusNumber;
4551: CM_PARTIAL_RESOURCE_LIST PartialResourceList;
4552: } CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
4553:
4554: //
4555: // The Resource list is what will be stored by the drivers into the
4556: // resource map via the IO API.
4557: //
4558:
4559: typedef struct _CM_RESOURCE_LIST {
4560: ULONG Count;
4561: CM_FULL_RESOURCE_DESCRIPTOR List[1];
4562: } CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
4563:
4564: //
4565: // Define the structures used to interpret configuration data of
4566: // \\Registry\machine\hardware\description tree.
4567: // Basically, these structures are used to interpret component
4568: // sepcific data.
4569: //
4570:
4571: //
4572: // Define DEVICE_FLAGS
4573: //
4574:
4575: typedef struct _DEVICE_FLAGS {
4576: ULONG Failed : 1;
4577: ULONG ReadOnly : 1;
4578: ULONG Removable : 1;
4579: ULONG ConsoleIn : 1;
4580: ULONG ConsoleOut : 1;
4581: ULONG Input : 1;
4582: ULONG Output : 1;
4583: } DEVICE_FLAGS, *PDEVICE_FLAGS;
4584:
4585: //
4586: // Define Component Information structure
4587: //
4588:
4589: typedef struct _CM_COMPONENT_INFORMATION {
4590: DEVICE_FLAGS Flags;
4591: ULONG Version;
4592: ULONG Key;
4593: ULONG AffinityMask;
4594: } CM_COMPONENT_INFORMATION, *PCM_COMPONENT_INFORMATION;
4595:
4596: //
4597: // The following structures are used to interpret x86
4598: // DeviceSpecificData of CM_PARTIAL_RESOURCE_DESCRIPTOR.
4599: // (Most of the structures are defined by BIOS. They are
4600: // not aligned on word (or dword) boundary.
4601: //
4602:
4603: //
4604: // Define the Rom Block structure
4605: //
4606:
4607: typedef struct _CM_ROM_BLOCK {
4608: ULONG Address;
4609: ULONG Size;
4610: } CM_ROM_BLOCK, *PCM_ROM_BLOCK;
4611:
4612: // begin_ntminiport
4613:
4614: #pragma pack(1)
4615:
4616: // end_ntminiport
4617:
4618: //
4619: // Define INT13 driver parameter block
4620: //
4621:
4622: typedef struct _CM_INT13_DRIVE_PARAMETER {
4623: USHORT DriveSelect;
4624: ULONG MaxCylinders;
4625: USHORT SectorsPerTrack;
4626: USHORT MaxHeads;
4627: USHORT NumberDrives;
4628: } CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER;
4629:
4630: // begin_ntminiport
4631:
4632: //
4633: // Define Mca POS data block for slot
4634: //
4635:
4636: typedef struct _CM_MCA_POS_DATA {
4637: USHORT AdapterId;
4638: UCHAR PosData1;
4639: UCHAR PosData2;
4640: UCHAR PosData3;
4641: UCHAR PosData4;
4642: } CM_MCA_POS_DATA, *PCM_MCA_POS_DATA;
4643:
4644: //
4645: // Memory configuration of eisa data block structure
4646: //
4647:
4648: typedef struct _EISA_MEMORY_TYPE {
4649: UCHAR ReadWrite: 1;
4650: UCHAR Cached : 1;
4651: UCHAR Reserved0 :1;
4652: UCHAR Type:2;
4653: UCHAR Shared:1;
4654: UCHAR Reserved1 :1;
4655: UCHAR MoreEntries : 1;
4656: } EISA_MEMORY_TYPE, *PEISA_MEMORY_TYPE;
4657:
4658: typedef struct _EISA_MEMORY_CONFIGURATION {
4659: EISA_MEMORY_TYPE ConfigurationByte;
4660: UCHAR DataSize;
4661: USHORT AddressLowWord;
4662: UCHAR AddressHighByte;
4663: USHORT MemorySize;
4664: } EISA_MEMORY_CONFIGURATION, *PEISA_MEMORY_CONFIGURATION;
4665:
4666:
4667: //
4668: // Interrupt configurationn of eisa data block structure
4669: //
4670:
4671: typedef struct _EISA_IRQ_DESCRIPTOR {
4672: UCHAR Interrupt : 4;
4673: UCHAR Reserved :1;
4674: UCHAR LevelTriggered :1;
4675: UCHAR Shared : 1;
4676: UCHAR MoreEntries : 1;
4677: } EISA_IRQ_DESCRIPTOR, *PEISA_IRQ_DESCRIPTOR;
4678:
4679: typedef struct _EISA_IRQ_CONFIGURATION {
4680: EISA_IRQ_DESCRIPTOR ConfigurationByte;
4681: UCHAR Reserved;
4682: } EISA_IRQ_CONFIGURATION, *PEISA_IRQ_CONFIGURATION;
4683:
4684:
4685: //
4686: // DMA description of eisa data block structure
4687: //
4688:
4689: typedef struct _DMA_CONFIGURATION_BYTE0 {
4690: UCHAR Channel : 3;
4691: UCHAR Reserved : 3;
4692: UCHAR Shared :1;
4693: UCHAR MoreEntries :1;
4694: } DMA_CONFIGURATION_BYTE0;
4695:
4696: typedef struct _DMA_CONFIGURATION_BYTE1 {
4697: UCHAR Reserved0 : 2;
4698: UCHAR TransferSize : 2;
4699: UCHAR Timing : 2;
4700: UCHAR Reserved1 : 2;
4701: } DMA_CONFIGURATION_BYTE1;
4702:
4703: typedef struct _EISA_DMA_CONFIGURATION {
4704: DMA_CONFIGURATION_BYTE0 ConfigurationByte0;
4705: DMA_CONFIGURATION_BYTE1 ConfigurationByte1;
4706: } EISA_DMA_CONFIGURATION, *PEISA_DMA_CONFIGURATION;
4707:
4708:
4709: //
4710: // Port description of eisa data block structure
4711: //
4712:
4713: typedef struct _EISA_PORT_DESCRIPTOR {
4714: UCHAR NumberPorts : 5;
4715: UCHAR Reserved :1;
4716: UCHAR Shared :1;
4717: UCHAR MoreEntries : 1;
4718: } EISA_PORT_DESCRIPTOR, *PEISA_PORT_DESCRIPTOR;
4719:
4720: typedef struct _EISA_PORT_CONFIGURATION {
4721: EISA_PORT_DESCRIPTOR Configuration;
4722: USHORT PortAddress;
4723: } EISA_PORT_CONFIGURATION, *PEISA_PORT_CONFIGURATION;
4724:
4725:
4726: //
4727: // Eisa slot information definition
4728: // N.B. This structure is different from the one defined
4729: // in ARC eisa addendum.
4730: //
4731:
4732: typedef struct _CM_EISA_SLOT_INFORMATION {
4733: UCHAR ReturnCode;
4734: UCHAR ReturnFlags;
4735: UCHAR MajorRevision;
4736: UCHAR MinorRevision;
4737: USHORT Checksum;
4738: UCHAR NumberFunctions;
4739: UCHAR FunctionInformation;
4740: ULONG CompressedId;
4741: } CM_EISA_SLOT_INFORMATION, *PCM_EISA_SLOT_INFORMATION;
4742:
4743:
4744: //
4745: // Eisa function information definition
4746: //
4747:
4748: typedef struct _CM_EISA_FUNCTION_INFORMATION {
4749: ULONG CompressedId;
4750: UCHAR IdSlotFlags1;
4751: UCHAR IdSlotFlags2;
4752: UCHAR MinorRevision;
4753: UCHAR MajorRevision;
4754: UCHAR Selections[26];
4755: UCHAR FunctionFlags;
4756: UCHAR TypeString[80];
4757: EISA_MEMORY_CONFIGURATION EisaMemory[9];
4758: EISA_IRQ_CONFIGURATION EisaIrq[7];
4759: EISA_DMA_CONFIGURATION EisaDma[4];
4760: EISA_PORT_CONFIGURATION EisaPort[20];
4761: UCHAR InitializationData[60];
4762: } CM_EISA_FUNCTION_INFORMATION, *PCM_EISA_FUNCTION_INFORMATION;
4763:
4764: #pragma pack()
4765:
4766: //
4767: // Masks for EISA function information
4768: //
4769:
4770: #define EISA_FUNCTION_ENABLED 0x80
4771: #define EISA_FREE_FORM_DATA 0x40
4772: #define EISA_HAS_PORT_INIT_ENTRY 0x20
4773: #define EISA_HAS_PORT_RANGE 0x10
4774: #define EISA_HAS_DMA_ENTRY 0x08
4775: #define EISA_HAS_IRQ_ENTRY 0x04
4776: #define EISA_HAS_MEMORY_ENTRY 0x02
4777: #define EISA_HAS_TYPE_ENTRY 0x01
4778: #define EISA_HAS_INFORMATION EISA_HAS_PORT_RANGE + \
4779: EISA_HAS_DMA_ENTRY + \
4780: EISA_HAS_IRQ_ENTRY + \
4781: EISA_HAS_MEMORY_ENTRY + \
4782: EISA_HAS_TYPE_ENTRY
4783:
4784: //
4785: // Masks for EISA memory configuration
4786: //
4787:
4788: #define EISA_MORE_ENTRIES 0x80
4789: #define EISA_SYSTEM_MEMORY 0x00
4790: #define EISA_MEMORY_TYPE_RAM 0x01
4791:
4792: //
4793: // Returned error code for EISA bios call
4794: //
4795:
4796: #define EISA_INVALID_SLOT 0x80
4797: #define EISA_INVALID_FUNCTION 0x81
4798: #define EISA_INVALID_CONFIGURATION 0x82
4799: #define EISA_EMPTY_SLOT 0x83
4800: #define EISA_INVALID_BIOS_CALL 0x86
4801:
4802: // end_ntminiport
4803:
4804: //
4805: // The following structures are used to interpret mips
4806: // DeviceSpecificData of CM_PARTIAL_RESOURCE_DESCRIPTOR.
4807: //
4808:
4809: //
4810: // Device data records for adapters.
4811: //
4812:
4813: //
4814: // The device data record for the Emulex SCSI controller.
4815: //
4816:
4817: typedef struct _CM_SCSI_DEVICE_DATA {
4818: USHORT Version;
4819: USHORT Revision;
4820: UCHAR HostIdentifier;
4821: } CM_SCSI_DEVICE_DATA, *PCM_SCSI_DEVICE_DATA;
4822:
4823: //
4824: // Device data records for controllers.
4825: //
4826:
4827: //
4828: // The device data record for the Video controller.
4829: //
4830:
4831: typedef struct _CM_VIDEO_DEVICE_DATA {
4832: USHORT Version;
4833: USHORT Revision;
4834: ULONG VideoClock;
4835: } CM_VIDEO_DEVICE_DATA, *PCM_VIDEO_DEVICE_DATA;
4836:
4837: //
4838: // The device data record for the SONIC network controller.
4839: //
4840:
4841: typedef struct _CM_SONIC_DEVICE_DATA {
4842: USHORT Version;
4843: USHORT Revision;
4844: USHORT DataConfigurationRegister;
4845: UCHAR EthernetAddress[8];
4846: } CM_SONIC_DEVICE_DATA, *PCM_SONIC_DEVICE_DATA;
4847:
4848: //
4849: // The device data record for the serial controller.
4850: //
4851:
4852: typedef struct _CM_SERIAL_DEVICE_DATA {
4853: USHORT Version;
4854: USHORT Revision;
4855: ULONG BaudClock;
4856: } CM_SERIAL_DEVICE_DATA, *PCM_SERIAL_DEVICE_DATA;
4857:
4858: //
4859: // Device data records for peripherals.
4860: //
4861:
4862: //
4863: // The device data record for the Monitor peripheral.
4864: //
4865:
4866: typedef struct _CM_MONITOR_DEVICE_DATA {
4867: USHORT Version;
4868: USHORT Revision;
4869: USHORT HorizontalScreenSize;
4870: USHORT VerticalScreenSize;
4871: USHORT HorizontalResolution;
4872: USHORT VerticalResolution;
4873: USHORT HorizontalDisplayTimeLow;
4874: USHORT HorizontalDisplayTime;
4875: USHORT HorizontalDisplayTimeHigh;
4876: USHORT HorizontalBackPorchLow;
4877: USHORT HorizontalBackPorch;
4878: USHORT HorizontalBackPorchHigh;
4879: USHORT HorizontalFrontPorchLow;
4880: USHORT HorizontalFrontPorch;
4881: USHORT HorizontalFrontPorchHigh;
4882: USHORT HorizontalSyncLow;
4883: USHORT HorizontalSync;
4884: USHORT HorizontalSyncHigh;
4885: USHORT VerticalBackPorchLow;
4886: USHORT VerticalBackPorch;
4887: USHORT VerticalBackPorchHigh;
4888: USHORT VerticalFrontPorchLow;
4889: USHORT VerticalFrontPorch;
4890: USHORT VerticalFrontPorchHigh;
4891: USHORT VerticalSyncLow;
4892: USHORT VerticalSync;
4893: USHORT VerticalSyncHigh;
4894: } CM_MONITOR_DEVICE_DATA, *PCM_MONITOR_DEVICE_DATA;
4895:
4896: //
4897: // The device data record for the Floppy peripheral.
4898: //
4899:
4900: typedef struct _CM_FLOPPY_DEVICE_DATA {
4901: USHORT Version;
4902: USHORT Revision;
4903: CHAR Size[8];
4904: ULONG MaxDensity;
4905: ULONG MountDensity;
4906: //
4907: // New data fields for version >= 2.0
4908: //
4909: UCHAR StepRateHeadUnloadTime;
4910: UCHAR HeadLoadTime;
4911: UCHAR MotorOffTime;
4912: UCHAR SectorLengthCode;
4913: UCHAR SectorPerTrack;
4914: UCHAR ReadWriteGapLength;
4915: UCHAR DataTransferLength;
4916: UCHAR FormatGapLength;
4917: UCHAR FormatFillCharacter;
4918: UCHAR HeadSettleTime;
4919: UCHAR MotorSettleTime;
4920: UCHAR MaximumTrackValue;
4921: UCHAR DataTransferRate;
4922: } CM_FLOPPY_DEVICE_DATA, *PCM_FLOPPY_DEVICE_DATA;
4923:
4924: //
4925: // The device data record for the Keyboard peripheral.
4926: // The KeyboardFlags is defined (by x86 BIOS INT 16h, function 02) as:
4927: // bit 7 : Insert on
4928: // bit 6 : Caps Lock on
4929: // bit 5 : Num Lock on
4930: // bit 4 : Scroll Lock on
4931: // bit 3 : Alt Key is down
4932: // bit 2 : Ctrl Key is down
4933: // bit 1 : Left shift key is down
4934: // bit 0 : Right shift key is down
4935: //
4936:
4937: typedef struct _CM_KEYBOARD_DEVICE_DATA {
4938: USHORT Version;
4939: USHORT Revision;
4940: UCHAR Type;
4941: UCHAR Subtype;
4942: USHORT KeyboardFlags;
4943: } CM_KEYBOARD_DEVICE_DATA, *PCM_KEYBOARD_DEVICE_DATA;
4944:
4945: //
4946: // Declaration of the structure for disk geometries
4947: //
4948:
4949: typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA {
4950: ULONG BytesPerSector;
4951: ULONG NumberOfCylinders;
4952: ULONG SectorsPerTrack;
4953: ULONG NumberOfHeads;
4954: } CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA;
4955:
4956: //
4957: // Exception flag definitions.
4958: //
4959:
4960: // begin_winnt
4961: #define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception
4962: // end_winnt
4963:
4964: //
4965: // Define maximum number of exception parameters.
4966: //
4967:
4968: // begin_winnt
4969: #define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
4970:
4971: //
4972: // Exception record definition.
4973: //
4974:
4975: typedef struct _EXCEPTION_RECORD {
4976: /*lint -e18 */ // Don't complain about different definitions
4977: NTSTATUS ExceptionCode;
4978: /*lint +e18 */ // Resume checking for different definitions
4979: ULONG ExceptionFlags;
4980: struct _EXCEPTION_RECORD *ExceptionRecord;
4981: PVOID ExceptionAddress;
4982: ULONG NumberParameters;
4983: ULONG ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
4984: } EXCEPTION_RECORD;
4985:
4986: typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;
4987:
4988: //
4989: // Typedef for pointer returned by exception_info()
4990: //
4991:
4992: typedef struct _EXCEPTION_POINTERS {
4993: PEXCEPTION_RECORD ExceptionRecord;
4994: PCONTEXT ContextRecord;
4995: } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
4996: // end_winnt
4997:
4998: //
4999: // Define configuration routine types.
5000: //
5001: // Configuration information.
5002: //
5003:
5004: typedef enum _CONFIGURATION_TYPE {
5005: ArcSystem,
5006: CentralProcessor,
5007: FloatingPointProcessor,
5008: PrimaryIcache,
5009: PrimaryDcache,
5010: SecondaryIcache,
5011: SecondaryDcache,
5012: SecondaryCache,
5013: EisaAdapter,
5014: TcAdapter,
5015: ScsiAdapter,
5016: DtiAdapter,
5017: MultiFunctionAdapter,
5018: DiskController,
5019: TapeController,
5020: CdromController,
5021: WormController,
5022: SerialController,
5023: NetworkController,
5024: DisplayController,
5025: ParallelController,
5026: PointerController,
5027: KeyboardController,
5028: AudioController,
5029: OtherController,
5030: DiskPeripheral,
5031: FloppyDiskPeripheral,
5032: TapePeripheral,
5033: ModemPeripheral,
5034: MonitorPeripheral,
5035: PrinterPeripheral,
5036: PointerPeripheral,
5037: KeyboardPeripheral,
5038: TerminalPeripheral,
5039: OtherPeripheral,
5040: LinePeripheral,
5041: NetworkPeripheral,
5042: SystemMemory,
5043: MaximumType
5044: } CONFIGURATION_TYPE, *PCONFIGURATION_TYPE;
5045:
5046:
5047: //
5048: // Interrupt modes.
5049: //
5050:
5051: typedef enum _KINTERRUPT_MODE {
5052: LevelSensitive,
5053: Latched
5054: } KINTERRUPT_MODE;
5055:
5056: //
5057: // Wait reasons
5058: //
5059:
5060: typedef enum _KWAIT_REASON {
5061: Executive,
5062: FreePage,
5063: PageIn,
5064: PoolAllocation,
5065: DelayExecution,
5066: Suspended,
5067: UserRequest,
5068: WrExecutive,
5069: WrFreePage,
5070: WrPageIn,
5071: WrPoolAllocation,
5072: WrDelayExecution,
5073: WrSuspended,
5074: WrUserRequest,
5075: WrEventPairHigh,
5076: WrEventPairLow,
5077: WrLpcReceive,
5078: WrLpcReply,
5079: WrVirtualMemory,
5080: WrPageOut,
5081: Spare1,
5082: Spare2,
5083: Spare3,
5084: Spare4,
5085: Spare5,
5086: Spare6,
5087: WrKernel,
5088: MaximumWaitReason
5089: } KWAIT_REASON;
5090:
5091: //
5092: // Common dispatcher object header
5093: //
5094:
5095: typedef struct _DISPATCHER_HEADER {
5096: CSHORT Type;
5097: CSHORT Size;
5098: LONG SignalState;
5099: LIST_ENTRY WaitListHead;
5100: } DISPATCHER_HEADER;
5101:
5102: //
5103: // Wait block
5104: //
5105:
5106: typedef struct _KWAIT_BLOCK {
5107: LIST_ENTRY WaitListEntry;
5108: struct _KTHREAD *Thread;
5109: PVOID Object;
5110: struct _KWAIT_BLOCK *NextWaitBlock;
5111: CSHORT WaitKey;
5112: WAIT_TYPE WaitType;
5113: } KWAIT_BLOCK, *PKWAIT_BLOCK;
5114:
5115: //
5116: // Thread start function
5117: //
5118:
5119: typedef
5120: VOID
5121: (*PKSTART_ROUTINE) (
5122: IN PVOID StartContext
5123: );
5124:
5125: //
5126: // Kernel object structure definitions
5127: //
5128:
5129: //
5130: // Device Queue object and entry
5131: //
5132:
5133: typedef struct _KDEVICE_QUEUE {
5134: CSHORT Type;
5135: CSHORT Size;
5136: LIST_ENTRY DeviceListHead;
5137: KSPIN_LOCK Lock;
5138: BOOLEAN Busy;
5139: } KDEVICE_QUEUE, *PKDEVICE_QUEUE;
5140:
5141: typedef struct _KDEVICE_QUEUE_ENTRY {
5142: LIST_ENTRY DeviceListEntry;
5143: ULONG SortKey;
5144: BOOLEAN Inserted;
5145: } KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY;
5146:
5147: //
5148: // Event object
5149: //
5150:
5151: typedef struct _KEVENT {
5152: DISPATCHER_HEADER Header;
5153: } KEVENT, *PKEVENT;
5154:
5155: //
5156: // Define the interrupt service function type and the empty struct
5157: // type.
5158: //
5159: typedef
5160: BOOLEAN
5161: (*PKSERVICE_ROUTINE) (
5162: IN struct _KINTERRUPT *Interrupt,
5163: IN PVOID ServiceContext
5164: );
5165: //
5166: // Mutex object
5167: //
5168:
5169: typedef struct _KMUTEX {
5170: DISPATCHER_HEADER Header;
5171: LIST_ENTRY MutexListEntry;
5172: struct _KTHREAD *OwnerThread;
5173: ULONG Level;
5174: } KMUTEX;
5175:
5176: typedef KMUTEX *PKMUTEX;
5177:
5178: //
5179: // Power notify object
5180: //
5181:
5182: typedef struct _KPOWER_NOTIFY {
5183: CSHORT Type;
5184: CSHORT Size;
5185: LIST_ENTRY NotifyListEntry;
5186: PKNOTIFY_ROUTINE NotifyRoutine;
5187: PVOID NotifyContext;
5188: BOOLEAN Inserted;
5189: } KPOWER_NOTIFY;
5190:
5191: typedef KPOWER_NOTIFY *PKPOWER_NOTIFY;
5192:
5193: //
5194: // Power status object
5195: //
5196:
5197: typedef struct _KPOWER_STATUS {
5198: CSHORT Type;
5199: CSHORT Size;
5200: LIST_ENTRY StatusListEntry;
5201: PBOOLEAN Status;
5202: BOOLEAN Inserted;
5203: } KPOWER_STATUS;
5204:
5205: typedef KPOWER_STATUS *PKPOWER_STATUS;
5206:
5207: //
5208: // Semaphore object
5209: //
5210:
5211: typedef struct _KSEMAPHORE {
5212: DISPATCHER_HEADER Header;
5213: LONG Limit;
5214: } KSEMAPHORE;
5215:
5216: typedef KSEMAPHORE *PKSEMAPHORE;
5217:
5218: //
5219: // Timer object
5220: //
5221:
5222: typedef struct _KTIMER {
5223: DISPATCHER_HEADER Header;
5224: ULARGE_INTEGER DueTime;
5225: LIST_ENTRY TimerListEntry;
5226: struct _KDPC *Dpc;
5227: BOOLEAN Inserted;
5228: } KTIMER;
5229:
5230: typedef KTIMER *PKTIMER;
5231:
5232: //
5233: // DPC object
5234: //
5235:
5236: VOID
5237: KeInitializeDpc (
5238: IN PKDPC Dpc,
5239: IN PKDEFERRED_ROUTINE DeferredRoutine,
5240: IN PVOID DeferredContext
5241: );
5242:
5243: BOOLEAN
5244: KeInsertQueueDpc (
5245: IN PKDPC Dpc,
5246: IN PVOID SystemArgument1,
5247: IN PVOID SystemArgument2
5248: );
5249:
5250: BOOLEAN
5251: KeRemoveQueueDpc (
5252: IN PKDPC Dpc
5253: );
5254:
5255: //
5256: // Device queue object
5257: //
5258:
5259: VOID
5260: KeInitializeDeviceQueue (
5261: IN PKDEVICE_QUEUE DeviceQueue
5262: );
5263:
5264: BOOLEAN
5265: KeInsertDeviceQueue (
5266: IN PKDEVICE_QUEUE DeviceQueue,
5267: IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
5268: );
5269:
5270: BOOLEAN
5271: KeInsertByKeyDeviceQueue (
5272: IN PKDEVICE_QUEUE DeviceQueue,
5273: IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
5274: IN ULONG SortKey
5275: );
5276:
5277: PKDEVICE_QUEUE_ENTRY
5278: KeRemoveDeviceQueue (
5279: IN PKDEVICE_QUEUE DeviceQueue
5280: );
5281:
5282: PKDEVICE_QUEUE_ENTRY
5283: KeRemoveByKeyDeviceQueue (
5284: IN PKDEVICE_QUEUE DeviceQueue,
5285: IN ULONG SortKey
5286: );
5287:
5288: BOOLEAN
5289: KeRemoveEntryDeviceQueue (
5290: IN PKDEVICE_QUEUE DeviceQueue,
5291: IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
5292: );
5293:
5294: BOOLEAN
5295: KeSynchronizeExecution (
5296: IN PKINTERRUPT Interrupt,
5297: IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
5298: IN PVOID SynchronizeContext
5299: );
5300:
5301: //
5302: // Kernel dispatcher object functions
5303: //
5304: // Event Object
5305: //
5306:
5307: VOID
5308: KeInitializeEvent (
5309: IN PKEVENT Event,
5310: IN EVENT_TYPE Type,
5311: IN BOOLEAN State
5312: );
5313:
5314: LONG
5315: KeReadStateEvent (
5316: IN PKEVENT Event
5317: );
5318:
5319: LONG
5320: KeResetEvent (
5321: IN PKEVENT Event
5322: );
5323:
5324: LONG
5325: KeSetEvent (
5326: IN PKEVENT Event,
5327: IN KPRIORITY Increment,
5328: IN BOOLEAN Wait
5329: );
5330:
5331: //
5332: // Mutex object
5333: //
5334:
5335: VOID
5336: KeInitializeMutex (
5337: IN PKMUTEX Mutex,
5338: IN ULONG Level
5339: );
5340:
5341: LONG
5342: KeReadStateMutex (
5343: IN PKMUTEX
5344: );
5345:
5346: LONG
5347: KeReleaseMutex (
5348: IN PKMUTEX Mutex,
5349: IN BOOLEAN Wait
5350: );
5351:
5352: //
5353: // Semaphore object
5354: //
5355:
5356: VOID
5357: KeInitializeSemaphore (
5358: IN PKSEMAPHORE Semaphore,
5359: IN LONG Count,
5360: IN LONG Limit
5361: );
5362:
5363: LONG
5364: KeReadStateSemaphore (
5365: IN PKSEMAPHORE Semaphore
5366: );
5367:
5368: LONG
5369: KeReleaseSemaphore (
5370: IN PKSEMAPHORE Semaphore,
5371: IN KPRIORITY Increment,
5372: IN LONG Adjustment,
5373: IN BOOLEAN Wait
5374: );
5375:
5376: NTSTATUS
5377: KeDelayExecutionThread (
5378: IN KPROCESSOR_MODE WaitMode,
5379: IN BOOLEAN Alertable,
5380: IN PLARGE_INTEGER Interval
5381: );
5382:
5383: LONG
5384: KeSetBasePriorityThread (
5385: IN PKTHREAD Thread,
5386: IN LONG Increment
5387: );
5388:
5389: KPRIORITY
5390: KeSetPriorityThread (
5391: IN PKTHREAD Thread,
5392: IN KPRIORITY Priority
5393: );
5394:
5395: //
5396: // Timer object
5397: //
5398:
5399: VOID
5400: KeInitializeTimer (
5401: IN PKTIMER Timer
5402: );
5403:
5404: BOOLEAN
5405: KeCancelTimer (
5406: IN PKTIMER
5407: );
5408:
5409: BOOLEAN
5410: KeReadStateTimer (
5411: PKTIMER Timer
5412: );
5413:
5414: BOOLEAN
5415: KeSetTimer (
5416: IN PKTIMER Timer,
5417: IN LARGE_INTEGER DueTime,
5418: IN PKDPC Dpc OPTIONAL
5419: );
5420:
5421:
5422: NTSTATUS
5423: KeWaitForMultipleObjects (
5424: IN ULONG Count,
5425: IN PVOID Object[],
5426: IN WAIT_TYPE WaitType,
5427: IN KWAIT_REASON WaitReason,
5428: IN KPROCESSOR_MODE WaitMode,
5429: IN BOOLEAN Alertable,
5430: IN PLARGE_INTEGER Timeout OPTIONAL,
5431: IN PKWAIT_BLOCK WaitBlockArray OPTIONAL
5432: );
5433:
5434: NTSTATUS
5435: KeWaitForSingleObject (
5436: IN PVOID Object,
5437: IN KWAIT_REASON WaitReason,
5438: IN KPROCESSOR_MODE WaitMode,
5439: IN BOOLEAN Alertable,
5440: IN PLARGE_INTEGER Timeout OPTIONAL
5441: );
5442:
5443: //
5444: // spin lock functions
5445: //
5446:
5447: VOID
5448: KeInitializeSpinLock (
5449: IN PKSPIN_LOCK SpinLock
5450: );
5451:
5452: VOID
5453: KeAcquireSpinLock (
5454: IN PKSPIN_LOCK SpinLock,
5455: OUT PKIRQL OldIrql
5456: );
5457:
5458: VOID
5459: KeReleaseSpinLock (
5460: IN PKSPIN_LOCK SpinLock,
5461: IN KIRQL NewIrql
5462: );
5463:
5464: VOID
5465: KeAcquireSpinLockAtDpcLevel (
5466: IN PKSPIN_LOCK SpinLock
5467: );
5468:
5469: VOID
5470: KeReleaseSpinLockFromDpcLevel (
5471: IN PKSPIN_LOCK SpinLock
5472: );
5473:
5474:
5475: //
5476: // Miscellaneous kernel functions
5477: //
5478:
5479: VOID
5480: KeBugCheck (
5481: IN ULONG BugCheckCode
5482: );
5483:
5484: VOID
5485: KeBugCheckEx(
5486: IN ULONG BugCheckCode,
5487: IN ULONG BugCheckParameter1,
5488: IN ULONG BugCheckParameter2,
5489: IN ULONG BugCheckParameter3,
5490: IN ULONG BugCheckParameter4
5491: );
5492:
5493: VOID
5494: KeEnterKernelDebugger (
5495: VOID
5496: );
5497:
5498:
5499: VOID
5500: KeQuerySystemTime (
5501: OUT PLARGE_INTEGER CurrentTime
5502: );
5503:
5504: VOID
5505: KeQueryTickCount (
5506: OUT PLARGE_INTEGER CurrentCount
5507: );
5508:
5509: ULONG
5510: KeQueryTimeIncrement (
5511: VOID
5512: );
5513:
5514: //
5515: // Define external data.
5516: //
5517:
5518: extern BOOLEAN KdDebuggerNotPresent;
5519: extern BOOLEAN KdDebuggerEnabled;
5520:
5521: //
5522: // Interlocked support routine definitions.
5523: //
5524:
5525: LARGE_INTEGER
5526: ExInterlockedAddLargeInteger (
5527: IN PLARGE_INTEGER Addend,
5528: IN LARGE_INTEGER Increment,
5529: IN PKSPIN_LOCK Lock
5530: );
5531:
5532: ULONG
5533: ExInterlockedAddUlong (
5534: IN PULONG Addend,
5535: IN ULONG Increment,
5536: IN PKSPIN_LOCK Lock
5537: );
5538:
5539: PLIST_ENTRY
5540: ExInterlockedInsertHeadList (
5541: IN PLIST_ENTRY ListHead,
5542: IN PLIST_ENTRY ListEntry,
5543: IN PKSPIN_LOCK Lock
5544: );
5545:
5546: PLIST_ENTRY
5547: ExInterlockedInsertTailList (
5548: IN PLIST_ENTRY ListHead,
5549: IN PLIST_ENTRY ListEntry,
5550: IN PKSPIN_LOCK Lock
5551: );
5552:
5553: PLIST_ENTRY
5554: ExInterlockedRemoveHeadList (
5555: IN PLIST_ENTRY ListHead,
5556: IN PKSPIN_LOCK Lock
5557: );
5558:
5559: PSINGLE_LIST_ENTRY
5560: ExInterlockedPopEntryList (
5561: IN PSINGLE_LIST_ENTRY ListHead,
5562: IN PKSPIN_LOCK Lock
5563: );
5564:
5565: PSINGLE_LIST_ENTRY
5566: ExInterlockedPushEntryList (
5567: IN PSINGLE_LIST_ENTRY ListHead,
5568: IN PSINGLE_LIST_ENTRY ListEntry,
5569: IN PKSPIN_LOCK Lock
5570: );
5571:
5572: INTERLOCKED_RESULT
5573: ExInterlockedIncrementLong (
5574: IN PLONG Addend,
5575: IN PKSPIN_LOCK Lock
5576: );
5577:
5578: INTERLOCKED_RESULT
5579: ExInterlockedDecrementLong (
5580: IN PLONG Addend,
5581: IN PKSPIN_LOCK Lock
5582: );
5583:
5584: ULONG
5585: ExInterlockedExchangeUlong (
5586: IN PULONG Target,
5587: IN ULONG Value,
5588: IN PKSPIN_LOCK Lock
5589: );
5590:
5591: //
5592: // Pool Allocation routines (in pool.c)
5593: //
5594:
5595: typedef enum _POOL_TYPE {
5596: NonPagedPool,
5597: PagedPool,
5598: NonPagedPoolMustSucceed,
5599: DontUseThisType,
5600: NonPagedPoolCacheAligned,
5601: PagedPoolCacheAligned,
5602: NonPagedPoolCacheAlignedMustS,
5603: MaxPoolType
5604: } POOL_TYPE;
5605:
5606:
5607: PVOID
5608: ExAllocatePool(
5609: IN POOL_TYPE PoolType,
5610: IN ULONG NumberOfBytes
5611: );
5612:
5613: PVOID
5614: ExAllocatePoolWithQuota(
5615: IN POOL_TYPE PoolType,
5616: IN ULONG NumberOfBytes
5617: );
5618:
5619: VOID
5620: ExFreePool(
5621: IN PVOID P
5622: );
5623:
5624: //
5625: // Worker Thread
5626: //
5627:
5628: typedef enum _WORK_QUEUE_TYPE {
5629: CriticalWorkQueue,
5630: DelayedWorkQueue,
5631: MaximumWorkQueue
5632: } WORK_QUEUE_TYPE;
5633:
5634: typedef
5635: VOID
5636: (*PWORKER_THREAD_ROUTINE)(
5637: IN PVOID Parameter
5638: );
5639:
5640: typedef struct _WORK_QUEUE_ITEM {
5641: LIST_ENTRY List;
5642: PWORKER_THREAD_ROUTINE WorkerRoutine;
5643: PVOID Parameter;
5644: } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM;
5645:
5646:
5647: #define ExInitializeWorkItem(Item, Routine, Context) \
5648: (Item)->WorkerRoutine = (Routine); \
5649: (Item)->Parameter = (Context); \
5650: (Item)->List.Flink = NULL;
5651:
5652: VOID
5653: ExQueueWorkItem(
5654: IN PWORK_QUEUE_ITEM WorkItem,
5655: IN WORK_QUEUE_TYPE QueueType
5656: );
5657:
5658: //
5659: // Zone Allocation
5660: //
5661:
5662: typedef struct _ZONE_SEGMENT_HEADER {
5663: SINGLE_LIST_ENTRY SegmentList;
5664: PVOID Reserved;
5665: } ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
5666:
5667: typedef struct _ZONE_HEADER {
5668: SINGLE_LIST_ENTRY FreeList;
5669: SINGLE_LIST_ENTRY SegmentList;
5670: ULONG BlockSize;
5671: ULONG TotalSegmentSize;
5672: } ZONE_HEADER, *PZONE_HEADER;
5673:
5674:
5675: NTSTATUS
5676: ExInitializeZone(
5677: IN PZONE_HEADER Zone,
5678: IN ULONG BlockSize,
5679: IN PVOID InitialSegment,
5680: IN ULONG InitialSegmentSize
5681: );
5682:
5683: NTSTATUS
5684: ExExtendZone(
5685: IN PZONE_HEADER Zone,
5686: IN PVOID Segment,
5687: IN ULONG SegmentSize
5688: );
5689:
5690: //++
5691: //
5692: // PVOID
5693: // ExAllocateFromZone(
5694: // IN PZONE_HEADER Zone
5695: // )
5696: //
5697: // Routine Description:
5698: //
5699: // This routine removes an entry from the zone and returns a pointer to it.
5700: //
5701: // Arguments:
5702: //
5703: // Zone - Pointer to the zone header controlling the storage from which the
5704: // entry is to be allocated.
5705: //
5706: // Return Value:
5707: //
5708: // The function value is a pointer to the storage allocated from the zone.
5709: //
5710: //--
5711:
5712: #define ExAllocateFromZone(Zone) \
5713: (PVOID)((Zone)->FreeList.Next); \
5714: if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
5715:
5716:
5717: //++
5718: //
5719: // PVOID
5720: // ExFreeToZone(
5721: // IN PZONE_HEADER Zone,
5722: // IN PVOID Block
5723: // )
5724: //
5725: // Routine Description:
5726: //
5727: // This routine places the specified block of storage back onto the free
5728: // list in the specified zone.
5729: //
5730: // Arguments:
5731: //
5732: // Zone - Pointer to the zone header controlling the storage to which the
5733: // entry is to be inserted.
5734: //
5735: // Block - Pointer to the block of storage to be freed back to the zone.
5736: //
5737: // Return Value:
5738: //
5739: // Pointer to previous block of storage that was at the head of the free
5740: // list. NULL implies the zone went from no available free blocks to
5741: // at least one free block.
5742: //
5743: //--
5744:
5745: #define ExFreeToZone(Zone,Block) \
5746: ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
5747: (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
5748: ((PSINGLE_LIST_ENTRY)(Block))->Next \
5749: )
5750:
5751:
5752: //++
5753: //
5754: // BOOLEAN
5755: // ExIsFullZone(
5756: // IN PZONE_HEADER Zone
5757: // )
5758: //
5759: // Routine Description:
5760: //
5761: // This routine determines if the specified zone is full or not. A zone
5762: // is considered full if the free list is empty.
5763: //
5764: // Arguments:
5765: //
5766: // Zone - Pointer to the zone header to be tested.
5767: //
5768: // Return Value:
5769: //
5770: // TRUE if the zone is full and FALSE otherwise.
5771: //
5772: //--
5773:
5774: #define ExIsFullZone(Zone) \
5775: ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
5776:
5777: //++
5778: //
5779: // PVOID
5780: // ExInterlockedAllocateFromZone(
5781: // IN PZONE_HEADER Zone,
5782: // IN PKSPIN_LOCK Lock
5783: // )
5784: //
5785: // Routine Description:
5786: //
5787: // This routine removes an entry from the zone and returns a pointer to it.
5788: // The removal is performed with the specified lock owned for the sequence
5789: // to make it MP-safe.
5790: //
5791: // Arguments:
5792: //
5793: // Zone - Pointer to the zone header controlling the storage from which the
5794: // entry is to be allocated.
5795: //
5796: // Lock - Pointer to the spin lock which should be obtained before removing
5797: // the entry from the allocation list. The lock is released before
5798: // returning to the caller.
5799: //
5800: // Return Value:
5801: //
5802: // The function value is a pointer to the storage allocated from the zone.
5803: //
5804: //--
5805:
5806: #define ExInterlockedAllocateFromZone(Zone,Lock) \
5807: (PVOID) ExInterlockedPopEntryList( &(Zone)->FreeList, Lock )
5808:
5809: //++
5810: //
5811: // PVOID
5812: // ExInterlockedFreeToZone(
5813: // IN PZONE_HEADER Zone,
5814: // IN PVOID Block,
5815: // IN PKSPIN_LOCK Lock
5816: // )
5817: //
5818: // Routine Description:
5819: //
5820: // This routine places the specified block of storage back onto the free
5821: // list in the specified zone. The insertion is performed with the lock
5822: // owned for the sequence to make it MP-safe.
5823: //
5824: // Arguments:
5825: //
5826: // Zone - Pointer to the zone header controlling the storage to which the
5827: // entry is to be inserted.
5828: //
5829: // Block - Pointer to the block of storage to be freed back to the zone.
5830: //
5831: // Lock - Pointer to the spin lock which should be obtained before inserting
5832: // the entry onto the free list. The lock is released before returning
5833: // to the caller.
5834: //
5835: // Return Value:
5836: //
5837: // Pointer to previous block of storage that was at the head of the free
5838: // list. NULL implies the zone went from no available free blocks to
5839: // at least one free block.
5840: //
5841: //--
5842:
5843: #define ExInterlockedFreeToZone(Zone,Block,Lock) \
5844: ExInterlockedPushEntryList( &(Zone)->FreeList, ((PSINGLE_LIST_ENTRY) (Block)), Lock )
5845:
5846: //
5847: // Shared resource function definitions (in resource.c).
5848: //
5849: // Note that this structure is opaque, but we'll define it here
5850: // so drivers can allocate the proper amount of memory for a resource.
5851: //
5852:
5853: typedef ULONG ERESOURCE_THREAD;
5854: typedef ERESOURCE_THREAD *PERESOURCE_THREAD;
5855:
5856: typedef struct _ERESOURCE {
5857:
5858: //
5859: // First 8 bytes are used to align the next part of the structure
5860: // onto 16 bytes. (typical case)
5861: //
5862:
5863: LIST_ENTRY SystemResourcesList;
5864:
5865: //
5866: // Next 128 bits of this structure are field which we know
5867: // we will hit to obtain this resource either shared or exclusive
5868: //
5869:
5870: PERESOURCE_THREAD OwnerThreads;
5871: PUCHAR OwnerCounts;
5872:
5873: USHORT TableSize;
5874: USHORT ActiveCount;
5875:
5876: USHORT Flag;
5877: USHORT TableRover; // (0 - 128 bits)
5878:
5879: //
5880: // Next 128 bits contain the initial counters and at least the
5881: // first initial thread (which is also highly updated)
5882: //
5883:
5884: UCHAR InitialOwnerCounts[4];
5885: ERESOURCE_THREAD InitialOwnerThreads[4];
5886:
5887: ULONG Spare1;
5888:
5889: //
5890: // The rest is what ever was left. The spinlock is in with
5891: // a part of the stucture we normally don't touch in the
5892: // hot paths (read or write)
5893: //
5894:
5895: ULONG ContentionCount;
5896:
5897: USHORT NumberOfExclusiveWaiters;
5898: USHORT NumberOfSharedWaiters;
5899:
5900: KSEMAPHORE SharedWaiters;
5901: KEVENT ExclusiveWaiters;
5902:
5903: KSPIN_LOCK SpinLock;
5904:
5905: #ifdef _X86_
5906: ULONG CreatorBackTraceIndex;
5907: USHORT Depth;
5908: USHORT Reserved;
5909: PVOID OwnerBackTrace[ 4 ];
5910: #else
5911: ULONG Spare[ 6 ];
5912: #endif
5913:
5914: } ERESOURCE;
5915: typedef ERESOURCE *PERESOURCE;
5916:
5917: //
5918: // Values for ERESOURCE.Flag
5919: //
5920: #define ResourceNeverExclusive 0x10
5921: #define ResourceReleaseByOtherThread 0x20
5922: #define ResourceOwnedExclusive 0x80
5923:
5924: NTSTATUS
5925: ExInitializeResource(
5926: IN PERESOURCE Resource
5927: );
5928:
5929:
5930: BOOLEAN
5931: ExAcquireResourceExclusive(
5932: IN PERESOURCE Resource,
5933: IN BOOLEAN Wait
5934: );
5935:
5936: //
5937: // VOID
5938: // ExReleaseResource(
5939: // IN PERESOURCE Resource
5940: // );
5941: //
5942:
5943: #define ExReleaseResource(R) (ExReleaseResourceForThread(R, ExGetCurrentResourceThread()))
5944:
5945: VOID
5946: ExReleaseResourceForThread(
5947: IN PERESOURCE Resource,
5948: IN ERESOURCE_THREAD ResourceThreadId
5949: );
5950:
5951:
5952: NTSTATUS
5953: ExDeleteResource (
5954: IN PERESOURCE Resource
5955: );
5956:
5957:
5958: //
5959: // ERESOURCE_THREAD
5960: // ExGetCurrentResourceThread(
5961: // );
5962: //
5963:
5964: #define ExGetCurrentResourceThread() ((ULONG)PsGetCurrentThread())
5965:
5966: //
5967: // Priority increment definitions. The comment for each definition gives
5968: // the names of the system services that use the definition when satisfying
5969: // a wait.
5970: //
5971: //
5972: // Priority increment when no I/O has been done. This is used by device
5973: // and file system drivers when completing an IRP (IoCompleteRequest).
5974: //
5975:
5976: #define IO_NO_INCREMENT 0
5977:
5978: //
5979: // Priority increment for completing CD-ROM I/O. This is used by CD-ROM device
5980: // and file system drivers when completing an IRP (IoCompleteRequest)
5981: //
5982:
5983: #define IO_CD_ROM_INCREMENT 1
5984:
5985: //
5986: // Priority increment for completing disk I/O. This is used by disk device
5987: // and file system drivers when completing an IRP (IoCompleteRequest)
5988: //
5989:
5990: #define IO_DISK_INCREMENT 1
5991:
5992: //
5993: // Priority increment for completing keyboard I/O. This is used by keyboard
5994: // device drivers when completing an IRP (IoCompleteRequest)
5995: //
5996:
5997: #define IO_KEYBOARD_INCREMENT 6
5998:
5999: //
6000: // Priority increment for completing mailslot I/O. This is used by the mail-
6001: // slot file system driver when completing an IRP (IoCompleteRequest).
6002: //
6003:
6004: #define IO_MAILSLOT_INCREMENT 2
6005:
6006: //
6007: // Priority increment for completing mouse I/O. This is used by mouse device
6008: // drivers when completing an IRP (IoCompleteRequest)
6009: //
6010:
6011: #define IO_MOUSE_INCREMENT 6
6012:
6013: //
6014: // Priority increment for completing named pipe I/O. This is used by the
6015: // named pipe file system driver when completing an IRP (IoCompleteRequest).
6016: //
6017:
6018: #define IO_NAMED_PIPE_INCREMENT 2
6019:
6020: //
6021: // Priority increment for completing network I/O. This is used by network
6022: // device and network file system drivers when completing an IRP
6023: // (IoCompleteRequest).
6024: //
6025:
6026: #define IO_NETWORK_INCREMENT 2
6027:
6028: //
6029: // Priority increment for completing parallel I/O. This is used by parallel
6030: // device drivers when completing an IRP (IoCompleteRequest)
6031: //
6032:
6033: #define IO_PARALLEL_INCREMENT 1
6034:
6035: //
6036: // Priority increment for completing serial I/O. This is used by serial device
6037: // drivers when completing an IRP (IoCompleteRequest)
6038: //
6039:
6040: #define IO_SERIAL_INCREMENT 2
6041:
6042: //
6043: // Priority increment for completing sound I/O. This is used by sound device
6044: // drivers when completing an IRP (IoCompleteRequest)
6045: //
6046:
6047: #define IO_SOUND_INCREMENT 8
6048:
6049: //
6050: // Priority increment for completing video I/O. This is used by video device
6051: // drivers when completing an IRP (IoCompleteRequest)
6052: //
6053:
6054: #define IO_VIDEO_INCREMENT 1
6055:
6056: //
6057: // Priority increment used when satisfying a wait on an executive semaphore
6058: // (NtReleaseSemaphore)
6059: //
6060:
6061: #define SEMAPHORE_INCREMENT 1
6062:
6063: //
6064: // Define maximum disk transfer size to be used by MM and Cache Manager,
6065: // so that packet-oriented disk drivers can optimize their packet allocation
6066: // to this size.
6067: //
6068:
6069: #define MM_MAXIMUM_DISK_IO_SIZE (0x10000)
6070:
6071: //++
6072: //
6073: // ULONG
6074: // ROUND_TO_PAGES (
6075: // IN ULONG Size
6076: // )
6077: //
6078: // Routine Description:
6079: //
6080: // The ROUND_TO_PAGES macro takes a size in bytes and rounds it up to a
6081: // multiple of the page size.
6082: //
6083: // NOTE: This macro fails for values 0xFFFFFFFF - (PAGE_SIZE - 1).
6084: //
6085: // Arguments:
6086: //
6087: // Size - Size in bytes to round up to a page multiple.
6088: //
6089: // Return Value:
6090: //
6091: // Returns the size rounded up to a multiple of the page size.
6092: //
6093: //--
6094:
6095: #define ROUND_TO_PAGES(Size) (((ULONG)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
6096:
6097: //++
6098: //
6099: // ULONG
6100: // BYTES_TO_PAGES (
6101: // IN ULONG Size
6102: // )
6103: //
6104: // Routine Description:
6105: //
6106: // The BYTES_TO_PAGES macro takes the size in bytes and calculates the
6107: // number of pages required to contain the bytes.
6108: //
6109: // Arguments:
6110: //
6111: // Size - Size in bytes.
6112: //
6113: // Return Value:
6114: //
6115: // Returns the number of pages required to contain the specified size.
6116: //
6117: //--
6118:
6119: #define BYTES_TO_PAGES(Size) (((ULONG)(Size) >> PAGE_SHIFT) + \
6120: (((ULONG)(Size) & (PAGE_SIZE - 1)) != 0))
6121:
6122: //++
6123: //
6124: // ULONG
6125: // BYTE_OFFSET (
6126: // IN PVOID Va
6127: // )
6128: //
6129: // Routine Description:
6130: //
6131: // The BYTE_OFFSET macro takes a virtual address and returns the byte offset
6132: // of that address within the page.
6133: //
6134: // Arguments:
6135: //
6136: // Va - Virtual address.
6137: //
6138: // Return Value:
6139: //
6140: // Returns the byte offset portion of the virtual address.
6141: //
6142: //--
6143:
6144: #define BYTE_OFFSET(Va) ((ULONG)(Va) & (PAGE_SIZE - 1))
6145:
6146: //++
6147: //
6148: // PVOID
6149: // PAGE_ALIGN (
6150: // IN PVOID Va
6151: // )
6152: //
6153: // Routine Description:
6154: //
6155: // The PAGE_ALIGN macro takes a virtual address and returns a page-aligned
6156: // virtual address for that page.
6157: //
6158: // Arguments:
6159: //
6160: // Va - Virtual address.
6161: //
6162: // Return Value:
6163: //
6164: // Returns the page aligned virtual address.
6165: //
6166: //--
6167:
6168: #define PAGE_ALIGN(Va) ((PVOID)((ULONG)(Va) & ~(PAGE_SIZE - 1)))
6169:
6170: //++
6171: //
6172: // ULONG
6173: // ADDRESS_AND_SIZE_TO_SPAN_PAGES (
6174: // IN PVOID Va,
6175: // IN ULONG Size
6176: // )
6177: //
6178: // Routine Description:
6179: //
6180: // The ADDRESS_AND_SIZE_TO_SPAN_PAGES macro takes a virtual address and
6181: // size and returns the number of pages spanned by the size.
6182: //
6183: // Arguments:
6184: //
6185: // Va - Virtual address.
6186: //
6187: // Size - Size in bytes.
6188: //
6189: // Return Value:
6190: //
6191: // Returns the number of pages spanned by the size.
6192: //
6193: //--
6194:
6195: #define ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va,Size) \
6196: ((((ULONG)((ULONG)(Size) - 1L) >> PAGE_SHIFT) + \
6197: (((((ULONG)(Size-1)&(PAGE_SIZE-1)) + ((ULONG)Va & (PAGE_SIZE -1)))) >> PAGE_SHIFT)) + 1L)
6198:
6199:
6200: //++
6201: //
6202: // PVOID
6203: // MmGetMdlVirtualAddress (
6204: // IN PMDL Mdl
6205: // )
6206: //
6207: // Routine Description:
6208: //
6209: // The MmGetMdlVirtualAddress returns the virual address of the buffer
6210: // described by the Mdl.
6211: //
6212: // Arguments:
6213: //
6214: // Mdl - Pointer to an MDL.
6215: //
6216: // Return Value:
6217: //
6218: // Returns the virtual address of the buffer described by the Mdl
6219: //
6220: //--
6221:
6222: #define MmGetMdlVirtualAddress(Mdl) ((PVOID) ((PCHAR) (Mdl)->StartVa + (Mdl)->ByteOffset))
6223:
6224: //++
6225: //
6226: // ULONG
6227: // MmGetMdlByteCount (
6228: // IN PMDL Mdl
6229: // )
6230: //
6231: // Routine Description:
6232: //
6233: // The MmGetMdlByteCount returns the length in bytes of the buffer
6234: // described by the Mdl.
6235: //
6236: // Arguments:
6237: //
6238: // Mdl - Pointer to an MDL.
6239: //
6240: // Return Value:
6241: //
6242: // Returns the byte count of the buffer described by the Mdl
6243: //
6244: //--
6245:
6246: #define MmGetMdlByteCount(Mdl) ((Mdl)->ByteCount)
6247:
6248: typedef enum _MM_SYSTEM_SIZE {
6249: MmSmallSystem,
6250: MmMediumSystem,
6251: MmLargeSystem
6252: } MM_SYSTEMSIZE;
6253:
6254: MM_SYSTEMSIZE
6255: MmQuerySystemSize(
6256: VOID
6257: );
6258:
6259: typedef enum _LOCK_OPERATION {
6260: IoReadAccess,
6261: IoWriteAccess,
6262: IoModifyAccess
6263: } LOCK_OPERATION;
6264:
6265: //
6266: // I/O support routines.
6267: //
6268:
6269: VOID
6270: MmProbeAndLockPages (
6271: IN OUT PMDL MemoryDescriptorList,
6272: IN KPROCESSOR_MODE AccessMode,
6273: IN LOCK_OPERATION Operation
6274: );
6275:
6276: VOID
6277: MmUnlockPages (
6278: IN PMDL MemoryDescriptorList
6279: );
6280:
6281: VOID
6282: MmBuildMdlForNonPagedPool (
6283: IN OUT PMDL MemoryDescriptorList
6284: );
6285:
6286: PVOID
6287: MmMapLockedPages (
6288: IN PMDL MemoryDescriptorList,
6289: IN KPROCESSOR_MODE AccessMode
6290: );
6291:
6292: VOID
6293: MmUnmapLockedPages (
6294: IN PVOID BaseAddress,
6295: IN PMDL MemoryDescriptorList
6296: );
6297:
6298:
6299: PVOID
6300: MmMapIoSpace (
6301: IN PHYSICAL_ADDRESS PhysicalAddress,
6302: IN ULONG NumberOfBytes,
6303: IN BOOLEAN CacheEnable
6304: );
6305:
6306: VOID
6307: MmUnmapIoSpace (
6308: IN PVOID BaseAddress,
6309: IN ULONG NumberOfBytes
6310: );
6311:
6312: PHYSICAL_ADDRESS
6313: MmGetPhysicalAddress (
6314: IN PVOID BaseAddress
6315: );
6316:
6317: PVOID
6318: MmAllocateContiguousMemory (
6319: IN ULONG NumberOfBytes,
6320: IN PHYSICAL_ADDRESS HighestAcceptableAddress
6321: );
6322:
6323: VOID
6324: MmFreeContiguousMemory (
6325: IN PVOID BaseAddress
6326: );
6327:
6328: PVOID
6329: MmAllocateNonCachedMemory (
6330: IN ULONG NumberOfBytes
6331: );
6332:
6333: VOID
6334: MmFreeNonCachedMemory (
6335: IN PVOID BaseAddress,
6336: IN ULONG NumberOfBytes
6337: );
6338:
6339: BOOLEAN
6340: MmIsAddressValid (
6341: IN PVOID VirtualAddress
6342: );
6343:
6344: BOOLEAN
6345: MmIsNonPagedSystemAddressValid (
6346: IN PVOID VirtualAddress
6347: );
6348:
6349:
6350: ULONG
6351: MmSizeOfMdl(
6352: IN PVOID Base,
6353: IN ULONG Length
6354: );
6355:
6356: PMDL
6357: MmCreateMdl(
6358: IN PMDL MemoryDescriptorList OPTIONAL,
6359: IN PVOID Base,
6360: IN ULONG Length
6361: );
6362:
6363: //++
6364: //
6365: // VOID
6366: // MmInitializeMdl (
6367: // IN PMDL MemoryDescriptorList,
6368: // IN PVOID BaseVa,
6369: // IN ULONG Length
6370: // )
6371: //
6372: // Routine Description:
6373: //
6374: // This routine initializes the header of a Memory Descriptor List (MDL).
6375: //
6376: // Arguments:
6377: //
6378: // MemoryDescriptorList - Pointer to the MDL to initialize.
6379: //
6380: // BaseVa - Base virtual address mapped by the MDL.
6381: //
6382: // Length - Length, in bytes, of the buffer mapped by the MDL.
6383: //
6384: // Return Value:
6385: //
6386: // None.
6387: //
6388: //--
6389:
6390: #define MmInitializeMdl(MemoryDescriptorList, BaseVa, Length) { \
6391: (MemoryDescriptorList)->Next = (PMDL) NULL; \
6392: (MemoryDescriptorList)->Size = (CSHORT)(sizeof(MDL) + \
6393: (sizeof(ULONG) * ADDRESS_AND_SIZE_TO_SPAN_PAGES((BaseVa), (Length)))); \
6394: (MemoryDescriptorList)->MdlFlags = 0; \
6395: (MemoryDescriptorList)->StartVa = (PVOID) PAGE_ALIGN((BaseVa)); \
6396: (MemoryDescriptorList)->ByteOffset = BYTE_OFFSET((BaseVa)); \
6397: (MemoryDescriptorList)->ByteCount = (Length); \
6398: }
6399:
6400: //++
6401: //
6402: // PVOID
6403: // MmGetSystemAddressForMdl (
6404: // IN PMDL MDL
6405: // )
6406: //
6407: // Routine Description:
6408: //
6409: // This routine returns the mapped address of an MDL, if the
6410: // Mdl is not already mapped or a system address, it is mapped.
6411: //
6412: // Arguments:
6413: //
6414: // MemoryDescriptorList - Pointer to the MDL to map.
6415: //
6416: // Return Value:
6417: //
6418: // Returns the base address where the pages are mapped. The base address
6419: // has the same offset as the virtual address in the MDL.
6420: //
6421: //--
6422:
6423: //#define MmGetSystemAddressForMdl(MDL)
6424: // (((MDL)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA)) ?
6425: // ((MDL)->MappedSystemVa) :
6426: // ((((MDL)->MdlFlags & (MDL_SOURCE_IS_NONPAGED_POOL)) ?
6427: // ((PVOID)((ULONG)(MDL)->StartVa | (MDL)->ByteOffset)) :
6428: // (MmMapLockedPages((MDL),KernelMode)))))
6429:
6430: #define MmGetSystemAddressForMdl(MDL) \
6431: (((MDL)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \
6432: MDL_SOURCE_IS_NONPAGED_POOL)) ? \
6433: ((MDL)->MappedSystemVa) : \
6434: (MmMapLockedPages((MDL),KernelMode)))
6435:
6436: //++
6437: //
6438: // VOID
6439: // MmPrepareMdlForReuse (
6440: // IN PMDL MDL
6441: // )
6442: //
6443: // Routine Description:
6444: //
6445: // This routine will take all of the steps necessary to allow an MDL to be
6446: // re-used.
6447: //
6448: // Arguments:
6449: //
6450: // MemoryDescriptorList - Pointer to the MDL that will be re-used.
6451: //
6452: // Return Value:
6453: //
6454: // None.
6455: //
6456: //--
6457:
6458: #define MmPrepareMdlForReuse(MDL) \
6459: if (((MDL)->MdlFlags & MDL_PARTIAL_HAS_BEEN_MAPPED) != 0) { \
6460: ASSERT(((MDL)->MdlFlags & MDL_PARTIAL) != 0); \
6461: MmUnmapLockedPages( (MDL)->MappedSystemVa, (MDL) ); \
6462: } else if (((MDL)->MdlFlags & MDL_PARTIAL) == 0) { \
6463: ASSERT(((MDL)->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0); \
6464: }
6465:
6466:
6467: //
6468: // Security operation codes
6469: //
6470:
6471: typedef enum _SECURITY_OPERATION_CODE {
6472: SetSecurityDescriptor,
6473: QuerySecurityDescriptor,
6474: DeleteSecurityDescriptor,
6475: AssignSecurityDescriptor
6476: } SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE;
6477:
6478: //
6479: // Data structure used to capture subject security context
6480: // for access validations and auditing.
6481: //
6482: // THE FIELDS OF THIS DATA STRUCTURE SHOULD BE CONSIDERED OPAQUE
6483: // BY ALL EXCEPT THE SECURITY ROUTINES.
6484: //
6485:
6486: typedef struct _SECURITY_SUBJECT_CONTEXT {
6487: PACCESS_TOKEN ClientToken;
6488: SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
6489: PACCESS_TOKEN PrimaryToken;
6490: PVOID ProcessAuditId;
6491: } SECURITY_SUBJECT_CONTEXT, *PSECURITY_SUBJECT_CONTEXT;
6492:
6493: ///////////////////////////////////////////////////////////////////////////////
6494: // //
6495: // ACCESS_STATE and related structures //
6496: // //
6497: ///////////////////////////////////////////////////////////////////////////////
6498:
6499: //
6500: // Initial Privilege Set - Room for three privileges, which should
6501: // be enough for most applications. This structure exists so that
6502: // it can be imbedded in an ACCESS_STATE structure. Use PRIVILEGE_SET
6503: // for all other references to Privilege sets.
6504: //
6505:
6506: #define INITIAL_PRIVILEGE_COUNT 3
6507:
6508: typedef struct _INITIAL_PRIVILEGE_SET {
6509: ULONG PrivilegeCount;
6510: ULONG Control;
6511: LUID_AND_ATTRIBUTES Privilege[INITIAL_PRIVILEGE_COUNT];
6512: } INITIAL_PRIVILEGE_SET, * PINITIAL_PRIVILEGE_SET;
6513:
6514:
6515:
6516: //
6517: // Combine the information that describes the state
6518: // of an access-in-progress into a single structure
6519: //
6520:
6521:
6522: typedef struct _ACCESS_STATE {
6523: LUID OperationID;
6524: BOOLEAN SecurityEvaluated;
6525: BOOLEAN AuditHandleCreation;
6526: BOOLEAN GenerateOnClose;
6527: BOOLEAN PrivilegesAllocated;
6528: ULONG Flags;
6529: ACCESS_MASK RemainingDesiredAccess;
6530: ACCESS_MASK PreviouslyGrantedAccess;
6531: ACCESS_MASK OriginalDesiredAccess;
6532: SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
6533: PSECURITY_DESCRIPTOR SecurityDescriptor;
6534: PPRIVILEGE_SET PrivilegesUsed;
6535: union {
6536: INITIAL_PRIVILEGE_SET InitialPrivilegeSet;
6537: PRIVILEGE_SET PrivilegeSet;
6538: } Privileges;
6539: } ACCESS_STATE, *PACCESS_STATE;
6540:
6541:
6542: NTSTATUS
6543: SeAssignSecurity (
6544: IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
6545: IN PSECURITY_DESCRIPTOR ExplicitDescriptor,
6546: OUT PSECURITY_DESCRIPTOR *NewDescriptor,
6547: IN BOOLEAN IsDirectoryObject,
6548: IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
6549: IN PGENERIC_MAPPING GenericMapping,
6550: IN POOL_TYPE PoolType
6551: );
6552:
6553: NTSTATUS
6554: SeDeassignSecurity (
6555: IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor
6556: );
6557:
6558:
6559: BOOLEAN
6560: SeAccessCheck (
6561: IN PSECURITY_DESCRIPTOR SecurityDescriptor,
6562: IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
6563: IN BOOLEAN SubjectContextLocked,
6564: IN ACCESS_MASK DesiredAccess,
6565: IN ACCESS_MASK PreviouslyGrantedAccess,
6566: OUT PPRIVILEGE_SET *Privileges OPTIONAL,
6567: IN PGENERIC_MAPPING GenericMapping,
6568: IN KPROCESSOR_MODE AccessMode,
6569: OUT PACCESS_MASK GrantedAccess,
6570: OUT PNTSTATUS AccessStatus
6571: );
6572:
6573: BOOLEAN
6574: SeSinglePrivilegeCheck(
6575: LUID PrivilegeValue,
6576: KPROCESSOR_MODE PreviousMode
6577: );
6578: //
6579: // System Thread and Process Creation and Termination
6580: //
6581:
6582: NTSTATUS
6583: PsCreateSystemThread(
6584: OUT PHANDLE ThreadHandle,
6585: IN ULONG DesiredAccess,
6586: IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
6587: IN HANDLE ProcessHandle OPTIONAL,
6588: OUT PCLIENT_ID ClientId OPTIONAL,
6589: IN PKSTART_ROUTINE StartRoutine,
6590: IN PVOID StartContext
6591: );
6592:
6593: NTSTATUS
6594: PsTerminateSystemThread(
6595: IN NTSTATUS ExitStatus
6596: );
6597:
6598: //
6599: // Define I/O system data structure type codes. Each major data structure in
6600: // the I/O system has a type code The type field in each structure is at the
6601: // same offset. The following values can be used to determine which type of
6602: // data structure a pointer refers to.
6603: //
6604:
6605: #define IO_TYPE_ADAPTER 0x00000001
6606: #define IO_TYPE_CONTROLLER 0x00000002
6607: #define IO_TYPE_DEVICE 0x00000003
6608: #define IO_TYPE_DRIVER 0x00000004
6609: #define IO_TYPE_FILE 0x00000005
6610: #define IO_TYPE_IRP 0x00000006
6611: #define IO_TYPE_MASTER_ADAPTER 0x00000007
6612: #define IO_TYPE_OPEN_PACKET 0x00000008
6613: #define IO_TYPE_TIMER 0x00000009
6614: #define IO_TYPE_VPB 0x0000000a
6615: #define IO_TYPE_ERROR_LOG 0x0000000b
6616: #define IO_TYPE_ERROR_MESSAGE 0x0000000c
6617:
6618: //
6619: // Define the major function codes for IRPs. The lower 128 codes, from 0x00 to
6620: // 0x7f are reserved to Microsoft. The upper 128 codes, from 0x80 to 0xff, are
6621: // reserved to customers of Microsoft.
6622: //
6623:
6624: #define IRP_MJ_CREATE 0x00
6625: #define IRP_MJ_CREATE_NAMED_PIPE 0x01
6626: #define IRP_MJ_CLOSE 0x02
6627: #define IRP_MJ_READ 0x03
6628: #define IRP_MJ_WRITE 0x04
6629: #define IRP_MJ_QUERY_INFORMATION 0x05
6630: #define IRP_MJ_SET_INFORMATION 0x06
6631: #define IRP_MJ_QUERY_EA 0x07
6632: #define IRP_MJ_SET_EA 0x08
6633: #define IRP_MJ_FLUSH_BUFFERS 0x09
6634: #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
6635: #define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
6636: #define IRP_MJ_DIRECTORY_CONTROL 0x0c
6637: #define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
6638: #define IRP_MJ_DEVICE_CONTROL 0x0e
6639: #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
6640: #define IRP_MJ_SHUTDOWN 0x10
6641: #define IRP_MJ_LOCK_CONTROL 0x11
6642: #define IRP_MJ_CLEANUP 0x12
6643: #define IRP_MJ_CREATE_MAILSLOT 0x13
6644: #define IRP_MJ_QUERY_SECURITY 0x14
6645: #define IRP_MJ_SET_SECURITY 0x15
6646: #define IRP_MJ_MAXIMUM_FUNCTION 0x15
6647:
6648: //
6649: // Make the Scsi major code the same as internal device control.
6650: //
6651:
6652: #define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL
6653:
6654: //
6655: // Define the minor function codes for IRPs. The lower 128 codes, from 0x00 to
6656: // 0x7f are reserved to Microsoft. The upper 128 codes, from 0x80 to 0xff, are
6657: // reserved to customers of Microsoft.
6658: //
6659:
6660: //
6661: // Directory control minor function codes
6662: //
6663:
6664: #define IRP_MN_QUERY_DIRECTORY 0x01
6665: #define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02
6666:
6667: //
6668: // File system control minor function codes. Note that "user request" is
6669: // assumed to be zero by both the I/O system and file systems. Do not change
6670: // this value.
6671: //
6672:
6673: #define IRP_MN_USER_FS_REQUEST 0x00
6674: #define IRP_MN_MOUNT_VOLUME 0x01
6675: #define IRP_MN_VERIFY_VOLUME 0x02
6676: #define IRP_MN_LOAD_FILE_SYSTEM 0x03
6677:
6678: //
6679: // Lock control minor function codes
6680: //
6681:
6682: #define IRP_MN_LOCK 0x01
6683: #define IRP_MN_UNLOCK_SINGLE 0x02
6684: #define IRP_MN_UNLOCK_ALL 0x03
6685: #define IRP_MN_UNLOCK_ALL_BY_KEY 0x04
6686:
6687: //
6688: // Read and Write minor function codes for file systems supporting Lan Manager
6689: // software. All of these subfunction codes are invalid if the file has been
6690: // opened with FO_NO_INTERMEDIATE_BUFFERING. They are also invalid in combi-
6691: // nation with synchronous calls (Irp Flag or file open option).
6692: //
6693: // Note that "normal" is assumed to be zero by both the I/O system and file
6694: // systems. Do not change this value.
6695: //
6696:
6697: #define IRP_MN_NORMAL 0x00
6698: #define IRP_MN_DPC 0x01
6699: #define IRP_MN_MDL 0x02
6700: #define IRP_MN_COMPLETE 0x04
6701:
6702: #define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC)
6703: #define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL)
6704: #define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
6705:
6706: //
6707: // Device Control Request minor function codes for SCSI support. Note that
6708: // user requests are assumed to be zero.
6709: //
6710:
6711: #define IRP_MN_SCSI_CLASS 0x01
6712:
6713: //
6714: // Define option flags for IoCreateFile. Note that these values must be
6715: // exactly the same as the SL_... flags for a create function. Note also
6716: // that there are flags that may be passed to IoCreateFile that are not
6717: // placed in the stack location for the create IRP. These flags start in
6718: // the next byte.
6719: //
6720:
6721: #define IO_FORCE_ACCESS_CHECK 0x0001
6722: #define IO_OPEN_PAGING_FILE 0x0002
6723: #define IO_OPEN_TARGET_DIRECTORY 0x0004
6724:
6725: //
6726: // Define callout routine type for use in IoQueryDeviceDescription().
6727: //
6728:
6729: typedef NTSTATUS (*PIO_QUERY_DEVICE_ROUTINE)(
6730: IN PVOID Context,
6731: IN PUNICODE_STRING PathName,
6732: IN INTERFACE_TYPE BusType,
6733: IN ULONG BusNumber,
6734: IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
6735: IN CONFIGURATION_TYPE ControllerType,
6736: IN ULONG ControllerNumber,
6737: IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
6738: IN CONFIGURATION_TYPE PeripheralType,
6739: IN ULONG PeripheralNumber,
6740: IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
6741: );
6742:
6743: //
6744: // Defines the order of the information in the array of
6745: // PKEY_VALUE_FULL_INFORMATION.
6746: //
6747:
6748: typedef enum _IO_QUERY_DEVICE_DATA_FORMAT {
6749: IoQueryDeviceIdentifier = 0,
6750: IoQueryDeviceConfigurationData,
6751: IoQueryDeviceComponentInformation,
6752: IoQueryDeviceMaxData
6753: } IO_QUERY_DEVICE_DATA_FORMAT, *PIO_QUERY_DEVICE_DATA_FORMAT;
6754:
6755: //
6756: // Define the objects that can be created by IoCreateFile.
6757: //
6758:
6759: typedef enum _CREATE_FILE_TYPE {
6760: CreateFileTypeNone,
6761: CreateFileTypeNamedPipe,
6762: CreateFileTypeMailslot
6763: } CREATE_FILE_TYPE;
6764:
6765: //
6766: // Define the structures used by the I/O system
6767: //
6768:
6769: //
6770: // Define empty typedefs for the _IRP, _DEVICE_OBJECT, and _DRIVER_OBJECT
6771: // structures so they may be referenced by function types before they are
6772: // actually defined.
6773: //
6774:
6775: struct _DEVICE_OBJECT;
6776: struct _DRIVER_OBJECT;
6777: struct _DRIVE_LAYOUT_INFORMATION;
6778: struct _DISK_PARTITION;
6779: struct _FILE_OBJECT;
6780: struct _IRP;
6781: struct _SCSI_REQUEST_BLOCK;
6782:
6783: //
6784: // Define the I/O version of a DPC routine.
6785: //
6786:
6787: typedef
6788: VOID
6789: (*PIO_DPC_ROUTINE) (
6790: IN PKDPC Dpc,
6791: IN struct _DEVICE_OBJECT *DeviceObject,
6792: IN struct _IRP *Irp,
6793: IN PVOID Context
6794: );
6795:
6796: //
6797: // Define driver timer routine type.
6798: //
6799:
6800: typedef
6801: VOID
6802: (*PIO_TIMER_ROUTINE) (
6803: IN struct _DEVICE_OBJECT *DeviceObject,
6804: IN PVOID Context
6805: );
6806:
6807: //
6808: // Define driver initialization routine type.
6809: //
6810:
6811: typedef
6812: NTSTATUS
6813: (*PDRIVER_INITIALIZE) (
6814: IN struct _DRIVER_OBJECT *DriverObject,
6815: IN PUNICODE_STRING RegistryPath
6816: );
6817:
6818: //
6819: // Define driver reinitialization routine type.
6820: //
6821:
6822: typedef
6823: VOID
6824: (*PDRIVER_REINITIALIZE) (
6825: IN struct _DRIVER_OBJECT *DriverObject,
6826: IN PVOID Context,
6827: IN ULONG Count
6828: );
6829:
6830: //
6831: // Define driver cancel routine type.
6832: //
6833:
6834: typedef
6835: VOID
6836: (*PDRIVER_CANCEL) (
6837: IN struct _DEVICE_OBJECT *DeviceObject,
6838: IN struct _IRP *Irp
6839: );
6840:
6841: //
6842: // Define driver dispatch routine type.
6843: //
6844:
6845: typedef
6846: NTSTATUS
6847: (*PDRIVER_DISPATCH) (
6848: IN struct _DEVICE_OBJECT *DeviceObject,
6849: IN struct _IRP *Irp
6850: );
6851:
6852: //
6853: // Define driver start I/O routine type.
6854: //
6855:
6856: typedef
6857: VOID
6858: (*PDRIVER_STARTIO) (
6859: IN struct _DEVICE_OBJECT *DeviceObject,
6860: IN struct _IRP *Irp
6861: );
6862:
6863: //
6864: // Define driver unload routine type.
6865: //
6866:
6867: typedef
6868: VOID
6869: (*PDRIVER_UNLOAD) (
6870: IN struct _DRIVER_OBJECT *DriverObject
6871: );
6872:
6873:
6874: //
6875: // Define fast I/O procedure prototypes.
6876: //
6877: // Fast I/O read and write procedures.
6878: //
6879:
6880: typedef
6881: BOOLEAN
6882: (*PFAST_IO_CHECK_IF_POSSIBLE) (
6883: IN struct _FILE_OBJECT *FileObject,
6884: IN PLARGE_INTEGER FileOffset,
6885: IN ULONG Length,
6886: IN BOOLEAN Wait,
6887: IN ULONG LockKey,
6888: IN BOOLEAN CheckForReadOperation,
6889: OUT PIO_STATUS_BLOCK IoStatus
6890: );
6891:
6892: typedef
6893: BOOLEAN
6894: (*PFAST_IO_READ) (
6895: IN struct _FILE_OBJECT *FileObject,
6896: IN PLARGE_INTEGER FileOffset,
6897: IN ULONG Length,
6898: IN BOOLEAN Wait,
6899: IN ULONG LockKey,
6900: OUT PVOID Buffer,
6901: OUT PIO_STATUS_BLOCK IoStatus
6902: );
6903:
6904: typedef
6905: BOOLEAN
6906: (*PFAST_IO_WRITE) (
6907: IN struct _FILE_OBJECT *FileObject,
6908: IN PLARGE_INTEGER FileOffset,
6909: IN ULONG Length,
6910: IN BOOLEAN Wait,
6911: IN ULONG LockKey,
6912: IN PVOID Buffer,
6913: OUT PIO_STATUS_BLOCK IoStatus
6914: );
6915:
6916: //
6917: // Fast I/O query basic and standard information procedures.
6918: //
6919:
6920: typedef
6921: BOOLEAN
6922: (*PFAST_IO_QUERY_BASIC_INFO) (
6923: IN struct _FILE_OBJECT *FileObject,
6924: IN BOOLEAN Wait,
6925: OUT PFILE_BASIC_INFORMATION Buffer,
6926: OUT PIO_STATUS_BLOCK IoStatus
6927: );
6928:
6929: typedef
6930: BOOLEAN
6931: (*PFAST_IO_QUERY_STANDARD_INFO) (
6932: IN struct _FILE_OBJECT *FileObject,
6933: IN BOOLEAN Wait,
6934: OUT PFILE_STANDARD_INFORMATION Buffer,
6935: OUT PIO_STATUS_BLOCK IoStatus
6936: );
6937:
6938: //
6939: // Fast I/O lock and unlock procedures.
6940: //
6941:
6942: typedef
6943: BOOLEAN
6944: (*PFAST_IO_LOCK) (
6945: IN struct _FILE_OBJECT *FileObject,
6946: IN PLARGE_INTEGER FileOffset,
6947: IN PLARGE_INTEGER Length,
6948: PEPROCESS ProcessId,
6949: ULONG Key,
6950: BOOLEAN FailImmediately,
6951: BOOLEAN ExclusiveLock,
6952: OUT PIO_STATUS_BLOCK IoStatus
6953: );
6954:
6955: typedef
6956: BOOLEAN
6957: (*PFAST_IO_UNLOCK_SINGLE) (
6958: IN struct _FILE_OBJECT *FileObject,
6959: IN PLARGE_INTEGER FileOffset,
6960: IN PLARGE_INTEGER Length,
6961: PEPROCESS ProcessId,
6962: ULONG Key,
6963: OUT PIO_STATUS_BLOCK IoStatus
6964: );
6965:
6966: typedef
6967: BOOLEAN
6968: (*PFAST_IO_UNLOCK_ALL) (
6969: IN struct _FILE_OBJECT *FileObject,
6970: PEPROCESS ProcessId,
6971: OUT PIO_STATUS_BLOCK IoStatus
6972: );
6973:
6974: typedef
6975: BOOLEAN
6976: (*PFAST_IO_UNLOCK_ALL_BY_KEY) (
6977: IN struct _FILE_OBJECT *FileObject,
6978: PVOID ProcessId,
6979: ULONG Key,
6980: OUT PIO_STATUS_BLOCK IoStatus
6981: );
6982:
6983: //
6984: // Fast I/O device control procedure.
6985: //
6986:
6987: typedef
6988: BOOLEAN
6989: (*PFAST_IO_DEVICE_CONTROL) (
6990: IN struct _FILE_OBJECT *FileObject,
6991: IN BOOLEAN Wait,
6992: IN PVOID InputBuffer OPTIONAL,
6993: IN ULONG InputBufferLength,
6994: OUT PVOID OutputBuffer OPTIONAL,
6995: IN ULONG OutputBufferLength,
6996: IN ULONG IoControlCode,
6997: OUT PIO_STATUS_BLOCK IoStatus
6998: );
6999:
7000: //
7001: // Define the structure to describe the Fast I/O dispatch routines.
7002: //
7003:
7004: typedef struct _FAST_IO_DISPATCH {
7005: ULONG SizeOfFastIoDispatch;
7006: PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible;
7007: PFAST_IO_READ FastIoRead;
7008: PFAST_IO_WRITE FastIoWrite;
7009: PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo;
7010: PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo;
7011: PFAST_IO_LOCK FastIoLock;
7012: PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle;
7013: PFAST_IO_UNLOCK_ALL FastIoUnlockAll;
7014: PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey;
7015: PFAST_IO_DEVICE_CONTROL FastIoDeviceControl;
7016: } FAST_IO_DISPATCH, *PFAST_IO_DISPATCH;
7017:
7018: //
7019: // Define the actions that a driver execution routine may request of the
7020: // adapter/controller allocation routines upon return.
7021: //
7022:
7023: typedef enum _IO_ALLOCATION_ACTION {
7024: KeepObject = 1,
7025: DeallocateObject,
7026: DeallocateObjectKeepRegisters
7027: } IO_ALLOCATION_ACTION, *PIO_ALLOCATION_ACTION;
7028:
7029: //
7030: // Define device driver adapter/controller execution routine.
7031: //
7032:
7033: typedef
7034: IO_ALLOCATION_ACTION
7035: (*PDRIVER_CONTROL) (
7036: IN struct _DEVICE_OBJECT *DeviceObject,
7037: IN struct _IRP *Irp,
7038: IN PVOID MapRegisterBase,
7039: IN PVOID Context
7040: );
7041:
7042: //
7043: // Define the I/O system's security context type for use by file system's
7044: // when checking access to volumes, files, and directories.
7045: //
7046:
7047: typedef struct _IO_SECURITY_CONTEXT {
7048: PSECURITY_QUALITY_OF_SERVICE SecurityQos;
7049: PACCESS_STATE AccessState;
7050: ACCESS_MASK DesiredAccess;
7051: } IO_SECURITY_CONTEXT, *PIO_SECURITY_CONTEXT;
7052:
7053: //
7054: // Define Volume Parameter Block (VPB) flags.
7055: //
7056:
7057: #define VPB_MOUNTED 0x00000001
7058: #define VPB_LOCKED 0x00000002
7059:
7060: //
7061: // Volume Parameter Block (VPB)
7062: //
7063:
7064: #define MAXIMUM_VOLUME_LABEL_LENGTH (32 * sizeof(WCHAR)) // 32 characters
7065:
7066: typedef struct _VPB {
7067: CSHORT Type;
7068: CSHORT Size;
7069: USHORT Flags;
7070: USHORT VolumeLabelLength; // in bytes
7071: struct _DEVICE_OBJECT *DeviceObject;
7072: struct _DEVICE_OBJECT *RealDevice;
7073: ULONG SerialNumber;
7074: ULONG ReferenceCount;
7075: WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)];
7076: } VPB, *PVPB;
7077:
7078: //
7079: // Define object type specific fields of various objects used by the I/O system
7080: //
7081:
7082: typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT;
7083:
7084: //
7085: // Define Wait Context Block (WCB)
7086: //
7087:
7088: typedef struct _WAIT_CONTEXT_BLOCK {
7089: KDEVICE_QUEUE_ENTRY WaitQueueEntry;
7090: PDRIVER_CONTROL DeviceRoutine;
7091: PVOID DeviceContext;
7092: ULONG NumberOfMapRegisters;
7093: PVOID DeviceObject;
7094: PVOID CurrentIrp;
7095: PKDPC BufferChainingDpc;
7096: } WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK;
7097:
7098: typedef struct _CONTROLLER_OBJECT {
7099: CSHORT Type;
7100: CSHORT Size;
7101: PVOID ControllerExtension;
7102: KDEVICE_QUEUE DeviceWaitQueue;
7103:
7104: ULONG Spare1;
7105: LARGE_INTEGER Spare2;
7106:
7107: } CONTROLLER_OBJECT, *PCONTROLLER_OBJECT;
7108:
7109:
7110: //
7111: // Define Device Object (DO) flags
7112: //
7113:
7114: #define DO_UNLOAD_PENDING 0x00000001
7115: #define DO_VERIFY_VOLUME 0x00000002
7116: #define DO_BUFFERED_IO 0x00000004
7117: #define DO_EXCLUSIVE 0x00000008
7118: #define DO_DIRECT_IO 0x00000010
7119: #define DO_MAP_IO_BUFFER 0x00000020
7120: #define DO_DEVICE_HAS_NAME 0x00000040
7121: #define DO_DEVICE_INITIALIZING 0x00000080
7122: #define DO_SYSTEM_BOOT_PARTITION 0x00000100
7123:
7124: //
7125: // Device Object structure definition
7126: //
7127:
7128: typedef struct _DEVICE_OBJECT {
7129: CSHORT Type;
7130: USHORT Size;
7131: LONG ReferenceCount;
7132: struct _DRIVER_OBJECT *DriverObject;
7133: struct _DEVICE_OBJECT *NextDevice;
7134: struct _DEVICE_OBJECT *AttachedDevice;
7135: struct _IRP *CurrentIrp;
7136: PIO_TIMER Timer;
7137: ULONG Flags; // See above: DO_...
7138: ULONG Characteristics; // See ntioapi: FILE_...
7139: PVPB Vpb;
7140: PVOID DeviceExtension;
7141: DEVICE_TYPE DeviceType;
7142: CCHAR StackSize;
7143: union {
7144: LIST_ENTRY ListEntry;
7145: WAIT_CONTEXT_BLOCK Wcb;
7146: } Queue;
7147: ULONG AlignmentRequirement;
7148: KDEVICE_QUEUE DeviceQueue;
7149: KDPC Dpc;
7150:
7151: //
7152: // The following field is for exclusive use by the filesystem to keep
7153: // track of the number of Fsp threads currently using the device
7154: //
7155:
7156: ULONG ActiveThreadCount;
7157: PSECURITY_DESCRIPTOR SecurityDescriptor;
7158: KEVENT DeviceLock;
7159:
7160: ULONG Spare1;
7161: LARGE_INTEGER Spare2;
7162:
7163: } DEVICE_OBJECT, *PDEVICE_OBJECT;
7164:
7165: //
7166: // Define Driver Object (DRVO) flags
7167: //
7168:
7169: #define DRVO_UNLOAD_INVOKED 0x00000001
7170:
7171: typedef struct _DRIVER_OBJECT {
7172: CSHORT Type;
7173: CSHORT Size;
7174:
7175: //
7176: // The following links all of the devices created by a single driver
7177: // together on a list, and the Flags word provides an extensible flag
7178: // location for driver objects.
7179: //
7180:
7181: PDEVICE_OBJECT DeviceObject;
7182: ULONG Flags;
7183:
7184: //
7185: // The following section describes where the driver is loaded. The count
7186: // field is used to count the number of times the driver has had its
7187: // registered reinitialization routine invoked.
7188: //
7189:
7190: PVOID DriverStart;
7191: ULONG DriverSize;
7192: PVOID DriverSection;
7193: ULONG Count;
7194:
7195: //
7196: // The driver name field is used by the error log thread
7197: // determine the name of the driver that an I/O request is/was bound.
7198: //
7199:
7200: UNICODE_STRING DriverName;
7201:
7202: //
7203: // The following section is for registry support. Thise is a pointer
7204: // to the path to the hardware information in the registry
7205: //
7206:
7207: PUNICODE_STRING HardwareDatabase;
7208:
7209: //
7210: // The following section contains the optional pointer to an array of
7211: // alternate entry points to a driver for "fast I/O" support. Fast I/O
7212: // is performed by invoking the driver routine directly with separate
7213: // parameters, rather than using the standard IRP call mechanism. Note
7214: // that these functions may only be used for synchronous I/O, and when
7215: // the file is cached.
7216: //
7217:
7218: PFAST_IO_DISPATCH FastIoDispatch;
7219:
7220: //
7221: // The following section describes the entry points to this particular
7222: // driver. Note that the major function dispatch table must be the last
7223: // field in the object so that it remains extensible.
7224: //
7225:
7226: PDRIVER_INITIALIZE DriverInit;
7227: PDRIVER_STARTIO DriverStartIo;
7228: PDRIVER_UNLOAD DriverUnload;
7229: PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
7230: } DRIVER_OBJECT, *PDRIVER_OBJECT;
7231:
7232: //
7233: // The following structure is pointed to by the SectionObject pointer field
7234: // of a file object, and is allocated by the various NT file systems.
7235: //
7236:
7237: typedef struct _SECTION_OBJECT_POINTERS {
7238: PVOID DataSectionObject;
7239: PVOID SharedCacheMap;
7240: PVOID ImageSectionObject;
7241: } SECTION_OBJECT_POINTERS;
7242: typedef SECTION_OBJECT_POINTERS *PSECTION_OBJECT_POINTERS;
7243:
7244: //
7245: // Define File Object (FO) flags
7246: //
7247:
7248: #define FO_FILE_OPEN 0x00000001
7249: #define FO_SYNCHRONOUS_IO 0x00000002
7250: #define FO_ALERTABLE_IO 0x00000004
7251: #define FO_NO_INTERMEDIATE_BUFFERING 0x00000008
7252: #define FO_WRITE_THROUGH 0x00000010
7253: #define FO_SEQUENTIAL_ONLY 0x00000020
7254: #define FO_CACHE_SUPPORTED 0x00000040
7255: #define FO_NAMED_PIPE 0x00000080
7256: #define FO_STREAM_FILE 0x00000100
7257: #define FO_MAILSLOT 0x00000200
7258: #define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400
7259: #define FO_DIRECT_DEVICE_OPEN 0x00000800
7260: #define FO_FILE_MODIFIED 0x00001000
7261: #define FO_FILE_SIZE_CHANGED 0x00002000
7262: #define FO_CLEANUP_COMPLETE 0x00004000
7263: #define FO_TEMPORARY_FILE 0x00008000
7264: #define FO_DELETE_ON_CLOSE 0x00010000
7265: #define FO_OPENED_CASE_SENSITIVE 0x00020000
7266: #define FO_HANDLE_CREATED 0x00040000
7267: #define FO_FILE_FAST_IO_READ 0x00080000
7268:
7269: typedef struct _FILE_OBJECT {
7270: CSHORT Type;
7271: CSHORT Size;
7272: PDEVICE_OBJECT DeviceObject;
7273: PVPB Vpb;
7274: PVOID FsContext;
7275: PVOID FsContext2;
7276: PSECTION_OBJECT_POINTERS SectionObjectPointer;
7277: PVOID PrivateCacheMap;
7278: NTSTATUS FinalStatus;
7279: struct _FILE_OBJECT *RelatedFileObject;
7280: BOOLEAN LockOperation;
7281: BOOLEAN DeletePending;
7282: BOOLEAN ReadAccess;
7283: BOOLEAN WriteAccess;
7284: BOOLEAN DeleteAccess;
7285: BOOLEAN SharedRead;
7286: BOOLEAN SharedWrite;
7287: BOOLEAN SharedDelete;
7288: ULONG Flags;
7289: UNICODE_STRING FileName;
7290: LARGE_INTEGER CurrentByteOffset;
7291: ULONG Waiters;
7292: ULONG Busy;
7293: BOOLEAN Spare1;
7294: KEVENT Lock;
7295: KEVENT Event;
7296: } FILE_OBJECT, *PFILE_OBJECT;
7297:
7298: //
7299: // Define I/O Request Packet (IRP) flags
7300: //
7301:
7302: #define IRP_NOCACHE 0x00000001
7303: #define IRP_PAGING_IO 0x00000002
7304: #define IRP_MOUNT_COMPLETION 0x00000002
7305: #define IRP_SYNCHRONOUS_API 0x00000004
7306: #define IRP_ASSOCIATED_IRP 0x00000008
7307: #define IRP_BUFFERED_IO 0x00000010
7308: #define IRP_DEALLOCATE_BUFFER 0x00000020
7309: #define IRP_INPUT_OPERATION 0x00000040
7310: #define IRP_SYNCHRONOUS_PAGING_IO 0x00000040
7311: #define IRP_CREATE_OPERATION 0x00000080
7312: #define IRP_READ_OPERATION 0x00000100
7313: #define IRP_WRITE_OPERATION 0x00000200
7314: #define IRP_CLOSE_OPERATION 0x00000400
7315: #define IRP_DEFER_IO_COMPLETION 0x00000800
7316: #define IRP_OB_QUERY_NAME 0x00001000
7317:
7318: //
7319: // I/O Request Packet (IRP) definition
7320: //
7321:
7322: typedef struct _IRP {
7323: CSHORT Type;
7324: USHORT Size;
7325:
7326: //
7327: // Define the common fields used to control the IRP.
7328: //
7329:
7330: //
7331: // Define a pointer to the Memory Descriptor List (MDL) for this I/O
7332: // request. This field is only used if the I/O is "direct I/O".
7333: //
7334:
7335: PMDL MdlAddress;
7336:
7337: //
7338: // Flags word - used to remember various flags.
7339: //
7340:
7341: ULONG Flags;
7342:
7343: //
7344: // The following union is used for one of three purposes:
7345: //
7346: // 1. This IRP is an associated IRP. The field is a pointer to a master
7347: // IRP.
7348: //
7349: // 2. This is the master IRP. The field is the count of the number of
7350: // IRPs which must complete (associated IRPs) before the master can
7351: // complete.
7352: //
7353: // 3. This operation is being buffered and the field is the address of
7354: // the system space buffer.
7355: //
7356:
7357: union {
7358: struct _IRP *MasterIrp;
7359: LONG IrpCount;
7360: PVOID SystemBuffer;
7361: } AssociatedIrp;
7362:
7363: //
7364: // Thread list entry - allows queueing the IRP to the thread pending I/O
7365: // request packet list.
7366: //
7367:
7368: LIST_ENTRY ThreadListEntry;
7369:
7370: //
7371: // I/O status - final status of operation.
7372: //
7373:
7374: IO_STATUS_BLOCK IoStatus;
7375:
7376: //
7377: // Requestor mode - mode of the original requestor of this operation.
7378: //
7379:
7380: KPROCESSOR_MODE RequestorMode;
7381:
7382: //
7383: // Pending returned - TRUE if pending was initially returned as the
7384: // status for this packet.
7385: //
7386:
7387: BOOLEAN PendingReturned;
7388:
7389: //
7390: // Stack state information.
7391: //
7392:
7393: CCHAR StackCount;
7394: CCHAR CurrentLocation;
7395:
7396: //
7397: // Cancel - packet has been canceled.
7398: //
7399:
7400: BOOLEAN Cancel;
7401:
7402: //
7403: // Cancel Irql - Irql at which the cancel spinlock was acquired.
7404: //
7405:
7406: KIRQL CancelIrql;
7407:
7408: //
7409: // ApcEnvironment - Used to save the APC environment at the time that the
7410: // packet was initialized.
7411: //
7412:
7413: CCHAR ApcEnvironment;
7414:
7415: //
7416: // Zoned - packet was allocated from a zone.
7417: //
7418:
7419: BOOLEAN Zoned;
7420:
7421: //
7422: // User parameters.
7423: //
7424:
7425: PIO_STATUS_BLOCK UserIosb;
7426: PKEVENT UserEvent;
7427: union {
7428: struct {
7429: PIO_APC_ROUTINE UserApcRoutine;
7430: PVOID UserApcContext;
7431: } AsynchronousParameters;
7432: LARGE_INTEGER AllocationSize;
7433: } Overlay;
7434:
7435: //
7436: // CancelRoutine - Used to contain the address of a cancel routine supplied
7437: // by a device driver when the IRP is in a cancelable state.
7438: //
7439:
7440: PDRIVER_CANCEL CancelRoutine;
7441:
7442: //
7443: // Note that the UserBuffer parameter is outside of the stack so that I/O
7444: // completion can copy data back into the user's address space without
7445: // having to know exactly which service was being invoked. The length
7446: // of the copy is stored in the second half of the I/O status block. If
7447: // the UserBuffer field is NULL, then no copy is performed.
7448: //
7449:
7450: PVOID UserBuffer;
7451:
7452: //
7453: // Kernel structures
7454: //
7455: // The following section contains kernel structures which the IRP needs
7456: // in order to place various work information in kernel controller system
7457: // queues. Because the size and alignment cannot be controlled, they are
7458: // placed here at the end so they just hang off and do not affect the
7459: // alignment of other fields in the IRP.
7460: //
7461:
7462: union {
7463:
7464: struct {
7465:
7466: //
7467: // DeviceQueueEntry - The device queue entry field is used to queue
7468: // the IRP to the device driver device queue.
7469: //
7470:
7471: KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
7472:
7473: //
7474: // Thread - pointer to caller's Thread Control Block.
7475: //
7476:
7477: PETHREAD Thread;
7478:
7479: //
7480: // Auxillary buffer - pointer to any auxillary buffer that is
7481: // required to pass information to a driver that is not contained
7482: // in a normal buffer.
7483: //
7484:
7485: PCHAR AuxiliaryBuffer;
7486:
7487: //
7488: // List entry - used to queue the packet to completion queue, among
7489: // others.
7490: //
7491:
7492: LIST_ENTRY ListEntry;
7493:
7494: //
7495: // Current stack location - contains a pointer to the current
7496: // IO_STACK_LOCATION structure in the IRP stack. This field
7497: // should never be directly accessed by drivers. They should
7498: // use the standard functions.
7499: //
7500:
7501: struct _IO_STACK_LOCATION *CurrentStackLocation;
7502:
7503: //
7504: // Original file object - pointer to the original file object
7505: // that was used to open the file. This field is owned by the
7506: // I/O system and should not be used by any other drivers.
7507: //
7508:
7509: PFILE_OBJECT OriginalFileObject;
7510:
7511: } Overlay;
7512:
7513: //
7514: // APC - This APC control block is used for the special kernel APC as
7515: // well as for the caller's APC, if one was specified in the original
7516: // argument list. If so, then the APC is reused for the normal APC for
7517: // whatever mode the caller was in and the "special" routine that is
7518: // invoked before the APC gets control simply deallocates the IRP.
7519: //
7520:
7521: KAPC Apc;
7522:
7523: } Tail;
7524:
7525: } IRP, *PIRP;
7526:
7527: //
7528: // Define completion routine types for use in stack locations in an IRP
7529: //
7530:
7531: typedef
7532: NTSTATUS
7533: (*PIO_COMPLETION_ROUTINE) (
7534: IN PDEVICE_OBJECT DeviceObject,
7535: IN PIRP Irp,
7536: IN PVOID Context
7537: );
7538:
7539: //
7540: // Define stack location control flags
7541: //
7542:
7543: #define SL_PENDING_RETURNED 0x01
7544: #define SL_INVOKE_ON_CANCEL 0x20
7545: #define SL_INVOKE_ON_SUCCESS 0x40
7546: #define SL_INVOKE_ON_ERROR 0x80
7547:
7548: //
7549: // Define flags for various functions
7550: //
7551:
7552: //
7553: // Create / Create Named Pipe
7554: //
7555: // The following flags must exactly match those in the IoCreateFile call's
7556: // options. The case sensitive flag is added in later, by the parse routine,
7557: // and is not an actual option to open. Rather, it is part of the object
7558: // manager's attributes structure.
7559: //
7560:
7561: #define SL_FORCE_ACCESS_CHECK 0x01
7562: #define SL_OPEN_PAGING_FILE 0x02
7563: #define SL_OPEN_TARGET_DIRECTORY 0x04
7564:
7565: #define SL_CASE_SENSITIVE 0x80
7566:
7567: //
7568: // Read / Write
7569: //
7570:
7571: #define SL_KEY_SPECIFIED 0x01
7572: #define SL_OVERRIDE_VERIFY_VOLUME 0x02
7573: #define SL_WRITE_THROUGH 0x04
7574: #define SL_FT_SEQUENTIAL_WRITE 0x08
7575:
7576: //
7577: // Device I/O Control
7578: //
7579: //
7580: // Same SL_OVERRIDE_VERIFY_VOLUME as for read/write above.
7581: //
7582:
7583: //
7584: // Lock
7585: //
7586:
7587: #define SL_FAIL_IMMEDIATELY 0x01
7588: #define SL_EXCLUSIVE_LOCK 0x02
7589:
7590: //
7591: // QueryDirectory / QueryEa
7592: //
7593:
7594: #define SL_RESTART_SCAN 0x01
7595: #define SL_RETURN_SINGLE_ENTRY 0x02
7596: #define SL_INDEX_SPECIFIED 0x04
7597:
7598: //
7599: // NotifyDirectory
7600: //
7601:
7602: #define SL_WATCH_TREE 0x01
7603:
7604: //
7605: // FileSystemControl
7606: //
7607: // minor: mount/verify volume
7608: //
7609:
7610: #define SL_ALLOW_RAW_MOUNT 0x01
7611:
7612: //
7613: // Define I/O Request Packet (IRP) stack locations
7614: //
7615:
7616: #if !defined(_ALPHA_)
7617: #pragma pack(4)
7618: #endif
7619: typedef struct _IO_STACK_LOCATION {
7620: UCHAR MajorFunction;
7621: UCHAR MinorFunction;
7622: UCHAR Flags;
7623: UCHAR Control;
7624:
7625: //
7626: // The following user parameters are based on the service that is being
7627: // invoked. Drivers and file systems can determine which set to use based
7628: // on the above major and minor function codes.
7629: //
7630:
7631: union {
7632:
7633: //
7634: // System service parameters for: NtCreateFile
7635: //
7636:
7637: struct {
7638: PIO_SECURITY_CONTEXT SecurityContext;
7639: ULONG Options;
7640: USHORT FileAttributes;
7641: USHORT ShareAccess;
7642: ULONG EaLength;
7643: } Create;
7644:
7645:
7646: //
7647: // System service parameters for: NtReadFile
7648: //
7649:
7650: struct {
7651: ULONG Length;
7652: ULONG Key;
7653: LARGE_INTEGER ByteOffset;
7654: } Read;
7655:
7656: //
7657: // System service parameters for: NtWriteFile
7658: //
7659:
7660: struct {
7661: ULONG Length;
7662: ULONG Key;
7663: LARGE_INTEGER ByteOffset;
7664: } Write;
7665:
7666:
7667: //
7668: // System service parameters for: NtQueryInformationFile
7669: //
7670:
7671: struct {
7672: ULONG Length;
7673: FILE_INFORMATION_CLASS FileInformationClass;
7674: } QueryFile;
7675:
7676: //
7677: // System service parameters for: NtSetInformationFile
7678: //
7679:
7680: struct {
7681: ULONG Length;
7682: FILE_INFORMATION_CLASS FileInformationClass;
7683: PFILE_OBJECT FileObject;
7684: BOOLEAN ReplaceIfExists;
7685: BOOLEAN AdvanceOnly;
7686: } SetFile;
7687:
7688:
7689: //
7690: // System service parameters for: NtQueryVolumeInformationFile
7691: //
7692:
7693: struct {
7694: ULONG Length;
7695: FS_INFORMATION_CLASS FsInformationClass;
7696: } QueryVolume;
7697:
7698:
7699: //
7700: // System service parameters for: NtFlushBuffersFile
7701: //
7702: // No extra user-supplied parameters.
7703: //
7704:
7705:
7706: //
7707: // System service parameters for: NtDeviceIoControlFile
7708: //
7709: // Note that the user's output buffer is stored in the UserBuffer field
7710: // and the user's input buffer is stored in the SystemBuffer field.
7711: //
7712:
7713: struct {
7714: ULONG OutputBufferLength;
7715: ULONG InputBufferLength;
7716: ULONG IoControlCode;
7717: PVOID Type3InputBuffer;
7718: } DeviceIoControl;
7719:
7720: //
7721: // System service parameters for: NtQuerySecurityObject
7722: //
7723:
7724: struct {
7725: SECURITY_INFORMATION SecurityInformation;
7726: ULONG Length;
7727: } QuerySecurity;
7728:
7729: //
7730: // System service parameters for: NtSetSecurityObject
7731: //
7732:
7733: struct {
7734: SECURITY_INFORMATION SecurityInformation;
7735: PSECURITY_DESCRIPTOR SecurityDescriptor;
7736: } SetSecurity;
7737:
7738: //
7739: // Non-system service parameters.
7740: //
7741: // Parameters for MountVolume
7742: //
7743:
7744: struct {
7745: PVPB Vpb;
7746: PDEVICE_OBJECT DeviceObject;
7747: } MountVolume;
7748:
7749: //
7750: // Parameters for VerifyVolume
7751: //
7752:
7753: struct {
7754: PVPB Vpb;
7755: PDEVICE_OBJECT DeviceObject;
7756: } VerifyVolume;
7757:
7758: //
7759: // Parameters for Scsi with internal device contorl.
7760: //
7761:
7762: struct {
7763: struct _SCSI_REQUEST_BLOCK *Srb;
7764: } Scsi;
7765:
7766: //
7767: // Parameters for Cleanup
7768: //
7769: // No extra parameters supplied
7770: //
7771:
7772: //
7773: // Others - driver-specific
7774: //
7775:
7776: struct {
7777: PVOID Argument1;
7778: PVOID Argument2;
7779: PVOID Argument3;
7780: PVOID Argument4;
7781: } Others;
7782:
7783: } Parameters;
7784:
7785: //
7786: // Save a pointer to this device driver's device object for this request
7787: // so it can be passed to the completion routine if needed.
7788: //
7789:
7790: PDEVICE_OBJECT DeviceObject;
7791:
7792: //
7793: // The following location contains a pointer to the file object for this
7794: //
7795:
7796: PFILE_OBJECT FileObject;
7797:
7798: //
7799: // The following routine is invoked depending on the flags in the above
7800: // flags field.
7801: //
7802:
7803: PIO_COMPLETION_ROUTINE CompletionRoutine;
7804:
7805: //
7806: // The following is used to store the address of the context parameter
7807: // that should be passed to the CompletionRoutine.
7808: //
7809:
7810: PVOID Context;
7811:
7812: } IO_STACK_LOCATION, *PIO_STACK_LOCATION;
7813: #if !defined(_ALPHA_)
7814: #pragma pack()
7815: #endif
7816:
7817: //
7818: // Define the share access structure used by file systems to determine
7819: // whether or not another accessor may open the file.
7820: //
7821:
7822: typedef struct _SHARE_ACCESS {
7823: ULONG OpenCount;
7824: ULONG Readers;
7825: ULONG Writers;
7826: ULONG Deleters;
7827: ULONG SharedRead;
7828: ULONG SharedWrite;
7829: ULONG SharedDelete;
7830: } SHARE_ACCESS, *PSHARE_ACCESS;
7831:
7832: // begin_nthal
7833:
7834: //
7835: // The following structure is used by drivers that are initializing to
7836: // determine the number of devices of a particular type that have already
7837: // been initialized. It is also used to track whether or not the AtDisk
7838: // address range has already been claimed. Finally, it is used by the
7839: // NtQuerySystemInformation system service to return device type counts.
7840: //
7841:
7842: typedef struct _CONFIGURATION_INFORMATION {
7843:
7844: //
7845: // This field indicates the total number of disks in the system. This
7846: // number should be used by the driver to determine the name of new
7847: // disks. This field should be updated by the driver as it finds new
7848: // disks.
7849: //
7850:
7851: ULONG DiskCount; // Count of hard disks thus far
7852: ULONG FloppyCount; // Count of floppy disks thus far
7853: ULONG CdRomCount; // Count of CD-ROM drives thus far
7854: ULONG TapeCount; // Count of tape drives thus far
7855: ULONG ScsiPortCount; // Count of SCSI port adapters thus far
7856: ULONG SerialCount; // Count of serial devices thus far
7857: ULONG ParallelCount; // Count of parallel devices thus far
7858:
7859: //
7860: // These next two fields indicate ownership of one of the two IO address
7861: // spaces that are used by WD1003-compatable disk controllers.
7862: //
7863:
7864: BOOLEAN AtDiskPrimaryAddressClaimed; // 0x1F0 - 0x1FF
7865: BOOLEAN AtDiskSecondaryAddressClaimed; // 0x170 - 0x17F
7866:
7867: } CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION;
7868:
7869: //
7870: // Public I/O routine definitions
7871: //
7872:
7873: VOID
7874: IoAcquireCancelSpinLock(
7875: OUT PKIRQL Irql
7876: );
7877:
7878:
7879: NTSTATUS
7880: IoAllocateAdapterChannel(
7881: IN PADAPTER_OBJECT AdapterObject,
7882: IN PDEVICE_OBJECT DeviceObject,
7883: IN ULONG NumberOfMapRegisters,
7884: IN PDRIVER_CONTROL ExecutionRoutine,
7885: IN PVOID Context
7886: );
7887:
7888: VOID
7889: IoAllocateController(
7890: IN PCONTROLLER_OBJECT ControllerObject,
7891: IN PDEVICE_OBJECT DeviceObject,
7892: IN PDRIVER_CONTROL ExecutionRoutine,
7893: IN PVOID Context
7894: );
7895:
7896: PVOID
7897: IoAllocateErrorLogEntry(
7898: IN PVOID IoObject,
7899: IN UCHAR EntrySize
7900: );
7901:
7902: PIRP
7903: IoAllocateIrp(
7904: IN CCHAR StackSize,
7905: IN BOOLEAN ChargeQuota
7906: );
7907:
7908: PMDL
7909: IoAllocateMdl(
7910: IN PVOID VirtualAddress,
7911: IN ULONG Length,
7912: IN BOOLEAN SecondaryBuffer,
7913: IN BOOLEAN ChargeQuota,
7914: IN OUT PIRP Irp OPTIONAL
7915: );
7916:
7917: //++
7918: //
7919: // VOID
7920: // IoAssignArcName(
7921: // IN PUNICODE_STRING ArcName,
7922: // IN PUNICODE_STRING DeviceName
7923: // )
7924: //
7925: // Routine Description:
7926: //
7927: // This routine is invoked by drivers of bootable media to create a symbolic
7928: // link between the ARC name of their device and its NT name. This allows
7929: // the system to determine which device in the system was actually booted
7930: // from since the ARC firmware only deals in ARC names, and NT only deals
7931: // in NT names.
7932: //
7933: // Arguments:
7934: //
7935: // ArcName - Supplies the Unicode string representing the ARC name.
7936: //
7937: // DeviceName - Supplies the name to which the ARCname refers.
7938: //
7939: // Return Value:
7940: //
7941: // None.
7942: //
7943: //--
7944:
7945: #define IoAssignArcName( ArcName, DeviceName ) ( \
7946: IoCreateSymbolicLink( (ArcName), (DeviceName) ) )
7947:
7948: NTSTATUS
7949: IoAttachDevice(
7950: IN PDEVICE_OBJECT SourceDevice,
7951: IN PUNICODE_STRING TargetDevice,
7952: OUT PDEVICE_OBJECT *AttachedDevice
7953: );
7954:
7955: NTSTATUS
7956: IoAttachDeviceByPointer(
7957: IN PDEVICE_OBJECT SourceDevice,
7958: IN PDEVICE_OBJECT TargetDevice
7959: );
7960:
7961: PIRP
7962: IoBuildAsynchronousFsdRequest(
7963: IN ULONG MajorFunction,
7964: IN PDEVICE_OBJECT DeviceObject,
7965: IN OUT PVOID Buffer OPTIONAL,
7966: IN ULONG Length OPTIONAL,
7967: IN PLARGE_INTEGER StartingOffset OPTIONAL,
7968: IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL
7969: );
7970:
7971: PIRP
7972: IoBuildDeviceIoControlRequest(
7973: IN ULONG IoControlCode,
7974: IN PDEVICE_OBJECT DeviceObject,
7975: IN PVOID InputBuffer OPTIONAL,
7976: IN ULONG InputBufferLength,
7977: OUT PVOID OutputBuffer OPTIONAL,
7978: IN ULONG OutputBufferLength,
7979: IN BOOLEAN InternalDeviceIoControl,
7980: IN PKEVENT Event,
7981: OUT PIO_STATUS_BLOCK IoStatusBlock
7982: );
7983:
7984: VOID
7985: IoBuildPartialMdl(
7986: IN PMDL SourceMdl,
7987: IN OUT PMDL TargetMdl,
7988: IN PVOID VirtualAddress,
7989: IN ULONG Length
7990: );
7991:
7992: PIRP
7993: IoBuildSynchronousFsdRequest(
7994: IN ULONG MajorFunction,
7995: IN PDEVICE_OBJECT DeviceObject,
7996: IN OUT PVOID Buffer OPTIONAL,
7997: IN ULONG Length OPTIONAL,
7998: IN PLARGE_INTEGER StartingOffset OPTIONAL,
7999: IN PKEVENT Event,
8000: OUT PIO_STATUS_BLOCK IoStatusBlock
8001: );
8002:
8003: NTSTATUS
8004: IoCallDriver(
8005: IN PDEVICE_OBJECT DeviceObject,
8006: IN OUT PIRP Irp
8007: );
8008:
8009: BOOLEAN
8010: IoCancelIrp(
8011: IN PIRP Irp
8012: );
8013:
8014:
8015: NTSTATUS
8016: IoCheckShareAccess(
8017: IN ACCESS_MASK DesiredAccess,
8018: IN ULONG DesiredShareAccess,
8019: IN OUT PFILE_OBJECT FileObject,
8020: IN OUT PSHARE_ACCESS ShareAccess,
8021: IN BOOLEAN Update
8022: );
8023:
8024: VOID
8025: IoCompleteRequest(
8026: IN PIRP Irp,
8027: IN CCHAR PriorityBoost
8028: );
8029:
8030: NTSTATUS
8031: IoConnectInterrupt(
8032: OUT PKINTERRUPT *InterruptObject,
8033: IN PKSERVICE_ROUTINE ServiceRoutine,
8034: IN PVOID ServiceContext,
8035: IN PKSPIN_LOCK SpinLock OPTIONAL,
8036: IN ULONG Vector,
8037: IN KIRQL Irql,
8038: IN KIRQL SynchronizeIrql,
8039: IN KINTERRUPT_MODE InterruptMode,
8040: IN BOOLEAN ShareVector,
8041: IN KAFFINITY ProcessorEnableMask,
8042: IN BOOLEAN FloatingSave
8043: );
8044:
8045: PCONTROLLER_OBJECT
8046: IoCreateController(
8047: IN ULONG Size
8048: );
8049:
8050: NTSTATUS
8051: IoCreateDevice(
8052: IN PDRIVER_OBJECT DriverObject,
8053: IN ULONG DeviceExtensionSize,
8054: IN PUNICODE_STRING DeviceName OPTIONAL,
8055: IN DEVICE_TYPE DeviceType,
8056: IN ULONG DeviceCharacteristics,
8057: IN BOOLEAN Exclusive,
8058: OUT PDEVICE_OBJECT *DeviceObject
8059: );
8060:
8061:
8062: NTSTATUS
8063: IoCreateSymbolicLink(
8064: IN PUNICODE_STRING SymbolicLinkName,
8065: IN PUNICODE_STRING DeviceName
8066: );
8067:
8068: PKEVENT
8069: IoCreateSynchronizationEvent(
8070: IN PUNICODE_STRING EventName,
8071: OUT PHANDLE EventHandle
8072: );
8073:
8074: NTSTATUS
8075: IoCreateUnprotectedSymbolicLink(
8076: IN PUNICODE_STRING SymbolicLinkName,
8077: IN PUNICODE_STRING DeviceName
8078: );
8079:
8080: //++
8081: //
8082: // VOID
8083: // IoDeassignArcName(
8084: // IN PUNICODE_STRING ArcName
8085: // )
8086: //
8087: // Routine Description:
8088: //
8089: // This routine is invoked by drivers to deassign an ARC name that they
8090: // created to a device. This is generally only called if the driver is
8091: // deleting the device object, which means that the driver is probably
8092: // unloading.
8093: //
8094: // Arguments:
8095: //
8096: // ArcName - Supplies the ARC name to be removed.
8097: //
8098: // Return Value:
8099: //
8100: // None.
8101: //
8102: //--
8103:
8104: #define IoDeassignArcName( ArcName ) ( \
8105: IoDeleteSymbolicLink( (ArcName) ) )
8106:
8107: VOID
8108: IoDeleteController(
8109: IN PCONTROLLER_OBJECT ControllerObject
8110: );
8111:
8112: VOID
8113: IoDeleteDevice(
8114: IN PDEVICE_OBJECT DeviceObject
8115: );
8116:
8117: NTSTATUS
8118: IoDeleteSymbolicLink(
8119: IN PUNICODE_STRING SymbolicLinkName
8120: );
8121:
8122: VOID
8123: IoDetachDevice(
8124: IN OUT PDEVICE_OBJECT TargetDevice
8125: );
8126:
8127: VOID
8128: IoDisconnectInterrupt(
8129: IN PKINTERRUPT InterruptObject
8130: );
8131:
8132: VOID
8133: IoFreeController(
8134: IN PCONTROLLER_OBJECT ControllerObject
8135: );
8136:
8137: VOID
8138: IoFreeIrp(
8139: IN PIRP Irp
8140: );
8141:
8142: VOID
8143: IoFreeMdl(
8144: IN PMDL Mdl
8145: );
8146:
8147: PCONFIGURATION_INFORMATION
8148: IoGetConfigurationInformation( VOID );
8149:
8150: //++
8151: //
8152: // PIO_STACK_LOCATION
8153: // IoGetCurrentIrpStackLocation(
8154: // IN PIRP Irp
8155: // )
8156: //
8157: // Routine Description:
8158: //
8159: // This routine is invoked to return a pointer to the current stack location
8160: // in an I/O Request Packet (IRP).
8161: //
8162: // Arguments:
8163: //
8164: // Irp - Pointer to the I/O Request Packet.
8165: //
8166: // Return Value:
8167: //
8168: // The function value is a pointer to the current stack location in the
8169: // packet.
8170: //
8171: //--
8172:
8173: #define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation )
8174:
8175: // end_nthal
8176:
8177: PEPROCESS
8178: IoGetCurrentProcess(
8179: VOID
8180: );
8181:
8182: // begin_nthal
8183:
8184: NTSTATUS
8185: IoGetDeviceObjectPointer(
8186: IN PUNICODE_STRING ObjectName,
8187: IN ACCESS_MASK DesiredAccess,
8188: OUT PFILE_OBJECT *FileObject,
8189: OUT PDEVICE_OBJECT *DeviceObject
8190: );
8191:
8192: //++
8193: //
8194: // PIO_STACK_LOCATION
8195: // IoGetNextIrpStackLocation(
8196: // IN PIRP Irp
8197: // )
8198: //
8199: // Routine Description:
8200: //
8201: // This routine is invoked to return a pointer to the next stack location
8202: // in an I/O Request Packet (IRP).
8203: //
8204: // Arguments:
8205: //
8206: // Irp - Pointer to the I/O Request Packet.
8207: //
8208: // Return Value:
8209: //
8210: // The function value is a pointer to the next stack location in the packet.
8211: //
8212: //--
8213:
8214: #define IoGetNextIrpStackLocation( Irp ) (\
8215: (Irp)->Tail.Overlay.CurrentStackLocation - 1 )
8216:
8217: PDEVICE_OBJECT
8218: IoGetRelatedDeviceObject(
8219: IN PFILE_OBJECT FileObject
8220: );
8221:
8222:
8223: //++
8224: //
8225: // VOID
8226: // IoInitializeDpcRequest(
8227: // IN PDEVICE_OBJECT DeviceObject,
8228: // IN PIO_DPC_ROUTINE DpcRoutine
8229: // )
8230: //
8231: // Routine Description:
8232: //
8233: // This routine is invoked to initialize the DPC in a device object for a
8234: // device driver during its initialization routine. The DPC is used later
8235: // when the driver interrupt service routine requests that a DPC routine
8236: // be queued for later execution.
8237: //
8238: // Arguments:
8239: //
8240: // DeviceObject - Pointer to the device object that the request is for.
8241: //
8242: // DpcRoutine - Address of the driver's DPC routine to be executed when
8243: // the DPC is dequeued for processing.
8244: //
8245: // Return Value:
8246: //
8247: // None.
8248: //
8249: //--
8250:
8251: #define IoInitializeDpcRequest( DeviceObject, DpcRoutine ) (\
8252: KeInitializeDpc( &(DeviceObject)->Dpc, \
8253: (PKDEFERRED_ROUTINE) (DpcRoutine), \
8254: (DeviceObject) ) )
8255:
8256: VOID
8257: IoInitializeIrp(
8258: IN OUT PIRP Irp,
8259: IN USHORT PacketSize,
8260: IN CCHAR StackSize
8261: );
8262:
8263: NTSTATUS
8264: IoInitializeTimer(
8265: IN PDEVICE_OBJECT DeviceObject,
8266: IN PIO_TIMER_ROUTINE TimerRoutine,
8267: IN PVOID Context
8268: );
8269:
8270:
8271: //++
8272: //
8273: // BOOLEAN
8274: // IoIsErrorUserInduced(
8275: // IN NTSTATUS Status
8276: // )
8277: //
8278: // Routine Description:
8279: //
8280: // This routine is invoked to determine if an error was as a
8281: // result of user actions. Typically these error are related
8282: // to removable media and will result in a pop-up.
8283: //
8284: // Arguments:
8285: //
8286: // Status - The status value to check.
8287: //
8288: // Return Value:
8289: //
8290: // The function value is TRUE if the user induced the error,
8291: // otherwise FALSE is returned.
8292: //
8293: //--
8294: #define IoIsErrorUserInduced( Status ) ((BOOLEAN) \
8295: (((Status) == STATUS_DEVICE_NOT_READY) || \
8296: ((Status) == STATUS_IO_TIMEOUT) || \
8297: ((Status) == STATUS_MEDIA_WRITE_PROTECTED) || \
8298: ((Status) == STATUS_NO_MEDIA_IN_DEVICE) || \
8299: ((Status) == STATUS_VERIFY_REQUIRED) || \
8300: ((Status) == STATUS_UNRECOGNIZED_MEDIA) || \
8301: ((Status) == STATUS_WRONG_VOLUME)))
8302:
8303:
8304: PIRP
8305: IoMakeAssociatedIrp(
8306: IN PIRP Irp,
8307: IN CCHAR StackSize
8308: );
8309:
8310: //++
8311: //
8312: // VOID
8313: // IoMarkIrpPending(
8314: // IN OUT PIRP Irp
8315: // )
8316: //
8317: // Routine Description:
8318: //
8319: // This routine marks the specified I/O Request Packet (IRP) to indicate
8320: // that an initial status of STATUS_PENDING was returned to the caller.
8321: // This is used so that I/O completion can determine whether or not to
8322: // fully complete the I/O operation requested by the packet.
8323: //
8324: // Arguments:
8325: //
8326: // Irp - Pointer to the I/O Request Packet to be marked pending.
8327: //
8328: // Return Value:
8329: //
8330: // None.
8331: //
8332: //--
8333:
8334: #define IoMarkIrpPending( Irp ) ( \
8335: IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )
8336:
8337: NTSTATUS
8338: IoQueryDeviceDescription(
8339: IN PINTERFACE_TYPE BusType OPTIONAL,
8340: IN PULONG BusNumber OPTIONAL,
8341: IN PCONFIGURATION_TYPE ControllerType OPTIONAL,
8342: IN PULONG ControllerNumber OPTIONAL,
8343: IN PCONFIGURATION_TYPE PeripheralType OPTIONAL,
8344: IN PULONG PeripheralNumber OPTIONAL,
8345: IN PIO_QUERY_DEVICE_ROUTINE CalloutRoutine,
8346: IN PVOID Context
8347: );
8348: VOID
8349: IoRaiseHardError(
8350: IN PIRP Irp,
8351: IN PVPB Vpb OPTIONAL,
8352: IN PDEVICE_OBJECT RealDeviceObject
8353: );
8354:
8355: VOID
8356: IoRaiseInformationalHardError(
8357: IN NTSTATUS ErrorStatus,
8358: IN PUNICODE_STRING String OPTIONAL,
8359: IN PKTHREAD Thread OPTIONAL
8360: );
8361:
8362: VOID
8363: IoRegisterDriverReinitialization(
8364: IN PDRIVER_OBJECT DriverObject,
8365: IN PDRIVER_REINITIALIZE DriverReinitializationRoutine,
8366: IN PVOID Context
8367: );
8368:
8369: NTSTATUS
8370: IoRegisterShutdownNotification(
8371: IN PDEVICE_OBJECT DeviceObject
8372: );
8373:
8374: VOID
8375: IoReleaseCancelSpinLock(
8376: IN KIRQL Irql
8377: );
8378:
8379:
8380: VOID
8381: IoRemoveShareAccess(
8382: IN PFILE_OBJECT FileObject,
8383: IN OUT PSHARE_ACCESS ShareAccess
8384: );
8385:
8386:
8387: NTSTATUS
8388: IoReportResourceUsage(
8389: IN PUNICODE_STRING DriverClassName OPTIONAL,
8390: IN PDRIVER_OBJECT DriverObject,
8391: IN PCM_RESOURCE_LIST DriverList OPTIONAL,
8392: IN ULONG DriverListSize OPTIONAL,
8393: IN PDEVICE_OBJECT DeviceObject,
8394: IN PCM_RESOURCE_LIST DeviceList OPTIONAL,
8395: IN ULONG DeviceListSize OPTIONAL,
8396: IN BOOLEAN OverrideConflict,
8397: OUT PBOOLEAN ConflictDetected
8398: );
8399:
8400: //++
8401: //
8402: // VOID
8403: // IoRequestDpc(
8404: // IN PDEVICE_OBJECT DeviceObject,
8405: // IN PIRP Irp,
8406: // IN PVOID Context
8407: // )
8408: //
8409: // Routine Description:
8410: //
8411: // This routine is invoked by the device driver's interrupt service routine
8412: // to request that a DPC routine be queued for later execution at a lower
8413: // IRQL.
8414: //
8415: // Arguments:
8416: //
8417: // DeviceObject - Device object for which the request is being processed.
8418: //
8419: // Irp - Pointer to the current I/O Request Packet (IRP) for the specified
8420: // device.
8421: //
8422: // Context - Provides a general context parameter to be passed to the
8423: // DPC routine.
8424: //
8425: // Return Value:
8426: //
8427: // None.
8428: //
8429: //--
8430:
8431: #define IoRequestDpc( DeviceObject, Irp, Context ) ( \
8432: KeInsertQueueDpc( &(DeviceObject)->Dpc, (Irp), (Context) ) )
8433:
8434: //++
8435: //
8436: // VOID
8437: // IoSetCancelRoutine(
8438: // IN PIRP Irp,
8439: // IN PDRIVER_CANCEL CancelRoutine
8440: // )
8441: //
8442: // Routine Description:
8443: //
8444: // This routine is invoked to set the address of a cancel routine which
8445: // is to be invoked when an I/O packet has been canceled.
8446: //
8447: // Arguments:
8448: //
8449: // Irp - Pointer to the I/O Request Packet itself.
8450: //
8451: // CancelRoutine - Address of the cancel routine that is to be invoked
8452: // if the IRP is cancelled.
8453: //
8454: // Return Value:
8455: //
8456: // None.
8457: //
8458: // Note:
8459: //
8460: // The I/O cancel spin lock must be held when this routine is invoked.
8461: //
8462: //--
8463:
8464: #define IoSetCancelRoutine( Irp, NewCancelRoutine ) ( \
8465: (Irp)->CancelRoutine = (NewCancelRoutine) )
8466:
8467: //++
8468: //
8469: // VOID
8470: // IoSetCompletionRoutine(
8471: // IN PIRP Irp,
8472: // IN PIO_COMPLETION_ROUTINE CompletionRoutine,
8473: // IN PVOID Context,
8474: // IN BOOLEAN InvokeOnSuccess,
8475: // IN BOOLEAN InvokeOnError,
8476: // IN BOOLEAN InvokeOnCancel
8477: // )
8478: //
8479: // Routine Description:
8480: //
8481: // This routine is invoked to set the address of a completion routine which
8482: // is to be invoked when an I/O packet has been completed by a lower-level
8483: // driver.
8484: //
8485: // Arguments:
8486: //
8487: // Irp - Pointer to the I/O Request Packet itself.
8488: //
8489: // CompletionRoutine - Address of the completion routine that is to be
8490: // invoked once the next level driver completes the packet.
8491: //
8492: // Context - Specifies a context parameter to be passed to the completion
8493: // routine.
8494: //
8495: // InvokeOnSuccess - Specifies that the completion routine is invoked when the
8496: // operation is successfully completed.
8497: //
8498: // InvokeOnError - Specifies that the completion routine is invoked when the
8499: // operation completes with an error status.
8500: //
8501: // InvokeOnCancel - Specifies that the completion routine is invoked when the
8502: // operation is being canceled.
8503: //
8504: // Return Value:
8505: //
8506: // None.
8507: //
8508: //--
8509:
8510: #define IoSetCompletionRoutine( Irp, Routine, CompletionContext, Success, Error, Cancel ) { \
8511: PIO_STACK_LOCATION irpSp; \
8512: ASSERT( (Success) | (Error) | (Cancel) ? (Routine) != NULL : TRUE ); \
8513: irpSp = IoGetNextIrpStackLocation( (Irp) ); \
8514: irpSp->CompletionRoutine = (Routine); \
8515: irpSp->Context = (CompletionContext); \
8516: irpSp->Control = 0; \
8517: if ((Success)) { irpSp->Control = SL_INVOKE_ON_SUCCESS; } \
8518: if ((Error)) { irpSp->Control |= SL_INVOKE_ON_ERROR; } \
8519: if ((Cancel)) { irpSp->Control |= SL_INVOKE_ON_CANCEL; } }
8520:
8521: VOID
8522: IoSetHardErrorOrVerifyDevice(
8523: IN PIRP Irp,
8524: IN PDEVICE_OBJECT DeviceObject
8525: );
8526:
8527:
8528: //++
8529: //
8530: // VOID
8531: // IoSetNextIrpStackLocation (
8532: // IN OUT PIRP Irp
8533: // )
8534: //
8535: // Routine Description:
8536: //
8537: // This routine is invoked to set the current IRP stack location to
8538: // the next stack location, i.e. it "pushes" the stack.
8539: //
8540: // Arguments:
8541: //
8542: // Irp - Pointer to the I/O Request Packet (IRP).
8543: //
8544: // Return Value:
8545: //
8546: // None.
8547: //
8548: //--
8549:
8550: #define IoSetNextIrpStackLocation( Irp ) { \
8551: (Irp)->CurrentLocation--; \
8552: (Irp)->Tail.Overlay.CurrentStackLocation--; }
8553:
8554: VOID
8555: IoSetShareAccess(
8556: IN ACCESS_MASK DesiredAccess,
8557: IN ULONG DesiredShareAccess,
8558: IN OUT PFILE_OBJECT FileObject,
8559: OUT PSHARE_ACCESS ShareAccess
8560: );
8561:
8562:
8563: //++
8564: //
8565: // USHORT
8566: // IoSizeOfIrp(
8567: // IN CCHAR StackSize
8568: // )
8569: //
8570: // Routine Description:
8571: //
8572: // Determines the size of an IRP given the number of stack locations
8573: // the IRP will have.
8574: //
8575: // Arguments:
8576: //
8577: // StackSize - Number of stack locations for the IRP.
8578: //
8579: // Return Value:
8580: //
8581: // Size in bytes of the IRP.
8582: //
8583: //--
8584:
8585: #define IoSizeOfIrp( StackSize ) \
8586: ((USHORT) (sizeof( IRP ) + ((StackSize) * (sizeof( IO_STACK_LOCATION )))))
8587:
8588: VOID
8589: IoStartNextPacket(
8590: IN PDEVICE_OBJECT DeviceObject,
8591: IN BOOLEAN Cancelable
8592: );
8593:
8594: VOID
8595: IoStartNextPacketByKey(
8596: IN PDEVICE_OBJECT DeviceObject,
8597: IN BOOLEAN Cancelable,
8598: IN ULONG Key
8599: );
8600:
8601: VOID
8602: IoStartPacket(
8603: IN PDEVICE_OBJECT DeviceObject,
8604: IN PIRP Irp,
8605: IN PULONG Key OPTIONAL,
8606: IN PDRIVER_CANCEL CancelFunction OPTIONAL
8607: );
8608:
8609: VOID
8610: IoStartTimer(
8611: IN PDEVICE_OBJECT DeviceObject
8612: );
8613:
8614: VOID
8615: IoStopTimer(
8616: IN PDEVICE_OBJECT DeviceObject
8617: );
8618:
8619: VOID
8620: IoUnregisterShutdownNotification(
8621: IN PDEVICE_OBJECT DeviceObject
8622: );
8623:
8624: VOID
8625: IoUpdateShareAccess(
8626: IN PFILE_OBJECT FileObject,
8627: IN OUT PSHARE_ACCESS ShareAccess
8628: );
8629:
8630: VOID
8631: IoWriteErrorLogEntry(
8632: IN PVOID ElEntry
8633: );
8634: //
8635: // The following definitions are for HAL structures.
8636: //
8637:
8638: // begin_ntminiport
8639: //
8640: // Define types of bus information.
8641: //
8642:
8643: typedef enum _BUS_DATA_TYPE {
8644: Cmos,
8645: EisaConfiguration,
8646: Pos,
8647: CbusConfiguration,
8648: PCIConfiguration,
8649: VMEConfiguration,
8650: NuBusConfiguration,
8651: PCMCIAConfiguration,
8652: MPIConfiguration,
8653: MPSAConfiguration,
8654: MaximumBusDataType
8655: } BUS_DATA_TYPE, *PBUS_DATA_TYPE;
8656:
8657: //
8658: // Define the device description structure.
8659: //
8660:
8661: typedef struct _DEVICE_DESCRIPTION {
8662: ULONG Version;
8663: BOOLEAN Master;
8664: BOOLEAN ScatterGather;
8665: BOOLEAN DemandMode;
8666: BOOLEAN AutoInitialize;
8667: BOOLEAN Dma32BitAddresses;
8668: ULONG BusNumber;
8669: ULONG DmaChannel;
8670: INTERFACE_TYPE InterfaceType;
8671: DMA_WIDTH DmaWidth;
8672: DMA_SPEED DmaSpeed;
8673: ULONG MaximumLength;
8674: ULONG DmaPort;
8675: } DEVICE_DESCRIPTION, *PDEVICE_DESCRIPTION;
8676:
8677: //
8678: // Define the supported version numbers for the device description structure.
8679: //
8680:
8681: #define DEVICE_DESCRIPTION_VERSION 0
8682:
8683: //
8684: // The following function prototypes are for HAL routines with a prefix of Hal.
8685: //
8686: // General functions.
8687: //
8688:
8689: VOID
8690: HalAcquireDisplayOwnership (
8691: VOID
8692: );
8693:
8694: #if defined(_MIPS_) || defined(_ALPHA_)
8695:
8696: ULONG
8697: HalGetDmaAlignmentRequirement (
8698: VOID
8699: );
8700:
8701: #endif
8702:
8703: #if defined(_M_IX86)
8704:
8705: #define HalGetDmaAlignmentRequirement() 1L
8706:
8707: #endif
8708:
8709: VOID
8710: KeFlushWriteBuffer (
8711: VOID
8712: );
8713:
8714: //
8715: // I/O driver configuration functions.
8716: //
8717:
8718: ULONG
8719: HalGetInterruptVector(
8720: IN INTERFACE_TYPE InterfaceType,
8721: IN ULONG BusNumber,
8722: IN ULONG BusInterruptLevel,
8723: IN ULONG BusInterruptVector,
8724: OUT PKIRQL Irql,
8725: OUT PKAFFINITY Affinity
8726: );
8727:
8728: BOOLEAN
8729: HalTranslateBusAddress(
8730: IN INTERFACE_TYPE InterfaceType,
8731: IN ULONG BusNumber,
8732: IN PHYSICAL_ADDRESS BusAddress,
8733: IN OUT PULONG AddressSpace,
8734: OUT PPHYSICAL_ADDRESS TranslatedAddress
8735: );
8736:
8737: PVOID
8738: HalAllocateCommonBuffer(
8739: IN PADAPTER_OBJECT AdapterObject,
8740: IN ULONG Length,
8741: OUT PPHYSICAL_ADDRESS LogicalAddress,
8742: IN BOOLEAN CacheEnabled
8743: );
8744:
8745: VOID
8746: HalFreeCommonBuffer(
8747: IN PADAPTER_OBJECT AdapterObject,
8748: IN ULONG Length,
8749: IN PHYSICAL_ADDRESS LogicalAddress,
8750: IN PVOID VirtualAddress,
8751: IN BOOLEAN CacheEnabled
8752: );
8753:
8754: ULONG
8755: HalGetBusData(
8756: IN BUS_DATA_TYPE BusDataType,
8757: IN ULONG BusNumber,
8758: IN ULONG SlotNumber,
8759: IN PVOID Buffer,
8760: IN ULONG Length
8761: );
8762:
8763: PADAPTER_OBJECT
8764: HalGetAdapter(
8765: IN PDEVICE_DESCRIPTION DeviceDescription,
8766: IN OUT PULONG NumberOfMapRegisters
8767: );
8768:
8769: //
8770: // The following function prototypes are for HAL routines with a prefix of Io.
8771: //
8772: // DMA adapter object functions.
8773: //
8774:
8775: ULONG
8776: HalReadDmaCounter(
8777: IN PADAPTER_OBJECT AdapterObject
8778: );
8779:
8780: BOOLEAN
8781: IoFlushAdapterBuffers(
8782: IN PADAPTER_OBJECT AdapterObject,
8783: IN PMDL Mdl,
8784: IN PVOID MapRegisterBase,
8785: IN PVOID CurrentVa,
8786: IN ULONG Length,
8787: IN BOOLEAN WriteToDevice
8788: );
8789:
8790: VOID
8791: IoFreeAdapterChannel(
8792: IN PADAPTER_OBJECT AdapterObject
8793: );
8794:
8795: VOID
8796: IoFreeMapRegisters(
8797: IN PADAPTER_OBJECT AdapterObject,
8798: IN PVOID MapRegisterBase,
8799: IN ULONG NumberOfMapRegisters
8800: );
8801:
8802: PHYSICAL_ADDRESS
8803: IoMapTransfer(
8804: IN PADAPTER_OBJECT AdapterObject,
8805: IN PMDL Mdl,
8806: IN PVOID MapRegisterBase,
8807: IN PVOID CurrentVa,
8808: IN OUT PULONG Length,
8809: IN BOOLEAN WriteToDevice
8810: );
8811:
8812: NTSTATUS
8813: IoReadPartitionTable(
8814: IN PDEVICE_OBJECT DeviceObject,
8815: IN ULONG SectorSize,
8816: IN BOOLEAN ReturnRecognizedPartitions,
8817: OUT struct _DRIVE_LAYOUT_INFORMATION **PartitionBuffer
8818: );
8819:
8820: NTSTATUS
8821: IoSetPartitionInformation(
8822: IN PDEVICE_OBJECT DeviceObject,
8823: IN ULONG SectorSize,
8824: IN ULONG PartitionNumber,
8825: IN ULONG PartitionType
8826: );
8827:
8828: NTSTATUS
8829: IoWritePartitionTable(
8830: IN PDEVICE_OBJECT DeviceObject,
8831: IN ULONG SectorSize,
8832: IN ULONG SectorsPerTrack,
8833: IN ULONG NumberOfHeads,
8834: IN struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer
8835: );
8836:
8837: //
8838: // Performance counter function.
8839: //
8840:
8841: LARGE_INTEGER
8842: KeQueryPerformanceCounter (
8843: IN PLARGE_INTEGER PerformanceFrequency OPTIONAL
8844: );
8845:
8846: //
8847: // Stall processor execution function.
8848: //
8849:
8850: VOID
8851: KeStallExecutionProcessor (
8852: IN ULONG MicroSeconds
8853: );
8854:
8855: //
8856: // Determine if there is a complete device failure on an error.
8857: //
8858:
8859: BOOLEAN
8860: FsRtlIsTotalDeviceFailure(
8861: IN NTSTATUS Status
8862: );
8863:
8864: //
8865: // Object Manager types
8866: //
8867:
8868: typedef struct _OBJECT_HANDLE_INFORMATION {
8869: ULONG HandleAttributes;
8870: ACCESS_MASK GrantedAccess;
8871: } OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION;
8872:
8873: NTSTATUS
8874: ObReferenceObjectByHandle(
8875: IN HANDLE Handle,
8876: IN ACCESS_MASK DesiredAccess,
8877: IN POBJECT_TYPE ObjectType OPTIONAL,
8878: IN KPROCESSOR_MODE AccessMode,
8879: OUT PVOID *Object,
8880: OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
8881: );
8882: NTSTATUS
8883: ObReferenceObjectByPointer(
8884: IN PVOID Object,
8885: IN ACCESS_MASK DesiredAccess,
8886: IN POBJECT_TYPE ObjectType,
8887: IN KPROCESSOR_MODE AccessMode
8888: );
8889: VOID
8890: ObDereferenceObject(
8891: IN PVOID Object
8892: );
8893:
8894: //
8895: // Define exported ZwXxx routines to device drivers.
8896: //
8897:
8898: NTSTATUS
8899: ZwClose(
8900: IN HANDLE Handle
8901: );
8902:
8903: NTSTATUS
8904: ZwCreateDirectoryObject(
8905: OUT PHANDLE DirectoryHandle,
8906: IN ACCESS_MASK DesiredAccess,
8907: IN POBJECT_ATTRIBUTES ObjectAttributes
8908: );
8909:
8910: NTSTATUS
8911: ZwMakeTemporaryObject(
8912: IN HANDLE Handle
8913: );
8914:
8915: NTSTATUS
8916: ZwOpenSection(
8917: OUT PHANDLE SectionHandle,
8918: IN ACCESS_MASK DesiredAccess,
8919: IN POBJECT_ATTRIBUTES ObjectAttributes
8920: );
8921:
8922: NTSTATUS
8923: ZwMapViewOfSection(
8924: IN HANDLE SectionHandle,
8925: IN HANDLE ProcessHandle,
8926: IN OUT PVOID *BaseAddress,
8927: IN ULONG ZeroBits,
8928: IN ULONG CommitSize,
8929: IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
8930: IN OUT PULONG ViewSize,
8931: IN SECTION_INHERIT InheritDisposition,
8932: IN ULONG AllocationType,
8933: IN ULONG Protect
8934: );
8935:
8936: NTSTATUS
8937: ZwUnmapViewOfSection(
8938: IN HANDLE ProcessHandle,
8939: IN PVOID BaseAddress
8940: );
8941:
8942: NTSTATUS
8943: ZwCreateKey(
8944: OUT PHANDLE KeyHandle,
8945: IN ACCESS_MASK DesiredAccess,
8946: IN POBJECT_ATTRIBUTES ObjectAttributes,
8947: IN ULONG TitleIndex,
8948: IN PUNICODE_STRING Class OPTIONAL,
8949: IN ULONG CreateOptions,
8950: OUT PULONG Disposition OPTIONAL
8951: );
8952:
8953: NTSTATUS
8954: ZwOpenKey(
8955: OUT PHANDLE KeyHandle,
8956: IN ACCESS_MASK DesiredAccess,
8957: IN POBJECT_ATTRIBUTES ObjectAttributes
8958: );
8959:
8960: NTSTATUS
8961: ZwEnumerateKey(
8962: IN HANDLE KeyHandle,
8963: IN ULONG Index,
8964: IN KEY_INFORMATION_CLASS KeyInformationClass,
8965: OUT PVOID KeyInformation,
8966: IN ULONG Length,
8967: OUT PULONG ResultLength
8968: );
8969:
8970: NTSTATUS
8971: ZwEnumerateValueKey(
8972: IN HANDLE KeyHandle,
8973: IN ULONG Index,
8974: IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
8975: OUT PVOID KeyValueInformation,
8976: IN ULONG Length,
8977: OUT PULONG ResultLength
8978: );
8979:
8980: NTSTATUS
8981: ZwFlushKey(
8982: IN HANDLE KeyHandle
8983: );
8984:
8985: NTSTATUS
8986: NTAPI
8987: ZwQueryKey(
8988: IN HANDLE KeyHandle,
8989: IN KEY_INFORMATION_CLASS KeyInformationClass,
8990: OUT PVOID KeyInformation,
8991: IN ULONG Length,
8992: OUT PULONG ResultLength
8993: );
8994:
8995: NTSTATUS
8996: ZwQueryValueKey(
8997: IN HANDLE KeyHandle,
8998: OUT PUNICODE_STRING ValueName,
8999: IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
9000: OUT PVOID KeyValueInformation,
9001: IN ULONG Length,
9002: OUT PULONG ResultLength
9003: );
9004:
9005: NTSTATUS
9006: ZwSetValueKey(
9007: IN HANDLE KeyHandle,
9008: IN PUNICODE_STRING ValueName,
9009: IN ULONG TitleIndex OPTIONAL,
9010: IN ULONG Type,
9011: IN PVOID Data,
9012: IN ULONG DataSize
9013: );
9014:
9015:
9016: #endif // _NTDDK_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.