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
548 IN PDEVICE_OBJECT DeviceObject
553 IopInitPlugPlayEvents(VOID
);
556 IopQueueTargetDeviceEvent(
558 PUNICODE_STRING DeviceIds
562 IopInitializePnpServices(
563 IN PDEVICE_NODE DeviceNode
,
564 IN BOOLEAN BootDrivers
)
568 IopInvalidateDeviceRelations(
569 IN PDEVICE_NODE DeviceNode
,
570 IN DEVICE_RELATION_TYPE Type
574 // Initialization Routines
582 IoCreateSystemRootLink(
583 IN PCHAR ParameterLine
587 // Device/Volume Routines
592 IN PDEVICE_NODE DeviceNode
,
593 IN PDRIVER_OBJECT DriverObject
598 IN PDEVICE_NODE DeviceNode
604 IN POPEN_PACKET OpenPacket
,
605 IN PDEVICE_OBJECT DeviceObject
,
606 IN PUNICODE_STRING RemainingName
,
613 IN PDEVICE_OBJECT DeviceObject
,
614 IN BOOLEAN AllowRawMount
,
615 IN BOOLEAN DeviceIsLocked
,
616 IN BOOLEAN Alertable
,
622 IN PVOID SymbolicLink
627 IN PVOID SymbolicLink
,
634 IN PDEVICE_OBJECT DeviceObject
645 IoInitFileSystemImplementation(
651 IoInitVpbImplementation(
657 IopReferenceDeviceObject(
658 IN PDEVICE_OBJECT DeviceObject
663 IopDereferenceDeviceObject(
664 IN PDEVICE_OBJECT DeviceObject
,
665 IN BOOLEAN ForceUnload
674 IN PFILE_OBJECT FileObject
,
675 IN PKEVENT EventObject
680 IopAbortInterruptedIrp(
681 IN PKEVENT EventObject
,
689 IoInitShutdownNotification(
695 IoShutdownRegisteredDevices(
701 IoShutdownRegisteredFileSystems(
706 // Boot logging support
710 IN BOOLEAN StartBootLog
725 IN PUNICODE_STRING DriverName
,
730 IopSaveBootLogToFile(
735 // I/O Cancellation Routines
744 IoInitCancelHandling(
755 IN PKNORMAL_ROUTINE
* NormalRoutine
,
756 IN PVOID
* NormalContext
,
757 IN PVOID
* SystemArgument1
,
758 IN PVOID
* SystemArgument2
762 // Error Logging Routines
777 // Raw File System MiniDriver
780 RawFsIsRawFileSystemDeviceObject(
781 IN PDEVICE_OBJECT DeviceObject
787 IN PDRIVER_OBJECT DriverObject
,
788 IN PUNICODE_STRING RegistryPath
792 // PnP Root MiniDriver
797 IN PDRIVER_OBJECT DriverObject
,
798 IN PUNICODE_STRING RegistryPath
803 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject
811 IopInitializeBootDrivers(
817 IopInitializeSystemDrivers(
829 IopCreateDriverObject(
830 OUT PDRIVER_OBJECT
*DriverObject
,
831 IN PUNICODE_STRING ServiceName
,
832 IN ULONG CreateAttributes
,
833 IN BOOLEAN FileSystemDriver
,
834 IN PVOID DriverImageStart
,
835 IN ULONG DriverImageSize
841 OUT PDRIVER_OBJECT
*DriverObject
,
842 IN PUNICODE_STRING ServiceName
,
843 IN BOOLEAN FileSystem
848 IopLoadServiceModule(
849 IN PUNICODE_STRING ServiceName
,
850 OUT PLDR_DATA_TABLE_ENTRY
*ModuleObject
855 IopInitializeDriverModule(
856 IN PDEVICE_NODE DeviceNode
,
857 IN PLDR_DATA_TABLE_ENTRY ModuleObject
,
858 IN PUNICODE_STRING ServiceName
,
859 IN BOOLEAN FileSystemDriver
,
860 OUT PDRIVER_OBJECT
*DriverObject
865 IopAttachFilterDrivers(
866 IN PDEVICE_NODE DeviceNode
,
872 IopReinitializeDrivers(
878 IopReinitializeBootDrivers(
888 IN PVOID ParseObject
,
890 IN OUT PACCESS_STATE AccessState
,
891 IN KPROCESSOR_MODE AccessMode
,
893 IN OUT PUNICODE_STRING CompleteName
,
894 IN OUT PUNICODE_STRING RemainingName
,
895 IN OUT PVOID Context OPTIONAL
,
896 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL
,
903 IN PVOID ParseObject
,
905 IN OUT PACCESS_STATE AccessState
,
906 IN KPROCESSOR_MODE AccessMode
,
908 IN OUT PUNICODE_STRING CompleteName
,
909 IN OUT PUNICODE_STRING RemainingName
,
910 IN OUT PVOID Context OPTIONAL
,
911 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL
,
925 IN SECURITY_OPERATION_CODE OperationCode
,
926 IN SECURITY_INFORMATION SecurityInformation
,
927 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
928 IN OUT PULONG BufferLength
,
929 OUT PSECURITY_DESCRIPTOR
*OldSecurityDescriptor
,
930 IN POOL_TYPE PoolType
,
931 IN OUT PGENERIC_MAPPING GenericMapping
939 OUT POBJECT_NAME_INFORMATION ObjectNameInfo
,
941 OUT PULONG ReturnLength
,
942 IN KPROCESSOR_MODE PreviousMode
948 IN PEPROCESS Process OPTIONAL
,
950 IN ACCESS_MASK GrantedAccess
,
951 IN ULONG ProcessHandleCount
,
952 IN ULONG SystemHandleCount
956 // I/O Timer Routines
960 IopInitTimerImplementation(
966 IopRemoveTimerFromTimerList(
971 // I/O Completion Routines
975 IopDeleteIoCompletion(
980 // I/O HAL Entrypoints
984 xHalQueryDriveLayout(
985 IN PUNICODE_STRING DeviceName
,
986 OUT PDRIVE_LAYOUT_INFORMATION
*LayoutInfo
993 IN PDEVICE_OBJECT DeviceObject
,
995 IN ULONG MBRTypeIdentifier
,
1001 xHalIoAssignDriveLetters(
1002 IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock
,
1003 IN PSTRING NtDeviceName
,
1004 OUT PUCHAR NtSystemPath
,
1005 OUT PSTRING NtSystemPathString
1010 xHalIoReadPartitionTable(
1011 IN PDEVICE_OBJECT DeviceObject
,
1012 IN ULONG SectorSize
,
1013 IN BOOLEAN ReturnRecognizedPartitions
,
1014 OUT PDRIVE_LAYOUT_INFORMATION
*PartitionBuffer
1019 xHalIoSetPartitionInformation(
1020 IN PDEVICE_OBJECT DeviceObject
,
1021 IN ULONG SectorSize
,
1022 IN ULONG PartitionNumber
,
1023 IN ULONG PartitionType
1028 xHalIoWritePartitionTable(
1029 IN PDEVICE_OBJECT DeviceObject
,
1030 IN ULONG SectorSize
,
1031 IN ULONG SectorsPerTrack
,
1032 IN ULONG NumberOfHeads
,
1033 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer
1039 extern POBJECT_TYPE IoCompletionType
;
1040 extern PDEVICE_NODE IopRootDeviceNode
;
1041 extern ULONG IopTraceLevel
;
1042 extern NPAGED_LOOKASIDE_LIST IopMdlLookasideList
;
1043 extern GENERIC_MAPPING IopCompletionMapping
;
1044 extern GENERIC_MAPPING IopFileMapping
;
1047 // Inlined Functions