2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/io/iomgr.c
5 * PURPOSE: I/O Manager Initialization and Misc Utility Functions
7 * PROGRAMMERS: David Welch (welch@mcmail.com)
10 /* INCLUDES ****************************************************************/
14 #include <internal/debug.h>
16 /* GLOBALS *******************************************************************/
18 #define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
19 #define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
20 #define TAG_ADAPTER_TYPE TAG('A', 'D', 'P', 'T')
22 /* DATA ********************************************************************/
24 POBJECT_TYPE EXPORTED IoDeviceObjectType
= NULL
;
25 POBJECT_TYPE EXPORTED IoFileObjectType
= NULL
;
26 ULONG EXPORTED IoReadOperationCount
= 0;
27 ULONGLONG EXPORTED IoReadTransferCount
= 0;
28 ULONG EXPORTED IoWriteOperationCount
= 0;
29 ULONGLONG EXPORTED IoWriteTransferCount
= 0;
30 ULONG IoOtherOperationCount
= 0;
31 ULONGLONG IoOtherTransferCount
= 0;
32 KSPIN_LOCK EXPORTED IoStatisticsLock
= 0;
34 GENERIC_MAPPING IopFileMapping
= {
40 static KSPIN_LOCK CancelSpinLock
;
41 extern LIST_ENTRY ShutdownListHead
;
42 extern KSPIN_LOCK ShutdownListLock
;
44 /* INIT FUNCTIONS ************************************************************/
48 IoInitCancelHandling(VOID
)
50 KeInitializeSpinLock(&CancelSpinLock
);
55 IoInitShutdownNotification (VOID
)
57 InitializeListHead(&ShutdownListHead
);
58 KeInitializeSpinLock(&ShutdownListLock
);
65 OBJECT_ATTRIBUTES ObjectAttributes
;
66 UNICODE_STRING DirName
;
67 UNICODE_STRING LinkName
;
70 IopInitDriverImplementation();
73 * Register iomgr types: DeviceObjectType
75 IoDeviceObjectType
= ExAllocatePool (NonPagedPool
,
76 sizeof (OBJECT_TYPE
));
78 IoDeviceObjectType
->Tag
= TAG_DEVICE_TYPE
;
79 IoDeviceObjectType
->TotalObjects
= 0;
80 IoDeviceObjectType
->TotalHandles
= 0;
81 IoDeviceObjectType
->PeakObjects
= 0;
82 IoDeviceObjectType
->PeakHandles
= 0;
83 IoDeviceObjectType
->PagedPoolCharge
= 0;
84 IoDeviceObjectType
->NonpagedPoolCharge
= sizeof (DEVICE_OBJECT
);
85 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
86 IoDeviceObjectType
->Dump
= NULL
;
87 IoDeviceObjectType
->Open
= NULL
;
88 IoDeviceObjectType
->Close
= NULL
;
89 IoDeviceObjectType
->Delete
= NULL
;
90 IoDeviceObjectType
->Parse
= NULL
;
91 IoDeviceObjectType
->Security
= NULL
;
92 IoDeviceObjectType
->QueryName
= NULL
;
93 IoDeviceObjectType
->OkayToClose
= NULL
;
94 IoDeviceObjectType
->Create
= NULL
;
95 IoDeviceObjectType
->DuplicationNotify
= NULL
;
97 RtlInitUnicodeString(&IoDeviceObjectType
->TypeName
, L
"Device");
99 ObpCreateTypeObject(IoDeviceObjectType
);
102 * Register iomgr types: FileObjectType
103 * (alias DriverObjectType)
105 IoFileObjectType
= ExAllocatePool (NonPagedPool
, sizeof (OBJECT_TYPE
));
107 IoFileObjectType
->Tag
= TAG_FILE_TYPE
;
108 IoFileObjectType
->TotalObjects
= 0;
109 IoFileObjectType
->TotalHandles
= 0;
110 IoFileObjectType
->PeakObjects
= 0;
111 IoFileObjectType
->PeakHandles
= 0;
112 IoFileObjectType
->PagedPoolCharge
= 0;
113 IoFileObjectType
->NonpagedPoolCharge
= sizeof(FILE_OBJECT
);
114 IoFileObjectType
->Mapping
= &IopFileMapping
;
115 IoFileObjectType
->Dump
= NULL
;
116 IoFileObjectType
->Open
= NULL
;
117 IoFileObjectType
->Close
= IopCloseFile
;
118 IoFileObjectType
->Delete
= IopDeleteFile
;
119 IoFileObjectType
->Parse
= NULL
;
120 IoFileObjectType
->Security
= IopSecurityFile
;
121 IoFileObjectType
->QueryName
= IopQueryNameFile
;
122 IoFileObjectType
->OkayToClose
= NULL
;
123 IoFileObjectType
->Create
= IopCreateFile
;
124 IoFileObjectType
->DuplicationNotify
= NULL
;
126 RtlInitUnicodeString(&IoFileObjectType
->TypeName
, L
"File");
128 ObpCreateTypeObject(IoFileObjectType
);
131 * Register iomgr types: AdapterObjectType
133 IoAdapterObjectType
= ExAllocatePool (NonPagedPool
,
134 sizeof (OBJECT_TYPE
));
135 RtlZeroMemory(IoAdapterObjectType
, sizeof(OBJECT_TYPE
));
136 IoAdapterObjectType
->Tag
= TAG_ADAPTER_TYPE
;
137 IoAdapterObjectType
->PeakObjects
= 0;
138 IoAdapterObjectType
->PeakHandles
= 0;
139 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
140 RtlInitUnicodeString(&IoAdapterObjectType
->TypeName
, L
"Adapter");
141 ObpCreateTypeObject(IoAdapterObjectType
);
144 * Create the '\Driver' object directory
146 RtlRosInitUnicodeStringFromLiteral(&DirName
, L
"\\Driver");
147 InitializeObjectAttributes(&ObjectAttributes
,
152 ZwCreateDirectoryObject(&Handle
,
157 * Create the '\FileSystem' object directory
159 RtlRosInitUnicodeStringFromLiteral(&DirName
,
161 InitializeObjectAttributes(&ObjectAttributes
,
166 ZwCreateDirectoryObject(&Handle
,
171 * Create the '\Device' directory
173 RtlRosInitUnicodeStringFromLiteral(&DirName
,
175 InitializeObjectAttributes(&ObjectAttributes
,
180 ZwCreateDirectoryObject(&Handle
,
185 * Create the '\??' directory
187 RtlRosInitUnicodeStringFromLiteral(&DirName
,
189 InitializeObjectAttributes(&ObjectAttributes
,
194 ZwCreateDirectoryObject(&Handle
,
199 * Create the '\ArcName' directory
201 RtlRosInitUnicodeStringFromLiteral(&DirName
,
203 InitializeObjectAttributes(&ObjectAttributes
,
208 ZwCreateDirectoryObject(&Handle
,
213 * Initialize remaining subsubsystem
215 IoInitCancelHandling();
216 IoInitFileSystemImplementation();
217 IoInitVpbImplementation();
218 IoInitShutdownNotification();
219 IopInitPnpNotificationImplementation();
221 IopInitTimerImplementation();
222 IopInitIoCompletionImplementation();
225 * Create link from '\DosDevices' to '\??' directory
227 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
229 RtlRosInitUnicodeStringFromLiteral(&DirName
,
231 IoCreateSymbolicLink(&LinkName
,
235 * Initialize PnP manager
242 IoInit2(BOOLEAN BootLog
)
244 PDEVICE_NODE DeviceNode
;
245 PDRIVER_OBJECT DriverObject
;
246 MODULE_OBJECT ModuleObject
;
249 IoCreateDriverList();
251 KeInitializeSpinLock (&IoStatisticsLock
);
253 /* Initialize raw filesystem driver */
255 /* Use IopRootDeviceNode for now */
256 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
259 if (!NT_SUCCESS(Status
))
261 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
265 ModuleObject
.Base
= NULL
;
266 ModuleObject
.Length
= 0;
267 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
269 Status
= IopInitializeDriverModule(
272 &DeviceNode
->ServiceName
,
275 if (!NT_SUCCESS(Status
))
277 IopFreeDeviceNode(DeviceNode
);
278 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
282 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
283 if (!NT_SUCCESS(Status
))
285 IopFreeDeviceNode(DeviceNode
);
286 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
291 * Initialize PnP root releations
293 IopInvalidateDeviceRelations(
297 /* Start boot logging */
298 IopInitBootLog(BootLog
);
300 /* Load boot start drivers */
301 IopInitializeBootDrivers();
311 /* Create ARC names for boot devices */
314 /* Create the SystemRoot symbolic link */
315 CPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
316 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
317 if (!NT_SUCCESS(Status
)) {
318 DbgPrint("IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
319 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
325 /* I/O is now setup for disk access, so phase 3 */
326 KdInitSystem(3, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
328 /* Load services for devices found by PnP manager */
329 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
331 /* Load system start drivers */
332 IopInitializeSystemDrivers();
333 IoDestroyDriverList();
335 /* Stop boot logging */
338 /* Assign drive letters */
339 IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
345 /* FUNCTIONS *****************************************************************/
352 IoAcquireCancelSpinLock(PKIRQL Irql
)
354 KeAcquireSpinLock(&CancelSpinLock
,Irql
);
362 IoGetInitialStack(VOID
)
364 return(PsGetCurrentThread()->Tcb
.InitialStack
);
372 IoGetStackLimits(OUT PULONG LowLimit
,
373 OUT PULONG HighLimit
)
375 *LowLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackLimit
;
376 *HighLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackBase
;
384 IoIsSystemThread(IN PETHREAD Thread
)
386 /* Call the Ps Function */
387 return PsIsSystemThread(Thread
);
394 IoIsWdmVersionAvailable(IN UCHAR MajorVersion
,
395 IN UCHAR MinorVersion
)
397 if (MajorVersion
<= 1 && MinorVersion
<= 10)
407 IoReleaseCancelSpinLock(KIRQL Irql
)
409 KeReleaseSpinLock(&CancelSpinLock
,Irql
);
417 IoThreadToProcess(IN PETHREAD Thread
)
419 return(Thread
->ThreadsProcess
);