* Sync up to trunk r55544.
[reactos.git] / drivers / usb / usbhub / pdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Hub Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbhub/fdo.c
5 * PURPOSE: Handle PDO
6 * PROGRAMMERS:
7 * Hervé Poussineau (hpoussin@reactos.org)
8 * Michael Martin (michael.martin@reactos.org)
9 * Johannes Anderwald (johannes.anderwald@reactos.org)
10 */
11
12 #include "usbhub.h"
13
14 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
15
16 NTSTATUS
17 NTAPI
18 UrbCompletion(
19 PDEVICE_OBJECT DeviceObject,
20 PIRP Irp,
21 PVOID Context)
22 {
23 PIRP OriginalIrp;
24 DPRINT("Entered Urb Completion\n");
25
26 //
27 // Get the original Irp
28 //
29 OriginalIrp = (PIRP)Context;
30
31 //
32 // Update it to match what was returned for the IRP that was passed to RootHub
33 //
34 OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
35 OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
36 DPRINT("Status %x, Information %x\n", Irp->IoStatus.Status, Irp->IoStatus.Information);
37
38 //
39 // Complete the original Irp
40 //
41 IoCompleteRequest(OriginalIrp, IO_NO_INCREMENT);
42
43 //
44 // Return this status so the IO Manager doesnt mess with the Irp
45 //
46 return STATUS_MORE_PROCESSING_REQUIRED;
47 }
48
49 NTSTATUS
50 FowardUrbToRootHub(
51 PDEVICE_OBJECT RootHubDeviceObject,
52 IN ULONG IoControlCode,
53 PIRP Irp,
54 OUT PVOID OutParameter1,
55 OUT PVOID OutParameter2)
56 {
57 NTSTATUS Status;
58 PIRP ForwardIrp;
59 IO_STATUS_BLOCK IoStatus;
60 PIO_STACK_LOCATION ForwardStack, CurrentStack;
61 PURB Urb;
62
63 //
64 // Get the current stack location for the Irp
65 //
66 CurrentStack = IoGetCurrentIrpStackLocation(Irp);
67 ASSERT(CurrentStack);
68
69 //
70 // Pull the Urb from that stack, it will be reused in the Irp sent to RootHub
71 //
72 Urb = (PURB)CurrentStack->Parameters.Others.Argument1;
73 ASSERT(Urb);
74
75 //
76 // Create the Irp to forward to RootHub
77 //
78 ForwardIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_SHUTDOWN,
79 RootHubDeviceObject,
80 NULL,
81 0,
82 0,
83 &IoStatus);
84 if (!ForwardIrp)
85 {
86 DPRINT1("Failed to allocate IRP\n");
87 return STATUS_INSUFFICIENT_RESOURCES;
88 }
89
90 //
91 // Get the new Irps next stack
92 //
93 ForwardStack = IoGetNextIrpStackLocation(ForwardIrp);
94
95 //
96 // Copy the stack for the current irp into the next stack of new irp
97 //
98 RtlCopyMemory(ForwardStack, CurrentStack, sizeof(IO_STACK_LOCATION));
99
100 IoStatus.Status = STATUS_NOT_SUPPORTED;
101 IoStatus.Information = 0;
102
103 //
104 // Mark the Irp from upper driver as pending
105 //
106 IoMarkIrpPending(Irp);
107
108 //
109 // Now set the completion routine for the new Irp.
110 //
111 IoSetCompletionRoutine(ForwardIrp,
112 UrbCompletion,
113 Irp,
114 TRUE,
115 TRUE,
116 TRUE);
117
118 Status = IoCallDriver(RootHubDeviceObject, ForwardIrp);
119
120 //
121 // Always return pending as the completion routine will take care of it
122 //
123 return STATUS_PENDING;
124 }
125
126 NTSTATUS
127 USBHUB_PdoHandleInternalDeviceControl(
128 IN PDEVICE_OBJECT DeviceObject,
129 IN PIRP Irp)
130 {
131 NTSTATUS Status;
132 PIO_STACK_LOCATION Stack;
133 ULONG_PTR Information = 0;
134 PHUB_DEVICE_EXTENSION HubDeviceExtension;
135 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
136 PDEVICE_OBJECT RootHubDeviceObject;
137 PURB Urb;
138
139 //DPRINT1("UsbhubInternalDeviceControlPdo(%x) called\n", DeviceObject);
140
141 //
142 // get current stack location
143 //
144 Stack = IoGetCurrentIrpStackLocation(Irp);
145 ASSERT(Stack);
146
147 //
148 // Set default status
149 //
150 Status = Irp->IoStatus.Status;
151
152 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
153 ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
154 HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
155 RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
156
157 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
158 {
159 case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
160 {
161 PHUB_DEVICE_EXTENSION DeviceExtension;
162
163 DPRINT1("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
164 if (Irp->AssociatedIrp.SystemBuffer == NULL
165 || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
166 {
167 Status = STATUS_INVALID_PARAMETER;
168 }
169 else
170 {
171 PVOID* pHubPointer;
172 DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
173
174 pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
175 // FIXME
176 *pHubPointer = NULL;
177 Information = sizeof(PVOID);
178 Status = STATUS_SUCCESS;
179 }
180 break;
181 }
182 case IOCTL_INTERNAL_USB_SUBMIT_URB:
183 {
184 //DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB\n");
185
186 //
187 // Get the Urb
188 //
189 Urb = (PURB)Stack->Parameters.Others.Argument1;
190 ASSERT(Urb);
191
192 //
193 // Set the real device handle
194 //
195 //DPRINT("UsbdDeviceHandle %x, ChildDeviceHandle %x\n", Urb->UrbHeader.UsbdDeviceHandle, ChildDeviceExtension->UsbDeviceHandle);
196
197 Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
198
199 //
200 // Submit to RootHub
201 //
202 switch (Urb->UrbHeader.Function)
203 {
204 //
205 // Debugging only
206 //
207 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
208 DPRINT1("URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
209 break;
210 case URB_FUNCTION_CLASS_DEVICE:
211 DPRINT1("URB_FUNCTION_CLASS_DEVICE\n");
212 break;
213 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
214 DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
215 break;
216 case URB_FUNCTION_SELECT_CONFIGURATION:
217 DPRINT1("URB_FUNCTION_SELECT_CONFIGURATION\n");
218 break;
219 case URB_FUNCTION_SELECT_INTERFACE:
220 DPRINT1("URB_FUNCTION_SELECT_INTERFACE\n");
221 break;
222 case URB_FUNCTION_CLASS_OTHER:
223 DPRINT1("URB_FUNCTION_CLASS_OTHER\n");
224 break;
225 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
226 {
227 /*
228 DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
229 DPRINT1("PipeHandle %x\n", Urb->UrbBulkOrInterruptTransfer.PipeHandle);
230 DPRINT1("TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
231 DPRINT1("Buffer %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
232 DPRINT1("BufferMDL %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
233 DPRINT1("Length %x\n", Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
234 DPRINT1("UrbLink %x\n", Urb->UrbBulkOrInterruptTransfer.UrbLink);
235 DPRINT1("hca %x\n", Urb->UrbBulkOrInterruptTransfer.hca);
236 if (Urb->UrbBulkOrInterruptTransfer.TransferFlags == USBD_SHORT_TRANSFER_OK)
237 {
238 }
239 */
240 break;
241
242 }
243 case URB_FUNCTION_CLASS_INTERFACE:
244 DPRINT1("URB_FUNCTION_CLASS_INTERFACE\n");
245 break;
246 default:
247 DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
248 break;
249 }
250 Urb->UrbHeader.UsbdDeviceHandle = ChildDeviceExtension->UsbDeviceHandle;
251 //DPRINT1("Stack->CompletionRoutine %x\n", Stack->CompletionRoutine);
252 //
253 // Send the request to RootHub
254 //
255 Status = FowardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
256 return Status;
257 break;
258 }
259 //
260 // FIXME: Can these be sent to RootHub?
261 //
262 case IOCTL_INTERNAL_USB_RESET_PORT:
263 DPRINT1("IOCTL_INTERNAL_USB_RESET_PORT\n");
264 break;
265 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
266 {
267 PORT_STATUS_CHANGE PortStatus;
268 LONG PortId;
269 PUCHAR PortStatusBits;
270
271 PortStatusBits = (PUCHAR)Stack->Parameters.Others.Argument1;
272 //
273 // USBD_PORT_ENABLED (bit 0) or USBD_PORT_CONNECTED (bit 1)
274 //
275 DPRINT1("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
276 DPRINT1("Arg1 %x\n", *PortStatusBits);
277 *PortStatusBits = 0;
278 if (Stack->Parameters.Others.Argument1)
279 {
280 for (PortId = 1; PortId <= HubDeviceExtension->UsbExtHubInfo.NumberOfPorts; PortId++)
281 {
282 Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
283 if (NT_SUCCESS(Status))
284 {
285 DPRINT1("Connect %x\n", ((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2));
286 DPRINT1("Enable %x\n", ((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
287 *PortStatusBits +=
288 (((PortStatus.Status & USB_PORT_STATUS_CONNECT) << 1) << ((PortId - 1) * 2)) +
289 (((PortStatus.Status & USB_PORT_STATUS_ENABLE) >> 1) << ((PortId - 1) * 2));
290
291 }
292 }
293 }
294
295 DPRINT1("Arg1 %x\n", *PortStatusBits);
296 Status = STATUS_SUCCESS;
297 break;
298 }
299 case IOCTL_INTERNAL_USB_ENABLE_PORT:
300 DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
301 break;
302 case IOCTL_INTERNAL_USB_CYCLE_PORT:
303 DPRINT1("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
304 break;
305 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
306 DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
307 break;
308 default:
309 {
310 DPRINT1("Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
311 Information = Irp->IoStatus.Information;
312 Status = Irp->IoStatus.Status;
313 }
314 }
315
316 if (Status != STATUS_PENDING)
317 {
318 Irp->IoStatus.Information = Information;
319 Irp->IoStatus.Status = Status;
320 IoCompleteRequest(Irp, IO_NO_INCREMENT);
321 }
322 return Status;
323 }
324
325 NTSTATUS
326 USBHUB_PdoStartDevice(
327 IN PDEVICE_OBJECT DeviceObject,
328 IN PIRP Irp)
329 {
330 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
331 //NTSTATUS Status;
332 DPRINT1("USBHUB_PdoStartDevice %x\n", DeviceObject);
333 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
334
335 //
336 // This should be a PDO
337 //
338 ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
339
340 //
341 // FIXME: Fow now assume success
342 //
343
344 UNIMPLEMENTED
345 return STATUS_SUCCESS;
346 }
347
348 NTSTATUS
349 USBHUB_PdoQueryId(
350 IN PDEVICE_OBJECT DeviceObject,
351 IN PIRP Irp,
352 OUT ULONG_PTR* Information)
353 {
354 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
355 ULONG IdType;
356 PUNICODE_STRING SourceString = NULL;
357 PWCHAR ReturnString = NULL;
358 NTSTATUS Status = STATUS_SUCCESS;
359
360 IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
361 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
362
363 switch (IdType)
364 {
365 case BusQueryDeviceID:
366 {
367 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
368 SourceString = &ChildDeviceExtension->usDeviceId;
369 break;
370 }
371 case BusQueryHardwareIDs:
372 {
373 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
374 SourceString = &ChildDeviceExtension->usHardwareIds;
375 break;
376 }
377 case BusQueryCompatibleIDs:
378 {
379 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
380 SourceString = &ChildDeviceExtension->usCompatibleIds;
381 break;
382 }
383 case BusQueryInstanceID:
384 {
385 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
386 SourceString = &ChildDeviceExtension->usInstanceId;
387 break;
388 }
389 default:
390 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
391 return STATUS_NOT_SUPPORTED;
392 }
393
394 if (SourceString)
395 {
396 //
397 // allocate buffer
398 //
399 ReturnString = ExAllocatePool(PagedPool, SourceString->MaximumLength);
400 if (!ReturnString)
401 {
402 //
403 // no memory
404 //
405 return STATUS_INSUFFICIENT_RESOURCES;
406 }
407
408 //
409 // copy buffer
410 //
411 RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->MaximumLength);
412 }
413
414 *Information = (ULONG_PTR)ReturnString;
415
416 return Status;
417 }
418
419 NTSTATUS
420 USBHUB_PdoQueryDeviceText(
421 IN PDEVICE_OBJECT DeviceObject,
422 IN PIRP Irp,
423 OUT ULONG_PTR* Information)
424 {
425 PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
426 DEVICE_TEXT_TYPE DeviceTextType;
427 PUNICODE_STRING SourceString = NULL;
428 PWCHAR ReturnString = NULL;
429 NTSTATUS Status = STATUS_SUCCESS;
430 LCID LocaleId;
431
432 DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
433 LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
434 ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
435
436 //
437 // FIXME: LocaleId
438 //
439
440 switch (DeviceTextType)
441 {
442 case DeviceTextDescription:
443 case DeviceTextLocationInformation:
444 {
445 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
446
447 //
448 // does the device provide a text description
449 //
450 if (ChildDeviceExtension->usTextDescription.Buffer && ChildDeviceExtension->usTextDescription.Length)
451 {
452 //
453 // use device text
454 //
455 SourceString = &ChildDeviceExtension->usTextDescription;
456 }
457 break;
458 }
459 default:
460 {
461 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
462 Status = STATUS_NOT_SUPPORTED;
463 break;
464 }
465 }
466
467 if (SourceString)
468 {
469 ReturnString = ExAllocatePool(PagedPool, SourceString->Length);
470 RtlCopyMemory(ReturnString, SourceString->Buffer, SourceString->Length);
471 DPRINT1("%S\n", ReturnString);
472 *Information = (ULONG_PTR)ReturnString;
473 }
474
475 return Status;
476 }
477
478 NTSTATUS
479 USBHUB_PdoHandlePnp(
480 IN PDEVICE_OBJECT DeviceObject,
481 IN PIRP Irp)
482 {
483 NTSTATUS Status;
484 ULONG MinorFunction;
485 PIO_STACK_LOCATION Stack;
486 ULONG_PTR Information = 0;
487 PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
488 ULONG Index;
489 ULONG bFound;
490 PDEVICE_RELATIONS DeviceRelation;
491
492 UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
493 Stack = IoGetCurrentIrpStackLocation(Irp);
494 MinorFunction = Stack->MinorFunction;
495
496 switch (MinorFunction)
497 {
498 case IRP_MN_START_DEVICE:
499 {
500 DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
501 Status = USBHUB_PdoStartDevice(DeviceObject, Irp);
502 break;
503 }
504 case IRP_MN_QUERY_CAPABILITIES:
505 {
506 PDEVICE_CAPABILITIES DeviceCapabilities;
507 ULONG i;
508 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
509
510 DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
511 // FIXME: capabilities can change with connected device
512 DeviceCapabilities->LockSupported = FALSE;
513 DeviceCapabilities->EjectSupported = FALSE;
514 DeviceCapabilities->Removable = TRUE;
515 DeviceCapabilities->DockDevice = FALSE;
516 DeviceCapabilities->UniqueID = FALSE;
517 DeviceCapabilities->SilentInstall = FALSE;
518 DeviceCapabilities->RawDeviceOK = FALSE;
519 DeviceCapabilities->SurpriseRemovalOK = FALSE;
520 DeviceCapabilities->HardwareDisabled = FALSE;
521 //DeviceCapabilities->NoDisplayInUI = FALSE;
522 DeviceCapabilities->Address = UsbChildExtension->PortNumber;
523 DeviceCapabilities->UINumber = 0;
524 DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
525 for (i = 1; i < PowerSystemMaximum; i++)
526 DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
527 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined;
528 DeviceCapabilities->D1Latency = 0;
529 DeviceCapabilities->D2Latency = 0;
530 DeviceCapabilities->D3Latency = 0;
531 Status = STATUS_SUCCESS;
532 break;
533 }
534 case IRP_MN_QUERY_RESOURCES:
535 {
536 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
537
538 Information = Irp->IoStatus.Information;
539 Status = Irp->IoStatus.Status;
540 break;
541 }
542 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
543 {
544 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
545
546 Information = Irp->IoStatus.Information;
547 Status = Irp->IoStatus.Status;
548 break;
549 }
550 case IRP_MN_QUERY_DEVICE_TEXT:
551 {
552 Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
553 break;
554 }
555 case IRP_MN_QUERY_ID:
556 {
557 Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
558 break;
559 }
560 case IRP_MN_QUERY_BUS_INFORMATION:
561 {
562 PPNP_BUS_INFORMATION BusInfo;
563 BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
564 RtlCopyMemory(&BusInfo->BusTypeGuid,
565 &GUID_BUS_TYPE_USB,
566 sizeof(BusInfo->BusTypeGuid));
567 BusInfo->LegacyBusType = PNPBus;
568 // FIXME
569 BusInfo->BusNumber = 0;
570 Information = (ULONG_PTR)BusInfo;
571 Status = STATUS_SUCCESS;
572 break;
573 }
574 case IRP_MN_REMOVE_DEVICE:
575 {
576 PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
577 PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
578
579 DPRINT1("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
580
581 /* remove us from pdo list */
582 bFound = FALSE;
583 for(Index = 0; Index < USB_MAXCHILDREN; Index++)
584 {
585 if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
586 {
587 /* Remove the device */
588 Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
589
590 /* FIXME handle error */
591 ASSERT(Status == STATUS_SUCCESS);
592
593 /* remove us */
594 HubDeviceExtension->ChildDeviceObject[Index] = NULL;
595 bFound = TRUE;
596 break;
597 }
598 }
599
600 /* Complete the IRP */
601 Irp->IoStatus.Status = STATUS_SUCCESS;
602 IoCompleteRequest(Irp, IO_NO_INCREMENT);
603
604 if (bFound)
605 {
606 /* Delete the device object */
607 IoDeleteDevice(DeviceObject);
608 }
609
610 return STATUS_SUCCESS;
611 }
612 case IRP_MN_QUERY_DEVICE_RELATIONS:
613 {
614 /* only target relations are supported */
615 if (Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
616 {
617 /* not supported */
618 Status = Irp->IoStatus.Status;
619 break;
620 }
621
622 /* allocate device relations */
623 DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS));
624 if (!DeviceRelation)
625 {
626 /* no memory */
627 Status = STATUS_INSUFFICIENT_RESOURCES;
628 break;
629 }
630
631 /* init device relation */
632 DeviceRelation->Count = 1;
633 DeviceRelation->Objects[0] = DeviceObject;
634 ObReferenceObject(DeviceRelation->Objects[0]);
635
636 /* store result */
637 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
638 Status = STATUS_SUCCESS;
639 break;
640 }
641 case IRP_MN_QUERY_STOP_DEVICE:
642 case IRP_MN_QUERY_REMOVE_DEVICE:
643 {
644 /* Sure, no problem */
645 Status = STATUS_SUCCESS;
646 Information = 0;
647 break;
648 }
649 default:
650 {
651 DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
652 Information = Irp->IoStatus.Information;
653 Status = Irp->IoStatus.Status;
654 }
655 }
656
657 Irp->IoStatus.Information = Information;
658 Irp->IoStatus.Status = Status;
659 IoCompleteRequest(Irp, IO_NO_INCREMENT);
660 return Status;
661 }
662