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)
15 USBCCGP_PdoHandleQueryDeviceText(
16 IN PDEVICE_OBJECT DeviceObject
,
20 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
21 LPWSTR GenericString
= L
"Composite USB Device";
23 // get device extension
25 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
28 // is there a device description
30 if (PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
)
35 Buffer
= AllocateItem(NonPagedPool
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
+ sizeof(WCHAR
));
41 return STATUS_INSUFFICIENT_RESOURCES
;
47 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
48 RtlCopyMemory(Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
);
49 return STATUS_SUCCESS
;
53 // FIXME use GenericCompositeUSBDeviceString
56 Buffer
= AllocateItem(PagedPool
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
62 return STATUS_INSUFFICIENT_RESOURCES
;
64 RtlCopyMemory(Buffer
, GenericString
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
65 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
67 return STATUS_SUCCESS
;
71 USBCCGP_PdoHandleDeviceRelations(
72 IN PDEVICE_OBJECT DeviceObject
,
75 PDEVICE_RELATIONS DeviceRelations
;
76 PIO_STACK_LOCATION IoStack
;
78 DPRINT("USBCCGP_PdoHandleDeviceRelations\n");
81 // get current irp stack location
83 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
86 // check if relation type is BusRelations
88 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
91 // PDO handles only target device relation
93 return Irp
->IoStatus
.Status
;
97 // allocate device relations
99 DeviceRelations
= (PDEVICE_RELATIONS
)AllocateItem(PagedPool
, sizeof(DEVICE_RELATIONS
));
100 if (!DeviceRelations
)
105 return STATUS_INSUFFICIENT_RESOURCES
;
109 // initialize device relations
111 DeviceRelations
->Count
= 1;
112 DeviceRelations
->Objects
[0] = DeviceObject
;
113 ObReferenceObject(DeviceObject
);
118 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
121 // completed successfully
123 return STATUS_SUCCESS
;
127 USBCCGP_PdoAppendInterfaceNumber(
129 IN ULONG InterfaceNumber
,
130 OUT LPWSTR
*OutString
)
132 ULONG Length
= 0, StringLength
;
136 // count length of string
141 StringLength
= wcslen(String
) + 1;
142 Length
+= StringLength
;
143 Length
+= 6; //&MI_XX
144 String
+= StringLength
;
148 // now allocate the buffer
150 String
= AllocateItem(NonPagedPool
, (Length
+ 2) * sizeof(WCHAR
));
156 return STATUS_INSUFFICIENT_RESOURCES
;
166 StringLength
= swprintf(String
, L
"%s&MI_%02x", DeviceId
, InterfaceNumber
) + 1;
167 Length
= wcslen(DeviceId
) + 1;
168 DPRINT("String %p\n", String
);
173 String
+= StringLength
;
180 return STATUS_SUCCESS
;
185 USBCCGP_PdoHandleQueryId(
186 PDEVICE_OBJECT DeviceObject
,
189 PIO_STACK_LOCATION IoStack
;
190 PUNICODE_STRING DeviceString
= NULL
;
191 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
196 // get current irp stack location
198 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
201 // get device extension
203 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
206 if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryDeviceID
)
209 // handle query device id
211 Status
= USBCCGP_SyncForwardIrp(PDODeviceExtension
->NextDeviceObject
, Irp
);
212 if (NT_SUCCESS(Status
))
217 Buffer
= AllocateItem(NonPagedPool
, (wcslen((LPWSTR
)Irp
->IoStatus
.Information
) + 7) * sizeof(WCHAR
));
221 // append interface number
223 ASSERT(Irp
->IoStatus
.Information
);
224 swprintf(Buffer
, L
"%s&MI_%02x", (LPWSTR
)Irp
->IoStatus
.Information
, PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
225 DPRINT("BusQueryDeviceID %S\n", Buffer
);
227 ExFreePool((PVOID
)Irp
->IoStatus
.Information
);
228 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
235 Status
= STATUS_INSUFFICIENT_RESOURCES
;
240 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryHardwareIDs
)
243 // handle instance id
245 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->HardwareId
;
247 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryInstanceID
)
250 // handle instance id
252 Buffer
= AllocateItem(NonPagedPool
, 5 * sizeof(WCHAR
));
258 return STATUS_INSUFFICIENT_RESOURCES
;
262 // use function number
264 swprintf(Buffer
, L
"%04x", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
265 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
266 return STATUS_SUCCESS
;
268 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryCompatibleIDs
)
271 // handle instance id
273 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->CompatibleId
;
280 return Irp
->IoStatus
.Status
;
286 ASSERT(DeviceString
!= NULL
);
291 Buffer
= AllocateItem(NonPagedPool
, DeviceString
->Length
+ sizeof(WCHAR
));
297 return STATUS_INSUFFICIENT_RESOURCES
;
303 RtlCopyMemory(Buffer
, DeviceString
->Buffer
, DeviceString
->Length
);
304 Buffer
[DeviceString
->Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
305 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
307 return STATUS_SUCCESS
;
312 PDEVICE_OBJECT DeviceObject
,
315 PIO_STACK_LOCATION IoStack
;
316 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
321 // get current stack location
323 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
326 // get device extension
328 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
333 ASSERT(PDODeviceExtension
->Common
.IsFDO
== FALSE
);
335 switch(IoStack
->MinorFunction
)
337 case IRP_MN_QUERY_DEVICE_RELATIONS
:
340 // handle device relations
342 Status
= USBCCGP_PdoHandleDeviceRelations(DeviceObject
, Irp
);
345 case IRP_MN_QUERY_DEVICE_TEXT
:
348 // handle query device text
350 Status
= USBCCGP_PdoHandleQueryDeviceText(DeviceObject
, Irp
);
353 case IRP_MN_QUERY_ID
:
358 Status
= USBCCGP_PdoHandleQueryId(DeviceObject
, Irp
);
361 case IRP_MN_REMOVE_DEVICE
:
364 // remove us from the fdo's pdo list
367 for(Index
= 0; Index
< PDODeviceExtension
->FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
369 if (PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] == DeviceObject
)
374 PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] = NULL
;
383 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
384 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
389 // Delete the device object
391 IoDeleteDevice(DeviceObject
);
393 return STATUS_SUCCESS
;
395 case IRP_MN_QUERY_CAPABILITIES
:
398 // copy device capabilities
400 RtlCopyMemory(IoStack
->Parameters
.DeviceCapabilities
.Capabilities
, &PDODeviceExtension
->Capabilities
, sizeof(DEVICE_CAPABILITIES
));
402 /* Complete the IRP */
403 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
404 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
405 return STATUS_SUCCESS
;
407 case IRP_MN_QUERY_REMOVE_DEVICE
:
408 case IRP_MN_QUERY_STOP_DEVICE
:
413 Status
= STATUS_SUCCESS
;
416 case IRP_MN_START_DEVICE
:
421 DPRINT("[USBCCGP] PDO IRP_MN_START\n");
422 Status
= STATUS_SUCCESS
;
425 case IRP_MN_QUERY_INTERFACE
:
428 // forward to lower device object
430 IoSkipCurrentIrpStackLocation(Irp
);
431 return IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
438 Status
= Irp
->IoStatus
.Status
;
446 if (Status
!= STATUS_PENDING
)
451 Irp
->IoStatus
.Status
= Status
;
456 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
467 USBCCGP_BuildConfigurationDescriptor(
468 PDEVICE_OBJECT DeviceObject
,
471 PIO_STACK_LOCATION IoStack
;
472 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
473 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
;
474 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
475 ULONG TotalSize
, Index
;
480 UCHAR InterfaceNumber
;
483 // get current stack location
485 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
487 DPRINT("USBCCGP_BuildConfigurationDescriptor\n");
490 // get device extension
492 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
495 // get configuration descriptor
497 ConfigurationDescriptor
= PDODeviceExtension
->ConfigurationDescriptor
;
500 // calculate size of configuration descriptor
502 TotalSize
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
504 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
507 // get current interface descriptor
509 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
510 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
513 // add to size and move to next descriptor
515 TotalSize
+= InterfaceDescriptor
->bLength
;
516 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
520 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
523 // reached end of configuration descriptor
529 // association descriptors are removed
531 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
533 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
535 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
538 // reached next descriptor
544 // include alternate descriptor
551 TotalSize
+= InterfaceDescriptor
->bLength
;
555 // move to next descriptor
557 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
562 // now allocate temporary buffer for the configuration descriptor
564 Buffer
= AllocateItem(NonPagedPool
, TotalSize
);
568 // failed to allocate buffer
570 DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize
);
571 return STATUS_INSUFFICIENT_RESOURCES
;
575 // first copy the configuration descriptor
577 RtlCopyMemory(Buffer
, ConfigurationDescriptor
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
578 BufferPtr
= (PUCHAR
)((ULONG_PTR
)Buffer
+ ConfigurationDescriptor
->bLength
);
580 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
583 // get current interface descriptor
585 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
586 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
589 // copy descriptor and move to next descriptor
591 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
592 BufferPtr
+= InterfaceDescriptor
->bLength
;
593 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
597 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
600 // reached end of configuration descriptor
606 // association descriptors are removed
608 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
610 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
612 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
615 // reached next descriptor
621 // include alternate descriptor
623 DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor
, InterfaceDescriptor
->bAlternateSetting
, InterfaceDescriptor
->bInterfaceNumber
);
629 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
630 BufferPtr
+= InterfaceDescriptor
->bLength
;
634 // move to next descriptor
636 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
641 // modify configuration descriptor
643 ConfigurationDescriptor
= Buffer
;
644 ConfigurationDescriptor
->wTotalLength
= (USHORT
)TotalSize
;
645 ConfigurationDescriptor
->bNumInterfaces
= PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
;
650 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
656 Size
= min(TotalSize
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
657 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, Buffer
, Size
);
662 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= Size
;
672 return STATUS_SUCCESS
;
676 USBCCGP_PDOSelectConfiguration(
677 PDEVICE_OBJECT DeviceObject
,
680 PIO_STACK_LOCATION IoStack
;
681 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
683 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
684 ULONG InterfaceIndex
, Length
;
685 PUSBD_INTERFACE_LIST_ENTRY Entry
;
686 ULONG NeedSelect
, FoundInterface
;
690 // get current stack location
692 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
695 // get device extension
697 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
702 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
706 // is there already an configuration handle
708 if (Urb
->UrbSelectConfiguration
.ConfigurationHandle
)
713 return STATUS_SUCCESS
;
717 //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
718 //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
719 //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
720 //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
722 // available buffer length
723 Length
= Urb
->UrbSelectConfiguration
.Hdr
.Length
- FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION
, Interface
.Length
);
726 // check all interfaces
728 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
733 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
);
734 ASSERT(InterfaceInformation
->Length
);
736 // search for the interface in the local interface list
738 FoundInterface
= FALSE
;
739 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; InterfaceIndex
++)
741 if (PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[InterfaceIndex
]->bInterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
743 // found interface entry
744 FoundInterface
= TRUE
;
754 DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
756 return STATUS_INVALID_PARAMETER
;
760 // now query the total interface list
763 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->InterfaceListCount
; InterfaceIndex
++)
765 if (PDODeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->InterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
770 Entry
= &PDODeviceExtension
->InterfaceList
[InterfaceIndex
];
781 // corruption detected
787 if (Entry
->InterfaceDescriptor
->bAlternateSetting
== InterfaceInformation
->AlternateSetting
)
789 for(InterfaceIndex
= 0; InterfaceIndex
< InterfaceInformation
->NumberOfPipes
; InterfaceIndex
++)
791 if (InterfaceInformation
->Pipes
[InterfaceIndex
].MaximumTransferSize
!= Entry
->Interface
->Pipes
[InterfaceIndex
].MaximumTransferSize
)
803 // need select as the interface number differ
811 // interface is already selected
813 ASSERT(Length
>= Entry
->Interface
->Length
);
814 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
817 // adjust remaining buffer size
819 ASSERT(Entry
->Interface
->Length
);
820 Length
-= Entry
->Interface
->Length
;
823 // move to next output interface information
825 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
832 DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
833 ASSERT(InterfaceInformation
->Length
== Entry
->Interface
->Length
);
838 NewUrb
= AllocateItem(NonPagedPool
, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
));
844 return STATUS_INSUFFICIENT_RESOURCES
;
848 // now prepare interface urb
850 UsbBuildSelectInterfaceRequest(NewUrb
, (USHORT
)GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
), PDODeviceExtension
->ConfigurationHandle
, InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
);
853 // now select the interface
855 Status
= USBCCGP_SyncUrbRequest(PDODeviceExtension
->NextDeviceObject
, NewUrb
);
856 DPRINT1("SelectInterface Status %x\n", Status
);
858 if (!NT_SUCCESS(Status
))
867 // update configuration info
869 ASSERT(Entry
->Interface
->Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
870 ASSERT(Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
871 RtlCopyMemory(Entry
->Interface
, &NewUrb
->UrbSelectInterface
.Interface
, NewUrb
->UrbSelectInterface
.Interface
.Length
);
874 // update provided interface information
876 ASSERT(Length
>= Entry
->Interface
->Length
);
877 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
880 // decrement remaining buffer size
882 ASSERT(Entry
->Interface
->Length
);
883 Length
-= Entry
->Interface
->Length
;
886 // adjust output buffer offset
888 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
899 // store configuration handle
901 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= PDODeviceExtension
->ConfigurationHandle
;
903 DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
908 return STATUS_SUCCESS
;
912 PDO_HandleInternalDeviceControl(
913 PDEVICE_OBJECT DeviceObject
,
916 PIO_STACK_LOCATION IoStack
;
917 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
922 // get current stack location
924 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
927 // get device extension
929 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
931 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
936 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
938 DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb
->UrbHeader
.Function
);
940 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_SELECT_CONFIGURATION
)
943 // select configuration
945 Status
= USBCCGP_PDOSelectConfiguration(DeviceObject
, Irp
);
946 Irp
->IoStatus
.Status
= Status
;
947 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
950 else if (Urb
->UrbHeader
.Function
== URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
)
952 if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
)
955 // is the buffer big enough
957 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
< sizeof(USB_DEVICE_DESCRIPTOR
))
960 // invalid buffer size
962 DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
963 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
964 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
965 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
966 return STATUS_INVALID_BUFFER_SIZE
;
970 // copy device descriptor
972 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
973 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, &PDODeviceExtension
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
974 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
975 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
976 return STATUS_SUCCESS
;
978 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_CONFIGURATION_DESCRIPTOR_TYPE
)
981 // build configuration descriptor
983 Status
= USBCCGP_BuildConfigurationDescriptor(DeviceObject
, Irp
);
984 Irp
->IoStatus
.Status
= Status
;
985 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
988 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_STRING_DESCRIPTOR_TYPE
)
990 PUSB_STRING_DESCRIPTOR StringDescriptor
;
993 // get the requested string descriptor
995 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
996 Status
= USBCCGP_GetDescriptor(PDODeviceExtension
->FDODeviceExtension
->NextDeviceObject
,
997 USB_STRING_DESCRIPTOR_TYPE
,
998 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
,
999 Urb
->UrbControlDescriptorRequest
.Index
,
1000 Urb
->UrbControlDescriptorRequest
.LanguageId
,
1001 (PVOID
*)&StringDescriptor
);
1002 if (NT_SUCCESS(Status
))
1004 if (StringDescriptor
->bLength
== 2)
1006 FreeItem(StringDescriptor
);
1007 Status
= STATUS_DEVICE_DATA_ERROR
;
1011 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
1012 StringDescriptor
->bString
,
1013 StringDescriptor
->bLength
+ sizeof(WCHAR
));
1014 FreeItem(StringDescriptor
);
1015 Status
= STATUS_SUCCESS
;
1018 Irp
->IoStatus
.Status
= Status
;
1019 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1025 IoSkipCurrentIrpStackLocation(Irp
);
1026 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1030 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_GET_PORT_STATUS
)
1032 IoSkipCurrentIrpStackLocation(Irp
);
1033 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1036 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_RESET_PORT
)
1038 IoSkipCurrentIrpStackLocation(Irp
);
1039 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1042 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_CYCLE_PORT
)
1044 IoSkipCurrentIrpStackLocation(Irp
);
1045 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1049 DPRINT1("IOCTL %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
);
1050 DPRINT1("InputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
1051 DPRINT1("OutputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
1052 DPRINT1("Type3InputBuffer %p\n", IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
1056 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1057 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1058 return STATUS_NOT_IMPLEMENTED
;
1064 PDEVICE_OBJECT DeviceObject
,
1067 PIO_STACK_LOCATION IoStack
;
1070 /* get stack location */
1071 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1073 switch(IoStack
->MajorFunction
)
1076 return PDO_HandlePnp(DeviceObject
, Irp
);
1077 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
1078 return PDO_HandleInternalDeviceControl(DeviceObject
, Irp
);
1080 DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack
->MajorFunction
);
1081 Status
= Irp
->IoStatus
.Status
;
1082 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);