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 ****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 #define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
20 #define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
21 #define TAG_ADAPTER_TYPE TAG('A', 'D', 'P', 'T')
23 /* DATA ********************************************************************/
26 POBJECT_TYPE EXPORTED IoDeviceObjectType
= NULL
;
27 POBJECT_TYPE EXPORTED IoFileObjectType
= NULL
;
28 ULONG EXPORTED IoReadOperationCount
= 0;
29 ULONGLONG EXPORTED IoReadTransferCount
= 0;
30 ULONG EXPORTED IoWriteOperationCount
= 0;
31 ULONGLONG EXPORTED IoWriteTransferCount
= 0;
32 ULONG IoOtherOperationCount
= 0;
33 ULONGLONG IoOtherTransferCount
= 0;
34 KSPIN_LOCK EXPORTED IoStatisticsLock
= 0;
36 static GENERIC_MAPPING IopFileMapping
= {FILE_GENERIC_READ
,
41 /* FUNCTIONS ****************************************************************/
44 IopCloseFile(PVOID ObjectBody
,
47 PFILE_OBJECT FileObject
= (PFILE_OBJECT
)ObjectBody
;
49 PIO_STACK_LOCATION StackPtr
;
52 DPRINT("IopCloseFile()\n");
54 if (HandleCount
> 0 || FileObject
->DeviceObject
== NULL
)
60 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
61 ObReferenceObjectByPointer(FileObject
,
62 STANDARD_RIGHTS_REQUIRED
,
67 KeResetEvent( &FileObject
->Event
);
69 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP
,
70 FileObject
->DeviceObject
,
76 StackPtr
= IoGetNextIrpStackLocation(Irp
);
77 StackPtr
->FileObject
= FileObject
;
79 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
80 if (Status
== STATUS_PENDING
)
82 KeWaitForSingleObject(&FileObject
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
88 IopDeleteFile(PVOID ObjectBody
)
90 PFILE_OBJECT FileObject
= (PFILE_OBJECT
)ObjectBody
;
92 PIO_STACK_LOCATION StackPtr
;
95 DPRINT("IopDeleteFile()\n");
97 if (FileObject
->DeviceObject
)
100 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
102 ObReferenceObjectByPointer(ObjectBody
,
103 STANDARD_RIGHTS_REQUIRED
,
107 KeResetEvent( &FileObject
->Event
);
108 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE
,
109 FileObject
->DeviceObject
,
115 Irp
->Flags
|= IRP_CLOSE_OPERATION
;
116 StackPtr
= IoGetNextIrpStackLocation(Irp
);
117 StackPtr
->FileObject
= FileObject
;
119 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
120 if (Status
== STATUS_PENDING
)
122 KeWaitForSingleObject(&FileObject
->Event
, Executive
, KernelMode
, FALSE
, NULL
);
126 if (FileObject
->FileName
.Buffer
!= NULL
)
128 ExFreePool(FileObject
->FileName
.Buffer
);
129 FileObject
->FileName
.Buffer
= 0;
135 IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation
,
136 PSECURITY_DESCRIPTOR SecurityDescriptor
,
144 DPRINT("IopSetDefaultSecurityDescriptor() called\n");
146 if (SecurityInformation
== 0)
148 return STATUS_ACCESS_DENIED
;
151 SidSize
= RtlLengthSid(SeWorldSid
);
152 SdSize
= sizeof(SECURITY_DESCRIPTOR
) + (2 * SidSize
);
154 if (*BufferLength
< SdSize
)
156 *BufferLength
= SdSize
;
157 return STATUS_BUFFER_TOO_SMALL
;
160 *BufferLength
= SdSize
;
162 Status
= RtlCreateSecurityDescriptor(SecurityDescriptor
,
163 SECURITY_DESCRIPTOR_REVISION
);
164 if (!NT_SUCCESS(Status
))
169 SecurityDescriptor
->Control
|= SE_SELF_RELATIVE
;
170 Current
= (ULONG_PTR
)SecurityDescriptor
+ sizeof(SECURITY_DESCRIPTOR
);
172 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
174 RtlCopyMemory((PVOID
)Current
,
177 SecurityDescriptor
->Owner
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
181 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
183 RtlCopyMemory((PVOID
)Current
,
186 SecurityDescriptor
->Group
= (PSID
)((ULONG_PTR
)Current
- (ULONG_PTR
)SecurityDescriptor
);
190 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
192 SecurityDescriptor
->Control
|= SE_DACL_PRESENT
;
195 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
197 SecurityDescriptor
->Control
|= SE_SACL_PRESENT
;
200 return STATUS_SUCCESS
;
205 IopSecurityFile(PVOID ObjectBody
,
206 SECURITY_OPERATION_CODE OperationCode
,
207 SECURITY_INFORMATION SecurityInformation
,
208 PSECURITY_DESCRIPTOR SecurityDescriptor
,
211 IO_STATUS_BLOCK IoStatusBlock
;
212 PIO_STACK_LOCATION StackPtr
;
213 PFILE_OBJECT FileObject
;
217 DPRINT("IopSecurityFile() called\n");
219 FileObject
= (PFILE_OBJECT
)ObjectBody
;
221 switch (OperationCode
)
223 case SetSecurityDescriptor
:
224 DPRINT("Set security descriptor\n");
225 KeResetEvent(&FileObject
->Event
);
226 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY
,
227 FileObject
->DeviceObject
,
234 StackPtr
= IoGetNextIrpStackLocation(Irp
);
235 StackPtr
->FileObject
= FileObject
;
237 StackPtr
->Parameters
.SetSecurity
.SecurityInformation
= SecurityInformation
;
238 StackPtr
->Parameters
.SetSecurity
.SecurityDescriptor
= SecurityDescriptor
;
240 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
241 if (Status
== STATUS_PENDING
)
243 KeWaitForSingleObject(&FileObject
->Event
,
248 Status
= IoStatusBlock
.Status
;
251 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
253 Status
= STATUS_SUCCESS
;
257 case QuerySecurityDescriptor
:
258 DPRINT("Query security descriptor\n");
259 KeResetEvent(&FileObject
->Event
);
260 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY
,
261 FileObject
->DeviceObject
,
268 Irp
->UserBuffer
= SecurityDescriptor
;
270 StackPtr
= IoGetNextIrpStackLocation(Irp
);
271 StackPtr
->FileObject
= FileObject
;
273 StackPtr
->Parameters
.QuerySecurity
.SecurityInformation
= SecurityInformation
;
274 StackPtr
->Parameters
.QuerySecurity
.Length
= *BufferLength
;
276 Status
= IoCallDriver(FileObject
->DeviceObject
, Irp
);
277 if (Status
== STATUS_PENDING
)
279 KeWaitForSingleObject(&FileObject
->Event
,
284 Status
= IoStatusBlock
.Status
;
287 if (Status
== STATUS_INVALID_DEVICE_REQUEST
)
289 Status
= IopSetDefaultSecurityDescriptor(SecurityInformation
,
295 /* FIXME: Is this correct?? */
296 *BufferLength
= IoStatusBlock
.Information
;
300 case DeleteSecurityDescriptor
:
301 DPRINT("Delete security descriptor\n");
302 return STATUS_SUCCESS
;
304 case AssignSecurityDescriptor
:
305 DPRINT("Assign security descriptor\n");
306 return STATUS_SUCCESS
;
309 return STATUS_UNSUCCESSFUL
;
314 IopQueryNameFile(PVOID ObjectBody
,
315 POBJECT_NAME_INFORMATION ObjectNameInfo
,
319 POBJECT_NAME_INFORMATION LocalInfo
;
320 PFILE_NAME_INFORMATION FileNameInfo
;
321 PFILE_OBJECT FileObject
;
322 ULONG LocalReturnLength
;
325 DPRINT ("IopQueryNameFile() called\n");
327 FileObject
= (PFILE_OBJECT
)ObjectBody
;
329 LocalInfo
= ExAllocatePool (NonPagedPool
,
330 sizeof(OBJECT_NAME_INFORMATION
) +
331 MAX_PATH
* sizeof(WCHAR
));
332 if (LocalInfo
== NULL
)
333 return STATUS_INSUFFICIENT_RESOURCES
;
335 Status
= ObQueryNameString (FileObject
->DeviceObject
->Vpb
->RealDevice
,
337 MAX_PATH
* sizeof(WCHAR
),
339 if (!NT_SUCCESS (Status
))
341 ExFreePool (LocalInfo
);
344 DPRINT ("Device path: %wZ\n", &LocalInfo
->Name
);
346 Status
= RtlAppendUnicodeStringToString (&ObjectNameInfo
->Name
,
349 ExFreePool (LocalInfo
);
351 FileNameInfo
= ExAllocatePool (NonPagedPool
,
352 MAX_PATH
* sizeof(WCHAR
) + sizeof(ULONG
));
353 if (FileNameInfo
== NULL
)
354 return STATUS_INSUFFICIENT_RESOURCES
;
356 Status
= IoQueryFileInformation (FileObject
,
358 MAX_PATH
* sizeof(WCHAR
) + sizeof(ULONG
),
361 if (Status
!= STATUS_SUCCESS
)
363 ExFreePool (FileNameInfo
);
367 Status
= RtlAppendUnicodeToString (&ObjectNameInfo
->Name
,
368 FileNameInfo
->FileName
);
370 DPRINT ("Total path: %wZ\n", &ObjectNameInfo
->Name
);
372 ExFreePool (FileNameInfo
);
381 OBJECT_ATTRIBUTES ObjectAttributes
;
382 UNICODE_STRING DirName
;
383 UNICODE_STRING LinkName
;
386 IopInitDriverImplementation();
389 * Register iomgr types: DeviceObjectType
391 IoDeviceObjectType
= ExAllocatePool (NonPagedPool
,
392 sizeof (OBJECT_TYPE
));
394 IoDeviceObjectType
->Tag
= TAG_DEVICE_TYPE
;
395 IoDeviceObjectType
->TotalObjects
= 0;
396 IoDeviceObjectType
->TotalHandles
= 0;
397 IoDeviceObjectType
->PeakObjects
= 0;
398 IoDeviceObjectType
->PeakHandles
= 0;
399 IoDeviceObjectType
->PagedPoolCharge
= 0;
400 IoDeviceObjectType
->NonpagedPoolCharge
= sizeof (DEVICE_OBJECT
);
401 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
402 IoDeviceObjectType
->Dump
= NULL
;
403 IoDeviceObjectType
->Open
= NULL
;
404 IoDeviceObjectType
->Close
= NULL
;
405 IoDeviceObjectType
->Delete
= NULL
;
406 IoDeviceObjectType
->Parse
= NULL
;
407 IoDeviceObjectType
->Security
= NULL
;
408 IoDeviceObjectType
->QueryName
= NULL
;
409 IoDeviceObjectType
->OkayToClose
= NULL
;
410 IoDeviceObjectType
->Create
= IopCreateDevice
;
411 IoDeviceObjectType
->DuplicationNotify
= NULL
;
413 RtlRosInitUnicodeStringFromLiteral(&IoDeviceObjectType
->TypeName
, L
"Device");
415 ObpCreateTypeObject(IoDeviceObjectType
);
418 * Register iomgr types: FileObjectType
419 * (alias DriverObjectType)
421 IoFileObjectType
= ExAllocatePool (NonPagedPool
, sizeof (OBJECT_TYPE
));
423 IoFileObjectType
->Tag
= TAG_FILE_TYPE
;
424 IoFileObjectType
->TotalObjects
= 0;
425 IoFileObjectType
->TotalHandles
= 0;
426 IoFileObjectType
->PeakObjects
= 0;
427 IoFileObjectType
->PeakHandles
= 0;
428 IoFileObjectType
->PagedPoolCharge
= 0;
429 IoFileObjectType
->NonpagedPoolCharge
= sizeof(FILE_OBJECT
);
430 IoFileObjectType
->Mapping
= &IopFileMapping
;
431 IoFileObjectType
->Dump
= NULL
;
432 IoFileObjectType
->Open
= NULL
;
433 IoFileObjectType
->Close
= IopCloseFile
;
434 IoFileObjectType
->Delete
= IopDeleteFile
;
435 IoFileObjectType
->Parse
= NULL
;
436 IoFileObjectType
->Security
= IopSecurityFile
;
437 IoFileObjectType
->QueryName
= IopQueryNameFile
;
438 IoFileObjectType
->OkayToClose
= NULL
;
439 IoFileObjectType
->Create
= IopCreateFile
;
440 IoFileObjectType
->DuplicationNotify
= NULL
;
442 RtlRosInitUnicodeStringFromLiteral(&IoFileObjectType
->TypeName
, L
"File");
444 ObpCreateTypeObject(IoFileObjectType
);
447 * Register iomgr types: AdapterObjectType
449 IoAdapterObjectType
= ExAllocatePool (NonPagedPool
,
450 sizeof (OBJECT_TYPE
));
451 RtlZeroMemory(IoAdapterObjectType
, sizeof(OBJECT_TYPE
));
452 IoAdapterObjectType
->Tag
= TAG_ADAPTER_TYPE
;
453 IoAdapterObjectType
->PeakObjects
= 0;
454 IoAdapterObjectType
->PeakHandles
= 0;
455 IoDeviceObjectType
->Mapping
= &IopFileMapping
;
456 RtlRosInitUnicodeStringFromLiteral(&IoAdapterObjectType
->TypeName
, L
"Adapter");
457 ObpCreateTypeObject(IoAdapterObjectType
);
460 * Create the '\Driver' object directory
462 RtlRosInitUnicodeStringFromLiteral(&DirName
, L
"\\Driver");
463 InitializeObjectAttributes(&ObjectAttributes
,
468 ZwCreateDirectoryObject(&Handle
,
473 * Create the '\FileSystem' object directory
475 RtlRosInitUnicodeStringFromLiteral(&DirName
,
477 InitializeObjectAttributes(&ObjectAttributes
,
482 ZwCreateDirectoryObject(&Handle
,
487 * Create the '\Device' directory
489 RtlRosInitUnicodeStringFromLiteral(&DirName
,
491 InitializeObjectAttributes(&ObjectAttributes
,
496 ZwCreateDirectoryObject(&Handle
,
501 * Create the '\??' directory
503 RtlRosInitUnicodeStringFromLiteral(&DirName
,
505 InitializeObjectAttributes(&ObjectAttributes
,
510 ZwCreateDirectoryObject(&Handle
,
515 * Create the '\ArcName' directory
517 RtlRosInitUnicodeStringFromLiteral(&DirName
,
519 InitializeObjectAttributes(&ObjectAttributes
,
524 ZwCreateDirectoryObject(&Handle
,
529 * Initialize remaining subsubsystem
531 IoInitCancelHandling();
532 IoInitFileSystemImplementation();
533 IoInitVpbImplementation();
534 IoInitShutdownNotification();
536 IopInitTimerImplementation();
537 IopInitIoCompletionImplementation();
540 * Create link from '\DosDevices' to '\??' directory
542 RtlRosInitUnicodeStringFromLiteral(&LinkName
,
544 RtlRosInitUnicodeStringFromLiteral(&DirName
,
546 IoCreateSymbolicLink(&LinkName
,
550 * Initialize PnP manager
559 PDEVICE_NODE DeviceNode
;
560 PDRIVER_OBJECT DriverObject
;
561 MODULE_OBJECT ModuleObject
;
564 KeInitializeSpinLock (&IoStatisticsLock
);
566 /* Initialize raw filesystem driver */
568 /* Use IopRootDeviceNode for now */
569 Status
= IopCreateDeviceNode(IopRootDeviceNode
,
572 if (!NT_SUCCESS(Status
))
574 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status
);
578 ModuleObject
.Base
= NULL
;
579 ModuleObject
.Length
= 0;
580 ModuleObject
.EntryPoint
= RawFsDriverEntry
;
582 Status
= IopInitializeDriverModule(
587 if (!NT_SUCCESS(Status
))
589 IopFreeDeviceNode(DeviceNode
);
590 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status
);
594 Status
= IopInitializeDevice(DeviceNode
, DriverObject
);
595 if (!NT_SUCCESS(Status
))
597 IopFreeDeviceNode(DeviceNode
);
598 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status
);
603 * Initialize PnP root releations
605 IopInvalidateDeviceRelations(
613 PGENERIC_MAPPING STDCALL
614 IoGetFileObjectGenericMapping(VOID
)
616 return(&IopFileMapping
);