3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/iomgr.c
6 * PURPOSE: Initializes the io manager
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES ****************************************************************/
14 #include "../dbg/kdb.h"
16 #include <internal/debug.h>
18 /* GLOBALS *******************************************************************/
20 #define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
21 #define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
22 #define TAG_ADAPTER_TYPE TAG('A', 'D', 'P', 'T')
24 /* DATA ********************************************************************/
27 POBJECT_TYPE EXPORTED IoDeviceObjectType
= NULL
;
28 POBJECT_TYPE EXPORTED IoFileObjectType
= NULL
;
29 ULONG EXPORTED IoReadOperationCount
= 0;
30 ULONGLONG EXPORTED IoReadTransferCount
= 0;
31 ULONG EXPORTED IoWriteOperationCount
= 0;
32 ULONGLONG EXPORTED IoWriteTransferCount
= 0;
33 ULONG IoOtherOperationCount
= 0;
34 ULONGLONG IoOtherTransferCount
= 0;
35 KSPIN_LOCK EXPORTED IoStatisticsLock
= 0;
37 static GENERIC_MAPPING IopFileMapping
= {FILE_GENERIC_READ
,
42 /* FUNCTIONS ****************************************************************/
45 IopCloseFile(PVOID ObjectBody
,
48 PFILE_OBJECT FileObject
= (PFILE_OBJECT
)ObjectBody
;
50 PIO_STACK_LOCATION StackPtr
;
53 DPRINT("IopCloseFile()\n");
55 if (HandleCount
> 1 || FileObject
->DeviceObject
== NULL
)
61 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
62 ObReferenceObjectByPointer(FileObject
,
63 STANDARD_RIGHTS_REQUIRED
,
68 KeResetEvent( &FileObject
->Event
);
70 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP
,
71 FileObject
->DeviceObject
,
77 StackPtr
= IoGetNextIrpStackLocation(Irp
);
78 StackPtr
->FileObject
= FileObject
;
80 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
81 if (Status
== STATUS_PENDING
)
83 KeWaitForSingleObject(&FileObject
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
89 IopDeleteFile(PVOID ObjectBody
)
91 PFILE_OBJECT FileObject
= (PFILE_OBJECT
)ObjectBody
;
93 PIO_STACK_LOCATION StackPtr
;
96 DPRINT("IopDeleteFile()\n");
98 if (FileObject
->DeviceObject
)
101 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
103 ObReferenceObjectByPointer(ObjectBody
,
104 STANDARD_RIGHTS_REQUIRED
,
108 KeResetEvent( &FileObject
->Event
);
110 Irp
= IoAllocateIrp(FileObject
->DeviceObject
->StackSize
, TRUE
);
114 * FIXME: This case should eventually be handled. We should wait
115 * until enough memory is available to allocate the IRP.
120 Irp
->UserEvent
= &FileObject
->Event
;
121 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
122 Irp
->Flags
|= IRP_CLOSE_OPERATION
;
124 StackPtr
= IoGetNextIrpStackLocation(Irp
);
125 StackPtr
->MajorFunction
= IRP_MJ_CLOSE
;
126 StackPtr
->DeviceObject
= FileObject
->DeviceObject
;
127 StackPtr
->FileObject
= FileObject
;
129 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
130 if (Status
== STATUS_PENDING
)
132 KeWaitForSingleObject(&FileObject
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
136 if (FileObject
->FileName
.Buffer
!= NULL
)
138 ExFreePool(FileObject
->FileName
.Buffer
);
139 FileObject
->FileName
.Buffer
= 0;
145 IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation
,
146 PSECURITY_DESCRIPTOR SecurityDescriptor
,
154 DPRINT("IopSetDefaultSecurityDescriptor() called\n");
156 if (SecurityInformation
== 0)
158 return STATUS_ACCESS_DENIED
;
161 SidSize
= RtlLengthSid(SeWorldSid
);
162 SdSize
= sizeof(SECURITY_DESCRIPTOR
) + (2 * SidSize
);
164 if (*BufferLength
< SdSize
)
166 *BufferLength
= SdSize
;
167 return STATUS_BUFFER_TOO_SMALL
;
170 *BufferLength
= SdSize
;
172 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
173 SECURITY_DESCRIPTOR_REVISION
);
174 if (!NT_SUCCESS(Status
))
179 SecurityDescriptor
->Control
|= SE_SELF_RELATIVE
;
180 Current
= (ULONG_PTR
)SecurityDescriptor
+ sizeof(SECURITY_DESCRIPTOR
);
182 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
184 RtlCopyMemory((PVOID
)Current
,
187 SecurityDescriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
191 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
193 RtlCopyMemory((PVOID
)Current
,
196 SecurityDescriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
200 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
202 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
;
205 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
207 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
;
210 return STATUS_SUCCESS
;
215 IopSecurityFile(PVOID ObjectBody
,
216 SECURITY_OPERATION_CODE OperationCode
,
217 SECURITY_INFORMATION SecurityInformation
,
218 PSECURITY_DESCRIPTOR SecurityDescriptor
,
221 IO_STATUS_BLOCK IoStatusBlock
;
222 PIO_STACK_LOCATION StackPtr
;
223 PFILE_OBJECT FileObject
;
227 DPRINT("IopSecurityFile() called\n");
229 FileObject
= (PFILE_OBJECT
)ObjectBody
;
231 switch (OperationCode
)
233 case SetSecurityDescriptor
:
234 DPRINT("Set security descriptor\n");
235 KeResetEvent(&FileObject
->Event
);
236 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY
,
237 FileObject
->DeviceObject
,
244 StackPtr
= IoGetNextIrpStackLocation(Irp
);
245 StackPtr
->FileObject
= FileObject
;
247 StackPtr
->Parameters
.SetSecurity
.SecurityInformation
= SecurityInformation
;
248 StackPtr
->Parameters
.SetSecurity
.SecurityDescriptor
= SecurityDescriptor
;
250 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
251 if (Status
== STATUS_PENDING
)
253 KeWaitForSingleObject(&FileObject
->Event
,
258 Status
= IoStatusBlock
.Status
;
261 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
263 Status
= STATUS_SUCCESS
;
267 case QuerySecurityDescriptor
:
268 DPRINT("Query security descriptor\n");
269 KeResetEvent(&FileObject
->Event
);
270 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY
,
271 FileObject
->DeviceObject
,
278 Irp
->UserBuffer
= SecurityDescriptor
;
280 StackPtr
= IoGetNextIrpStackLocation(Irp
);
281 StackPtr
->FileObject
= FileObject
;
283 StackPtr
->Parameters
.QuerySecurity
.SecurityInformation
= SecurityInformation
;
284 StackPtr
->Parameters
.QuerySecurity
.Length
= *BufferLength
;
286 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
287 if (Status
== STATUS_PENDING
)
289 KeWaitForSingleObject(&FileObject
->Event
,
294 Status
= IoStatusBlock
.Status
;
297 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
299 Status
= IopSetDefaultSecurityDescriptor(SecurityInformation
,
305 /* FIXME: Is this correct?? */
306 *BufferLength
= IoStatusBlock
.Information
;
310 case DeleteSecurityDescriptor
:
311 DPRINT("Delete security descriptor\n");
312 return STATUS_SUCCESS
;
314 case AssignSecurityDescriptor
:
315 DPRINT("Assign security descriptor\n");
316 return STATUS_SUCCESS
;
319 return STATUS_UNSUCCESSFUL
;
324 IopQueryNameFile(PVOID ObjectBody
,
325 POBJECT_NAME_INFORMATION ObjectNameInfo
,
329 POBJECT_NAME_INFORMATION LocalInfo
;
330 PFILE_NAME_INFORMATION FileNameInfo
;
331 PFILE_OBJECT FileObject
;
332 ULONG LocalReturnLength
;
335 DPRINT ("IopQueryNameFile() called\n");
337 FileObject
= (PFILE_OBJECT
)ObjectBody
;
339 LocalInfo
= ExAllocatePool (NonPagedPool
,
340 sizeof(OBJECT_NAME_INFORMATION
) +
341 MAX_PATH
* sizeof(WCHAR
));
342 if (LocalInfo
== NULL
)
343 return STATUS_INSUFFICIENT_RESOURCES
;
345 Status
= ObQueryNameString (FileObject
->DeviceObject
->Vpb
->RealDevice
,
347 MAX_PATH
* sizeof(WCHAR
),
349 if (!NT_SUCCESS (Status
))
351 ExFreePool (LocalInfo
);
354 DPRINT ("Device path: %wZ\n", &LocalInfo
->Name
);
356 Status
= RtlAppendUnicodeStringToString (&ObjectNameInfo
->Name
,
359 ExFreePool (LocalInfo
);
361 FileNameInfo
= ExAllocatePool (NonPagedPool
,
362 MAX_PATH
* sizeof(WCHAR
) + sizeof(ULONG
));
363 if (FileNameInfo
== NULL
)
364 return STATUS_INSUFFICIENT_RESOURCES
;
366 Status
= IoQueryFileInformation (FileObject
,
368 MAX_PATH
* sizeof(WCHAR
) + sizeof(ULONG
),
371 if (Status
!= STATUS_SUCCESS
)
373 ExFreePool (FileNameInfo
);
377 Status
= RtlAppendUnicodeToString (&ObjectNameInfo
->Name
,
378 FileNameInfo
->FileName
);
380 DPRINT ("Total path: %wZ\n", &ObjectNameInfo
->Name
);
382 ExFreePool (FileNameInfo
);
391 OBJECT_ATTRIBUTES ObjectAttributes
;
392 UNICODE_STRING DirName
;
393 UNICODE_STRING LinkName
;
396 IopInitDriverImplementation();
399 * Register iomgr types: DeviceObjectType
401 IoDeviceObjectType
= ExAllocatePool (NonPagedPool
,
402 sizeof (OBJECT_TYPE
));
404 IoDeviceObjectType
->Tag
= TAG_DEVICE_TYPE
;
405 IoDeviceObjectType
->TotalObjects
= 0;
406 IoDeviceObjectType
->TotalHandles
= 0;
407 IoDeviceObjectType
->PeakObjects
= 0;
408 IoDeviceObjectType
->PeakHandles
= 0;
409 IoDeviceObjectType
->PagedPoolCharge
= 0;
410 IoDeviceObjectType
->NonpagedPoolCharge
= sizeof (DEVICE_OBJECT
);
411 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
412 IoDeviceObjectType
->Dump
= NULL
;
413 IoDeviceObjectType
->Open
= NULL
;
414 IoDeviceObjectType
->Close
= NULL
;
415 IoDeviceObjectType
->Delete
= NULL
;
416 IoDeviceObjectType
->Parse
= NULL
;
417 IoDeviceObjectType
->Security
= NULL
;
418 IoDeviceObjectType
->QueryName
= NULL
;
419 IoDeviceObjectType
->OkayToClose
= NULL
;
420 IoDeviceObjectType
->Create
= IopCreateDevice
;
421 IoDeviceObjectType
->DuplicationNotify
= NULL
;
423 RtlInitUnicodeString(&IoDeviceObjectType
->TypeName
, L
"Device");
425 ObpCreateTypeObject(IoDeviceObjectType
);
428 * Register iomgr types: FileObjectType
429 * (alias DriverObjectType)
431 IoFileObjectType
= ExAllocatePool (NonPagedPool
, sizeof (OBJECT_TYPE
));
433 IoFileObjectType
->Tag
= TAG_FILE_TYPE
;
434 IoFileObjectType
->TotalObjects
= 0;
435 IoFileObjectType
->TotalHandles
= 0;
436 IoFileObjectType
->PeakObjects
= 0;
437 IoFileObjectType
->PeakHandles
= 0;
438 IoFileObjectType
->PagedPoolCharge
= 0;
439 IoFileObjectType
->NonpagedPoolCharge
= sizeof(FILE_OBJECT
);
440 IoFileObjectType
->Mapping
= &IopFileMapping
;
441 IoFileObjectType
->Dump
= NULL
;
442 IoFileObjectType
->Open
= NULL
;
443 IoFileObjectType
->Close
= IopCloseFile
;
444 IoFileObjectType
->Delete
= IopDeleteFile
;
445 IoFileObjectType
->Parse
= NULL
;
446 IoFileObjectType
->Security
= IopSecurityFile
;
447 IoFileObjectType
->QueryName
= IopQueryNameFile
;
448 IoFileObjectType
->OkayToClose
= NULL
;
449 IoFileObjectType
->Create
= IopCreateFile
;
450 IoFileObjectType
->DuplicationNotify
= NULL
;
452 RtlInitUnicodeString(&IoFileObjectType
->TypeName
, L
"File");
454 ObpCreateTypeObject(IoFileObjectType
);
457 * Register iomgr types: AdapterObjectType
459 IoAdapterObjectType
= ExAllocatePool (NonPagedPool
,
460 sizeof (OBJECT_TYPE
));
461 RtlZeroMemory(IoAdapterObjectType
, sizeof(OBJECT_TYPE
));
462 IoAdapterObjectType
->Tag
= TAG_ADAPTER_TYPE
;
463 IoAdapterObjectType
->PeakObjects
= 0;
464 IoAdapterObjectType
->PeakHandles
= 0;
465 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
466 RtlInitUnicodeString(&IoAdapterObjectType
->TypeName
, L
"Adapter");
467 ObpCreateTypeObject(IoAdapterObjectType
);
470 * Create the '\Driver' object directory
472 RtlRosInitUnicodeStringFromLiteral(&DirName
, L
"\\Driver");
473 InitializeObjectAttributes(&ObjectAttributes
,
478 ZwCreateDirectoryObject(&Handle
,
483 * Create the '\FileSystem' object directory
485 RtlRosInitUnicodeStringFromLiteral(&DirName
,
487 InitializeObjectAttributes(&ObjectAttributes
,
492 ZwCreateDirectoryObject(&Handle
,
497 * Create the '\Device' directory
499 RtlRosInitUnicodeStringFromLiteral(&DirName
,
501 InitializeObjectAttributes(&ObjectAttributes
,
506 ZwCreateDirectoryObject(&Handle
,
511 * Create the '\??' directory
513 RtlRosInitUnicodeStringFromLiteral(&DirName
,
515 InitializeObjectAttributes(&ObjectAttributes
,
520 ZwCreateDirectoryObject(&Handle
,
525 * Create the '\ArcName' directory
527 RtlRosInitUnicodeStringFromLiteral(&DirName
,
529 InitializeObjectAttributes(&ObjectAttributes
,
534 ZwCreateDirectoryObject(&Handle
,
539 * Initialize remaining subsubsystem
541 IoInitCancelHandling();
542 IoInitFileSystemImplementation();
543 IoInitVpbImplementation();
544 IoInitShutdownNotification();
546 IopInitTimerImplementation();
547 IopInitIoCompletionImplementation();
550 * Create link from '\DosDevices' to '\??' directory
552 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
554 RtlRosInitUnicodeStringFromLiteral(&DirName
,
556 IoCreateSymbolicLink(&LinkName
,
560 * Initialize PnP manager
568 IoInit2(BOOLEAN BootLog
)
570 PDEVICE_NODE DeviceNode
;
571 PDRIVER_OBJECT DriverObject
;
572 MODULE_OBJECT ModuleObject
;
575 IoCreateDriverList();
577 KeInitializeSpinLock (&IoStatisticsLock
);
579 /* Initialize raw filesystem driver */
581 /* Use IopRootDeviceNode for now */
582 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
585 if (!NT_SUCCESS(Status
))
587 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
591 ModuleObject
.Base
= NULL
;
592 ModuleObject
.Length
= 0;
593 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
595 Status
= IopInitializeDriverModule(
600 if (!NT_SUCCESS(Status
))
602 IopFreeDeviceNode(DeviceNode
);
603 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
607 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
608 if (!NT_SUCCESS(Status
))
610 IopFreeDeviceNode(DeviceNode
);
611 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
616 * Initialize PnP root releations
618 IopInvalidateDeviceRelations(
622 /* Start boot logging */
623 IopInitBootLog(BootLog
);
625 /* Load boot start drivers */
626 IopInitializeBootDrivers();
636 /* Create ARC names for boot devices */
639 /* Create the SystemRoot symbolic link */
640 CPRINT("CommandLine: %s\n", (PCHAR
)KeLoaderBlock
.CommandLine
);
641 Status
= IoCreateSystemRootLink((PCHAR
)KeLoaderBlock
.CommandLine
);
642 if (!NT_SUCCESS(Status
)) {
643 DbgPrint("IoCreateSystemRootLink FAILED: (0x%x) - ", Status
);
644 DbgPrintErrorMessage (Status
);
645 KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE
);
648 /* Start Profiling on a Debug Build */
653 /* I/O is now setup for disk access, so start the debugging logger thread. */
654 if (KdDebugState
& KD_DEBUG_FILELOG
) DebugLogInit2();
656 /* Load services for devices found by PnP manager */
657 IopInitializePnpServices(IopRootDeviceNode
, FALSE
);
659 /* Load system start drivers */
660 IopInitializeSystemDrivers();
661 IoDestroyDriverList();
663 /* Stop boot logging */
666 /* Assign drive letters */
667 IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK
)&KeLoaderBlock
,
676 PGENERIC_MAPPING STDCALL
677 IoGetFileObjectGenericMapping(VOID
)
679 return(&IopFileMapping
);