- Implemented ObQueryNameString().
[reactos.git] / reactos / ntoskrnl / io / iomgr.c
1 /* $Id: iomgr.c,v 1.34 2003/06/02 10:02:56 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
20 #define NDEBUG
21 #include <internal/debug.h>
22
23 /* GLOBALS *******************************************************************/
24
25 #define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
26 #define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
27
28 /* DATA ********************************************************************/
29
30
31 POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
32 POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
33 ULONG EXPORTED IoReadOperationCount = 0; /* FIXME: unknown type */
34 ULONG EXPORTED IoReadTransferCount = 0; /* FIXME: unknown type */
35 ULONG EXPORTED IoWriteOperationCount = 0; /* FIXME: unknown type */
36 ULONG EXPORTED IoWriteTransferCount = 0; /* FIXME: unknown type */
37 ULONG EXPORTED IoStatisticsLock = 0; /* FIXME: unknown type */
38
39 static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
40 FILE_GENERIC_WRITE,
41 FILE_GENERIC_EXECUTE,
42 FILE_ALL_ACCESS};
43
44 /* FUNCTIONS ****************************************************************/
45
46 VOID STDCALL
47 IopCloseFile(PVOID ObjectBody,
48 ULONG HandleCount)
49 {
50 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
51 PIRP Irp;
52 PIO_STACK_LOCATION StackPtr;
53 NTSTATUS Status;
54
55 DPRINT("IopCloseFile()\n");
56
57 if (HandleCount > 0 || FileObject->DeviceObject == NULL)
58 {
59 return;
60 }
61
62 #if 0
63 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
64 ObReferenceObjectByPointer(FileObject,
65 STANDARD_RIGHTS_REQUIRED,
66 IoFileObjectType,
67 UserMode);
68 #endif
69
70 KeResetEvent( &FileObject->Event );
71
72 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
73 FileObject->DeviceObject,
74 NULL,
75 0,
76 NULL,
77 NULL,
78 NULL);
79 StackPtr = IoGetNextIrpStackLocation(Irp);
80 StackPtr->FileObject = FileObject;
81
82 Status = IoCallDriver(FileObject->DeviceObject, Irp);
83 if (Status == STATUS_PENDING)
84 {
85 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
86 }
87 }
88
89
90 VOID STDCALL
91 IopDeleteFile(PVOID ObjectBody)
92 {
93 PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
94 PIRP Irp;
95 PIO_STACK_LOCATION StackPtr;
96 NTSTATUS Status;
97
98 DPRINT("IopDeleteFile()\n");
99
100 if (FileObject->DeviceObject)
101 {
102 #if 0
103 //NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
104
105 ObReferenceObjectByPointer(ObjectBody,
106 STANDARD_RIGHTS_REQUIRED,
107 IoFileObjectType,
108 UserMode);
109 #endif
110 KeResetEvent( &FileObject->Event );
111 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
112 FileObject->DeviceObject,
113 NULL,
114 0,
115 NULL,
116 NULL,
117 NULL);
118 StackPtr = IoGetNextIrpStackLocation(Irp);
119 StackPtr->FileObject = FileObject;
120
121 Status = IoCallDriver(FileObject->DeviceObject, Irp);
122 if (Status == STATUS_PENDING)
123 {
124 KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
125 }
126 }
127
128 if (FileObject->FileName.Buffer != NULL)
129 {
130 ExFreePool(FileObject->FileName.Buffer);
131 FileObject->FileName.Buffer = 0;
132 }
133 }
134
135
136 NTSTATUS STDCALL
137 IopQueryNameFile(PVOID ObjectBody,
138 POBJECT_NAME_INFORMATION ObjectNameInfo,
139 ULONG Length,
140 PULONG ReturnLength)
141 {
142 POBJECT_NAME_INFORMATION LocalInfo;
143 PFILE_NAME_INFORMATION FileNameInfo;
144 PFILE_OBJECT FileObject;
145 ULONG LocalReturnLength;
146 NTSTATUS Status;
147
148 DPRINT ("IopQueryNameFile() called\n");
149
150 FileObject = (PFILE_OBJECT)ObjectBody;
151
152 LocalInfo = ExAllocatePool (NonPagedPool,
153 sizeof(OBJECT_NAME_INFORMATION) +
154 MAX_PATH * sizeof(WCHAR));
155 if (LocalInfo == NULL)
156 return STATUS_INSUFFICIENT_RESOURCES;
157
158 Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
159 LocalInfo,
160 MAX_PATH * sizeof(WCHAR),
161 &LocalReturnLength);
162 if (!NT_SUCCESS (Status))
163 {
164 ExFreePool (LocalInfo);
165 return Status;
166 }
167 DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
168
169 Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
170 &LocalInfo->Name);
171
172 ExFreePool (LocalInfo);
173
174 FileNameInfo = ExAllocatePool (NonPagedPool,
175 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
176 if (FileNameInfo == NULL)
177 return STATUS_INSUFFICIENT_RESOURCES;
178
179 Status = IoQueryFileInformation (FileObject,
180 FileNameInformation,
181 MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
182 FileNameInfo,
183 NULL);
184 if (Status != STATUS_SUCCESS)
185 {
186 ExFreePool (FileNameInfo);
187 return Status;
188 }
189
190 Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
191 FileNameInfo->FileName);
192
193 DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
194
195 ExFreePool (FileNameInfo);
196
197 return Status;
198 }
199
200
201 VOID IoInit (VOID)
202 {
203 OBJECT_ATTRIBUTES ObjectAttributes;
204 UNICODE_STRING DirName;
205 UNICODE_STRING LinkName;
206 HANDLE Handle;
207
208 IopInitDriverImplementation();
209
210 /*
211 * Register iomgr types: DeviceObjectType
212 */
213 IoDeviceObjectType = ExAllocatePool (NonPagedPool,
214 sizeof (OBJECT_TYPE));
215
216 IoDeviceObjectType->Tag = TAG_DEVICE_TYPE;
217 IoDeviceObjectType->TotalObjects = 0;
218 IoDeviceObjectType->TotalHandles = 0;
219 IoDeviceObjectType->MaxObjects = ULONG_MAX;
220 IoDeviceObjectType->MaxHandles = ULONG_MAX;
221 IoDeviceObjectType->PagedPoolCharge = 0;
222 IoDeviceObjectType->NonpagedPoolCharge = sizeof (DEVICE_OBJECT);
223 IoDeviceObjectType->Mapping = &IopFileMapping;
224 IoDeviceObjectType->Dump = NULL;
225 IoDeviceObjectType->Open = NULL;
226 IoDeviceObjectType->Close = NULL;
227 IoDeviceObjectType->Delete = NULL;
228 IoDeviceObjectType->Parse = NULL;
229 IoDeviceObjectType->Security = NULL;
230 IoDeviceObjectType->QueryName = NULL;
231 IoDeviceObjectType->OkayToClose = NULL;
232 IoDeviceObjectType->Create = IopCreateDevice;
233 IoDeviceObjectType->DuplicationNotify = NULL;
234
235 RtlInitUnicodeStringFromLiteral(&IoDeviceObjectType->TypeName, L"Device");
236
237 /*
238 * Register iomgr types: FileObjectType
239 * (alias DriverObjectType)
240 */
241 IoFileObjectType = ExAllocatePool (NonPagedPool, sizeof (OBJECT_TYPE));
242
243 IoFileObjectType->Tag = TAG_FILE_TYPE;
244 IoFileObjectType->TotalObjects = 0;
245 IoFileObjectType->TotalHandles = 0;
246 IoFileObjectType->MaxObjects = ULONG_MAX;
247 IoFileObjectType->MaxHandles = ULONG_MAX;
248 IoFileObjectType->PagedPoolCharge = 0;
249 IoFileObjectType->NonpagedPoolCharge = sizeof(FILE_OBJECT);
250 IoFileObjectType->Mapping = &IopFileMapping;
251 IoFileObjectType->Dump = NULL;
252 IoFileObjectType->Open = NULL;
253 IoFileObjectType->Close = IopCloseFile;
254 IoFileObjectType->Delete = IopDeleteFile;
255 IoFileObjectType->Parse = NULL;
256 IoFileObjectType->Security = NULL;
257 IoFileObjectType->QueryName = IopQueryNameFile;
258 IoFileObjectType->OkayToClose = NULL;
259 IoFileObjectType->Create = IopCreateFile;
260 IoFileObjectType->DuplicationNotify = NULL;
261
262 RtlInitUnicodeStringFromLiteral(&IoFileObjectType->TypeName, L"File");
263
264 /*
265 * Create the '\Driver' object directory
266 */
267 RtlInitUnicodeStringFromLiteral(&DirName, L"\\Driver");
268 InitializeObjectAttributes(&ObjectAttributes,
269 &DirName,
270 0,
271 NULL,
272 NULL);
273 NtCreateDirectoryObject(&Handle,
274 0,
275 &ObjectAttributes);
276
277 /*
278 * Create the '\FileSystem' object directory
279 */
280 RtlInitUnicodeStringFromLiteral(&DirName,
281 L"\\FileSystem");
282 InitializeObjectAttributes(&ObjectAttributes,
283 &DirName,
284 0,
285 NULL,
286 NULL);
287 NtCreateDirectoryObject(&Handle,
288 0,
289 &ObjectAttributes);
290
291 /*
292 * Create the '\Device' directory
293 */
294 RtlInitUnicodeStringFromLiteral(&DirName,
295 L"\\Device");
296 InitializeObjectAttributes(&ObjectAttributes,
297 &DirName,
298 0,
299 NULL,
300 NULL);
301 ZwCreateDirectoryObject(&Handle,
302 0,
303 &ObjectAttributes);
304
305 /*
306 * Create the '\??' directory
307 */
308 RtlInitUnicodeStringFromLiteral(&DirName,
309 L"\\??");
310 InitializeObjectAttributes(&ObjectAttributes,
311 &DirName,
312 0,
313 NULL,
314 NULL);
315 ZwCreateDirectoryObject(&Handle,
316 0,
317 &ObjectAttributes);
318
319 /*
320 * Create the '\ArcName' directory
321 */
322 RtlInitUnicodeStringFromLiteral(&DirName,
323 L"\\ArcName");
324 InitializeObjectAttributes(&ObjectAttributes,
325 &DirName,
326 0,
327 NULL,
328 NULL);
329 ZwCreateDirectoryObject(&Handle,
330 0,
331 &ObjectAttributes);
332
333 /*
334 * Initialize remaining subsubsystem
335 */
336 IoInitCancelHandling();
337 IoInitFileSystemImplementation();
338 IoInitVpbImplementation();
339 IoInitShutdownNotification();
340
341 /*
342 * Create link from '\DosDevices' to '\??' directory
343 */
344 RtlInitUnicodeStringFromLiteral(&LinkName,
345 L"\\DosDevices");
346 RtlInitUnicodeStringFromLiteral(&DirName,
347 L"\\??");
348 IoCreateSymbolicLink(&LinkName,
349 &DirName);
350
351 /*
352 * Initialize PnP manager
353 */
354 PnpInit();
355 }
356
357 VOID IoInit2(VOID)
358 {
359 PDEVICE_NODE DeviceNode;
360 NTSTATUS Status;
361
362 /* Initialize raw filesystem driver */
363
364 /* Use IopRootDeviceNode for now */
365 Status = IopCreateDeviceNode(IopRootDeviceNode,
366 NULL,
367 &DeviceNode);
368 if (!NT_SUCCESS(Status))
369 {
370 CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status);
371 return;
372 }
373
374 Status = IopInitializeDriver(RawFsDriverEntry,
375 DeviceNode,
376 TRUE);
377 if (!NT_SUCCESS(Status))
378 {
379 IopFreeDeviceNode(DeviceNode);
380 CPRINT("IopInitializeDriver() failed with status (%x)\n", Status);
381 return;
382 }
383 }
384
385 PGENERIC_MAPPING STDCALL
386 IoGetFileObjectGenericMapping(VOID)
387 {
388 return(&IopFileMapping);
389 }
390
391 /* EOF */