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