mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 14:45:06 +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
|
@ -125,6 +125,29 @@ HidP_GetCaps(
|
||||||
return HidParser_GetCaps(&Parser, PreparsedData, Capabilities);
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
HidP_GetCollectionDescription(
|
HidP_GetCollectionDescription(
|
||||||
|
@ -134,6 +157,7 @@ HidP_GetCollectionDescription(
|
||||||
OUT PHIDP_DEVICE_DESC DeviceDescription)
|
OUT PHIDP_DEVICE_DESC DeviceDescription)
|
||||||
{
|
{
|
||||||
HID_PARSER Parser;
|
HID_PARSER Parser;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
//
|
//
|
||||||
// init parser
|
// init parser
|
||||||
|
@ -143,7 +167,8 @@ HidP_GetCollectionDescription(
|
||||||
//
|
//
|
||||||
// get description;
|
// get description;
|
||||||
//
|
//
|
||||||
return HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength, PoolType, DeviceDescription);
|
Status = HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength, PoolType, DeviceDescription);
|
||||||
|
return TranslateStatusForUpperLayer(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
HIDAPI
|
HIDAPI
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
add_definitions(-DDEBUG_MODE)
|
add_definitions(-DDEBUG_MODE)
|
||||||
|
add_definitions(-DNTDDI_VERSION=0x05020400)
|
||||||
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
|
|
|
@ -569,6 +569,11 @@ QueryInterface(
|
||||||
Stack->Parameters.QueryInterface.Interface = Interface;
|
Stack->Parameters.QueryInterface.Interface = Interface;
|
||||||
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the status block before sending the IRP
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
|
@ -1089,8 +1094,7 @@ DestroyUsbChildDeviceObject(
|
||||||
PDEVICE_OBJECT ChildDeviceObject = NULL;
|
PDEVICE_OBJECT ChildDeviceObject = NULL;
|
||||||
ULONG Index = 0;
|
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++)
|
for (Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||||
{
|
{
|
||||||
if (HubDeviceExtension->ChildDeviceObject[Index])
|
if (HubDeviceExtension->ChildDeviceObject[Index])
|
||||||
|
@ -1111,12 +1115,17 @@ DestroyUsbChildDeviceObject(
|
||||||
if (!ChildDeviceObject)
|
if (!ChildDeviceObject)
|
||||||
{
|
{
|
||||||
DPRINT1("Removal request for non-existant device!\n");
|
DPRINT1("Removal request for non-existant device!\n");
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Removing device on port %d (Child index: %d)\n", PortId, Index);
|
||||||
|
|
||||||
/* Remove the device from the table */
|
/* Remove the device from the table */
|
||||||
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
|
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
|
||||||
|
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
|
|
||||||
/* Invalidate device relations for the root hub */
|
/* Invalidate device relations for the root hub */
|
||||||
IoInvalidateDeviceRelations(HubDeviceExtension->RootHubPhysicalDeviceObject, BusRelations);
|
IoInvalidateDeviceRelations(HubDeviceExtension->RootHubPhysicalDeviceObject, BusRelations);
|
||||||
|
|
||||||
|
@ -1147,26 +1156,6 @@ CreateUsbChildDeviceObject(
|
||||||
HubInterface = &HubDeviceExtension->HubInterface;
|
HubInterface = &HubDeviceExtension->HubInterface;
|
||||||
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||||
HubInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
|
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)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
@ -1226,10 +1215,6 @@ CreateUsbChildDeviceObject(
|
||||||
UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
|
UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
|
||||||
UsbChildExtension->PortNumber = PortId;
|
UsbChildExtension->PortNumber = PortId;
|
||||||
|
|
||||||
// copy device interface
|
|
||||||
RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the UsbDeviceObject
|
// Create the UsbDeviceObject
|
||||||
//
|
//
|
||||||
|
@ -1244,12 +1229,6 @@ CreateUsbChildDeviceObject(
|
||||||
goto Cleanup;
|
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
|
// Initialize UsbDevice
|
||||||
//
|
//
|
||||||
|
@ -1339,8 +1318,43 @@ CreateUsbChildDeviceObject(
|
||||||
goto Cleanup;
|
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->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
|
||||||
HubDeviceExtension->InstanceCount++;
|
HubDeviceExtension->InstanceCount++;
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
|
|
||||||
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
|
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -1384,16 +1398,20 @@ Cleanup:
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
USBHUB_FdoQueryBusRelations(
|
USBHUB_FdoQueryBusRelations(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PDEVICE_RELATIONS RelationsFromTop,
|
||||||
OUT PDEVICE_RELATIONS* pDeviceRelations)
|
OUT PDEVICE_RELATIONS* pDeviceRelations)
|
||||||
{
|
{
|
||||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||||
PDEVICE_RELATIONS DeviceRelations;
|
PDEVICE_RELATIONS DeviceRelations;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
ULONG ChildrenFromTop = 0;
|
||||||
ULONG Children = 0;
|
ULONG Children = 0;
|
||||||
ULONG NeededSize;
|
ULONG NeededSize;
|
||||||
|
|
||||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Count the number of children
|
// Count the number of children
|
||||||
//
|
//
|
||||||
|
@ -1407,9 +1425,19 @@ USBHUB_FdoQueryBusRelations(
|
||||||
Children++;
|
Children++;
|
||||||
}
|
}
|
||||||
|
|
||||||
NeededSize = sizeof(DEVICE_RELATIONS);
|
if (RelationsFromTop)
|
||||||
if (Children > 1)
|
{
|
||||||
NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
|
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
|
// Allocate DeviceRelations
|
||||||
|
@ -1418,9 +1446,22 @@ USBHUB_FdoQueryBusRelations(
|
||||||
NeededSize);
|
NeededSize);
|
||||||
|
|
||||||
if (!DeviceRelations)
|
if (!DeviceRelations)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
{
|
||||||
DeviceRelations->Count = Children;
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
Children = 0;
|
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
|
// Fill in return structure
|
||||||
|
@ -1429,12 +1470,19 @@ USBHUB_FdoQueryBusRelations(
|
||||||
{
|
{
|
||||||
if (HubDeviceExtension->ChildDeviceObject[i])
|
if (HubDeviceExtension->ChildDeviceObject[i])
|
||||||
{
|
{
|
||||||
|
// The PnP Manager removes the reference when appropriate.
|
||||||
ObReferenceObject(HubDeviceExtension->ChildDeviceObject[i]);
|
ObReferenceObject(HubDeviceExtension->ChildDeviceObject[i]);
|
||||||
HubDeviceExtension->ChildDeviceObject[i]->Flags &= ~DO_DEVICE_INITIALIZING;
|
HubDeviceExtension->ChildDeviceObject[i]->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
DeviceRelations->Objects[Children++] = HubDeviceExtension->ChildDeviceObject[i];
|
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);
|
ASSERT(Children == DeviceRelations->Count);
|
||||||
*pDeviceRelations = DeviceRelations;
|
*pDeviceRelations = DeviceRelations;
|
||||||
|
|
||||||
|
@ -1551,7 +1599,8 @@ USBHUB_FdoStartDevice(
|
||||||
if (!Urb)
|
if (!Urb)
|
||||||
{
|
{
|
||||||
// no memory
|
// no memory
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero urb
|
// zero urb
|
||||||
|
@ -1566,8 +1615,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to obtain hub pdo
|
// failed to obtain hub pdo
|
||||||
DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n", Status);
|
DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
@ -1578,14 +1626,13 @@ USBHUB_FdoStartDevice(
|
||||||
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||||
|
|
||||||
// Send the StartDevice to RootHub
|
// Send the StartDevice to RootHub
|
||||||
Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
|
Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
// failed to start pdo
|
// failed to start pdo
|
||||||
DPRINT1("Failed to start the RootHub PDO\n");
|
DPRINT1("Failed to start the RootHub PDO\n");
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current number of hubs
|
// Get the current number of hubs
|
||||||
|
@ -1596,8 +1643,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get number of hubs
|
// failed to get number of hubs
|
||||||
DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
|
DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Hub Interface
|
// Get the Hub Interface
|
||||||
|
@ -1611,8 +1657,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get root hub interface
|
// failed to get root hub interface
|
||||||
DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
|
DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
|
HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
|
||||||
|
@ -1628,8 +1673,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get usbdi interface
|
// failed to get usbdi interface
|
||||||
DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
|
DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Root Hub Device Handle
|
// Get Root Hub Device Handle
|
||||||
|
@ -1642,8 +1686,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed
|
// failed
|
||||||
DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 0x%08lx\n", Status);
|
DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 0x%08lx\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1687,8 +1730,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get device descriptor of hub
|
// failed to get device descriptor of hub
|
||||||
DPRINT1("Failed to get HubDeviceDescriptor!\n");
|
DPRINT1("Failed to get HubDeviceDescriptor!\n");
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build configuration request
|
// build configuration request
|
||||||
|
@ -1715,8 +1757,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get configuration descriptor
|
// failed to get configuration descriptor
|
||||||
DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
|
DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
@ -1742,16 +1783,15 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get hub information
|
// failed to get hub information
|
||||||
DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
|
DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
|
if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
|
||||||
{
|
{
|
||||||
// bogus port driver
|
// bogus port driver
|
||||||
DPRINT1("Failed to retrieve the number of ports\n");
|
DPRINT1("Failed to retrieve the number of ports\n");
|
||||||
ExFreePool(Urb);
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
|
DPRINT("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
|
||||||
|
@ -1782,8 +1822,8 @@ USBHUB_FdoStartDevice(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to get Hub Descriptor!\n");
|
DPRINT1("Failed to get Hub Descriptor!\n");
|
||||||
ExFreePool(Urb);
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
@ -1811,8 +1851,8 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to get hub status
|
// failed to get hub status
|
||||||
DPRINT1("Failed to get Hub Status!\n");
|
DPRINT1("Failed to get Hub Status!\n");
|
||||||
ExFreePool(Urb);
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
|
// Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
|
||||||
|
@ -1820,6 +1860,13 @@ USBHUB_FdoStartDevice(
|
||||||
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
|
sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
|
||||||
USB_HUB_TAG);
|
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
|
// Get the first Configuration Descriptor
|
||||||
Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
|
Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
|
||||||
&HubDeviceExtension->HubConfigDescriptor,
|
&HubDeviceExtension->HubConfigDescriptor,
|
||||||
|
@ -1828,8 +1875,8 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed parse hub descriptor
|
// failed parse hub descriptor
|
||||||
DPRINT1("Failed to parse configuration descriptor\n");
|
DPRINT1("Failed to parse configuration descriptor\n");
|
||||||
ExFreePool(Urb);
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create configuration request
|
// create configuration request
|
||||||
|
@ -1840,8 +1887,8 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to build urb
|
// failed to build urb
|
||||||
DPRINT1("Failed to allocate urb\n");
|
DPRINT1("Failed to allocate urb\n");
|
||||||
ExFreePool(Urb);
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send request
|
// send request
|
||||||
|
@ -1853,9 +1900,7 @@ USBHUB_FdoStartDevice(
|
||||||
{
|
{
|
||||||
// failed to select configuration
|
// failed to select configuration
|
||||||
DPRINT1("Failed to select configuration with %x\n", Status);
|
DPRINT1("Failed to select configuration with %x\n", Status);
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
ExFreePool(ConfigUrb);
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store configuration & pipe handle
|
// store configuration & pipe handle
|
||||||
|
@ -1863,12 +1908,6 @@ USBHUB_FdoStartDevice(
|
||||||
HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
|
HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
|
||||||
DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
|
DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
|
||||||
|
|
||||||
FDO_QueryInterface(DeviceObject, &HubDeviceExtension->DeviceInterface);
|
|
||||||
|
|
||||||
|
|
||||||
// free urb
|
|
||||||
ExFreePool(ConfigUrb);
|
|
||||||
|
|
||||||
// check if function is available
|
// check if function is available
|
||||||
if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
|
if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
|
||||||
{
|
{
|
||||||
|
@ -1908,8 +1947,7 @@ USBHUB_FdoStartDevice(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to set callback\n");
|
DPRINT1("Failed to set callback\n");
|
||||||
ExFreePool(Urb);
|
goto cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1961,8 +1999,30 @@ USBHUB_FdoStartDevice(
|
||||||
// free urb
|
// free urb
|
||||||
ExFreePool(Urb);
|
ExFreePool(Urb);
|
||||||
|
|
||||||
|
// free ConfigUrb
|
||||||
|
ExFreePool(ConfigUrb);
|
||||||
|
|
||||||
// done
|
// done
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
|
@ -1972,17 +2032,31 @@ USBHUB_FdoHandlePnp(
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
ULONG_PTR Information = 0;
|
PDEVICE_OBJECT ChildDeviceObject;
|
||||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||||
|
PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
|
||||||
|
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
|
||||||
|
|
||||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
HubInterface = &HubDeviceExtension->HubInterface;
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
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)
|
switch (Stack->MinorFunction)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
{
|
{
|
||||||
|
DPRINT("IRP_MN_START_DEVICE\n");
|
||||||
if (USBHUB_IsRootHubFDO(DeviceObject))
|
if (USBHUB_IsRootHubFDO(DeviceObject))
|
||||||
{
|
{
|
||||||
// start root hub fdo
|
// start root hub fdo
|
||||||
|
@ -1992,7 +2066,13 @@ USBHUB_FdoHandlePnp(
|
||||||
{
|
{
|
||||||
Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
|
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:
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
|
@ -2002,66 +2082,197 @@ USBHUB_FdoHandlePnp(
|
||||||
case BusRelations:
|
case BusRelations:
|
||||||
{
|
{
|
||||||
PDEVICE_RELATIONS DeviceRelations = NULL;
|
PDEVICE_RELATIONS DeviceRelations = NULL;
|
||||||
|
PDEVICE_RELATIONS RelationsFromTop = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
|
||||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case RemovalRelations:
|
case RemovalRelations:
|
||||||
{
|
{
|
||||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
|
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
|
||||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
|
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
|
||||||
Stack->Parameters.QueryDeviceRelations.Type);
|
Stack->Parameters.QueryDeviceRelations.Type);
|
||||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
|
||||||
case IRP_MN_QUERY_STOP_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;
|
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:
|
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;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
Status = ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
|
|
||||||
IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
|
IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
|
||||||
|
DPRINT("Deleting FDO 0x%p\n", DeviceObject);
|
||||||
IoDeleteDevice(DeviceObject);
|
IoDeleteDevice(DeviceObject);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||||
{
|
{
|
||||||
|
// Function drivers and filter drivers do not handle this IRP.
|
||||||
DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
|
DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_ID:
|
case IRP_MN_QUERY_ID:
|
||||||
{
|
{
|
||||||
DPRINT("IRP_MN_QUERY_ID\n");
|
DPRINT("IRP_MN_QUERY_ID\n");
|
||||||
|
// Function drivers and filter drivers do not handle this IRP.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_CAPABILITIES:
|
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");
|
DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DPRINT(" IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack->MinorFunction);
|
DPRINT(" IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack->MinorFunction);
|
||||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Information = Information;
|
Status = ForwardIrpAndForget(DeviceObject, Irp);
|
||||||
Irp->IoStatus.Status = Status;
|
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2086,6 +2297,25 @@ USBHUB_FdoHandleDeviceControl(
|
||||||
// get device extension
|
// get device extension
|
||||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
|
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)
|
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_INFORMATION)
|
||||||
{
|
{
|
||||||
// is the buffer big enough
|
// is the buffer big enough
|
||||||
|
@ -2131,6 +2361,7 @@ USBHUB_FdoHandleDeviceControl(
|
||||||
// sanity checks
|
// sanity checks
|
||||||
ASSERT(NodeConnectionInfo);
|
ASSERT(NodeConnectionInfo);
|
||||||
|
|
||||||
|
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||||
{
|
{
|
||||||
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
|
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
|
||||||
|
@ -2157,6 +2388,7 @@ USBHUB_FdoHandleDeviceControl(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
// done
|
// done
|
||||||
Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
|
Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
@ -2177,6 +2409,7 @@ USBHUB_FdoHandleDeviceControl(
|
||||||
// sanity checks
|
// sanity checks
|
||||||
ASSERT(NodeKey);
|
ASSERT(NodeKey);
|
||||||
|
|
||||||
|
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||||
{
|
{
|
||||||
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
|
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
|
||||||
|
@ -2216,6 +2449,7 @@ USBHUB_FdoHandleDeviceControl(
|
||||||
NodeKey->ActualLength = Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
|
NodeKey->ActualLength = Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_NAME)
|
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_NAME)
|
||||||
|
@ -2247,6 +2481,7 @@ USBHUB_FdoHandleDeviceControl(
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -211,84 +211,3 @@ SubmitRequestToRootHub(
|
||||||
|
|
||||||
return Status;
|
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;
|
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
|
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;
|
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
||||||
{
|
{
|
||||||
if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
|
if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
|
||||||
{
|
{
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
|
|
||||||
/* PDO exists */
|
/* PDO exists */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
|
|
||||||
/* invalid pdo */
|
/* invalid pdo */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -190,18 +199,31 @@ USBHUB_PdoHandleInternalDeviceControl(
|
||||||
|
|
||||||
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
|
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);
|
DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
|
||||||
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
|
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||||
return STATUS_DEVICE_NOT_CONNECTED;
|
return STATUS_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
|
||||||
|
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
|
||||||
|
|
||||||
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||||
{
|
{
|
||||||
case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
|
case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
|
||||||
|
@ -301,6 +323,7 @@ USBHUB_PdoHandleInternalDeviceControl(
|
||||||
// Send the request to RootHub
|
// Send the request to RootHub
|
||||||
//
|
//
|
||||||
Status = ForwardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
|
Status = ForwardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
|
||||||
|
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -397,6 +420,7 @@ USBHUB_PdoHandleInternalDeviceControl(
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
}
|
}
|
||||||
|
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +445,8 @@ USBHUB_PdoStartDevice(
|
||||||
IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_DEVICE, NULL, &ChildDeviceExtension->SymbolicLinkName);
|
IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_DEVICE, NULL, &ChildDeviceExtension->SymbolicLinkName);
|
||||||
IoSetDeviceInterfaceState(&ChildDeviceExtension->SymbolicLinkName, TRUE);
|
IoSetDeviceInterfaceState(&ChildDeviceExtension->SymbolicLinkName, TRUE);
|
||||||
|
|
||||||
|
SET_NEW_PNP_STATE(ChildDeviceExtension->Common, Started);
|
||||||
|
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -563,15 +589,20 @@ USBHUB_PdoHandlePnp(
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
ULONG_PTR Information = 0;
|
ULONG_PTR Information = 0;
|
||||||
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
|
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
|
||||||
ULONG Index;
|
|
||||||
ULONG bFound;
|
|
||||||
PDEVICE_RELATIONS DeviceRelation;
|
PDEVICE_RELATIONS DeviceRelation;
|
||||||
PDEVICE_OBJECT ParentDevice;
|
|
||||||
|
|
||||||
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
MinorFunction = Stack->MinorFunction;
|
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)
|
switch (MinorFunction)
|
||||||
{
|
{
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
|
@ -628,17 +659,20 @@ USBHUB_PdoHandlePnp(
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_DEVICE_TEXT:
|
case IRP_MN_QUERY_DEVICE_TEXT:
|
||||||
{
|
{
|
||||||
|
DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
|
||||||
Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
|
Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_ID:
|
case IRP_MN_QUERY_ID:
|
||||||
{
|
{
|
||||||
|
DPRINT("IRP_MN_QUERY_ID\n");
|
||||||
Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
|
Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||||
{
|
{
|
||||||
PPNP_BUS_INFORMATION BusInfo;
|
PPNP_BUS_INFORMATION BusInfo;
|
||||||
|
DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
|
||||||
BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
|
BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
|
||||||
RtlCopyMemory(&BusInfo->BusTypeGuid,
|
RtlCopyMemory(&BusInfo->BusTypeGuid,
|
||||||
&GUID_BUS_TYPE_USB,
|
&GUID_BUS_TYPE_USB,
|
||||||
|
@ -654,42 +688,58 @@ USBHUB_PdoHandlePnp(
|
||||||
{
|
{
|
||||||
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
|
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
|
||||||
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
|
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
|
||||||
ParentDevice = UsbChildExtension->ParentDeviceObject;
|
|
||||||
|
|
||||||
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
||||||
|
|
||||||
/* remove us from pdo list */
|
ASSERT((UsbChildExtension->Common.PnPState == RemovePending) ||
|
||||||
bFound = FALSE;
|
(UsbChildExtension->Common.PnPState == SurpriseRemovePending));
|
||||||
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
|
|
||||||
|
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(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
|
||||||
Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
/* FIXME handle error */
|
|
||||||
ASSERT(Status == STATUS_SUCCESS);
|
|
||||||
|
|
||||||
/* remove us */
|
|
||||||
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
|
|
||||||
bFound = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
// 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 */
|
/* Complete the IRP */
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
/* delete device */
|
|
||||||
IoDeleteDevice(DeviceObject);
|
|
||||||
|
|
||||||
if (bFound)
|
|
||||||
{
|
|
||||||
/* invalidate device relations */
|
|
||||||
IoInvalidateDeviceRelations(ParentDevice, BusRelations);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
|
@ -699,6 +749,7 @@ USBHUB_PdoHandlePnp(
|
||||||
{
|
{
|
||||||
/* not supported */
|
/* not supported */
|
||||||
Status = Irp->IoStatus.Status;
|
Status = Irp->IoStatus.Status;
|
||||||
|
Information = Irp->IoStatus.Information;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,13 +773,46 @@ USBHUB_PdoHandlePnp(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_STOP_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 the PnP manager rebalances resources.
|
||||||
|
//
|
||||||
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
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 */
|
/* Sure, no problem */
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
Information = 0;
|
Information = 0;
|
||||||
break;
|
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:
|
case IRP_MN_QUERY_INTERFACE:
|
||||||
{
|
{
|
||||||
DPRINT1("IRP_MN_QUERY_INTERFACE\n");
|
DPRINT1("IRP_MN_QUERY_INTERFACE\n");
|
||||||
|
@ -736,17 +820,28 @@ USBHUB_PdoHandlePnp(
|
||||||
{
|
{
|
||||||
DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
|
DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
|
||||||
RtlCopyMemory(Stack->Parameters.QueryInterface.Interface, &UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
|
RtlCopyMemory(Stack->Parameters.QueryInterface.Interface, &UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
|
||||||
|
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass irp down
|
// pass irp down
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
|
Status = IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
|
||||||
|
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
case IRP_MN_SURPRISE_REMOVAL:
|
case IRP_MN_SURPRISE_REMOVAL:
|
||||||
{
|
{
|
||||||
DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
|
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;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -758,6 +853,8 @@ USBHUB_PdoHandlePnp(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
|
||||||
|
|
||||||
Irp->IoStatus.Information = Information;
|
Irp->IoStatus.Information = Information;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
|
@ -62,7 +62,7 @@ USBHUB_AddDevice(
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
DPRINT("USBHUB: AddDevice\n");
|
DPRINT("USBHUB: AddDevice (%p)\n", PhysicalDeviceObject);
|
||||||
//
|
//
|
||||||
// Create the Device Object
|
// Create the Device Object
|
||||||
//
|
//
|
||||||
|
@ -86,12 +86,20 @@ USBHUB_AddDevice(
|
||||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
|
RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
|
||||||
|
|
||||||
|
INITIALIZE_PNP_STATE(HubDeviceExtension->Common);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set this to Fdo
|
// Set this to Fdo
|
||||||
//
|
//
|
||||||
HubDeviceExtension->Common.IsFDO = TRUE;
|
HubDeviceExtension->Common.IsFDO = TRUE;
|
||||||
DeviceObject->Flags |= DO_POWER_PAGABLE;
|
DeviceObject->Flags |= DO_POWER_PAGABLE;
|
||||||
|
|
||||||
|
// initialize mutex
|
||||||
|
KeInitializeGuardedMutex(&HubDeviceExtension->HubMutexLock);
|
||||||
|
|
||||||
|
// initialize remove lock
|
||||||
|
IoInitializeRemoveLock(&HubDeviceExtension->Common.RemoveLock, 'buH', 0, 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// initialize reset complete event
|
// initialize reset complete event
|
||||||
//
|
//
|
||||||
|
@ -158,6 +166,18 @@ USBHUB_DispatchDeviceControl(
|
||||||
return USBHUB_IrpStub(DeviceObject, Irp);
|
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
|
NTSTATUS NTAPI
|
||||||
USBHUB_DispatchInternalDeviceControl(
|
USBHUB_DispatchInternalDeviceControl(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -188,37 +208,59 @@ USBHUB_DispatchPower(
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PHUB_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
NTSTATUS Status;
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
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);
|
DPRINT1("Power Function %x\n", IoStack->MinorFunction);
|
||||||
|
|
||||||
if (IoStack->MinorFunction == IRP_MN_SET_POWER)
|
if (DeviceExtension->Common.IsFDO)
|
||||||
{
|
{
|
||||||
PoStartNextPowerIrp(Irp);
|
PoStartNextPowerIrp(Irp);
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
Status = PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
|
||||||
return STATUS_SUCCESS;
|
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;
|
|
||||||
|
|
||||||
}
|
switch (IoStack->MinorFunction)
|
||||||
else if (IoStack->MinorFunction == IRP_MN_WAIT_WAKE)
|
|
||||||
{
|
{
|
||||||
PoStartNextPowerIrp(Irp);
|
case IRP_MN_SET_POWER:
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
{
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
DPRINT("IRP_MN_SET_POWER\n");
|
||||||
return STATUS_SUCCESS;
|
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);
|
PoStartNextPowerIrp(Irp);
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +287,7 @@ DriverEntry(
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBHUB_DispatchDeviceControl;
|
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_INTERNAL_DEVICE_CONTROL] = USBHUB_DispatchInternalDeviceControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
|
DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
|
||||||
DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
|
DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
|
||||||
|
|
|
@ -39,9 +39,43 @@ typedef struct _WORK_ITEM_DATA
|
||||||
PVOID Context;
|
PVOID Context;
|
||||||
} WORK_ITEM_DATA, *PWORK_ITEM_DATA;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
BOOLEAN IsFDO;
|
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;
|
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _HUB_CHILDDEVICE_EXTENSION
|
typedef struct _HUB_CHILDDEVICE_EXTENSION
|
||||||
|
@ -72,6 +106,8 @@ typedef struct _HUB_DEVICE_EXTENSION
|
||||||
PDEVICE_OBJECT RootHubPhysicalDeviceObject;
|
PDEVICE_OBJECT RootHubPhysicalDeviceObject;
|
||||||
PDEVICE_OBJECT RootHubFunctionalDeviceObject;
|
PDEVICE_OBJECT RootHubFunctionalDeviceObject;
|
||||||
|
|
||||||
|
KGUARDED_MUTEX HubMutexLock;
|
||||||
|
|
||||||
ULONG NumberOfHubs;
|
ULONG NumberOfHubs;
|
||||||
KEVENT ResetComplete;
|
KEVENT ResetComplete;
|
||||||
|
|
||||||
|
@ -94,7 +130,6 @@ typedef struct _HUB_DEVICE_EXTENSION
|
||||||
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
|
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
|
||||||
USBD_PIPE_HANDLE PipeHandle;
|
USBD_PIPE_HANDLE PipeHandle;
|
||||||
PVOID RootHubHandle;
|
PVOID RootHubHandle;
|
||||||
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
|
|
||||||
|
|
||||||
UNICODE_STRING SymbolicLinkName;
|
UNICODE_STRING SymbolicLinkName;
|
||||||
ULONG InstanceCount;
|
ULONG InstanceCount;
|
||||||
|
|
|
@ -163,7 +163,7 @@ HidParser_StoreCollection(
|
||||||
//
|
//
|
||||||
// store offset
|
// store offset
|
||||||
//
|
//
|
||||||
TargetCollection->Offsets[Collection->NodeCount + Index] = CurrentOffset;
|
TargetCollection->Offsets[Collection->ReportCount + Index] = CurrentOffset;
|
||||||
|
|
||||||
//
|
//
|
||||||
// store sub collections
|
// store sub collections
|
||||||
|
@ -254,7 +254,7 @@ HidParser_SearchReportInCollection(
|
||||||
//
|
//
|
||||||
// get collection
|
// 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
|
// recursively search collection
|
||||||
|
@ -314,7 +314,7 @@ HidParser_GetCollectionCount(
|
||||||
//
|
//
|
||||||
// get offset to sub collection
|
// 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
|
// count collection for sub nodes
|
||||||
|
|
|
@ -68,7 +68,7 @@ HidParser_GetCollectionDescription(
|
||||||
// failed to parse report descriptor
|
// failed to parse report descriptor
|
||||||
//
|
//
|
||||||
Parser->Debug("[HIDPARSER] Failed to parse report descriptor with %x\n", ParserStatus);
|
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
|
// 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
|
// get collection usage page
|
||||||
//
|
//
|
||||||
ParserStatus = HidParser_GetCollectionUsagePage((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, &DeviceDescription->CollectionDesc[Index].Usage, &DeviceDescription->CollectionDesc[Index].UsagePage);
|
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
|
// windows seems to prepend the report id, regardless if it is required
|
||||||
|
|
|
@ -713,30 +713,6 @@ HidParser_AddMainItem(
|
||||||
return HIDPARSER_STATUS_SUCCESS;
|
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_STATUS
|
||||||
HidParser_ParseReportDescriptor(
|
HidParser_ParseReportDescriptor(
|
||||||
IN PHID_PARSER Parser,
|
IN PHID_PARSER Parser,
|
||||||
|
@ -760,12 +736,18 @@ HidParser_ParseReportDescriptor(
|
||||||
PMAIN_ITEM_DATA MainItemData;
|
PMAIN_ITEM_DATA MainItemData;
|
||||||
PHID_PARSER_CONTEXT ParserContext;
|
PHID_PARSER_CONTEXT ParserContext;
|
||||||
|
|
||||||
|
CurrentOffset = ReportDescriptor;
|
||||||
|
ReportEnd = ReportDescriptor + ReportLength;
|
||||||
|
|
||||||
|
if (ReportDescriptor >= ReportEnd)
|
||||||
|
return HIDPARSER_STATUS_COLLECTION_NOT_FOUND;
|
||||||
|
|
||||||
//
|
//
|
||||||
// allocate parser
|
// allocate parser
|
||||||
//
|
//
|
||||||
Status = AllocateParserContext(Parser, &ParserContext);
|
ParserContext = Parser->Alloc(sizeof(HID_PARSER_CONTEXT));;
|
||||||
if (Status != HIDPARSER_STATUS_SUCCESS)
|
if (!ParserContext)
|
||||||
return Status;
|
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -778,6 +760,7 @@ HidParser_ParseReportDescriptor(
|
||||||
//
|
//
|
||||||
// no memory
|
// no memory
|
||||||
//
|
//
|
||||||
|
Parser->Free(ParserContext);
|
||||||
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,6 +775,7 @@ HidParser_ParseReportDescriptor(
|
||||||
//
|
//
|
||||||
Parser->Free(ParserContext->LocalItemState.UsageStack);
|
Parser->Free(ParserContext->LocalItemState.UsageStack);
|
||||||
ParserContext->LocalItemState.UsageStack = NULL;
|
ParserContext->LocalItemState.UsageStack = NULL;
|
||||||
|
Parser->Free(ParserContext);
|
||||||
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,8 +783,6 @@ HidParser_ParseReportDescriptor(
|
||||||
// start parsing
|
// start parsing
|
||||||
//
|
//
|
||||||
CurrentCollection = ParserContext->RootCollection;
|
CurrentCollection = ParserContext->RootCollection;
|
||||||
CurrentOffset = ReportDescriptor;
|
|
||||||
ReportEnd = ReportDescriptor + ReportLength;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -1230,8 +1212,7 @@ HidParser_ParseReportDescriptor(
|
||||||
//
|
//
|
||||||
CurrentOffset += CurrentItemSize + sizeof(ITEM_PREFIX);
|
CurrentOffset += CurrentItemSize + sizeof(ITEM_PREFIX);
|
||||||
|
|
||||||
|
}while (CurrentOffset < ReportEnd);
|
||||||
}while(CurrentOffset < ReportEnd);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -568,7 +568,8 @@ CHubController::HandlePnp(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status = STATUS_SUCCESS;
|
// Here we should leave Status as is.
|
||||||
|
Status = Irp->IoStatus.Status;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_CAPABILITIES:
|
case IRP_MN_QUERY_CAPABILITIES:
|
||||||
|
@ -611,6 +612,14 @@ CHubController::HandlePnp(
|
||||||
// handle device interface requests
|
// handle device interface requests
|
||||||
//
|
//
|
||||||
Status = HandleQueryInterface(IoStack);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
case IRP_MN_REMOVE_DEVICE:
|
||||||
|
@ -3736,6 +3745,7 @@ CHubController::HandleQueryInterface(
|
||||||
InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
|
InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InterfaceHub->InterfaceReference(InterfaceHub->BusContext);
|
||||||
//
|
//
|
||||||
// request completed
|
// request completed
|
||||||
//
|
//
|
||||||
|
@ -3790,6 +3800,7 @@ CHubController::HandleQueryInterface(
|
||||||
InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
|
InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InterfaceDI->InterfaceReference(InterfaceDI->BusContext);
|
||||||
//
|
//
|
||||||
// request completed
|
// request completed
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue