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