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 extern POBJECT_TYPE IoControllerObjectType
;
33 ULONG EXPORTED IoReadOperationCount
= 0;
34 ULONGLONG EXPORTED IoReadTransferCount
= 0;
35 ULONG EXPORTED IoWriteOperationCount
= 0;
36 ULONGLONG EXPORTED IoWriteTransferCount
= 0;
37 ULONG IoOtherOperationCount
= 0;
38 ULONGLONG IoOtherTransferCount
= 0;
39 KSPIN_LOCK EXPORTED IoStatisticsLock
= 0;
41 GENERIC_MAPPING IopFileMapping
= {
47 static KSPIN_LOCK CancelSpinLock
;
48 extern LIST_ENTRY ShutdownListHead
;
49 extern KSPIN_LOCK ShutdownListLock
;
50 extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside
;
51 NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside
;
52 NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside
;
54 /* INIT FUNCTIONS ************************************************************/
58 IoInitCancelHandling(VOID
)
60 KeInitializeSpinLock(&CancelSpinLock
);
65 IoInitShutdownNotification (VOID
)
67 InitializeListHead(&ShutdownListHead
);
68 KeInitializeSpinLock(&ShutdownListLock
);
73 IopInitLookasideLists(VOID
)
75 ULONG LargeIrpSize
, SmallIrpSize
;
78 PNPAGED_LOOKASIDE_LIST CurrentList
= NULL
;
80 /* Calculate the sizes */
81 LargeIrpSize
= sizeof(IRP
) + (8 * sizeof(IO_STACK_LOCATION
));
82 SmallIrpSize
= sizeof(IRP
) + sizeof(IO_STACK_LOCATION
);
84 /* Initialize the Lookaside List for Large IRPs */
85 ExInitializeNPagedLookasideList(&IoLargeIrpLookaside
,
93 /* Initialize the Lookaside List for Small IRPs */
94 ExInitializeNPagedLookasideList(&IoSmallIrpLookaside
,
102 /* Initialize the Lookaside List for I\O Completion */
103 ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside
,
107 sizeof(IO_COMPLETION_PACKET
),
111 /* Now allocate the per-processor lists */
112 for (i
= 0; i
< KeNumberProcessors
; i
++)
114 /* Get the PRCB for this CPU */
115 Prcb
= ((PKPCR
)(KPCR_BASE
+ i
* PAGE_SIZE
))->Prcb
;
116 DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i
, Prcb
);
118 /* Set the Large IRP List */
119 Prcb
->PPLookasideList
[LookasideLargeIrpList
].L
= &IoLargeIrpLookaside
.L
;
120 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
121 sizeof(NPAGED_LOOKASIDE_LIST
),
125 /* Initialize the Lookaside List for Large IRPs */
126 ExInitializeNPagedLookasideList(CurrentList
,
136 CurrentList
= &IoLargeIrpLookaside
;
138 Prcb
->PPLookasideList
[LookasideLargeIrpList
].P
= &CurrentList
->L
;
140 /* Set the Small IRP List */
141 Prcb
->PPLookasideList
[LookasideSmallIrpList
].L
= &IoSmallIrpLookaside
.L
;
142 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
143 sizeof(NPAGED_LOOKASIDE_LIST
),
147 /* Initialize the Lookaside List for Large IRPs */
148 ExInitializeNPagedLookasideList(CurrentList
,
158 CurrentList
= &IoSmallIrpLookaside
;
160 Prcb
->PPLookasideList
[LookasideSmallIrpList
].P
= &CurrentList
->L
;
162 /* Set the I/O Completion List */
163 Prcb
->PPLookasideList
[LookasideCompletionList
].L
= &IoCompletionPacketLookaside
.L
;
164 CurrentList
= ExAllocatePoolWithTag(NonPagedPool
,
165 sizeof(NPAGED_LOOKASIDE_LIST
),
169 /* Initialize the Lookaside List for Large IRPs */
170 ExInitializeNPagedLookasideList(CurrentList
,
180 CurrentList
= &IoCompletionPacketLookaside
;
182 Prcb
->PPLookasideList
[LookasideCompletionList
].P
= &CurrentList
->L
;
185 DPRINT("Done allocation\n");
192 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
194 OBJECT_ATTRIBUTES ObjectAttributes
;
195 UNICODE_STRING DirName
;
196 UNICODE_STRING LinkName
;
199 IopInitDriverImplementation();
201 DPRINT1("Creating Device Object Type\n");
203 /* Initialize the Driver object type */
204 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
205 RtlInitUnicodeString(&Name
, L
"Device");
206 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
207 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(DEVICE_OBJECT
);
208 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
209 ObjectTypeInitializer
.ValidAccessMask
= FILE_ALL_ACCESS
;
210 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
211 ObjectTypeInitializer
.GenericMapping
= IopFileMapping
;
212 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoDeviceObjectType
);
214 /* Do the Adapter Type */
215 RtlInitUnicodeString(&Name
, L
"Adapter");
216 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoAdapterObjectType
);
218 /* Do the Controller Type */
219 RtlInitUnicodeString(&Name
, L
"Controller");
220 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(CONTROLLER_OBJECT
);
221 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoControllerObjectType
);
223 /* Initialize the File object type */
224 RtlInitUnicodeString(&Name
, L
"File");
225 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
226 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(FILE_OBJECT
);
227 ObjectTypeInitializer
.CloseProcedure
= IopCloseFile
;
228 ObjectTypeInitializer
.DeleteProcedure
= IopDeleteFile
;
229 ObjectTypeInitializer
.SecurityProcedure
= IopSecurityFile
;
230 ObjectTypeInitializer
.QueryNameProcedure
= IopQueryNameFile
;
231 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &IoFileObjectType
);
234 * Create the '\Driver' object directory
236 RtlRosInitUnicodeStringFromLiteral(&DirName
, L
"\\Driver");
237 InitializeObjectAttributes(&ObjectAttributes
,
242 ZwCreateDirectoryObject(&Handle
,
247 * Create the '\FileSystem' object directory
249 RtlRosInitUnicodeStringFromLiteral(&DirName
,
251 InitializeObjectAttributes(&ObjectAttributes
,
256 ZwCreateDirectoryObject(&Handle
,
261 * Create the '\Device' directory
263 RtlRosInitUnicodeStringFromLiteral(&DirName
,
265 InitializeObjectAttributes(&ObjectAttributes
,
270 ZwCreateDirectoryObject(&Handle
,
275 * Create the '\??' directory
277 RtlRosInitUnicodeStringFromLiteral(&DirName
,
279 InitializeObjectAttributes(&ObjectAttributes
,
284 ZwCreateDirectoryObject(&Handle
,
289 * Create the '\ArcName' directory
291 RtlRosInitUnicodeStringFromLiteral(&DirName
,
293 InitializeObjectAttributes(&ObjectAttributes
,
298 ZwCreateDirectoryObject(&Handle
,
303 * Initialize remaining subsubsystem
305 IoInitCancelHandling();
306 IoInitFileSystemImplementation();
307 IoInitVpbImplementation();
308 IoInitShutdownNotification();
309 IopInitPnpNotificationImplementation();
311 IopInitTimerImplementation();
312 IopInitIoCompletionImplementation();
313 IopInitLookasideLists();
316 * Create link from '\DosDevices' to '\??' directory
318 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
320 RtlRosInitUnicodeStringFromLiteral(&DirName
,
322 IoCreateSymbolicLink(&LinkName
,
326 * Initialize PnP manager
333 IoInit2(BOOLEAN BootLog
)
335 PDEVICE_NODE DeviceNode
;
336 PDRIVER_OBJECT DriverObject
;
337 MODULE_OBJECT ModuleObject
;
340 IoCreateDriverList();
342 KeInitializeSpinLock (&IoStatisticsLock
);
344 /* Initialize raw filesystem driver */
346 /* Use IopRootDeviceNode for now */
347 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
350 if (!NT_SUCCESS(Status
))
352 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
356 ModuleObject
.Base
= NULL
;
357 ModuleObject
.Length
= 0;
358 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
360 Status
= IopInitializeDriverModule(
363 &DeviceNode
->ServiceName
,
366 if (!NT_SUCCESS(Status
))
368 IopFreeDeviceNode(DeviceNode
);
369 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
373 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
374 if (!NT_SUCCESS(Status
))
376 IopFreeDeviceNode(DeviceNode
);
377 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
381 Status
= IopStartDevice(DeviceNode
);
382 if (!NT_SUCCESS(Status
))
384 IopFreeDeviceNode(DeviceNode
);
385 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
390 * Initialize PnP root releations
392 IopInvalidateDeviceRelations(
396 /* Start boot logging */
397 IopInitBootLog(BootLog
);
399 /* Load boot start drivers */
400 IopInitializeBootDrivers();
410 /* Create ARC names for boot devices */
413 /* Create the SystemRoot symbolic link */
414 DPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
415 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
416 if (!NT_SUCCESS(Status
)) {
417 CPRINT("IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
418 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
424 /* I/O is now setup for disk access, so phase 3 */
425 KdInitSystem(3, (PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
);
427 /* Load services for devices found by PnP manager */
428 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
430 /* Load system start drivers */
431 IopInitializeSystemDrivers();
432 IoDestroyDriverList();
434 /* Stop boot logging */
437 /* Assign drive letters */
438 IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
444 /* FUNCTIONS *****************************************************************/
451 IoAcquireCancelSpinLock(PKIRQL Irql
)
453 KeAcquireSpinLock(&CancelSpinLock
,Irql
);
461 IoGetInitialStack(VOID
)
463 return(PsGetCurrentThread()->Tcb
.InitialStack
);
471 IoGetStackLimits(OUT PULONG LowLimit
,
472 OUT PULONG HighLimit
)
474 *LowLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackLimit
;
475 *HighLimit
= (ULONG
)NtCurrentTeb()->Tib
.StackBase
;
483 IoIsSystemThread(IN PETHREAD Thread
)
485 /* Call the Ps Function */
486 return PsIsSystemThread(Thread
);
493 IoIsWdmVersionAvailable(IN UCHAR MajorVersion
,
494 IN UCHAR MinorVersion
)
496 if (MajorVersion
<= 1 && MinorVersion
<= 10)
506 IoReleaseCancelSpinLock(KIRQL Irql
)
508 KeReleaseSpinLock(&CancelSpinLock
,Irql
);
516 IoThreadToProcess(IN PETHREAD Thread
)
518 return(Thread
->ThreadsProcess
);