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