diff --git a/reactos/drivers/usb/usbhub/fdo.c b/reactos/drivers/usb/usbhub/fdo.c index ec56674fc09..65c529ccbe8 100644 --- a/reactos/drivers/usb/usbhub/fdo.c +++ b/reactos/drivers/usb/usbhub/fdo.c @@ -819,6 +819,7 @@ CreateDeviceIds( 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; @@ -828,6 +829,9 @@ CreateDeviceIds( // UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension; + // get hub device extension + HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension; + // // get device descriptor // @@ -1011,10 +1015,12 @@ CreateDeviceIds( // 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)) { @@ -1022,15 +1028,31 @@ CreateDeviceIds( 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) { @@ -1304,6 +1326,7 @@ CreateUsbChildDeviceObject( } HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject; + HubDeviceExtension->InstanceCount++; IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations); return STATUS_SUCCESS; diff --git a/reactos/drivers/usb/usbhub/pdo.c b/reactos/drivers/usb/usbhub/pdo.c index 939a9f3f816..6c561b99662 100644 --- a/reactos/drivers/usb/usbhub/pdo.c +++ b/reactos/drivers/usb/usbhub/pdo.c @@ -558,6 +558,7 @@ USBHUB_PdoHandlePnp( ULONG Index; ULONG bFound; PDEVICE_RELATIONS DeviceRelation; + PDEVICE_OBJECT ParentDevice; UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; Stack = IoGetCurrentIrpStackLocation(Irp); @@ -645,6 +646,7 @@ 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"); @@ -671,10 +673,13 @@ USBHUB_PdoHandlePnp( 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; @@ -731,6 +736,12 @@ USBHUB_PdoHandlePnp( 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); diff --git a/reactos/drivers/usb/usbhub/usbhub.h b/reactos/drivers/usb/usbhub/usbhub.h index 23337755e74..52d62e2540b 100644 --- a/reactos/drivers/usb/usbhub/usbhub.h +++ b/reactos/drivers/usb/usbhub/usbhub.h @@ -103,8 +103,9 @@ typedef struct _HUB_DEVICE_EXTENSION PVOID RootHubHandle; USB_BUS_INTERFACE_USBDI_V2 DeviceInterface; - UNICODE_STRING SymbolicLinkName; + ULONG InstanceCount; + } HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION; // createclose.c diff --git a/reactos/drivers/usb/usbstor/fdo.c b/reactos/drivers/usb/usbstor/fdo.c index 07518428037..a9f408da099 100644 --- a/reactos/drivers/usb/usbstor/fdo.c +++ b/reactos/drivers/usb/usbstor/fdo.c @@ -125,10 +125,19 @@ USBSTOR_FdoHandleRemoveDevice( 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); @@ -264,7 +273,7 @@ USBSTOR_FdoHandleStartDevice( // // create pdo // - Status = USBSTOR_CreatePDO(DeviceObject, Index, &DeviceExtension->ChildPDO[Index]); + Status = USBSTOR_CreatePDO(DeviceObject, Index); // // check for failure @@ -282,6 +291,7 @@ USBSTOR_FdoHandleStartDevice( // increment pdo index // Index++; + DeviceExtension->InstanceCount++; }while(Index < DeviceExtension->MaxLUN); @@ -340,8 +350,20 @@ USBSTOR_FdoHandlePnp( 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; } diff --git a/reactos/drivers/usb/usbstor/pdo.c b/reactos/drivers/usb/usbstor/pdo.c index 9e293df80a6..f7a2a654789 100644 --- a/reactos/drivers/usb/usbstor/pdo.c +++ b/reactos/drivers/usb/usbstor/pdo.c @@ -676,9 +676,9 @@ USBSTOR_PdoHandleQueryInstanceId( 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); } // @@ -897,7 +897,7 @@ USBSTOR_PdoHandlePnp( // 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; @@ -929,6 +929,11 @@ USBSTOR_PdoHandlePnp( Status = STATUS_SUCCESS; break; } + case IRP_MN_SURPRISE_REMOVAL: + { + Status = STATUS_SUCCESS; + break; + } default: { // @@ -1256,13 +1261,19 @@ USBSTOR_SendFormatCapacityIrp( 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 @@ -1292,7 +1303,7 @@ USBSTOR_CreatePDO( 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; @@ -1309,7 +1320,7 @@ USBSTOR_CreatePDO( // // output device object // - *ChildDeviceObject = PDO; + FDODeviceExtension->ChildPDO[LUN] = PDO; // // send inquiry command by irp diff --git a/reactos/drivers/usb/usbstor/usbstor.h b/reactos/drivers/usb/usbstor/usbstor.h index 29ef1ce6bd6..3fb4d3cc642 100644 --- a/reactos/drivers/usb/usbstor/usbstor.h +++ b/reactos/drivers/usb/usbstor/usbstor.h @@ -71,6 +71,7 @@ typedef struct 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 @@ -364,8 +365,7 @@ USBSTOR_PdoHandlePnp( NTSTATUS USBSTOR_CreatePDO( IN PDEVICE_OBJECT DeviceObject, - IN UCHAR LUN, - OUT PDEVICE_OBJECT *ChildDeviceObject); + IN UCHAR LUN); //--------------------------------------------------------------------- //