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