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/pdo.c
5 * PURPOSE: USB device driver.
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
20 USBCCGP_PdoHandleQueryDeviceText(
21 IN PDEVICE_OBJECT DeviceObject
,
24 PIO_STACK_LOCATION IoStack
;
26 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
27 LPWSTR GenericString
= L
"Composite USB Device";
30 // get current irp stack location
32 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
35 // get device extension
37 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
40 // check if type is description
42 if (IoStack
->Parameters
.QueryDeviceText
.DeviceTextType
!= DeviceTextDescription
)
45 // we only handle description
47 return Irp
->IoStatus
.Status
;
51 // is there a device description
53 if (PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
)
58 Buffer
= AllocateItem(NonPagedPool
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
+ sizeof(WCHAR
));
64 return STATUS_INSUFFICIENT_RESOURCES
;
70 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
71 RtlCopyMemory(Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
);
72 return STATUS_SUCCESS
;
76 // FIXME use GenericCompositeUSBDeviceString
79 Buffer
= AllocateItem(PagedPool
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
85 return STATUS_INSUFFICIENT_RESOURCES
;
87 RtlCopyMemory(Buffer
, GenericString
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
88 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
90 return STATUS_SUCCESS
;
94 USBCCGP_PdoHandleDeviceRelations(
95 IN PDEVICE_OBJECT DeviceObject
,
98 PDEVICE_RELATIONS DeviceRelations
;
99 PIO_STACK_LOCATION IoStack
;
101 DPRINT("USBCCGP_PdoHandleDeviceRelations\n");
104 // get current irp stack location
106 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
109 // check if relation type is BusRelations
111 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
114 // PDO handles only target device relation
116 return Irp
->IoStatus
.Status
;
120 // allocate device relations
122 DeviceRelations
= (PDEVICE_RELATIONS
)AllocateItem(PagedPool
, sizeof(DEVICE_RELATIONS
));
123 if (!DeviceRelations
)
128 return STATUS_INSUFFICIENT_RESOURCES
;
132 // initialize device relations
134 DeviceRelations
->Count
= 1;
135 DeviceRelations
->Objects
[0] = DeviceObject
;
136 ObReferenceObject(DeviceObject
);
141 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
144 // completed successfully
146 return STATUS_SUCCESS
;
150 USBCCGP_PdoAppendInterfaceNumber(
152 IN ULONG InterfaceNumber
,
153 OUT LPWSTR
*OutString
)
155 ULONG Length
= 0, StringLength
;
159 // count length of string
164 StringLength
= wcslen(String
) + 1;
165 Length
+= StringLength
;
166 Length
+= 6; //&MI_XX
167 String
+= StringLength
;
171 // now allocate the buffer
173 String
= AllocateItem(NonPagedPool
, (Length
+ 2) * sizeof(WCHAR
));
179 return STATUS_INSUFFICIENT_RESOURCES
;
189 StringLength
= swprintf(String
, L
"%s&MI_%02x", DeviceId
, InterfaceNumber
) + 1;
190 Length
= wcslen(DeviceId
) + 1;
191 DPRINT("String %p\n", String
);
196 String
+= StringLength
;
203 return STATUS_SUCCESS
;
208 USBCCGP_PdoHandleQueryId(
209 PDEVICE_OBJECT DeviceObject
,
212 PIO_STACK_LOCATION IoStack
;
213 PUNICODE_STRING DeviceString
= NULL
;
214 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
219 // get current irp stack location
221 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
224 // get device extension
226 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
229 if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryDeviceID
)
232 // handle query device id
234 Status
= USBCCGP_SyncForwardIrp(PDODeviceExtension
->NextDeviceObject
, Irp
);
235 if (NT_SUCCESS(Status
))
240 Buffer
= AllocateItem(NonPagedPool
, (wcslen((LPWSTR
)Irp
->IoStatus
.Information
) + 7) * sizeof(WCHAR
));
244 // append interface number
246 ASSERT(Irp
->IoStatus
.Information
);
247 swprintf(Buffer
, L
"%s&MI_%02x", (LPWSTR
)Irp
->IoStatus
.Information
, PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
248 DPRINT("BusQueryDeviceID %S\n", Buffer
);
250 ExFreePool((PVOID
)Irp
->IoStatus
.Information
);
251 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
258 Status
= STATUS_INSUFFICIENT_RESOURCES
;
263 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryHardwareIDs
)
266 // handle instance id
268 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->HardwareId
;
270 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryInstanceID
)
273 // handle instance id
275 Buffer
= AllocateItem(NonPagedPool
, 5 * sizeof(WCHAR
));
281 return STATUS_INSUFFICIENT_RESOURCES
;
285 // use function number
287 swprintf(Buffer
, L
"%04x", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
288 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
289 return STATUS_SUCCESS
;
291 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryCompatibleIDs
)
294 // handle instance id
296 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->CompatibleId
;
303 return Irp
->IoStatus
.Status
;
309 ASSERT(DeviceString
!= NULL
);
314 Buffer
= AllocateItem(NonPagedPool
, DeviceString
->Length
+ sizeof(WCHAR
));
320 return STATUS_INSUFFICIENT_RESOURCES
;
326 RtlCopyMemory(Buffer
, DeviceString
->Buffer
, DeviceString
->Length
);
327 Buffer
[DeviceString
->Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
328 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
330 return STATUS_SUCCESS
;
335 PDEVICE_OBJECT DeviceObject
,
338 PIO_STACK_LOCATION IoStack
;
339 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
344 // get current stack location
346 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
349 // get device extension
351 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
356 ASSERT(PDODeviceExtension
->Common
.IsFDO
== FALSE
);
358 switch(IoStack
->MinorFunction
)
360 case IRP_MN_QUERY_DEVICE_RELATIONS
:
363 // handle device relations
365 Status
= USBCCGP_PdoHandleDeviceRelations(DeviceObject
, Irp
);
368 case IRP_MN_QUERY_DEVICE_TEXT
:
371 // handle query device text
373 Status
= USBCCGP_PdoHandleQueryDeviceText(DeviceObject
, Irp
);
376 case IRP_MN_QUERY_ID
:
381 Status
= USBCCGP_PdoHandleQueryId(DeviceObject
, Irp
);
384 case IRP_MN_REMOVE_DEVICE
:
387 // remove us from the fdo's pdo list
390 for(Index
= 0; Index
< PDODeviceExtension
->FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
392 if (PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] == DeviceObject
)
397 PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] = NULL
;
406 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
407 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
412 // Delete the device object
414 IoDeleteDevice(DeviceObject
);
416 return STATUS_SUCCESS
;
418 case IRP_MN_QUERY_CAPABILITIES
:
421 // copy device capabilities
423 RtlCopyMemory(IoStack
->Parameters
.DeviceCapabilities
.Capabilities
, &PDODeviceExtension
->Capabilities
, sizeof(DEVICE_CAPABILITIES
));
425 /* Complete the IRP */
426 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
427 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
428 return STATUS_SUCCESS
;
430 case IRP_MN_QUERY_REMOVE_DEVICE
:
431 case IRP_MN_QUERY_STOP_DEVICE
:
436 Status
= STATUS_SUCCESS
;
439 case IRP_MN_START_DEVICE
:
444 DPRINT("[USBCCGP] PDO IRP_MN_START\n");
445 Status
= STATUS_SUCCESS
;
448 case IRP_MN_QUERY_INTERFACE
:
451 // forward to lower device object
453 IoSkipCurrentIrpStackLocation(Irp
);
454 return IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
461 Status
= Irp
->IoStatus
.Status
;
469 if (Status
!= STATUS_PENDING
)
474 Irp
->IoStatus
.Status
= Status
;
479 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
490 USBCCGP_BuildConfigurationDescriptor(
491 PDEVICE_OBJECT DeviceObject
,
494 PIO_STACK_LOCATION IoStack
;
495 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
496 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
;
497 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
498 ULONG TotalSize
, Index
;
503 UCHAR InterfaceNumber
;
506 // get current stack location
508 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
510 DPRINT("USBCCGP_BuildConfigurationDescriptor\n");
513 // get device extension
515 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
518 // get configuration descriptor
520 ConfigurationDescriptor
= PDODeviceExtension
->ConfigurationDescriptor
;
523 // calculate size of configuration descriptor
525 TotalSize
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
527 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
530 // get current interface descriptor
532 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
533 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
536 // add to size and move to next descriptor
538 TotalSize
+= InterfaceDescriptor
->bLength
;
539 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
543 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
546 // reached end of configuration descriptor
552 // association descriptors are removed
554 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
556 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
558 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
561 // reached next descriptor
567 // include alternate descriptor
574 TotalSize
+= InterfaceDescriptor
->bLength
;
578 // move to next descriptor
580 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
585 // now allocate temporary buffer for the configuration descriptor
587 Buffer
= AllocateItem(NonPagedPool
, TotalSize
);
591 // failed to allocate buffer
593 DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize
);
594 return STATUS_INSUFFICIENT_RESOURCES
;
598 // first copy the configuration descriptor
600 RtlCopyMemory(Buffer
, ConfigurationDescriptor
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
601 BufferPtr
= (PUCHAR
)((ULONG_PTR
)Buffer
+ ConfigurationDescriptor
->bLength
);
603 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
606 // get current interface descriptor
608 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
609 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
612 // copy descriptor and move to next descriptor
614 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
615 BufferPtr
+= InterfaceDescriptor
->bLength
;
616 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
620 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
623 // reached end of configuration descriptor
629 // association descriptors are removed
631 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
633 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
635 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
638 // reached next descriptor
644 // include alternate descriptor
646 DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor
, InterfaceDescriptor
->bAlternateSetting
, InterfaceDescriptor
->bInterfaceNumber
);
652 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
653 BufferPtr
+= InterfaceDescriptor
->bLength
;
657 // move to next descriptor
659 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
664 // modify configuration descriptor
666 ConfigurationDescriptor
= Buffer
;
667 ConfigurationDescriptor
->wTotalLength
= (USHORT
)TotalSize
;
668 ConfigurationDescriptor
->bNumInterfaces
= PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
;
673 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
679 Size
= min(TotalSize
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
680 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, Buffer
, Size
);
685 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= Size
;
695 return STATUS_SUCCESS
;
699 USBCCGP_PDOSelectConfiguration(
700 PDEVICE_OBJECT DeviceObject
,
703 PIO_STACK_LOCATION IoStack
;
704 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
706 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
707 ULONG InterfaceIndex
, Length
;
708 PUSBD_INTERFACE_LIST_ENTRY Entry
;
709 ULONG NeedSelect
, FoundInterface
;
713 // get current stack location
715 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
718 // get device extension
720 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
725 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
729 // is there already an configuration handle
731 if (Urb
->UrbSelectConfiguration
.ConfigurationHandle
)
736 return STATUS_SUCCESS
;
740 // if there is no configuration descriptor, unconfigure the device
742 if (Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
== NULL
)
744 return STATUS_SUCCESS
;
748 //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
749 //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
750 //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
751 //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
753 // available buffer length
754 Length
= Urb
->UrbSelectConfiguration
.Hdr
.Length
- FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION
, Interface
.Length
);
757 // check all interfaces
759 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
764 DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x Length %lu InterfaceInformation->Length %lu\n", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
, InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, Length
, InterfaceInformation
->Length
);
765 ASSERT(InterfaceInformation
->Length
);
767 // search for the interface in the local interface list
769 FoundInterface
= FALSE
;
770 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; InterfaceIndex
++)
772 if (PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[InterfaceIndex
]->bInterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
774 // found interface entry
775 FoundInterface
= TRUE
;
785 DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
786 return STATUS_INVALID_PARAMETER
;
790 // now query the total interface list
793 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->InterfaceListCount
; InterfaceIndex
++)
795 if (PDODeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->InterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
800 Entry
= &PDODeviceExtension
->InterfaceList
[InterfaceIndex
];
811 // corruption detected
817 if (Entry
->InterfaceDescriptor
->bAlternateSetting
== InterfaceInformation
->AlternateSetting
)
819 for(InterfaceIndex
= 0; InterfaceIndex
< InterfaceInformation
->NumberOfPipes
; InterfaceIndex
++)
821 if (InterfaceInformation
->Pipes
[InterfaceIndex
].MaximumTransferSize
!= Entry
->Interface
->Pipes
[InterfaceIndex
].MaximumTransferSize
)
833 // need select as the interface number differ
841 // interface is already selected
843 ASSERT(Length
>= Entry
->Interface
->Length
);
844 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
847 // adjust remaining buffer size
849 ASSERT(Entry
->Interface
->Length
);
850 Length
-= Entry
->Interface
->Length
;
853 // move to next output interface information
855 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
862 DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
863 ASSERT(InterfaceInformation
->Length
== Entry
->Interface
->Length
);
868 NewUrb
= AllocateItem(NonPagedPool
, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
));
874 return STATUS_INSUFFICIENT_RESOURCES
;
878 // now prepare interface urb
880 UsbBuildSelectInterfaceRequest(NewUrb
, (USHORT
)GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
), PDODeviceExtension
->ConfigurationHandle
, InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
);
883 // now select the interface
885 Status
= USBCCGP_SyncUrbRequest(PDODeviceExtension
->NextDeviceObject
, NewUrb
);
886 DPRINT1("SelectInterface Status %x\n", Status
);
888 if (!NT_SUCCESS(Status
))
897 // update configuration info
899 ASSERT(Entry
->Interface
->Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
900 ASSERT(Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
901 RtlCopyMemory(Entry
->Interface
, &NewUrb
->UrbSelectInterface
.Interface
, NewUrb
->UrbSelectInterface
.Interface
.Length
);
904 // update provided interface information
906 ASSERT(Length
>= Entry
->Interface
->Length
);
907 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
910 // decrement remaining buffer size
912 ASSERT(Entry
->Interface
->Length
);
913 Length
-= Entry
->Interface
->Length
;
916 // adjust output buffer offset
918 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
929 // store configuration handle
931 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= PDODeviceExtension
->ConfigurationHandle
;
933 DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
938 return STATUS_SUCCESS
;
942 PDO_HandleInternalDeviceControl(
943 PDEVICE_OBJECT DeviceObject
,
946 PIO_STACK_LOCATION IoStack
;
947 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
952 // get current stack location
954 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
957 // get device extension
959 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
961 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
966 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
968 DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb
->UrbHeader
.Function
);
970 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_SELECT_CONFIGURATION
)
973 // select configuration
975 Status
= USBCCGP_PDOSelectConfiguration(DeviceObject
, Irp
);
976 Irp
->IoStatus
.Status
= Status
;
977 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
980 else if (Urb
->UrbHeader
.Function
== URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
)
982 if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
)
985 // is the buffer big enough
987 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
< sizeof(USB_DEVICE_DESCRIPTOR
))
990 // invalid buffer size
992 DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
993 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
994 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
995 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
996 return STATUS_INVALID_BUFFER_SIZE
;
1000 // copy device descriptor
1002 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1003 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, &PDODeviceExtension
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
1004 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1005 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1006 return STATUS_SUCCESS
;
1008 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_CONFIGURATION_DESCRIPTOR_TYPE
)
1011 // build configuration descriptor
1013 Status
= USBCCGP_BuildConfigurationDescriptor(DeviceObject
, Irp
);
1014 Irp
->IoStatus
.Status
= Status
;
1015 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1018 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_STRING_DESCRIPTOR_TYPE
)
1020 PUSB_STRING_DESCRIPTOR StringDescriptor
;
1023 // get the requested string descriptor
1025 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1026 Status
= USBCCGP_GetDescriptor(PDODeviceExtension
->FDODeviceExtension
->NextDeviceObject
,
1027 USB_STRING_DESCRIPTOR_TYPE
,
1028 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
,
1029 Urb
->UrbControlDescriptorRequest
.Index
,
1030 Urb
->UrbControlDescriptorRequest
.LanguageId
,
1031 (PVOID
*)&StringDescriptor
);
1032 if (NT_SUCCESS(Status
))
1034 if (StringDescriptor
->bLength
== 2)
1036 FreeItem(StringDescriptor
);
1037 Status
= STATUS_DEVICE_DATA_ERROR
;
1041 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
1042 StringDescriptor
->bString
,
1043 StringDescriptor
->bLength
+ sizeof(WCHAR
));
1044 FreeItem(StringDescriptor
);
1045 Status
= STATUS_SUCCESS
;
1048 Irp
->IoStatus
.Status
= Status
;
1049 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1055 IoSkipCurrentIrpStackLocation(Irp
);
1056 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1060 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_GET_PORT_STATUS
)
1062 IoSkipCurrentIrpStackLocation(Irp
);
1063 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1066 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_RESET_PORT
)
1068 IoSkipCurrentIrpStackLocation(Irp
);
1069 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1072 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_CYCLE_PORT
)
1074 IoSkipCurrentIrpStackLocation(Irp
);
1075 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1079 DPRINT1("IOCTL %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
);
1080 DPRINT1("InputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
1081 DPRINT1("OutputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
1082 DPRINT1("Type3InputBuffer %p\n", IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
1086 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1087 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1088 return STATUS_NOT_IMPLEMENTED
;
1093 PDEVICE_OBJECT DeviceObject
,
1097 PIO_STACK_LOCATION IoStack
;
1099 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1101 switch (IoStack
->MinorFunction
)
1103 case IRP_MN_SET_POWER
:
1104 case IRP_MN_QUERY_POWER
:
1105 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1109 Status
= Irp
->IoStatus
.Status
;
1110 PoStartNextPowerIrp(Irp
);
1111 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1118 PDEVICE_OBJECT DeviceObject
,
1121 PIO_STACK_LOCATION IoStack
;
1124 /* get stack location */
1125 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1127 switch(IoStack
->MajorFunction
)
1130 return PDO_HandlePnp(DeviceObject
, Irp
);
1131 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
1132 return PDO_HandleInternalDeviceControl(DeviceObject
, Irp
);
1134 return PDO_HandlePower(DeviceObject
, Irp
);
1136 DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack
->MajorFunction
);
1137 Status
= Irp
->IoStatus
.Status
;
1138 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);