mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
[HIDPARSE][HIDPARSER][LIBUSB][USBHUB] Merge USB stack improvements by Vardan Mikayelyan in GSoC.
svn path=/trunk/; revision=73605
This commit is contained in:
parent
92d1110c00
commit
9bbe22afa8
11 changed files with 619 additions and 263 deletions
|
@ -125,6 +125,29 @@ HidP_GetCaps(
|
|||
return HidParser_GetCaps(&Parser, PreparsedData, Capabilities);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
TranslateStatusForUpperLayer(
|
||||
IN HIDPARSER_STATUS Status)
|
||||
{
|
||||
//
|
||||
// now we are handling only this values, for others just return
|
||||
// status as it is.
|
||||
//
|
||||
switch (Status)
|
||||
{
|
||||
case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES:
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
case HIDPARSER_STATUS_INVALID_REPORT_TYPE:
|
||||
return HIDP_STATUS_INVALID_REPORT_TYPE;
|
||||
case HIDPARSER_STATUS_BUFFER_TOO_SMALL:
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
|
||||
return STATUS_NO_DATA_DETECTED;
|
||||
default:
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HidP_GetCollectionDescription(
|
||||
|
@ -134,6 +157,7 @@ HidP_GetCollectionDescription(
|
|||
OUT PHIDP_DEVICE_DESC DeviceDescription)
|
||||
{
|
||||
HID_PARSER Parser;
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// init parser
|
||||
|
@ -143,7 +167,8 @@ HidP_GetCollectionDescription(
|
|||
//
|
||||
// get description;
|
||||
//
|
||||
return HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength, PoolType, DeviceDescription);
|
||||
Status = HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength, PoolType, DeviceDescription);
|
||||
return TranslateStatusForUpperLayer(Status);
|
||||
}
|
||||
|
||||
HIDAPI
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
add_definitions(-DDEBUG_MODE)
|
||||
add_definitions(-DNTDDI_VERSION=0x05020400)
|
||||
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||
|
||||
list(APPEND SOURCE
|
||||
|
|
|
@ -569,6 +569,11 @@ QueryInterface(
|
|||
Stack->Parameters.QueryInterface.Interface = Interface;
|
||||
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
||||
|
||||
//
|
||||
// Initialize the status block before sending the IRP
|
||||
//
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
|
@ -1089,8 +1094,7 @@ DestroyUsbChildDeviceObject(
|
|||
PDEVICE_OBJECT ChildDeviceObject = NULL;
|
||||
ULONG Index = 0;
|
||||
|
||||
DPRINT("Removing device on port %d (Child index: %d)\n", PortId, Index);
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
for (Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[Index])
|
||||
|
@ -1111,12 +1115,17 @@ DestroyUsbChildDeviceObject(
|
|||
if (!ChildDeviceObject)
|
||||
{
|
||||
DPRINT1("Removal request for non-existant device!\n");
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DPRINT("Removing device on port %d (Child index: %d)\n", PortId, Index);
|
||||
|
||||
/* Remove the device from the table */
|
||||
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
|
||||
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
/* Invalidate device relations for the root hub */
|
||||
IoInvalidateDeviceRelations(HubDeviceExtension->RootHubPhysicalDeviceObject, BusRelations);
|
||||
|
||||
|
@ -1147,26 +1156,6 @@ CreateUsbChildDeviceObject(
|
|||
HubInterface = &HubDeviceExtension->HubInterface;
|
||||
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||
HubInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
|
||||
//
|
||||
// Find an empty slot in the child device array
|
||||
//
|
||||
for (ChildDeviceCount = 0; ChildDeviceCount < USB_MAXCHILDREN; ChildDeviceCount++)
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
|
||||
{
|
||||
DPRINT("Found unused entry at %d\n", ChildDeviceCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the limit has been reached for maximum usb devices
|
||||
//
|
||||
if (ChildDeviceCount == USB_MAXCHILDREN)
|
||||
{
|
||||
DPRINT1("USBHUB: Too many child devices!\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
|
@ -1226,10 +1215,6 @@ CreateUsbChildDeviceObject(
|
|||
UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
|
||||
UsbChildExtension->PortNumber = PortId;
|
||||
|
||||
// copy device interface
|
||||
RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
|
||||
|
||||
|
||||
//
|
||||
// Create the UsbDeviceObject
|
||||
//
|
||||
|
@ -1244,12 +1229,6 @@ CreateUsbChildDeviceObject(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// copy device interface
|
||||
RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
|
||||
|
||||
// FIXME replace buscontext
|
||||
UsbChildExtension->DeviceInterface.BusContext = UsbChildExtension->UsbDeviceHandle;
|
||||
|
||||
//
|
||||
// Initialize UsbDevice
|
||||
//
|
||||
|
@ -1339,8 +1318,43 @@ CreateUsbChildDeviceObject(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// copy device interface
|
||||
RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->UsbDInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
|
||||
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
|
||||
|
||||
INITIALIZE_PNP_STATE(UsbChildExtension->Common);
|
||||
|
||||
IoInitializeRemoveLock(&UsbChildExtension->Common.RemoveLock, 'pbuH', 0, 0);
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
//
|
||||
// Find an empty slot in the child device array
|
||||
//
|
||||
for (ChildDeviceCount = 0; ChildDeviceCount < USB_MAXCHILDREN; ChildDeviceCount++)
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
|
||||
{
|
||||
DPRINT("Found unused entry at %d\n", ChildDeviceCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if the limit has been reached for maximum usb devices
|
||||
//
|
||||
if (ChildDeviceCount == USB_MAXCHILDREN)
|
||||
{
|
||||
DPRINT1("USBHUB: Too many child devices!\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
|
||||
HubDeviceExtension->InstanceCount++;
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -1384,16 +1398,20 @@ Cleanup:
|
|||
NTSTATUS
|
||||
USBHUB_FdoQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PDEVICE_RELATIONS RelationsFromTop,
|
||||
OUT PDEVICE_RELATIONS* pDeviceRelations)
|
||||
{
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
ULONG i;
|
||||
ULONG ChildrenFromTop = 0;
|
||||
ULONG Children = 0;
|
||||
ULONG NeededSize;
|
||||
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
//
|
||||
// Count the number of children
|
||||
//
|
||||
|
@ -1407,9 +1425,19 @@ USBHUB_FdoQueryBusRelations(
|
|||
Children++;
|
||||
}
|
||||
|
||||
NeededSize = sizeof(DEVICE_RELATIONS);
|
||||
if (Children > 1)
|
||||
NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
|
||||
if (RelationsFromTop)
|
||||
{
|
||||
ChildrenFromTop = RelationsFromTop->Count;
|
||||
if (!Children)
|
||||
{
|
||||
// We have nothing to add
|
||||
*pDeviceRelations = RelationsFromTop;
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
NeededSize = sizeof(DEVICE_RELATIONS) + (Children + ChildrenFromTop - 1) * sizeof(PDEVICE_OBJECT);
|
||||
|
||||
//
|
||||
// Allocate DeviceRelations
|
||||
|
@ -1418,9 +1446,22 @@ USBHUB_FdoQueryBusRelations(
|
|||
NeededSize);
|
||||
|
||||
if (!DeviceRelations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
DeviceRelations->Count = Children;
|
||||
Children = 0;
|
||||
{
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
if (!RelationsFromTop)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
// Copy the objects coming from top
|
||||
if (ChildrenFromTop)
|
||||
{
|
||||
RtlCopyMemory(DeviceRelations->Objects, RelationsFromTop->Objects,
|
||||
ChildrenFromTop * sizeof(PDEVICE_OBJECT));
|
||||
}
|
||||
|
||||
DeviceRelations->Count = Children + ChildrenFromTop;
|
||||
Children = ChildrenFromTop;
|
||||
|
||||
//
|
||||
// Fill in return structure
|
||||
|
@ -1429,12 +1470,19 @@ USBHUB_FdoQueryBusRelations(
|
|||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[i])
|
||||
{
|
||||
// The PnP Manager removes the reference when appropriate.
|
||||
ObReferenceObject(HubDeviceExtension->ChildDeviceObject[i]);
|
||||
HubDeviceExtension->ChildDeviceObject[i]->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
DeviceRelations->Objects[Children++] = HubDeviceExtension->ChildDeviceObject[i];
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
// We should do this, because replaced this with our's one
|
||||
if (RelationsFromTop)
|
||||
ExFreePool(RelationsFromTop);
|
||||
|
||||
ASSERT(Children == DeviceRelations->Count);
|
||||
*pDeviceRelations = DeviceRelations;
|
||||
|
||||
|
@ -1551,7 +1599,8 @@ USBHUB_FdoStartDevice(
|
|||
if (!Urb)
|
||||
{
|
||||
// no memory
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// zero urb
|
||||
|
@ -1566,8 +1615,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to obtain hub pdo
|
||||
DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n", Status);
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// sanity checks
|
||||
|
@ -1578,14 +1626,13 @@ USBHUB_FdoStartDevice(
|
|||
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||
|
||||
// Send the StartDevice to RootHub
|
||||
Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
|
||||
Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
// failed to start pdo
|
||||
DPRINT1("Failed to start the RootHub PDO\n");
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get the current number of hubs
|
||||
|
@ -1596,8 +1643,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get number of hubs
|
||||
DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get the Hub Interface
|
||||
|
@ -1611,8 +1657,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get root hub interface
|
||||
DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
|
||||
|
@ -1628,8 +1673,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get usbdi interface
|
||||
DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get Root Hub Device Handle
|
||||
|
@ -1642,8 +1686,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed
|
||||
DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 0x%08lx\n", Status);
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1687,8 +1730,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get device descriptor of hub
|
||||
DPRINT1("Failed to get HubDeviceDescriptor!\n");
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// build configuration request
|
||||
|
@ -1715,8 +1757,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get configuration descriptor
|
||||
DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// sanity checks
|
||||
|
@ -1742,16 +1783,15 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get hub information
|
||||
DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
|
||||
{
|
||||
// bogus port driver
|
||||
DPRINT1("Failed to retrieve the number of ports\n");
|
||||
ExFreePool(Urb);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DPRINT("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
|
||||
|
@ -1782,8 +1822,8 @@ USBHUB_FdoStartDevice(
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to get Hub Descriptor!\n");
|
||||
ExFreePool(Urb);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// sanity checks
|
||||
|
@ -1811,8 +1851,8 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to get hub status
|
||||
DPRINT1("Failed to get Hub Status!\n");
|
||||
ExFreePool(Urb);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
|
||||
|
@ -1820,6 +1860,13 @@ USBHUB_FdoStartDevice(
|
|||
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
|
||||
USB_HUB_TAG);
|
||||
|
||||
if (!HubDeviceExtension->PortStatusChange)
|
||||
{
|
||||
DPRINT1("Failed to allocate pool for PortStatusChange!\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get the first Configuration Descriptor
|
||||
Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
|
||||
&HubDeviceExtension->HubConfigDescriptor,
|
||||
|
@ -1828,8 +1875,8 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed parse hub descriptor
|
||||
DPRINT1("Failed to parse configuration descriptor\n");
|
||||
ExFreePool(Urb);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// create configuration request
|
||||
|
@ -1840,8 +1887,8 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to build urb
|
||||
DPRINT1("Failed to allocate urb\n");
|
||||
ExFreePool(Urb);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// send request
|
||||
|
@ -1853,9 +1900,7 @@ USBHUB_FdoStartDevice(
|
|||
{
|
||||
// failed to select configuration
|
||||
DPRINT1("Failed to select configuration with %x\n", Status);
|
||||
ExFreePool(Urb);
|
||||
ExFreePool(ConfigUrb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// store configuration & pipe handle
|
||||
|
@ -1863,12 +1908,6 @@ USBHUB_FdoStartDevice(
|
|||
HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
|
||||
DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
|
||||
|
||||
FDO_QueryInterface(DeviceObject, &HubDeviceExtension->DeviceInterface);
|
||||
|
||||
|
||||
// free urb
|
||||
ExFreePool(ConfigUrb);
|
||||
|
||||
// check if function is available
|
||||
if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
|
||||
{
|
||||
|
@ -1908,8 +1947,7 @@ USBHUB_FdoStartDevice(
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to set callback\n");
|
||||
ExFreePool(Urb);
|
||||
return Status;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1961,8 +1999,30 @@ USBHUB_FdoStartDevice(
|
|||
// free urb
|
||||
ExFreePool(Urb);
|
||||
|
||||
// free ConfigUrb
|
||||
ExFreePool(ConfigUrb);
|
||||
|
||||
// done
|
||||
return Status;
|
||||
|
||||
cleanup:
|
||||
if (Urb)
|
||||
ExFreePool(Urb);
|
||||
|
||||
// Dereference interfaces
|
||||
if (HubDeviceExtension->HubInterface.Size)
|
||||
HubDeviceExtension->HubInterface.InterfaceDereference(HubDeviceExtension->HubInterface.BusContext);
|
||||
|
||||
if (HubDeviceExtension->UsbDInterface.Size)
|
||||
HubDeviceExtension->UsbDInterface.InterfaceDereference(HubDeviceExtension->UsbDInterface.BusContext);
|
||||
|
||||
if (HubDeviceExtension->PortStatusChange)
|
||||
ExFreePool(HubDeviceExtension->PortStatusChange);
|
||||
|
||||
if (ConfigUrb)
|
||||
ExFreePool(ConfigUrb);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -1972,17 +2032,31 @@ USBHUB_FdoHandlePnp(
|
|||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG_PTR Information = 0;
|
||||
PDEVICE_OBJECT ChildDeviceObject;
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||
PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
|
||||
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
|
||||
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||
|
||||
HubInterface = &HubDeviceExtension->HubInterface;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
switch (Stack->MinorFunction)
|
||||
{
|
||||
int i;
|
||||
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
DPRINT("IRP_MN_START_DEVICE\n");
|
||||
if (USBHUB_IsRootHubFDO(DeviceObject))
|
||||
{
|
||||
// start root hub fdo
|
||||
|
@ -1992,7 +2066,13 @@ USBHUB_FdoHandlePnp(
|
|||
{
|
||||
Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
|
||||
}
|
||||
break;
|
||||
|
||||
SET_NEW_PNP_STATE(HubDeviceExtension->Common, Started);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
|
@ -2002,66 +2082,197 @@ USBHUB_FdoHandlePnp(
|
|||
case BusRelations:
|
||||
{
|
||||
PDEVICE_RELATIONS DeviceRelations = NULL;
|
||||
PDEVICE_RELATIONS RelationsFromTop = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
|
||||
|
||||
Status = USBHUB_FdoQueryBusRelations(DeviceObject, &DeviceRelations);
|
||||
Status = USBHUB_FdoQueryBusRelations(DeviceObject, RelationsFromTop, &DeviceRelations);
|
||||
|
||||
Information = (ULONG_PTR)DeviceRelations;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_NOT_SUPPORTED)
|
||||
{
|
||||
// We should process this to not lose relations from top.
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
// We should fail an IRP
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
Irp->IoStatus.Status = Status;
|
||||
break;
|
||||
}
|
||||
case RemovalRelations:
|
||||
{
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
|
||||
Stack->Parameters.QueryDeviceRelations.Type);
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
{
|
||||
//
|
||||
// We should fail this request, because we're not handling
|
||||
// IRP_MN_STOP_DEVICE for now.We'll receive this IRP ONLY when
|
||||
// PnP manager rebalances resources.
|
||||
//
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
{
|
||||
// No action is required from FDO because it have nothing to free.
|
||||
DPRINT("IRP_MN_QUERY_REMOVE_DEVICE\n");
|
||||
|
||||
SET_NEW_PNP_STATE(HubDeviceExtension->Common, RemovePending);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
{
|
||||
DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
|
||||
|
||||
if (HubDeviceExtension->Common.PnPState == RemovePending)
|
||||
RESTORE_PREVIOUS_PNP_STATE(HubDeviceExtension->Common);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
{
|
||||
//
|
||||
// We'll receive this IRP on HUB unexpected removal, or on USB
|
||||
// controller removal from PCI port. Here we should "let know" all
|
||||
// our children that their parent is removed and on next removal
|
||||
// they also can be removed.
|
||||
//
|
||||
SET_NEW_PNP_STATE(HubDeviceExtension->Common, SurpriseRemovePending);
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
for (i = 0; i < USB_MAXCHILDREN; i++)
|
||||
{
|
||||
ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
|
||||
if (ChildDeviceObject)
|
||||
{
|
||||
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceObjectExtension;
|
||||
ChildDeviceExtension->ParentDeviceObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
// This IRP can't be failed
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
{
|
||||
DPRINT("IRP_MN_REMOVE_DEVICE\n");
|
||||
|
||||
SET_NEW_PNP_STATE(HubDeviceExtension->Common, Deleted);
|
||||
|
||||
IoReleaseRemoveLockAndWait(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
|
||||
//
|
||||
// Here we should remove all child PDOs. At this point all children
|
||||
// received and returned from IRP_MN_REMOVE so remove synchronization
|
||||
// isn't needed here
|
||||
//
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
for (i = 0; i < USB_MAXCHILDREN; i++)
|
||||
{
|
||||
ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
|
||||
if (ChildDeviceObject)
|
||||
{
|
||||
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
|
||||
|
||||
SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
|
||||
|
||||
// Remove the usb device
|
||||
if (UsbChildExtension->UsbDeviceHandle)
|
||||
{
|
||||
Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
// Free full configuration descriptor
|
||||
if (UsbChildExtension->FullConfigDesc)
|
||||
ExFreePool(UsbChildExtension->FullConfigDesc);
|
||||
|
||||
// Free ID buffers
|
||||
if (UsbChildExtension->usCompatibleIds.Buffer)
|
||||
ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
|
||||
|
||||
if (UsbChildExtension->usDeviceId.Buffer)
|
||||
ExFreePool(UsbChildExtension->usDeviceId.Buffer);
|
||||
|
||||
if (UsbChildExtension->usHardwareIds.Buffer)
|
||||
ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
|
||||
|
||||
if (UsbChildExtension->usInstanceId.Buffer)
|
||||
ExFreePool(UsbChildExtension->usInstanceId.Buffer);
|
||||
|
||||
DPRINT("Deleting child PDO\n");
|
||||
IoDeleteDevice(DeviceObject);
|
||||
ChildDeviceObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
Status = ForwardIrpAndForget(DeviceObject, Irp);
|
||||
|
||||
IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
|
||||
DPRINT("Deleting FDO 0x%p\n", DeviceObject);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return Status;
|
||||
}
|
||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||
{
|
||||
// Function drivers and filter drivers do not handle this IRP.
|
||||
DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_ID:
|
||||
{
|
||||
DPRINT("IRP_MN_QUERY_ID\n");
|
||||
// Function drivers and filter drivers do not handle this IRP.
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
{
|
||||
//
|
||||
// If a function or filter driver does not handle this IRP, it
|
||||
// should pass that down.
|
||||
//
|
||||
DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT(" IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack->MinorFunction);
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
Status = ForwardIrpAndForget(DeviceObject, Irp);
|
||||
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -2086,6 +2297,25 @@ USBHUB_FdoHandleDeviceControl(
|
|||
// get device extension
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||
|
||||
Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Prevent handling of control requests in remove pending state
|
||||
if (HubDeviceExtension->Common.PnPState == RemovePending)
|
||||
{
|
||||
DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
|
||||
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
return STATUS_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_INFORMATION)
|
||||
{
|
||||
// is the buffer big enough
|
||||
|
@ -2131,6 +2361,7 @@ USBHUB_FdoHandleDeviceControl(
|
|||
// sanity checks
|
||||
ASSERT(NodeConnectionInfo);
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
|
||||
|
@ -2157,6 +2388,7 @@ USBHUB_FdoHandleDeviceControl(
|
|||
}
|
||||
break;
|
||||
}
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
// done
|
||||
Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -2177,6 +2409,7 @@ USBHUB_FdoHandleDeviceControl(
|
|||
// sanity checks
|
||||
ASSERT(NodeKey);
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
|
||||
|
@ -2216,6 +2449,7 @@ USBHUB_FdoHandleDeviceControl(
|
|||
NodeKey->ActualLength = Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
|
||||
break;
|
||||
}
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
}
|
||||
}
|
||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_NAME)
|
||||
|
@ -2247,6 +2481,7 @@ USBHUB_FdoHandleDeviceControl(
|
|||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,84 +211,3 @@ SubmitRequestToRootHub(
|
|||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FDO_QueryInterfaceCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
/* Set event */
|
||||
KeSetEvent((PRKEVENT)Context, 0, FALSE);
|
||||
|
||||
/* Completion is done in the HidClassFDO_QueryCapabilities routine */
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FDO_QueryInterface(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN OUT PUSB_BUS_INTERFACE_USBDI_V2 Interface)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||
|
||||
/* Get device extension */
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(HubDeviceExtension->Common.IsFDO);
|
||||
|
||||
/* Init event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
/* Now allocate the irp */
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||
if (!Irp)
|
||||
{
|
||||
/* No memory */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Get next stack location */
|
||||
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
/* Init stack location */
|
||||
IoStack->MajorFunction = IRP_MJ_PNP;
|
||||
IoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
||||
IoStack->Parameters.QueryInterface.Interface = (PINTERFACE)Interface;
|
||||
IoStack->Parameters.QueryInterface.InterfaceType = &USB_BUS_INTERFACE_USBDI_GUID;
|
||||
IoStack->Parameters.QueryInterface.Version = USB_BUSIF_USBDI_VERSION_2;
|
||||
IoStack->Parameters.QueryInterface.Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
|
||||
|
||||
|
||||
/* Set completion routine */
|
||||
IoSetCompletionRoutine(Irp,
|
||||
FDO_QueryInterfaceCompletionRoutine,
|
||||
(PVOID)&Event,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
/* Pnp irps have default completion code */
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* Call lower device */
|
||||
Status = IoCallDriver(HubDeviceExtension->LowerDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
/* Wait for completion */
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
|
||||
/* Get status */
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
/* Complete request */
|
||||
IoFreeIrp(Irp);
|
||||
|
||||
/* Done */
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -146,16 +146,25 @@ IsValidPDO(
|
|||
|
||||
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
|
||||
|
||||
// This can happen when parent device was surprise removed.
|
||||
if (ChildDeviceExtension->ParentDeviceObject == NULL)
|
||||
return FALSE;
|
||||
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
|
||||
|
||||
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
|
||||
{
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
/* PDO exists */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
/* invalid pdo */
|
||||
return FALSE;
|
||||
|
@ -190,18 +199,31 @@ USBHUB_PdoHandleInternalDeviceControl(
|
|||
|
||||
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
|
||||
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||
|
||||
if(!IsValidPDO(DeviceObject))
|
||||
Status = IoAcquireRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (ChildDeviceExtension->Common.PnPState == SurpriseRemovePending ||
|
||||
ChildDeviceExtension->Common.PnPState == RemovePending ||
|
||||
ChildDeviceExtension->ParentDeviceObject == NULL)
|
||||
{
|
||||
// Parent or child device was surprise removed.
|
||||
DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
|
||||
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||
return STATUS_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
|
||||
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||
|
||||
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
|
||||
|
@ -301,6 +323,7 @@ USBHUB_PdoHandleInternalDeviceControl(
|
|||
// Send the request to RootHub
|
||||
//
|
||||
Status = ForwardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
|
||||
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
|
@ -397,6 +420,7 @@ USBHUB_PdoHandleInternalDeviceControl(
|
|||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -421,6 +445,8 @@ USBHUB_PdoStartDevice(
|
|||
IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_DEVICE, NULL, &ChildDeviceExtension->SymbolicLinkName);
|
||||
IoSetDeviceInterfaceState(&ChildDeviceExtension->SymbolicLinkName, TRUE);
|
||||
|
||||
SET_NEW_PNP_STATE(ChildDeviceExtension->Common, Started);
|
||||
|
||||
UNIMPLEMENTED
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -563,15 +589,20 @@ USBHUB_PdoHandlePnp(
|
|||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = 0;
|
||||
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
|
||||
ULONG Index;
|
||||
ULONG bFound;
|
||||
PDEVICE_RELATIONS DeviceRelation;
|
||||
PDEVICE_OBJECT ParentDevice;
|
||||
|
||||
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
|
||||
Status = IoAcquireRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
|
@ -628,17 +659,20 @@ USBHUB_PdoHandlePnp(
|
|||
}
|
||||
case IRP_MN_QUERY_DEVICE_TEXT:
|
||||
{
|
||||
DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
|
||||
Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_ID:
|
||||
{
|
||||
DPRINT("IRP_MN_QUERY_ID\n");
|
||||
Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||
{
|
||||
PPNP_BUS_INFORMATION BusInfo;
|
||||
DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
|
||||
BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
|
||||
RtlCopyMemory(&BusInfo->BusTypeGuid,
|
||||
&GUID_BUS_TYPE_USB,
|
||||
|
@ -654,42 +688,58 @@ USBHUB_PdoHandlePnp(
|
|||
{
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
|
||||
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
|
||||
ParentDevice = UsbChildExtension->ParentDeviceObject;
|
||||
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
||||
|
||||
/* remove us from pdo list */
|
||||
bFound = FALSE;
|
||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||
ASSERT((UsbChildExtension->Common.PnPState == RemovePending) ||
|
||||
(UsbChildExtension->Common.PnPState == SurpriseRemovePending));
|
||||
|
||||
SET_NEW_PNP_STATE(UsbChildExtension->Common, NotStarted);
|
||||
|
||||
if (!IsValidPDO(DeviceObject))
|
||||
{
|
||||
if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
|
||||
// Parent or child device was surprise removed, freeing resources allocated for child device.
|
||||
SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
|
||||
|
||||
IoReleaseRemoveLockAndWait(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||
|
||||
// Remove the usb device
|
||||
if (UsbChildExtension->UsbDeviceHandle)
|
||||
{
|
||||
/* Remove the device */
|
||||
Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
/* remove us */
|
||||
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
|
||||
bFound = TRUE;
|
||||
break;
|
||||
Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
}
|
||||
// Free full configuration descriptor
|
||||
if (UsbChildExtension->FullConfigDesc)
|
||||
ExFreePool(UsbChildExtension->FullConfigDesc);
|
||||
|
||||
// Free ID buffers
|
||||
if (UsbChildExtension->usCompatibleIds.Buffer)
|
||||
ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
|
||||
|
||||
if (UsbChildExtension->usDeviceId.Buffer)
|
||||
ExFreePool(UsbChildExtension->usDeviceId.Buffer);
|
||||
|
||||
if (UsbChildExtension->usHardwareIds.Buffer)
|
||||
ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
|
||||
|
||||
if (UsbChildExtension->usInstanceId.Buffer)
|
||||
ExFreePool(UsbChildExtension->usInstanceId.Buffer);
|
||||
|
||||
DPRINT("Deleting child PDO\n");
|
||||
IoDeleteDevice(DeviceObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||
}
|
||||
|
||||
// If device is physically presented, we leave its PDO undeleted.
|
||||
|
||||
/* Complete the IRP */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* delete device */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
if (bFound)
|
||||
{
|
||||
/* invalidate device relations */
|
||||
IoInvalidateDeviceRelations(ParentDevice, BusRelations);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
|
@ -699,6 +749,7 @@ USBHUB_PdoHandlePnp(
|
|||
{
|
||||
/* not supported */
|
||||
Status = Irp->IoStatus.Status;
|
||||
Information = Irp->IoStatus.Information;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -722,13 +773,46 @@ USBHUB_PdoHandlePnp(
|
|||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
{
|
||||
//
|
||||
// We should fail this request, because we're not handling IRP_MN_STOP_DEVICE for now.
|
||||
// We'll receive this IRP ONLY when the PnP manager rebalances resources.
|
||||
//
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
{
|
||||
//
|
||||
// Free interface obtained from bottom, according MSDN we should
|
||||
// check interfaces provided to top, but here we are not checking.
|
||||
// All checking will be performed in roothub driver's
|
||||
// IRP_MN_QUERY_REMOVE_DEVICE handler. This will make problems when
|
||||
// buggy driver is loaded on top of us. But we decided to keep source
|
||||
// simpler, because in any case buggy driver will prevent removing of
|
||||
// whole stack.
|
||||
//
|
||||
UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
|
||||
|
||||
SET_NEW_PNP_STATE(UsbChildExtension->Common, RemovePending);
|
||||
|
||||
/* Sure, no problem */
|
||||
Status = STATUS_SUCCESS;
|
||||
Information = 0;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
{
|
||||
// Check to see have we received query-remove before
|
||||
if (UsbChildExtension->Common.PnPState == RemovePending)
|
||||
{
|
||||
RESTORE_PREVIOUS_PNP_STATE(UsbChildExtension->Common);
|
||||
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_INTERFACE:
|
||||
{
|
||||
DPRINT1("IRP_MN_QUERY_INTERFACE\n");
|
||||
|
@ -736,17 +820,28 @@ USBHUB_PdoHandlePnp(
|
|||
{
|
||||
DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
|
||||
RtlCopyMemory(Stack->Parameters.QueryInterface.Interface, &UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
|
||||
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
// pass irp down
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
|
||||
Status = IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
|
||||
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
{
|
||||
DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
|
||||
|
||||
//
|
||||
// Here we should free all resources and stop all access, lets just set
|
||||
// the flag and do further clean-up in subsequent IRP_MN_REMOVE_DEVICE
|
||||
// We can receive this IRP when device is physically connected (on stop/start fail).
|
||||
//
|
||||
SET_NEW_PNP_STATE(UsbChildExtension->Common, SurpriseRemovePending);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
@ -758,6 +853,8 @@ USBHUB_PdoHandlePnp(
|
|||
}
|
||||
}
|
||||
|
||||
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
|
|
@ -62,7 +62,7 @@ USBHUB_AddDevice(
|
|||
PDEVICE_OBJECT DeviceObject;
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||
NTSTATUS Status;
|
||||
DPRINT("USBHUB: AddDevice\n");
|
||||
DPRINT("USBHUB: AddDevice (%p)\n", PhysicalDeviceObject);
|
||||
//
|
||||
// Create the Device Object
|
||||
//
|
||||
|
@ -86,12 +86,20 @@ USBHUB_AddDevice(
|
|||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
|
||||
|
||||
INITIALIZE_PNP_STATE(HubDeviceExtension->Common);
|
||||
|
||||
//
|
||||
// Set this to Fdo
|
||||
//
|
||||
HubDeviceExtension->Common.IsFDO = TRUE;
|
||||
DeviceObject->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
// initialize mutex
|
||||
KeInitializeGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||
|
||||
// initialize remove lock
|
||||
IoInitializeRemoveLock(&HubDeviceExtension->Common.RemoveLock, 'buH', 0, 0);
|
||||
|
||||
//
|
||||
// initialize reset complete event
|
||||
//
|
||||
|
@ -158,6 +166,18 @@ USBHUB_DispatchDeviceControl(
|
|||
return USBHUB_IrpStub(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
USBHUB_DispatchSystemControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
DPRINT("Usbhub: DispatchSystemControl\n");
|
||||
if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return USBHUB_IrpStub(DeviceObject, Irp);
|
||||
else
|
||||
return USBHUB_IrpStub(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
USBHUB_DispatchInternalDeviceControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -188,37 +208,59 @@ USBHUB_DispatchPower(
|
|||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
Status = IoAcquireRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DPRINT1("Power Function %x\n", IoStack->MinorFunction);
|
||||
|
||||
if (IoStack->MinorFunction == IRP_MN_SET_POWER)
|
||||
if (DeviceExtension->Common.IsFDO)
|
||||
{
|
||||
PoStartNextPowerIrp(Irp);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
|
||||
IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
|
||||
return Status;
|
||||
}
|
||||
else if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
|
||||
{
|
||||
PoStartNextPowerIrp(Irp);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
else if (IoStack->MinorFunction == IRP_MN_WAIT_WAKE)
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
PoStartNextPowerIrp(Irp);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
case IRP_MN_SET_POWER:
|
||||
{
|
||||
DPRINT("IRP_MN_SET_POWER\n");
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_POWER:
|
||||
{
|
||||
DPRINT("IRP_MN_QUERY_POWER\n");
|
||||
break;
|
||||
}
|
||||
case IRP_MN_WAIT_WAKE:
|
||||
{
|
||||
DPRINT("IRP_MN_WAIT_WAKE\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT1("PDO IRP_MJ_POWER / unknown minor function 0x%lx\n", IoStack->MinorFunction);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
||||
}
|
||||
|
||||
PoStartNextPowerIrp(Irp);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -245,6 +287,7 @@ DriverEntry(
|
|||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBHUB_DispatchDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USBHUB_DispatchSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = USBHUB_DispatchInternalDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
|
||||
|
|
|
@ -39,9 +39,43 @@ typedef struct _WORK_ITEM_DATA
|
|||
PVOID Context;
|
||||
} WORK_ITEM_DATA, *PWORK_ITEM_DATA;
|
||||
|
||||
|
||||
//
|
||||
// Definitions for device's PnP state tracking, all this states are described
|
||||
// in PnP Device States diagram of DDK documentation.
|
||||
//
|
||||
typedef enum _DEVICE_PNP_STATE {
|
||||
|
||||
NotStarted = 0, // Not started
|
||||
Started, // After handling of START_DEVICE IRP
|
||||
StopPending, // After handling of QUERY_STOP IRP
|
||||
Stopped, // After handling of STOP_DEVICE IRP
|
||||
RemovePending, // After handling of QUERY_REMOVE IRP
|
||||
SurpriseRemovePending, // After handling of SURPRISE_REMOVE IRP
|
||||
Deleted, // After handling of REMOVE_DEVICE IRP
|
||||
UnKnown // Unknown state
|
||||
|
||||
} DEVICE_PNP_STATE;
|
||||
|
||||
#define INITIALIZE_PNP_STATE(Data) \
|
||||
(Data).PnPState = NotStarted;\
|
||||
(Data).PreviousPnPState = NotStarted;
|
||||
|
||||
#define SET_NEW_PNP_STATE(Data, state) \
|
||||
(Data).PreviousPnPState = (Data).PnPState;\
|
||||
(Data).PnPState = (state);
|
||||
|
||||
#define RESTORE_PREVIOUS_PNP_STATE(Data) \
|
||||
(Data).PnPState = (Data).PreviousPnPState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOLEAN IsFDO;
|
||||
// We'll track device PnP state via this variables
|
||||
DEVICE_PNP_STATE PnPState;
|
||||
DEVICE_PNP_STATE PreviousPnPState;
|
||||
// Remove lock
|
||||
IO_REMOVE_LOCK RemoveLock;
|
||||
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct _HUB_CHILDDEVICE_EXTENSION
|
||||
|
@ -72,6 +106,8 @@ typedef struct _HUB_DEVICE_EXTENSION
|
|||
PDEVICE_OBJECT RootHubPhysicalDeviceObject;
|
||||
PDEVICE_OBJECT RootHubFunctionalDeviceObject;
|
||||
|
||||
KGUARDED_MUTEX HubMutexLock;
|
||||
|
||||
ULONG NumberOfHubs;
|
||||
KEVENT ResetComplete;
|
||||
|
||||
|
@ -94,7 +130,6 @@ typedef struct _HUB_DEVICE_EXTENSION
|
|||
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
|
||||
USBD_PIPE_HANDLE PipeHandle;
|
||||
PVOID RootHubHandle;
|
||||
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
|
||||
|
||||
UNICODE_STRING SymbolicLinkName;
|
||||
ULONG InstanceCount;
|
||||
|
|
|
@ -163,7 +163,7 @@ HidParser_StoreCollection(
|
|||
//
|
||||
// store offset
|
||||
//
|
||||
TargetCollection->Offsets[Collection->NodeCount + Index] = CurrentOffset;
|
||||
TargetCollection->Offsets[Collection->ReportCount + Index] = CurrentOffset;
|
||||
|
||||
//
|
||||
// store sub collections
|
||||
|
@ -254,7 +254,7 @@ HidParser_SearchReportInCollection(
|
|||
//
|
||||
// get collection
|
||||
//
|
||||
SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->NodeCount + Index]);
|
||||
SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->ReportCount + Index]);
|
||||
|
||||
//
|
||||
// recursively search collection
|
||||
|
@ -314,7 +314,7 @@ HidParser_GetCollectionCount(
|
|||
//
|
||||
// get offset to sub collection
|
||||
//
|
||||
SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->NodeCount + Index]);
|
||||
SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->ReportCount + Index]);
|
||||
|
||||
//
|
||||
// count collection for sub nodes
|
||||
|
|
|
@ -68,7 +68,7 @@ HidParser_GetCollectionDescription(
|
|||
// failed to parse report descriptor
|
||||
//
|
||||
Parser->Debug("[HIDPARSER] Failed to parse report descriptor with %x\n", ParserStatus);
|
||||
return TranslateHidParserStatus(ParserStatus);
|
||||
return ParserStatus;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -126,7 +126,9 @@ HidParser_GetCollectionDescription(
|
|||
//
|
||||
// no memory
|
||||
//
|
||||
return TranslateHidParserStatus(ParserStatus);
|
||||
Parser->Free(DeviceDescription->CollectionDesc);
|
||||
Parser->Free(DeviceDescription->ReportIDs);
|
||||
return ParserStatus;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -153,6 +155,13 @@ HidParser_GetCollectionDescription(
|
|||
// get collection usage page
|
||||
//
|
||||
ParserStatus = HidParser_GetCollectionUsagePage((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, &DeviceDescription->CollectionDesc[Index].Usage, &DeviceDescription->CollectionDesc[Index].UsagePage);
|
||||
if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
|
||||
{
|
||||
// collection not found
|
||||
Parser->Free(DeviceDescription->CollectionDesc);
|
||||
Parser->Free(DeviceDescription->ReportIDs);
|
||||
return ParserStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// windows seems to prepend the report id, regardless if it is required
|
||||
|
|
|
@ -713,30 +713,6 @@ HidParser_AddMainItem(
|
|||
return HIDPARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
HIDPARSER_STATUS
|
||||
AllocateParserContext(
|
||||
IN PHID_PARSER Parser,
|
||||
OUT PHID_PARSER_CONTEXT *OutParserContext)
|
||||
{
|
||||
PHID_PARSER_CONTEXT ParserContext;
|
||||
|
||||
ParserContext = Parser->Alloc(sizeof(HID_PARSER_CONTEXT));
|
||||
if (!ParserContext)
|
||||
{
|
||||
//
|
||||
// failed
|
||||
//
|
||||
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
*OutParserContext = ParserContext;
|
||||
return HIDPARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
HIDPARSER_STATUS
|
||||
HidParser_ParseReportDescriptor(
|
||||
IN PHID_PARSER Parser,
|
||||
|
@ -760,12 +736,18 @@ HidParser_ParseReportDescriptor(
|
|||
PMAIN_ITEM_DATA MainItemData;
|
||||
PHID_PARSER_CONTEXT ParserContext;
|
||||
|
||||
CurrentOffset = ReportDescriptor;
|
||||
ReportEnd = ReportDescriptor + ReportLength;
|
||||
|
||||
if (ReportDescriptor >= ReportEnd)
|
||||
return HIDPARSER_STATUS_COLLECTION_NOT_FOUND;
|
||||
|
||||
//
|
||||
// allocate parser
|
||||
//
|
||||
Status = AllocateParserContext(Parser, &ParserContext);
|
||||
if (Status != HIDPARSER_STATUS_SUCCESS)
|
||||
return Status;
|
||||
ParserContext = Parser->Alloc(sizeof(HID_PARSER_CONTEXT));;
|
||||
if (!ParserContext)
|
||||
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
|
||||
//
|
||||
|
@ -778,6 +760,7 @@ HidParser_ParseReportDescriptor(
|
|||
//
|
||||
// no memory
|
||||
//
|
||||
Parser->Free(ParserContext);
|
||||
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
@ -792,6 +775,7 @@ HidParser_ParseReportDescriptor(
|
|||
//
|
||||
Parser->Free(ParserContext->LocalItemState.UsageStack);
|
||||
ParserContext->LocalItemState.UsageStack = NULL;
|
||||
Parser->Free(ParserContext);
|
||||
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
@ -799,8 +783,6 @@ HidParser_ParseReportDescriptor(
|
|||
// start parsing
|
||||
//
|
||||
CurrentCollection = ParserContext->RootCollection;
|
||||
CurrentOffset = ReportDescriptor;
|
||||
ReportEnd = ReportDescriptor + ReportLength;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -1230,8 +1212,7 @@ HidParser_ParseReportDescriptor(
|
|||
//
|
||||
CurrentOffset += CurrentItemSize + sizeof(ITEM_PREFIX);
|
||||
|
||||
|
||||
}while(CurrentOffset < ReportEnd);
|
||||
}while (CurrentOffset < ReportEnd);
|
||||
|
||||
|
||||
//
|
||||
|
|
|
@ -568,7 +568,8 @@ CHubController::HandlePnp(
|
|||
break;
|
||||
}
|
||||
}
|
||||
Status = STATUS_SUCCESS;
|
||||
// Here we should leave Status as is.
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
|
@ -611,6 +612,14 @@ CHubController::HandlePnp(
|
|||
// handle device interface requests
|
||||
//
|
||||
Status = HandleQueryInterface(IoStack);
|
||||
|
||||
//
|
||||
// If a bus driver does not export the requested interface, it
|
||||
// should leave Status as is.
|
||||
//
|
||||
if (Status == STATUS_NOT_SUPPORTED)
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
break;
|
||||
}
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
|
@ -3736,6 +3745,7 @@ CHubController::HandleQueryInterface(
|
|||
InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
|
||||
}
|
||||
|
||||
InterfaceHub->InterfaceReference(InterfaceHub->BusContext);
|
||||
//
|
||||
// request completed
|
||||
//
|
||||
|
@ -3790,6 +3800,7 @@ CHubController::HandleQueryInterface(
|
|||
InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
|
||||
}
|
||||
|
||||
InterfaceDI->InterfaceReference(InterfaceDI->BusContext);
|
||||
//
|
||||
// request completed
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue