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 /* DATA ********************************************************************/
18 POBJECT_TYPE IoDeviceObjectType
= NULL
;
19 POBJECT_TYPE IoFileObjectType
= NULL
;
20 extern POBJECT_TYPE IoControllerObjectType
;
21 ULONG IoReadOperationCount
= 0;
22 LARGE_INTEGER IoReadTransferCount
= {{0, 0}};
23 ULONG IoWriteOperationCount
= 0;
24 LARGE_INTEGER IoWriteTransferCount
= {{0, 0}};
25 ULONG IoOtherOperationCount
= 0;
26 LARGE_INTEGER IoOtherTransferCount
= {{0, 0}};
27 KSPIN_LOCK IoStatisticsLock
= 0;
29 GENERIC_MAPPING IopFileMapping
= {
35 static KSPIN_LOCK CancelSpinLock
;
36 extern LIST_ENTRY ShutdownListHead
;
37 extern KSPIN_LOCK ShutdownListLock
;
38 extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside
;
39 extern POBJECT_TYPE IoAdapterObjectType
;
40 NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside
;
41 NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside
;
43 /* INIT FUNCTIONS ************************************************************/
47 IoInitCancelHandling(VOID
)
49 KeInitializeSpinLock(&CancelSpinLock
);
54 IoInitShutdownNotification (VOID
)
56 InitializeListHead(&ShutdownListHead
);
57 KeInitializeSpinLock(&ShutdownListLock
);
62 IopInitLookasideLists(VOID
)
64 ULONG LargeIrpSize
, SmallIrpSize
;
67 PNPAGED_LOOKASIDE_LIST CurrentList
= NULL
;
69 /* Calculate the sizes */
70 LargeIrpSize
= sizeof(IRP
) + (8 * sizeof(IO_STACK_LOCATION
));
71 SmallIrpSize
= sizeof(IRP
) + sizeof(IO_STACK_LOCATION
);
73 /* Initialize the Lookaside List for Large IRPs */
74 ExInitializeNPagedLookasideList(&IoLargeIrpLookaside
,
82 /* Initialize the Lookaside List for Small IRPs */
83 ExInitializeNPagedLookasideList(&IoSmallIrpLookaside
,
91 /* Initialize the Lookaside List for I\O Completion */
92 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside
,
96 sizeof(IO_COMPLETION_PACKET
),
100 /* Now allocate the per-processor lists */
101 for (i
= 0; i
< KeNumberProcessors
; i
++)
103 /* Get the PRCB for this CPU */
104 Prcb
= ((PKPCR
)(KPCR_BASE
+ i
* PAGE_SIZE
))->Prcb
;
105 DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i
, Prcb
);
107 /* Set the Large IRP List */
108 Prcb
->PPLookasideList
[LookasideLargeIrpList
].L
= &IoLargeIrpLookaside
.L
;
109 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
110 sizeof(NPAGED_LOOKASIDE_LIST
),
114 /* Initialize the Lookaside List for Large IRPs */
115 ExInitializeNPagedLookasideList(CurrentList
,
125 CurrentList
= &IoLargeIrpLookaside
;
127 Prcb
->PPLookasideList
[LookasideLargeIrpList
].P
= &CurrentList
->L
;
129 /* Set the Small IRP List */
130 Prcb
->PPLookasideList
[LookasideSmallIrpList
].L
= &IoSmallIrpLookaside
.L
;
131 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
132 sizeof(NPAGED_LOOKASIDE_LIST
),
136 /* Initialize the Lookaside List for Large IRPs */
137 ExInitializeNPagedLookasideList(CurrentList
,
147 CurrentList
= &IoSmallIrpLookaside
;
149 Prcb
->PPLookasideList
[LookasideSmallIrpList
].P
= &CurrentList
->L
;
151 /* Set the I/O Completion List */
152 Prcb
->PPLookasideList
[LookasideCompletionList
].L
= &IoCompletionPacketLookaside
.L
;
153 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
154 sizeof(NPAGED_LOOKASIDE_LIST
),
158 /* Initialize the Lookaside List for Large IRPs */
159 ExInitializeNPagedLookasideList(CurrentList
,
169 CurrentList
= &IoCompletionPacketLookaside
;
171 Prcb
->PPLookasideList
[LookasideCompletionList
].P
= &CurrentList
->L
;
174 DPRINT("Done allocation\n");
181 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
183 OBJECT_ATTRIBUTES ObjectAttributes
;
184 UNICODE_STRING DirName
;
185 UNICODE_STRING LinkName
= RTL_CONSTANT_STRING(L
"\\DosDevices");
188 IopInitDriverImplementation();
190 DPRINT("Creating Device Object Type\n");
192 /* Initialize the Driver object type */
193 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
194 RtlInitUnicodeString(&Name
, L
"Device");
195 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
196 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(DEVICE_OBJECT
);
197 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
198 ObjectTypeInitializer
.ValidAccessMask
= FILE_ALL_ACCESS
;
199 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
200 ObjectTypeInitializer
.GenericMapping
= IopFileMapping
;
201 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoDeviceObjectType
);
203 /* Do the Adapter Type */
204 RtlInitUnicodeString(&Name
, L
"Adapter");
205 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoAdapterObjectType
);
207 /* Do the Controller Type */
208 RtlInitUnicodeString(&Name
, L
"Controller");
209 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(CONTROLLER_OBJECT
);
210 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoControllerObjectType
);
212 /* Initialize the File object type */
213 RtlInitUnicodeString(&Name
, L
"File");
214 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
215 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(FILE_OBJECT
);
216 ObjectTypeInitializer
.CloseProcedure
= IopCloseFile
;
217 ObjectTypeInitializer
.DeleteProcedure
= IopDeleteFile
;
218 ObjectTypeInitializer
.SecurityProcedure
= IopSecurityFile
;
219 ObjectTypeInitializer
.QueryNameProcedure
= IopQueryNameFile
;
220 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoFileObjectType
);
223 * Create the '\Driver' object directory
225 RtlInitUnicodeString(&DirName
, L
"\\Driver");
226 InitializeObjectAttributes(&ObjectAttributes
,
231 ZwCreateDirectoryObject(&Handle
,
236 * Create the '\FileSystem' object directory
238 RtlInitUnicodeString(&DirName
,
240 InitializeObjectAttributes(&ObjectAttributes
,
245 ZwCreateDirectoryObject(&Handle
,
250 * Create the '\Device' directory
252 RtlInitUnicodeString(&DirName
,
254 InitializeObjectAttributes(&ObjectAttributes
,
259 ZwCreateDirectoryObject(&Handle
,
264 * Create the '\??' directory
266 RtlInitUnicodeString(&DirName
,
268 InitializeObjectAttributes(&ObjectAttributes
,
273 ZwCreateDirectoryObject(&Handle
,
278 * Create the '\ArcName' directory
280 RtlInitUnicodeString(&DirName
,
282 InitializeObjectAttributes(&ObjectAttributes
,
287 ZwCreateDirectoryObject(&Handle
,
292 * Initialize remaining subsubsystem
294 IoInitCancelHandling();
295 IoInitFileSystemImplementation();
296 IoInitVpbImplementation();
297 IoInitShutdownNotification();
298 IopInitPnpNotificationImplementation();
300 IopInitTimerImplementation();
301 IopInitIoCompletionImplementation();
302 IopInitLookasideLists();
305 * Create link from '\DosDevices' to '\??' directory
307 RtlInitUnicodeString(&DirName
,
309 IoCreateSymbolicLink(&LinkName
,
313 * Initialize PnP manager
320 IoInit2(BOOLEAN BootLog
)
322 PDEVICE_NODE DeviceNode
;
323 PDRIVER_OBJECT DriverObject
;
324 MODULE_OBJECT ModuleObject
;
329 IoCreateDriverList();
331 KeInitializeSpinLock (&IoStatisticsLock
);
333 /* Initialize raw filesystem driver */
335 /* Use IopRootDeviceNode for now */
336 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
339 if (!NT_SUCCESS(Status
))
341 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
345 ModuleObject
.Base
= NULL
;
346 ModuleObject
.Length
= 0;
347 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
349 Status
= IopInitializeDriverModule(
352 &DeviceNode
->ServiceName
,
355 if (!NT_SUCCESS(Status
))
357 IopFreeDeviceNode(DeviceNode
);
358 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
362 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
363 if (!NT_SUCCESS(Status
))
365 IopFreeDeviceNode(DeviceNode
);
366 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
370 Status
= IopStartDevice(DeviceNode
);
371 if (!NT_SUCCESS(Status
))
373 IopFreeDeviceNode(DeviceNode
);
374 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
379 * Initialize PnP root releations
381 IopInvalidateDeviceRelations(
385 /* Start boot logging */
386 IopInitBootLog(BootLog
);
388 /* Load boot start drivers */
389 IopInitializeBootDrivers();
399 /* Create ARC names for boot devices */
402 /* Create the SystemRoot symbolic link */
403 DPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
404 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
405 if (!NT_SUCCESS(Status
)) {
406 CPRINT("IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
407 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
413 /* I/O is now setup for disk access, so phase 3 */
414 KdInitSystem(3, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
416 /* Load services for devices found by PnP manager */
417 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
419 /* Load system start drivers */
420 IopInitializeSystemDrivers();
421 IoDestroyDriverList();
423 /* Stop boot logging */
426 /* Assign drive letters */
427 IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
433 /* FUNCTIONS *****************************************************************/
440 IoAcquireCancelSpinLock(PKIRQL Irql
)
442 KeAcquireSpinLock(&CancelSpinLock
,Irql
);
450 IoGetInitialStack(VOID
)
452 return(PsGetCurrentThread()->Tcb
.InitialStack
);
460 IoGetStackLimits(OUT PULONG LowLimit
,
461 OUT PULONG HighLimit
)
463 *LowLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackLimit
;
464 *HighLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackBase
;
472 IoIsSystemThread(IN PETHREAD Thread
)
474 /* Call the Ps Function */
475 return PsIsSystemThread(Thread
);
482 IoIsWdmVersionAvailable(IN UCHAR MajorVersion
,
483 IN UCHAR MinorVersion
)
485 if (MajorVersion
<= 1 && MinorVersion
<= 10)
495 IoReleaseCancelSpinLock(KIRQL Irql
)
497 KeReleaseSpinLock(&CancelSpinLock
,Irql
);
505 IoThreadToProcess(IN PETHREAD Thread
)
507 return(Thread
->ThreadsProcess
);