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