xref: /reactos/ntoskrnl/include/internal/io.h (revision 4514e91d)
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 NTAPI
803 IopVerifyDiskSignature(
804     IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout,
805     IN PARC_DISK_SIGNATURE ArcDiskSignature,
806     OUT PULONG Signature
807 );
808 
809 BOOLEAN
810 NTAPI
811 IoInitializeCrashDump(
812     IN HANDLE PageFileHandle
813 );
814 
815 CODE_SEG("INIT")
816 VOID
817 PiInitializeNotifications(
818     VOID);
819 
820 //
821 // Device/Volume Routines
822 //
823 VOID
824 NTAPI
825 IopReadyDeviceObjects(
826     IN PDRIVER_OBJECT Driver
827 );
828 
829 PVPB
830 NTAPI
831 IopCheckVpbMounted(
832     IN POPEN_PACKET OpenPacket,
833     IN PDEVICE_OBJECT DeviceObject,
834     IN PUNICODE_STRING RemainingName,
835     OUT PNTSTATUS Status
836 );
837 
838 NTSTATUS
839 NTAPI
840 IopMountVolume(
841     IN PDEVICE_OBJECT DeviceObject,
842     IN BOOLEAN AllowRawMount,
843     IN BOOLEAN DeviceIsLocked,
844     IN BOOLEAN Alertable,
845     OUT PVPB *Vpb
846 );
847 
848 PVOID
849 IoOpenSymlink(
850     IN PVOID SymbolicLink
851 );
852 
853 PVOID
854 IoOpenFileOnDevice(
855     IN PVOID SymbolicLink,
856     IN PWCHAR Name
857 );
858 
859 NTSTATUS
860 NTAPI
861 IopCreateVpb(
862     IN PDEVICE_OBJECT DeviceObject
863 );
864 
865 VOID
866 NTAPI
867 IopDereferenceVpbAndFree(
868     IN PVPB Vpb
869 );
870 
871 VOID
872 NTAPI
873 IoInitFileSystemImplementation(
874     VOID
875 );
876 
877 VOID
878 NTAPI
879 IoInitVpbImplementation(
880     VOID
881 );
882 
883 NTSTATUS
884 NTAPI
885 IopReferenceDeviceObject(
886     IN PDEVICE_OBJECT DeviceObject
887 );
888 
889 VOID
890 NTAPI
891 IopDereferenceDeviceObject(
892     IN PDEVICE_OBJECT DeviceObject,
893     IN BOOLEAN ForceUnload
894 );
895 
896 NTSTATUS
897 NTAPI
898 IopGetRelatedTargetDevice(
899     IN PFILE_OBJECT FileObject,
900     OUT PDEVICE_NODE *DeviceNode);
901 
902 NTSTATUS
903 NTAPI
904 IoGetRelatedTargetDevice(
905     IN PFILE_OBJECT FileObject,
906     OUT PDEVICE_OBJECT *DeviceObject
907 );
908 
909 VOID
910 NTAPI
911 IopUnloadDevice(
912     IN PDEVICE_OBJECT DeviceObject
913 );
914 
915 PDEVICE_OBJECT
916 NTAPI
917 IopGetDeviceAttachmentBase(
918     IN PDEVICE_OBJECT DeviceObject
919 );
920 
921 //
922 // IRP Routines
923 //
924 NTSTATUS
925 NTAPI
926 IopCleanupFailedIrp(
927     IN PFILE_OBJECT FileObject,
928     IN PKEVENT EventObject,
929     IN PVOID Buffer OPTIONAL
930 );
931 
932 VOID
933 NTAPI
934 IopAbortInterruptedIrp(
935     IN PKEVENT EventObject,
936     IN PIRP Irp
937 );
938 
939 PIRP
940 NTAPI
941 IopAllocateIrpMustSucceed(
942     IN CCHAR StackSize
943 );
944 
945 BOOLEAN
946 NTAPI
947 IopInitializeReserveIrp(
948     IN PRESERVE_IRP_ALLOCATOR ReserveIrpAllocator
949 );
950 
951 PIRP
952 NTAPI
953 IopAllocateReserveIrp(
954     IN CCHAR StackSize
955 );
956 
957 //
958 // Shutdown routines
959 //
960 VOID
961 IoInitShutdownNotification(
962     VOID
963 );
964 
965 VOID
966 NTAPI
967 IoShutdownSystem(
968     IN ULONG Phase
969 );
970 
971 VOID
972 NTAPI
973 IopShutdownBaseFileSystems(
974     IN PLIST_ENTRY ListHead
975 );
976 
977 //
978 // Boot logging support
979 //
980 CODE_SEG("INIT")
981 VOID
982 IopInitBootLog(
983     IN BOOLEAN StartBootLog
984 );
985 
986 CODE_SEG("INIT")
987 VOID
988 IopStartBootLog(
989     VOID
990 );
991 
992 VOID
993 IopStopBootLog(
994     VOID
995 );
996 
997 VOID
998 IopBootLog(
999     IN PUNICODE_STRING DriverName,
1000     IN BOOLEAN Success
1001 );
1002 
1003 VOID
1004 IopSaveBootLogToFile(
1005     VOID
1006 );
1007 
1008 //
1009 // I/O Cancellation Routines
1010 //
1011 VOID
1012 NTAPI
1013 IoCancelThreadIo(
1014     IN PETHREAD Thread
1015 );
1016 
1017 VOID
1018 IoInitCancelHandling(
1019     VOID
1020 );
1021 
1022 //
1023 // I/O Completion
1024 //
1025 VOID
1026 NTAPI
1027 IopCompleteRequest(
1028     IN PKAPC Apc,
1029     IN PKNORMAL_ROUTINE* NormalRoutine,
1030     IN PVOID* NormalContext,
1031     IN PVOID* SystemArgument1,
1032     IN PVOID* SystemArgument2
1033 );
1034 
1035 //
1036 // Error Logging Routines
1037 //
1038 VOID
1039 NTAPI
1040 IopInitErrorLog(
1041     VOID
1042 );
1043 
1044 VOID
1045 NTAPI
1046 IopLogWorker(
1047     IN PVOID Parameter
1048 );
1049 
1050 //
1051 // Raw File System MiniDriver
1052 //
1053 BOOLEAN
1054 RawFsIsRawFileSystemDeviceObject(
1055     IN PDEVICE_OBJECT DeviceObject
1056 );
1057 
1058 CODE_SEG("INIT")
1059 NTSTATUS
1060 NTAPI
1061 RawFsDriverEntry(
1062     IN PDRIVER_OBJECT DriverObject,
1063     IN PUNICODE_STRING RegistryPath
1064 );
1065 
1066 //
1067 // PnP Root MiniDriver
1068 //
1069 NTSTATUS
1070 NTAPI
1071 PnpRootDriverEntry(
1072    IN PDRIVER_OBJECT DriverObject,
1073    IN PUNICODE_STRING RegistryPath
1074 );
1075 
1076 NTSTATUS
1077 PnpRootCreateDeviceObject(
1078     OUT PDEVICE_OBJECT *DeviceObject);
1079 
1080 NTSTATUS
1081 PnpRootCreateDevice(
1082     IN PUNICODE_STRING ServiceName,
1083     OUT PDEVICE_OBJECT *PhysicalDeviceObject,
1084     OUT PUNICODE_STRING FullInstancePath
1085 );
1086 
1087 NTSTATUS
1088 PnpRootRegisterDevice(
1089     IN PDEVICE_OBJECT DeviceObject);
1090 
1091 VOID
1092 PnpRootInitializeDevExtension(VOID);
1093 
1094 //
1095 // Driver Routines
1096 //
1097 CODE_SEG("INIT")
1098 VOID
1099 FASTCALL
1100 IopInitializeBootDrivers(
1101     VOID
1102 );
1103 
1104 CODE_SEG("INIT")
1105 VOID
1106 FASTCALL
1107 IopInitializeSystemDrivers(
1108     VOID
1109 );
1110 
1111 VOID
1112 NTAPI
1113 IopDeleteDriver(
1114     IN PVOID ObjectBody
1115 );
1116 
1117 NTSTATUS
1118 IopLoadDriver(
1119     _In_ HANDLE ServiceHandle,
1120     _Out_ PDRIVER_OBJECT *DriverObject);
1121 
1122 NTSTATUS
1123 IopGetDriverNames(
1124     _In_ HANDLE ServiceHandle,
1125     _Out_ PUNICODE_STRING DriverName,
1126     _Out_opt_ PUNICODE_STRING ServiceName);
1127 
1128 NTSTATUS
1129 IopInitializeDriverModule(
1130     _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
1131     _In_ HANDLE ServiceHandle,
1132     _Out_ PDRIVER_OBJECT *DriverObject,
1133     _Out_ NTSTATUS *DriverEntryStatus);
1134 
1135 NTSTATUS
1136 FASTCALL
1137 IopAttachFilterDrivers(
1138     IN PDEVICE_NODE DeviceNode,
1139     IN HANDLE EnumSubKey,
1140     IN HANDLE ClassKey,
1141     IN BOOLEAN Lower
1142 );
1143 
1144 VOID
1145 NTAPI
1146 IopReinitializeDrivers(
1147     VOID
1148 );
1149 
1150 VOID
1151 NTAPI
1152 IopReinitializeBootDrivers(
1153     VOID
1154 );
1155 
1156 //
1157 // File Routines
1158 //
1159 VOID
1160 NTAPI
1161 IopDeleteDevice(IN PVOID ObjectBody);
1162 
1163 NTSTATUS
1164 NTAPI
1165 IopParseDevice(
1166     IN PVOID ParseObject,
1167     IN PVOID ObjectType,
1168     IN OUT PACCESS_STATE AccessState,
1169     IN KPROCESSOR_MODE AccessMode,
1170     IN ULONG Attributes,
1171     IN OUT PUNICODE_STRING CompleteName,
1172     IN OUT PUNICODE_STRING RemainingName,
1173     IN OUT PVOID Context,
1174     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1175     OUT PVOID *Object
1176 );
1177 
1178 NTSTATUS
1179 NTAPI
1180 IopParseFile(
1181     IN PVOID ParseObject,
1182     IN PVOID ObjectType,
1183     IN OUT PACCESS_STATE AccessState,
1184     IN KPROCESSOR_MODE AccessMode,
1185     IN ULONG Attributes,
1186     IN OUT PUNICODE_STRING CompleteName,
1187     IN OUT PUNICODE_STRING RemainingName,
1188     IN OUT PVOID Context OPTIONAL,
1189     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1190     OUT PVOID *Object
1191 );
1192 
1193 VOID
1194 NTAPI
1195 IopDeleteFile(
1196     IN PVOID ObjectBody
1197 );
1198 
1199 NTSTATUS
1200 NTAPI
1201 IopGetSetSecurityObject(
1202     IN PVOID ObjectBody,
1203     IN SECURITY_OPERATION_CODE OperationCode,
1204     IN PSECURITY_INFORMATION SecurityInformation,
1205     IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
1206     IN OUT PULONG BufferLength,
1207     OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1208     IN POOL_TYPE PoolType,
1209     IN OUT PGENERIC_MAPPING GenericMapping
1210 );
1211 
1212 NTSTATUS
1213 NTAPI
1214 IopQueryName(
1215     IN PVOID ObjectBody,
1216     IN BOOLEAN HasName,
1217     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1218     IN ULONG Length,
1219     OUT PULONG ReturnLength,
1220     IN KPROCESSOR_MODE PreviousMode
1221 );
1222 
1223 NTSTATUS
1224 NTAPI
1225 IopQueryNameInternal(
1226     IN PVOID ObjectBody,
1227     IN BOOLEAN HasName,
1228     IN BOOLEAN QueryDosName,
1229     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1230     IN ULONG Length,
1231     OUT PULONG ReturnLength,
1232     IN KPROCESSOR_MODE PreviousMode
1233 );
1234 
1235 VOID
1236 NTAPI
1237 IopCloseFile(
1238     IN PEPROCESS Process OPTIONAL,
1239     IN PVOID Object,
1240     IN ACCESS_MASK GrantedAccess,
1241     IN ULONG ProcessHandleCount,
1242     IN ULONG SystemHandleCount
1243 );
1244 
1245 NTSTATUS
1246 NTAPI
1247 IopAcquireFileObjectLock(
1248     _In_ PFILE_OBJECT FileObject,
1249     _In_ KPROCESSOR_MODE AccessMode,
1250     _In_ BOOLEAN Alertable,
1251     _Out_ PBOOLEAN LockFailed
1252 );
1253 
1254 PVOID
1255 NTAPI
1256 IoGetFileObjectFilterContext(
1257     IN PFILE_OBJECT FileObject
1258 );
1259 
1260 NTSTATUS
1261 NTAPI
1262 IoChangeFileObjectFilterContext(
1263     IN PFILE_OBJECT FileObject,
1264     IN PVOID FilterContext,
1265     IN BOOLEAN Define
1266 );
1267 
1268 VOID
1269 NTAPI
1270 IopDoNameTransmogrify(
1271     IN PIRP Irp,
1272     IN PFILE_OBJECT FileObject,
1273     IN PREPARSE_DATA_BUFFER DataBuffer
1274 );
1275 
1276 NTSTATUS
1277 NTAPI
1278 IoComputeDesiredAccessFileObject(
1279     IN PFILE_OBJECT FileObject,
1280     IN PACCESS_MASK DesiredAccess
1281 );
1282 
1283 NTSTATUS
1284 NTAPI
1285 IopGetFileInformation(
1286     IN PFILE_OBJECT FileObject,
1287     IN ULONG Length,
1288     IN FILE_INFORMATION_CLASS FileInfoClass,
1289     OUT PVOID Buffer,
1290     OUT PULONG ReturnedLength
1291 );
1292 
1293 BOOLEAN
1294 NTAPI
1295 IopVerifyDeviceObjectOnStack(
1296     IN PDEVICE_OBJECT BaseDeviceObject,
1297     IN PDEVICE_OBJECT TopDeviceObjectHint
1298 );
1299 
1300 //
1301 // I/O Timer Routines
1302 //
1303 VOID
1304 FASTCALL
1305 IopInitTimerImplementation(
1306     VOID
1307 );
1308 
1309 VOID
1310 NTAPI
1311 IopRemoveTimerFromTimerList(
1312     IN PIO_TIMER Timer
1313 );
1314 
1315 //
1316 // I/O Completion Routines
1317 //
1318 VOID
1319 NTAPI
1320 IopDeleteIoCompletion(
1321     PVOID ObjectBody
1322 );
1323 
1324 NTSTATUS
1325 NTAPI
1326 IoSetIoCompletion(
1327     IN PVOID IoCompletion,
1328     IN PVOID KeyContext,
1329     IN PVOID ApcContext,
1330     IN NTSTATUS IoStatus,
1331     IN ULONG_PTR IoStatusInformation,
1332     IN BOOLEAN Quota
1333 );
1334 
1335 //
1336 // Ramdisk Routines
1337 //
1338 CODE_SEG("INIT")
1339 NTSTATUS
1340 NTAPI
1341 IopStartRamdisk(
1342     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1343 );
1344 
1345 //
1346 // Configuration Routines
1347 //
1348 NTSTATUS
1349 IopFetchConfigurationInformation(
1350     _Out_ PWSTR* SymbolicLinkList,
1351     _In_ GUID Guid,
1352     _In_ ULONG ExpectedInterfaces,
1353     _Out_ PULONG Interfaces
1354 );
1355 
1356 VOID
1357 IopStoreSystemPartitionInformation(
1358     _In_ PUNICODE_STRING NtSystemPartitionDeviceName,
1359     _In_ PUNICODE_STRING OsLoaderPathName
1360 );
1361 
1362 //
1363 // Device action
1364 //
1365 VOID
1366 PiQueueDeviceAction(
1367     _In_ PDEVICE_OBJECT DeviceObject,
1368     _In_ DEVICE_ACTION Action,
1369     _In_opt_ PKEVENT CompletionEvent,
1370     _Out_opt_ NTSTATUS *CompletionStatus);
1371 
1372 NTSTATUS
1373 PiPerformSyncDeviceAction(
1374     _In_ PDEVICE_OBJECT DeviceObject,
1375     _In_ DEVICE_ACTION Action);
1376 
1377 //
1378 // PnP notifications
1379 //
1380 CODE_SEG("PAGE")
1381 VOID
1382 PiNotifyDeviceInterfaceChange(
1383     _In_ LPCGUID Event,
1384     _In_ LPCGUID InterfaceClassGuid,
1385     _In_ PUNICODE_STRING SymbolicLinkName);
1386 
1387 CODE_SEG("PAGE")
1388 VOID
1389 PiNotifyHardwareProfileChange(
1390     _In_ LPCGUID Event);
1391 
1392 CODE_SEG("PAGE")
1393 VOID
1394 PiNotifyTargetDeviceChange(
1395     _In_ LPCGUID Event,
1396     _In_ PDEVICE_OBJECT DeviceObject,
1397     _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification);
1398 
1399 //
1400 // PnP IRPs
1401 //
1402 NTSTATUS
1403 PiIrpStartDevice(
1404     _In_ PDEVICE_NODE DeviceNode);
1405 
1406 NTSTATUS
1407 PiIrpStopDevice(
1408     _In_ PDEVICE_NODE DeviceNode);
1409 
1410 NTSTATUS
1411 PiIrpQueryStopDevice(
1412     _In_ PDEVICE_NODE DeviceNode);
1413 
1414 NTSTATUS
1415 PiIrpCancelStopDevice(
1416     _In_ PDEVICE_NODE DeviceNode);
1417 
1418 NTSTATUS
1419 PiIrpQueryDeviceRelations(
1420     _In_ PDEVICE_NODE DeviceNode,
1421     _In_ DEVICE_RELATION_TYPE Type);
1422 
1423 NTSTATUS
1424 PiIrpQueryResources(
1425     _In_ PDEVICE_NODE DeviceNode,
1426     _Out_ PCM_RESOURCE_LIST *Resources);
1427 
1428 NTSTATUS
1429 PiIrpQueryResourceRequirements(
1430     _In_ PDEVICE_NODE DeviceNode,
1431     _Out_ PIO_RESOURCE_REQUIREMENTS_LIST *Resources);
1432 
1433 NTSTATUS
1434 PiIrpQueryDeviceText(
1435     _In_ PDEVICE_NODE DeviceNode,
1436     _In_ LCID LocaleId,
1437     _In_ DEVICE_TEXT_TYPE Type,
1438     _Out_ PWSTR *DeviceText);
1439 
1440 NTSTATUS
1441 PiIrpQueryPnPDeviceState(
1442     _In_ PDEVICE_NODE DeviceNode,
1443     _Out_ PPNP_DEVICE_STATE DeviceState);
1444 
1445 //
1446 // Global I/O Data
1447 //
1448 extern POBJECT_TYPE IoCompletionType;
1449 extern PDEVICE_NODE IopRootDeviceNode;
1450 extern KSPIN_LOCK IopDeviceTreeLock;
1451 extern ULONG IopTraceLevel;
1452 extern GENERAL_LOOKASIDE IopMdlLookasideList;
1453 extern GENERIC_MAPPING IopCompletionMapping;
1454 extern GENERIC_MAPPING IopFileMapping;
1455 extern POBJECT_TYPE _IoFileObjectType;
1456 extern HAL_DISPATCH _HalDispatchTable;
1457 extern LIST_ENTRY IopErrorLogListHead;
1458 extern ULONG IopNumTriageDumpDataBlocks;
1459 extern PVOID IopTriageDumpDataBlocks[64];
1460 extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
1461 extern PDRIVER_OBJECT IopRootDriverObject;
1462 extern KSPIN_LOCK IopDeviceActionLock;
1463 extern LIST_ENTRY IopDeviceActionRequestList;
1464 extern RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator;
1465 extern BOOLEAN IoRemoteBootClient;
1466 
1467 //
1468 // Inlined Functions
1469 //
1470 #include "io_x.h"
1471