xref: /reactos/ntoskrnl/include/internal/io.h (revision 34593d93)
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     PiActionStartDevice
539 } DEVICE_ACTION;
540 
541 //
542 // Resource code
543 //
544 ULONG
545 NTAPI
546 PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList);
547 
548 NTSTATUS
549 NTAPI
550 IopAssignDeviceResources(
551     IN PDEVICE_NODE DeviceNode
552 );
553 
554 NTSTATUS
555 NTAPI
556 IopFixupResourceListWithRequirements(
557     IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
558     OUT PCM_RESOURCE_LIST *ResourceList
559 );
560 
561 NTSTATUS
562 NTAPI
563 IopDetectResourceConflict(
564      IN PCM_RESOURCE_LIST ResourceList,
565      IN BOOLEAN Silent,
566      OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor
567 );
568 
569 //
570 // PNP Routines
571 //
572 NTSTATUS
573 NTAPI
574 PipCallDriverAddDevice(
575     IN PDEVICE_NODE DeviceNode,
576     IN BOOLEAN LoadDriver,
577     IN PDRIVER_OBJECT DriverObject
578 );
579 
580 CODE_SEG("INIT")
581 NTSTATUS
582 NTAPI
583 IopInitializePlugPlayServices(
584     VOID
585 );
586 
587 BOOLEAN
588 NTAPI
589 PpInitSystem(
590     VOID
591 );
592 
593 VOID
594 PnpInit2(
595     VOID
596 );
597 
598 VOID
599 IopInitDriverImplementation(
600     VOID
601 );
602 
603 NTSTATUS
604 IopGetSystemPowerDeviceObject(
605     IN PDEVICE_OBJECT *DeviceObject
606 );
607 
608 PDEVICE_NODE
609 PipAllocateDeviceNode(
610     IN PDEVICE_OBJECT PhysicalDeviceObject
611 );
612 
613 VOID
614 PiInsertDevNode(
615     _In_ PDEVICE_NODE DeviceNode,
616     _In_ PDEVICE_NODE ParentNode);
617 
618 PNP_DEVNODE_STATE
619 PiSetDevNodeState(
620     _In_ PDEVICE_NODE DeviceNode,
621     _In_ PNP_DEVNODE_STATE NewState);
622 
623 VOID
624 PiSetDevNodeProblem(
625     _In_ PDEVICE_NODE DeviceNode,
626     _In_ UINT32 Problem);
627 
628 VOID
629 PiClearDevNodeProblem(
630     _In_ PDEVICE_NODE DeviceNode);
631 
632 NTSTATUS
633 IopFreeDeviceNode(
634     IN PDEVICE_NODE DeviceNode
635 );
636 
637 NTSTATUS
638 NTAPI
639 IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
640                            PDEVICE_CAPABILITIES DeviceCaps);
641 
642 NTSTATUS
643 IopSynchronousCall(
644     IN PDEVICE_OBJECT DeviceObject,
645     IN PIO_STACK_LOCATION IoStackLocation,
646     OUT PVOID *Information
647 );
648 
649 NTSTATUS
650 NTAPI
651 IopInitiatePnpIrp(
652     IN PDEVICE_OBJECT DeviceObject,
653     IN PIO_STATUS_BLOCK IoStatusBlock,
654     IN UCHAR MinorFunction,
655     IN PIO_STACK_LOCATION Stack
656 );
657 
658 PDEVICE_NODE
659 FASTCALL
660 IopGetDeviceNode(
661     IN PDEVICE_OBJECT DeviceObject
662 );
663 
664 NTSTATUS
665 IoCreateDriverList(
666     VOID
667 );
668 
669 NTSTATUS
670 IoDestroyDriverList(
671     VOID
672 );
673 
674 CODE_SEG("INIT")
675 NTSTATUS
676 IopInitPlugPlayEvents(VOID);
677 
678 NTSTATUS
679 IopQueueTargetDeviceEvent(
680     const GUID *Guid,
681     PUNICODE_STRING DeviceIds
682 );
683 
684 NTSTATUS
685 NTAPI
686 IopOpenRegistryKeyEx(
687     PHANDLE KeyHandle,
688     HANDLE ParentKey,
689     PUNICODE_STRING Name,
690     ACCESS_MASK DesiredAccess);
691 
692 NTSTATUS
693 NTAPI
694 IopGetRegistryValue(
695     IN HANDLE Handle,
696     IN PWSTR ValueName,
697     OUT PKEY_VALUE_FULL_INFORMATION *Information
698 );
699 
700 NTSTATUS
701 NTAPI
702 IopCreateRegistryKeyEx(
703     OUT PHANDLE Handle,
704     IN HANDLE BaseHandle OPTIONAL,
705     IN PUNICODE_STRING KeyName,
706     IN ACCESS_MASK DesiredAccess,
707     IN ULONG CreateOptions,
708     OUT PULONG Disposition OPTIONAL
709 );
710 
711 
712 NTSTATUS
713 IopTraverseDeviceTree(
714     PDEVICETREE_TRAVERSE_CONTEXT Context);
715 
716 NTSTATUS
717 NTAPI
718 IopCreateDeviceKeyPath(
719     IN PCUNICODE_STRING RegistryPath,
720     IN ULONG CreateOptions,
721     OUT PHANDLE Handle);
722 
723 //
724 // PnP Routines
725 //
726 CODE_SEG("INIT")
727 NTSTATUS
728 NTAPI
729 IopUpdateRootKey(
730     VOID
731 );
732 
733 CODE_SEG("INIT")
734 NTSTATUS
735 NTAPI
736 PiInitCacheGroupInformation(
737     VOID
738 );
739 
740 USHORT
741 NTAPI
742 PpInitGetGroupOrderIndex(
743     IN HANDLE ServiceHandle
744 );
745 
746 USHORT
747 NTAPI
748 PipGetDriverTagPriority(
749     IN HANDLE ServiceHandle
750 );
751 
752 NTSTATUS
753 NTAPI
754 PnpRegMultiSzToUnicodeStrings(
755     IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
756     OUT PUNICODE_STRING *UnicodeStringList,
757     OUT PULONG UnicodeStringCount
758 );
759 
760 BOOLEAN
761 NTAPI
762 PnpRegSzToString(
763     IN PWCHAR RegSzData,
764     IN ULONG RegSzLength,
765     OUT PUSHORT StringLength OPTIONAL
766 );
767 
768 VOID
769 PiSetDevNodeText(
770     _In_ PDEVICE_NODE DeviceNode,
771     _In_ HANDLE InstanceKey);
772 
773 //
774 // Initialization Routines
775 //
776 CODE_SEG("INIT")
777 NTSTATUS
778 NTAPI
779 IopCreateArcNames(
780     IN PLOADER_PARAMETER_BLOCK LoaderBlock
781 );
782 
783 CODE_SEG("INIT")
784 NTSTATUS
785 NTAPI
786 IopReassignSystemRoot(
787     IN PLOADER_PARAMETER_BLOCK LoaderBlock,
788     OUT PANSI_STRING NtBootPath
789 );
790 
791 CODE_SEG("INIT")
792 BOOLEAN
793 NTAPI
794 IoInitSystem(
795     IN PLOADER_PARAMETER_BLOCK LoaderBlock
796 );
797 
798 BOOLEAN
799 NTAPI
800 IopVerifyDiskSignature(
801     IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout,
802     IN PARC_DISK_SIGNATURE ArcDiskSignature,
803     OUT PULONG Signature
804 );
805 
806 BOOLEAN
807 NTAPI
808 IoInitializeCrashDump(
809     IN HANDLE PageFileHandle
810 );
811 
812 CODE_SEG("INIT")
813 VOID
814 PiInitializeNotifications(
815     VOID);
816 
817 //
818 // Device/Volume Routines
819 //
820 VOID
821 NTAPI
822 IopReadyDeviceObjects(
823     IN PDRIVER_OBJECT Driver
824 );
825 
826 PVPB
827 NTAPI
828 IopCheckVpbMounted(
829     IN POPEN_PACKET OpenPacket,
830     IN PDEVICE_OBJECT DeviceObject,
831     IN PUNICODE_STRING RemainingName,
832     OUT PNTSTATUS Status
833 );
834 
835 NTSTATUS
836 NTAPI
837 IopMountVolume(
838     IN PDEVICE_OBJECT DeviceObject,
839     IN BOOLEAN AllowRawMount,
840     IN BOOLEAN DeviceIsLocked,
841     IN BOOLEAN Alertable,
842     OUT PVPB *Vpb
843 );
844 
845 PVOID
846 IoOpenSymlink(
847     IN PVOID SymbolicLink
848 );
849 
850 PVOID
851 IoOpenFileOnDevice(
852     IN PVOID SymbolicLink,
853     IN PWCHAR Name
854 );
855 
856 NTSTATUS
857 NTAPI
858 IopCreateVpb(
859     IN PDEVICE_OBJECT DeviceObject
860 );
861 
862 VOID
863 NTAPI
864 IopDereferenceVpbAndFree(
865     IN PVPB Vpb
866 );
867 
868 VOID
869 NTAPI
870 IoInitFileSystemImplementation(
871     VOID
872 );
873 
874 VOID
875 NTAPI
876 IoInitVpbImplementation(
877     VOID
878 );
879 
880 NTSTATUS
881 NTAPI
882 IopReferenceDeviceObject(
883     IN PDEVICE_OBJECT DeviceObject
884 );
885 
886 VOID
887 NTAPI
888 IopDereferenceDeviceObject(
889     IN PDEVICE_OBJECT DeviceObject,
890     IN BOOLEAN ForceUnload
891 );
892 
893 NTSTATUS
894 NTAPI
895 IopGetRelatedTargetDevice(
896     IN PFILE_OBJECT FileObject,
897     OUT PDEVICE_NODE *DeviceNode);
898 
899 NTSTATUS
900 NTAPI
901 IoGetRelatedTargetDevice(
902     IN PFILE_OBJECT FileObject,
903     OUT PDEVICE_OBJECT *DeviceObject
904 );
905 
906 VOID
907 NTAPI
908 IopUnloadDevice(
909     IN PDEVICE_OBJECT DeviceObject
910 );
911 
912 PDEVICE_OBJECT
913 NTAPI
914 IopGetDeviceAttachmentBase(
915     IN PDEVICE_OBJECT DeviceObject
916 );
917 
918 //
919 // IRP Routines
920 //
921 NTSTATUS
922 NTAPI
923 IopCleanupFailedIrp(
924     IN PFILE_OBJECT FileObject,
925     IN PKEVENT EventObject,
926     IN PVOID Buffer OPTIONAL
927 );
928 
929 VOID
930 NTAPI
931 IopAbortInterruptedIrp(
932     IN PKEVENT EventObject,
933     IN PIRP Irp
934 );
935 
936 PIRP
937 NTAPI
938 IopAllocateIrpMustSucceed(
939     IN CCHAR StackSize
940 );
941 
942 BOOLEAN
943 NTAPI
944 IopInitializeReserveIrp(
945     IN PRESERVE_IRP_ALLOCATOR ReserveIrpAllocator
946 );
947 
948 PIRP
949 NTAPI
950 IopAllocateReserveIrp(
951     IN CCHAR StackSize
952 );
953 
954 //
955 // Shutdown routines
956 //
957 VOID
958 IoInitShutdownNotification(
959     VOID
960 );
961 
962 VOID
963 NTAPI
964 IoShutdownSystem(
965     IN ULONG Phase
966 );
967 
968 VOID
969 NTAPI
970 IopShutdownBaseFileSystems(
971     IN PLIST_ENTRY ListHead
972 );
973 
974 //
975 // Boot logging support
976 //
977 CODE_SEG("INIT")
978 VOID
979 IopInitBootLog(
980     IN BOOLEAN StartBootLog
981 );
982 
983 CODE_SEG("INIT")
984 VOID
985 IopStartBootLog(
986     VOID
987 );
988 
989 VOID
990 IopStopBootLog(
991     VOID
992 );
993 
994 VOID
995 IopBootLog(
996     IN PUNICODE_STRING DriverName,
997     IN BOOLEAN Success
998 );
999 
1000 VOID
1001 IopSaveBootLogToFile(
1002     VOID
1003 );
1004 
1005 //
1006 // I/O Cancellation Routines
1007 //
1008 VOID
1009 NTAPI
1010 IoCancelThreadIo(
1011     IN PETHREAD Thread
1012 );
1013 
1014 VOID
1015 IoInitCancelHandling(
1016     VOID
1017 );
1018 
1019 //
1020 // I/O Completion
1021 //
1022 VOID
1023 NTAPI
1024 IopCompleteRequest(
1025     IN PKAPC Apc,
1026     IN PKNORMAL_ROUTINE* NormalRoutine,
1027     IN PVOID* NormalContext,
1028     IN PVOID* SystemArgument1,
1029     IN PVOID* SystemArgument2
1030 );
1031 
1032 //
1033 // Error Logging Routines
1034 //
1035 VOID
1036 NTAPI
1037 IopInitErrorLog(
1038     VOID
1039 );
1040 
1041 VOID
1042 NTAPI
1043 IopLogWorker(
1044     IN PVOID Parameter
1045 );
1046 
1047 //
1048 // Raw File System MiniDriver
1049 //
1050 BOOLEAN
1051 RawFsIsRawFileSystemDeviceObject(
1052     IN PDEVICE_OBJECT DeviceObject
1053 );
1054 
1055 CODE_SEG("INIT")
1056 NTSTATUS
1057 NTAPI
1058 RawFsDriverEntry(
1059     IN PDRIVER_OBJECT DriverObject,
1060     IN PUNICODE_STRING RegistryPath
1061 );
1062 
1063 //
1064 // PnP Root MiniDriver
1065 //
1066 NTSTATUS
1067 NTAPI
1068 PnpRootDriverEntry(
1069    IN PDRIVER_OBJECT DriverObject,
1070    IN PUNICODE_STRING RegistryPath
1071 );
1072 
1073 NTSTATUS
1074 PnpRootCreateDevice(
1075     IN PUNICODE_STRING ServiceName,
1076     IN OPTIONAL PDRIVER_OBJECT DriverObject,
1077     OUT PDEVICE_OBJECT *PhysicalDeviceObject,
1078     OUT OPTIONAL PUNICODE_STRING FullInstancePath
1079 );
1080 
1081 NTSTATUS
1082 PnpRootRegisterDevice(
1083     IN PDEVICE_OBJECT DeviceObject);
1084 
1085 //
1086 // Driver Routines
1087 //
1088 CODE_SEG("INIT")
1089 VOID
1090 FASTCALL
1091 IopInitializeBootDrivers(
1092     VOID
1093 );
1094 
1095 CODE_SEG("INIT")
1096 VOID
1097 FASTCALL
1098 IopInitializeSystemDrivers(
1099     VOID
1100 );
1101 
1102 VOID
1103 NTAPI
1104 IopDeleteDriver(
1105     IN PVOID ObjectBody
1106 );
1107 
1108 NTSTATUS
1109 IopLoadDriver(
1110     _In_ HANDLE ServiceHandle,
1111     _Out_ PDRIVER_OBJECT *DriverObject);
1112 
1113 NTSTATUS
1114 IopGetDriverNames(
1115     _In_ HANDLE ServiceHandle,
1116     _Out_ PUNICODE_STRING DriverName,
1117     _Out_opt_ PUNICODE_STRING ServiceName);
1118 
1119 NTSTATUS
1120 IopInitializeDriverModule(
1121     _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
1122     _In_ HANDLE ServiceHandle,
1123     _Out_ PDRIVER_OBJECT *DriverObject,
1124     _Out_ NTSTATUS *DriverEntryStatus);
1125 
1126 NTSTATUS
1127 FASTCALL
1128 IopAttachFilterDrivers(
1129     IN PDEVICE_NODE DeviceNode,
1130     IN HANDLE EnumSubKey,
1131     IN HANDLE ClassKey,
1132     IN BOOLEAN Lower
1133 );
1134 
1135 VOID
1136 NTAPI
1137 IopReinitializeDrivers(
1138     VOID
1139 );
1140 
1141 VOID
1142 NTAPI
1143 IopReinitializeBootDrivers(
1144     VOID
1145 );
1146 
1147 //
1148 // File Routines
1149 //
1150 VOID
1151 NTAPI
1152 IopDeleteDevice(IN PVOID ObjectBody);
1153 
1154 NTSTATUS
1155 NTAPI
1156 IopParseDevice(
1157     IN PVOID ParseObject,
1158     IN PVOID ObjectType,
1159     IN OUT PACCESS_STATE AccessState,
1160     IN KPROCESSOR_MODE AccessMode,
1161     IN ULONG Attributes,
1162     IN OUT PUNICODE_STRING CompleteName,
1163     IN OUT PUNICODE_STRING RemainingName,
1164     IN OUT PVOID Context,
1165     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1166     OUT PVOID *Object
1167 );
1168 
1169 NTSTATUS
1170 NTAPI
1171 IopParseFile(
1172     IN PVOID ParseObject,
1173     IN PVOID ObjectType,
1174     IN OUT PACCESS_STATE AccessState,
1175     IN KPROCESSOR_MODE AccessMode,
1176     IN ULONG Attributes,
1177     IN OUT PUNICODE_STRING CompleteName,
1178     IN OUT PUNICODE_STRING RemainingName,
1179     IN OUT PVOID Context OPTIONAL,
1180     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1181     OUT PVOID *Object
1182 );
1183 
1184 VOID
1185 NTAPI
1186 IopDeleteFile(
1187     IN PVOID ObjectBody
1188 );
1189 
1190 NTSTATUS
1191 NTAPI
1192 IopGetSetSecurityObject(
1193     IN PVOID ObjectBody,
1194     IN SECURITY_OPERATION_CODE OperationCode,
1195     IN PSECURITY_INFORMATION SecurityInformation,
1196     IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
1197     IN OUT PULONG BufferLength,
1198     OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1199     IN POOL_TYPE PoolType,
1200     IN OUT PGENERIC_MAPPING GenericMapping
1201 );
1202 
1203 NTSTATUS
1204 NTAPI
1205 IopQueryName(
1206     IN PVOID ObjectBody,
1207     IN BOOLEAN HasName,
1208     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1209     IN ULONG Length,
1210     OUT PULONG ReturnLength,
1211     IN KPROCESSOR_MODE PreviousMode
1212 );
1213 
1214 NTSTATUS
1215 NTAPI
1216 IopQueryNameInternal(
1217     IN PVOID ObjectBody,
1218     IN BOOLEAN HasName,
1219     IN BOOLEAN QueryDosName,
1220     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1221     IN ULONG Length,
1222     OUT PULONG ReturnLength,
1223     IN KPROCESSOR_MODE PreviousMode
1224 );
1225 
1226 VOID
1227 NTAPI
1228 IopCloseFile(
1229     IN PEPROCESS Process OPTIONAL,
1230     IN PVOID Object,
1231     IN ACCESS_MASK GrantedAccess,
1232     IN ULONG ProcessHandleCount,
1233     IN ULONG SystemHandleCount
1234 );
1235 
1236 NTSTATUS
1237 NTAPI
1238 IopAcquireFileObjectLock(
1239     _In_ PFILE_OBJECT FileObject,
1240     _In_ KPROCESSOR_MODE AccessMode,
1241     _In_ BOOLEAN Alertable,
1242     _Out_ PBOOLEAN LockFailed
1243 );
1244 
1245 PVOID
1246 NTAPI
1247 IoGetFileObjectFilterContext(
1248     IN PFILE_OBJECT FileObject
1249 );
1250 
1251 NTSTATUS
1252 NTAPI
1253 IoChangeFileObjectFilterContext(
1254     IN PFILE_OBJECT FileObject,
1255     IN PVOID FilterContext,
1256     IN BOOLEAN Define
1257 );
1258 
1259 VOID
1260 NTAPI
1261 IopDoNameTransmogrify(
1262     IN PIRP Irp,
1263     IN PFILE_OBJECT FileObject,
1264     IN PREPARSE_DATA_BUFFER DataBuffer
1265 );
1266 
1267 NTSTATUS
1268 NTAPI
1269 IoComputeDesiredAccessFileObject(
1270     IN PFILE_OBJECT FileObject,
1271     IN PACCESS_MASK DesiredAccess
1272 );
1273 
1274 NTSTATUS
1275 NTAPI
1276 IopGetFileInformation(
1277     IN PFILE_OBJECT FileObject,
1278     IN ULONG Length,
1279     IN FILE_INFORMATION_CLASS FileInfoClass,
1280     OUT PVOID Buffer,
1281     OUT PULONG ReturnedLength
1282 );
1283 
1284 BOOLEAN
1285 NTAPI
1286 IopVerifyDeviceObjectOnStack(
1287     IN PDEVICE_OBJECT BaseDeviceObject,
1288     IN PDEVICE_OBJECT TopDeviceObjectHint
1289 );
1290 
1291 //
1292 // I/O Timer Routines
1293 //
1294 VOID
1295 FASTCALL
1296 IopInitTimerImplementation(
1297     VOID
1298 );
1299 
1300 VOID
1301 NTAPI
1302 IopRemoveTimerFromTimerList(
1303     IN PIO_TIMER Timer
1304 );
1305 
1306 //
1307 // I/O Completion Routines
1308 //
1309 VOID
1310 NTAPI
1311 IopDeleteIoCompletion(
1312     PVOID ObjectBody
1313 );
1314 
1315 NTSTATUS
1316 NTAPI
1317 IoSetIoCompletion(
1318     IN PVOID IoCompletion,
1319     IN PVOID KeyContext,
1320     IN PVOID ApcContext,
1321     IN NTSTATUS IoStatus,
1322     IN ULONG_PTR IoStatusInformation,
1323     IN BOOLEAN Quota
1324 );
1325 
1326 //
1327 // Ramdisk Routines
1328 //
1329 CODE_SEG("INIT")
1330 NTSTATUS
1331 NTAPI
1332 IopStartRamdisk(
1333     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1334 );
1335 
1336 //
1337 // Configuration Routines
1338 //
1339 NTSTATUS
1340 NTAPI
1341 IopFetchConfigurationInformation(OUT PWSTR * SymbolicLinkList,
1342                                  IN GUID Guid,
1343                                  IN ULONG ExpectedInterfaces,
1344                                  IN PULONG Interfaces
1345 );
1346 
1347 VOID
1348 NTAPI
1349 IopStoreSystemPartitionInformation(IN PUNICODE_STRING NtSystemPartitionDeviceName,
1350                                    IN PUNICODE_STRING OsLoaderPathName
1351 );
1352 
1353 //
1354 // Device action
1355 //
1356 VOID
1357 PiQueueDeviceAction(
1358     _In_ PDEVICE_OBJECT DeviceObject,
1359     _In_ DEVICE_ACTION Action,
1360     _In_opt_ PKEVENT CompletionEvent,
1361     _Out_opt_ NTSTATUS *CompletionStatus);
1362 
1363 NTSTATUS
1364 PiPerformSyncDeviceAction(
1365     _In_ PDEVICE_OBJECT DeviceObject,
1366     _In_ DEVICE_ACTION Action);
1367 
1368 //
1369 // PnP notifications
1370 //
1371 CODE_SEG("PAGE")
1372 VOID
1373 PiNotifyDeviceInterfaceChange(
1374     _In_ LPCGUID Event,
1375     _In_ LPCGUID InterfaceClassGuid,
1376     _In_ PUNICODE_STRING SymbolicLinkName);
1377 
1378 CODE_SEG("PAGE")
1379 VOID
1380 PiNotifyHardwareProfileChange(
1381     _In_ LPCGUID Event);
1382 
1383 CODE_SEG("PAGE")
1384 VOID
1385 PiNotifyTargetDeviceChange(
1386     _In_ LPCGUID Event,
1387     _In_ PDEVICE_OBJECT DeviceObject,
1388     _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification);
1389 
1390 //
1391 // PnP IRPs
1392 //
1393 NTSTATUS
1394 PiIrpStartDevice(
1395     _In_ PDEVICE_NODE DeviceNode);
1396 
1397 NTSTATUS
1398 PiIrpStopDevice(
1399     _In_ PDEVICE_NODE DeviceNode);
1400 
1401 NTSTATUS
1402 PiIrpQueryStopDevice(
1403     _In_ PDEVICE_NODE DeviceNode);
1404 
1405 NTSTATUS
1406 PiIrpCancelStopDevice(
1407     _In_ PDEVICE_NODE DeviceNode);
1408 
1409 NTSTATUS
1410 PiIrpQueryDeviceRelations(
1411     _In_ PDEVICE_NODE DeviceNode,
1412     _In_ DEVICE_RELATION_TYPE Type);
1413 
1414 NTSTATUS
1415 PiIrpQueryDeviceText(
1416     _In_ PDEVICE_NODE DeviceNode,
1417     _In_ LCID LocaleId,
1418     _In_ DEVICE_TEXT_TYPE Type,
1419     _Out_ PWSTR *DeviceText);
1420 
1421 NTSTATUS
1422 PiIrpQueryPnPDeviceState(
1423     _In_ PDEVICE_NODE DeviceNode,
1424     _Out_ PPNP_DEVICE_STATE DeviceState);
1425 
1426 //
1427 // Global I/O Data
1428 //
1429 extern POBJECT_TYPE IoCompletionType;
1430 extern PDEVICE_NODE IopRootDeviceNode;
1431 extern KSPIN_LOCK IopDeviceTreeLock;
1432 extern ULONG IopTraceLevel;
1433 extern GENERAL_LOOKASIDE IopMdlLookasideList;
1434 extern GENERIC_MAPPING IopCompletionMapping;
1435 extern GENERIC_MAPPING IopFileMapping;
1436 extern POBJECT_TYPE _IoFileObjectType;
1437 extern HAL_DISPATCH _HalDispatchTable;
1438 extern LIST_ENTRY IopErrorLogListHead;
1439 extern ULONG IopNumTriageDumpDataBlocks;
1440 extern PVOID IopTriageDumpDataBlocks[64];
1441 extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
1442 extern PDRIVER_OBJECT IopRootDriverObject;
1443 extern KSPIN_LOCK IopDeviceActionLock;
1444 extern LIST_ENTRY IopDeviceActionRequestList;
1445 extern RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator;
1446 extern BOOLEAN IoRemoteBootClient;
1447 
1448 //
1449 // Inlined Functions
1450 //
1451 #include "io_x.h"
1452