mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-01 04:13:35 +00:00
Implement IRP_MN_QUERY_DEVICE_RELATIONS for USB hubs
Implement IRP_MN_QUERY_ID for devices enumerated by USB hubs svn path=/trunk/; revision=16093
This commit is contained in:
@@ -10,8 +10,6 @@
|
||||
#define NDEBUG
|
||||
#include "usbhub.h"
|
||||
|
||||
extern struct usb_driver hub_driver;
|
||||
|
||||
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
|
||||
|
||||
static VOID
|
||||
@@ -47,6 +45,147 @@ UsbhubGetUserBuffers(
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
UsbhubFdoQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PDEVICE_RELATIONS* pDeviceRelations)
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
PDEVICE_OBJECT Pdo;
|
||||
PHUB_DEVICE_EXTENSION PdoExtension;
|
||||
struct usb_device* dev;
|
||||
ULONG i;
|
||||
ULONG Children = 0;
|
||||
ULONG NeededSize;
|
||||
NTSTATUS Status;
|
||||
CHAR Buffer[3][40];
|
||||
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
dev = DeviceExtension->dev;
|
||||
|
||||
/* Create PDOs that are missing */
|
||||
for (i = 0; i < USB_MAXCHILDREN; i++)
|
||||
{
|
||||
if (dev->children[i] == NULL)
|
||||
{
|
||||
/* No child device at this place */
|
||||
continue;
|
||||
}
|
||||
Children++;
|
||||
if (DeviceExtension->Children[i] != NULL)
|
||||
{
|
||||
/* PDO already exists */
|
||||
continue;
|
||||
}
|
||||
/* Need to create the PDO */
|
||||
Status = IoCreateDevice(
|
||||
DeviceObject->DriverObject,
|
||||
sizeof(HUB_DEVICE_EXTENSION),
|
||||
NULL, /* Device name */
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
FILE_AUTOGENERATED_DEVICE_NAME,
|
||||
FALSE,
|
||||
&DeviceExtension->Children[i]);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Usbhub: IoCreateDevice() failed with status 0x%08lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Pdo = DeviceExtension->Children[i];
|
||||
Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
|
||||
PdoExtension = Pdo->DeviceExtension;
|
||||
RtlZeroMemory(PdoExtension, sizeof(HUB_DEVICE_EXTENSION));
|
||||
|
||||
PdoExtension->IsFDO = FALSE;
|
||||
PdoExtension->dev = dev->children[i];
|
||||
|
||||
RtlInitUnicodeString(
|
||||
&PdoExtension->DeviceDescription,
|
||||
L"USB device"); /* FIXME */
|
||||
|
||||
sprintf(Buffer[0], "%lu", i + 1);
|
||||
Status = UsbhubInitMultiSzString(
|
||||
&PdoExtension->InstanceId,
|
||||
Buffer[0], NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
/* FIXME: what if it is a multiple-interface usb device? */
|
||||
sprintf(Buffer[0], "USB\\Vid_%04x&Pid_%04x&Rev_%04x",
|
||||
PdoExtension->dev->descriptor.idVendor,
|
||||
PdoExtension->dev->descriptor.idProduct,
|
||||
0 /* FIXME: need to put the revision */);
|
||||
sprintf(Buffer[1], "USB\\Vid_%04x&Pid_%04x",
|
||||
PdoExtension->dev->descriptor.idVendor,
|
||||
PdoExtension->dev->descriptor.idProduct);
|
||||
Status = UsbhubInitMultiSzString(
|
||||
&PdoExtension->HardwareIds,
|
||||
Buffer[0], Buffer[1], NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
Status = UsbhubInitMultiSzString(
|
||||
&PdoExtension->DeviceId,
|
||||
Buffer[1], NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
/* FIXME: what if it is a multiple-interface usb device? */
|
||||
sprintf(Buffer[0], "USB\\Class_%02x&SubClass_%02x&Prot_%02x",
|
||||
PdoExtension->dev->descriptor.bDeviceClass,
|
||||
PdoExtension->dev->descriptor.bDeviceSubClass,
|
||||
PdoExtension->dev->descriptor.bDeviceProtocol);
|
||||
sprintf(Buffer[1], "USB\\Class_%02x&SubClass_%02x",
|
||||
PdoExtension->dev->descriptor.bDeviceClass,
|
||||
PdoExtension->dev->descriptor.bDeviceSubClass);
|
||||
sprintf(Buffer[2], "USB\\Class_%02x",
|
||||
PdoExtension->dev->descriptor.bDeviceClass);
|
||||
Status = UsbhubInitMultiSzString(
|
||||
&PdoExtension->CompatibleIds,
|
||||
Buffer[0], Buffer[1], Buffer[2], NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
}
|
||||
|
||||
/* Fill returned structure */
|
||||
NeededSize = sizeof(DEVICE_RELATIONS);
|
||||
if (Children > 1)
|
||||
NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
|
||||
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
|
||||
PagedPool,
|
||||
NeededSize);
|
||||
if (!DeviceRelations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
DeviceRelations->Count = Children;
|
||||
Children = 0;
|
||||
for (i = 0; i < USB_MAXCHILDREN; i++)
|
||||
{
|
||||
if (DeviceExtension->Children[i])
|
||||
{
|
||||
ObReferenceObject(DeviceExtension->Children[i]);
|
||||
DeviceRelations->Objects[Children++] = DeviceExtension->Children[i];
|
||||
}
|
||||
}
|
||||
ASSERT(Children == DeviceRelations->Count);
|
||||
|
||||
*pDeviceRelations = DeviceRelations;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
ByeBye:
|
||||
RtlFreeUnicodeString(&PdoExtension->DeviceDescription);
|
||||
RtlFreeUnicodeString(&PdoExtension->DeviceId);
|
||||
RtlFreeUnicodeString(&PdoExtension->InstanceId);
|
||||
RtlFreeUnicodeString(&PdoExtension->HardwareIds);
|
||||
RtlFreeUnicodeString(&PdoExtension->CompatibleIds);
|
||||
IoDeleteDevice(Pdo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
UsbhubPnpFdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
@@ -62,33 +201,35 @@ UsbhubPnpFdo(
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
case IRP_MN_START_DEVICE: /* 0x0 */
|
||||
{
|
||||
DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||
//if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
|
||||
// Status = OHCD_PnPStartDevice(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
//case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
//case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
|
||||
{
|
||||
DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
|
||||
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
|
||||
Status = STATUS_SUCCESS;
|
||||
IoDeleteDevice(DeviceObject); // just delete device for now
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
switch (IrpSp->Parameters.QueryDeviceRelations.Type)
|
||||
{
|
||||
case BusRelations:
|
||||
{
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
|
||||
Status = UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations);
|
||||
Information = (ULONG_PTR)DeviceRelations;
|
||||
break;
|
||||
}
|
||||
case RemovalRelations:
|
||||
{
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
default:
|
||||
DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
|
||||
IrpSp->Parameters.QueryDeviceRelations.Type);
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -104,11 +245,6 @@ UsbhubPnpFdo(
|
||||
return Status;
|
||||
}
|
||||
|
||||
static inline struct device *hubdev (struct usb_device *dev)
|
||||
{
|
||||
return &dev->actconfig->interface [0].dev;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
UsbhubDeviceControlFdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
@@ -147,7 +283,7 @@ UsbhubDeviceControlFdo(
|
||||
NodeInformation->NodeType = UsbHub;
|
||||
RtlCopyMemory(
|
||||
&NodeInformation->u.HubInformation.HubDescriptor,
|
||||
((struct usb_hub *)usb_get_intfdata(to_usb_interface(hubdev(dev))))->descriptor,
|
||||
((struct usb_hub *)usb_get_intfdata(to_usb_interface(&dev->actconfig->interface[0].dev)))->descriptor,
|
||||
sizeof(USB_HUB_DESCRIPTOR));
|
||||
NodeInformation->u.HubInformation.HubIsBusPowered = TRUE; /* FIXME */
|
||||
Information = sizeof(USB_NODE_INFORMATION);
|
||||
@@ -189,17 +325,24 @@ UsbhubDeviceControlFdo(
|
||||
ConnectionInformation = (PUSB_NODE_CONNECTION_INFORMATION)BufferOut;
|
||||
DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION partially implemented\n");
|
||||
dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
|
||||
ConnectionInformation->ConnectionIndex = 0; /* FIXME */
|
||||
dev = dev->children[ConnectionInformation->ConnectionIndex = 0];
|
||||
if (dev == NULL)
|
||||
{
|
||||
/* No device connected to this port */
|
||||
RtlZeroMemory(ConnectionInformation, sizeof(USB_NODE_CONNECTION_INFORMATION));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
RtlCopyMemory(
|
||||
&ConnectionInformation->DeviceDescriptor,
|
||||
&dev->descriptor,
|
||||
sizeof(USB_DEVICE_DESCRIPTOR));
|
||||
ConnectionInformation->CurrentConfigurationValue = 0; /* FIXME */
|
||||
ConnectionInformation->LowSpeed = TRUE; /* FIXME */
|
||||
ConnectionInformation->DeviceIsHub = TRUE;
|
||||
RtlZeroMemory(&ConnectionInformation->DeviceAddress, sizeof(ConnectionInformation->DeviceAddress)); /* FIXME */
|
||||
ConnectionInformation->LowSpeed = dev->speed == USB_SPEED_LOW || dev->speed == USB_SPEED_FULL;
|
||||
ConnectionInformation->DeviceIsHub = dev->descriptor.bDeviceClass == USB_CLASS_HUB;
|
||||
ConnectionInformation->DeviceAddress = dev->devnum;
|
||||
RtlZeroMemory(&ConnectionInformation->NumberOfOpenPipes, sizeof(ConnectionInformation->NumberOfOpenPipes)); /* FIXME */
|
||||
RtlZeroMemory(&ConnectionInformation->ConnectionStatus, sizeof(ConnectionInformation->ConnectionStatus)); /* FIXME */
|
||||
ConnectionInformation->ConnectionStatus = DeviceConnected;
|
||||
RtlZeroMemory(&ConnectionInformation->PipeList, sizeof(ConnectionInformation->PipeList)); /* FIXME */
|
||||
/*for (i = 0; i < 32; i++)
|
||||
{
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
*/
|
||||
|
||||
//#define NDEBUG
|
||||
#include <stdio.h>
|
||||
#include "usbhub.h"
|
||||
|
||||
extern struct usb_driver hub_driver;
|
||||
|
||||
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
|
||||
|
||||
NTSTATUS
|
||||
@@ -44,6 +43,59 @@ UsbhubDeviceControlPdo(
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
UsbhubPdoQueryId(
|
||||
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;
|
||||
|
||||
IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
|
||||
DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
RtlInitUnicodeString(&String, NULL);
|
||||
|
||||
switch (IdType)
|
||||
{
|
||||
case BusQueryDeviceID:
|
||||
{
|
||||
DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
|
||||
SourceString = &DeviceExtension->DeviceId;
|
||||
break;
|
||||
}
|
||||
case BusQueryHardwareIDs:
|
||||
{
|
||||
DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
|
||||
SourceString = &DeviceExtension->HardwareIds;
|
||||
break;
|
||||
}
|
||||
case BusQueryCompatibleIDs:
|
||||
DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
|
||||
SourceString = &DeviceExtension->CompatibleIds;
|
||||
break;
|
||||
case BusQueryInstanceID:
|
||||
{
|
||||
DPRINT("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;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
UsbhubPnpPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
@@ -59,6 +111,11 @@ UsbhubPnpPdo(
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_ID: /* 0x13 */
|
||||
{
|
||||
Status = UsbhubPdoQueryId(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* We can't forward request to the lower driver, because
|
||||
|
||||
@@ -19,6 +19,15 @@ typedef struct _HUB_DEVICE_EXTENSION
|
||||
BOOLEAN IsFDO;
|
||||
struct usb_device* dev;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
|
||||
PDEVICE_OBJECT Children[USB_MAXCHILDREN];
|
||||
|
||||
/* Fields valid only when IsFDO == FALSE */
|
||||
UNICODE_STRING DeviceDescription; // REG_SZ
|
||||
UNICODE_STRING DeviceId; // REG_SZ
|
||||
UNICODE_STRING InstanceId; // REG_SZ
|
||||
UNICODE_STRING HardwareIds; // REG_MULTI_SZ
|
||||
UNICODE_STRING CompatibleIds; // REG_MULTI_SZ
|
||||
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
|
||||
|
||||
/* createclose.c */
|
||||
|
||||
Reference in New Issue
Block a user