xref: /reactos/ntoskrnl/include/internal/io.h (revision c7bba39a)
1 /*
2 * PROJECT:         ReactOS Kernel
3 * LICENSE:         GPL - See COPYING in the top level directory
4 * FILE:            ntoskrnl/include/internal/io.h
5 * PURPOSE:         Internal header for the I/O Manager
6 * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
7 */
8 
9 #include "ntdddisk.h"
10 
11 //
12 // Define this if you want debugging support
13 //
14 #define _IO_DEBUG_                                      0x00
15 
16 //
17 // These define the Debug Masks Supported
18 //
19 #define IO_IRP_DEBUG                                    0x01
20 #define IO_FILE_DEBUG                                   0x02
21 #define IO_API_DEBUG                                    0x04
22 #define IO_CTL_DEBUG                                    0x08
23 
24 //
25 // Debug/Tracing support
26 //
27 #if _IO_DEBUG_
28 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
29 #define IOTRACE(x, ...)                                     \
30     {                                                       \
31         DbgPrintEx("%s [%.16s] - ",                         \
32                    __FUNCTION__,                            \
33                    PsGetCurrentProcess()->ImageFileName);   \
34         DbgPrintEx(__VA_ARGS__);                            \
35     }
36 #else
37 #define IOTRACE(x, ...)                                     \
38     if (x & IopTraceLevel)                                  \
39     {                                                       \
40         DbgPrint("%s [%.16s] - ",                           \
41                  __FUNCTION__,                              \
42                  PsGetCurrentProcess()->ImageFileName);     \
43         DbgPrint(__VA_ARGS__);                              \
44     }
45 #endif
46 #else
47 #define IOTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__)
48 #endif
49 
50 //
51 // Registry path to the enumeration root key
52 //
53 #define ENUM_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum"
54 
55 //
56 // Returns the type of METHOD_ used in this IOCTL
57 //
58 #define IO_METHOD_FROM_CTL_CODE(c)                      (c & 0x00000003)
59 
60 //
61 // Bugcheck codes for RAM disk booting
62 //
63 //
64 // No LoaderXIPRom descriptor was found in the loader memory list
65 //
66 #define RD_NO_XIPROM_DESCRIPTOR  1
67 //
68 // Unable to open the RAM disk driver (ramdisk.sys or \Device\Ramdisk)
69 //
70 #define RD_NO_RAMDISK_DRIVER     2
71 //
72 // FSCTL_CREATE_RAM_DISK failed
73 //
74 #define RD_FSCTL_FAILED          3
75 //
76 // Unable to create GUID string from binary GUID
77 //
78 #define RD_GUID_CONVERT_FAILED   4
79 //
80 // Unable to create symbolic link pointing to the RAM disk device
81 //
82 #define RD_SYMLINK_CREATE_FAILED 5
83 
84 //
85 // Max traversal of reparse points for a single open in IoParseDevice
86 //
87 #define IOP_MAX_REPARSE_TRAVERSAL 0x20
88 
89 //
90 // Private flags for IoCreateFile / IoParseDevice
91 //
92 #define IOP_USE_TOP_LEVEL_DEVICE_HINT       0x01
93 #define IOP_CREATE_FILE_OBJECT_EXTENSION    0x02
94 
95 
96 typedef struct _FILE_OBJECT_EXTENSION
97 {
98     PDEVICE_OBJECT TopDeviceObjectHint;
99 
100 } FILE_OBJECT_EXTENSION, *PFILE_OBJECT_EXTENSION;
101 
102 
103 
104 //
105 // We can call the Ob Inlined API, it's the same thing
106 //
107 #define IopAllocateMdlFromLookaside                     \
108     ObpAllocateObjectCreateInfoBuffer
109 #define IopFreeMdlFromLookaside                         \
110     ObpFreeCapturedAttributes
111 
112 //
113 // Determines if the IRP is Synchronous
114 //
115 #define IsIrpSynchronous(Irp, FileObject)               \
116     ((Irp->Flags & IRP_SYNCHRONOUS_API)  ||             \
117      (!(FileObject) ?                                   \
118         FALSE :                                         \
119         FileObject->Flags & FO_SYNCHRONOUS_IO))         \
120 
121 //
122 // Returns the internal Device Object Extension
123 //
124 #define IoGetDevObjExtension(DeviceObject)              \
125     ((PEXTENDED_DEVOBJ_EXTENSION)                       \
126      (DeviceObject->DeviceObjectExtension))             \
127 
128 //
129 // Returns the internal Driver Object Extension
130 //
131 #define IoGetDrvObjExtension(DriverObject)              \
132     ((PEXTENDED_DRIVER_EXTENSION)                       \
133      (DriverObject->DriverExtension))                   \
134 
135 /*
136  * VOID
137  * IopDeviceNodeSetFlag(
138  *   PDEVICE_NODE DeviceNode,
139  *   ULONG Flag);
140  */
141 #define IopDeviceNodeSetFlag(DeviceNode, Flag)          \
142     ((DeviceNode)->Flags |= (Flag))
143 
144 /*
145  * VOID
146  * IopDeviceNodeClearFlag(
147  *   PDEVICE_NODE DeviceNode,
148  *   ULONG Flag);
149  */
150 #define IopDeviceNodeClearFlag(DeviceNode, Flag)        \
151     ((DeviceNode)->Flags &= ~(Flag))
152 
153 /*
154  * BOOLEAN
155  * IopDeviceNodeHasFlag(
156  *   PDEVICE_NODE DeviceNode,
157  *   ULONG Flag);
158  */
159 #define IopDeviceNodeHasFlag(DeviceNode, Flag)          \
160     (((DeviceNode)->Flags & (Flag)) > 0)
161 
162 /*
163  * VOID
164  * IopDeviceNodeSetUserFlag(
165  *   PDEVICE_NODE DeviceNode,
166  *   ULONG UserFlag);
167  */
168 #define IopDeviceNodeSetUserFlag(DeviceNode, UserFlag)  \
169     ((DeviceNode)->UserFlags |= (UserFlag))
170 
171 /*
172  * VOID
173  * IopDeviceNodeClearUserFlag(
174  *   PDEVICE_NODE DeviceNode,
175  *   ULONG UserFlag);
176  */
177 #define IopDeviceNodeClearUserFlag(DeviceNode, UserFlag)\
178     ((DeviceNode)->UserFlags &= ~(UserFlag))
179 
180 /*
181  * BOOLEAN
182  * IopDeviceNodeHasUserFlag(
183  *   PDEVICE_NODE DeviceNode,
184  *   ULONG UserFlag);
185  */
186 #define IopDeviceNodeHasUserFlag(DeviceNode, UserFlag)  \
187     (((DeviceNode)->UserFlags & (UserFlag)) > 0)
188 
189  /*
190  * VOID
191  * IopDeviceNodeSetProblem(
192  *   PDEVICE_NODE DeviceNode,
193  *   ULONG Problem);
194  */
195 #define IopDeviceNodeSetProblem(DeviceNode, Problem)    \
196     ((DeviceNode)->Problem |= (Problem))
197 
198 /*
199  * VOID
200  * IopDeviceNodeClearProblem(
201  *   PDEVICE_NODE DeviceNode,
202  *   ULONG Problem);
203  */
204 #define IopDeviceNodeClearProblem(DeviceNode, Problem)  \
205     ((DeviceNode)->Problem &= ~(Problem))
206 
207 /*
208  * BOOLEAN
209  * IopDeviceNodeHasProblem(
210  *   PDEVICE_NODE DeviceNode,
211  *   ULONG Problem);
212  */
213 #define IopDeviceNodeHasProblem(DeviceNode, Problem)    \
214     (((DeviceNode)->Problem & (Problem)) > 0)
215 
216 /*
217  * VOID
218  * IopInitDeviceTreeTraverseContext(
219  *   PDEVICETREE_TRAVERSE_CONTEXT DeviceTreeTraverseContext,
220  *   PDEVICE_NODE DeviceNode,
221  *   DEVICETREE_TRAVERSE_ROUTINE Action,
222  *   PVOID Context);
223  */
224 #define IopInitDeviceTreeTraverseContext(               \
225     _DeviceTreeTraverseContext, _DeviceNode, _Action,   \
226     _Context) {                                         \
227     (_DeviceTreeTraverseContext)->FirstDeviceNode =     \
228         (_DeviceNode);                                  \
229     (_DeviceTreeTraverseContext)->Action = (_Action);   \
230     (_DeviceTreeTraverseContext)->Context = (_Context); }
231 
232 /*
233  * BOOLEAN
234  * IopIsValidPhysicalDeviceObject(
235  *   IN PDEVICE_OBJECT PhysicalDeviceObject);
236  */
237 #define IopIsValidPhysicalDeviceObject(PhysicalDeviceObject)                                                            \
238         (((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject) &&                                                          \
239         (((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode) &&                      \
240         (((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->Flags & DNF_ENUMERATED))
241 
242 //
243 // Device List Operations
244 //
245 typedef enum _IOP_DEVICE_LIST_OPERATION
246 {
247     IopRemove,
248     IopAdd
249 } IOP_DEVICE_LIST_OPERATION, *PIOP_DEVICE_LIST_OPERATION;
250 
251 //
252 // Transfer statistics
253 //
254 typedef enum _IOP_TRANSFER_TYPE
255 {
256     IopReadTransfer,
257     IopWriteTransfer,
258     IopOtherTransfer
259 } IOP_TRANSFER_TYPE, *PIOP_TRANSFER_TYPE;
260 
261 //
262 // Packet Types when piggybacking on the IRP Overlay
263 //
264 typedef enum _COMPLETION_PACKET_TYPE
265     {
266     IopCompletionPacketIrp,
267     IopCompletionPacketMini,
268     IopCompletionPacketQuota
269 } COMPLETION_PACKET_TYPE, *PCOMPLETION_PACKET_TYPE;
270 
271 //
272 // Special version of the IRP Overlay used to optimize I/O completion
273 // by not using up a separate structure.
274 //
275 typedef struct _IOP_MINI_COMPLETION_PACKET
276 {
277     struct
278     {
279         LIST_ENTRY ListEntry;
280         union
281         {
282             struct _IO_STACK_LOCATION *CurrentStackLocation;
283             ULONG PacketType;
284         };
285     };
286     PVOID KeyContext;
287     PVOID ApcContext;
288     NTSTATUS IoStatus;
289     ULONG_PTR IoStatusInformation;
290 } IOP_MINI_COMPLETION_PACKET, *PIOP_MINI_COMPLETION_PACKET;
291 
292 //
293 // I/O Completion Context for IoSetIoCompletionRoutineEx
294 //
295 typedef struct _IO_UNLOAD_SAFE_COMPLETION_CONTEXT
296 {
297     PDEVICE_OBJECT DeviceObject;
298     PVOID Context;
299     PIO_COMPLETION_ROUTINE CompletionRoutine;
300 } IO_UNLOAD_SAFE_COMPLETION_CONTEXT, *PIO_UNLOAD_SAFE_COMPLETION_CONTEXT;
301 
302 //
303 // I/O Wrapper around the Executive Work Item
304 //
305 typedef struct _IO_WORKITEM
306 {
307     WORK_QUEUE_ITEM Item;
308     PDEVICE_OBJECT DeviceObject;
309     PIO_WORKITEM_ROUTINE WorkerRoutine;
310     PVOID Context;
311 } IO_WORKITEM;
312 
313 //
314 // I/O Wrapper around the Kernel Interrupt
315 //
316 typedef struct _IO_INTERRUPT
317 {
318     KINTERRUPT FirstInterrupt;
319     PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS];
320     KSPIN_LOCK SpinLock;
321 } IO_INTERRUPT, *PIO_INTERRUPT;
322 
323 //
324 // I/O Error Log Packet Header
325 //
326 typedef struct _ERROR_LOG_ENTRY
327 {
328     CSHORT Type;
329     CSHORT Size;
330     LIST_ENTRY ListEntry;
331     PDEVICE_OBJECT DeviceObject;
332     PDRIVER_OBJECT DriverObject;
333     LARGE_INTEGER TimeStamp;
334 } ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
335 
336 //
337 // To simplify matters, the kernel is made to support both the checked and free
338 // version of the I/O Remove Lock in the same binary. This structure includes
339 // both, since the DDK has the structure with a compile-time #ifdef.
340 //
341 typedef struct _EXTENDED_IO_REMOVE_LOCK
342 {
343     IO_REMOVE_LOCK_COMMON_BLOCK Common;
344     IO_REMOVE_LOCK_DBG_BLOCK Dbg;
345 } EXTENDED_IO_REMOVE_LOCK, *PEXTENDED_IO_REMOVE_LOCK;
346 
347 //
348 // Dummy File Object used inside the Open Packet so that OB knows how to
349 // deal with the Object Pointer even though it's not a real file.
350 //
351 typedef struct _DUMMY_FILE_OBJECT
352 {
353     OBJECT_HEADER ObjectHeader;
354     CHAR FileObjectBody[sizeof(FILE_OBJECT)];
355 } DUMMY_FILE_OBJECT, *PDUMMY_FILE_OBJECT;
356 
357 //
358 // Open packet used as a context for Device/File parsing so that the parse
359 // routine can know what operation is being requested.
360 //
361 typedef struct _OPEN_PACKET
362 {
363     CSHORT Type;
364     CSHORT Size;
365     PFILE_OBJECT FileObject;
366     NTSTATUS FinalStatus;
367     ULONG_PTR Information;
368     ULONG ParseCheck;
369     PFILE_OBJECT RelatedFileObject;
370     OBJECT_ATTRIBUTES OriginalAttributes;
371     LARGE_INTEGER AllocationSize;
372     ULONG CreateOptions;
373     USHORT FileAttributes;
374     USHORT ShareAccess;
375     PVOID EaBuffer;
376     ULONG EaLength;
377     ULONG Options;
378     ULONG Disposition;
379     PFILE_BASIC_INFORMATION BasicInformation;
380     PFILE_NETWORK_OPEN_INFORMATION NetworkInformation;
381     CREATE_FILE_TYPE CreateFileType;
382     PVOID ExtraCreateParameters;
383     BOOLEAN Override;
384     BOOLEAN QueryOnly;
385     BOOLEAN DeleteOnly;
386     BOOLEAN FullAttributes;
387     PDUMMY_FILE_OBJECT LocalFileObject;
388     BOOLEAN TraversedMountPoint;
389     ULONG InternalFlags;
390     PDEVICE_OBJECT TopDeviceObjectHint;
391 } OPEN_PACKET, *POPEN_PACKET;
392 
393 //
394 // Parameters packet for Load/Unload work item's context
395 //
396 typedef struct _LOAD_UNLOAD_PARAMS
397 {
398     NTSTATUS Status;
399     PCUNICODE_STRING RegistryPath;
400     WORK_QUEUE_ITEM WorkItem;
401     KEVENT Event;
402     PDRIVER_OBJECT DriverObject;
403 } LOAD_UNLOAD_PARAMS, *PLOAD_UNLOAD_PARAMS;
404 
405 //
406 // Boot Driver List Entry
407 //
408 typedef struct _DRIVER_INFORMATION
409 {
410     LIST_ENTRY Link;
411     PDRIVER_OBJECT DriverObject;
412     PBOOT_DRIVER_LIST_ENTRY DataTableEntry;
413     HANDLE ServiceHandle;
414     USHORT TagPosition;
415     ULONG Failed;
416     ULONG Processed;
417     NTSTATUS Status;
418 } DRIVER_INFORMATION, *PDRIVER_INFORMATION;
419 
420 //
421 // Boot Driver Node
422 //
423 typedef struct _BOOT_DRIVER_NODE
424 {
425     BOOT_DRIVER_LIST_ENTRY ListEntry;
426     UNICODE_STRING Group;
427     UNICODE_STRING Name;
428     ULONG Tag;
429     ULONG ErrorControl;
430 } BOOT_DRIVER_NODE, *PBOOT_DRIVER_NODE;
431 
432 //
433 // List of Bus Type GUIDs
434 //
435 typedef struct _IO_BUS_TYPE_GUID_LIST
436 {
437     ULONG GuidCount;
438     FAST_MUTEX Lock;
439     GUID Guids[1];
440 } IO_BUS_TYPE_GUID_LIST, *PIO_BUS_TYPE_GUID_LIST;
441 extern PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList;
442 
443 //
444 // Shutdown entry for registed devices
445 //
446 typedef struct _SHUTDOWN_ENTRY
447 {
448     LIST_ENTRY ShutdownList;
449     PDEVICE_OBJECT DeviceObject;
450 } SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
451 
452 //
453 // F/S Notification entry for registered File Systems
454 //
455 typedef struct _FS_CHANGE_NOTIFY_ENTRY
456 {
457     LIST_ENTRY FsChangeNotifyList;
458     PDRIVER_OBJECT DriverObject;
459     PDRIVER_FS_NOTIFICATION FSDNotificationProc;
460 } FS_CHANGE_NOTIFY_ENTRY, *PFS_CHANGE_NOTIFY_ENTRY;
461 
462 //
463 // Driver (Boot) Re-Initialization Entry
464 //
465 typedef struct _DRIVER_REINIT_ITEM
466 {
467     LIST_ENTRY ItemEntry;
468     PDRIVER_OBJECT DriverObject;
469     PDRIVER_REINITIALIZE ReinitRoutine;
470     PVOID Context;
471 } DRIVER_REINIT_ITEM, *PDRIVER_REINIT_ITEM;
472 
473 //
474 // Called on every visit of a node during a preorder-traversal of the device
475 // node tree.
476 // If the routine returns STATUS_UNSUCCESSFUL the traversal will stop and
477 // STATUS_SUCCESS is returned to the caller who initiated the tree traversal.
478 // Any other returned status code will be returned to the caller. If a status
479 // code that indicates an error (other than STATUS_UNSUCCESSFUL) is returned,
480 // the traversal is stopped immediately and the status code is returned to
481 // the caller.
482 //
483 typedef
484 NTSTATUS
485 (*DEVICETREE_TRAVERSE_ROUTINE)(
486     IN PDEVICE_NODE DeviceNode,
487     IN PVOID Context
488 );
489 
490 //
491 // Context information for traversing the device tree
492 //
493 typedef struct _DEVICETREE_TRAVERSE_CONTEXT
494 {
495     //
496     // Current device node during a traversal
497     //
498     PDEVICE_NODE DeviceNode;
499 
500     //
501     // Initial device node where we start the traversal
502     //
503     PDEVICE_NODE FirstDeviceNode;
504 
505     //
506     // Action routine to be called for every device node
507     //
508     DEVICETREE_TRAVERSE_ROUTINE Action;
509 
510     //
511     // Context passed to the action routine
512     //
513     PVOID Context;
514 } DEVICETREE_TRAVERSE_CONTEXT, *PDEVICETREE_TRAVERSE_CONTEXT;
515 
516 //
517 // Reserve IRP allocator
518 // Used for read paging IOs in low-memory situations
519 //
520 typedef struct _RESERVE_IRP_ALLOCATOR
521 {
522     PIRP ReserveIrp;
523     volatile LONG ReserveIrpInUse;
524     KEVENT WaitEvent;
525     CCHAR StackSize;
526 } RESERVE_IRP_ALLOCATOR, *PRESERVE_IRP_ALLOCATOR;
527 
528 //
529 // Resource code
530 //
531 ULONG
532 NTAPI
533 PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList);
534 
535 NTSTATUS
536 NTAPI
537 IopAssignDeviceResources(
538     IN PDEVICE_NODE DeviceNode
539 );
540 
541 NTSTATUS
542 NTAPI
543 IopFixupResourceListWithRequirements(
544     IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
545     OUT PCM_RESOURCE_LIST *ResourceList
546 );
547 
548 NTSTATUS
549 NTAPI
550 IopDetectResourceConflict(
551      IN PCM_RESOURCE_LIST ResourceList,
552      IN BOOLEAN Silent,
553      OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor
554 );
555 
556 //
557 // PNP Routines
558 //
559 NTSTATUS
560 NTAPI
561 PipCallDriverAddDevice(
562     IN PDEVICE_NODE DeviceNode,
563     IN BOOLEAN LoadDriver,
564     IN PDRIVER_OBJECT DriverObject
565 );
566 
567 NTSTATUS
568 NTAPI
569 IopInitializePlugPlayServices(
570     VOID
571 );
572 
573 BOOLEAN
574 NTAPI
575 PpInitSystem(
576     VOID
577 );
578 
579 VOID
580 PnpInit2(
581     VOID
582 );
583 
584 VOID
585 IopInitDriverImplementation(
586     VOID
587 );
588 
589 VOID
590 IopInitPnpNotificationImplementation(
591     VOID
592 );
593 
594 VOID
595 IopNotifyPlugPlayNotification(
596     IN PDEVICE_OBJECT DeviceObject,
597     IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
598     IN LPCGUID Event,
599     IN PVOID EventCategoryData1,
600     IN PVOID EventCategoryData2
601 );
602 
603 NTSTATUS
604 IopGetSystemPowerDeviceObject(
605     IN PDEVICE_OBJECT *DeviceObject
606 );
607 
608 PDEVICE_NODE
609 NTAPI
610 PipAllocateDeviceNode(
611     IN PDEVICE_OBJECT PhysicalDeviceObject
612 );
613 
614 NTSTATUS
615 IopCreateDeviceNode(
616     IN PDEVICE_NODE ParentNode,
617     IN PDEVICE_OBJECT PhysicalDeviceObject,
618     IN PUNICODE_STRING ServiceName,
619     OUT PDEVICE_NODE *DeviceNode
620 );
621 
622 NTSTATUS
623 IopFreeDeviceNode(
624     IN PDEVICE_NODE DeviceNode
625 );
626 
627 NTSTATUS
628 NTAPI
629 IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
630                            PDEVICE_CAPABILITIES DeviceCaps);
631 
632 NTSTATUS
633 NTAPI
634 IopSynchronousCall(
635     IN PDEVICE_OBJECT DeviceObject,
636     IN PIO_STACK_LOCATION IoStackLocation,
637     OUT PVOID *Information
638 );
639 
640 NTSTATUS
641 NTAPI
642 IopInitiatePnpIrp(
643     IN PDEVICE_OBJECT DeviceObject,
644     IN PIO_STATUS_BLOCK IoStatusBlock,
645     IN UCHAR MinorFunction,
646     IN PIO_STACK_LOCATION Stack
647 );
648 
649 PDEVICE_NODE
650 FASTCALL
651 IopGetDeviceNode(
652     IN PDEVICE_OBJECT DeviceObject
653 );
654 
655 NTSTATUS
656 IopActionConfigureChildServices(
657     IN PDEVICE_NODE DeviceNode,
658     IN PVOID Context
659 );
660 
661 NTSTATUS
662 IopActionInitChildServices(
663     IN PDEVICE_NODE DeviceNode,
664     IN PVOID Context
665 );
666 
667 NTSTATUS
668 IopEnumerateDevice(
669     IN PDEVICE_OBJECT DeviceObject
670 );
671 
672 NTSTATUS
673 IoCreateDriverList(
674     VOID
675 );
676 
677 NTSTATUS
678 IoDestroyDriverList(
679     VOID
680 );
681 
682 NTSTATUS
683 IopInitPlugPlayEvents(VOID);
684 
685 NTSTATUS
686 IopQueueTargetDeviceEvent(
687     const GUID *Guid,
688     PUNICODE_STRING DeviceIds
689 );
690 
691 NTSTATUS
692 IopInitializePnpServices(
693     IN PDEVICE_NODE DeviceNode);
694 
695 NTSTATUS
696 NTAPI
697 IopOpenRegistryKeyEx(
698     PHANDLE KeyHandle,
699     HANDLE ParentKey,
700     PUNICODE_STRING Name,
701     ACCESS_MASK DesiredAccess);
702 
703 NTSTATUS
704 NTAPI
705 IopGetRegistryValue(
706     IN HANDLE Handle,
707     IN PWSTR ValueName,
708     OUT PKEY_VALUE_FULL_INFORMATION *Information
709 );
710 
711 NTSTATUS
712 NTAPI
713 IopCreateRegistryKeyEx(
714     OUT PHANDLE Handle,
715     IN HANDLE BaseHandle OPTIONAL,
716     IN PUNICODE_STRING KeyName,
717     IN ACCESS_MASK DesiredAccess,
718     IN ULONG CreateOptions,
719     OUT PULONG Disposition OPTIONAL
720 );
721 
722 
723 NTSTATUS
724 IopTraverseDeviceTree(
725     PDEVICETREE_TRAVERSE_CONTEXT Context);
726 
727 //
728 // PnP Routines
729 //
730 NTSTATUS
731 NTAPI
732 IopUpdateRootKey(
733     VOID
734 );
735 
736 NTSTATUS
737 NTAPI
738 PiInitCacheGroupInformation(
739     VOID
740 );
741 
742 USHORT
743 NTAPI
744 PpInitGetGroupOrderIndex(
745     IN HANDLE ServiceHandle
746 );
747 
748 USHORT
749 NTAPI
750 PipGetDriverTagPriority(
751     IN HANDLE ServiceHandle
752 );
753 
754 NTSTATUS
755 NTAPI
756 PnpRegMultiSzToUnicodeStrings(
757     IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
758     OUT PUNICODE_STRING *UnicodeStringList,
759     OUT PULONG UnicodeStringCount
760 );
761 
762 BOOLEAN
763 NTAPI
764 PnpRegSzToString(
765     IN PWCHAR RegSzData,
766     IN ULONG RegSzLength,
767     OUT PUSHORT StringLength OPTIONAL
768 );
769 
770 //
771 // Initialization Routines
772 //
773 NTSTATUS
774 NTAPI
775 IopCreateArcNames(
776     IN PLOADER_PARAMETER_BLOCK LoaderBlock
777 );
778 
779 NTSTATUS
780 NTAPI
781 IopReassignSystemRoot(
782     IN PLOADER_PARAMETER_BLOCK LoaderBlock,
783     OUT PANSI_STRING NtBootPath
784 );
785 
786 BOOLEAN
787 NTAPI
788 IoInitSystem(
789     IN PLOADER_PARAMETER_BLOCK LoaderBlock
790 );
791 
792 BOOLEAN
793 NTAPI
794 IopVerifyDiskSignature(
795     IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout,
796     IN PARC_DISK_SIGNATURE ArcDiskSignature,
797     OUT PULONG Signature
798 );
799 
800 //
801 // Device/Volume Routines
802 //
803 VOID
804 NTAPI
805 IopReadyDeviceObjects(
806     IN PDRIVER_OBJECT Driver
807 );
808 
809 NTSTATUS
810 FASTCALL
811 IopInitializeDevice(
812     IN PDEVICE_NODE DeviceNode,
813     IN PDRIVER_OBJECT DriverObject
814 );
815 
816 NTSTATUS
817 IopStartDevice(
818     IN PDEVICE_NODE DeviceNode
819 );
820 
821 NTSTATUS
822 IopStopDevice(
823     IN PDEVICE_NODE DeviceNode
824 );
825 
826 NTSTATUS
827 IopRemoveDevice(
828     IN PDEVICE_NODE DeviceNode
829 );
830 
831 PVPB
832 NTAPI
833 IopCheckVpbMounted(
834     IN POPEN_PACKET OpenPacket,
835     IN PDEVICE_OBJECT DeviceObject,
836     IN PUNICODE_STRING RemainingName,
837     OUT PNTSTATUS Status
838 );
839 
840 NTSTATUS
841 NTAPI
842 IopMountVolume(
843     IN PDEVICE_OBJECT DeviceObject,
844     IN BOOLEAN AllowRawMount,
845     IN BOOLEAN DeviceIsLocked,
846     IN BOOLEAN Alertable,
847     OUT PVPB *Vpb
848 );
849 
850 PVOID
851 IoOpenSymlink(
852     IN PVOID SymbolicLink
853 );
854 
855 PVOID
856 IoOpenFileOnDevice(
857     IN PVOID SymbolicLink,
858     IN PWCHAR Name
859 );
860 
861 NTSTATUS
862 NTAPI
863 IopCreateVpb(
864     IN PDEVICE_OBJECT DeviceObject
865 );
866 
867 VOID
868 NTAPI
869 IopDereferenceVpbAndFree(
870     IN PVPB Vpb
871 );
872 
873 VOID
874 NTAPI
875 IoInitFileSystemImplementation(
876     VOID
877 );
878 
879 VOID
880 NTAPI
881 IoInitVpbImplementation(
882     VOID
883 );
884 
885 NTSTATUS
886 NTAPI
887 IopReferenceDeviceObject(
888     IN PDEVICE_OBJECT DeviceObject
889 );
890 
891 VOID
892 NTAPI
893 IopDereferenceDeviceObject(
894     IN PDEVICE_OBJECT DeviceObject,
895     IN BOOLEAN ForceUnload
896 );
897 
898 NTSTATUS
899 NTAPI
900 IoGetRelatedTargetDevice(
901     IN PFILE_OBJECT FileObject,
902     OUT PDEVICE_OBJECT *DeviceObject
903 );
904 
905 VOID
906 NTAPI
907 IopUnloadDevice(
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 VOID
971 IopInitBootLog(
972     IN BOOLEAN StartBootLog
973 );
974 
975 VOID
976 IopStartBootLog(
977     VOID
978 );
979 
980 VOID
981 IopStopBootLog(
982     VOID
983 );
984 
985 VOID
986 IopBootLog(
987     IN PUNICODE_STRING DriverName,
988     IN BOOLEAN Success
989 );
990 
991 VOID
992 IopSaveBootLogToFile(
993     VOID
994 );
995 
996 //
997 // I/O Cancellation Routines
998 //
999 VOID
1000 NTAPI
1001 IoCancelThreadIo(
1002     IN PETHREAD Thread
1003 );
1004 
1005 VOID
1006 IoInitCancelHandling(
1007     VOID
1008 );
1009 
1010 //
1011 // I/O Completion
1012 //
1013 VOID
1014 NTAPI
1015 IopCompleteRequest(
1016     IN PKAPC Apc,
1017     IN PKNORMAL_ROUTINE* NormalRoutine,
1018     IN PVOID* NormalContext,
1019     IN PVOID* SystemArgument1,
1020     IN PVOID* SystemArgument2
1021 );
1022 
1023 //
1024 // Error Logging Routines
1025 //
1026 VOID
1027 NTAPI
1028 IopInitErrorLog(
1029     VOID
1030 );
1031 
1032 VOID
1033 NTAPI
1034 IopLogWorker(
1035     IN PVOID Parameter
1036 );
1037 
1038 //
1039 // Raw File System MiniDriver
1040 //
1041 BOOLEAN
1042 RawFsIsRawFileSystemDeviceObject(
1043     IN PDEVICE_OBJECT DeviceObject
1044 );
1045 
1046 NTSTATUS
1047 NTAPI
1048 RawFsDriverEntry(
1049     IN PDRIVER_OBJECT DriverObject,
1050     IN PUNICODE_STRING RegistryPath
1051 );
1052 
1053 //
1054 // PnP Root MiniDriver
1055 //
1056 NTSTATUS
1057 NTAPI
1058 PnpRootDriverEntry(
1059    IN PDRIVER_OBJECT DriverObject,
1060    IN PUNICODE_STRING RegistryPath
1061 );
1062 
1063 NTSTATUS
1064 PnpRootCreateDevice(
1065     IN PUNICODE_STRING ServiceName,
1066     IN OPTIONAL PDRIVER_OBJECT DriverObject,
1067     OUT PDEVICE_OBJECT *PhysicalDeviceObject,
1068     OUT OPTIONAL PUNICODE_STRING FullInstancePath
1069 );
1070 
1071 NTSTATUS
1072 PnpRootRegisterDevice(
1073     IN PDEVICE_OBJECT DeviceObject);
1074 
1075 //
1076 // Driver Routines
1077 //
1078 VOID
1079 FASTCALL
1080 IopInitializeBootDrivers(
1081     VOID
1082 );
1083 
1084 VOID
1085 FASTCALL
1086 IopInitializeSystemDrivers(
1087     VOID
1088 );
1089 
1090 NTSTATUS
1091 NTAPI
1092 IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
1093                 IN PDRIVER_INITIALIZE InitializationFunction,
1094                 IN PUNICODE_STRING RegistryPath,
1095                 IN PCUNICODE_STRING ServiceName,
1096                 PLDR_DATA_TABLE_ENTRY ModuleObject,
1097                 OUT PDRIVER_OBJECT *pDriverObject);
1098 
1099 VOID
1100 NTAPI
1101 IopDeleteDriver(
1102     IN PVOID ObjectBody
1103 );
1104 
1105 NTSTATUS
1106 FASTCALL
1107 IopGetDriverObject(
1108     OUT PDRIVER_OBJECT *DriverObject,
1109     IN PUNICODE_STRING ServiceName,
1110     IN BOOLEAN FileSystem
1111 );
1112 
1113 NTSTATUS
1114 FASTCALL
1115 IopLoadServiceModule(
1116     IN PUNICODE_STRING ServiceName,
1117     OUT PLDR_DATA_TABLE_ENTRY *ModuleObject
1118 );
1119 
1120 NTSTATUS
1121 NTAPI
1122 IopLoadUnloadDriver(
1123     _In_opt_ PCUNICODE_STRING RegistryPath,
1124     _Inout_ PDRIVER_OBJECT *DriverObject
1125 );
1126 
1127 NTSTATUS
1128 FASTCALL
1129 IopInitializeDriverModule(
1130     IN PDEVICE_NODE DeviceNode,
1131     IN PLDR_DATA_TABLE_ENTRY ModuleObject,
1132     IN PUNICODE_STRING ServiceName,
1133     IN BOOLEAN FileSystemDriver,
1134     OUT PDRIVER_OBJECT *DriverObject
1135 );
1136 
1137 NTSTATUS
1138 FASTCALL
1139 IopAttachFilterDrivers(
1140     IN PDEVICE_NODE DeviceNode,
1141     IN HANDLE EnumSubKey,
1142     IN HANDLE ClassKey,
1143     IN BOOLEAN Lower
1144 );
1145 
1146 VOID
1147 NTAPI
1148 IopReinitializeDrivers(
1149     VOID
1150 );
1151 
1152 VOID
1153 NTAPI
1154 IopReinitializeBootDrivers(
1155     VOID
1156 );
1157 
1158 //
1159 // File Routines
1160 //
1161 VOID
1162 NTAPI
1163 IopDeleteDevice(IN PVOID ObjectBody);
1164 
1165 NTSTATUS
1166 NTAPI
1167 IopParseDevice(
1168     IN PVOID ParseObject,
1169     IN PVOID ObjectType,
1170     IN OUT PACCESS_STATE AccessState,
1171     IN KPROCESSOR_MODE AccessMode,
1172     IN ULONG Attributes,
1173     IN OUT PUNICODE_STRING CompleteName,
1174     IN OUT PUNICODE_STRING RemainingName,
1175     IN OUT PVOID Context,
1176     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1177     OUT PVOID *Object
1178 );
1179 
1180 NTSTATUS
1181 NTAPI
1182 IopParseFile(
1183     IN PVOID ParseObject,
1184     IN PVOID ObjectType,
1185     IN OUT PACCESS_STATE AccessState,
1186     IN KPROCESSOR_MODE AccessMode,
1187     IN ULONG Attributes,
1188     IN OUT PUNICODE_STRING CompleteName,
1189     IN OUT PUNICODE_STRING RemainingName,
1190     IN OUT PVOID Context OPTIONAL,
1191     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1192     OUT PVOID *Object
1193 );
1194 
1195 VOID
1196 NTAPI
1197 IopDeleteFile(
1198     IN PVOID ObjectBody
1199 );
1200 
1201 NTSTATUS
1202 NTAPI
1203 IopGetSetSecurityObject(
1204     IN PVOID ObjectBody,
1205     IN SECURITY_OPERATION_CODE OperationCode,
1206     IN PSECURITY_INFORMATION SecurityInformation,
1207     IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
1208     IN OUT PULONG BufferLength,
1209     OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1210     IN POOL_TYPE PoolType,
1211     IN OUT PGENERIC_MAPPING GenericMapping
1212 );
1213 
1214 NTSTATUS
1215 NTAPI
1216 IopQueryNameFile(
1217     IN PVOID ObjectBody,
1218     IN BOOLEAN HasName,
1219     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1220     IN ULONG Length,
1221     OUT PULONG ReturnLength,
1222     IN KPROCESSOR_MODE PreviousMode
1223 );
1224 
1225 VOID
1226 NTAPI
1227 IopCloseFile(
1228     IN PEPROCESS Process OPTIONAL,
1229     IN PVOID Object,
1230     IN ACCESS_MASK GrantedAccess,
1231     IN ULONG ProcessHandleCount,
1232     IN ULONG SystemHandleCount
1233 );
1234 
1235 PVOID
1236 NTAPI
1237 IoGetFileObjectFilterContext(
1238     IN PFILE_OBJECT FileObject
1239 );
1240 
1241 NTSTATUS
1242 NTAPI
1243 IoChangeFileObjectFilterContext(
1244     IN PFILE_OBJECT FileObject,
1245     IN PVOID FilterContext,
1246     IN BOOLEAN Define
1247 );
1248 
1249 VOID
1250 NTAPI
1251 IopDoNameTransmogrify(
1252     IN PIRP Irp,
1253     IN PFILE_OBJECT FileObject,
1254     IN PREPARSE_DATA_BUFFER DataBuffer
1255 );
1256 
1257 NTSTATUS
1258 NTAPI
1259 IoComputeDesiredAccessFileObject(
1260     IN PFILE_OBJECT FileObject,
1261     IN PACCESS_MASK DesiredAccess
1262 );
1263 
1264 //
1265 // I/O Timer Routines
1266 //
1267 VOID
1268 FASTCALL
1269 IopInitTimerImplementation(
1270     VOID
1271 );
1272 
1273 VOID
1274 NTAPI
1275 IopRemoveTimerFromTimerList(
1276     IN PIO_TIMER Timer
1277 );
1278 
1279 //
1280 // I/O Completion Routines
1281 //
1282 VOID
1283 NTAPI
1284 IopDeleteIoCompletion(
1285     PVOID ObjectBody
1286 );
1287 
1288 NTSTATUS
1289 NTAPI
1290 IoSetIoCompletion(
1291     IN PVOID IoCompletion,
1292     IN PVOID KeyContext,
1293     IN PVOID ApcContext,
1294     IN NTSTATUS IoStatus,
1295     IN ULONG_PTR IoStatusInformation,
1296     IN BOOLEAN Quota
1297 );
1298 
1299 //
1300 // Ramdisk Routines
1301 //
1302 NTSTATUS
1303 NTAPI
1304 IopStartRamdisk(
1305     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1306 );
1307 
1308 //
1309 // Configuration Routines
1310 //
1311 NTSTATUS
1312 NTAPI
1313 IopFetchConfigurationInformation(OUT PWSTR * SymbolicLinkList,
1314                                  IN GUID Guid,
1315                                  IN ULONG ExpectedInterfaces,
1316                                  IN PULONG Interfaces
1317 );
1318 
1319 VOID
1320 NTAPI
1321 IopStoreSystemPartitionInformation(IN PUNICODE_STRING NtSystemPartitionDeviceName,
1322                                    IN PUNICODE_STRING OsLoaderPathName
1323 );
1324 
1325 //
1326 // Global I/O Data
1327 //
1328 extern POBJECT_TYPE IoCompletionType;
1329 extern PDEVICE_NODE IopRootDeviceNode;
1330 extern KSPIN_LOCK IopDeviceTreeLock;
1331 extern ULONG IopTraceLevel;
1332 extern GENERAL_LOOKASIDE IopMdlLookasideList;
1333 extern GENERIC_MAPPING IopCompletionMapping;
1334 extern GENERIC_MAPPING IopFileMapping;
1335 extern POBJECT_TYPE _IoFileObjectType;
1336 extern HAL_DISPATCH _HalDispatchTable;
1337 extern LIST_ENTRY IopErrorLogListHead;
1338 extern ULONG IopNumTriageDumpDataBlocks;
1339 extern PVOID IopTriageDumpDataBlocks[64];
1340 extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
1341 extern PDRIVER_OBJECT IopRootDriverObject;
1342 extern KSPIN_LOCK IopDeviceRelationsSpinLock;
1343 extern LIST_ENTRY IopDeviceRelationsRequestList;
1344 extern RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator;
1345 
1346 //
1347 // Inlined Functions
1348 //
1349 #include "io_x.h"
1350