[SHELL32] Fix Control_RunDLLW (#5400)
[reactos.git] / drivers / usb / usbccgp / fdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbccgp/fdo.c
5 * PURPOSE: USB device driver.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 * Cameron Gutman
10 */
11
12 #include "usbccgp.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 NTSTATUS
18 NTAPI
19 FDO_QueryCapabilitiesCompletionRoutine(
20 IN PDEVICE_OBJECT DeviceObject,
21 IN PIRP Irp,
22 IN PVOID Context)
23 {
24 /* Set event */
25 KeSetEvent((PRKEVENT)Context, 0, FALSE);
26
27 /* Completion is done in the HidClassFDO_QueryCapabilities routine */
28 return STATUS_MORE_PROCESSING_REQUIRED;
29 }
30
31 NTSTATUS
32 FDO_QueryCapabilities(
33 IN PDEVICE_OBJECT DeviceObject,
34 IN OUT PDEVICE_CAPABILITIES Capabilities)
35 {
36 PIRP Irp;
37 KEVENT Event;
38 NTSTATUS Status;
39 PIO_STACK_LOCATION IoStack;
40 PFDO_DEVICE_EXTENSION FDODeviceExtension;
41
42 /* Get device extension */
43 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
44 ASSERT(FDODeviceExtension->Common.IsFDO);
45
46 /* Init event */
47 KeInitializeEvent(&Event, NotificationEvent, FALSE);
48
49 /* Now allocate the irp */
50 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
51 if (!Irp)
52 {
53 /* No memory */
54 return STATUS_INSUFFICIENT_RESOURCES;
55 }
56
57 /* Get next stack location */
58 IoStack = IoGetNextIrpStackLocation(Irp);
59
60 /* Init stack location */
61 IoStack->MajorFunction = IRP_MJ_PNP;
62 IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
63 IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;
64
65 /* Set completion routine */
66 IoSetCompletionRoutine(Irp,
67 FDO_QueryCapabilitiesCompletionRoutine,
68 (PVOID)&Event,
69 TRUE,
70 TRUE,
71 TRUE);
72
73 /* Init capabilities */
74 RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
75 Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
76 Capabilities->Version = 1; // FIXME hardcoded constant
77 Capabilities->Address = MAXULONG;
78 Capabilities->UINumber = MAXULONG;
79
80 /* Pnp irps have default completion code */
81 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
82
83 /* Call lower device */
84 Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
85 if (Status == STATUS_PENDING)
86 {
87 /* Wait for completion */
88 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
89 }
90
91 /* Get status */
92 Status = Irp->IoStatus.Status;
93
94 /* Complete request */
95 IoFreeIrp(Irp);
96
97 /* Done */
98 return Status;
99 }
100
101 NTSTATUS
102 FDO_DeviceRelations(
103 PDEVICE_OBJECT DeviceObject,
104 PIRP Irp)
105 {
106 ULONG DeviceCount = 0;
107 ULONG Index;
108 PDEVICE_RELATIONS DeviceRelations;
109 PIO_STACK_LOCATION IoStack;
110 PFDO_DEVICE_EXTENSION FDODeviceExtension;
111
112 /* Get device extension */
113 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
114
115 /* Get current irp stack location */
116 IoStack = IoGetCurrentIrpStackLocation(Irp);
117
118 /* Check if relation type is BusRelations */
119 if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
120 {
121 /* FDO always only handles bus relations */
122 return STATUS_SUCCESS;
123 }
124
125 /* Go through array and count device objects */
126 for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++)
127 {
128 if (FDODeviceExtension->ChildPDO[Index])
129 {
130 /* Child pdo */
131 DeviceCount++;
132 }
133 }
134
135 /* Allocate device relations */
136 DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool,
137 sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
138 if (!DeviceRelations)
139 {
140 /* No memory */
141 return STATUS_INSUFFICIENT_RESOURCES;
142 }
143
144 /* Add device objects */
145 for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++)
146 {
147 if (FDODeviceExtension->ChildPDO[Index])
148 {
149 /* Store child pdo */
150 DeviceRelations->Objects[DeviceRelations->Count] = FDODeviceExtension->ChildPDO[Index];
151
152 /* Add reference */
153 ObReferenceObject(FDODeviceExtension->ChildPDO[Index]);
154
155 /* Increment count */
156 DeviceRelations->Count++;
157 }
158 }
159
160 /* Store result */
161 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
162 Irp->IoStatus.Status = STATUS_SUCCESS;
163
164 /* Request completed successfully */
165 return STATUS_SUCCESS;
166 }
167
168 NTSTATUS
169 FDO_CreateChildPdo(
170 IN PDEVICE_OBJECT DeviceObject)
171 {
172 NTSTATUS Status;
173 PDEVICE_OBJECT PDODeviceObject;
174 PPDO_DEVICE_EXTENSION PDODeviceExtension;
175 PFDO_DEVICE_EXTENSION FDODeviceExtension;
176 ULONG Index;
177
178 /* Get device extension */
179 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
180 ASSERT(FDODeviceExtension->Common.IsFDO);
181
182 /* Lets create array for the child PDO */
183 FDODeviceExtension->ChildPDO = AllocateItem(NonPagedPool,
184 sizeof(PDEVICE_OBJECT) * FDODeviceExtension->FunctionDescriptorCount);
185 if (!FDODeviceExtension->ChildPDO)
186 {
187 /* No memory */
188 return STATUS_INSUFFICIENT_RESOURCES;
189 }
190
191 /* Create pdo for each function */
192 for(Index = 0; Index < FDODeviceExtension->FunctionDescriptorCount; Index++)
193 {
194 /* Create the PDO */
195 Status = IoCreateDevice(FDODeviceExtension->DriverObject,
196 sizeof(PDO_DEVICE_EXTENSION),
197 NULL,
198 FILE_DEVICE_USB,
199 FILE_AUTOGENERATED_DEVICE_NAME,
200 FALSE,
201 &PDODeviceObject);
202 if (!NT_SUCCESS(Status))
203 {
204 /* Failed to create device object */
205 DPRINT1("IoCreateDevice failed with %x\n", Status);
206 return Status;
207 }
208
209 /* Store in array */
210 FDODeviceExtension->ChildPDO[Index] = PDODeviceObject;
211
212 /* Get device extension */
213 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)PDODeviceObject->DeviceExtension;
214 RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
215
216 /* Init device extension */
217 PDODeviceExtension->Common.IsFDO = FALSE;
218 PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index];
219 PDODeviceExtension->NextDeviceObject = DeviceObject;
220 PDODeviceExtension->FunctionIndex = Index;
221 PDODeviceExtension->FDODeviceExtension = FDODeviceExtension;
222 PDODeviceExtension->InterfaceList = FDODeviceExtension->InterfaceList;
223 PDODeviceExtension->InterfaceListCount = FDODeviceExtension->InterfaceListCount;
224 PDODeviceExtension->ConfigurationHandle = FDODeviceExtension->ConfigurationHandle;
225 PDODeviceExtension->ConfigurationDescriptor = FDODeviceExtension->ConfigurationDescriptor;
226 RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
227 RtlCopyMemory(&PDODeviceExtension->DeviceDescriptor, FDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
228
229 /* Patch the stack size */
230 PDODeviceObject->StackSize = DeviceObject->StackSize + 1;
231
232 /* Set device flags */
233 PDODeviceObject->Flags |= DO_DIRECT_IO | DO_MAP_IO_BUFFER;
234
235 /* Device is initialized */
236 PDODeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
237 }
238
239 /* Done */
240 return STATUS_SUCCESS;
241 }
242
243 NTSTATUS
244 FDO_StartDevice(
245 PDEVICE_OBJECT DeviceObject,
246 PIRP Irp)
247 {
248 NTSTATUS Status;
249 PFDO_DEVICE_EXTENSION FDODeviceExtension;
250
251 /* Get device extension */
252 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
253 ASSERT(FDODeviceExtension->Common.IsFDO);
254
255 /* First start lower device */
256 if (IoForwardIrpSynchronously(FDODeviceExtension->NextDeviceObject, Irp))
257 {
258 Status = Irp->IoStatus.Status;
259 }
260 else
261 {
262 Status = STATUS_UNSUCCESSFUL;
263 }
264
265 if (!NT_SUCCESS(Status))
266 {
267 /* Failed to start lower device */
268 DPRINT1("FDO_StartDevice lower device failed to start with %x\n", Status);
269 return Status;
270 }
271
272 /* Get descriptors */
273 Status = USBCCGP_GetDescriptors(DeviceObject);
274 if (!NT_SUCCESS(Status))
275 {
276 /* Failed to start lower device */
277 DPRINT1("FDO_StartDevice failed to get descriptors with %x\n", Status);
278 return Status;
279 }
280
281 /* Get capabilities */
282 Status = FDO_QueryCapabilities(DeviceObject,
283 &FDODeviceExtension->Capabilities);
284 if (!NT_SUCCESS(Status))
285 {
286 /* Failed to start lower device */
287 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
288 return Status;
289 }
290
291 /* Now select the configuration */
292 Status = USBCCGP_SelectConfiguration(DeviceObject, FDODeviceExtension);
293 if (!NT_SUCCESS(Status))
294 {
295 /* Failed to select interface */
296 DPRINT1("FDO_StartDevice failed to get capabilities with %x\n", Status);
297 return Status;
298 }
299
300 /* Query bus interface */
301 USBCCGP_QueryInterface(FDODeviceExtension->NextDeviceObject,
302 &FDODeviceExtension->BusInterface);
303
304 /* Now enumerate the functions */
305 Status = USBCCGP_EnumerateFunctions(DeviceObject);
306 if (!NT_SUCCESS(Status))
307 {
308 /* Failed to enumerate functions */
309 DPRINT1("Failed to enumerate functions with %x\n", Status);
310 return Status;
311 }
312
313 /* Sanity checks */
314 ASSERT(FDODeviceExtension->FunctionDescriptorCount);
315 ASSERT(FDODeviceExtension->FunctionDescriptor);
316 DumpFunctionDescriptor(FDODeviceExtension->FunctionDescriptor,
317 FDODeviceExtension->FunctionDescriptorCount);
318
319 /* Now create the pdo */
320 Status = FDO_CreateChildPdo(DeviceObject);
321 if (!NT_SUCCESS(Status))
322 {
323 /* Failed */
324 DPRINT1("FDO_CreateChildPdo failed with %x\n", Status);
325 return Status;
326 }
327
328 /* Inform pnp manager of new device objects */
329 IoInvalidateDeviceRelations(FDODeviceExtension->PhysicalDeviceObject,
330 BusRelations);
331
332 /* Done */
333 DPRINT("[USBCCGP] FDO initialized successfully\n");
334 return Status;
335 }
336
337 NTSTATUS
338 FDO_CloseConfiguration(
339 IN PDEVICE_OBJECT DeviceObject)
340 {
341 NTSTATUS Status;
342 PURB Urb;
343 PFDO_DEVICE_EXTENSION FDODeviceExtension;
344
345 /* Get device extension */
346 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
347 ASSERT(FDODeviceExtension->Common.IsFDO);
348
349 /* Nothing to do if we're not configured */
350 if (FDODeviceExtension->ConfigurationDescriptor == NULL ||
351 FDODeviceExtension->InterfaceList == NULL)
352 {
353 return STATUS_SUCCESS;
354 }
355
356 /* Now allocate the urb */
357 Urb = USBD_CreateConfigurationRequestEx(FDODeviceExtension->ConfigurationDescriptor,
358 FDODeviceExtension->InterfaceList);
359 if (!Urb)
360 {
361 /* No memory */
362 return STATUS_INSUFFICIENT_RESOURCES;
363 }
364
365 /* Clear configuration descriptor to make it an unconfigure request */
366 Urb->UrbSelectConfiguration.ConfigurationDescriptor = NULL;
367
368 /* Submit urb */
369 Status = USBCCGP_SyncUrbRequest(FDODeviceExtension->NextDeviceObject, Urb);
370 if (!NT_SUCCESS(Status))
371 {
372 /* Failed to set configuration */
373 DPRINT1("USBCCGP_SyncUrbRequest failed to unconfigure device\n", Status);
374 }
375
376 ExFreePool(Urb);
377 return Status;
378 }
379
380
381 NTSTATUS
382 FDO_HandlePnp(
383 PDEVICE_OBJECT DeviceObject,
384 PIRP Irp)
385 {
386 PIO_STACK_LOCATION IoStack;
387 NTSTATUS Status;
388 PFDO_DEVICE_EXTENSION FDODeviceExtension;
389
390 /* Get device extension */
391 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
392 ASSERT(FDODeviceExtension->Common.IsFDO);
393
394
395 /* Get stack location */
396 IoStack = IoGetCurrentIrpStackLocation(Irp);
397 DPRINT("[USBCCGP] PnP Minor %x\n", IoStack->MinorFunction);
398 switch(IoStack->MinorFunction)
399 {
400 case IRP_MN_REMOVE_DEVICE:
401 {
402 // Unconfigure device */
403 DPRINT1("[USBCCGP] FDO IRP_MN_REMOVE\n");
404 FDO_CloseConfiguration(DeviceObject);
405
406 /* Send the IRP down the stack */
407 Irp->IoStatus.Status = STATUS_SUCCESS;
408 IoSkipCurrentIrpStackLocation(Irp);
409 Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
410
411 /* Detach from the device stack */
412 IoDetachDevice(FDODeviceExtension->NextDeviceObject);
413
414 /* Delete the device object */
415 IoDeleteDevice(DeviceObject);
416
417 /* Request completed */
418 break;
419 }
420 case IRP_MN_START_DEVICE:
421 {
422 /* Start the device */
423 Status = FDO_StartDevice(DeviceObject, Irp);
424 break;
425 }
426 case IRP_MN_QUERY_DEVICE_RELATIONS:
427 {
428 /* Handle device relations */
429 Status = FDO_DeviceRelations(DeviceObject, Irp);
430 if (!NT_SUCCESS(Status))
431 {
432 break;
433 }
434
435 /* Forward irp to next device object */
436 IoSkipCurrentIrpStackLocation(Irp);
437 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
438 }
439 case IRP_MN_QUERY_CAPABILITIES:
440 {
441 /* Copy capabilities */
442 RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities,
443 &FDODeviceExtension->Capabilities,
444 sizeof(DEVICE_CAPABILITIES));
445 Status = STATUS_UNSUCCESSFUL;
446
447 if (IoForwardIrpSynchronously(FDODeviceExtension->NextDeviceObject, Irp))
448 {
449 Status = Irp->IoStatus.Status;
450 if (NT_SUCCESS(Status))
451 {
452 IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE;
453 }
454 }
455 break;
456 }
457 case IRP_MN_QUERY_REMOVE_DEVICE:
458 case IRP_MN_QUERY_STOP_DEVICE:
459 {
460 /* Sure */
461 Irp->IoStatus.Status = STATUS_SUCCESS;
462
463 /* Forward irp to next device object */
464 IoSkipCurrentIrpStackLocation(Irp);
465 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
466 }
467 default:
468 {
469 /* Forward irp to next device object */
470 IoSkipCurrentIrpStackLocation(Irp);
471 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
472 }
473
474 }
475
476 /* Complete request */
477 Irp->IoStatus.Status = Status;
478 IoCompleteRequest(Irp, IO_NO_INCREMENT);
479 return Status;
480 }
481
482 NTSTATUS
483 FDO_HandleResetCyclePort(
484 PDEVICE_OBJECT DeviceObject,
485 PIRP Irp)
486 {
487 PIO_STACK_LOCATION IoStack;
488 NTSTATUS Status;
489 PFDO_DEVICE_EXTENSION FDODeviceExtension;
490 PLIST_ENTRY ListHead, Entry;
491 LIST_ENTRY TempList;
492 PUCHAR ResetActive;
493 PIRP ListIrp;
494 KIRQL OldLevel;
495
496 /* Get device extension */
497 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
498 ASSERT(FDODeviceExtension->Common.IsFDO);
499
500 /* Get stack location */
501 IoStack = IoGetCurrentIrpStackLocation(Irp);
502 DPRINT("FDO_HandleResetCyclePort IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
503
504 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT)
505 {
506 /* Use reset port list */
507 ListHead = &FDODeviceExtension->ResetPortListHead;
508 ResetActive = &FDODeviceExtension->ResetPortActive;
509 }
510 else
511 {
512 /* Use cycle port list */
513 ListHead = &FDODeviceExtension->CyclePortListHead;
514 ResetActive = &FDODeviceExtension->CyclePortActive;
515 }
516
517 /* Acquire lock */
518 KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel);
519
520 if (*ResetActive)
521 {
522 /* Insert into pending list */
523 InsertTailList(ListHead, &Irp->Tail.Overlay.ListEntry);
524
525 /* Mark irp pending */
526 IoMarkIrpPending(Irp);
527 Status = STATUS_PENDING;
528
529 /* Release lock */
530 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel);
531 }
532 else
533 {
534 /* Mark reset active */
535 *ResetActive = TRUE;
536
537 /* Release lock */
538 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel);
539
540 /* Forward request synchronized */
541 NT_VERIFY(IoForwardIrpSynchronously(FDODeviceExtension->NextDeviceObject, Irp));
542
543 /* Reacquire lock */
544 KeAcquireSpinLock(&FDODeviceExtension->Lock, &OldLevel);
545
546 /* Mark reset as completed */
547 *ResetActive = FALSE;
548
549 /* Move all requests into temporary list */
550 InitializeListHead(&TempList);
551 while(!IsListEmpty(ListHead))
552 {
553 Entry = RemoveHeadList(ListHead);
554 InsertTailList(&TempList, Entry);
555 }
556
557 /* Release lock */
558 KeReleaseSpinLock(&FDODeviceExtension->Lock, OldLevel);
559
560 /* Complete pending irps */
561 while(!IsListEmpty(&TempList))
562 {
563 Entry = RemoveHeadList(&TempList);
564 ListIrp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
565
566 /* Complete request with status success */
567 ListIrp->IoStatus.Status = STATUS_SUCCESS;
568 IoCompleteRequest(ListIrp, IO_NO_INCREMENT);
569 }
570
571 /* Status success */
572 Status = STATUS_SUCCESS;
573 }
574
575 return Status;
576 }
577
578
579
580 NTSTATUS
581 FDO_HandleInternalDeviceControl(
582 PDEVICE_OBJECT DeviceObject,
583 PIRP Irp)
584 {
585 PIO_STACK_LOCATION IoStack;
586 NTSTATUS Status;
587 PFDO_DEVICE_EXTENSION FDODeviceExtension;
588
589 /* Get device extension */
590 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
591 ASSERT(FDODeviceExtension->Common.IsFDO);
592
593 /* Get stack location */
594 IoStack = IoGetCurrentIrpStackLocation(Irp);
595
596 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT ||
597 IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT)
598 {
599 /* Handle reset / cycle ports */
600 Status = FDO_HandleResetCyclePort(DeviceObject, Irp);
601 DPRINT("FDO_HandleResetCyclePort Status %x\n", Status);
602 if (Status != STATUS_PENDING)
603 {
604 /* Complete request */
605 Irp->IoStatus.Status = Status;
606 IoCompleteRequest(Irp, IO_NO_INCREMENT);
607 }
608 return Status;
609 }
610
611 /* Forward and forget request */
612 IoSkipCurrentIrpStackLocation(Irp);
613 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
614 }
615
616 NTSTATUS
617 FDO_HandleSystemControl(
618 PDEVICE_OBJECT DeviceObject,
619 PIRP Irp)
620 {
621 PFDO_DEVICE_EXTENSION FDODeviceExtension;
622
623 /* Get device extension */
624 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
625 ASSERT(FDODeviceExtension->Common.IsFDO);
626
627 /* Forward and forget request */
628 IoSkipCurrentIrpStackLocation(Irp);
629 return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
630 }
631
632 NTSTATUS
633 FDO_Dispatch(
634 PDEVICE_OBJECT DeviceObject,
635 PIRP Irp)
636 {
637 PIO_STACK_LOCATION IoStack;
638 NTSTATUS Status;
639 PFDO_DEVICE_EXTENSION FDODeviceExtension;
640
641 /* Get device extension */
642 FDODeviceExtension = DeviceObject->DeviceExtension;
643 ASSERT(FDODeviceExtension->Common.IsFDO);
644
645 /* Get stack location */
646 IoStack = IoGetCurrentIrpStackLocation(Irp);
647
648 switch(IoStack->MajorFunction)
649 {
650 case IRP_MJ_PNP:
651 return FDO_HandlePnp(DeviceObject, Irp);
652 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
653 return FDO_HandleInternalDeviceControl(DeviceObject, Irp);
654 case IRP_MJ_POWER:
655 PoStartNextPowerIrp(Irp);
656 IoSkipCurrentIrpStackLocation(Irp);
657 return PoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
658 case IRP_MJ_SYSTEM_CONTROL:
659 return FDO_HandleSystemControl(DeviceObject, Irp);
660 default:
661 DPRINT1("FDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
662 ASSERT(FALSE);
663 Status = Irp->IoStatus.Status;
664 IoCompleteRequest(Irp, IO_NO_INCREMENT);
665 return Status;
666 }
667
668 }