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')
21 #define IO_LARGEIRP TAG('I', 'r', 'p', 'l')
22 #define IO_SMALLIRP TAG('I', 'r', 'p', 's')
23 #define IO_LARGEIRP_CPU TAG('I', 'r', 'p', 'L')
24 #define IO_SMALLIRP_CPU TAG('I', 'r', 'p', 'S')
25 #define IOC_TAG TAG('I', 'p', 'c', ' ')
26 #define IOC_CPU TAG('I', 'p', 'c', 'P')
28 /* DATA ********************************************************************/
30 POBJECT_TYPE EXPORTED IoDeviceObjectType
= NULL
;
31 POBJECT_TYPE EXPORTED IoFileObjectType
= NULL
;
32 ULONG EXPORTED IoReadOperationCount
= 0;
33 ULONGLONG EXPORTED IoReadTransferCount
= 0;
34 ULONG EXPORTED IoWriteOperationCount
= 0;
35 ULONGLONG EXPORTED IoWriteTransferCount
= 0;
36 ULONG IoOtherOperationCount
= 0;
37 ULONGLONG IoOtherTransferCount
= 0;
38 KSPIN_LOCK EXPORTED IoStatisticsLock
= 0;
40 GENERIC_MAPPING IopFileMapping
= {
46 static KSPIN_LOCK CancelSpinLock
;
47 extern LIST_ENTRY ShutdownListHead
;
48 extern KSPIN_LOCK ShutdownListLock
;
49 extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside
;
50 NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside
;
51 NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside
;
53 /* INIT FUNCTIONS ************************************************************/
57 IoInitCancelHandling(VOID
)
59 KeInitializeSpinLock(&CancelSpinLock
);
64 IoInitShutdownNotification (VOID
)
66 InitializeListHead(&ShutdownListHead
);
67 KeInitializeSpinLock(&ShutdownListLock
);
72 IopInitLookasideLists(VOID
)
74 ULONG LargeIrpSize
, SmallIrpSize
;
77 PNPAGED_LOOKASIDE_LIST CurrentList
= NULL
;
79 /* Calculate the sizes */
80 LargeIrpSize
= sizeof(IRP
) + (8 * sizeof(IO_STACK_LOCATION
));
81 SmallIrpSize
= sizeof(IRP
) + sizeof(IO_STACK_LOCATION
);
83 /* Initialize the Lookaside List for Large IRPs */
84 ExInitializeNPagedLookasideList(&IoLargeIrpLookaside
,
92 /* Initialize the Lookaside List for Small IRPs */
93 ExInitializeNPagedLookasideList(&IoSmallIrpLookaside
,
101 /* Initialize the Lookaside List for I\O Completion */
102 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside
,
106 sizeof(IO_COMPLETION_PACKET
),
110 /* Now allocate the per-processor lists */
111 for (i
= 0; i
< KeNumberProcessors
; i
++)
113 /* Get the PRCB for this CPU */
114 Prcb
= ((PKPCR
)(KPCR_BASE
+ i
* PAGE_SIZE
))->Prcb
;
115 DPRINT1("Setting up lookaside for CPU: %x, PRCB: %p\n", i
, Prcb
);
117 /* Set the Large IRP List */
118 Prcb
->PPLookasideList
[LookasideLargeIrpList
].L
= &IoLargeIrpLookaside
.L
;
119 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
120 sizeof(NPAGED_LOOKASIDE_LIST
),
124 /* Initialize the Lookaside List for Large IRPs */
125 ExInitializeNPagedLookasideList(CurrentList
,
135 CurrentList
= &IoLargeIrpLookaside
;
137 Prcb
->PPLookasideList
[LookasideLargeIrpList
].P
= &CurrentList
->L
;
139 /* Set the Small IRP List */
140 Prcb
->PPLookasideList
[LookasideSmallIrpList
].L
= &IoSmallIrpLookaside
.L
;
141 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
142 sizeof(NPAGED_LOOKASIDE_LIST
),
146 /* Initialize the Lookaside List for Large IRPs */
147 ExInitializeNPagedLookasideList(CurrentList
,
157 CurrentList
= &IoSmallIrpLookaside
;
159 Prcb
->PPLookasideList
[LookasideSmallIrpList
].P
= &CurrentList
->L
;
161 /* Set the I/O Completion List */
162 Prcb
->PPLookasideList
[LookasideCompletionList
].L
= &IoCompletionPacketLookaside
.L
;
163 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
164 sizeof(NPAGED_LOOKASIDE_LIST
),
168 /* Initialize the Lookaside List for Large IRPs */
169 ExInitializeNPagedLookasideList(CurrentList
,
179 CurrentList
= &IoCompletionPacketLookaside
;
181 Prcb
->PPLookasideList
[LookasideCompletionList
].P
= &CurrentList
->L
;
184 DPRINT1("Done allocation\n");
191 OBJECT_ATTRIBUTES ObjectAttributes
;
192 UNICODE_STRING DirName
;
193 UNICODE_STRING LinkName
;
196 IopInitDriverImplementation();
199 * Register iomgr types: DeviceObjectType
201 IoDeviceObjectType
= ExAllocatePool (NonPagedPool
,
202 sizeof (OBJECT_TYPE
));
204 IoDeviceObjectType
->Tag
= TAG_DEVICE_TYPE
;
205 IoDeviceObjectType
->TotalObjects
= 0;
206 IoDeviceObjectType
->TotalHandles
= 0;
207 IoDeviceObjectType
->PeakObjects
= 0;
208 IoDeviceObjectType
->PeakHandles
= 0;
209 IoDeviceObjectType
->PagedPoolCharge
= 0;
210 IoDeviceObjectType
->NonpagedPoolCharge
= sizeof (DEVICE_OBJECT
);
211 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
212 IoDeviceObjectType
->Dump
= NULL
;
213 IoDeviceObjectType
->Open
= NULL
;
214 IoDeviceObjectType
->Close
= NULL
;
215 IoDeviceObjectType
->Delete
= NULL
;
216 IoDeviceObjectType
->Parse
= NULL
;
217 IoDeviceObjectType
->Security
= NULL
;
218 IoDeviceObjectType
->QueryName
= NULL
;
219 IoDeviceObjectType
->OkayToClose
= NULL
;
221 RtlInitUnicodeString(&IoDeviceObjectType
->TypeName
, L
"Device");
223 ObpCreateTypeObject(IoDeviceObjectType
);
226 * Register iomgr types: FileObjectType
227 * (alias DriverObjectType)
229 IoFileObjectType
= ExAllocatePool (NonPagedPool
, sizeof (OBJECT_TYPE
));
231 IoFileObjectType
->Tag
= TAG_FILE_TYPE
;
232 IoFileObjectType
->TotalObjects
= 0;
233 IoFileObjectType
->TotalHandles
= 0;
234 IoFileObjectType
->PeakObjects
= 0;
235 IoFileObjectType
->PeakHandles
= 0;
236 IoFileObjectType
->PagedPoolCharge
= 0;
237 IoFileObjectType
->NonpagedPoolCharge
= sizeof(FILE_OBJECT
);
238 IoFileObjectType
->Mapping
= &IopFileMapping
;
239 IoFileObjectType
->Dump
= NULL
;
240 IoFileObjectType
->Open
= NULL
;
241 IoFileObjectType
->Close
= IopCloseFile
;
242 IoFileObjectType
->Delete
= IopDeleteFile
;
243 IoFileObjectType
->Parse
= NULL
;
244 IoFileObjectType
->Security
= IopSecurityFile
;
245 IoFileObjectType
->QueryName
= IopQueryNameFile
;
246 IoFileObjectType
->OkayToClose
= NULL
;
248 RtlInitUnicodeString(&IoFileObjectType
->TypeName
, L
"File");
250 ObpCreateTypeObject(IoFileObjectType
);
253 * Register iomgr types: AdapterObjectType
255 IoAdapterObjectType
= ExAllocatePool (NonPagedPool
,
256 sizeof (OBJECT_TYPE
));
257 RtlZeroMemory(IoAdapterObjectType
, sizeof(OBJECT_TYPE
));
258 IoAdapterObjectType
->Tag
= TAG_ADAPTER_TYPE
;
259 IoAdapterObjectType
->PeakObjects
= 0;
260 IoAdapterObjectType
->PeakHandles
= 0;
261 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
262 RtlInitUnicodeString(&IoAdapterObjectType
->TypeName
, L
"Adapter");
263 ObpCreateTypeObject(IoAdapterObjectType
);
266 * Create the '\Driver' object directory
268 RtlRosInitUnicodeStringFromLiteral(&DirName
, L
"\\Driver");
269 InitializeObjectAttributes(&ObjectAttributes
,
274 ZwCreateDirectoryObject(&Handle
,
279 * Create the '\FileSystem' object directory
281 RtlRosInitUnicodeStringFromLiteral(&DirName
,
283 InitializeObjectAttributes(&ObjectAttributes
,
288 ZwCreateDirectoryObject(&Handle
,
293 * Create the '\Device' directory
295 RtlRosInitUnicodeStringFromLiteral(&DirName
,
297 InitializeObjectAttributes(&ObjectAttributes
,
302 ZwCreateDirectoryObject(&Handle
,
307 * Create the '\??' directory
309 RtlRosInitUnicodeStringFromLiteral(&DirName
,
311 InitializeObjectAttributes(&ObjectAttributes
,
316 ZwCreateDirectoryObject(&Handle
,
321 * Create the '\ArcName' directory
323 RtlRosInitUnicodeStringFromLiteral(&DirName
,
325 InitializeObjectAttributes(&ObjectAttributes
,
330 ZwCreateDirectoryObject(&Handle
,
335 * Initialize remaining subsubsystem
337 IoInitCancelHandling();
338 IoInitFileSystemImplementation();
339 IoInitVpbImplementation();
340 IoInitShutdownNotification();
341 IopInitPnpNotificationImplementation();
343 IopInitTimerImplementation();
344 IopInitIoCompletionImplementation();
345 IopInitLookasideLists();
348 * Create link from '\DosDevices' to '\??' directory
350 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
352 RtlRosInitUnicodeStringFromLiteral(&DirName
,
354 IoCreateSymbolicLink(&LinkName
,
358 * Initialize PnP manager
365 IoInit2(BOOLEAN BootLog
)
367 PDEVICE_NODE DeviceNode
;
368 PDRIVER_OBJECT DriverObject
;
369 MODULE_OBJECT ModuleObject
;
372 IoCreateDriverList();
374 KeInitializeSpinLock (&IoStatisticsLock
);
376 /* Initialize raw filesystem driver */
378 /* Use IopRootDeviceNode for now */
379 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
382 if (!NT_SUCCESS(Status
))
384 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
388 ModuleObject
.Base
= NULL
;
389 ModuleObject
.Length
= 0;
390 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
392 Status
= IopInitializeDriverModule(
395 &DeviceNode
->ServiceName
,
398 if (!NT_SUCCESS(Status
))
400 IopFreeDeviceNode(DeviceNode
);
401 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
405 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
406 if (!NT_SUCCESS(Status
))
408 IopFreeDeviceNode(DeviceNode
);
409 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
414 * Initialize PnP root releations
416 IopInvalidateDeviceRelations(
420 /* Start boot logging */
421 IopInitBootLog(BootLog
);
423 /* Load boot start drivers */
424 IopInitializeBootDrivers();
434 /* Create ARC names for boot devices */
437 /* Create the SystemRoot symbolic link */
438 CPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
439 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
440 if (!NT_SUCCESS(Status
)) {
441 DbgPrint("IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
442 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
448 /* I/O is now setup for disk access, so phase 3 */
449 KdInitSystem(3, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
451 /* Load services for devices found by PnP manager */
452 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
454 /* Load system start drivers */
455 IopInitializeSystemDrivers();
456 IoDestroyDriverList();
458 /* Stop boot logging */
461 /* Assign drive letters */
462 IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
468 /* FUNCTIONS *****************************************************************/
475 IoAcquireCancelSpinLock(PKIRQL Irql
)
477 KeAcquireSpinLock(&CancelSpinLock
,Irql
);
485 IoGetInitialStack(VOID
)
487 return(PsGetCurrentThread()->Tcb
.InitialStack
);
495 IoGetStackLimits(OUT PULONG LowLimit
,
496 OUT PULONG HighLimit
)
498 *LowLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackLimit
;
499 *HighLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackBase
;
507 IoIsSystemThread(IN PETHREAD Thread
)
509 /* Call the Ps Function */
510 return PsIsSystemThread(Thread
);
517 IoIsWdmVersionAvailable(IN UCHAR MajorVersion
,
518 IN UCHAR MinorVersion
)
520 if (MajorVersion
<= 1 && MinorVersion
<= 10)
530 IoReleaseCancelSpinLock(KIRQL Irql
)
532 KeReleaseSpinLock(&CancelSpinLock
,Irql
);
540 IoThreadToProcess(IN PETHREAD Thread
)
542 return(Thread
->ThreadsProcess
);