- Put the event from file object as user event into the irp in IopCloseFile
[reactos.git] / reactos / ntoskrnl / io / iomgr.c
1 /* $Id: iomgr.c,v 1.48 2004/05/09 15:02:07 hbirr 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 IopQueryNameFile(PVOID ObjectBody,
143 POBJECT_NAME_INFORMATION ObjectNameInfo,
144 ULONG Length,
145 PULONG ReturnLength)
146 {
147 POBJECT_NAME_INFORMATION LocalInfo;
148 PFILE_NAME_INFORMATION FileNameInfo;
149 PFILE_OBJECT FileObject;
150 ULONG LocalReturnLength;
151 NTSTATUS Status;
152
153 DPRINT ("IopQueryNameFile() called\n");
154
155 FileObject = (PFILE_OBJECT)ObjectBody;
156
157 LocalInfo = ExAllocatePool (NonPagedPool,
158 sizeof(OBJECT_NAME_INFORMATION) +
159 MAX_PATH * sizeof(WCHAR));
160 if (LocalInfo == NULL)
161 return STATUS_INSUFFICIENT_RESOURCES;
162
163 Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
164 LocalInfo,
165 MAX_PATH * sizeof(WCHAR),
166 &LocalReturnLength);
167 if (!NT_SUCCESS (Status))
168 {
169 ExFreePool (LocalInfo);
170 return Status;
171 }
172 DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
173
174 Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
175 &LocalInfo->Name);
176
177 ExFreePool (LocalInfo);
178
179 FileNameInfo = ExAllocatePool (NonPagedPool,
180 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
181 if (FileNameInfo == NULL)
182 return STATUS_INSUFFICIENT_RESOURCES;
183
184 Status = IoQueryFileInformation (FileObject,
185 FileNameInformation,
186 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
187 FileNameInfo,
188 NULL);
189 if (Status != STATUS_SUCCESS)
190 {
191 ExFreePool (FileNameInfo);
192 return Status;
193 }
194
195 Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
196 FileNameInfo->FileName);
197
198 DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
199
200 ExFreePool (FileNameInfo);
201
202 return Status;
203 }
204
205
206 VOID INIT_FUNCTION
207 IoInit (VOID)
208 {
209 OBJECT_ATTRIBUTES ObjectAttributes;
210 UNICODE_STRING DirName;
211 UNICODE_STRING LinkName;
212 HANDLE Handle;
213
214 IopInitDriverImplementation();
215
216 /*
217 * Register iomgr types: DeviceObjectType
218 */
219 IoDeviceObjectType = ExAllocatePool (NonPagedPool,
220 sizeof (OBJECT_TYPE));
221
222 IoDeviceObjectType->Tag = TAG_DEVICE_TYPE;
223 IoDeviceObjectType->TotalObjects = 0;
224 IoDeviceObjectType->TotalHandles = 0;
225 IoDeviceObjectType->MaxObjects = ULONG_MAX;
226 IoDeviceObjectType->MaxHandles = ULONG_MAX;
227 IoDeviceObjectType->PagedPoolCharge = 0;
228 IoDeviceObjectType->NonpagedPoolCharge = sizeof (DEVICE_OBJECT);
229 IoDeviceObjectType->Mapping = &IopFileMapping;
230 IoDeviceObjectType->Dump = NULL;
231 IoDeviceObjectType->Open = NULL;
232 IoDeviceObjectType->Close = NULL;
233 IoDeviceObjectType->Delete = NULL;
234 IoDeviceObjectType->Parse = NULL;
235 IoDeviceObjectType->Security = NULL;
236 IoDeviceObjectType->QueryName = NULL;
237 IoDeviceObjectType->OkayToClose = NULL;
238 IoDeviceObjectType->Create = IopCreateDevice;
239 IoDeviceObjectType->DuplicationNotify = NULL;
240
241 RtlRosInitUnicodeStringFromLiteral(&IoDeviceObjectType->TypeName, L"Device");
242
243 ObpCreateTypeObject(IoDeviceObjectType);
244
245 /*
246 * Register iomgr types: FileObjectType
247 * (alias DriverObjectType)
248 */
249 IoFileObjectType = ExAllocatePool (NonPagedPool, sizeof (OBJECT_TYPE));
250
251 IoFileObjectType->Tag = TAG_FILE_TYPE;
252 IoFileObjectType->TotalObjects = 0;
253 IoFileObjectType->TotalHandles = 0;
254 IoFileObjectType->MaxObjects = ULONG_MAX;
255 IoFileObjectType->MaxHandles = ULONG_MAX;
256 IoFileObjectType->PagedPoolCharge = 0;
257 IoFileObjectType->NonpagedPoolCharge = sizeof(FILE_OBJECT);
258 IoFileObjectType->Mapping = &IopFileMapping;
259 IoFileObjectType->Dump = NULL;
260 IoFileObjectType->Open = NULL;
261 IoFileObjectType->Close = IopCloseFile;
262 IoFileObjectType->Delete = IopDeleteFile;
263 IoFileObjectType->Parse = NULL;
264 IoFileObjectType->Security = NULL;
265 IoFileObjectType->QueryName = IopQueryNameFile;
266 IoFileObjectType->OkayToClose = NULL;
267 IoFileObjectType->Create = IopCreateFile;
268 IoFileObjectType->DuplicationNotify = NULL;
269
270 RtlRosInitUnicodeStringFromLiteral(&IoFileObjectType->TypeName, L"File");
271
272 ObpCreateTypeObject(IoFileObjectType);
273
274 /*
275 * Create the '\Driver' object directory
276 */
277 RtlRosInitUnicodeStringFromLiteral(&DirName, L"\\Driver");
278 InitializeObjectAttributes(&ObjectAttributes,
279 &DirName,
280 0,
281 NULL,
282 NULL);
283 NtCreateDirectoryObject(&Handle,
284 0,
285 &ObjectAttributes);
286
287 /*
288 * Create the '\FileSystem' object directory
289 */
290 RtlRosInitUnicodeStringFromLiteral(&DirName,
291 L"\\FileSystem");
292 InitializeObjectAttributes(&ObjectAttributes,
293 &DirName,
294 0,
295 NULL,
296 NULL);
297 NtCreateDirectoryObject(&Handle,
298 0,
299 &ObjectAttributes);
300
301 /*
302 * Create the '\Device' directory
303 */
304 RtlRosInitUnicodeStringFromLiteral(&DirName,
305 L"\\Device");
306 InitializeObjectAttributes(&ObjectAttributes,
307 &DirName,
308 0,
309 NULL,
310 NULL);
311 ZwCreateDirectoryObject(&Handle,
312 0,
313 &ObjectAttributes);
314
315 /*
316 * Create the '\??' directory
317 */
318 RtlRosInitUnicodeStringFromLiteral(&DirName,
319 L"\\??");
320 InitializeObjectAttributes(&ObjectAttributes,
321 &DirName,
322 0,
323 NULL,
324 NULL);
325 ZwCreateDirectoryObject(&Handle,
326 0,
327 &ObjectAttributes);
328
329 /*
330 * Create the '\ArcName' directory
331 */
332 RtlRosInitUnicodeStringFromLiteral(&DirName,
333 L"\\ArcName");
334 InitializeObjectAttributes(&ObjectAttributes,
335 &DirName,
336 0,
337 NULL,
338 NULL);
339 ZwCreateDirectoryObject(&Handle,
340 0,
341 &ObjectAttributes);
342
343 /*
344 * Initialize remaining subsubsystem
345 */
346 IoInitCancelHandling();
347 IoInitFileSystemImplementation();
348 IoInitVpbImplementation();
349 IoInitShutdownNotification();
350 IopInitErrorLog();
351
352 /*
353 * Create link from '\DosDevices' to '\??' directory
354 */
355 RtlRosInitUnicodeStringFromLiteral(&LinkName,
356 L"\\DosDevices");
357 RtlRosInitUnicodeStringFromLiteral(&DirName,
358 L"\\??");
359 IoCreateSymbolicLink(&LinkName,
360 &DirName);
361
362 /*
363 * Initialize PnP manager
364 */
365 PnpInit();
366 }
367
368
369 VOID INIT_FUNCTION
370 IoInit2(VOID)
371 {
372 PDEVICE_NODE DeviceNode;
373 PDRIVER_OBJECT DriverObject;
374 MODULE_OBJECT ModuleObject;
375 NTSTATUS Status;
376
377 KeInitializeSpinLock (&IoStatisticsLock);
378
379 /* Initialize raw filesystem driver */
380
381 /* Use IopRootDeviceNode for now */
382 Status = IopCreateDeviceNode(IopRootDeviceNode,
383 NULL,
384 &DeviceNode);
385 if (!NT_SUCCESS(Status))
386 {
387 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status);
388 return;
389 }
390
391 ModuleObject.Base = NULL;
392 ModuleObject.Length = 0;
393 ModuleObject.EntryPoint = RawFsDriverEntry;
394
395 Status = IopInitializeDriverModule(
396 DeviceNode,
397 &ModuleObject,
398 TRUE,
399 &DriverObject);
400 if (!NT_SUCCESS(Status))
401 {
402 IopFreeDeviceNode(DeviceNode);
403 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status);
404 return;
405 }
406
407 Status = IopInitializeDevice(DeviceNode, DriverObject);
408 if (!NT_SUCCESS(Status))
409 {
410 IopFreeDeviceNode(DeviceNode);
411 CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
412 return;
413 }
414
415 /*
416 * Initialize PnP root releations
417 */
418 IopInvalidateDeviceRelations(
419 IopRootDeviceNode,
420 BusRelations);
421 }
422
423 /*
424 * @implemented
425 */
426 PGENERIC_MAPPING STDCALL
427 IoGetFileObjectGenericMapping(VOID)
428 {
429 return(&IopFileMapping);
430 }
431
432 /* EOF */