xref: /reactos/ntoskrnl/include/internal/io.h (revision 6a6b5ec2)
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 PnpRootCreateDeviceObject(
1068     OUT PDEVICE_OBJECT *DeviceObject);
1069 
1070 NTSTATUS
1071 PnpRootCreateDevice(
1072     IN PUNICODE_STRING ServiceName,
1073     OUT PDEVICE_OBJECT *PhysicalDeviceObject,
1074     OUT PUNICODE_STRING FullInstancePath
1075 );
1076 
1077 NTSTATUS
1078 PnpRootRegisterDevice(
1079     IN PDEVICE_OBJECT DeviceObject);
1080 
1081 VOID
1082 PnpRootInitializeDevExtension(VOID);
1083 
1084 //
1085 // Driver Routines
1086 //
1087 CODE_SEG("INIT")
1088 VOID
1089 FASTCALL
1090 IopInitializeBootDrivers(
1091     VOID
1092 );
1093 
1094 CODE_SEG("INIT")
1095 VOID
1096 FASTCALL
1097 IopInitializeSystemDrivers(
1098     VOID
1099 );
1100 
1101 VOID
1102 NTAPI
1103 IopDeleteDriver(
1104     IN PVOID ObjectBody
1105 );
1106 
1107 NTSTATUS
1108 IopLoadDriver(
1109     _In_ HANDLE ServiceHandle,
1110     _Out_ PDRIVER_OBJECT *DriverObject);
1111 
1112 NTSTATUS
1113 IopGetDriverNames(
1114     _In_ HANDLE ServiceHandle,
1115     _Out_ PUNICODE_STRING DriverName,
1116     _Out_opt_ PUNICODE_STRING ServiceName);
1117 
1118 NTSTATUS
1119 IopInitializeDriverModule(
1120     _In_ PLDR_DATA_TABLE_ENTRY ModuleObject,
1121     _In_ HANDLE ServiceHandle,
1122     _Out_ PDRIVER_OBJECT *DriverObject,
1123     _Out_ NTSTATUS *DriverEntryStatus);
1124 
1125 NTSTATUS
1126 FASTCALL
1127 IopAttachFilterDrivers(
1128     IN PDEVICE_NODE DeviceNode,
1129     IN HANDLE EnumSubKey,
1130     IN HANDLE ClassKey,
1131     IN BOOLEAN Lower
1132 );
1133 
1134 VOID
1135 NTAPI
1136 IopReinitializeDrivers(
1137     VOID
1138 );
1139 
1140 VOID
1141 NTAPI
1142 IopReinitializeBootDrivers(
1143     VOID
1144 );
1145 
1146 //
1147 // File Routines
1148 //
1149 VOID
1150 NTAPI
1151 IopDeleteDevice(IN PVOID ObjectBody);
1152 
1153 NTSTATUS
1154 NTAPI
1155 IopParseDevice(
1156     IN PVOID ParseObject,
1157     IN PVOID ObjectType,
1158     IN OUT PACCESS_STATE AccessState,
1159     IN KPROCESSOR_MODE AccessMode,
1160     IN ULONG Attributes,
1161     IN OUT PUNICODE_STRING CompleteName,
1162     IN OUT PUNICODE_STRING RemainingName,
1163     IN OUT PVOID Context,
1164     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1165     OUT PVOID *Object
1166 );
1167 
1168 NTSTATUS
1169 NTAPI
1170 IopParseFile(
1171     IN PVOID ParseObject,
1172     IN PVOID ObjectType,
1173     IN OUT PACCESS_STATE AccessState,
1174     IN KPROCESSOR_MODE AccessMode,
1175     IN ULONG Attributes,
1176     IN OUT PUNICODE_STRING CompleteName,
1177     IN OUT PUNICODE_STRING RemainingName,
1178     IN OUT PVOID Context OPTIONAL,
1179     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
1180     OUT PVOID *Object
1181 );
1182 
1183 VOID
1184 NTAPI
1185 IopDeleteFile(
1186     IN PVOID ObjectBody
1187 );
1188 
1189 NTSTATUS
1190 NTAPI
1191 IopGetSetSecurityObject(
1192     IN PVOID ObjectBody,
1193     IN SECURITY_OPERATION_CODE OperationCode,
1194     IN PSECURITY_INFORMATION SecurityInformation,
1195     IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
1196     IN OUT PULONG BufferLength,
1197     OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
1198     IN POOL_TYPE PoolType,
1199     IN OUT PGENERIC_MAPPING GenericMapping
1200 );
1201 
1202 NTSTATUS
1203 NTAPI
1204 IopQueryName(
1205     IN PVOID ObjectBody,
1206     IN BOOLEAN HasName,
1207     OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
1208     IN ULONG Length,
1209     OUT PULONG ReturnLength,
1210     IN KPROCESSOR_MODE PreviousMode
1211 );
1212 
1213 NTSTATUS
1214 NTAPI
1215 IopQueryNameInternal(
1216     IN PVOID ObjectBody,
1217     IN BOOLEAN HasName,
1218     IN BOOLEAN QueryDosName,
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 NTSTATUS
1236 NTAPI
1237 IopAcquireFileObjectLock(
1238     _In_ PFILE_OBJECT FileObject,
1239     _In_ KPROCESSOR_MODE AccessMode,
1240     _In_ BOOLEAN Alertable,
1241     _Out_ PBOOLEAN LockFailed
1242 );
1243 
1244 PVOID
1245 NTAPI
1246 IoGetFileObjectFilterContext(
1247     IN PFILE_OBJECT FileObject
1248 );
1249 
1250 NTSTATUS
1251 NTAPI
1252 IoChangeFileObjectFilterContext(
1253     IN PFILE_OBJECT FileObject,
1254     IN PVOID FilterContext,
1255     IN BOOLEAN Define
1256 );
1257 
1258 VOID
1259 NTAPI
1260 IopDoNameTransmogrify(
1261     IN PIRP Irp,
1262     IN PFILE_OBJECT FileObject,
1263     IN PREPARSE_DATA_BUFFER DataBuffer
1264 );
1265 
1266 NTSTATUS
1267 NTAPI
1268 IoComputeDesiredAccessFileObject(
1269     IN PFILE_OBJECT FileObject,
1270     IN PACCESS_MASK DesiredAccess
1271 );
1272 
1273 NTSTATUS
1274 NTAPI
1275 IopGetFileInformation(
1276     IN PFILE_OBJECT FileObject,
1277     IN ULONG Length,
1278     IN FILE_INFORMATION_CLASS FileInfoClass,
1279     OUT PVOID Buffer,
1280     OUT PULONG ReturnedLength
1281 );
1282 
1283 BOOLEAN
1284 NTAPI
1285 IopVerifyDeviceObjectOnStack(
1286     IN PDEVICE_OBJECT BaseDeviceObject,
1287     IN PDEVICE_OBJECT TopDeviceObjectHint
1288 );
1289 
1290 //
1291 // I/O Timer Routines
1292 //
1293 VOID
1294 FASTCALL
1295 IopInitTimerImplementation(
1296     VOID
1297 );
1298 
1299 VOID
1300 NTAPI
1301 IopRemoveTimerFromTimerList(
1302     IN PIO_TIMER Timer
1303 );
1304 
1305 //
1306 // I/O Completion Routines
1307 //
1308 VOID
1309 NTAPI
1310 IopDeleteIoCompletion(
1311     PVOID ObjectBody
1312 );
1313 
1314 NTSTATUS
1315 NTAPI
1316 IoSetIoCompletion(
1317     IN PVOID IoCompletion,
1318     IN PVOID KeyContext,
1319     IN PVOID ApcContext,
1320     IN NTSTATUS IoStatus,
1321     IN ULONG_PTR IoStatusInformation,
1322     IN BOOLEAN Quota
1323 );
1324 
1325 //
1326 // Ramdisk Routines
1327 //
1328 CODE_SEG("INIT")
1329 NTSTATUS
1330 NTAPI
1331 IopStartRamdisk(
1332     IN PLOADER_PARAMETER_BLOCK LoaderBlock
1333 );
1334 
1335 //
1336 // Configuration Routines
1337 //
1338 NTSTATUS
1339 IopFetchConfigurationInformation(
1340     _Out_ PWSTR* SymbolicLinkList,
1341     _In_ GUID Guid,
1342     _In_ ULONG ExpectedInterfaces,
1343     _Out_ PULONG Interfaces
1344 );
1345 
1346 VOID
1347 IopStoreSystemPartitionInformation(
1348     _In_ PUNICODE_STRING NtSystemPartitionDeviceName,
1349     _In_ PUNICODE_STRING OsLoaderPathName
1350 );
1351 
1352 //
1353 // Device action
1354 //
1355 VOID
1356 PiQueueDeviceAction(
1357     _In_ PDEVICE_OBJECT DeviceObject,
1358     _In_ DEVICE_ACTION Action,
1359     _In_opt_ PKEVENT CompletionEvent,
1360     _Out_opt_ NTSTATUS *CompletionStatus);
1361 
1362 NTSTATUS
1363 PiPerformSyncDeviceAction(
1364     _In_ PDEVICE_OBJECT DeviceObject,
1365     _In_ DEVICE_ACTION Action);
1366 
1367 //
1368 // PnP notifications
1369 //
1370 CODE_SEG("PAGE")
1371 VOID
1372 PiNotifyDeviceInterfaceChange(
1373     _In_ LPCGUID Event,
1374     _In_ LPCGUID InterfaceClassGuid,
1375     _In_ PUNICODE_STRING SymbolicLinkName);
1376 
1377 CODE_SEG("PAGE")
1378 VOID
1379 PiNotifyHardwareProfileChange(
1380     _In_ LPCGUID Event);
1381 
1382 CODE_SEG("PAGE")
1383 VOID
1384 PiNotifyTargetDeviceChange(
1385     _In_ LPCGUID Event,
1386     _In_ PDEVICE_OBJECT DeviceObject,
1387     _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification);
1388 
1389 //
1390 // PnP IRPs
1391 //
1392 NTSTATUS
1393 PiIrpStartDevice(
1394     _In_ PDEVICE_NODE DeviceNode);
1395 
1396 NTSTATUS
1397 PiIrpStopDevice(
1398     _In_ PDEVICE_NODE DeviceNode);
1399 
1400 NTSTATUS
1401 PiIrpQueryStopDevice(
1402     _In_ PDEVICE_NODE DeviceNode);
1403 
1404 NTSTATUS
1405 PiIrpCancelStopDevice(
1406     _In_ PDEVICE_NODE DeviceNode);
1407 
1408 NTSTATUS
1409 PiIrpQueryDeviceRelations(
1410     _In_ PDEVICE_NODE DeviceNode,
1411     _In_ DEVICE_RELATION_TYPE Type);
1412 
1413 NTSTATUS
1414 PiIrpQueryResources(
1415     _In_ PDEVICE_NODE DeviceNode,
1416     _Out_ PCM_RESOURCE_LIST *Resources);
1417 
1418 NTSTATUS
1419 PiIrpQueryResourceRequirements(
1420     _In_ PDEVICE_NODE DeviceNode,
1421     _Out_ PIO_RESOURCE_REQUIREMENTS_LIST *Resources);
1422 
1423 NTSTATUS
1424 PiIrpQueryDeviceText(
1425     _In_ PDEVICE_NODE DeviceNode,
1426     _In_ LCID LocaleId,
1427     _In_ DEVICE_TEXT_TYPE Type,
1428     _Out_ PWSTR *DeviceText);
1429 
1430 NTSTATUS
1431 PiIrpQueryPnPDeviceState(
1432     _In_ PDEVICE_NODE DeviceNode,
1433     _Out_ PPNP_DEVICE_STATE DeviceState);
1434 
1435 //
1436 // Global I/O Data
1437 //
1438 extern POBJECT_TYPE IoCompletionType;
1439 extern PDEVICE_NODE IopRootDeviceNode;
1440 extern KSPIN_LOCK IopDeviceTreeLock;
1441 extern ULONG IopTraceLevel;
1442 extern GENERAL_LOOKASIDE IopMdlLookasideList;
1443 extern GENERIC_MAPPING IopCompletionMapping;
1444 extern GENERIC_MAPPING IopFileMapping;
1445 extern POBJECT_TYPE _IoFileObjectType;
1446 extern HAL_DISPATCH _HalDispatchTable;
1447 extern LIST_ENTRY IopErrorLogListHead;
1448 extern ULONG IopNumTriageDumpDataBlocks;
1449 extern PVOID IopTriageDumpDataBlocks[64];
1450 extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
1451 extern PDRIVER_OBJECT IopRootDriverObject;
1452 extern KSPIN_LOCK IopDeviceActionLock;
1453 extern LIST_ENTRY IopDeviceActionRequestList;
1454 extern RESERVE_IRP_ALLOCATOR IopReserveIrpAllocator;
1455 extern BOOLEAN IoRemoteBootClient;
1456 
1457 //
1458 // Inlined Functions
1459 //
1460 #include "io_x.h"
1461