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
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES ****************************************************************/
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
> 0 || 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
);
109 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE
,
110 FileObject
->DeviceObject
,
116 Irp
->Flags
|= IRP_CLOSE_OPERATION
;
117 StackPtr
= IoGetNextIrpStackLocation(Irp
);
118 StackPtr
->FileObject
= FileObject
;
120 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
121 if (Status
== STATUS_PENDING
)
123 KeWaitForSingleObject(&FileObject
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
127 if (FileObject
->FileName
.Buffer
!= NULL
)
129 ExFreePool(FileObject
->FileName
.Buffer
);
130 FileObject
->FileName
.Buffer
= 0;
136 IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation
,
137 PSECURITY_DESCRIPTOR SecurityDescriptor
,
145 DPRINT("IopSetDefaultSecurityDescriptor() called\n");
147 if (SecurityInformation
== 0)
149 return STATUS_ACCESS_DENIED
;
152 SidSize
= RtlLengthSid(SeWorldSid
);
153 SdSize
= sizeof(SECURITY_DESCRIPTOR
) + (2 * SidSize
);
155 if (*BufferLength
< SdSize
)
157 *BufferLength
= SdSize
;
158 return STATUS_BUFFER_TOO_SMALL
;
161 *BufferLength
= SdSize
;
163 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
164 SECURITY_DESCRIPTOR_REVISION
);
165 if (!NT_SUCCESS(Status
))
170 SecurityDescriptor
->Control
|= SE_SELF_RELATIVE
;
171 Current
= (ULONG_PTR
)SecurityDescriptor
+ sizeof(SECURITY_DESCRIPTOR
);
173 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
175 RtlCopyMemory((PVOID
)Current
,
178 SecurityDescriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
182 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
184 RtlCopyMemory((PVOID
)Current
,
187 SecurityDescriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
191 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
193 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
;
196 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
198 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
;
201 return STATUS_SUCCESS
;
206 IopSecurityFile(PVOID ObjectBody
,
207 SECURITY_OPERATION_CODE OperationCode
,
208 SECURITY_INFORMATION SecurityInformation
,
209 PSECURITY_DESCRIPTOR SecurityDescriptor
,
212 IO_STATUS_BLOCK IoStatusBlock
;
213 PIO_STACK_LOCATION StackPtr
;
214 PFILE_OBJECT FileObject
;
218 DPRINT("IopSecurityFile() called\n");
220 FileObject
= (PFILE_OBJECT
)ObjectBody
;
222 switch (OperationCode
)
224 case SetSecurityDescriptor
:
225 DPRINT("Set security descriptor\n");
226 KeResetEvent(&FileObject
->Event
);
227 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY
,
228 FileObject
->DeviceObject
,
235 StackPtr
= IoGetNextIrpStackLocation(Irp
);
236 StackPtr
->FileObject
= FileObject
;
238 StackPtr
->Parameters
.SetSecurity
.SecurityInformation
= SecurityInformation
;
239 StackPtr
->Parameters
.SetSecurity
.SecurityDescriptor
= SecurityDescriptor
;
241 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
242 if (Status
== STATUS_PENDING
)
244 KeWaitForSingleObject(&FileObject
->Event
,
249 Status
= IoStatusBlock
.Status
;
252 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
254 Status
= STATUS_SUCCESS
;
258 case QuerySecurityDescriptor
:
259 DPRINT("Query security descriptor\n");
260 KeResetEvent(&FileObject
->Event
);
261 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY
,
262 FileObject
->DeviceObject
,
269 Irp
->UserBuffer
= SecurityDescriptor
;
271 StackPtr
= IoGetNextIrpStackLocation(Irp
);
272 StackPtr
->FileObject
= FileObject
;
274 StackPtr
->Parameters
.QuerySecurity
.SecurityInformation
= SecurityInformation
;
275 StackPtr
->Parameters
.QuerySecurity
.Length
= *BufferLength
;
277 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
278 if (Status
== STATUS_PENDING
)
280 KeWaitForSingleObject(&FileObject
->Event
,
285 Status
= IoStatusBlock
.Status
;
288 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
290 Status
= IopSetDefaultSecurityDescriptor(SecurityInformation
,
296 /* FIXME: Is this correct?? */
297 *BufferLength
= IoStatusBlock
.Information
;
301 case DeleteSecurityDescriptor
:
302 DPRINT("Delete security descriptor\n");
303 return STATUS_SUCCESS
;
305 case AssignSecurityDescriptor
:
306 DPRINT("Assign security descriptor\n");
307 return STATUS_SUCCESS
;
310 return STATUS_UNSUCCESSFUL
;
315 IopQueryNameFile(PVOID ObjectBody
,
316 POBJECT_NAME_INFORMATION ObjectNameInfo
,
320 POBJECT_NAME_INFORMATION LocalInfo
;
321 PFILE_NAME_INFORMATION FileNameInfo
;
322 PFILE_OBJECT FileObject
;
323 ULONG LocalReturnLength
;
326 DPRINT ("IopQueryNameFile() called\n");
328 FileObject
= (PFILE_OBJECT
)ObjectBody
;
330 LocalInfo
= ExAllocatePool (NonPagedPool
,
331 sizeof(OBJECT_NAME_INFORMATION
) +
332 MAX_PATH
* sizeof(WCHAR
));
333 if (LocalInfo
== NULL
)
334 return STATUS_INSUFFICIENT_RESOURCES
;
336 Status
= ObQueryNameString (FileObject
->DeviceObject
->Vpb
->RealDevice
,
338 MAX_PATH
* sizeof(WCHAR
),
340 if (!NT_SUCCESS (Status
))
342 ExFreePool (LocalInfo
);
345 DPRINT ("Device path: %wZ\n", &LocalInfo
->Name
);
347 Status
= RtlAppendUnicodeStringToString (&ObjectNameInfo
->Name
,
350 ExFreePool (LocalInfo
);
352 FileNameInfo
= ExAllocatePool (NonPagedPool
,
353 MAX_PATH
* sizeof(WCHAR
) + sizeof(ULONG
));
354 if (FileNameInfo
== NULL
)
355 return STATUS_INSUFFICIENT_RESOURCES
;
357 Status
= IoQueryFileInformation (FileObject
,
359 MAX_PATH
* sizeof(WCHAR
) + sizeof(ULONG
),
362 if (Status
!= STATUS_SUCCESS
)
364 ExFreePool (FileNameInfo
);
368 Status
= RtlAppendUnicodeToString (&ObjectNameInfo
->Name
,
369 FileNameInfo
->FileName
);
371 DPRINT ("Total path: %wZ\n", &ObjectNameInfo
->Name
);
373 ExFreePool (FileNameInfo
);
382 OBJECT_ATTRIBUTES ObjectAttributes
;
383 UNICODE_STRING DirName
;
384 UNICODE_STRING LinkName
;
387 IopInitDriverImplementation();
390 * Register iomgr types: DeviceObjectType
392 IoDeviceObjectType
= ExAllocatePool (NonPagedPool
,
393 sizeof (OBJECT_TYPE
));
395 IoDeviceObjectType
->Tag
= TAG_DEVICE_TYPE
;
396 IoDeviceObjectType
->TotalObjects
= 0;
397 IoDeviceObjectType
->TotalHandles
= 0;
398 IoDeviceObjectType
->PeakObjects
= 0;
399 IoDeviceObjectType
->PeakHandles
= 0;
400 IoDeviceObjectType
->PagedPoolCharge
= 0;
401 IoDeviceObjectType
->NonpagedPoolCharge
= sizeof (DEVICE_OBJECT
);
402 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
403 IoDeviceObjectType
->Dump
= NULL
;
404 IoDeviceObjectType
->Open
= NULL
;
405 IoDeviceObjectType
->Close
= NULL
;
406 IoDeviceObjectType
->Delete
= NULL
;
407 IoDeviceObjectType
->Parse
= NULL
;
408 IoDeviceObjectType
->Security
= NULL
;
409 IoDeviceObjectType
->QueryName
= NULL
;
410 IoDeviceObjectType
->OkayToClose
= NULL
;
411 IoDeviceObjectType
->Create
= IopCreateDevice
;
412 IoDeviceObjectType
->DuplicationNotify
= NULL
;
414 RtlRosInitUnicodeStringFromLiteral(&IoDeviceObjectType
->TypeName
, L
"Device");
416 ObpCreateTypeObject(IoDeviceObjectType
);
419 * Register iomgr types: FileObjectType
420 * (alias DriverObjectType)
422 IoFileObjectType
= ExAllocatePool (NonPagedPool
, sizeof (OBJECT_TYPE
));
424 IoFileObjectType
->Tag
= TAG_FILE_TYPE
;
425 IoFileObjectType
->TotalObjects
= 0;
426 IoFileObjectType
->TotalHandles
= 0;
427 IoFileObjectType
->PeakObjects
= 0;
428 IoFileObjectType
->PeakHandles
= 0;
429 IoFileObjectType
->PagedPoolCharge
= 0;
430 IoFileObjectType
->NonpagedPoolCharge
= sizeof(FILE_OBJECT
);
431 IoFileObjectType
->Mapping
= &IopFileMapping
;
432 IoFileObjectType
->Dump
= NULL
;
433 IoFileObjectType
->Open
= NULL
;
434 IoFileObjectType
->Close
= IopCloseFile
;
435 IoFileObjectType
->Delete
= IopDeleteFile
;
436 IoFileObjectType
->Parse
= NULL
;
437 IoFileObjectType
->Security
= IopSecurityFile
;
438 IoFileObjectType
->QueryName
= IopQueryNameFile
;
439 IoFileObjectType
->OkayToClose
= NULL
;
440 IoFileObjectType
->Create
= IopCreateFile
;
441 IoFileObjectType
->DuplicationNotify
= NULL
;
443 RtlRosInitUnicodeStringFromLiteral(&IoFileObjectType
->TypeName
, L
"File");
445 ObpCreateTypeObject(IoFileObjectType
);
448 * Register iomgr types: AdapterObjectType
450 IoAdapterObjectType
= ExAllocatePool (NonPagedPool
,
451 sizeof (OBJECT_TYPE
));
452 RtlZeroMemory(IoAdapterObjectType
, sizeof(OBJECT_TYPE
));
453 IoAdapterObjectType
->Tag
= TAG_ADAPTER_TYPE
;
454 IoAdapterObjectType
->PeakObjects
= 0;
455 IoAdapterObjectType
->PeakHandles
= 0;
456 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
457 RtlRosInitUnicodeStringFromLiteral(&IoAdapterObjectType
->TypeName
, L
"Adapter");
458 ObpCreateTypeObject(IoAdapterObjectType
);
461 * Create the '\Driver' object directory
463 RtlRosInitUnicodeStringFromLiteral(&DirName
, L
"\\Driver");
464 InitializeObjectAttributes(&ObjectAttributes
,
469 NtCreateDirectoryObject(&Handle
,
474 * Create the '\FileSystem' object directory
476 RtlRosInitUnicodeStringFromLiteral(&DirName
,
478 InitializeObjectAttributes(&ObjectAttributes
,
483 NtCreateDirectoryObject(&Handle
,
488 * Create the '\Device' directory
490 RtlRosInitUnicodeStringFromLiteral(&DirName
,
492 InitializeObjectAttributes(&ObjectAttributes
,
497 ZwCreateDirectoryObject(&Handle
,
502 * Create the '\??' directory
504 RtlRosInitUnicodeStringFromLiteral(&DirName
,
506 InitializeObjectAttributes(&ObjectAttributes
,
511 ZwCreateDirectoryObject(&Handle
,
516 * Create the '\ArcName' directory
518 RtlRosInitUnicodeStringFromLiteral(&DirName
,
520 InitializeObjectAttributes(&ObjectAttributes
,
525 ZwCreateDirectoryObject(&Handle
,
530 * Initialize remaining subsubsystem
532 IoInitCancelHandling();
533 IoInitFileSystemImplementation();
534 IoInitVpbImplementation();
535 IoInitShutdownNotification();
537 IopInitTimerImplementation();
538 IopInitIoCompletionImplementation();
541 * Create link from '\DosDevices' to '\??' directory
543 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
545 RtlRosInitUnicodeStringFromLiteral(&DirName
,
547 IoCreateSymbolicLink(&LinkName
,
551 * Initialize PnP manager
560 PDEVICE_NODE DeviceNode
;
561 PDRIVER_OBJECT DriverObject
;
562 MODULE_OBJECT ModuleObject
;
565 KeInitializeSpinLock (&IoStatisticsLock
);
567 /* Initialize raw filesystem driver */
569 /* Use IopRootDeviceNode for now */
570 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
573 if (!NT_SUCCESS(Status
))
575 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
579 ModuleObject
.Base
= NULL
;
580 ModuleObject
.Length
= 0;
581 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
583 Status
= IopInitializeDriverModule(
588 if (!NT_SUCCESS(Status
))
590 IopFreeDeviceNode(DeviceNode
);
591 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
595 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
596 if (!NT_SUCCESS(Status
))
598 IopFreeDeviceNode(DeviceNode
);
599 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
604 * Initialize PnP root releations
606 IopInvalidateDeviceRelations(
614 PGENERIC_MAPPING STDCALL
615 IoGetFileObjectGenericMapping(VOID
)
617 return(&IopFileMapping
);