Author: janderwald Date: Wed May 4 12:33:01 2011 New Revision: 51575
URL: http://svn.reactos.org/svn/reactos?rev=51575&view=rev Log: [USBSTOR] - Don't free device descriptor if it failed to acquire it - Don't move out of usb configuration array. Found by special pool - Fix bug when storing interface information which lead to a overwrite - Implement retrieving generic type for device - Fix bugs in QueryDeviceId - Implement querying hardware ids - Implement querying instance ids - With these changes, usbstor now initializes and create pdo, which is also enumerated - Needs more code / fixes so that disk.sys attaches to usbstor - WIP
Modified: branches/usb-bringup/drivers/usb/usbstor/descriptor.c branches/usb-bringup/drivers/usb/usbstor/misc.c branches/usb-bringup/drivers/usb/usbstor/pdo.c
Modified: branches/usb-bringup/drivers/usb/usbstor/descriptor.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/descriptor.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/descriptor.c [iso-8859-1] Wed May 4 12:33:01 2011 @@ -115,7 +115,6 @@ // // failed to get device descriptor // - FreeItem(DeviceExtension->DeviceDescriptor); DeviceExtension->DeviceDescriptor = NULL; return Status; } @@ -271,7 +270,7 @@ // // was it the last descriptor // - if ((ULONG_PTR)CurrentDescriptor > ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) + if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) { // // reached last descriptor @@ -433,7 +432,8 @@ // // update configuration info // - RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectConfiguration.Interface.Length); + ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInformation->Length); + RtlCopyMemory(DeviceExtension->InterfaceInformation, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length); }
//
Modified: branches/usb-bringup/drivers/usb/usbstor/misc.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/misc.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/misc.c [iso-8859-1] Wed May 4 12:33:01 2011 @@ -203,6 +203,8 @@ IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest; + IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length; + Irp->IoStatus.Status = STATUS_SUCCESS;
// // setup completion routine
Modified: branches/usb-bringup/drivers/usb/usbstor/pdo.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbstor/... ============================================================================== --- branches/usb-bringup/drivers/usb/usbstor/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/usb/usbstor/pdo.c [iso-8859-1] Wed May 4 12:33:01 2011 @@ -75,10 +75,80 @@ // // other device // - return "CdRom"; - } - } -} + return "Other"; + } + } +} + +LPCWSTR +USBSTOR_GetGenericType( + IN PUFI_INQUIRY_RESPONSE InquiryData) +{ + // + // check if device type is zero + // + if (InquiryData->DeviceType == 0) + { + // + // direct access device + // + + // + // FIXME: check if floppy + // + return L"GenDisk"; + } + + // + // FIXME: use constant - derrived from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type + // + switch (InquiryData->DeviceType) + { + case 1: + { + // + // sequential device, i.e magnetic tape + // + return L"GenSequential"; + } + case 4: + { + // + // write once device + // + return L"GenWorm"; + } + case 5: + { + // + // CDROM device + // + return L"GenCdRom"; + } + case 7: + { + // + // optical memory device + // + return L"GenOptical"; + } + case 8: + { + // + // medium change device + // + return L"GenChanger"; + } + default: + { + // + // other device + // + return L"UsbstorOther"; + } + } +} +
ULONG CopyField( @@ -114,6 +184,8 @@ ANSI_STRING AnsiString; UNICODE_STRING DeviceId;
+ DPRINT1("USBSTOR_PdoHandleQueryDeviceId\n"); + // // get device extension // @@ -135,6 +207,11 @@ DeviceType = USBSTOR_GetDeviceType(InquiryData);
// + // zero buffer + // + RtlZeroMemory(Buffer, sizeof(Buffer)); + + // // lets create device string // Offset = sprintf(&Buffer[Offset], "USBSTOR\%s&Ven_", DeviceType); @@ -192,7 +269,7 @@ // allocate DeviceId string // DeviceId.Length = 0; - DeviceId.MaximumLength = (Offset + 2) * sizeof(WCHAR); + DeviceId.MaximumLength = (strlen((PCHAR)Buffer) + 1) * sizeof(WCHAR); DeviceId.Buffer = (LPWSTR)AllocateItem(PagedPool, DeviceId.MaximumLength); if (!DeviceId.Buffer) { @@ -217,7 +294,7 @@ Irp->IoStatus.Information = (ULONG_PTR)DeviceId.Buffer; }
- DPRINT1("DeviceId %wZ\n", &DeviceId); + DPRINT1("DeviceId %wZ Status %x\n", &DeviceId, Status);
// // done @@ -225,6 +302,161 @@ return Status; }
+NTSTATUS +USBSTOR_PdoHandleQueryHardwareId( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + WCHAR Buffer[200]; + ULONG Length; + LPWSTR DeviceName; + LPCWSTR GenericType; + + DPRINT1("USBSTOR_PdoHandleQueryInstanceId\n"); + + // + // get PDO device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->DeviceDescriptor); + + // + // get generic type + // + GenericType = USBSTOR_GetGenericType((PUFI_INQUIRY_RESPONSE)PDODeviceExtension->InquiryData); + ASSERT(GenericType); + + // + // zero buffer + // + RtlZeroMemory(Buffer, sizeof(Buffer)); + + // + // format hardware id + // + Length = swprintf(Buffer, L"USB\VID_%04x&Pid_%04x&Rev_%04x", FDODeviceExtension->DeviceDescriptor->idVendor, FDODeviceExtension->DeviceDescriptor->idProduct, FDODeviceExtension->DeviceDescriptor->bcdDevice) + 1; + Length += swprintf(&Buffer[Length], L"USB\VID_%04x&Pid_%04x", FDODeviceExtension->DeviceDescriptor->idVendor, FDODeviceExtension->DeviceDescriptor->idProduct) + 1; + Length += swprintf(&Buffer[Length], L"USBSTOR\%s", GenericType) + 1; + Length += swprintf(&Buffer[Length], L"%s", GenericType) + 1; + + // + // TODO: add more ids + // + + Buffer[Length] = UNICODE_NULL; + Length++; + + DPRINT1("Name %S\n", Buffer); + + // + // allocate buffer + // + DeviceName = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR)); + + if (!DeviceName) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy device name + // + RtlMoveMemory(DeviceName, Buffer, Length * sizeof(WCHAR)); + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)DeviceName; + + // + // done + // + return STATUS_SUCCESS; +} + +NTSTATUS +USBSTOR_PdoHandleQueryInstanceId( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp) +{ + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + WCHAR Buffer[100]; + ULONG Length; + LPWSTR InstanceId; + + DPRINT1("USBSTOR_PdoHandleQueryInstanceId\n"); + + // + // get PDO device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get FDO device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension; + + // + // sanity check + // + ASSERT(FDODeviceExtension->DeviceDescriptor); + + // + // format instance id + // + swprintf(Buffer, L"USB\VID_%04x&PID_%04x\%s", FDODeviceExtension->DeviceDescriptor->idVendor, FDODeviceExtension->DeviceDescriptor->idProduct, L"00000000"); + + // + // calculate length + // + Length = wcslen(Buffer) + 1; + + // + // allocate instance id + // + InstanceId = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR)); + if (!InstanceId) + { + // + // no memory + // + Irp->IoStatus.Information = 0; + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // copy instance id + // + wcscpy(InstanceId, Buffer); + + DPRINT1("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId); + + // + // store result + // + Irp->IoStatus.Information = (ULONG_PTR)InstanceId; + + // + // completed successfully + // + return STATUS_SUCCESS; +}
NTSTATUS USBSTOR_PdoHandleDeviceRelations( @@ -234,6 +466,8 @@ PDEVICE_RELATIONS DeviceRelations; PIO_STACK_LOCATION IoStack;
+ DPRINT1("USBSTOR_PdoHandleDeviceRelations\n"); + // // get current irp stack location // @@ -289,6 +523,7 @@ PIO_STACK_LOCATION IoStack; PPDO_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; + PDEVICE_CAPABILITIES Caps;
// // get current stack location @@ -326,9 +561,26 @@ Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp); break; } + else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs) + { + // + // handle instance id + // + Status = USBSTOR_PdoHandleQueryHardwareId(DeviceObject, Irp); + break; + } + else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID) + { + // + // handle instance id + // + Status = USBSTOR_PdoHandleQueryInstanceId(DeviceObject, Irp); + break; + }
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType); Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = 0; break; } case IRP_MN_REMOVE_DEVICE: @@ -341,6 +593,16 @@ // just forward irp to lower device // Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); + + if (NT_SUCCESS(Status)) + { + // + // check if no unique id + // + Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities; + Caps->UniqueID = FALSE; //FIXME + Caps->Removable = TRUE; //FIXME + } break; } case IRP_MN_START_DEVICE: