Standardize comment headers. Patch by Trevor McCort
[reactos.git] / reactos / ntoskrnl / io / iomgr.c
1 /* $Id$
2 *
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 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES ****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* GLOBALS *******************************************************************/
18
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')
22
23 /* DATA ********************************************************************/
24
25
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;
35
36 static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
37 FILE_GENERIC_WRITE,
38 FILE_GENERIC_EXECUTE,
39 FILE_ALL_ACCESS};
40
41 /* FUNCTIONS ****************************************************************/
42
43 VOID STDCALL
44 IopCloseFile(PVOID ObjectBody,
45 ULONG HandleCount)
46 {
47 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
48 PIRP Irp;
49 PIO_STACK_LOCATION StackPtr;
50 NTSTATUS Status;
51
52 DPRINT("IopCloseFile()\n");
53
54 if (HandleCount > 0 || FileObject->DeviceObject == NULL)
55 {
56 return;
57 }
58
59 #if 0
60 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
61 ObReferenceObjectByPointer(FileObject,
62 STANDARD_RIGHTS_REQUIRED,
63 IoFileObjectType,
64 UserMode);
65 #endif
66
67 KeResetEvent( &FileObject->Event );
68
69 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
70 FileObject->DeviceObject,
71 NULL,
72 0,
73 NULL,
74 &FileObject->Event,
75 NULL);
76 StackPtr = IoGetNextIrpStackLocation(Irp);
77 StackPtr->FileObject = FileObject;
78
79 Status = IoCallDriver(FileObject->DeviceObject, Irp);
80 if (Status == STATUS_PENDING)
81 {
82 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
83 }
84 }
85
86
87 VOID STDCALL
88 IopDeleteFile(PVOID ObjectBody)
89 {
90 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
91 PIRP Irp;
92 PIO_STACK_LOCATION StackPtr;
93 NTSTATUS Status;
94
95 DPRINT("IopDeleteFile()\n");
96
97 if (FileObject->DeviceObject)
98 {
99 #if 0
100 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
101
102 ObReferenceObjectByPointer(ObjectBody,
103 STANDARD_RIGHTS_REQUIRED,
104 IoFileObjectType,
105 UserMode);
106 #endif
107 KeResetEvent( &FileObject->Event );
108 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
109 FileObject->DeviceObject,
110 NULL,
111 0,
112 NULL,
113 &FileObject->Event,
114 NULL);
115 Irp->Flags |= IRP_CLOSE_OPERATION;
116 StackPtr = IoGetNextIrpStackLocation(Irp);
117 StackPtr->FileObject = FileObject;
118
119 Status = IoCallDriver(FileObject->DeviceObject, Irp);
120 if (Status == STATUS_PENDING)
121 {
122 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
123 }
124 }
125
126 if (FileObject->FileName.Buffer != NULL)
127 {
128 ExFreePool(FileObject->FileName.Buffer);
129 FileObject->FileName.Buffer = 0;
130 }
131 }
132
133
134 static NTSTATUS
135 IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
136 PSECURITY_DESCRIPTOR SecurityDescriptor,
137 PULONG BufferLength)
138 {
139 ULONG_PTR Current;
140 ULONG SidSize;
141 ULONG SdSize;
142 NTSTATUS Status;
143
144 DPRINT("IopSetDefaultSecurityDescriptor() called\n");
145
146 if (SecurityInformation == 0)
147 {
148 return STATUS_ACCESS_DENIED;
149 }
150
151 SidSize = RtlLengthSid(SeWorldSid);
152 SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
153
154 if (*BufferLength < SdSize)
155 {
156 *BufferLength = SdSize;
157 return STATUS_BUFFER_TOO_SMALL;
158 }
159
160 *BufferLength = SdSize;
161
162 Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
163 SECURITY_DESCRIPTOR_REVISION);
164 if (!NT_SUCCESS(Status))
165 {
166 return Status;
167 }
168
169 SecurityDescriptor->Control |= SE_SELF_RELATIVE;
170 Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
171
172 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
173 {
174 RtlCopyMemory((PVOID)Current,
175 SeWorldSid,
176 SidSize);
177 SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
178 Current += SidSize;
179 }
180
181 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
182 {
183 RtlCopyMemory((PVOID)Current,
184 SeWorldSid,
185 SidSize);
186 SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
187 Current += SidSize;
188 }
189
190 if (SecurityInformation & DACL_SECURITY_INFORMATION)
191 {
192 SecurityDescriptor->Control |= SE_DACL_PRESENT;
193 }
194
195 if (SecurityInformation & SACL_SECURITY_INFORMATION)
196 {
197 SecurityDescriptor->Control |= SE_SACL_PRESENT;
198 }
199
200 return STATUS_SUCCESS;
201 }
202
203
204 NTSTATUS STDCALL
205 IopSecurityFile(PVOID ObjectBody,
206 SECURITY_OPERATION_CODE OperationCode,
207 SECURITY_INFORMATION SecurityInformation,
208 PSECURITY_DESCRIPTOR SecurityDescriptor,
209 PULONG BufferLength)
210 {
211 IO_STATUS_BLOCK IoStatusBlock;
212 PIO_STACK_LOCATION StackPtr;
213 PFILE_OBJECT FileObject;
214 PIRP Irp;
215 NTSTATUS Status;
216
217 DPRINT("IopSecurityFile() called\n");
218
219 FileObject = (PFILE_OBJECT)ObjectBody;
220
221 switch (OperationCode)
222 {
223 case SetSecurityDescriptor:
224 DPRINT("Set security descriptor\n");
225 KeResetEvent(&FileObject->Event);
226 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY,
227 FileObject->DeviceObject,
228 NULL,
229 0,
230 NULL,
231 &FileObject->Event,
232 &IoStatusBlock);
233
234 StackPtr = IoGetNextIrpStackLocation(Irp);
235 StackPtr->FileObject = FileObject;
236
237 StackPtr->Parameters.SetSecurity.SecurityInformation = SecurityInformation;
238 StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
239
240 Status = IoCallDriver(FileObject->DeviceObject, Irp);
241 if (Status == STATUS_PENDING)
242 {
243 KeWaitForSingleObject(&FileObject->Event,
244 Executive,
245 KernelMode,
246 FALSE,
247 NULL);
248 Status = IoStatusBlock.Status;
249 }
250
251 if (Status == STATUS_INVALID_DEVICE_REQUEST)
252 {
253 Status = STATUS_SUCCESS;
254 }
255 return Status;
256
257 case QuerySecurityDescriptor:
258 DPRINT("Query security descriptor\n");
259 KeResetEvent(&FileObject->Event);
260 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY,
261 FileObject->DeviceObject,
262 NULL,
263 0,
264 NULL,
265 &FileObject->Event,
266 &IoStatusBlock);
267
268 Irp->UserBuffer = SecurityDescriptor;
269
270 StackPtr = IoGetNextIrpStackLocation(Irp);
271 StackPtr->FileObject = FileObject;
272
273 StackPtr->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
274 StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
275
276 Status = IoCallDriver(FileObject->DeviceObject, Irp);
277 if (Status == STATUS_PENDING)
278 {
279 KeWaitForSingleObject(&FileObject->Event,
280 Executive,
281 KernelMode,
282 FALSE,
283 NULL);
284 Status = IoStatusBlock.Status;
285 }
286
287 if (Status == STATUS_INVALID_DEVICE_REQUEST)
288 {
289 Status = IopSetDefaultSecurityDescriptor(SecurityInformation,
290 SecurityDescriptor,
291 BufferLength);
292 }
293 else
294 {
295 /* FIXME: Is this correct?? */
296 *BufferLength = IoStatusBlock.Information;
297 }
298 return Status;
299
300 case DeleteSecurityDescriptor:
301 DPRINT("Delete security descriptor\n");
302 return STATUS_SUCCESS;
303
304 case AssignSecurityDescriptor:
305 DPRINT("Assign security descriptor\n");
306 return STATUS_SUCCESS;
307 }
308
309 return STATUS_UNSUCCESSFUL;
310 }
311
312
313 NTSTATUS STDCALL
314 IopQueryNameFile(PVOID ObjectBody,
315 POBJECT_NAME_INFORMATION ObjectNameInfo,
316 ULONG Length,
317 PULONG ReturnLength)
318 {
319 POBJECT_NAME_INFORMATION LocalInfo;
320 PFILE_NAME_INFORMATION FileNameInfo;
321 PFILE_OBJECT FileObject;
322 ULONG LocalReturnLength;
323 NTSTATUS Status;
324
325 DPRINT ("IopQueryNameFile() called\n");
326
327 FileObject = (PFILE_OBJECT)ObjectBody;
328
329 LocalInfo = ExAllocatePool (NonPagedPool,
330 sizeof(OBJECT_NAME_INFORMATION) +
331 MAX_PATH * sizeof(WCHAR));
332 if (LocalInfo == NULL)
333 return STATUS_INSUFFICIENT_RESOURCES;
334
335 Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
336 LocalInfo,
337 MAX_PATH * sizeof(WCHAR),
338 &LocalReturnLength);
339 if (!NT_SUCCESS (Status))
340 {
341 ExFreePool (LocalInfo);
342 return Status;
343 }
344 DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
345
346 Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
347 &LocalInfo->Name);
348
349 ExFreePool (LocalInfo);
350
351 FileNameInfo = ExAllocatePool (NonPagedPool,
352 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
353 if (FileNameInfo == NULL)
354 return STATUS_INSUFFICIENT_RESOURCES;
355
356 Status = IoQueryFileInformation (FileObject,
357 FileNameInformation,
358 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
359 FileNameInfo,
360 NULL);
361 if (Status != STATUS_SUCCESS)
362 {
363 ExFreePool (FileNameInfo);
364 return Status;
365 }
366
367 Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
368 FileNameInfo->FileName);
369
370 DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
371
372 ExFreePool (FileNameInfo);
373
374 return Status;
375 }
376
377
378 VOID INIT_FUNCTION
379 IoInit (VOID)
380 {
381 OBJECT_ATTRIBUTES ObjectAttributes;
382 UNICODE_STRING DirName;
383 UNICODE_STRING LinkName;
384 HANDLE Handle;
385
386 IopInitDriverImplementation();
387
388 /*
389 * Register iomgr types: DeviceObjectType
390 */
391 IoDeviceObjectType = ExAllocatePool (NonPagedPool,
392 sizeof (OBJECT_TYPE));
393
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;
412
413 RtlRosInitUnicodeStringFromLiteral(&IoDeviceObjectType->TypeName, L"Device");
414
415 ObpCreateTypeObject(IoDeviceObjectType);
416
417 /*
418 * Register iomgr types: FileObjectType
419 * (alias DriverObjectType)
420 */
421 IoFileObjectType = ExAllocatePool (NonPagedPool, sizeof (OBJECT_TYPE));
422
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;
441
442 RtlRosInitUnicodeStringFromLiteral(&IoFileObjectType->TypeName, L"File");
443
444 ObpCreateTypeObject(IoFileObjectType);
445
446 /*
447 * Register iomgr types: AdapterObjectType
448 */
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);
458
459 /*
460 * Create the '\Driver' object directory
461 */
462 RtlRosInitUnicodeStringFromLiteral(&DirName, L"\\Driver");
463 InitializeObjectAttributes(&ObjectAttributes,
464 &DirName,
465 0,
466 NULL,
467 NULL);
468 NtCreateDirectoryObject(&Handle,
469 0,
470 &ObjectAttributes);
471
472 /*
473 * Create the '\FileSystem' object directory
474 */
475 RtlRosInitUnicodeStringFromLiteral(&DirName,
476 L"\\FileSystem");
477 InitializeObjectAttributes(&ObjectAttributes,
478 &DirName,
479 0,
480 NULL,
481 NULL);
482 NtCreateDirectoryObject(&Handle,
483 0,
484 &ObjectAttributes);
485
486 /*
487 * Create the '\Device' directory
488 */
489 RtlRosInitUnicodeStringFromLiteral(&DirName,
490 L"\\Device");
491 InitializeObjectAttributes(&ObjectAttributes,
492 &DirName,
493 0,
494 NULL,
495 NULL);
496 ZwCreateDirectoryObject(&Handle,
497 0,
498 &ObjectAttributes);
499
500 /*
501 * Create the '\??' directory
502 */
503 RtlRosInitUnicodeStringFromLiteral(&DirName,
504 L"\\??");
505 InitializeObjectAttributes(&ObjectAttributes,
506 &DirName,
507 0,
508 NULL,
509 NULL);
510 ZwCreateDirectoryObject(&Handle,
511 0,
512 &ObjectAttributes);
513
514 /*
515 * Create the '\ArcName' directory
516 */
517 RtlRosInitUnicodeStringFromLiteral(&DirName,
518 L"\\ArcName");
519 InitializeObjectAttributes(&ObjectAttributes,
520 &DirName,
521 0,
522 NULL,
523 NULL);
524 ZwCreateDirectoryObject(&Handle,
525 0,
526 &ObjectAttributes);
527
528 /*
529 * Initialize remaining subsubsystem
530 */
531 IoInitCancelHandling();
532 IoInitFileSystemImplementation();
533 IoInitVpbImplementation();
534 IoInitShutdownNotification();
535 IopInitErrorLog();
536 IopInitTimerImplementation();
537 IopInitIoCompletionImplementation();
538
539 /*
540 * Create link from '\DosDevices' to '\??' directory
541 */
542 RtlRosInitUnicodeStringFromLiteral(&LinkName,
543 L"\\DosDevices");
544 RtlRosInitUnicodeStringFromLiteral(&DirName,
545 L"\\??");
546 IoCreateSymbolicLink(&LinkName,
547 &DirName);
548
549 /*
550 * Initialize PnP manager
551 */
552 PnpInit();
553 }
554
555
556 VOID INIT_FUNCTION
557 IoInit2(VOID)
558 {
559 PDEVICE_NODE DeviceNode;
560 PDRIVER_OBJECT DriverObject;
561 MODULE_OBJECT ModuleObject;
562 NTSTATUS Status;
563
564 KeInitializeSpinLock (&IoStatisticsLock);
565
566 /* Initialize raw filesystem driver */
567
568 /* Use IopRootDeviceNode for now */
569 Status = IopCreateDeviceNode(IopRootDeviceNode,
570 NULL,
571 &DeviceNode);
572 if (!NT_SUCCESS(Status))
573 {
574 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status);
575 return;
576 }
577
578 ModuleObject.Base = NULL;
579 ModuleObject.Length = 0;
580 ModuleObject.EntryPoint = RawFsDriverEntry;
581
582 Status = IopInitializeDriverModule(
583 DeviceNode,
584 &ModuleObject,
585 TRUE,
586 &DriverObject);
587 if (!NT_SUCCESS(Status))
588 {
589 IopFreeDeviceNode(DeviceNode);
590 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status);
591 return;
592 }
593
594 Status = IopInitializeDevice(DeviceNode, DriverObject);
595 if (!NT_SUCCESS(Status))
596 {
597 IopFreeDeviceNode(DeviceNode);
598 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
599 return;
600 }
601
602 /*
603 * Initialize PnP root releations
604 */
605 IopInvalidateDeviceRelations(
606 IopRootDeviceNode,
607 BusRelations);
608 }
609
610 /*
611 * @implemented
612 */
613 PGENERIC_MAPPING STDCALL
614 IoGetFileObjectGenericMapping(VOID)
615 {
616 return(&IopFileMapping);
617 }
618
619 /* EOF */