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