2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/include/io.h
5 * PURPOSE: Internal header for the I/O Manager
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
11 // Define this if you want debugging support
13 #define _IO_DEBUG_ 0x00
16 // These define the Debug Masks Supported
18 #define IO_IRP_DEBUG 0x01
21 // Debug/Tracing support
24 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
25 #define IOTRACE DbgPrintEx
27 #define IOTRACE(x, ...) \
28 if (x & IopTraceLevel) DbgPrint(__VA_ARGS__)
31 #define IOTRACE(x, ...) DPRINT(__VA_ARGS__)
35 // Returns the type of METHOD_ used in this IOCTL
37 #define IO_METHOD_FROM_CTL_CODE(c) (c & 0x00000003)
40 // Packet Types when piggybacking on the IRP Overlay
42 #define IrpCompletionPacket 0x1
43 #define IrpMiniCompletionPacket 0x2
46 // Number of partition tables in the Boot Record
48 #define PARTITION_TBL_SIZE 4
51 // We can call the Ob Inlined API, it's the same thing
53 #define IopAllocateMdlFromLookaside \
54 ObpAllocateCapturedAttributes
55 #define IopFreeMdlFromLookaside \
56 ObpFreeCapturedAttributes
59 // Returns the size of a CM_RESOURCE_LIST
61 #define CM_RESOURCE_LIST_SIZE(ResList) \
62 (ResList->Count == 1) ? \
65 List[0].PartialResourceList. \
66 PartialDescriptors[(ResList)-> \
68 PartialResourceList. \
71 FIELD_OFFSET(CM_RESOURCE_LIST, List)
74 // Determines if the IRP is Synchronous
76 #define IsIrpSynchronous(Irp, FileObject) \
77 ((Irp->Flags & IRP_SYNCHRONOUS_API) || \
80 FileObject->Flags & FO_SYNCHRONOUS_IO)) \
83 // Returns the internal Device Object Extension
85 #define IoGetDevObjExtension(DeviceObject) \
86 ((PEXTENDED_DEVOBJ_EXTENSION) \
87 (DeviceObject->DeviceObjectExtension)) \
90 // Returns the internal Driver Object Extension
92 #define IoGetDrvObjExtension(DriverObject) \
93 ((PEXTENDED_DRIVER_EXTENSION) \
94 (DriverObject->DriverExtension)) \
98 * IopDeviceNodeSetFlag(
99 * PDEVICE_NODE DeviceNode,
102 #define IopDeviceNodeSetFlag(DeviceNode, Flag) \
103 ((DeviceNode)->Flags |= (Flag))
107 * IopDeviceNodeClearFlag(
108 * PDEVICE_NODE DeviceNode,
111 #define IopDeviceNodeClearFlag(DeviceNode, Flag) \
112 ((DeviceNode)->Flags &= ~(Flag))
116 * IopDeviceNodeHasFlag(
117 * PDEVICE_NODE DeviceNode,
120 #define IopDeviceNodeHasFlag(DeviceNode, Flag) \
121 (((DeviceNode)->Flags & (Flag)) > 0)
125 * IopDeviceNodeSetUserFlag(
126 * PDEVICE_NODE DeviceNode,
129 #define IopDeviceNodeSetUserFlag(DeviceNode, UserFlag) \
130 ((DeviceNode)->UserFlags |= (UserFlag))
134 * IopDeviceNodeClearUserFlag(
135 * PDEVICE_NODE DeviceNode,
138 #define IopDeviceNodeClearUserFlag(DeviceNode, UserFlag)\
139 ((DeviceNode)->UserFlags &= ~(UserFlag))
143 * IopDeviceNodeHasUserFlag(
144 * PDEVICE_NODE DeviceNode,
147 #define IopDeviceNodeHasUserFlag(DeviceNode, UserFlag) \
148 (((DeviceNode)->UserFlags & (UserFlag)) > 0)
152 * IopDeviceNodeSetProblem(
153 * PDEVICE_NODE DeviceNode,
156 #define IopDeviceNodeSetProblem(DeviceNode, Problem) \
157 ((DeviceNode)->Problem |= (Problem))
161 * IopDeviceNodeClearProblem(
162 * PDEVICE_NODE DeviceNode,
165 #define IopDeviceNodeClearProblem(DeviceNode, Problem) \
166 ((DeviceNode)->Problem &= ~(Problem))
170 * IopDeviceNodeHasProblem(
171 * PDEVICE_NODE DeviceNode,
174 #define IopDeviceNodeHasProblem(DeviceNode, Problem) \
175 (((DeviceNode)->Problem & (Problem)) > 0)
179 * IopInitDeviceTreeTraverseContext(
180 * PDEVICETREE_TRAVERSE_CONTEXT DeviceTreeTraverseContext,
181 * PDEVICE_NODE DeviceNode,
182 * DEVICETREE_TRAVERSE_ROUTINE Action,
185 #define IopInitDeviceTreeTraverseContext( \
186 _DeviceTreeTraverseContext, _DeviceNode, _Action, \
188 (_DeviceTreeTraverseContext)->FirstDeviceNode = \
190 (_DeviceTreeTraverseContext)->Action = (_Action); \
191 (_DeviceTreeTraverseContext)->Context = (_Context); }
194 // Device List Operations
196 typedef enum _IOP_DEVICE_LIST_OPERATION
200 } IOP_DEVICE_LIST_OPERATION
, *PIOP_DEVICE_LIST_OPERATION
;
203 // Transfer statistics
205 typedef enum _IOP_TRANSFER_TYPE
210 } IOP_TRANSFER_TYPE
, *PIOP_TRANSFER_TYPE
;
213 // Special version of the IRP Overlay used to optimize I/O completion
214 // by not using up a separate structure.
216 typedef struct _IO_COMPLETION_PACKET
220 LIST_ENTRY ListEntry
;
223 struct _IO_STACK_LOCATION
*CurrentStackLocation
;
229 IO_STATUS_BLOCK IoStatus
;
230 } IO_COMPLETION_PACKET
, *PIO_COMPLETION_PACKET
;
233 // I/O Wrapper around the Executive Work Item
235 typedef struct _IO_WORKITEM
237 WORK_QUEUE_ITEM Item
;
238 PDEVICE_OBJECT DeviceObject
;
239 PIO_WORKITEM_ROUTINE WorkerRoutine
;
241 } IO_WORKITEM
, *PIO_WORKITEM
;
244 // I/O Wrapper around the Kernel Interrupt
246 typedef struct _IO_INTERRUPT
248 KINTERRUPT FirstInterrupt
;
249 PKINTERRUPT Interrupt
[MAXIMUM_PROCESSORS
];
251 } IO_INTERRUPT
, *PIO_INTERRUPT
;
254 // I/O Error Log Packet Header
256 typedef struct _ERROR_LOG_ENTRY
260 LIST_ENTRY ListEntry
;
261 PDEVICE_OBJECT DeviceObject
;
262 PDRIVER_OBJECT DriverObject
;
263 LARGE_INTEGER TimeStamp
;
264 } ERROR_LOG_ENTRY
, *PERROR_LOG_ENTRY
;
267 // Event Log LPC Message
269 typedef struct _ELF_API_MSG
273 IO_ERROR_LOG_MESSAGE IoErrorMessage
;
274 } ELF_API_MSG
, *PELF_API_MSG
;
277 // To simplify matters, the kernel is made to support both the checked and free
278 // version of the I/O Remove Lock in the same binary. This structure includes
279 // both, since the DDK has the structure with a compile-time #ifdef.
281 typedef struct _EXTENDED_IO_REMOVE_LOCK
283 IO_REMOVE_LOCK_COMMON_BLOCK Common
;
284 IO_REMOVE_LOCK_DBG_BLOCK Dbg
;
285 } EXTENDED_IO_REMOVE_LOCK
, *PEXTENDED_IO_REMOVE_LOCK
;
288 // Dummy File Object used inside the Open Packet so that OB knows how to
289 // deal with the Object Pointer even though it's not a real file.
291 typedef struct _DUMMY_FILE_OBJECT
293 OBJECT_HEADER ObjectHeader
;
294 CHAR FileObjectBody
[sizeof(FILE_OBJECT
)];
295 } DUMMY_FILE_OBJECT
, *PDUMMY_FILE_OBJECT
;
298 // Open packet used as a context for Device/File parsing so that the parse
299 // routine can know what operation is being requested.
301 typedef struct _OPEN_PACKET
305 PFILE_OBJECT FileObject
;
306 NTSTATUS FinalStatus
;
307 ULONG_PTR Information
;
309 PFILE_OBJECT RelatedFileObject
;
310 OBJECT_ATTRIBUTES OriginalAttributes
;
311 LARGE_INTEGER AllocationSize
;
313 USHORT FileAttributes
;
319 PFILE_BASIC_INFORMATION BasicInformation
;
320 PFILE_NETWORK_OPEN_INFORMATION NetworkInformation
;
321 CREATE_FILE_TYPE CreateFileType
;
322 PVOID MailslotOrPipeParameters
;
326 BOOLEAN FullAttributes
;
327 PDUMMY_FILE_OBJECT DummyFileObject
;
329 //PIO_DRIVER_CREATE_CONTEXT DriverCreateContext; Vista only, needs ROS DDK Update
330 } OPEN_PACKET
, *POPEN_PACKET
;
333 // List of Bus Type GUIDs
335 typedef struct _IO_BUS_TYPE_GUID_LIST
340 } IO_BUS_TYPE_GUID_LIST
, *PIO_BUS_TYPE_GUID_LIST
;
341 extern PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList
;
344 // Shutdown entry for registed devices
346 typedef struct _SHUTDOWN_ENTRY
348 LIST_ENTRY ShutdownList
;
349 PDEVICE_OBJECT DeviceObject
;
350 } SHUTDOWN_ENTRY
, *PSHUTDOWN_ENTRY
;
353 // F/S Notification entry for registered File Systems
355 typedef struct _FS_CHANGE_NOTIFY_ENTRY
357 LIST_ENTRY FsChangeNotifyList
;
358 PDRIVER_OBJECT DriverObject
;
359 PDRIVER_FS_NOTIFICATION FSDNotificationProc
;
360 } FS_CHANGE_NOTIFY_ENTRY
, *PFS_CHANGE_NOTIFY_ENTRY
;
363 // Driver (Boot) Re-Initialization Entry
365 typedef struct _DRIVER_REINIT_ITEM
367 LIST_ENTRY ItemEntry
;
368 PDRIVER_OBJECT DriverObject
;
369 PDRIVER_REINITIALIZE ReinitRoutine
;
371 } DRIVER_REINIT_ITEM
, *PDRIVER_REINIT_ITEM
;
374 // Called on every visit of a node during a preorder-traversal of the device
376 // If the routine returns STATUS_UNSUCCESSFUL the traversal will stop and
377 // STATUS_SUCCESS is returned to the caller who initiated the tree traversal.
378 // Any other returned status code will be returned to the caller. If a status
379 // code that indicates an error (other than STATUS_UNSUCCESSFUL) is returned,
380 // the traversal is stopped immediately and the status code is returned to
385 (*DEVICETREE_TRAVERSE_ROUTINE
)(
386 IN PDEVICE_NODE DeviceNode
,
391 // Context information for traversing the device tree
393 typedef struct _DEVICETREE_TRAVERSE_CONTEXT
396 // Current device node during a traversal
398 PDEVICE_NODE DeviceNode
;
401 // Initial device node where we start the traversal
403 PDEVICE_NODE FirstDeviceNode
;
406 // Action routine to be called for every device node
408 DEVICETREE_TRAVERSE_ROUTINE Action
;
411 // Context passed to the action routine
414 } DEVICETREE_TRAVERSE_CONTEXT
, *PDEVICETREE_TRAVERSE_CONTEXT
;
417 // Internal Representation of a Disk
419 typedef struct _DISKENTRY
421 LIST_ENTRY ListEntry
;
425 PDEVICE_OBJECT DeviceObject
;
426 } DISKENTRY
, *PDISKENTRY
;
429 // Partition Table Entry
431 #include <pshpack1.h>
432 typedef struct _PARTITION
436 UCHAR StartingSector
;
437 UCHAR StartingCylinder
;
441 UCHAR EndingCylinder
;
444 } PARTITION
, *PPARTITION
;
447 // Boot Record Structure
449 typedef struct _PARTITION_SECTOR
454 PARTITION Partition
[PARTITION_TBL_SIZE
];
456 } PARTITION_SECTOR
, *PPARTITION_SECTOR
;
473 IopInitDriverImplementation(
478 IopInitPnpNotificationImplementation(
483 IopNotifyPlugPlayNotification(
484 IN PDEVICE_OBJECT DeviceObject
,
485 IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory
,
487 IN PVOID EventCategoryData1
,
488 IN PVOID EventCategoryData2
492 IopGetSystemPowerDeviceObject(
493 IN PDEVICE_OBJECT
*DeviceObject
498 IN PDEVICE_NODE ParentNode
,
499 IN PDEVICE_OBJECT PhysicalDeviceObject
,
500 OUT PDEVICE_NODE
*DeviceNode
505 IN PDEVICE_NODE DeviceNode
510 IN PDEVICE_OBJECT DeviceObject
,
511 IN PIO_STATUS_BLOCK IoStatusBlock
,
512 IN ULONG MinorFunction
,
513 IN PIO_STACK_LOCATION Stack
519 IN PDEVICE_OBJECT DeviceObject
523 IopActionConfigureChildServices(
524 IN PDEVICE_NODE DeviceNode
,
529 IopActionInitChildServices(
530 IN PDEVICE_NODE DeviceNode
,
532 IN BOOLEAN BootDrivers
547 IopInitPlugPlayEvents(VOID
);
550 IopQueueTargetDeviceEvent(
552 PUNICODE_STRING DeviceIds
556 IopInitializePnpServices(
557 IN PDEVICE_NODE DeviceNode
,
558 IN BOOLEAN BootDrivers
)
562 IopInvalidateDeviceRelations(
563 IN PDEVICE_NODE DeviceNode
,
564 IN DEVICE_RELATION_TYPE Type
568 // Initialization Routines
576 IoCreateSystemRootLink(
577 IN PCHAR ParameterLine
581 // Device/Volume Routines
586 IN PDEVICE_NODE DeviceNode
,
587 IN PDRIVER_OBJECT DriverObject
592 IN PDEVICE_NODE DeviceNode
598 IN POPEN_PACKET OpenPacket
,
599 IN PDEVICE_OBJECT DeviceObject
,
600 IN PUNICODE_STRING RemainingName
,
607 IN PDEVICE_OBJECT DeviceObject
,
608 IN BOOLEAN AllowRawMount
,
609 IN BOOLEAN DeviceIsLocked
,
610 IN BOOLEAN Alertable
,
616 IN PVOID SymbolicLink
621 IN PVOID SymbolicLink
,
628 IN PDEVICE_OBJECT DeviceObject
639 IoInitFileSystemImplementation(
645 IoInitVpbImplementation(
651 IopReferenceDeviceObject(
652 IN PDEVICE_OBJECT DeviceObject
657 IopDereferenceDeviceObject(
658 IN PDEVICE_OBJECT DeviceObject
,
659 IN BOOLEAN ForceUnload
668 IN PFILE_OBJECT FileObject
,
669 IN PKEVENT EventObject
,
670 IN PVOID Buffer OPTIONAL
675 IopAbortInterruptedIrp(
676 IN PKEVENT EventObject
,
684 IoInitShutdownNotification(
690 IoShutdownRegisteredDevices(
696 IoShutdownRegisteredFileSystems(
701 // Boot logging support
705 IN BOOLEAN StartBootLog
720 IN PUNICODE_STRING DriverName
,
725 IopSaveBootLogToFile(
730 // I/O Cancellation Routines
739 IoInitCancelHandling(
750 IN PKNORMAL_ROUTINE
* NormalRoutine
,
751 IN PVOID
* NormalContext
,
752 IN PVOID
* SystemArgument1
,
753 IN PVOID
* SystemArgument2
757 // Error Logging Routines
772 // Raw File System MiniDriver
775 RawFsIsRawFileSystemDeviceObject(
776 IN PDEVICE_OBJECT DeviceObject
782 IN PDRIVER_OBJECT DriverObject
,
783 IN PUNICODE_STRING RegistryPath
787 // PnP Root MiniDriver
792 IN PDRIVER_OBJECT DriverObject
,
793 IN PUNICODE_STRING RegistryPath
798 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject
806 IopInitializeBootDrivers(
812 IopInitializeSystemDrivers(
824 IopCreateDriverObject(
825 OUT PDRIVER_OBJECT
*DriverObject
,
826 IN PUNICODE_STRING ServiceName
,
827 IN ULONG CreateAttributes
,
828 IN BOOLEAN FileSystemDriver
,
829 IN PVOID DriverImageStart
,
830 IN ULONG DriverImageSize
836 OUT PDRIVER_OBJECT
*DriverObject
,
837 IN PUNICODE_STRING ServiceName
,
838 IN BOOLEAN FileSystem
843 IopLoadServiceModule(
844 IN PUNICODE_STRING ServiceName
,
845 OUT PLDR_DATA_TABLE_ENTRY
*ModuleObject
850 IopInitializeDriverModule(
851 IN PDEVICE_NODE DeviceNode
,
852 IN PLDR_DATA_TABLE_ENTRY ModuleObject
,
853 IN PUNICODE_STRING ServiceName
,
854 IN BOOLEAN FileSystemDriver
,
855 OUT PDRIVER_OBJECT
*DriverObject
860 IopAttachFilterDrivers(
861 IN PDEVICE_NODE DeviceNode
,
867 IopReinitializeDrivers(
873 IopReinitializeBootDrivers(
883 IN PVOID ParseObject
,
885 IN OUT PACCESS_STATE AccessState
,
886 IN KPROCESSOR_MODE AccessMode
,
888 IN OUT PUNICODE_STRING CompleteName
,
889 IN OUT PUNICODE_STRING RemainingName
,
890 IN OUT PVOID Context OPTIONAL
,
891 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL
,
898 IN PVOID ParseObject
,
900 IN OUT PACCESS_STATE AccessState
,
901 IN KPROCESSOR_MODE AccessMode
,
903 IN OUT PUNICODE_STRING CompleteName
,
904 IN OUT PUNICODE_STRING RemainingName
,
905 IN OUT PVOID Context OPTIONAL
,
906 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL
,
920 IN SECURITY_OPERATION_CODE OperationCode
,
921 IN SECURITY_INFORMATION SecurityInformation
,
922 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
923 IN OUT PULONG BufferLength
,
924 OUT PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
925 IN POOL_TYPE PoolType
,
926 IN OUT PGENERIC_MAPPING GenericMapping
934 OUT POBJECT_NAME_INFORMATION ObjectNameInfo
,
936 OUT PULONG ReturnLength
,
937 IN KPROCESSOR_MODE PreviousMode
943 IN PEPROCESS Process OPTIONAL
,
945 IN ACCESS_MASK GrantedAccess
,
946 IN ULONG ProcessHandleCount
,
947 IN ULONG SystemHandleCount
951 // I/O Timer Routines
955 IopInitTimerImplementation(
961 IopRemoveTimerFromTimerList(
966 // I/O Completion Routines
970 IopDeleteIoCompletion(
975 // I/O HAL Entrypoints
979 xHalQueryDriveLayout(
980 IN PUNICODE_STRING DeviceName
,
981 OUT PDRIVE_LAYOUT_INFORMATION
*LayoutInfo
988 IN PDEVICE_OBJECT DeviceObject
,
990 IN ULONG MBRTypeIdentifier
,
996 xHalIoAssignDriveLetters(
997 IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock
,
998 IN PSTRING NtDeviceName
,
999 OUT PUCHAR NtSystemPath
,
1000 OUT PSTRING NtSystemPathString
1005 xHalIoReadPartitionTable(
1006 IN PDEVICE_OBJECT DeviceObject
,
1007 IN ULONG SectorSize
,
1008 IN BOOLEAN ReturnRecognizedPartitions
,
1009 OUT PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
1014 xHalIoSetPartitionInformation(
1015 IN PDEVICE_OBJECT DeviceObject
,
1016 IN ULONG SectorSize
,
1017 IN ULONG PartitionNumber
,
1018 IN ULONG PartitionType
1023 xHalIoWritePartitionTable(
1024 IN PDEVICE_OBJECT DeviceObject
,
1025 IN ULONG SectorSize
,
1026 IN ULONG SectorsPerTrack
,
1027 IN ULONG NumberOfHeads
,
1028 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer
1034 extern POBJECT_TYPE IoCompletionType
;
1035 extern PDEVICE_NODE IopRootDeviceNode
;
1036 extern ULONG IopTraceLevel
;
1037 extern NPAGED_LOOKASIDE_LIST IopMdlLookasideList
;
1038 extern GENERIC_MAPPING IopCompletionMapping
;
1039 extern GENERIC_MAPPING IopFileMapping
;
1042 // Inlined Functions