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 ULONG IopTraceLevel
= IO_IRP_DEBUG
;
18 /* DATA ********************************************************************/
20 POBJECT_TYPE IoDeviceObjectType
= NULL
;
21 POBJECT_TYPE IoFileObjectType
= NULL
;
22 extern POBJECT_TYPE IoControllerObjectType
;
23 BOOLEAN IoCountOperations
;
24 ULONG IoReadOperationCount
= 0;
25 LARGE_INTEGER IoReadTransferCount
= {{0, 0}};
26 ULONG IoWriteOperationCount
= 0;
27 LARGE_INTEGER IoWriteTransferCount
= {{0, 0}};
28 ULONG IoOtherOperationCount
= 0;
29 LARGE_INTEGER IoOtherTransferCount
= {{0, 0}};
30 KSPIN_LOCK IoStatisticsLock
= 0;
32 GENERIC_MAPPING IopFileMapping
= {
38 extern LIST_ENTRY ShutdownListHead
;
39 extern KSPIN_LOCK ShutdownListLock
;
40 extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside
;
41 extern POBJECT_TYPE IoAdapterObjectType
;
42 NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside
;
43 NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside
;
44 NPAGED_LOOKASIDE_LIST IopMdlLookasideList
;
46 VOID INIT_FUNCTION
IopInitLookasideLists(VOID
);
48 #if defined (ALLOC_PRAGMA)
49 #pragma alloc_text(INIT, IoInitCancelHandling)
50 #pragma alloc_text(INIT, IoInitShutdownNotification)
51 #pragma alloc_text(INIT, IopInitLookasideLists)
52 #pragma alloc_text(INIT, IoInit)
53 #pragma alloc_text(INIT, IoInit2)
54 #pragma alloc_text(INIT, IoInit3)
57 /* INIT FUNCTIONS ************************************************************/
61 IoInitCancelHandling(VOID
)
63 extern KSPIN_LOCK CancelSpinLock
;
64 KeInitializeSpinLock(&CancelSpinLock
);
69 IoInitShutdownNotification (VOID
)
71 InitializeListHead(&ShutdownListHead
);
72 KeInitializeSpinLock(&ShutdownListLock
);
77 IopInitLookasideLists(VOID
)
79 ULONG LargeIrpSize
, SmallIrpSize
, MdlSize
;
82 PNPAGED_LOOKASIDE_LIST CurrentList
= NULL
;
84 /* Calculate the sizes */
85 LargeIrpSize
= sizeof(IRP
) + (8 * sizeof(IO_STACK_LOCATION
));
86 SmallIrpSize
= sizeof(IRP
) + sizeof(IO_STACK_LOCATION
);
87 MdlSize
= sizeof(MDL
) + (23 * sizeof(PFN_NUMBER
));
89 /* Initialize the Lookaside List for Large IRPs */
90 ExInitializeNPagedLookasideList(&IoLargeIrpLookaside
,
98 /* Initialize the Lookaside List for Small IRPs */
99 ExInitializeNPagedLookasideList(&IoSmallIrpLookaside
,
107 /* Initialize the Lookaside List for I\O Completion */
108 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside
,
112 sizeof(IO_COMPLETION_PACKET
),
116 /* Initialize the Lookaside List for MDLs */
117 ExInitializeNPagedLookasideList(&IopMdlLookasideList
,
125 /* Now allocate the per-processor lists */
126 for (i
= 0; i
< KeNumberProcessors
; i
++)
128 /* Get the PRCB for this CPU */
129 Prcb
= ((PKPCR
)(KPCR_BASE
+ i
* PAGE_SIZE
))->Prcb
;
130 DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i
, Prcb
);
132 /* Set the Large IRP List */
133 Prcb
->PPLookasideList
[LookasideLargeIrpList
].L
= &IoLargeIrpLookaside
.L
;
134 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
135 sizeof(NPAGED_LOOKASIDE_LIST
),
139 /* Initialize the Lookaside List for Large IRPs */
140 ExInitializeNPagedLookasideList(CurrentList
,
150 CurrentList
= &IoLargeIrpLookaside
;
152 Prcb
->PPLookasideList
[LookasideLargeIrpList
].P
= &CurrentList
->L
;
154 /* Set the Small IRP List */
155 Prcb
->PPLookasideList
[LookasideSmallIrpList
].L
= &IoSmallIrpLookaside
.L
;
156 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
157 sizeof(NPAGED_LOOKASIDE_LIST
),
161 /* Initialize the Lookaside List for Small IRPs */
162 ExInitializeNPagedLookasideList(CurrentList
,
172 CurrentList
= &IoSmallIrpLookaside
;
174 Prcb
->PPLookasideList
[LookasideSmallIrpList
].P
= &CurrentList
->L
;
176 /* Set the I/O Completion List */
177 Prcb
->PPLookasideList
[LookasideCompletionList
].L
= &IoCompletionPacketLookaside
.L
;
178 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
179 sizeof(NPAGED_LOOKASIDE_LIST
),
183 /* Initialize the Lookaside List for Large IRPs */
184 ExInitializeNPagedLookasideList(CurrentList
,
188 sizeof(IO_COMPLETION_PACKET
),
194 CurrentList
= &IoCompletionPacketLookaside
;
196 Prcb
->PPLookasideList
[LookasideCompletionList
].P
= &CurrentList
->L
;
198 /* Set the MDL Completion List */
199 Prcb
->PPLookasideList
[LookasideMdlList
].L
= &IopMdlLookasideList
.L
;
200 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
201 sizeof(NPAGED_LOOKASIDE_LIST
),
205 /* Initialize the Lookaside List for MDLs */
206 ExInitializeNPagedLookasideList(CurrentList
,
216 CurrentList
= &IopMdlLookasideList
;
218 Prcb
->PPLookasideList
[LookasideMdlList
].P
= &CurrentList
->L
;
221 DPRINT("Done allocation\n");
228 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
230 OBJECT_ATTRIBUTES ObjectAttributes
;
231 UNICODE_STRING DirName
;
232 UNICODE_STRING LinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices");
235 IopInitDriverImplementation();
237 DPRINT("Creating Device Object Type\n");
239 /* Initialize the Driver object type */
240 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
241 RtlInitUnicodeString(&Name
, L
"Device");
242 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
243 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(DEVICE_OBJECT
);
244 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
245 ObjectTypeInitializer
.ValidAccessMask
= FILE_ALL_ACCESS
;
246 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
247 ObjectTypeInitializer
.GenericMapping
= IopFileMapping
;
248 ObjectTypeInitializer
.ParseProcedure
= IopParseDevice
;
249 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &IoDeviceObjectType
);
251 /* Do the Adapter Type */
252 RtlInitUnicodeString(&Name
, L
"Adapter");
253 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &IoAdapterObjectType
);
255 /* Do the Controller Type */
256 RtlInitUnicodeString(&Name
, L
"Controller");
257 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(CONTROLLER_OBJECT
);
258 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &IoControllerObjectType
);
260 /* Initialize the File object type */
261 RtlInitUnicodeString(&Name
, L
"File");
262 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
263 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(FILE_OBJECT
);
264 ObjectTypeInitializer
.CloseProcedure
= IopCloseFile
;
265 ObjectTypeInitializer
.DeleteProcedure
= IopDeleteFile
;
266 ObjectTypeInitializer
.SecurityProcedure
= IopSecurityFile
;
267 ObjectTypeInitializer
.QueryNameProcedure
= IopQueryNameFile
;
268 ObjectTypeInitializer
.ParseProcedure
= IopParseFile
;
269 ObjectTypeInitializer
.UseDefaultObject
= FALSE
;
270 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &IoFileObjectType
);
273 * Create the '\Driver' object directory
275 RtlInitUnicodeString(&DirName
, L
"\\Driver");
276 InitializeObjectAttributes(&ObjectAttributes
,
281 ZwCreateDirectoryObject(&Handle
,
286 * Create the '\FileSystem' object directory
288 RtlInitUnicodeString(&DirName
,
290 InitializeObjectAttributes(&ObjectAttributes
,
295 ZwCreateDirectoryObject(&Handle
,
300 * Create the '\Device' directory
302 RtlInitUnicodeString(&DirName
,
304 InitializeObjectAttributes(&ObjectAttributes
,
309 ZwCreateDirectoryObject(&Handle
,
314 * Create the '\??' directory
316 RtlInitUnicodeString(&DirName
,
318 InitializeObjectAttributes(&ObjectAttributes
,
323 ZwCreateDirectoryObject(&Handle
,
328 * Create the '\ArcName' directory
330 RtlInitUnicodeString(&DirName
,
332 InitializeObjectAttributes(&ObjectAttributes
,
337 ZwCreateDirectoryObject(&Handle
,
342 * Initialize remaining subsubsystem
344 IoInitCancelHandling();
345 IoInitFileSystemImplementation();
346 IoInitVpbImplementation();
347 IoInitShutdownNotification();
348 IopInitPnpNotificationImplementation();
350 IopInitTimerImplementation();
351 IopInitIoCompletionImplementation();
352 IopInitLookasideLists();
355 * Create link from '\DosDevices' to '\??' directory
357 RtlInitUnicodeString(&DirName
,
359 IoCreateSymbolicLink(&LinkName
,
363 * Initialize PnP manager
370 IoInit2(BOOLEAN BootLog
)
372 PDEVICE_NODE DeviceNode
;
373 PDRIVER_OBJECT DriverObject
;
374 LDR_DATA_TABLE_ENTRY ModuleObject
;
379 IoCreateDriverList();
381 KeInitializeSpinLock (&IoStatisticsLock
);
383 /* Initialize raw filesystem driver */
385 /* Use IopRootDeviceNode for now */
386 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
389 if (!NT_SUCCESS(Status
))
391 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
395 ModuleObject
.DllBase
= NULL
;
396 ModuleObject
.SizeOfImage
= 0;
397 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
399 Status
= IopInitializeDriverModule(
402 &DeviceNode
->ServiceName
,
405 if (!NT_SUCCESS(Status
))
407 IopFreeDeviceNode(DeviceNode
);
408 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
412 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
413 if (!NT_SUCCESS(Status
))
415 IopFreeDeviceNode(DeviceNode
);
416 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
420 Status
= IopStartDevice(DeviceNode
);
421 if (!NT_SUCCESS(Status
))
423 IopFreeDeviceNode(DeviceNode
);
424 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
429 * Initialize PnP root releations
431 IopInvalidateDeviceRelations(
435 /* Start boot logging */
436 IopInitBootLog(BootLog
);
438 /* Load boot start drivers */
439 IopInitializeBootDrivers();
449 /* Create ARC names for boot devices */
452 /* Create the SystemRoot symbolic link */
453 DPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
454 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
455 if (!NT_SUCCESS(Status
)) {
456 CPRINT("IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
457 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
463 /* I/O is now setup for disk access, so phase 3 */
464 KdInitSystem(3, (PROS_LOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
466 /* Load services for devices found by PnP manager */
467 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
469 /* Load system start drivers */
470 IopInitializeSystemDrivers();
471 IoDestroyDriverList();
473 /* Call back drivers that asked for */
474 IopReinitializeBootDrivers();
476 /* Stop boot logging */
479 /* Assign drive letters */
480 IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,