- Add security function for file and registry key objects.
[reactos.git] / reactos / ntoskrnl / io / iomgr.c
1 /* $Id: iomgr.c,v 1.49 2004/07/22 18:36:35 ekohl Exp $
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 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * REVISION HISTORY:
9 * 29/07/98: Created
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <limits.h>
15 #include <ddk/ntddk.h>
16 #include <internal/ob.h>
17 #include <internal/io.h>
18 #include <internal/pool.h>
19 #include <internal/module.h>
20 #include <rosrtl/string.h>
21
22 #define NDEBUG
23 #include <internal/debug.h>
24
25 /* GLOBALS *******************************************************************/
26
27 #define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
28 #define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
29
30 /* DATA ********************************************************************/
31
32
33 POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
34 POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
35 ULONG EXPORTED IoReadOperationCount = 0;
36 ULONGLONG EXPORTED IoReadTransferCount = 0;
37 ULONG EXPORTED IoWriteOperationCount = 0;
38 ULONGLONG EXPORTED IoWriteTransferCount = 0;
39 ULONG IoOtherOperationCount = 0;
40 ULONGLONG IoOtherTransferCount = 0;
41 KSPIN_LOCK EXPORTED IoStatisticsLock = 0;
42
43 static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
44 FILE_GENERIC_WRITE,
45 FILE_GENERIC_EXECUTE,
46 FILE_ALL_ACCESS};
47
48 /* FUNCTIONS ****************************************************************/
49
50 VOID STDCALL
51 IopCloseFile(PVOID ObjectBody,
52 ULONG HandleCount)
53 {
54 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
55 PIRP Irp;
56 PIO_STACK_LOCATION StackPtr;
57 NTSTATUS Status;
58
59 DPRINT("IopCloseFile()\n");
60
61 if (HandleCount > 0 || FileObject->DeviceObject == NULL)
62 {
63 return;
64 }
65
66 #if 0
67 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
68 ObReferenceObjectByPointer(FileObject,
69 STANDARD_RIGHTS_REQUIRED,
70 IoFileObjectType,
71 UserMode);
72 #endif
73
74 KeResetEvent( &FileObject->Event );
75
76 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
77 FileObject->DeviceObject,
78 NULL,
79 0,
80 NULL,
81 &FileObject->Event,
82 NULL);
83 StackPtr = IoGetNextIrpStackLocation(Irp);
84 StackPtr->FileObject = FileObject;
85
86 Status = IoCallDriver(FileObject->DeviceObject, Irp);
87 if (Status == STATUS_PENDING)
88 {
89 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
90 }
91 }
92
93
94 VOID STDCALL
95 IopDeleteFile(PVOID ObjectBody)
96 {
97 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
98 PIRP Irp;
99 PIO_STACK_LOCATION StackPtr;
100 NTSTATUS Status;
101
102 DPRINT("IopDeleteFile()\n");
103
104 if (FileObject->DeviceObject)
105 {
106 #if 0
107 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
108
109 ObReferenceObjectByPointer(ObjectBody,
110 STANDARD_RIGHTS_REQUIRED,
111 IoFileObjectType,
112 UserMode);
113 #endif
114 KeResetEvent( &FileObject->Event );
115 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
116 FileObject->DeviceObject,
117 NULL,
118 0,
119 NULL,
120 &FileObject->Event,
121 NULL);
122 Irp->Flags |= IRP_CLOSE_OPERATION;
123 StackPtr = IoGetNextIrpStackLocation(Irp);
124 StackPtr->FileObject = FileObject;
125
126 Status = IoCallDriver(FileObject->DeviceObject, Irp);
127 if (Status == STATUS_PENDING)
128 {
129 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
130 }
131 }
132
133 if (FileObject->FileName.Buffer != NULL)
134 {
135 ExFreePool(FileObject->FileName.Buffer);
136 FileObject->FileName.Buffer = 0;
137 }
138 }
139
140
141 NTSTATUS STDCALL
142 IopSecurityFile(PVOID ObjectBody,
143 SECURITY_OPERATION_CODE OperationCode,
144 SECURITY_INFORMATION SecurityInformation,
145 PSECURITY_DESCRIPTOR SecurityDescriptor,
146 PULONG BufferLength)
147 {
148 DPRINT("IopSecurityFile() called\n");
149
150 switch (OperationCode)
151 {
152 case SetSecurityDescriptor:
153 DPRINT("Set security descriptor\n");
154 return STATUS_SUCCESS;
155
156 case QuerySecurityDescriptor:
157 DPRINT("Query security descriptor\n");
158 return STATUS_UNSUCCESSFUL;
159
160 case DeleteSecurityDescriptor:
161 DPRINT("Delete security descriptor\n");
162 return STATUS_SUCCESS;
163
164 case AssignSecurityDescriptor:
165 DPRINT("Assign security descriptor\n");
166 return STATUS_SUCCESS;
167 }
168
169 return STATUS_UNSUCCESSFUL;
170 }
171
172
173 NTSTATUS STDCALL
174 IopQueryNameFile(PVOID ObjectBody,
175 POBJECT_NAME_INFORMATION ObjectNameInfo,
176 ULONG Length,
177 PULONG ReturnLength)
178 {
179 POBJECT_NAME_INFORMATION LocalInfo;
180 PFILE_NAME_INFORMATION FileNameInfo;
181 PFILE_OBJECT FileObject;
182 ULONG LocalReturnLength;
183 NTSTATUS Status;
184
185 DPRINT ("IopQueryNameFile() called\n");
186
187 FileObject = (PFILE_OBJECT)ObjectBody;
188
189 LocalInfo = ExAllocatePool (NonPagedPool,
190 sizeof(OBJECT_NAME_INFORMATION) +
191 MAX_PATH * sizeof(WCHAR));
192 if (LocalInfo == NULL)
193 return STATUS_INSUFFICIENT_RESOURCES;
194
195 Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
196 LocalInfo,
197 MAX_PATH * sizeof(WCHAR),
198 &LocalReturnLength);
199 if (!NT_SUCCESS (Status))
200 {
201 ExFreePool (LocalInfo);
202 return Status;
203 }
204 DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
205
206 Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
207 &LocalInfo->Name);
208
209 ExFreePool (LocalInfo);
210
211 FileNameInfo = ExAllocatePool (NonPagedPool,
212 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
213 if (FileNameInfo == NULL)
214 return STATUS_INSUFFICIENT_RESOURCES;
215
216 Status = IoQueryFileInformation (FileObject,
217 FileNameInformation,
218 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
219 FileNameInfo,
220 NULL);
221 if (Status != STATUS_SUCCESS)
222 {
223 ExFreePool (FileNameInfo);
224 return Status;
225 }
226
227 Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
228 FileNameInfo->FileName);
229
230 DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
231
232 ExFreePool (FileNameInfo);
233
234 return Status;
235 }
236
237
238 VOID INIT_FUNCTION
239 IoInit (VOID)
240 {
241 OBJECT_ATTRIBUTES ObjectAttributes;
242 UNICODE_STRING DirName;
243 UNICODE_STRING LinkName;
244 HANDLE Handle;
245
246 IopInitDriverImplementation();
247
248 /*
249 * Register iomgr types: DeviceObjectType
250 */
251 IoDeviceObjectType = ExAllocatePool (NonPagedPool,
252 sizeof (OBJECT_TYPE));
253
254 IoDeviceObjectType->Tag = TAG_DEVICE_TYPE;
255 IoDeviceObjectType->TotalObjects = 0;
256 IoDeviceObjectType->TotalHandles = 0;
257 IoDeviceObjectType->MaxObjects = ULONG_MAX;
258 IoDeviceObjectType->MaxHandles = ULONG_MAX;
259 IoDeviceObjectType->PagedPoolCharge = 0;
260 IoDeviceObjectType->NonpagedPoolCharge = sizeof (DEVICE_OBJECT);
261 IoDeviceObjectType->Mapping = &IopFileMapping;
262 IoDeviceObjectType->Dump = NULL;
263 IoDeviceObjectType->Open = NULL;
264 IoDeviceObjectType->Close = NULL;
265 IoDeviceObjectType->Delete = NULL;
266 IoDeviceObjectType->Parse = NULL;
267 IoDeviceObjectType->Security = NULL;
268 IoDeviceObjectType->QueryName = NULL;
269 IoDeviceObjectType->OkayToClose = NULL;
270 IoDeviceObjectType->Create = IopCreateDevice;
271 IoDeviceObjectType->DuplicationNotify = NULL;
272
273 RtlRosInitUnicodeStringFromLiteral(&IoDeviceObjectType->TypeName, L"Device");
274
275 ObpCreateTypeObject(IoDeviceObjectType);
276
277 /*
278 * Register iomgr types: FileObjectType
279 * (alias DriverObjectType)
280 */
281 IoFileObjectType = ExAllocatePool (NonPagedPool, sizeof (OBJECT_TYPE));
282
283 IoFileObjectType->Tag = TAG_FILE_TYPE;
284 IoFileObjectType->TotalObjects = 0;
285 IoFileObjectType->TotalHandles = 0;
286 IoFileObjectType->MaxObjects = ULONG_MAX;
287 IoFileObjectType->MaxHandles = ULONG_MAX;
288 IoFileObjectType->PagedPoolCharge = 0;
289 IoFileObjectType->NonpagedPoolCharge = sizeof(FILE_OBJECT);
290 IoFileObjectType->Mapping = &IopFileMapping;
291 IoFileObjectType->Dump = NULL;
292 IoFileObjectType->Open = NULL;
293 IoFileObjectType->Close = IopCloseFile;
294 IoFileObjectType->Delete = IopDeleteFile;
295 IoFileObjectType->Parse = NULL;
296 IoFileObjectType->Security = IopSecurityFile;
297 IoFileObjectType->QueryName = IopQueryNameFile;
298 IoFileObjectType->OkayToClose = NULL;
299 IoFileObjectType->Create = IopCreateFile;
300 IoFileObjectType->DuplicationNotify = NULL;
301
302 RtlRosInitUnicodeStringFromLiteral(&IoFileObjectType->TypeName, L"File");
303
304 ObpCreateTypeObject(IoFileObjectType);
305
306 /*
307 * Create the '\Driver' object directory
308 */
309 RtlRosInitUnicodeStringFromLiteral(&DirName, L"\\Driver");
310 InitializeObjectAttributes(&ObjectAttributes,
311 &DirName,
312 0,
313 NULL,
314 NULL);
315 NtCreateDirectoryObject(&Handle,
316 0,
317 &ObjectAttributes);
318
319 /*
320 * Create the '\FileSystem' object directory
321 */
322 RtlRosInitUnicodeStringFromLiteral(&DirName,
323 L"\\FileSystem");
324 InitializeObjectAttributes(&ObjectAttributes,
325 &DirName,
326 0,
327 NULL,
328 NULL);
329 NtCreateDirectoryObject(&Handle,
330 0,
331 &ObjectAttributes);
332
333 /*
334 * Create the '\Device' directory
335 */
336 RtlRosInitUnicodeStringFromLiteral(&DirName,
337 L"\\Device");
338 InitializeObjectAttributes(&ObjectAttributes,
339 &DirName,
340 0,
341 NULL,
342 NULL);
343 ZwCreateDirectoryObject(&Handle,
344 0,
345 &ObjectAttributes);
346
347 /*
348 * Create the '\??' directory
349 */
350 RtlRosInitUnicodeStringFromLiteral(&DirName,
351 L"\\??");
352 InitializeObjectAttributes(&ObjectAttributes,
353 &DirName,
354 0,
355 NULL,
356 NULL);
357 ZwCreateDirectoryObject(&Handle,
358 0,
359 &ObjectAttributes);
360
361 /*
362 * Create the '\ArcName' directory
363 */
364 RtlRosInitUnicodeStringFromLiteral(&DirName,
365 L"\\ArcName");
366 InitializeObjectAttributes(&ObjectAttributes,
367 &DirName,
368 0,
369 NULL,
370 NULL);
371 ZwCreateDirectoryObject(&Handle,
372 0,
373 &ObjectAttributes);
374
375 /*
376 * Initialize remaining subsubsystem
377 */
378 IoInitCancelHandling();
379 IoInitFileSystemImplementation();
380 IoInitVpbImplementation();
381 IoInitShutdownNotification();
382 IopInitErrorLog();
383
384 /*
385 * Create link from '\DosDevices' to '\??' directory
386 */
387 RtlRosInitUnicodeStringFromLiteral(&LinkName,
388 L"\\DosDevices");
389 RtlRosInitUnicodeStringFromLiteral(&DirName,
390 L"\\??");
391 IoCreateSymbolicLink(&LinkName,
392 &DirName);
393
394 /*
395 * Initialize PnP manager
396 */
397 PnpInit();
398 }
399
400
401 VOID INIT_FUNCTION
402 IoInit2(VOID)
403 {
404 PDEVICE_NODE DeviceNode;
405 PDRIVER_OBJECT DriverObject;
406 MODULE_OBJECT ModuleObject;
407 NTSTATUS Status;
408
409 KeInitializeSpinLock (&IoStatisticsLock);
410
411 /* Initialize raw filesystem driver */
412
413 /* Use IopRootDeviceNode for now */
414 Status = IopCreateDeviceNode(IopRootDeviceNode,
415 NULL,
416 &DeviceNode);
417 if (!NT_SUCCESS(Status))
418 {
419 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status);
420 return;
421 }
422
423 ModuleObject.Base = NULL;
424 ModuleObject.Length = 0;
425 ModuleObject.EntryPoint = RawFsDriverEntry;
426
427 Status = IopInitializeDriverModule(
428 DeviceNode,
429 &ModuleObject,
430 TRUE,
431 &DriverObject);
432 if (!NT_SUCCESS(Status))
433 {
434 IopFreeDeviceNode(DeviceNode);
435 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status);
436 return;
437 }
438
439 Status = IopInitializeDevice(DeviceNode, DriverObject);
440 if (!NT_SUCCESS(Status))
441 {
442 IopFreeDeviceNode(DeviceNode);
443 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
444 return;
445 }
446
447 /*
448 * Initialize PnP root releations
449 */
450 IopInvalidateDeviceRelations(
451 IopRootDeviceNode,
452 BusRelations);
453 }
454
455 /*
456 * @implemented
457 */
458 PGENERIC_MAPPING STDCALL
459 IoGetFileObjectGenericMapping(VOID)
460 {
461 return(&IopFileMapping);
462 }
463
464 /* EOF */