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)
18 USBCCGP_PdoHandleQueryDeviceText(
19 IN PDEVICE_OBJECT DeviceObject
,
23 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
24 LPWSTR GenericString
= L
"Composite USB Device";
26 // get device extension
28 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
31 // is there a device description
33 if (PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
)
38 Buffer
= AllocateItem(NonPagedPool
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
+ sizeof(WCHAR
));
44 return STATUS_INSUFFICIENT_RESOURCES
;
50 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
51 RtlCopyMemory(Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
);
52 return STATUS_SUCCESS
;
56 // FIXME use GenericCompositeUSBDeviceString
59 Buffer
= AllocateItem(PagedPool
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
65 return STATUS_INSUFFICIENT_RESOURCES
;
67 RtlCopyMemory(Buffer
, GenericString
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
68 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
70 return STATUS_SUCCESS
;
74 USBCCGP_PdoHandleDeviceRelations(
75 IN PDEVICE_OBJECT DeviceObject
,
78 PDEVICE_RELATIONS DeviceRelations
;
79 PIO_STACK_LOCATION IoStack
;
81 DPRINT("USBCCGP_PdoHandleDeviceRelations\n");
84 // get current irp stack location
86 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
89 // check if relation type is BusRelations
91 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
94 // PDO handles only target device relation
96 return Irp
->IoStatus
.Status
;
100 // allocate device relations
102 DeviceRelations
= (PDEVICE_RELATIONS
)AllocateItem(PagedPool
, sizeof(DEVICE_RELATIONS
));
103 if (!DeviceRelations
)
108 return STATUS_INSUFFICIENT_RESOURCES
;
112 // initialize device relations
114 DeviceRelations
->Count
= 1;
115 DeviceRelations
->Objects
[0] = DeviceObject
;
116 ObReferenceObject(DeviceObject
);
121 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
124 // completed successfully
126 return STATUS_SUCCESS
;
130 USBCCGP_PdoAppendInterfaceNumber(
132 IN ULONG InterfaceNumber
,
133 OUT LPWSTR
*OutString
)
135 ULONG Length
= 0, StringLength
;
139 // count length of string
144 StringLength
= wcslen(String
) + 1;
145 Length
+= StringLength
;
146 Length
+= 6; //&MI_XX
147 String
+= StringLength
;
151 // now allocate the buffer
153 String
= AllocateItem(NonPagedPool
, (Length
+ 2) * sizeof(WCHAR
));
159 return STATUS_INSUFFICIENT_RESOURCES
;
169 StringLength
= swprintf(String
, L
"%s&MI_%02x", DeviceId
, InterfaceNumber
) + 1;
170 Length
= wcslen(DeviceId
) + 1;
171 DPRINT("String %p\n", String
);
176 String
+= StringLength
;
183 return STATUS_SUCCESS
;
188 USBCCGP_PdoHandleQueryId(
189 PDEVICE_OBJECT DeviceObject
,
192 PIO_STACK_LOCATION IoStack
;
193 PUNICODE_STRING DeviceString
= NULL
;
194 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
199 // get current irp stack location
201 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
204 // get device extension
206 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
209 if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryDeviceID
)
212 // handle query device id
214 Status
= USBCCGP_SyncForwardIrp(PDODeviceExtension
->NextDeviceObject
, Irp
);
215 if (NT_SUCCESS(Status
))
220 Buffer
= AllocateItem(NonPagedPool
, (wcslen((LPWSTR
)Irp
->IoStatus
.Information
) + 7) * sizeof(WCHAR
));
224 // append interface number
226 ASSERT(Irp
->IoStatus
.Information
);
227 swprintf(Buffer
, L
"%s&MI_%02x", (LPWSTR
)Irp
->IoStatus
.Information
, PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
228 DPRINT("BusQueryDeviceID %S\n", Buffer
);
230 ExFreePool((PVOID
)Irp
->IoStatus
.Information
);
231 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
238 Status
= STATUS_INSUFFICIENT_RESOURCES
;
243 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryHardwareIDs
)
246 // handle instance id
248 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->HardwareId
;
250 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryInstanceID
)
253 // handle instance id
255 Buffer
= AllocateItem(NonPagedPool
, 5 * sizeof(WCHAR
));
261 return STATUS_INSUFFICIENT_RESOURCES
;
265 // use function number
267 swprintf(Buffer
, L
"%04x", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
268 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
269 return STATUS_SUCCESS
;
271 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryCompatibleIDs
)
274 // handle instance id
276 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->CompatibleId
;
283 return Irp
->IoStatus
.Status
;
289 ASSERT(DeviceString
!= NULL
);
294 Buffer
= AllocateItem(NonPagedPool
, DeviceString
->Length
+ sizeof(WCHAR
));
300 return STATUS_INSUFFICIENT_RESOURCES
;
306 RtlCopyMemory(Buffer
, DeviceString
->Buffer
, DeviceString
->Length
);
307 Buffer
[DeviceString
->Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
308 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
310 return STATUS_SUCCESS
;
315 PDEVICE_OBJECT DeviceObject
,
318 PIO_STACK_LOCATION IoStack
;
319 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
324 // get current stack location
326 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
329 // get device extension
331 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
336 ASSERT(PDODeviceExtension
->Common
.IsFDO
== FALSE
);
338 switch(IoStack
->MinorFunction
)
340 case IRP_MN_QUERY_DEVICE_RELATIONS
:
343 // handle device relations
345 Status
= USBCCGP_PdoHandleDeviceRelations(DeviceObject
, Irp
);
348 case IRP_MN_QUERY_DEVICE_TEXT
:
351 // handle query device text
353 Status
= USBCCGP_PdoHandleQueryDeviceText(DeviceObject
, Irp
);
356 case IRP_MN_QUERY_ID
:
361 Status
= USBCCGP_PdoHandleQueryId(DeviceObject
, Irp
);
364 case IRP_MN_REMOVE_DEVICE
:
367 // remove us from the fdo's pdo list
370 for(Index
= 0; Index
< PDODeviceExtension
->FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
372 if (PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] == DeviceObject
)
377 PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] = NULL
;
386 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
387 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
392 // Delete the device object
394 IoDeleteDevice(DeviceObject
);
396 return STATUS_SUCCESS
;
398 case IRP_MN_QUERY_CAPABILITIES
:
401 // copy device capabilities
403 RtlCopyMemory(IoStack
->Parameters
.DeviceCapabilities
.Capabilities
, &PDODeviceExtension
->Capabilities
, sizeof(DEVICE_CAPABILITIES
));
405 /* Complete the IRP */
406 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
407 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
408 return STATUS_SUCCESS
;
410 case IRP_MN_QUERY_REMOVE_DEVICE
:
411 case IRP_MN_QUERY_STOP_DEVICE
:
416 Status
= STATUS_SUCCESS
;
419 case IRP_MN_START_DEVICE
:
424 DPRINT("[USBCCGP] PDO IRP_MN_START\n");
425 Status
= STATUS_SUCCESS
;
428 case IRP_MN_QUERY_INTERFACE
:
431 // forward to lower device object
433 IoSkipCurrentIrpStackLocation(Irp
);
434 return IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
441 Status
= Irp
->IoStatus
.Status
;
449 if (Status
!= STATUS_PENDING
)
454 Irp
->IoStatus
.Status
= Status
;
459 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
470 USBCCGP_BuildConfigurationDescriptor(
471 PDEVICE_OBJECT DeviceObject
,
474 PIO_STACK_LOCATION IoStack
;
475 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
476 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
;
477 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
478 ULONG TotalSize
, Index
;
483 UCHAR InterfaceNumber
;
486 // get current stack location
488 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
490 DPRINT("USBCCGP_BuildConfigurationDescriptor\n");
493 // get device extension
495 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
498 // get configuration descriptor
500 ConfigurationDescriptor
= PDODeviceExtension
->ConfigurationDescriptor
;
503 // calculate size of configuration descriptor
505 TotalSize
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
507 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
510 // get current interface descriptor
512 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
513 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
516 // add to size and move to next descriptor
518 TotalSize
+= InterfaceDescriptor
->bLength
;
519 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
523 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
526 // reached end of configuration descriptor
532 // association descriptors are removed
534 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
536 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
538 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
541 // reached next descriptor
547 // include alternate descriptor
554 TotalSize
+= InterfaceDescriptor
->bLength
;
558 // move to next descriptor
560 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
565 // now allocate temporary buffer for the configuration descriptor
567 Buffer
= AllocateItem(NonPagedPool
, TotalSize
);
571 // failed to allocate buffer
573 DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize
);
574 return STATUS_INSUFFICIENT_RESOURCES
;
578 // first copy the configuration descriptor
580 RtlCopyMemory(Buffer
, ConfigurationDescriptor
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
581 BufferPtr
= (PUCHAR
)((ULONG_PTR
)Buffer
+ ConfigurationDescriptor
->bLength
);
583 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
586 // get current interface descriptor
588 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
589 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
592 // copy descriptor and move to next descriptor
594 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
595 BufferPtr
+= InterfaceDescriptor
->bLength
;
596 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
600 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
603 // reached end of configuration descriptor
609 // association descriptors are removed
611 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
613 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
615 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
618 // reached next descriptor
624 // include alternate descriptor
626 DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor
, InterfaceDescriptor
->bAlternateSetting
, InterfaceDescriptor
->bInterfaceNumber
);
632 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
633 BufferPtr
+= InterfaceDescriptor
->bLength
;
637 // move to next descriptor
639 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
644 // modify configuration descriptor
646 ConfigurationDescriptor
= Buffer
;
647 ConfigurationDescriptor
->wTotalLength
= (USHORT
)TotalSize
;
648 ConfigurationDescriptor
->bNumInterfaces
= PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
;
653 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
659 Size
= min(TotalSize
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
660 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, Buffer
, Size
);
665 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= Size
;
675 return STATUS_SUCCESS
;
679 USBCCGP_PDOSelectConfiguration(
680 PDEVICE_OBJECT DeviceObject
,
683 PIO_STACK_LOCATION IoStack
;
684 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
686 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
687 ULONG InterfaceIndex
, Length
;
688 PUSBD_INTERFACE_LIST_ENTRY Entry
;
689 ULONG NeedSelect
, FoundInterface
;
693 // get current stack location
695 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
698 // get device extension
700 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
705 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
709 // is there already an configuration handle
711 if (Urb
->UrbSelectConfiguration
.ConfigurationHandle
)
716 return STATUS_SUCCESS
;
720 //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
721 //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
722 //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
723 //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
725 // available buffer length
726 Length
= Urb
->UrbSelectConfiguration
.Hdr
.Length
- FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION
, Interface
.Length
);
729 // check all interfaces
731 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
736 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
);
737 ASSERT(InterfaceInformation
->Length
);
739 // search for the interface in the local interface list
741 FoundInterface
= FALSE
;
742 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; InterfaceIndex
++)
744 if (PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[InterfaceIndex
]->bInterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
746 // found interface entry
747 FoundInterface
= TRUE
;
757 DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
759 return STATUS_INVALID_PARAMETER
;
763 // now query the total interface list
766 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->InterfaceListCount
; InterfaceIndex
++)
768 if (PDODeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->InterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
773 Entry
= &PDODeviceExtension
->InterfaceList
[InterfaceIndex
];
784 // corruption detected
790 if (Entry
->InterfaceDescriptor
->bAlternateSetting
== InterfaceInformation
->AlternateSetting
)
792 for(InterfaceIndex
= 0; InterfaceIndex
< InterfaceInformation
->NumberOfPipes
; InterfaceIndex
++)
794 if (InterfaceInformation
->Pipes
[InterfaceIndex
].MaximumTransferSize
!= Entry
->Interface
->Pipes
[InterfaceIndex
].MaximumTransferSize
)
806 // need select as the interface number differ
814 // interface is already selected
816 ASSERT(Length
>= Entry
->Interface
->Length
);
817 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
820 // adjust remaining buffer size
822 ASSERT(Entry
->Interface
->Length
);
823 Length
-= Entry
->Interface
->Length
;
826 // move to next output interface information
828 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
835 DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
836 ASSERT(InterfaceInformation
->Length
== Entry
->Interface
->Length
);
841 NewUrb
= AllocateItem(NonPagedPool
, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
));
847 return STATUS_INSUFFICIENT_RESOURCES
;
851 // now prepare interface urb
853 UsbBuildSelectInterfaceRequest(NewUrb
, (USHORT
)GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
), PDODeviceExtension
->ConfigurationHandle
, InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
);
856 // now select the interface
858 Status
= USBCCGP_SyncUrbRequest(PDODeviceExtension
->NextDeviceObject
, NewUrb
);
859 DPRINT1("SelectInterface Status %x\n", Status
);
861 if (!NT_SUCCESS(Status
))
870 // update configuration info
872 ASSERT(Entry
->Interface
->Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
873 ASSERT(Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
874 RtlCopyMemory(Entry
->Interface
, &NewUrb
->UrbSelectInterface
.Interface
, NewUrb
->UrbSelectInterface
.Interface
.Length
);
877 // update provided interface information
879 ASSERT(Length
>= Entry
->Interface
->Length
);
880 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
883 // decrement remaining buffer size
885 ASSERT(Entry
->Interface
->Length
);
886 Length
-= Entry
->Interface
->Length
;
889 // adjust output buffer offset
891 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
902 // store configuration handle
904 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= PDODeviceExtension
->ConfigurationHandle
;
906 DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
911 return STATUS_SUCCESS
;
915 PDO_HandleInternalDeviceControl(
916 PDEVICE_OBJECT DeviceObject
,
919 PIO_STACK_LOCATION IoStack
;
920 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
925 // get current stack location
927 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
930 // get device extension
932 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
934 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
939 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
941 DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb
->UrbHeader
.Function
);
943 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_SELECT_CONFIGURATION
)
946 // select configuration
948 Status
= USBCCGP_PDOSelectConfiguration(DeviceObject
, Irp
);
949 Irp
->IoStatus
.Status
= Status
;
950 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
953 else if (Urb
->UrbHeader
.Function
== URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
)
955 if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
)
958 // is the buffer big enough
960 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
< sizeof(USB_DEVICE_DESCRIPTOR
))
963 // invalid buffer size
965 DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
966 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
967 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
968 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
969 return STATUS_INVALID_BUFFER_SIZE
;
973 // copy device descriptor
975 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
976 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, &PDODeviceExtension
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
977 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
978 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
979 return STATUS_SUCCESS
;
981 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_CONFIGURATION_DESCRIPTOR_TYPE
)
984 // build configuration descriptor
986 Status
= USBCCGP_BuildConfigurationDescriptor(DeviceObject
, Irp
);
987 Irp
->IoStatus
.Status
= Status
;
988 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
991 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_STRING_DESCRIPTOR_TYPE
)
993 PUSB_STRING_DESCRIPTOR StringDescriptor
;
996 // get the requested string descriptor
998 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
999 Status
= USBCCGP_GetDescriptor(PDODeviceExtension
->FDODeviceExtension
->NextDeviceObject
,
1000 USB_STRING_DESCRIPTOR_TYPE
,
1001 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
,
1002 Urb
->UrbControlDescriptorRequest
.Index
,
1003 Urb
->UrbControlDescriptorRequest
.LanguageId
,
1004 (PVOID
*)&StringDescriptor
);
1005 if (NT_SUCCESS(Status
))
1007 if (StringDescriptor
->bLength
== 2)
1009 FreeItem(StringDescriptor
);
1010 Status
= STATUS_DEVICE_DATA_ERROR
;
1014 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
1015 StringDescriptor
->bString
,
1016 StringDescriptor
->bLength
+ sizeof(WCHAR
));
1017 FreeItem(StringDescriptor
);
1018 Status
= STATUS_SUCCESS
;
1021 Irp
->IoStatus
.Status
= Status
;
1022 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1028 IoSkipCurrentIrpStackLocation(Irp
);
1029 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1033 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_GET_PORT_STATUS
)
1035 IoSkipCurrentIrpStackLocation(Irp
);
1036 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1039 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_RESET_PORT
)
1041 IoSkipCurrentIrpStackLocation(Irp
);
1042 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1045 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_CYCLE_PORT
)
1047 IoSkipCurrentIrpStackLocation(Irp
);
1048 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1052 DPRINT1("IOCTL %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
);
1053 DPRINT1("InputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
1054 DPRINT1("OutputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
1055 DPRINT1("Type3InputBuffer %p\n", IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
1059 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1060 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1061 return STATUS_NOT_IMPLEMENTED
;
1067 PDEVICE_OBJECT DeviceObject
,
1070 PIO_STACK_LOCATION IoStack
;
1073 /* get stack location */
1074 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1076 switch(IoStack
->MajorFunction
)
1079 return PDO_HandlePnp(DeviceObject
, Irp
);
1080 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
1081 return PDO_HandleInternalDeviceControl(DeviceObject
, Irp
);
1083 PoStartNextPowerIrp(Irp
);
1084 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1085 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1086 return STATUS_SUCCESS
;
1088 DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack
->MajorFunction
);
1089 Status
= Irp
->IoStatus
.Status
;
1090 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);