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
,
25 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
26 LPWSTR GenericString
= L
"Composite USB Device";
28 // get device extension
30 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
33 // is there a device description
35 if (PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
)
40 Buffer
= AllocateItem(NonPagedPool
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
+ sizeof(WCHAR
));
46 return STATUS_INSUFFICIENT_RESOURCES
;
52 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
53 RtlCopyMemory(Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Buffer
, PDODeviceExtension
->FunctionDescriptor
->FunctionDescription
.Length
);
54 return STATUS_SUCCESS
;
58 // FIXME use GenericCompositeUSBDeviceString
61 Buffer
= AllocateItem(PagedPool
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
67 return STATUS_INSUFFICIENT_RESOURCES
;
69 RtlCopyMemory(Buffer
, GenericString
, (wcslen(GenericString
) + 1) * sizeof(WCHAR
));
70 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
72 return STATUS_SUCCESS
;
76 USBCCGP_PdoHandleDeviceRelations(
77 IN PDEVICE_OBJECT DeviceObject
,
80 PDEVICE_RELATIONS DeviceRelations
;
81 PIO_STACK_LOCATION IoStack
;
83 DPRINT("USBCCGP_PdoHandleDeviceRelations\n");
86 // get current irp stack location
88 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
91 // check if relation type is BusRelations
93 if (IoStack
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
96 // PDO handles only target device relation
98 return Irp
->IoStatus
.Status
;
102 // allocate device relations
104 DeviceRelations
= (PDEVICE_RELATIONS
)AllocateItem(PagedPool
, sizeof(DEVICE_RELATIONS
));
105 if (!DeviceRelations
)
110 return STATUS_INSUFFICIENT_RESOURCES
;
114 // initialize device relations
116 DeviceRelations
->Count
= 1;
117 DeviceRelations
->Objects
[0] = DeviceObject
;
118 ObReferenceObject(DeviceObject
);
123 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
126 // completed successfully
128 return STATUS_SUCCESS
;
132 USBCCGP_PdoAppendInterfaceNumber(
134 IN ULONG InterfaceNumber
,
135 OUT LPWSTR
*OutString
)
137 ULONG Length
= 0, StringLength
;
141 // count length of string
146 StringLength
= wcslen(String
) + 1;
147 Length
+= StringLength
;
148 Length
+= 6; //&MI_XX
149 String
+= StringLength
;
153 // now allocate the buffer
155 String
= AllocateItem(NonPagedPool
, (Length
+ 2) * sizeof(WCHAR
));
161 return STATUS_INSUFFICIENT_RESOURCES
;
171 StringLength
= swprintf(String
, L
"%s&MI_%02x", DeviceId
, InterfaceNumber
) + 1;
172 Length
= wcslen(DeviceId
) + 1;
173 DPRINT("String %p\n", String
);
178 String
+= StringLength
;
185 return STATUS_SUCCESS
;
190 USBCCGP_PdoHandleQueryId(
191 PDEVICE_OBJECT DeviceObject
,
194 PIO_STACK_LOCATION IoStack
;
195 PUNICODE_STRING DeviceString
= NULL
;
196 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
201 // get current irp stack location
203 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
206 // get device extension
208 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
211 if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryDeviceID
)
214 // handle query device id
216 Status
= USBCCGP_SyncForwardIrp(PDODeviceExtension
->NextDeviceObject
, Irp
);
217 if (NT_SUCCESS(Status
))
222 Buffer
= AllocateItem(NonPagedPool
, (wcslen((LPWSTR
)Irp
->IoStatus
.Information
) + 7) * sizeof(WCHAR
));
226 // append interface number
228 ASSERT(Irp
->IoStatus
.Information
);
229 swprintf(Buffer
, L
"%s&MI_%02x", (LPWSTR
)Irp
->IoStatus
.Information
, PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
230 DPRINT("BusQueryDeviceID %S\n", Buffer
);
232 ExFreePool((PVOID
)Irp
->IoStatus
.Information
);
233 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
240 Status
= STATUS_INSUFFICIENT_RESOURCES
;
245 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryHardwareIDs
)
248 // handle instance id
250 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->HardwareId
;
252 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryInstanceID
)
255 // handle instance id
257 Buffer
= AllocateItem(NonPagedPool
, 5 * sizeof(WCHAR
));
263 return STATUS_INSUFFICIENT_RESOURCES
;
267 // use function number
269 swprintf(Buffer
, L
"%04x", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
270 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
271 return STATUS_SUCCESS
;
273 else if (IoStack
->Parameters
.QueryId
.IdType
== BusQueryCompatibleIDs
)
276 // handle instance id
278 DeviceString
= &PDODeviceExtension
->FunctionDescriptor
->CompatibleId
;
285 return Irp
->IoStatus
.Status
;
291 ASSERT(DeviceString
!= NULL
);
296 Buffer
= AllocateItem(NonPagedPool
, DeviceString
->Length
+ sizeof(WCHAR
));
302 return STATUS_INSUFFICIENT_RESOURCES
;
308 RtlCopyMemory(Buffer
, DeviceString
->Buffer
, DeviceString
->Length
);
309 Buffer
[DeviceString
->Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
310 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
312 return STATUS_SUCCESS
;
317 PDEVICE_OBJECT DeviceObject
,
320 PIO_STACK_LOCATION IoStack
;
321 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
326 // get current stack location
328 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
331 // get device extension
333 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
338 ASSERT(PDODeviceExtension
->Common
.IsFDO
== FALSE
);
340 switch(IoStack
->MinorFunction
)
342 case IRP_MN_QUERY_DEVICE_RELATIONS
:
345 // handle device relations
347 Status
= USBCCGP_PdoHandleDeviceRelations(DeviceObject
, Irp
);
350 case IRP_MN_QUERY_DEVICE_TEXT
:
353 // handle query device text
355 Status
= USBCCGP_PdoHandleQueryDeviceText(DeviceObject
, Irp
);
358 case IRP_MN_QUERY_ID
:
363 Status
= USBCCGP_PdoHandleQueryId(DeviceObject
, Irp
);
366 case IRP_MN_REMOVE_DEVICE
:
369 // remove us from the fdo's pdo list
372 for(Index
= 0; Index
< PDODeviceExtension
->FDODeviceExtension
->FunctionDescriptorCount
; Index
++)
374 if (PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] == DeviceObject
)
379 PDODeviceExtension
->FDODeviceExtension
->ChildPDO
[Index
] = NULL
;
388 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
389 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
394 // Delete the device object
396 IoDeleteDevice(DeviceObject
);
398 return STATUS_SUCCESS
;
400 case IRP_MN_QUERY_CAPABILITIES
:
403 // copy device capabilities
405 RtlCopyMemory(IoStack
->Parameters
.DeviceCapabilities
.Capabilities
, &PDODeviceExtension
->Capabilities
, sizeof(DEVICE_CAPABILITIES
));
407 /* Complete the IRP */
408 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
409 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
410 return STATUS_SUCCESS
;
412 case IRP_MN_QUERY_REMOVE_DEVICE
:
413 case IRP_MN_QUERY_STOP_DEVICE
:
418 Status
= STATUS_SUCCESS
;
421 case IRP_MN_START_DEVICE
:
426 DPRINT("[USBCCGP] PDO IRP_MN_START\n");
427 Status
= STATUS_SUCCESS
;
430 case IRP_MN_QUERY_INTERFACE
:
433 // forward to lower device object
435 IoSkipCurrentIrpStackLocation(Irp
);
436 return IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
443 Status
= Irp
->IoStatus
.Status
;
451 if (Status
!= STATUS_PENDING
)
456 Irp
->IoStatus
.Status
= Status
;
461 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
472 USBCCGP_BuildConfigurationDescriptor(
473 PDEVICE_OBJECT DeviceObject
,
476 PIO_STACK_LOCATION IoStack
;
477 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
478 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
;
479 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
480 ULONG TotalSize
, Index
;
485 UCHAR InterfaceNumber
;
488 // get current stack location
490 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
492 DPRINT("USBCCGP_BuildConfigurationDescriptor\n");
495 // get device extension
497 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
500 // get configuration descriptor
502 ConfigurationDescriptor
= PDODeviceExtension
->ConfigurationDescriptor
;
505 // calculate size of configuration descriptor
507 TotalSize
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
509 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
512 // get current interface descriptor
514 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
515 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
518 // add to size and move to next descriptor
520 TotalSize
+= InterfaceDescriptor
->bLength
;
521 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
525 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
528 // reached end of configuration descriptor
534 // association descriptors are removed
536 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
538 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
540 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
543 // reached next descriptor
549 // include alternate descriptor
556 TotalSize
+= InterfaceDescriptor
->bLength
;
560 // move to next descriptor
562 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
567 // now allocate temporary buffer for the configuration descriptor
569 Buffer
= AllocateItem(NonPagedPool
, TotalSize
);
573 // failed to allocate buffer
575 DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize
);
576 return STATUS_INSUFFICIENT_RESOURCES
;
580 // first copy the configuration descriptor
582 RtlCopyMemory(Buffer
, ConfigurationDescriptor
, sizeof(USB_CONFIGURATION_DESCRIPTOR
));
583 BufferPtr
= (PUCHAR
)((ULONG_PTR
)Buffer
+ ConfigurationDescriptor
->bLength
);
585 for (Index
= 0; Index
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; Index
++)
588 // get current interface descriptor
590 InterfaceDescriptor
= PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[Index
];
591 InterfaceNumber
= InterfaceDescriptor
->bInterfaceNumber
;
594 // copy descriptor and move to next descriptor
596 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
597 BufferPtr
+= InterfaceDescriptor
->bLength
;
598 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
602 if ((ULONG_PTR
)InterfaceDescriptor
>= ((ULONG_PTR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
))
605 // reached end of configuration descriptor
611 // association descriptors are removed
613 if (InterfaceDescriptor
->bDescriptorType
!= USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
615 if (InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
617 if (InterfaceNumber
!= InterfaceDescriptor
->bInterfaceNumber
)
620 // reached next descriptor
626 // include alternate descriptor
628 DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor
, InterfaceDescriptor
->bAlternateSetting
, InterfaceDescriptor
->bInterfaceNumber
);
634 RtlCopyMemory(BufferPtr
, InterfaceDescriptor
, InterfaceDescriptor
->bLength
);
635 BufferPtr
+= InterfaceDescriptor
->bLength
;
639 // move to next descriptor
641 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
646 // modify configuration descriptor
648 ConfigurationDescriptor
= Buffer
;
649 ConfigurationDescriptor
->wTotalLength
= (USHORT
)TotalSize
;
650 ConfigurationDescriptor
->bNumInterfaces
= PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
;
655 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
661 Size
= min(TotalSize
, Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
662 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, Buffer
, Size
);
667 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= Size
;
677 return STATUS_SUCCESS
;
681 USBCCGP_PDOSelectConfiguration(
682 PDEVICE_OBJECT DeviceObject
,
685 PIO_STACK_LOCATION IoStack
;
686 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
688 PUSBD_INTERFACE_INFORMATION InterfaceInformation
;
689 ULONG InterfaceIndex
, Length
;
690 PUSBD_INTERFACE_LIST_ENTRY Entry
;
691 ULONG NeedSelect
, FoundInterface
;
695 // get current stack location
697 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
700 // get device extension
702 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
707 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
711 // is there already an configuration handle
713 if (Urb
->UrbSelectConfiguration
.ConfigurationHandle
)
718 return STATUS_SUCCESS
;
722 //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
723 //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
724 //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
725 //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
727 // available buffer length
728 Length
= Urb
->UrbSelectConfiguration
.Hdr
.Length
- FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION
, Interface
.Length
);
731 // check all interfaces
733 InterfaceInformation
= &Urb
->UrbSelectConfiguration
.Interface
;
738 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
);
739 ASSERT(InterfaceInformation
->Length
);
741 // search for the interface in the local interface list
743 FoundInterface
= FALSE
;
744 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->FunctionDescriptor
->NumberOfInterfaces
; InterfaceIndex
++)
746 if (PDODeviceExtension
->FunctionDescriptor
->InterfaceDescriptorList
[InterfaceIndex
]->bInterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
748 // found interface entry
749 FoundInterface
= TRUE
;
759 DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
760 return STATUS_INVALID_PARAMETER
;
764 // now query the total interface list
767 for (InterfaceIndex
= 0; InterfaceIndex
< PDODeviceExtension
->InterfaceListCount
; InterfaceIndex
++)
769 if (PDODeviceExtension
->InterfaceList
[InterfaceIndex
].Interface
->InterfaceNumber
== InterfaceInformation
->InterfaceNumber
)
774 Entry
= &PDODeviceExtension
->InterfaceList
[InterfaceIndex
];
785 // corruption detected
791 if (Entry
->InterfaceDescriptor
->bAlternateSetting
== InterfaceInformation
->AlternateSetting
)
793 for(InterfaceIndex
= 0; InterfaceIndex
< InterfaceInformation
->NumberOfPipes
; InterfaceIndex
++)
795 if (InterfaceInformation
->Pipes
[InterfaceIndex
].MaximumTransferSize
!= Entry
->Interface
->Pipes
[InterfaceIndex
].MaximumTransferSize
)
807 // need select as the interface number differ
815 // interface is already selected
817 ASSERT(Length
>= Entry
->Interface
->Length
);
818 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
821 // adjust remaining buffer size
823 ASSERT(Entry
->Interface
->Length
);
824 Length
-= Entry
->Interface
->Length
;
827 // move to next output interface information
829 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
836 DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
, InterfaceInformation
->NumberOfPipes
);
837 ASSERT(InterfaceInformation
->Length
== Entry
->Interface
->Length
);
842 NewUrb
= AllocateItem(NonPagedPool
, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
));
848 return STATUS_INSUFFICIENT_RESOURCES
;
852 // now prepare interface urb
854 UsbBuildSelectInterfaceRequest(NewUrb
, (USHORT
)GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation
->NumberOfPipes
), PDODeviceExtension
->ConfigurationHandle
, InterfaceInformation
->InterfaceNumber
, InterfaceInformation
->AlternateSetting
);
857 // now select the interface
859 Status
= USBCCGP_SyncUrbRequest(PDODeviceExtension
->NextDeviceObject
, NewUrb
);
860 DPRINT1("SelectInterface Status %x\n", Status
);
862 if (!NT_SUCCESS(Status
))
871 // update configuration info
873 ASSERT(Entry
->Interface
->Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
874 ASSERT(Length
>= NewUrb
->UrbSelectInterface
.Interface
.Length
);
875 RtlCopyMemory(Entry
->Interface
, &NewUrb
->UrbSelectInterface
.Interface
, NewUrb
->UrbSelectInterface
.Interface
.Length
);
878 // update provided interface information
880 ASSERT(Length
>= Entry
->Interface
->Length
);
881 RtlCopyMemory(InterfaceInformation
, Entry
->Interface
, Entry
->Interface
->Length
);
884 // decrement remaining buffer size
886 ASSERT(Entry
->Interface
->Length
);
887 Length
-= Entry
->Interface
->Length
;
890 // adjust output buffer offset
892 InterfaceInformation
= (PUSBD_INTERFACE_INFORMATION
)((ULONG_PTR
)InterfaceInformation
+ Entry
->Interface
->Length
);
903 // store configuration handle
905 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= PDODeviceExtension
->ConfigurationHandle
;
907 DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension
->FunctionDescriptor
->FunctionNumber
);
912 return STATUS_SUCCESS
;
916 PDO_HandleInternalDeviceControl(
917 PDEVICE_OBJECT DeviceObject
,
920 PIO_STACK_LOCATION IoStack
;
921 PPDO_DEVICE_EXTENSION PDODeviceExtension
;
926 // get current stack location
928 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
931 // get device extension
933 PDODeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
935 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_SUBMIT_URB
)
940 Urb
= (PURB
)IoStack
->Parameters
.Others
.Argument1
;
942 DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb
->UrbHeader
.Function
);
944 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_SELECT_CONFIGURATION
)
947 // select configuration
949 Status
= USBCCGP_PDOSelectConfiguration(DeviceObject
, Irp
);
950 Irp
->IoStatus
.Status
= Status
;
951 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
954 else if (Urb
->UrbHeader
.Function
== URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
)
956 if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
)
959 // is the buffer big enough
961 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
< sizeof(USB_DEVICE_DESCRIPTOR
))
964 // invalid buffer size
966 DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
967 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
968 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
969 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
970 return STATUS_INVALID_BUFFER_SIZE
;
974 // copy device descriptor
976 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
977 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
, &PDODeviceExtension
->DeviceDescriptor
, sizeof(USB_DEVICE_DESCRIPTOR
));
978 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
979 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
980 return STATUS_SUCCESS
;
982 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_CONFIGURATION_DESCRIPTOR_TYPE
)
985 // build configuration descriptor
987 Status
= USBCCGP_BuildConfigurationDescriptor(DeviceObject
, Irp
);
988 Irp
->IoStatus
.Status
= Status
;
989 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
992 else if (Urb
->UrbControlDescriptorRequest
.DescriptorType
== USB_STRING_DESCRIPTOR_TYPE
)
994 PUSB_STRING_DESCRIPTOR StringDescriptor
;
997 // get the requested string descriptor
999 ASSERT(Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
1000 Status
= USBCCGP_GetDescriptor(PDODeviceExtension
->FDODeviceExtension
->NextDeviceObject
,
1001 USB_STRING_DESCRIPTOR_TYPE
,
1002 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
,
1003 Urb
->UrbControlDescriptorRequest
.Index
,
1004 Urb
->UrbControlDescriptorRequest
.LanguageId
,
1005 (PVOID
*)&StringDescriptor
);
1006 if (NT_SUCCESS(Status
))
1008 if (StringDescriptor
->bLength
== 2)
1010 FreeItem(StringDescriptor
);
1011 Status
= STATUS_DEVICE_DATA_ERROR
;
1015 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
1016 StringDescriptor
->bString
,
1017 StringDescriptor
->bLength
+ sizeof(WCHAR
));
1018 FreeItem(StringDescriptor
);
1019 Status
= STATUS_SUCCESS
;
1022 Irp
->IoStatus
.Status
= Status
;
1023 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1029 IoSkipCurrentIrpStackLocation(Irp
);
1030 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1034 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_GET_PORT_STATUS
)
1036 IoSkipCurrentIrpStackLocation(Irp
);
1037 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1040 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_RESET_PORT
)
1042 IoSkipCurrentIrpStackLocation(Irp
);
1043 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1046 else if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_INTERNAL_USB_CYCLE_PORT
)
1048 IoSkipCurrentIrpStackLocation(Irp
);
1049 Status
= IoCallDriver(PDODeviceExtension
->NextDeviceObject
, Irp
);
1053 DPRINT1("IOCTL %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
);
1054 DPRINT1("InputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
1055 DPRINT1("OutputBufferLength %lu\n", IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
1056 DPRINT1("Type3InputBuffer %p\n", IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
1060 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
1061 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1062 return STATUS_NOT_IMPLEMENTED
;
1068 PDEVICE_OBJECT DeviceObject
,
1071 PIO_STACK_LOCATION IoStack
;
1074 /* get stack location */
1075 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1077 switch(IoStack
->MajorFunction
)
1080 return PDO_HandlePnp(DeviceObject
, Irp
);
1081 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
1082 return PDO_HandleInternalDeviceControl(DeviceObject
, Irp
);
1084 PoStartNextPowerIrp(Irp
);
1085 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1086 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1087 return STATUS_SUCCESS
;
1089 DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack
->MajorFunction
);
1090 Status
= Irp
->IoStatus
.Status
;
1091 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);