LPWSTR DeviceString;
WCHAR Buffer[200];
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
+ PHUB_DEVICE_EXTENSION HubDeviceExtension;
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
//
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension;
+ // get hub device extension
+ HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension;
+
//
// get device descriptor
//
//
if (UsbChildExtension->DeviceDesc.iSerialNumber)
{
+ LPWSTR SerialBuffer = NULL;
+
Status = GetUsbStringDescriptor(UsbChildDeviceObject,
UsbChildExtension->DeviceDesc.iSerialNumber,
0,
- (PVOID*)&UsbChildExtension->usInstanceId.Buffer,
+ (PVOID*)&SerialBuffer,
&UsbChildExtension->usInstanceId.Length);
if (!NT_SUCCESS(Status))
{
return Status;
}
- UsbChildExtension->usInstanceId.MaximumLength = UsbChildExtension->usInstanceId.Length;
- DPRINT("Usb InstanceId %wZ\n", &UsbChildExtension->usInstanceId);
+ // construct instance id buffer
+ Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1;
+ UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
+ if (UsbChildExtension->usInstanceId.Buffer == NULL)
+ {
+ DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ return Status;
+ }
+
+ //
+ // copy instance id
+ //
+ RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR));
+ UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR);
+ ExFreePool(SerialBuffer);
+
+ DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount);
}
else
{
//
// the device did not provide a serial number, lets create a pseudo instance id
//
- Index = swprintf(Buffer, L"0&%04d", UsbChildExtension->PortNumber) + 1;
+ Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1;
UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
if (UsbChildExtension->usInstanceId.Buffer == NULL)
{
}
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
+ HubDeviceExtension->InstanceCount++;
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
return STATUS_SUCCESS;
ULONG Index;
ULONG bFound;
PDEVICE_RELATIONS DeviceRelation;
+ PDEVICE_OBJECT ParentDevice;
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
{
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");
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ /* delete device */
+ IoDeleteDevice(DeviceObject);
+
if (bFound)
{
- /* Delete the device object */
- IoDeleteDevice(DeviceObject);
+ /* invalidate device relations */
+ IoInvalidateDeviceRelations(ParentDevice, BusRelations);
}
return STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
}
+ case IRP_MN_SURPRISE_REMOVAL:
+ {
+ DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
+ Status = STATUS_SUCCESS;
+ break;
+ }
default:
{
DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
PVOID RootHubHandle;
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
-
UNICODE_STRING SymbolicLinkName;
+ ULONG InstanceCount;
+
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
// createclose.c
IN OUT PIRP Irp)
{
NTSTATUS Status;
+ ULONG Index;
- DPRINT("Handling FDO removal\n");
+ DPRINT("Handling FDO removal %p\n", DeviceObject);
- /* We don't need to request removal of our children here */
+ /* FIXME: wait for devices finished processing */
+ for(Index = 0; Index < 16; Index++)
+ {
+ if (DeviceExtension->ChildPDO[Index] != NULL)
+ {
+ DPRINT("Deleting PDO %p RefCount %x AttachedDevice %p \n", DeviceExtension->ChildPDO[Index], DeviceExtension->ChildPDO[Index]->ReferenceCount, DeviceExtension->ChildPDO[Index]->AttachedDevice);
+ IoDeleteDevice(DeviceExtension->ChildPDO[Index]);
+ }
+ }
/* Send the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp);
//
// create pdo
//
- Status = USBSTOR_CreatePDO(DeviceObject, Index, &DeviceExtension->ChildPDO[Index]);
+ Status = USBSTOR_CreatePDO(DeviceObject, Index);
//
// check for failure
// increment pdo index
//
Index++;
+ DeviceExtension->InstanceCount++;
}while(Index < DeviceExtension->MaxLUN);
switch(IoStack->MinorFunction)
{
+ case IRP_MN_SURPRISE_REMOVAL:
+ {
+ DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ //
+ // forward irp to next device object
+ //
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
+ }
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
+ DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
break;
}
else
{
//
- // FIXME: should use some random value
+ // use instance count and LUN
//
- swprintf(Buffer, L"%s&%d", L"00000000", PDODeviceExtension->LUN);
+ swprintf(Buffer, L"%04d&%d", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
}
//
// check if no unique id
//
Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
- Caps->UniqueID = TRUE; //FIXME
+ Caps->UniqueID = FALSE; // no unique id is supported
Caps->Removable = TRUE; //FIXME
}
break;
Status = STATUS_SUCCESS;
break;
}
+ case IRP_MN_SURPRISE_REMOVAL:
+ {
+ Status = STATUS_SUCCESS;
+ break;
+ }
default:
{
//
NTSTATUS
USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR LUN,
- OUT PDEVICE_OBJECT *ChildDeviceObject)
+ IN UCHAR LUN)
{
PDEVICE_OBJECT PDO;
NTSTATUS Status;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUFI_INQUIRY_RESPONSE Response;
+ PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+ //
+ // get device extension
+ //
+ FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
//
// create child device object
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
PDODeviceExtension->Common.IsFDO = FALSE;
PDODeviceExtension->LowerDeviceObject = DeviceObject;
- PDODeviceExtension->PDODeviceObject = ChildDeviceObject;
+ PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
PDODeviceExtension->Self = PDO;
PDODeviceExtension->LUN = LUN;
//
// output device object
//
- *ChildDeviceObject = PDO;
+ FDODeviceExtension->ChildPDO[LUN] = PDO;
//
// send inquiry command by irp
PSCSI_REQUEST_BLOCK LastTimerActiveSrb; // last timer tick active srb
ULONG SrbErrorHandlingActive; // error handling of srb is activated
ULONG TimerWorkQueueEnabled; // timer work queue enabled
+ ULONG InstanceCount; // pdo instance count
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
typedef struct
NTSTATUS
USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR LUN,
- OUT PDEVICE_OBJECT *ChildDeviceObject);
+ IN UCHAR LUN);
//---------------------------------------------------------------------
//