mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 18:35:32 +00:00
[usb/usbhub]
- On completion of SCE request, create and queue a workitem to handle: Clearing the connection flag and reset the port. Create and initialize the USB device by calling the appropriate roothubs Direct Call Interface. Create the device object, get the device descriptors and the serial and product strings of the USB device to be used for creating the deviceid and instanceid. - Format code and misc changes. - Together with the usbehci driver, ReactOS at least runs the device installation wizard with the correct device description. svn path=/trunk/; revision=48771
This commit is contained in:
parent
45bd4d8031
commit
7a26c678b7
|
@ -16,6 +16,24 @@
|
|||
|
||||
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
|
||||
|
||||
|
||||
typedef struct _USB_LANGUAGEID_DESCRIPTOR {
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
WCHAR wLANGIDs[1];
|
||||
} USB_LANGUAGEID_DESCRIPTOR, *PUSB_LANGUAGEID_DESCRIPTOR;
|
||||
|
||||
typedef struct _PORTSTATUSANDCHANGE
|
||||
{
|
||||
USHORT Status;
|
||||
USHORT Change;
|
||||
} PORTSTATUSANDCHANGE, *PPORTSTATUSANDCHANGE;
|
||||
|
||||
NTSTATUS
|
||||
QueryRootHub(IN PDEVICE_OBJECT Pdo, IN ULONG IoControlCode, OUT PVOID OutParameter1, OUT PVOID OutParameter2);
|
||||
NTSTATUS
|
||||
WaitForUsbDeviceArrivalNotification(PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
||||
{
|
||||
DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
|
||||
|
@ -81,19 +99,309 @@ VOID DumpFullConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR Configuration
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
WorkerThread(IN PVOID Context)
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context, Pdo;
|
||||
PHUB_CHILDDEVICE_EXTENSION PdoExtension;
|
||||
PURB Urb;
|
||||
PORTSTATUSANDCHANGE PortStatusAndChange;
|
||||
int PortLoop, DeviceCount;
|
||||
NTSTATUS Status;
|
||||
USB_DEVICE_DESCRIPTOR DevDesc;
|
||||
USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
|
||||
ULONG DevDescSize, ConfigDescSize;
|
||||
PUSB_STRING_DESCRIPTOR StringDesc;
|
||||
USB_LANGUAGEID_DESCRIPTOR LanguageIdDescriptor;
|
||||
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* Determine where in the children array to store this device info */
|
||||
for (DeviceCount = 0; DeviceCount < USB_MAXCHILDREN; DeviceCount++)
|
||||
{
|
||||
if (DeviceExtension->UsbChildren[DeviceCount] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Storing Device Info at %x\n", DeviceCount);
|
||||
Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
|
||||
if (!Urb)
|
||||
{
|
||||
DPRINT1("Failed to allocate memory for URB!\n");
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
RtlZeroMemory(Urb, sizeof(URB));
|
||||
|
||||
for (PortLoop = 0; PortLoop < DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
|
||||
{
|
||||
/* Get the port status */
|
||||
UsbBuildVendorRequest(Urb,
|
||||
URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_OUT,
|
||||
0,
|
||||
USB_REQUEST_GET_STATUS,
|
||||
0,
|
||||
PortLoop + 1,
|
||||
&PortStatusAndChange,
|
||||
0,
|
||||
sizeof(PORTSTATUSANDCHANGE),
|
||||
0);
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to get PortStatus!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINT("Notification Port %x:\n", PortLoop + 1);
|
||||
DPRINT("Status %x\n", PortStatusAndChange.Status);
|
||||
DPRINT("Change %x\n", PortStatusAndChange.Change);
|
||||
|
||||
if (PortStatusAndChange.Change == USB_PORT_STATUS_RESET)
|
||||
{
|
||||
/* Clear the Reset */
|
||||
UsbBuildVendorRequest(Urb,
|
||||
URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_IN,
|
||||
0,
|
||||
USB_REQUEST_CLEAR_FEATURE,
|
||||
C_PORT_RESET,
|
||||
PortLoop + 1,
|
||||
&PortStatusAndChange,
|
||||
0,
|
||||
sizeof(PORTSTATUSANDCHANGE),
|
||||
0);
|
||||
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to Clear the Port Reset with Status %x!\n", Status);
|
||||
return;
|
||||
}
|
||||
UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_OUT,
|
||||
0,
|
||||
USB_REQUEST_GET_STATUS,
|
||||
0,
|
||||
PortLoop + 1,
|
||||
&PortStatusAndChange,
|
||||
0,
|
||||
sizeof(PORTSTATUSANDCHANGE),
|
||||
0);
|
||||
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
DPRINT("Status %x\n", PortStatusAndChange.Status);
|
||||
DPRINT("Change %x\n", PortStatusAndChange.Change);
|
||||
|
||||
/* Create the UsbDevice */
|
||||
Status = DeviceExtension->HubInterface.CreateUsbDevice(DeviceExtension->RootHubPdo,
|
||||
(PVOID)&DeviceExtension->UsbChildren[DeviceCount],
|
||||
DeviceExtension->RootHubUsbDevice,
|
||||
PortStatusAndChange.Status,
|
||||
PortLoop + 1);
|
||||
DPRINT1("CreateUsbDevice Status %x\n", Status);
|
||||
|
||||
Status = DeviceExtension->HubInterface.InitializeUsbDevice(DeviceExtension->RootHubPdo, DeviceExtension->UsbChildren[DeviceCount]);
|
||||
DPRINT1("InitializeUsbDevice Status %x\n", Status);
|
||||
|
||||
DevDescSize = sizeof(USB_DEVICE_DESCRIPTOR);
|
||||
ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
|
||||
Status = DeviceExtension->HubInterface.GetUsbDescriptors(DeviceExtension->RootHubPdo,
|
||||
DeviceExtension->UsbChildren[DeviceCount],
|
||||
(PUCHAR)&DevDesc,
|
||||
&DevDescSize,
|
||||
(PUCHAR)&ConfigDesc,
|
||||
&ConfigDescSize);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to Get Usb Deccriptors %x!\n", Status);
|
||||
}
|
||||
|
||||
DumpDeviceDescriptor(&DevDesc);
|
||||
|
||||
Status = IoCreateDevice(DeviceObject->DriverObject,
|
||||
sizeof(HUB_CHILDDEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
FILE_AUTOGENERATED_DEVICE_NAME,
|
||||
FALSE,
|
||||
&DeviceExtension->Children[DeviceCount]);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("UsbHub; IoCreateDevice failed with status %x\n",Status);
|
||||
return;
|
||||
}
|
||||
|
||||
Pdo = DeviceExtension->Children[DeviceCount];
|
||||
DPRINT1("Created New Device with %x\n", Pdo);
|
||||
Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
PdoExtension = Pdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(PdoExtension, sizeof(HUB_CHILDDEVICE_EXTENSION));
|
||||
|
||||
PdoExtension->DeviceId = ExAllocatePoolWithTag(NonPagedPool, 32 * sizeof(WCHAR), USB_HUB_TAG);
|
||||
RtlZeroMemory(PdoExtension->DeviceId, 32 * sizeof(WCHAR));
|
||||
swprintf(PdoExtension->DeviceId, L"USB\\Vid_%04x&Pid_%04x", DevDesc.idVendor, DevDesc.idProduct);
|
||||
|
||||
|
||||
/* Get the LANGids */
|
||||
RtlZeroMemory(&LanguageIdDescriptor, sizeof(USB_LANGUAGEID_DESCRIPTOR));
|
||||
UsbBuildGetDescriptorRequest(Urb,
|
||||
sizeof(Urb->UrbControlDescriptorRequest),
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
0,
|
||||
0,
|
||||
&LanguageIdDescriptor,
|
||||
NULL,
|
||||
sizeof(USB_LANGUAGEID_DESCRIPTOR),
|
||||
NULL);
|
||||
|
||||
Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
|
||||
|
||||
Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
/* Get the length of the SerialNumber */
|
||||
StringDesc = ExAllocatePoolWithTag(PagedPool, 64, USB_HUB_TAG);
|
||||
RtlZeroMemory(StringDesc, 64);
|
||||
StringDesc->bLength = 0;
|
||||
StringDesc->bDescriptorType = 0;
|
||||
|
||||
UsbBuildGetDescriptorRequest(Urb,
|
||||
sizeof(Urb->UrbControlDescriptorRequest),
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
DevDesc.iSerialNumber,
|
||||
LanguageIdDescriptor.wLANGIDs[0],
|
||||
StringDesc,
|
||||
NULL,
|
||||
64,
|
||||
NULL);
|
||||
|
||||
Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
|
||||
|
||||
Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
PdoExtension->InstanceId = ExAllocatePoolWithTag(NonPagedPool, (StringDesc->bLength + 1) * sizeof(WCHAR), USB_HUB_TAG);
|
||||
DPRINT1("PdoExtension->InstanceId %x\n",PdoExtension->InstanceId);
|
||||
|
||||
RtlZeroMemory(PdoExtension->InstanceId, (StringDesc->bLength + 1) * sizeof(WCHAR));
|
||||
RtlCopyMemory(PdoExtension->InstanceId, &StringDesc->bString[0], StringDesc->bLength);
|
||||
DPRINT1("------>SerialNumber %S\n", PdoExtension->InstanceId);
|
||||
|
||||
|
||||
|
||||
RtlZeroMemory(StringDesc, 64);
|
||||
StringDesc->bLength = 0;
|
||||
StringDesc->bDescriptorType = 0;
|
||||
|
||||
UsbBuildGetDescriptorRequest(Urb,
|
||||
sizeof(Urb->UrbControlDescriptorRequest),
|
||||
USB_STRING_DESCRIPTOR_TYPE,
|
||||
DevDesc.iProduct,
|
||||
LanguageIdDescriptor.wLANGIDs[0],
|
||||
StringDesc,
|
||||
NULL,
|
||||
64,
|
||||
NULL);
|
||||
|
||||
Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
|
||||
|
||||
Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
PdoExtension->TextDescription = ExAllocatePoolWithTag(NonPagedPool, (StringDesc->bLength + 1) * sizeof(WCHAR), USB_HUB_TAG);
|
||||
|
||||
RtlZeroMemory(PdoExtension->TextDescription, (StringDesc->bLength + 1) * sizeof(WCHAR));
|
||||
RtlCopyMemory(PdoExtension->TextDescription, &StringDesc->bString[0], StringDesc->bLength);
|
||||
ExFreePool(StringDesc);
|
||||
DPRINT1("------>TextDescription %S\n", PdoExtension->TextDescription);
|
||||
|
||||
PdoExtension->IsFDO = FALSE;
|
||||
PdoExtension->Parent = DeviceObject;
|
||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
IoInvalidateDeviceRelations(DeviceExtension->RootHubPdo, BusRelations);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Is a device connected to this port */
|
||||
if (PortStatusAndChange.Change == USB_PORT_STATUS_CONNECT)
|
||||
{
|
||||
/* Clear the Connect from ProtChange */
|
||||
UsbBuildVendorRequest(Urb,
|
||||
URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_IN,
|
||||
0,
|
||||
USB_REQUEST_CLEAR_FEATURE,
|
||||
C_PORT_CONNECTION,
|
||||
PortLoop + 1,
|
||||
&PortStatusAndChange,
|
||||
0,
|
||||
sizeof(PORTSTATUSANDCHANGE),
|
||||
0);
|
||||
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to Clear the Port Connect!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send the miniport controller a SCE request so when the port resets we can be informed */
|
||||
WaitForUsbDeviceArrivalNotification(DeviceObject);
|
||||
|
||||
UsbBuildVendorRequest(Urb,
|
||||
URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_IN,
|
||||
0,
|
||||
USB_REQUEST_SET_FEATURE,
|
||||
PORT_RESET,
|
||||
PortLoop + 1,
|
||||
&PortStatusAndChange,
|
||||
0,
|
||||
sizeof(PORTSTATUSANDCHANGE),
|
||||
0);
|
||||
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to Reset the port!\n");
|
||||
return;
|
||||
}
|
||||
/* At this point the miniport will complete another SCE to inform of Reset completed */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DeviceArrivalCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
|
||||
{
|
||||
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
LONG i;
|
||||
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
||||
|
||||
/* FIXME: Need to use the number of ports returned from miniport at device start */
|
||||
for (i=0; i < 8; i++)
|
||||
DPRINT1("Port %x DeviceExtension->PortStatus %x\n",i, DeviceExtension->PortStatus[i]);
|
||||
for (i=0; i < DeviceExtension->UsbExtHubInfo.NumberOfPorts; i++)
|
||||
DPRINT1("Port %x DeviceExtension->PortStatus %x\n",i+1, DeviceExtension->PortStatus[i]);
|
||||
|
||||
if (Irp->PendingReturned)
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
ExInitializeWorkItem(&DeviceExtension->WorkItem, (PWORKER_THREAD_ROUTINE)WorkerThread, Context);
|
||||
ExQueueWorkItem(&DeviceExtension->WorkItem, DelayedWorkQueue);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -147,7 +455,8 @@ WaitForUsbDeviceArrivalNotification(PDEVICE_OBJECT DeviceObject)
|
|||
Stack->Parameters.Others.Argument1 = Urb;
|
||||
Stack->Parameters.Others.Argument2 = NULL;
|
||||
|
||||
IoSetCompletionRoutineEx(DeviceExtension->RootHubPdo, Irp, (PIO_COMPLETION_ROUTINE)DeviceArrivalCompletion, DeviceObject, TRUE, TRUE, TRUE);
|
||||
//IoSetCompletionRoutineEx(DeviceExtension->RootHubPdo, Irp, (PIO_COMPLETION_ROUTINE)DeviceArrivalCompletion, DeviceObject, TRUE, TRUE, TRUE);
|
||||
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)DeviceArrivalCompletion, DeviceObject, TRUE, TRUE, TRUE);
|
||||
|
||||
Status = IoCallDriver(DeviceExtension->RootHubPdo, Irp);
|
||||
|
||||
|
@ -193,7 +502,7 @@ QueryRootHub(IN PDEVICE_OBJECT Pdo, IN ULONG IoControlCode, OUT PVOID OutParamet
|
|||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Usbhub: Operation pending\n");
|
||||
DPRINT1("Usbhub: Operation pending\n");
|
||||
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
@ -273,33 +582,22 @@ UsbhubFdoQueryBusRelations(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_RELATIONS
|
|||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
PDEVICE_OBJECT Pdo;
|
||||
PHUB_DEVICE_EXTENSION PdoExtension;
|
||||
ULONG i;
|
||||
ULONG Children = 0;
|
||||
ULONG NeededSize;
|
||||
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
DPRINT1("USBHUB: Query Bus Relations\n");
|
||||
|
||||
/* Create PDOs that are missing */
|
||||
for (i = 0; i < USB_MAXCHILDREN; i++)
|
||||
{
|
||||
|
||||
if (DeviceExtension->Children[i] == NULL)
|
||||
if (DeviceExtension->UsbChildren[i] == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Children++;
|
||||
Pdo = DeviceExtension->Children[i];
|
||||
Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
PdoExtension = Pdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(PdoExtension, sizeof(HUB_DEVICE_EXTENSION));
|
||||
|
||||
PdoExtension->IsFDO = FALSE;
|
||||
|
||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
}
|
||||
|
||||
/* Fill returned structure */
|
||||
|
@ -364,6 +662,7 @@ UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO, &DeviceExtension->RootHubPdo, &DeviceExtension->RootHubFdo);
|
||||
ASSERT(DeviceExtension->RootHubPdo);
|
||||
ASSERT(DeviceExtension->RootHubFdo);
|
||||
DPRINT1("RootPdo %x, RootFdo %x\n", DeviceExtension->RootHubPdo, DeviceExtension->RootHubFdo);
|
||||
|
||||
/* Send the START_DEVICE irp down to the PDO of RootHub */
|
||||
Status = ForwardIrpAndWait(DeviceExtension->RootHubPdo, Irp);
|
||||
|
@ -416,13 +715,13 @@ UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
&Result);
|
||||
|
||||
|
||||
DPRINT1("Status %x, Result %x\n", Status, Result);
|
||||
DPRINT1("InformationLevel %x\n", DeviceExtension->DeviceInformation.InformationLevel);
|
||||
DPRINT1("ActualLength %x\n", DeviceExtension->DeviceInformation.ActualLength);
|
||||
DPRINT1("PortNumber %x\n", DeviceExtension->DeviceInformation.PortNumber);
|
||||
DPRINT1("DeviceDescriptor %x\n", DeviceExtension->DeviceInformation.DeviceDescriptor);
|
||||
DPRINT1("HubAddress %x\n", DeviceExtension->DeviceInformation.HubAddress);
|
||||
DPRINT1("NumberofPipes %x\n", DeviceExtension->DeviceInformation.NumberOfOpenPipes);
|
||||
DPRINT("Status %x, Result %x\n", Status, Result);
|
||||
DPRINT("InformationLevel %x\n", DeviceExtension->DeviceInformation.InformationLevel);
|
||||
DPRINT("ActualLength %x\n", DeviceExtension->DeviceInformation.ActualLength);
|
||||
DPRINT("PortNumber %x\n", DeviceExtension->DeviceInformation.PortNumber);
|
||||
DPRINT("DeviceDescriptor %x\n", DeviceExtension->DeviceInformation.DeviceDescriptor);
|
||||
DPRINT("HubAddress %x\n", DeviceExtension->DeviceInformation.HubAddress);
|
||||
DPRINT("NumberofPipes %x\n", DeviceExtension->DeviceInformation.NumberOfOpenPipes);
|
||||
|
||||
/* Get roothubs device descriptor */
|
||||
UsbBuildGetDescriptorRequest(Urb,
|
||||
|
@ -458,6 +757,7 @@ UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;
|
||||
|
||||
Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Usbhub: Failed to get RootHub Configuration with status %x\n", Status);
|
||||
|
@ -513,8 +813,6 @@ UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
|
||||
Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
DPRINT1("Status %x\n", Status);
|
||||
|
||||
DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
|
||||
DeviceExtension->PipeHandle = Urb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
|
||||
DPRINT1("Configuration Handle %x\n", DeviceExtension->ConfigurationHandle);
|
||||
|
@ -523,6 +821,52 @@ UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|||
|
||||
DPRINT1("Status %x\n", Status);
|
||||
|
||||
{
|
||||
int PortLoop;
|
||||
USHORT PortStatusAndChange[2];
|
||||
|
||||
for (PortLoop=0; PortLoop< DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
|
||||
{
|
||||
DPRINT1("Port %x\n", PortLoop);
|
||||
UsbBuildVendorRequest(Urb,
|
||||
URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_IN,
|
||||
0,
|
||||
USB_REQUEST_SET_FEATURE,
|
||||
PORT_POWER,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
Urb->UrbOSFeatureDescriptorRequest.MS_FeatureDescriptorIndex = PortLoop + 1;
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
DPRINT1("Status %x\n", Status);
|
||||
|
||||
UsbBuildVendorRequest(Urb,
|
||||
URB_FUNCTION_CLASS_OTHER,
|
||||
sizeof(Urb->UrbControlVendorClassRequest),
|
||||
USBD_TRANSFER_DIRECTION_OUT,
|
||||
0,
|
||||
USB_REQUEST_GET_STATUS,
|
||||
0,
|
||||
PortLoop + 1,
|
||||
&PortStatusAndChange,
|
||||
0,
|
||||
sizeof(PortStatusAndChange),
|
||||
0);
|
||||
Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
|
||||
|
||||
DPRINT1("Status %x\n", Status);
|
||||
DPRINT1("PortStatus = %x\n", PortStatusAndChange[0]);
|
||||
DPRINT1("PortChange = %x\n", PortStatusAndChange[1]);
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(Urb);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,298 +16,299 @@
|
|||
|
||||
NTSTATUS
|
||||
UsbhubInternalDeviceControlPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = 0;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = 0;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("Usbhub: UsbhubInternalDeviceControlPdo() called\n");
|
||||
DPRINT1("Usbhub: UsbhubInternalDeviceControlPdo() called\n");
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Status = Irp->IoStatus.Status;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
DPRINT1("Usbhub: IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
|
||||
if (Irp->AssociatedIrp.SystemBuffer == NULL
|
||||
|| Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
PVOID* pHubPointer;
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
DPRINT1("Usbhub: IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
|
||||
if (Irp->AssociatedIrp.SystemBuffer == NULL
|
||||
|| Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
PVOID* pHubPointer;
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
|
||||
*pHubPointer = DeviceExtension->dev;
|
||||
Information = sizeof(PVOID);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
Information = Irp->IoStatus.Information;
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
}
|
||||
pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
|
||||
*pHubPointer = DeviceExtension->dev;
|
||||
Information = sizeof(PVOID);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
Information = Irp->IoStatus.Information;
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
UsbhubPdoStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* Register and activate device interface */
|
||||
/* Register and activate device interface */
|
||||
/*
|
||||
Status = IoRegisterDeviceInterface(
|
||||
DeviceObject,
|
||||
DeviceExtension->dev->descriptor.bDeviceClass == USB_CLASS_HUB ?
|
||||
&GUID_DEVINTERFACE_USB_HUB :
|
||||
&GUID_DEVINTERFACE_USB_DEVICE,
|
||||
NULL,
|
||||
&DeviceExtension->SymbolicLinkName);
|
||||
Status = IoRegisterDeviceInterface(
|
||||
DeviceObject,
|
||||
DeviceExtension->dev->descriptor.bDeviceClass == USB_CLASS_HUB ?
|
||||
&GUID_DEVINTERFACE_USB_HUB :
|
||||
&GUID_DEVINTERFACE_USB_DEVICE,
|
||||
NULL,
|
||||
&DeviceExtension->SymbolicLinkName);
|
||||
*/
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Usbhub: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Usbhub: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//Status = IoSetDeviceInterfaceState(&DeviceExtension->SymbolicLinkName, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Usbhub: IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
//Status = IoSetDeviceInterfaceState(&DeviceExtension->SymbolicLinkName, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Usbhub: IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
UsbhubPdoQueryId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
OUT ULONG_PTR* Information)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
OUT ULONG_PTR* Information)
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG IdType;
|
||||
PUNICODE_STRING SourceString;
|
||||
UNICODE_STRING String;
|
||||
NTSTATUS Status;
|
||||
PHUB_CHILDDEVICE_EXTENSION DeviceExtension;
|
||||
ULONG IdType;
|
||||
PWCHAR SourceString = NULL;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
RtlInitUnicodeString(&String, NULL);
|
||||
IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
|
||||
DeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
switch (IdType)
|
||||
{
|
||||
case BusQueryDeviceID:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
|
||||
SourceString = &DeviceExtension->DeviceId;
|
||||
break;
|
||||
}
|
||||
case BusQueryHardwareIDs:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
|
||||
SourceString = &DeviceExtension->HardwareIds;
|
||||
break;
|
||||
}
|
||||
case BusQueryCompatibleIDs:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
|
||||
SourceString = &DeviceExtension->CompatibleIds;
|
||||
break;
|
||||
}
|
||||
case BusQueryInstanceID:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
|
||||
SourceString = &DeviceExtension->InstanceId;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
switch (IdType)
|
||||
{
|
||||
case BusQueryDeviceID:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
|
||||
SourceString = DeviceExtension->DeviceId;
|
||||
break;
|
||||
}
|
||||
/* FIXME: Implement */
|
||||
case BusQueryHardwareIDs:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
|
||||
SourceString = DeviceExtension->HardwareIds;
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
/* FIXME: Implement */
|
||||
case BusQueryCompatibleIDs:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
|
||||
SourceString = DeviceExtension->CompatibleIds;
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
case BusQueryInstanceID:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
|
||||
SourceString = DeviceExtension->InstanceId;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Status = UsbhubDuplicateUnicodeString(
|
||||
&String,
|
||||
SourceString,
|
||||
PagedPool);
|
||||
*Information = (ULONG_PTR)String.Buffer;
|
||||
return Status;
|
||||
*Information = (ULONG_PTR)SourceString;
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
UsbhubPdoQueryDeviceText(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
OUT ULONG_PTR* Information)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
OUT ULONG_PTR* Information)
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
DEVICE_TEXT_TYPE DeviceTextType;
|
||||
LCID LocaleId;
|
||||
PHUB_CHILDDEVICE_EXTENSION DeviceExtension;
|
||||
DEVICE_TEXT_TYPE DeviceTextType;
|
||||
LCID LocaleId;
|
||||
|
||||
DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
|
||||
LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
DPRINT1("Usbhub: UsbhubPdoQueryDeviceText\n");
|
||||
switch (DeviceTextType)
|
||||
{
|
||||
case DeviceTextDescription:
|
||||
case DeviceTextLocationInformation:
|
||||
{
|
||||
if (DeviceTextType == DeviceTextDescription)
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
|
||||
else
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
|
||||
DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
|
||||
LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
|
||||
DeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* if (!DeviceExtension->dev->descriptor.iProduct)
|
||||
return STATUS_NOT_SUPPORTED;*/
|
||||
switch (DeviceTextType)
|
||||
{
|
||||
case DeviceTextDescription:
|
||||
case DeviceTextLocationInformation:
|
||||
{
|
||||
if (DeviceTextType == DeviceTextDescription)
|
||||
{
|
||||
*Information = (ULONG_PTR)DeviceExtension->TextDescription;
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
|
||||
}
|
||||
else
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
default:
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
/* if (!DeviceExtension->dev->descriptor.iProduct)
|
||||
return STATUS_NOT_SUPPORTED;*/
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
default:
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
UsbhubPnpPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG MinorFunction;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = 0;
|
||||
NTSTATUS Status;
|
||||
ULONG MinorFunction;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = 0;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE: /* 0x0 */
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
Status = UsbhubPdoStartDevice(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
|
||||
{
|
||||
PDEVICE_CAPABILITIES DeviceCapabilities;
|
||||
ULONG i;
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE: /* 0x0 */
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
Status = UsbhubPdoStartDevice(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
|
||||
{
|
||||
PDEVICE_CAPABILITIES DeviceCapabilities;
|
||||
ULONG i;
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
|
||||
|
||||
DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
|
||||
/* FIXME: capabilities can change with connected device */
|
||||
DeviceCapabilities->LockSupported = TRUE;
|
||||
DeviceCapabilities->EjectSupported = FALSE;
|
||||
DeviceCapabilities->Removable = FALSE;
|
||||
DeviceCapabilities->DockDevice = FALSE;
|
||||
DeviceCapabilities->UniqueID = FALSE;
|
||||
DeviceCapabilities->SilentInstall = TRUE;
|
||||
DeviceCapabilities->RawDeviceOK = FALSE;
|
||||
DeviceCapabilities->SurpriseRemovalOK = FALSE;
|
||||
DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
|
||||
//DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
|
||||
DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
|
||||
for (i = 0; i < PowerSystemMaximum; i++)
|
||||
DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
|
||||
//DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
|
||||
DeviceCapabilities->D1Latency = 0; /* FIXME */
|
||||
DeviceCapabilities->D2Latency = 0; /* FIXME */
|
||||
DeviceCapabilities->D3Latency = 0; /* FIXME */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_RESOURCES: /* 0x0a */
|
||||
{
|
||||
PCM_RESOURCE_LIST ResourceList;
|
||||
DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
|
||||
/* FIXME: capabilities can change with connected device */
|
||||
DeviceCapabilities->LockSupported = TRUE;
|
||||
DeviceCapabilities->EjectSupported = FALSE;
|
||||
DeviceCapabilities->Removable = FALSE;
|
||||
DeviceCapabilities->DockDevice = FALSE;
|
||||
DeviceCapabilities->UniqueID = FALSE;
|
||||
DeviceCapabilities->SilentInstall = TRUE;
|
||||
DeviceCapabilities->RawDeviceOK = FALSE;
|
||||
DeviceCapabilities->SurpriseRemovalOK = FALSE;
|
||||
DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
|
||||
//DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
|
||||
DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
|
||||
for (i = 0; i < PowerSystemMaximum; i++)
|
||||
DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
|
||||
//DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
|
||||
DeviceCapabilities->D1Latency = 0; /* FIXME */
|
||||
DeviceCapabilities->D2Latency = 0; /* FIXME */
|
||||
DeviceCapabilities->D3Latency = 0; /* FIXME */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_RESOURCES: /* 0x0a */
|
||||
{
|
||||
PCM_RESOURCE_LIST ResourceList;
|
||||
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
|
||||
ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
|
||||
if (!ResourceList)
|
||||
{
|
||||
DPRINT1("Usbhub: ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceList->Count = 0;
|
||||
Information = (ULONG_PTR)ResourceList;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
|
||||
{
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
|
||||
ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
|
||||
if (!ResourceList)
|
||||
{
|
||||
DPRINT1("Usbhub: ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceList->Count = 0;
|
||||
Information = (ULONG_PTR)ResourceList;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
|
||||
{
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
|
||||
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
|
||||
ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
|
||||
if (!ResourceList)
|
||||
{
|
||||
DPRINT1("Usbhub: ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlZeroMemory(ResourceList, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
|
||||
ResourceList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
|
||||
ResourceList->AlternativeLists = 1;
|
||||
ResourceList->List->Version = 1;
|
||||
ResourceList->List->Revision = 1;
|
||||
ResourceList->List->Count = 0;
|
||||
Information = (ULONG_PTR)ResourceList;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
|
||||
{
|
||||
Status = UsbhubPdoQueryDeviceText(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_ID: /* 0x13 */
|
||||
{
|
||||
Status = UsbhubPdoQueryId(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* We can't forward request to the lower driver, because
|
||||
* we are a Pdo, so we don't have lower driver...
|
||||
*/
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
|
||||
Information = Irp->IoStatus.Information;
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
}
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
|
||||
ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
|
||||
if (!ResourceList)
|
||||
{
|
||||
DPRINT1("Usbhub: ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlZeroMemory(ResourceList, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
|
||||
ResourceList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
|
||||
ResourceList->AlternativeLists = 1;
|
||||
ResourceList->List->Version = 1;
|
||||
ResourceList->List->Revision = 1;
|
||||
ResourceList->List->Count = 0;
|
||||
Information = (ULONG_PTR)ResourceList;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
|
||||
{
|
||||
Status = UsbhubPdoQueryDeviceText(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_ID: /* 0x13 */
|
||||
{
|
||||
Status = UsbhubPdoQueryId(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* We can't forward request to the lower driver, because
|
||||
* we are a Pdo, so we don't have lower driver...
|
||||
*/
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
|
||||
Information = Irp->IoStatus.Information;
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ UsbhubAddDevice(
|
|||
|
||||
DeviceExtension->IsFDO = TRUE;
|
||||
Fdo->Flags |= DO_POWER_PAGABLE;
|
||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
||||
//Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
|
||||
DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Usbhub: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
|
||||
|
|
|
@ -61,16 +61,29 @@ typedef struct _USB_DEVICE
|
|||
USB_CONFIGURATION *ActiveConfig;
|
||||
USB_INTERFACE *ActiveInterface;
|
||||
USB_CONFIGURATION **Configs;
|
||||
|
||||
} USB_DEVICE, *PUSB_DEVICE;
|
||||
|
||||
typedef struct _HUB_CHILDDEVICE_EXTENSION
|
||||
{
|
||||
BOOLEAN IsFDO;
|
||||
PDEVICE_OBJECT Parent;
|
||||
PWCHAR DeviceId; // REG_SZ
|
||||
PWCHAR InstanceId; // REG_SZ
|
||||
PWCHAR HardwareIds; // REG_MULTI_SZ
|
||||
PWCHAR CompatibleIds; // REG_MULTI_SZ
|
||||
PWCHAR TextDescription;
|
||||
UNICODE_STRING SymbolicLinkName;
|
||||
} HUB_CHILDDEVICE_EXTENSION, *PHUB_CHILDDEVICE_EXTENSION;
|
||||
|
||||
typedef struct _HUB_DEVICE_EXTENSION
|
||||
{
|
||||
BOOLEAN IsFDO;
|
||||
USB_DEVICE* dev;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
BOOLEAN IsFDO;
|
||||
USB_DEVICE* dev;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
ULONG ChildCount;
|
||||
PDEVICE_OBJECT Children[USB_MAXCHILDREN];
|
||||
PDEVICE_OBJECT Children[USB_MAXCHILDREN];
|
||||
|
||||
PUSB_DEVICE UsbChildren[USB_MAXCHILDREN];
|
||||
|
||||
PUSB_DEVICE RootHubUsbDevice;
|
||||
|
||||
|
@ -79,7 +92,7 @@ typedef struct _HUB_DEVICE_EXTENSION
|
|||
|
||||
ULONG HubCount;
|
||||
|
||||
ULONG PortStatus[256];
|
||||
USHORT PortStatus[256];
|
||||
|
||||
USB_BUS_INTERFACE_HUB_V5 HubInterface;
|
||||
USB_BUS_INTERFACE_USBDI_V2 UsbDInterface;
|
||||
|
@ -94,72 +107,70 @@ typedef struct _HUB_DEVICE_EXTENSION
|
|||
USB_EXTHUB_INFORMATION_0 UsbExtHubInfo;
|
||||
USB_DEVICE_INFORMATION_0 DeviceInformation;
|
||||
|
||||
WORK_QUEUE_ITEM WorkItem;
|
||||
|
||||
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
|
||||
USBD_PIPE_HANDLE PipeHandle;
|
||||
/* Fields valid only when IsFDO == FALSE */
|
||||
UNICODE_STRING DeviceId; // REG_SZ
|
||||
UNICODE_STRING InstanceId; // REG_SZ
|
||||
UNICODE_STRING HardwareIds; // REG_MULTI_SZ
|
||||
UNICODE_STRING CompatibleIds; // REG_MULTI_SZ
|
||||
|
||||
UNICODE_STRING SymbolicLinkName;
|
||||
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
|
||||
|
||||
/* createclose.c */
|
||||
NTSTATUS NTAPI
|
||||
UsbhubCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
UsbhubClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
UsbhubCleanup(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/* fdo.c */
|
||||
NTSTATUS NTAPI
|
||||
UsbhubPnpFdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
UsbhubDeviceControlFdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/* misc.c */
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ForwardIrpAndForget(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
UsbhubDuplicateUnicodeString(
|
||||
OUT PUNICODE_STRING Destination,
|
||||
IN PUNICODE_STRING Source,
|
||||
IN POOL_TYPE PoolType);
|
||||
OUT PUNICODE_STRING Destination,
|
||||
IN PUNICODE_STRING Source,
|
||||
IN POOL_TYPE PoolType);
|
||||
|
||||
NTSTATUS
|
||||
UsbhubInitMultiSzString(
|
||||
OUT PUNICODE_STRING Destination,
|
||||
... /* list of PCSZ */);
|
||||
OUT PUNICODE_STRING Destination,
|
||||
.../* list of PCSZ */);
|
||||
|
||||
/* pdo.c */
|
||||
NTSTATUS NTAPI
|
||||
UsbhubPnpPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
UsbhubInternalDeviceControlPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
|
Loading…
Reference in a new issue