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