Implemented driver reinitialization.
[reactos.git] / reactos / ntoskrnl / io / device.c
1 /* $Id: device.c,v 1.65 2003/12/15 17:50:23 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/device.c
6 * PURPOSE: Manage devices
7 * PROGRAMMER: David Welch (welch@cwcom.net)
8 * UPDATE HISTORY:
9 * 15/05/98: Created
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #define NTOS_MODE_KERNEL
15 #include <ntos.h>
16 #include <internal/io.h>
17 #include <internal/po.h>
18 #include <internal/ldr.h>
19 #include <internal/id.h>
20 #include <internal/pool.h>
21
22 #include <roscfg.h>
23
24 #define NDEBUG
25 //#define DBG
26 #include <internal/debug.h>
27
28 /* GLOBALS *******************************************************************/
29
30 #define TAG_DRIVER TAG('D', 'R', 'V', 'R')
31 #define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E')
32 #define TAG_DEVICE_EXTENSION TAG('D', 'E', 'X', 'T')
33
34 #define DRIVER_REGISTRY_KEY_BASENAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
35
36 /* FUNCTIONS ***************************************************************/
37
38 /*
39 * @implemented
40 */
41 NTSTATUS STDCALL
42 IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice,
43 IN PDEVICE_OBJECT TargetDevice)
44 {
45 PDEVICE_OBJECT AttachedDevice;
46
47 DPRINT("IoAttachDeviceByPointer(SourceDevice %x, TargetDevice %x)\n",
48 SourceDevice,
49 TargetDevice);
50
51 AttachedDevice = IoAttachDeviceToDeviceStack (SourceDevice,
52 TargetDevice);
53 if (AttachedDevice == NULL)
54 return STATUS_NO_SUCH_DEVICE;
55
56 return STATUS_SUCCESS;
57 }
58
59
60 /*
61 * @implemented
62 */
63 VOID STDCALL
64 IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
65 {
66 PDEVICE_OBJECT Previous;
67
68 if (DeviceObject->Flags & DO_SHUTDOWN_REGISTERED)
69 IoUnregisterShutdownNotification(DeviceObject);
70
71 /* remove the timer if it exists */
72 if (DeviceObject->Timer)
73 {
74 IoStopTimer(DeviceObject);
75 ExFreePool(DeviceObject->Timer);
76 }
77
78 /* free device extension */
79 if (DeviceObject->DeviceObjectExtension)
80 ExFreePool (DeviceObject->DeviceObjectExtension);
81
82 /* remove device from driver device list */
83 Previous = DeviceObject->DriverObject->DeviceObject;
84 if (Previous == DeviceObject)
85 {
86 DeviceObject->DriverObject->DeviceObject = DeviceObject->NextDevice;
87 }
88 else
89 {
90 while (Previous->NextDevice != DeviceObject)
91 Previous = Previous->NextDevice;
92 Previous->NextDevice = DeviceObject->NextDevice;
93 }
94
95 ObDereferenceObject (DeviceObject);
96 }
97
98
99 /*
100 * @implemented
101 */
102 PDEVICE_OBJECT
103 STDCALL
104 IoGetRelatedDeviceObject (
105 IN PFILE_OBJECT FileObject
106 )
107 {
108 /*Win NT File System Internals, page 633-634*/
109
110 /*get logical volume mounted on a physical/virtual/logical device*/
111 if (FileObject->Vpb && FileObject->Vpb->DeviceObject)
112 {
113 return IoGetAttachedDevice(FileObject->Vpb->DeviceObject);
114 }
115
116 /*check if fileobject has an associated device object mounted by some other file system*/
117 if (FileObject->DeviceObject->Vpb && FileObject->DeviceObject->Vpb->DeviceObject)
118 {
119 return IoGetAttachedDevice(FileObject->DeviceObject->Vpb->DeviceObject);
120 }
121
122 return IoGetAttachedDevice(FileObject->DeviceObject);
123 }
124
125
126 /*
127 * @implemented
128 */
129 NTSTATUS
130 STDCALL
131 IoGetDeviceObjectPointer (
132 IN PUNICODE_STRING ObjectName,
133 IN ACCESS_MASK DesiredAccess,
134 OUT PFILE_OBJECT * FileObject,
135 OUT PDEVICE_OBJECT * DeviceObject)
136 {
137 OBJECT_ATTRIBUTES ObjectAttributes;
138 IO_STATUS_BLOCK StatusBlock;
139 PFILE_OBJECT LocalFileObject;
140 HANDLE FileHandle;
141 NTSTATUS Status;
142
143 DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x, FileObject %p DeviceObject %p)\n",
144 ObjectName,
145 DesiredAccess,
146 FileObject,
147 DeviceObject);
148
149 InitializeObjectAttributes (&ObjectAttributes,
150 ObjectName,
151 0,
152 NULL,
153 NULL);
154
155 Status = NtOpenFile (&FileHandle,
156 DesiredAccess,
157 &ObjectAttributes,
158 &StatusBlock,
159 0,
160 FILE_NON_DIRECTORY_FILE);
161 if (!NT_SUCCESS(Status))
162 return Status;
163
164 Status = ObReferenceObjectByHandle (FileHandle,
165 0,
166 IoFileObjectType,
167 KernelMode,
168 (PVOID*)&LocalFileObject,
169 NULL);
170 if (NT_SUCCESS(Status))
171 {
172 *DeviceObject = IoGetRelatedDeviceObject (LocalFileObject);
173 *FileObject = LocalFileObject;
174 }
175 NtClose (FileHandle);
176
177 return Status;
178 }
179
180
181 /*
182 * @unimplemented
183 */
184 VOID
185 STDCALL
186 IoDetachDevice(PDEVICE_OBJECT TargetDevice)
187 {
188 // UNIMPLEMENTED;
189 DPRINT("IoDetachDevice(TargetDevice %x) - UNIMPLEMENTED\n", TargetDevice);
190 }
191
192
193 /*
194 * @implemented
195 */
196 PDEVICE_OBJECT
197 STDCALL
198 IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
199 {
200 PDEVICE_OBJECT Current = DeviceObject;
201
202 // DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject);
203
204 while (Current->AttachedDevice!=NULL)
205 {
206 Current = Current->AttachedDevice;
207 // DPRINT("Current %x\n",Current);
208 }
209
210 // DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject);
211 return(Current);
212 }
213
214 /*
215 * @implemented
216 */
217 PDEVICE_OBJECT
218 STDCALL
219 IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
220 {
221 PDEVICE_OBJECT Current = DeviceObject;
222
223 while (Current->AttachedDevice!=NULL)
224 {
225 Current = Current->AttachedDevice;
226 }
227
228 ObReferenceObject(Current);
229 return(Current);
230 }
231
232 /*
233 * @implemented
234 */
235 PDEVICE_OBJECT STDCALL
236 IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
237 PDEVICE_OBJECT TargetDevice)
238 {
239 PDEVICE_OBJECT AttachedDevice;
240
241 DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
242 SourceDevice,TargetDevice);
243
244 AttachedDevice = IoGetAttachedDevice(TargetDevice);
245 AttachedDevice->AttachedDevice = SourceDevice;
246 SourceDevice->AttachedDevice = NULL;
247 SourceDevice->StackSize = AttachedDevice->StackSize + 1;
248 SourceDevice->Vpb = AttachedDevice->Vpb;
249 return(AttachedDevice);
250 }
251
252
253 NTSTATUS STDCALL
254 IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject,
255 PIRP Irp)
256 {
257 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
258 Irp->IoStatus.Information = 0;
259
260 IoCompleteRequest(Irp, IO_NO_INCREMENT);
261 return(STATUS_NOT_IMPLEMENTED);
262 }
263
264
265 NTSTATUS
266 IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
267 PUNICODE_STRING ServiceName,
268 BOOLEAN FileSystem,
269 PVOID DriverImageStart,
270 ULONG DriverImageSize)
271 {
272 PDRIVER_OBJECT Object;
273 ULONG i;
274 WCHAR NameBuffer[MAX_PATH];
275 UNICODE_STRING DriverName;
276 OBJECT_ATTRIBUTES ObjectAttributes;
277 NTSTATUS Status;
278
279 DPRINT("IopCreateDriverObject(%p '%wZ' %x %p %x)\n", DriverObject, ServiceName, FileSystem,
280 DriverImageStart, DriverImageSize);
281
282 *DriverObject = NULL;
283
284 /* Create ModuleName string */
285 if ((ServiceName != NULL) && (ServiceName->Buffer != NULL))
286 {
287 if (FileSystem == TRUE)
288 wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
289 else
290 wcscpy(NameBuffer, DRIVER_ROOT_NAME);
291 wcscat(NameBuffer, ServiceName->Buffer);
292
293 RtlInitUnicodeString(&DriverName,
294 NameBuffer);
295 DPRINT("Driver name: '%wZ'\n", &DriverName);
296 }
297
298 /* Initialize ObjectAttributes for driver object */
299 InitializeObjectAttributes(&ObjectAttributes,
300 ((ServiceName != NULL) && (ServiceName->Buffer != NULL))? &DriverName : NULL,
301 OBJ_PERMANENT,
302 NULL,
303 NULL);
304
305 /* Create driver object */
306 Status = ObCreateObject(KernelMode,
307 IoDriverObjectType,
308 &ObjectAttributes,
309 KernelMode,
310 NULL,
311 sizeof(DRIVER_OBJECT),
312 0,
313 0,
314 (PVOID*)&Object);
315 if (!NT_SUCCESS(Status))
316 {
317 return(Status);
318 }
319
320 /* Create driver extension */
321 Object->DriverExtension = (PDRIVER_EXTENSION)
322 ExAllocatePoolWithTag(NonPagedPool,
323 sizeof(DRIVER_EXTENSION),
324 TAG_DRIVER_EXTENSION);
325 if (Object->DriverExtension == NULL)
326 {
327 ExFreePool(Object);
328 return(STATUS_INSUFFICIENT_RESOURCES);
329 }
330
331 RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
332
333 Object->Type = InternalDriverType;
334
335 Object->DriverStart = DriverImageStart;
336 Object->DriverSize = DriverImageSize;
337
338 for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
339 {
340 Object->MajorFunction[i] = (PDRIVER_DISPATCH) IopDefaultDispatchFunction;
341 }
342
343 *DriverObject = Object;
344
345 return STATUS_SUCCESS;
346 }
347
348 NTSTATUS
349 IopAttachFilterDrivers(PDEVICE_NODE DeviceNode,
350 BOOLEAN Lower)
351 {
352 return STATUS_SUCCESS;
353 }
354
355 NTSTATUS
356 IopInitializeDevice(PDEVICE_NODE DeviceNode,
357 BOOLEAN BootDriver)
358 {
359 IO_STATUS_BLOCK IoStatusBlock;
360 PDRIVER_OBJECT DriverObject;
361 IO_STACK_LOCATION Stack;
362 PDEVICE_OBJECT Fdo;
363 NTSTATUS Status;
364
365 DriverObject = DeviceNode->DriverObject;
366
367 if (DriverObject->DriverExtension->AddDevice)
368 {
369 /* This is a Plug and Play driver */
370 DPRINT("Plug and Play driver found\n");
371
372 assert(DeviceNode->Pdo);
373
374 DPRINT("Calling driver AddDevice entrypoint at %08lx\n",
375 DriverObject->DriverExtension->AddDevice);
376 Status = DriverObject->DriverExtension->AddDevice(
377 DriverObject, DeviceNode->Pdo);
378 if (!NT_SUCCESS(Status))
379 {
380 return(Status);
381 }
382
383 IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED);
384
385 DPRINT("Sending IRP_MN_START_DEVICE to driver\n");
386
387 Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo);
388
389 if (Fdo == DeviceNode->Pdo)
390 {
391 /* FIXME: What do we do? Unload the driver or just disable the device? */
392 DbgPrint("An FDO was not attached\n");
393 KEBUGCHECK(0);
394 }
395
396 /* FIXME: Put some resources in the IRP for the device */
397 Stack.Parameters.StartDevice.AllocatedResources = NULL;
398 Stack.Parameters.StartDevice.AllocatedResourcesTranslated = NULL;
399
400 Status = IopInitiatePnpIrp(
401 Fdo,
402 &IoStatusBlock,
403 IRP_MN_START_DEVICE,
404 &Stack);
405 if (!NT_SUCCESS(Status))
406 {
407 DPRINT("IopInitiatePnpIrp() failed\n");
408 ObDereferenceObject(Fdo);
409 return(Status);
410 }
411
412 if (Fdo->DeviceType == FILE_DEVICE_BUS_EXTENDER)
413 {
414 DPRINT("Bus extender found\n");
415
416 Status = IopInvalidateDeviceRelations(
417 DeviceNode, BusRelations, BootDriver);
418 if (!NT_SUCCESS(Status))
419 {
420 ObDereferenceObject(Fdo);
421 return(Status);
422 }
423 }
424 else if (Fdo->DeviceType == FILE_DEVICE_ACPI)
425 {
426 #ifdef ACPI
427 static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
428
429 /* There can be only one system power device */
430 if (!SystemPowerDeviceNodeCreated)
431 {
432 PopSystemPowerDeviceNode = DeviceNode;
433 SystemPowerDeviceNodeCreated = TRUE;
434 }
435 #endif /* ACPI */
436 }
437 ObDereferenceObject(Fdo);
438 }
439
440 return STATUS_SUCCESS;
441 }
442
443 NTSTATUS
444 IopInitializeService(
445 PDEVICE_NODE DeviceNode,
446 PUNICODE_STRING ImagePath)
447 {
448 PMODULE_OBJECT ModuleObject;
449 NTSTATUS Status;
450
451 ModuleObject = LdrGetModuleObject(&DeviceNode->ServiceName);
452 if (ModuleObject == NULL)
453 {
454 /* The module is currently not loaded, so load it now */
455
456 Status = LdrLoadModule(ImagePath, &ModuleObject);
457 if (!NT_SUCCESS(Status))
458 {
459 /* FIXME: Log the error */
460 CPRINT("Driver load failed\n");
461 return(Status);
462 }
463
464 Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, FALSE,
465 ModuleObject->Base, ModuleObject->Length,
466 FALSE);
467 if (!NT_SUCCESS(Status))
468 {
469 LdrUnloadModule(ModuleObject);
470
471 /* FIXME: Log the error */
472 CPRINT("A driver failed to initialize\n");
473 return(Status);
474 }
475 } else
476 {
477 /* FIXME: This doesn't work for two devices with the same driver */
478 Status = IopInitializeDevice(DeviceNode, FALSE);
479 }
480
481 return(Status);
482 }
483
484 NTSTATUS
485 IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
486 PDEVICE_NODE DeviceNode,
487 BOOLEAN FileSystemDriver,
488 PVOID DriverImageStart,
489 ULONG DriverImageSize,
490 BOOLEAN BootDriver)
491 /*
492 * FUNCTION: Called to initalize a loaded driver
493 * ARGUMENTS:
494 * DriverEntry = Pointer to driver entry routine
495 * DeviceNode = Pointer to device node
496 */
497 {
498 WCHAR RegistryKeyBuffer[MAX_PATH];
499 PDRIVER_OBJECT DriverObject;
500 UNICODE_STRING RegistryKey;
501 NTSTATUS Status;
502
503 DPRINT("IopInitializeDriver(DriverEntry %08lx, DeviceNode %08lx)\n",
504 DriverEntry, DeviceNode);
505
506 Status = IopCreateDriverObject(&DriverObject,
507 &DeviceNode->ServiceName,
508 FileSystemDriver,
509 DriverImageStart,
510 DriverImageSize);
511 if (!NT_SUCCESS(Status))
512 {
513 return(Status);
514 }
515
516 DeviceNode->DriverObject = DriverObject;
517
518 if (DeviceNode->ServiceName.Buffer)
519 {
520 wcscpy(RegistryKeyBuffer, DRIVER_REGISTRY_KEY_BASENAME);
521 wcscat(RegistryKeyBuffer, DeviceNode->ServiceName.Buffer);
522 RtlInitUnicodeString(&RegistryKey, RegistryKeyBuffer);
523 }
524 else
525 {
526 RtlInitUnicodeString(&RegistryKey, NULL);
527 }
528
529 DPRINT("RegistryKey: %wZ\n", &RegistryKey);
530 DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry);
531
532 IopMarkLastReinitializeDriver();
533
534 Status = DriverEntry(DriverObject, &RegistryKey);
535 if (!NT_SUCCESS(Status))
536 {
537 DeviceNode->DriverObject = NULL;
538 ExFreePool(DriverObject->DriverExtension);
539 ObMakeTemporaryObject(DriverObject);
540 ObDereferenceObject(DriverObject);
541 return(Status);
542 }
543
544 IopReinitializeDrivers();
545
546 Status = IopInitializeDevice(DeviceNode, BootDriver);
547
548 return(Status);
549 }
550
551
552 /*
553 * @implemented
554 */
555 NTSTATUS STDCALL
556 IoAttachDevice(PDEVICE_OBJECT SourceDevice,
557 PUNICODE_STRING TargetDeviceName,
558 PDEVICE_OBJECT* AttachedDevice)
559 /*
560 * FUNCTION: Layers a device over the highest device in a device stack
561 * ARGUMENTS:
562 * SourceDevice = Device to attached
563 * TargetDevice = Name of the target device
564 * AttachedDevice (OUT) = Caller storage for the device attached to
565 */
566 {
567 NTSTATUS Status;
568 PFILE_OBJECT FileObject;
569 PDEVICE_OBJECT TargetDevice;
570
571 Status = IoGetDeviceObjectPointer(TargetDeviceName,
572 FILE_READ_ATTRIBUTES,
573 &FileObject,
574 &TargetDevice);
575
576 if (!NT_SUCCESS(Status))
577 {
578 return Status;
579 }
580
581 *AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice,
582 TargetDevice);
583
584 ObDereferenceObject(FileObject);
585 return STATUS_SUCCESS;
586 }
587
588
589 NTSTATUS STDCALL
590 IopCreateDevice(PVOID ObjectBody,
591 PVOID Parent,
592 PWSTR RemainingPath,
593 POBJECT_ATTRIBUTES ObjectAttributes)
594 {
595
596 DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
597 ObjectBody, Parent, RemainingPath);
598
599 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
600 {
601 return(STATUS_UNSUCCESSFUL);
602 }
603
604 return(STATUS_SUCCESS);
605 }
606
607
608 /*
609 * @implemented
610 */
611 NTSTATUS STDCALL
612 IoCreateDevice(PDRIVER_OBJECT DriverObject,
613 ULONG DeviceExtensionSize,
614 PUNICODE_STRING DeviceName,
615 DEVICE_TYPE DeviceType,
616 ULONG DeviceCharacteristics,
617 BOOLEAN Exclusive,
618 PDEVICE_OBJECT* DeviceObject)
619 /*
620 * FUNCTION: Allocates memory for and intializes a device object for use for
621 * a driver
622 * ARGUMENTS:
623 * DriverObject : Driver object passed by iomgr when the driver was
624 * loaded
625 * DeviceExtensionSize : Number of bytes for the device extension
626 * DeviceName : Unicode name of device
627 * DeviceType : Device type
628 * DeviceCharacteristics : Bit mask of device characteristics
629 * Exclusive : True if only one thread can access the device at a
630 * time
631 * RETURNS:
632 * Success or failure
633 * DeviceObject : Contains a pointer to allocated device object
634 * if the call succeeded
635 * NOTES: See the DDK documentation for more information
636 */
637 {
638 PDEVICE_OBJECT CreatedDeviceObject;
639 OBJECT_ATTRIBUTES ObjectAttributes;
640 NTSTATUS Status;
641
642 assert_irql(PASSIVE_LEVEL);
643
644 if (DeviceName != NULL)
645 {
646 DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n",DriverObject,
647 DeviceName->Buffer);
648 }
649 else
650 {
651 DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject);
652 }
653
654 if (DeviceName != NULL)
655 {
656 InitializeObjectAttributes(&ObjectAttributes,DeviceName,0,NULL,NULL);
657 Status = ObCreateObject(KernelMode,
658 IoDeviceObjectType,
659 &ObjectAttributes,
660 KernelMode,
661 NULL,
662 sizeof(DEVICE_OBJECT),
663 0,
664 0,
665 (PVOID*)&CreatedDeviceObject);
666 }
667 else
668 {
669 Status = ObCreateObject(KernelMode,
670 IoDeviceObjectType,
671 NULL,
672 KernelMode,
673 NULL,
674 sizeof(DEVICE_OBJECT),
675 0,
676 0,
677 (PVOID*)&CreatedDeviceObject);
678 }
679
680 *DeviceObject = NULL;
681
682 if (!NT_SUCCESS(Status))
683 {
684 DPRINT("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status);
685 return(Status);
686 }
687
688 if (DriverObject->DeviceObject == NULL)
689 {
690 DriverObject->DeviceObject = CreatedDeviceObject;
691 CreatedDeviceObject->NextDevice = NULL;
692 }
693 else
694 {
695 CreatedDeviceObject->NextDevice = DriverObject->DeviceObject;
696 DriverObject->DeviceObject = CreatedDeviceObject;
697 }
698
699 CreatedDeviceObject->Type = DeviceType;
700 CreatedDeviceObject->DriverObject = DriverObject;
701 CreatedDeviceObject->CurrentIrp = NULL;
702 CreatedDeviceObject->Flags = 0;
703
704 CreatedDeviceObject->DeviceExtension =
705 ExAllocatePoolWithTag(NonPagedPool, DeviceExtensionSize,
706 TAG_DEVICE_EXTENSION);
707 if (DeviceExtensionSize > 0 && CreatedDeviceObject->DeviceExtension == NULL)
708 {
709 ExFreePool(CreatedDeviceObject);
710 DPRINT("IoCreateDevice() ExAllocatePoolWithTag failed, returning: 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES);
711 return(STATUS_INSUFFICIENT_RESOURCES);
712 }
713
714 if (DeviceExtensionSize > 0)
715 {
716 RtlZeroMemory(CreatedDeviceObject->DeviceExtension,
717 DeviceExtensionSize);
718 }
719
720 CreatedDeviceObject->AttachedDevice = NULL;
721 CreatedDeviceObject->DeviceType = DeviceType;
722 CreatedDeviceObject->StackSize = 1;
723 CreatedDeviceObject->AlignmentRequirement = 1;
724 KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue);
725
726 KeInitializeEvent(&CreatedDeviceObject->DeviceLock,
727 SynchronizationEvent,
728 TRUE);
729
730 /* FIXME: Do we need to add network drives too?! */
731 if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK ||
732 CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM ||
733 CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE)
734 {
735 IoAttachVpb(CreatedDeviceObject);
736 }
737
738 *DeviceObject = CreatedDeviceObject;
739
740 return(STATUS_SUCCESS);
741 }
742
743
744 NTSTATUS
745 STDCALL
746 IoOpenDeviceInstanceKey (
747 DWORD Unknown0,
748 DWORD Unknown1,
749 DWORD Unknown2,
750 DWORD Unknown3,
751 DWORD Unknown4
752 )
753 {
754 UNIMPLEMENTED;
755 return(STATUS_NOT_IMPLEMENTED);
756 }
757
758
759 DWORD
760 STDCALL
761 IoQueryDeviceEnumInfo (
762 DWORD Unknown0,
763 DWORD Unknown1
764 )
765 {
766 UNIMPLEMENTED;
767 return 0;
768 }
769
770
771 /* EOF */