xref: /reactos/ntoskrnl/include/internal/io.h (revision 3476cdae)
1 /*
2 * PROJECT:         ReactOS Kernel
3 * LICENSE:         GPL - See COPYING in the top level directory
4 * FILE:            ntoskrnl/include/internal/io.h
5 * PURPOSE:         Internal header for the I/O Manager
6 * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
7 */
8 
9 #include "ntdddisk.h"
10 
11 //
12 // Define this if you want debugging support
13 //
14 #define _IO_DEBUG_                                      0x00
15 
16 //
17 // These define the Debug Masks Supported
18 //
19 #define IO_IRP_DEBUG                                    0x01
20 #define IO_FILE_DEBUG                                   0x02
21 #define IO_API_DEBUG                                    0x04
22 #define IO_CTL_DEBUG                                    0x08
23 
24 //
25 // Debug/Tracing support
26 //
27 #if _IO_DEBUG_
28 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
29 #define IOTRACE(x, ...)                                     \
30     {                                                       \
31         DbgPrintEx("%s [%.16s] - ",                         \
32                    __FUNCTION__,                            \
33                    PsGetCurrentProcess()->ImageFileName);   \
34         DbgPrintEx(__VA_ARGS__);                            \
35     }
36 #else
37 #define IOTRACE(x, ...)                                     \
38     if (x & IopTraceLevel)                                  \
39     {                                                       \
40         DbgPrint("%s [%.16s] - ",                           \
41                  __FUNCTION__,                              \
42                  PsGetCurrentProcess()->ImageFileName);     \
43         DbgPrint(__VA_ARGS__);                              \
44     }
45 #endif
46 #else
47 #define IOTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
48 #endif
49 
50 //
51 // Registry path to the enumeration root key
52 //
53 #define ENUM_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum"
54 
55 //
56 // Returns the type of METHOD_ used in this IOCTL
57 //
58 #define IO_METHOD_FROM_CTL_CODE(c)                      (c & 0x00000003)
59 
60 //
61 // Bugcheck codes for RAM disk booting
62 //
63 //
64 // No LoaderXIPRom descriptor was found in the loader memory list
65 //
66 #define RD_NO_XIPROM_DESCRIPTOR  1
67 //
68 // Unable to open the RAM disk driver (ramdisk.sys or \Device\Ramdisk)
69 //
70 #define RD_NO_RAMDISK_DRIVER     2
71 //
72 // FSCTL_CREATE_RAM_DISK failed
73 //
74 #define RD_FSCTL_FAILED          3
75 //
76 // Unable to create GUID string from binary GUID
77 //
78 #define RD_GUID_CONVERT_FAILED   4
79 //
80 // Unable to create symbolic link pointing to the RAM disk device
81 //
82 #define RD_SYMLINK_CREATE_FAILED 5
83 
84 //
85 // Max traversal of reparse points for a single open in IoParseDevice
86 //
87 #define IOP_MAX_REPARSE_TRAVERSAL 0x20
88 
89 //
90 // Private flags for IoCreateFile / IoParseDevice
91 //
92 #define IOP_USE_TOP_LEVEL_DEVICE_HINT       0x01
93 #define IOP_CREATE_FILE_OBJECT_EXTENSION    0x02
94 
95 
96 typedef struct _FILE_OBJECT_EXTENSION
97 {
98     PDEVICE_OBJECT TopDeviceObjectHint;
99     PVOID FilterContext;
100 
101 } FILE_OBJECT_EXTENSION, *PFILE_OBJECT_EXTENSION;
102 
103 
104 
105 //
106 // We can call the Ob Inlined API, it's the same thing
107 //
108 #define IopAllocateMdlFromLookaside                     \
109     ObpAllocateObjectCreateInfoBuffer
110 #define IopFreeMdlFromLookaside                         \
111     ObpFreeCapturedAttributes
112 
113 //
114 // Determines if the IRP is Synchronous
115 //
116 #define IsIrpSynchronous(Irp, FileObject)               \
117     ((Irp->Flags & IRP_SYNCHRONOUS_API)  ||             \
118      (!(FileObject) ?                                   \
119         FALSE :                                         \
120         FileObject->Flags & FO_SYNCHRONOUS_IO))         \
121 
122 //
123 // Returns the internal Device Object Extension
124 //
125 #define IoGetDevObjExtension(DeviceObject)              \
126     ((PEXTENDED_DEVOBJ_EXTENSION)                       \
127      (DeviceObject->DeviceObjectExtension))             \
128 
129 //
130 // Returns the internal Driver Object Extension
131 //
132 #define IoGetDrvObjExtension(DriverObject)              \
133     ((PEXTENDED_DRIVER_EXTENSION)                       \
134      (DriverObject->DriverExtension))                   \
135 
136 /*
137  * VOID
138  * IopDeviceNodeSetFlag(
139  *   PDEVICE_NODE DeviceNode,
140  *   ULONG Flag);
141  */
142 #define IopDeviceNodeSetFlag(DeviceNode, Flag)          \
143     ((DeviceNode)->Flags |= (Flag))
144 
145 /*
146  * VOID
147  * IopDeviceNodeClearFlag(
148  *   PDEVICE_NODE DeviceNode,
149  *   ULONG Flag);
150  */
151 #define IopDeviceNodeClearFlag(DeviceNode, Flag)        \
152     ((DeviceNode)->Flags &= ~(Flag))
153 
154 /*
155  * BOOLEAN
156  * IopDeviceNodeHasFlag(
157  *   PDEVICE_NODE DeviceNode,
158  *   ULONG Flag);
159  */
160 #define IopDeviceNodeHasFlag(DeviceNode, Flag)          \
161     (((DeviceNode)->Flags & (Flag)) > 0)
162 
163 /*
164  * VOID
165  * IopDeviceNodeSetUserFlag(
166  *   PDEVICE_NODE DeviceNode,
167  *   ULONG UserFlag);
168  */
169 #define IopDeviceNodeSetUserFlag(DeviceNode, UserFlag)  \
170     ((DeviceNode)->UserFlags |= (UserFlag))
171 
172 /*
173  * VOID
174  * IopDeviceNodeClearUserFlag(
175  *   PDEVICE_NODE DeviceNode,
176  *   ULONG UserFlag);
177  */
178 #define IopDeviceNodeClearUserFlag(DeviceNode, UserFlag)\
179     ((DeviceNode)->UserFlags &= ~(UserFlag))
180 
181 /*
182  * BOOLEAN
183  * IopDeviceNodeHasUserFlag(
184  *   PDEVICE_NODE DeviceNode,
185  *   ULONG UserFlag);
186  */
187 #define IopDeviceNodeHasUserFlag(DeviceNode, UserFlag)  \
188     (((DeviceNode)->UserFlags & (UserFlag)) > 0)
189 
190  /*
191  * VOID
192  * IopDeviceNodeSetProblem(
193  *   PDEVICE_NODE DeviceNode,
194  *   ULONG Problem);
195  */
196 #define IopDeviceNodeSetProblem(DeviceNode, Problem)    \
197     ((DeviceNode)->Problem |= (Problem))
198 
199 /*
200  * VOID
201  * IopDeviceNodeClearProblem(
202  *   PDEVICE_NODE DeviceNode,
203  *   ULONG Problem);
204  */
205 #define IopDeviceNodeClearProblem(DeviceNode, Problem)  \
206     ((DeviceNode)->Problem &= ~(Problem))
207 
208 /*
209  * BOOLEAN
210  * IopDeviceNodeHasProblem(
211  *   PDEVICE_NODE DeviceNode,
212  *   ULONG Problem);
213  */
214 #define IopDeviceNodeHasProblem(DeviceNode, Problem)    \
215     (((DeviceNode)->Problem & (Problem)) > 0)
216 
217 /*
218  * VOID
219  * IopInitDeviceTreeTraverseContext(
220  *   PDEVICETREE_TRAVERSE_CONTEXT DeviceTreeTraverseContext,
221  *   PDEVICE_NODE DeviceNode,
222  *   DEVICETREE_TRAVERSE_ROUTINE Action,
223  *   PVOID Context);
224  */
225 #define IopInitDeviceTreeTraverseContext(               \
226     _DeviceTreeTraverseContext, _DeviceNode, _Action,   \
227     _Context) {                                         \
228     (_DeviceTreeTraverseContext)->FirstDeviceNode =     \
229         (_DeviceNode);                                  \
230     (_DeviceTreeTraverseContext)->Action = (_Action);   \
231     (_DeviceTreeTraverseContext)->Context = (_Context); }
232 
233 /*
234  * BOOLEAN
235  * IopIsValidPhysicalDeviceObject(
236  *   IN PDEVICE_OBJECT PhysicalDeviceObject);
237  */
238 #define IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)                                                            \
239         (((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject) &&                                                          \
240         (((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode) &&                      \
241         (((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->Flags & DNF_ENUMERATED))
242 
243 //
244 // Device List Operations
245 //
246 typedef enum _IOP_DEVICE_LIST_OPERATION
247 {
248     IopRemove,
249     IopAdd
250 } IOP_DEVICE_LIST_OPERATION, *PIOP_DEVICE_LIST_OPERATION;
251 
252 //
253 // Transfer statistics
254 //
255 typedef enum _IOP_TRANSFER_TYPE
256 {
257     IopReadTransfer,
258     IopWriteTransfer,
259     IopOtherTransfer
260 } IOP_TRANSFER_TYPE, *PIOP_TRANSFER_TYPE;
261 
262 //
263 // Packet Types when piggybacking on the IRP Overlay
264 //
265 typedef enum _COMPLETION_PACKET_TYPE
266     {
267     IopCompletionPacketIrp,
268     IopCompletionPacketMini,
269     IopCompletionPacketQuota
270 } COMPLETION_PACKET_TYPE, *PCOMPLETION_PACKET_TYPE;
271 
272 //
273 // Special version of the IRP Overlay used to optimize I/O completion
274 // by not using up a separate structure.
275 //
276 typedef struct _IOP_MINI_COMPLETION_PACKET
277 {
278     struct
279     {
280         LIST_ENTRY ListEntry;
281         union
282         {
283             struct _IO_STACK_LOCATION *CurrentStackLocation;
284             ULONG PacketType;
285         };
286     };
287     PVOID KeyContext;
288     PVOID ApcContext;
289     NTSTATUS IoStatus;
290     ULONG_PTR IoStatusInformation;
291 } IOP_MINI_COMPLETION_PACKET, *PIOP_MINI_COMPLETION_PACKET;
292 
293 //
294 // I/O Completion Context for IoSetIoCompletionRoutineEx
295 //
296 typedef struct _IO_UNLOAD_SAFE_COMPLETION_CONTEXT
297 {
298     PDEVICE_OBJECT DeviceObject;
299     PVOID Context;
300     PIO_COMPLETION_ROUTINE CompletionRoutine;
301 } IO_UNLOAD_SAFE_COMPLETION_CONTEXT, *PIO_UNLOAD_SAFE_COMPLETION_CONTEXT;
302 
303 //
304 // I/O Wrapper around the Executive Work Item
305 //
306 typedef struct _IO_WORKITEM
307 {
308     WORK_QUEUE_ITEM Item;
309     PDEVICE_OBJECT DeviceObject;
310     PIO_WORKITEM_ROUTINE WorkerRoutine;
311     PVOID Context;
312 } IO_WORKITEM;
313 
314 //
315 // I/O Wrapper around the Kernel Interrupt
316 //
317 typedef struct _IO_INTERRUPT
318 {
319     KINTERRUPT FirstInterrupt;
320     PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS];
321     KSPIN_LOCK SpinLock;
322 } IO_INTERRUPT, *PIO_INTERRUPT;
323 
324 //
325 // I/O Error Log Packet Header
326 //
327 typedef struct _ERROR_LOG_ENTRY
328 {
329     CSHORT Type;
330     CSHORT Size;
331     LIST_ENTRY ListEntry;
332     PDEVICE_OBJECT DeviceObject;
333     PDRIVER_OBJECT DriverObject;
334     LARGE_INTEGER TimeStamp;
335 } ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
336 
337 //
338 // To simplify matters, the kernel is made to support both the checked and free
339 // version of the I/O Remove Lock in the same binary. This structure includes
340 // both, since the DDK has the structure with a compile-time #ifdef.
341 //
342 typedef struct _EXTENDED_IO_REMOVE_LOCK
343 {
344     IO_REMOVE_LOCK_COMMON_BLOCK Common;
345     IO_REMOVE_LOCK_DBG_BLOCK Dbg;
346 } EXTENDED_IO_REMOVE_LOCK, *PEXTENDED_IO_REMOVE_LOCK;
347 
348 //
349 // Dummy File Object used inside the Open Packet so that OB knows how to
350 // deal with the Object Pointer even though it's not a real file.
351 //
352 typedef struct _DUMMY_FILE_OBJECT
353 {
354     OBJECT_HEADER ObjectHeader;
355     CHAR FileObjectBody[sizeof(FILE_OBJECT)];
356 } DUMMY_FILE_OBJECT, *PDUMMY_FILE_OBJECT;
357 
358 //
359 // Open packet used as a context for Device/File parsing so that the parse
360 // routine can know what operation is being requested.
361 //
362 typedef struct _OPEN_PACKET
363 {
364     CSHORT Type;
365     CSHORT Size;
366     PFILE_OBJECT FileObject;
367     NTSTATUS FinalStatus;
368     ULONG_PTR Information;
369     ULONG ParseCheck;
370     PFILE_OBJECT RelatedFileObject;
371     OBJECT_ATTRIBUTES OriginalAttributes;
372     LARGE_INTEGER AllocationSize;
373     ULONG CreateOptions;
374     USHORT FileAttributes;
375     USHORT ShareAccess;
376     PVOID EaBuffer;
377     ULONG EaLength;
378     ULONG Options;
379     ULONG Disposition;
380     PFILE_BASIC_INFORMATION BasicInformation;
381     PFILE_NETWORK_OPEN_INFORMATION NetworkInformation;
382     CREATE_FILE_TYPE CreateFileType;
383     PVOID ExtraCreateParameters;
384     BOOLEAN Override;
385     BOOLEAN QueryOnly;
386     BOOLEAN DeleteOnly;
387     BOOLEAN FullAttributes;
388     PDUMMY_FILE_OBJECT LocalFileObject;
389     BOOLEAN TraversedMountPoint;
390     ULONG InternalFlags;
391     PDEVICE_OBJECT TopDeviceObjectHint;
392 } OPEN_PACKET, *POPEN_PACKET;
393 
394 //
395 // Boot Driver List Entry
396 //
397 typedef struct _DRIVER_INFORMATION
398 {
399     LIST_ENTRY Link;
400     PDRIVER_OBJECT DriverObject;
401     PBOOT_DRIVER_LIST_ENTRY DataTableEntry;
402     HANDLE ServiceHandle;
403     USHORT TagPosition;
404     ULONG Failed;
405     ULONG Processed;
406     NTSTATUS Status;
407 } DRIVER_INFORMATION, *PDRIVER_INFORMATION;
408 
409 //
410 // Boot Driver Node
411 //
412 typedef struct _BOOT_DRIVER_NODE
413 {
414     BOOT_DRIVER_LIST_ENTRY ListEntry;
415     UNICODE_STRING Group;
416     UNICODE_STRING Name;
417     ULONG Tag;
418     ULONG ErrorControl;
419 } BOOT_DRIVER_NODE, *PBOOT_DRIVER_NODE;
420 
421 //
422 // List of Bus Type GUIDs
423 //
424 typedef struct _IO_BUS_TYPE_GUID_LIST
425 {
426     ULONG GuidCount;
427     FAST_MUTEX Lock;
428     GUID Guids[1];
429 } IO_BUS_TYPE_GUID_LIST, *PIO_BUS_TYPE_GUID_LIST;
430 extern PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList;
431 
432 //
433 // Shutdown entry for registed devices
434 //
435 typedef struct _SHUTDOWN_ENTRY
436 {
437     LIST_ENTRY ShutdownList;
438     PDEVICE_OBJECT DeviceObject;
439 } SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
440 
441 //
442 // F/S Notification entry for registered File Systems
443 //
444 typedef struct _FS_CHANGE_NOTIFY_ENTRY
445 {
446     LIST_ENTRY FsChangeNotifyList;
447     PDRIVER_OBJECT DriverObject;
448     PDRIVER_FS_NOTIFICATION FSDNotificationProc;
449 } FS_CHANGE_NOTIFY_ENTRY, *PFS_CHANGE_NOTIFY_ENTRY;
450 
451 //
452 // Driver (Boot) Re-Initialization Entry
453 //
454 typedef struct _DRIVER_REINIT_ITEM
455 {
456     LIST_ENTRY ItemEntry;
457     PDRIVER_OBJECT DriverObject;
458     PDRIVER_REINITIALIZE ReinitRoutine;
459     PVOID Context;
460 } DRIVER_REINIT_ITEM, *PDRIVER_REINIT_ITEM;
461 
462 //
463 // Called on every visit of a node during a preorder-traversal of the device
464 // node tree.
465 // If the routine returns STATUS_UNSUCCESSFUL the traversal will stop and
466 // STATUS_SUCCESS is returned to the caller who initiated the tree traversal.
467 // Any other returned status code will be returned to the caller. If a status
468 // code that indicates an error (other than STATUS_UNSUCCESSFUL) is returned,
469 // the traversal is stopped immediately and the status code is returned to
470 // the caller.
471 //
472 typedef
473 NTSTATUS
474 (*DEVICETREE_TRAVERSE_ROUTINE)(
475     IN PDEVICE_NODE DeviceNode,
476     IN PVOID Context
477 );
478 
479 //
480 // Context information for traversing the device tree
481 //
482 typedef struct _DEVICETREE_TRAVERSE_CONTEXT
483 {
484     //
485     // Current device node during a traversal
486     //
487     PDEVICE_NODE DeviceNode;
488 
489     //
490     // Initial device node where we start the traversal
491     //
492     PDEVICE_NODE FirstDeviceNode;
493 
494     //
495     // Action routine to be called for every device node
496     //
497     DEVICETREE_TRAVERSE_ROUTINE Action;
498 
499     //
500     // Context passed to the action routine
501     //
502     PVOID Context;
503 } DEVICETREE_TRAVERSE_CONTEXT, *PDEVICETREE_TRAVERSE_CONTEXT;
504 
505 //
506 // Reserve IRP allocator
507 // Used for read paging IOs in low-memory situations
508 //
509 typedef struct _RESERVE_IRP_ALLOCATOR
510 {
511     PIRP ReserveIrp;
512     volatile LONG ReserveIrpInUse;
513     KEVENT WaitEvent;
514     CCHAR StackSize;
515 } RESERVE_IRP_ALLOCATOR, *PRESERVE_IRP_ALLOCATOR;
516 
517 //
518 // Type selection for IopCreateSecurityDescriptorPerType()
519 //
520 typedef enum _SECURITY_DESCRIPTOR_TYPE
521 {
522     RestrictedPublic = 1,
523     UnrestrictedPublic,
524     RestrictedPublicOpen,
525     UnrestrictedPublicOpen,
526     SystemDefault,
527 } SECURITY_DESCRIPTOR_TYPE, *PSECURITY_DESCRIPTOR_TYPE;
528 
529 //
530 // Action types and data for PiQueueDeviceAction()
531 //
532 typedef enum _DEVICE_ACTION
533 {
534     PiActionEnumDeviceTree,
535     PiActionEnumRootDevices,
536     PiActionResetDevice,
537     PiActionAddBootDevices
538 } DEVICE_ACTION;
539 
540 //
541 // Resource code
542 //
543 ULONG
544 NTAPI
545 PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList);
546 
547 NTSTATUS
548 NTAPI
549 IopAssignDeviceResources(
550     IN PDEVICE_NODE DeviceNode
551 );
552 
553 NTSTATUS
554 NTAPI
555 IopFixupResourceListWithRequirements(
556     IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
557     OUT PCM_RESOURCE_LIST *ResourceList
558 );
559 
560 NTSTATUS
561 NTAPI
562 IopDetectResourceConflict(
563      IN PCM_RESOURCE_LIST ResourceList,
564      IN BOOLEAN Silent,
565      OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor
566 );
567 
568 //
569 // PNP Routines
570 //
571 NTSTATUS
572 NTAPI
573 IopInitializePlugPlayServices(
574     VOID
575 );
576 
577 BOOLEAN
578 NTAPI
579 PpInitSystem(
580     VOID
581 );
582 
583 VOID
584 PnpInit2(
585     VOID
586 );
587 
588 VOID
589 IopInitDriverImplementation(
590     VOID
591 );
592 
593 NTSTATUS
594 IopGetSystemPowerDeviceObject(
595     IN PDEVICE_OBJECT *DeviceObject
596 );
597 
598 PDEVICE_NODE
599 PipAllocateDeviceNode(
600     IN PDEVICE_OBJECT PhysicalDeviceObject
601 );
602 
603 VOID
604 PiInsertDevNode(
605     _In_ PDEVICE_NODE DeviceNode,
606     _In_ PDEVICE_NODE ParentNode);
607 
608 PNP_DEVNODE_STATE
609 PiSetDevNodeState(
610     _In_ PDEVICE_NODE DeviceNode,
611     _In_ PNP_DEVNODE_STATE NewState);
612 
613 VOID
614 PiSetDevNodeProblem(
615     _In_ PDEVICE_NODE DeviceNode,
616     _In_ UINT32 Problem);
617 
618 VOID
619 PiClearDevNodeProblem(
620     _In_ PDEVICE_NODE DeviceNode);
621 
622 NTSTATUS
623 IopFreeDeviceNode(
624     IN PDEVICE_NODE DeviceNode
625 );
626 
627 NTSTATUS
628 NTAPI
629 IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
630                            PDEVICE_CAPABILITIES DeviceCaps);
631 
632 NTSTATUS
633 IopSynchronousCall(
634     IN PDEVICE_OBJECT DeviceObject,
635     IN PIO_STACK_LOCATION IoStackLocation,
636     OUT PVOID *Information
637 );
638 
639 NTSTATUS
640 NTAPI
641 IopInitiatePnpIrp(
642     IN PDEVICE_OBJECT DeviceObject,
643     IN PIO_STATUS_BLOCK IoStatusBlock,
644     IN UCHAR MinorFunction,
645     IN PIO_STACK_LOCATION Stack
646 );
647 
648 PDEVICE_NODE
649 FASTCALL
650 IopGetDeviceNode(
651     IN PDEVICE_OBJECT DeviceObject
652 );
653 
654 NTSTATUS
655 IoCreateDriverList(
656     VOID
657 );
658 
659 NTSTATUS
660 IoDestroyDriverList(
661     VOID
662 );
663 
664 NTSTATUS
665 IopInitPlugPlayEvents(VOID);
666 
667 NTSTATUS
668 IopQueueTargetDeviceEvent(
669     const GUID *Guid,
670     PUNICODE_STRING DeviceIds
671 );
672 
673 NTSTATUS
674 NTAPI
675 IopOpenRegistryKeyEx(
676     PHANDLE KeyHandle,
677     HANDLE ParentKey,
678     PUNICODE_STRING Name,
679     ACCESS_MASK DesiredAccess);
680 
681 NTSTATUS
682 NTAPI
683 IopGetRegistryValue(
684     IN HANDLE Handle,
685     IN PWSTR ValueName,
686     OUT PKEY_VALUE_FULL_INFORMATION *Information
687 );
688 
689 NTSTATUS
690 NTAPI
691 IopCreateRegistryKeyEx(
692     OUT PHANDLE Handle,
693     IN HANDLE BaseHandle OPTIONAL,
694     IN PUNICODE_STRING KeyName,
695     IN ACCESS_MASK DesiredAccess,
696     IN ULONG CreateOptions,
697     OUT PULONG Disposition OPTIONAL
698 );
699 
700 
701 NTSTATUS
702 IopTraverseDeviceTree(
703     PDEVICETREE_TRAVERSE_CONTEXT Context);
704 
705 NTSTATUS
706 NTAPI
707 IopCreateDeviceKeyPath(
708     IN PCUNICODE_STRING RegistryPath,
709     IN ULONG CreateOptions,
710     OUT PHANDLE Handle);
711 
712 //
713 // PnP Routines
714 //
715 NTSTATUS
716 NTAPI
717 IopUpdateRootKey(
718     VOID
719 );
720 
721 NTSTATUS
722 NTAPI
723 PiInitCacheGroupInformation(
724     VOID
725 );
726 
727 USHORT
728 NTAPI
729 PpInitGetGroupOrderIndex(
730     IN HANDLE ServiceHandle
731 );
732 
733 USHORT
734 NTAPI
735 PipGetDriverTagPriority(
736     IN HANDLE ServiceHandle
737 );
738 
739 NTSTATUS
740 NTAPI
741 PnpRegMultiSzToUnicodeStrings(
742     IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
743     OUT PUNICODE_STRING *UnicodeStringList,
744     OUT PULONG UnicodeStringCount
745 );
746 
747 BOOLEAN
748 NTAPI
749 PnpRegSzToString(
750     IN PWCHAR RegSzData,
751     IN ULONG RegSzLength,
752     OUT PUSHORT StringLength OPTIONAL
753 );
754 
755 //
756 // Initialization Routines
757 //
758 NTSTATUS
759 NTAPI
760 IopCreateArcNames(
761     IN PLOADER_PARAMETER_BLOCK LoaderBlock
762 );
763 
764 NTSTATUS
765 NTAPI
766 IopReassignSystemRoot(
767     IN PLOADER_PARAMETER_BLOCK LoaderBlock,
768     OUT PANSI_STRING NtBootPath
769 );
770 
771 BOOLEAN
772 NTAPI
773 IoInitSystem(
774     IN PLOADER_PARAMETER_BLOCK LoaderBlock
775 );
776 
777 BOOLEAN
778 NTAPI
779 IopVerifyDiskSignature(
780     IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout,
781     IN PARC_DISK_SIGNATURE ArcDiskSignature,
782     OUT PULONG Signature
783 );
784 
785 BOOLEAN
786 NTAPI
787 IoInitializeCrashDump(
788     IN HANDLE PageFileHandle
789 );
790 
791 VOID
792 PiInitializeNotifications(
793     VOID);
794 
795 //
796 // Device/Volume Routines
797 //
798 VOID
799 NTAPI
800 IopReadyDeviceObjects(
801     IN PDRIVER_OBJECT Driver
802 );
803 
804 PVPB
805 NTAPI
806 IopCheckVpbMounted(
807     IN POPEN_PACKET OpenPacket,
808     IN PDEVICE_OBJECT DeviceObject,
809     IN PUNICODE_STRING RemainingName,
810     OUT PNTSTATUS Status
811 );
812 
813 NTSTATUS
814 NTAPI
815 IopMountVolume(
816     IN PDEVICE_OBJECT DeviceObject,
817     IN BOOLEAN AllowRawMount,
818     IN BOOLEAN DeviceIsLocked,
819     IN BOOLEAN Alertable,
820     OUT PVPB *Vpb
821 );
822 
823 PVOID
824 IoOpenSymlink(
825     IN PVOID SymbolicLink
826 );
827 
828 PVOID
829 IoOpenFileOnDevice(
830     IN PVOID SymbolicLink,
831     IN PWCHAR Name
832 );
833 
834 NTSTATUS
835 NTAPI
836 IopCreateVpb(
837     IN PDEVICE_OBJECT DeviceObject
838 );
839 
840 VOID
841 NTAPI
842 IopDereferenceVpbAndFree(
843     IN PVPB Vpb
844 );
845 
846 VOID
847 NTAPI
848 IoInitFileSystemImplementation(
849     VOID
850 );
851 
852 VOID
853 NTAPI
854 IoInitVpbImplementation(
855     VOID
856 );
857 
858 NTSTATUS
859 NTAPI
860 IopReferenceDeviceObject(
861     IN PDEVICE_OBJECT DeviceObject
862 );
863 
864 VOID
865 NTAPI
866 IopDereferenceDeviceObject(
867     IN PDEVICE_OBJECT DeviceObject,
868     IN BOOLEAN ForceUnload
869 );
870 
871 NTSTATUS
872 NTAPI
873 IopGetRelatedTargetDevice(
874     IN PFILE_OBJECT FileObject,
875     OUT PDEVICE_NODE *DeviceNode);
876 
877 NTSTATUS
878 NTAPI
879 IoGetRelatedTargetDevice(
880     IN PFILE_OBJECT FileObject,
881     OUT PDEVICE_OBJECT *DeviceObject
882 );
883 
884 VOID
885 NTAPI
886 IopUnloadDevice(
887     IN PDEVICE_OBJECT DeviceObject
888 );
889 
890 PDEVICE_OBJECT
891 NTAPI
892 IopGetDeviceAttachmentBase(
893     IN PDEVICE_OBJECT DeviceObject
894 );
895 
896 //
897 // IRP Routines
898 //
899 NTSTATUS
900 NTAPI
901 IopCleanupFailedIrp(
902     IN PFILE_OBJECT FileObject,
903     IN PKEVENT EventObject,
904     IN PVOID Buffer OPTIONAL
905 );
906 
907 VOID
908 NTAPI
909 IopAbortInterruptedIrp(
910     IN PKEVENT EventObject,
911     IN PIRP Irp
912 );
913 
914 PIRP
915 NTAPI
916 IopAllocateIrpMustSucceed(
917     IN CCHAR StackSize
918 );
919 
920 BOOLEAN
921 NTAPI
922 IopInitializeReserveIrp(
923     IN PRESERVE_IRP_ALLOCATOR ReserveIrpAllocator
924 );
925 
926 PIRP
927 NTAPI
928 IopAllocateReserveIrp(
929     IN CCHAR StackSize
930 );
931 
932 //
933 // Shutdown routines
934 //
935 VOID
936 IoInitShutdownNotification(
937     VOID
938 );
939 
940 VOID
941 NTAPI
942 IoShutdownSystem(
943     IN ULONG Phase
944 );
945 
946 VOID
947 NTAPI
948 IopShutdownBaseFileSystems(
949     IN PLIST_ENTRY ListHead
950 );
951 
952 //
953 // Boot logging support
954 //
955 VOID
956 IopInitBootLog(
957     IN BOOLEAN StartBootLog
958 );
959 
960 VOID
961 IopStartBootLog(
962     VOID
963 );
964 
965 VOID
966 IopStopBootLog(
967     VOID
968 );
969 
970 VOID
971 IopBootLog(
972     IN PUNICODE_STRING DriverName,
973     IN BOOLEAN Success
974 );
975 
976 VOID
977 IopSaveBootLogToFile(
978     VOID
979 );
980 
981 //
982 // I/O Cancellation Routines
983 //
984 VOID
985 NTAPI
986 IoCancelThreadIo(
987     IN PETHREAD Thread
988 );
989 
990 VOID
991 IoInitCancelHandling(
992     VOID
993 );
994 
995 //
996 // I/O Completion
997 //
998 VOID
999 NTAPI
1000 IopCompleteRequest(
1001     IN PKAPC Apc,
1002     IN PKNORMAL_ROUTINE* NormalRoutine,
1003     IN PVOID* NormalContext,
1004     IN PVOID* SystemArgument1,
1005     IN PVOID* SystemArgument2
1006 );
1007 
1008 //
1009 // Error Logging Routines
1010 //
1011 VOID
1012 NTAPI
1013 IopInitErrorLog(
1014     VOID
1015 );
1016 
1017 VOID
1018 NTAPI
1019 IopLogWorker(
1020     IN PVOID Parameter
1021 );
1022 
1023 //
1024 // Raw File System MiniDriver
1025 //
1026 BOOLEAN
1027 RawFsIsRawFileSystemDeviceObject(
1028     IN PDEVICE_OBJECT DeviceObject
1029 );
1030 
1031 NTSTATUS
1032 NTAPI
1033 RawFsDriverEntry(
1034     IN PDRIVER_OBJECT DriverObject,
1035     IN PUNICODE_STRING RegistryPath
1036 );
1037 
1038 //
1039 // PnP Root MiniDriver
1040 //
1041 NTSTATUS
1042 NTAPI
1043 PnpRootDriverEntry(
1044    IN PDRIVER_OBJECT DriverObject,
1045    IN PUNICODE_STRING RegistryPath
1046 );
1047 
1048 NTSTATUS
1049 PnpRootCreateDevice(
1050     IN PUNICODE_STRING ServiceName,
1051     IN OPTIONAL PDRIVER_OBJECT DriverObject,
1052     OUT PDEVICE_OBJECT *PhysicalDeviceObject,
1053     OUT OPTIONAL PUNICODE_STRING FullInstancePath
1054 );
1055 
1056 NTSTATUS
1057 PnpRootRegisterDevice(
1058     IN PDEVICE_OBJECT DeviceObject);
1059 
1060 //
1061 // Driver Routines
1062 //
1063 VOID
1064 FASTCALL
1065 IopInitializeBootDrivers(
1066     VOID
1067 );
1068 
1069 VOID
1070 FASTCALL
1071 IopInitializeSystemDrivers(
1072     VOID
1073 );
1074 
1075 VOID
1076 NTAPI
1077 IopDeleteDriver(
1078     IN PVOID ObjectBody
1079 );
1080 
1081 NTSTATUS
1082 IopLoadDriver(
1083     _In_ HANDLE ServiceHandle,
1084     _Out_ PDRIVER_OBJECT *DriverObject);
1085 
1086 NTSTATUS
1087 IopGetDriverNames(
1088     _In_ HANDLE ServiceHandle,
1089     _Out_ PUNICODE_STRING DriverName,
1090     _Out_opt_ PUNICODE_STRING ServiceName);
1091 
1092 NTSTATUS
1093 IopInitializeDriverModule(
1094     _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
1095     _In_ HANDLE ServiceHandle,
1096     _Out_ PDRIVER_OBJECT *DriverObject,
1097     _Out_ NTSTATUS *DriverEntryStatus);
1098 
1099 NTSTATUS
1100 FASTCALL
1101 IopAttachFilterDrivers(
1102     IN PDEVICE_NODE DeviceNode,
1103     IN HANDLE EnumSubKey,
1104     IN HANDLE ClassKey,
1105     IN BOOLEAN Lower
1106 );
1107 
1108 VOID
1109 NTAPI
1110 IopReinitializeDrivers(
1111     VOID
1112 );
1113 
1114 VOID
1115 NTAPI
1116 IopReinitializeBootDrivers(
1117     VOID
1118 );
1119 
1120 //
1121 // File Routines
1122 //
1123 VOID
1124 NTAPI
1125 IopDeleteDevice(IN PVOID ObjectBody);
1126 
1127 NTSTATUS
1128 NTAPI
1129 IopParseDevice(
1130     IN PVOID ParseObject,
1131     IN PVOID ObjectType,
1132     IN OUT PACCESS_STATE AccessState,
1133     IN KPROCESSOR_MODE AccessMode,
1134     IN ULONG Attributes,
1135     IN OUT PUNICODE_STRING CompleteName,
1136     IN OUT PUNICODE_STRING RemainingName,
1137     IN OUT PVOID Context,
1138     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1139     OUT PVOID *Object
1140 );
1141 
1142 NTSTATUS
1143 NTAPI
1144 IopParseFile(
1145     IN PVOID ParseObject,
1146     IN PVOID ObjectType,
1147     IN OUT PACCESS_STATE AccessState,
1148     IN KPROCESSOR_MODE AccessMode,
1149     IN ULONG Attributes,
1150     IN OUT PUNICODE_STRING CompleteName,
1151     IN OUT PUNICODE_STRING RemainingName,
1152     IN OUT PVOID Context OPTIONAL,
1153     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1154     OUT PVOID *Object
1155 );
1156 
1157 VOID
1158 NTAPI
1159 IopDeleteFile(
1160     IN PVOID ObjectBody
1161 );
1162 
1163 NTSTATUS
1164 NTAPI
1165 IopGetSetSecurityObject(
1166     IN PVOID ObjectBody,
1167     IN SECURITY_OPERATION_CODE OperationCode,
1168     IN PSECURITY_INFORMATION SecurityInformation,
1169     IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
1170     IN OUT PULONG BufferLength,
1171     OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1172     IN POOL_TYPE PoolType,
1173     IN OUT PGENERIC_MAPPING GenericMapping
1174 );
1175 
1176 NTSTATUS
1177 NTAPI
1178 IopQueryName(
1179     IN PVOID ObjectBody,
1180     IN BOOLEAN HasName,
1181     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1182     IN ULONG Length,
1183     OUT PULONG ReturnLength,
1184     IN KPROCESSOR_MODE PreviousMode
1185 );
1186 
1187 NTSTATUS
1188 NTAPI
1189 IopQueryNameInternal(
1190     IN PVOID ObjectBody,
1191     IN BOOLEAN HasName,
1192     IN BOOLEAN QueryDosName,
1193     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1194     IN ULONG Length,
1195     OUT PULONG ReturnLength,
1196     IN KPROCESSOR_MODE PreviousMode
1197 );
1198 
1199 VOID
1200 NTAPI
1201 IopCloseFile(
1202     IN PEPROCESS Process OPTIONAL,
1203     IN PVOID Object,
1204     IN ACCESS_MASK GrantedAccess,
1205     IN ULONG ProcessHandleCount,
1206     IN ULONG SystemHandleCount
1207 );
1208 
1209 NTSTATUS
1210 NTAPI
1211 IopAcquireFileObjectLock(
1212     _In_ PFILE_OBJECT FileObject,
1213     _In_ KPROCESSOR_MODE AccessMode,
1214     _In_ BOOLEAN Alertable,
1215     _Out_ PBOOLEAN LockFailed
1216 );
1217 
1218 PVOID
1219 NTAPI
1220 IoGetFileObjectFilterContext(
1221     IN PFILE_OBJECT FileObject
1222 );
1223 
1224 NTSTATUS
1225 NTAPI
1226 IoChangeFileObjectFilterContext(
1227     IN PFILE_OBJECT FileObject,
1228     IN PVOID FilterContext,
1229     IN BOOLEAN Define
1230 );
1231 
1232 VOID
1233 NTAPI
1234 IopDoNameTransmogrify(
1235     IN PIRP Irp,
1236     IN PFILE_OBJECT FileObject,
1237     IN PREPARSE_DATA_BUFFER DataBuffer
1238 );
1239 
1240 NTSTATUS
1241 NTAPI
1242 IoComputeDesiredAccessFileObject(
1243     IN PFILE_OBJECT FileObject,
1244     IN PACCESS_MASK DesiredAccess
1245 );
1246 
1247 NTSTATUS
1248 NTAPI
1249 IopGetFileInformation(
1250     IN PFILE_OBJECT FileObject,
1251     IN ULONG Length,
1252     IN FILE_INFORMATION_CLASS FileInfoClass,
1253     OUT PVOID Buffer,
1254     OUT PULONG ReturnedLength
1255 );
1256 
1257 BOOLEAN
1258 NTAPI
1259 IopVerifyDeviceObjectOnStack(
1260     IN PDEVICE_OBJECT BaseDeviceObject,
1261     IN PDEVICE_OBJECT TopDeviceObjectHint
1262 );
1263 
1264 //
1265 // I/O Timer Routines
1266 //
1267 VOID
1268 FASTCALL
1269 IopInitTimerImplementation(
1270     VOID
1271 );
1272 
1273 VOID
1274 NTAPI
1275 IopRemoveTimerFromTimerList(
1276     IN PIO_TIMER Timer
1277 );
1278 
1279 //
1280 // I/O Completion Routines
1281 //
1282 VOID
1283 NTAPI
1284 IopDeleteIoCompletion(
1285     PVOID ObjectBody
1286 );
1287 
1288 NTSTATUS
1289 NTAPI
1290 IoSetIoCompletion(
1291     IN PVOID IoCompletion,
1292     IN PVOID KeyContext,
1293     IN PVOID ApcContext,
1294     IN NTSTATUS IoStatus,
1295     IN ULONG_PTR IoStatusInformation,
1296     IN BOOLEAN Quota
1297 );
1298 
1299 //
1300 // Ramdisk Routines
1301 //
1302 NTSTATUS
1303 NTAPI
1304 IopStartRamdisk(
1305     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1306 );
1307 
1308 //
1309 // Configuration Routines
1310 //
1311 NTSTATUS
1312 NTAPI
1313 IopFetchConfigurationInformation(OUT PWSTR * SymbolicLinkList,
1314                                  IN GUID Guid,
1315                                  IN ULONG ExpectedInterfaces,
1316                                  IN PULONG Interfaces
1317 );
1318 
1319 VOID
1320 NTAPI
1321 IopStoreSystemPartitionInformation(IN PUNICODE_STRING NtSystemPartitionDeviceName,
1322                                    IN PUNICODE_STRING OsLoaderPathName
1323 );
1324 
1325 //
1326 // Device action
1327 //
1328 VOID
1329 PiQueueDeviceAction(
1330     _In_ PDEVICE_OBJECT DeviceObject,
1331     _In_ DEVICE_ACTION Action,
1332     _In_opt_ PKEVENT CompletionEvent,
1333     _Out_opt_ NTSTATUS *CompletionStatus);
1334 
1335 NTSTATUS
1336 PiPerformSyncDeviceAction(
1337     _In_ PDEVICE_OBJECT DeviceObject,
1338     _In_ DEVICE_ACTION Action);
1339 
1340 //
1341 // PnP notifications
1342 //
1343 VOID
1344 PiNotifyDeviceInterfaceChange(
1345     _In_ LPCGUID Event,
1346     _In_ LPCGUID InterfaceClassGuid,
1347     _In_ PUNICODE_STRING SymbolicLinkName);
1348 
1349 VOID
1350 PiNotifyHardwareProfileChange(
1351     _In_ LPCGUID Event);
1352 
1353 VOID
1354 PiNotifyTargetDeviceChange(
1355     _In_ LPCGUID Event,
1356     _In_ PDEVICE_OBJECT DeviceObject,
1357     _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification);
1358 
1359 //
1360 // PnP IRPs
1361 //
1362 NTSTATUS
1363 PiIrpStartDevice(
1364     _In_ PDEVICE_NODE DeviceNode);
1365 
1366 NTSTATUS
1367 PiIrpStopDevice(
1368     _In_ PDEVICE_NODE DeviceNode);
1369 
1370 NTSTATUS
1371 PiIrpQueryStopDevice(
1372     _In_ PDEVICE_NODE DeviceNode);
1373 
1374 NTSTATUS
1375 PiIrpCancelStopDevice(
1376     _In_ PDEVICE_NODE DeviceNode);
1377 
1378 NTSTATUS
1379 PiIrpQueryDeviceRelations(
1380     _In_ PDEVICE_NODE DeviceNode,
1381     _In_ DEVICE_RELATION_TYPE Type);
1382 
1383 NTSTATUS
1384 PiIrpQueryPnPDeviceState(
1385     _In_ PDEVICE_NODE DeviceNode,
1386     _Out_ PPNP_DEVICE_STATE DeviceState);
1387 
1388 //
1389 // Global I/O Data
1390 //
1391 extern POBJECT_TYPE IoCompletionType;
1392 extern PDEVICE_NODE IopRootDeviceNode;
1393 extern KSPIN_LOCK IopDeviceTreeLock;
1394 extern ULONG IopTraceLevel;
1395 extern GENERAL_LOOKASIDE IopMdlLookasideList;
1396 extern GENERIC_MAPPING IopCompletionMapping;
1397 extern GENERIC_MAPPING IopFileMapping;
1398 extern POBJECT_TYPE _IoFileObjectType;
1399 extern HAL_DISPATCH _HalDispatchTable;
1400 extern LIST_ENTRY IopErrorLogListHead;
1401 extern ULONG IopNumTriageDumpDataBlocks;
1402 extern PVOID IopTriageDumpDataBlocks[64];
1403 extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
1404 extern PDRIVER_OBJECT IopRootDriverObject;
1405 extern KSPIN_LOCK IopDeviceActionLock;
1406 extern LIST_ENTRY IopDeviceActionRequestList;
1407 extern RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator;
1408 extern BOOLEAN IoRemoteBootClient;
1409 
1410 //
1411 // Inlined Functions
1412 //
1413 #include "io_x.h"
1414