// Set usb device to unconfiguration state. NTSTATUS UsbDev::SetToUnconfigure() { NTSTATUS ntStatus; PURB pUrb; ULONG siz; DBGU_TRACE(">>>UsbDev::Unconfigure !\n"); siz = sizeof(struct _URB_SELECT_CONFIGURATION); pUrb = (PURB) ExAllocatePoolWithTag(NonPagedPool, siz, USBDEV_POOLTAG); if (pUrb) { UsbBuildSelectConfigurationRequest(pUrb, (USHORT) siz, NULL); ntStatus = SendAwaitUrb(pUrb); } else { ntStatus = STATUS_INSUFFICIENT_RESOURCES; } if(!NT_SUCCESS(ntStatus)) DBGU_TRACE("Fail to Unconfigure ! (Error : %x)\n",ntStatus); if(pUrb) ExFreePoolWithTag(pUrb,USBDEV_POOLTAG); return ntStatus; }
VOID StopDevice(IN PDEVICE_OBJECT fdo, BOOLEAN oktouch /* = FALSE */) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; // Stop polling StopPolling(pdx); // Disable the operational interface IoSetDeviceInterfaceState(&pdx->operationsInterfaceName, FALSE); // Disable the inquiry interface IoSetDeviceInterfaceState(&pdx->inquiriesInterfaceName, FALSE); // wait for polling thread to exit if(pdx->RecoveryThread) { // stop recovery thread pdx->RecoveryExit = TRUE; KeSetEvent(&pdx->RecoveryEvent, 0, FALSE); KeWaitForSingleObject(pdx->RecoveryThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(pdx->RecoveryThread); pdx->RecoveryThread = NULL; } // If it's okay to touch our hardware (i.e., we're processing an IRP_MN_STOP_DEVICE), // deconfigure the device. if(oktouch) { URB urb; UsbBuildSelectConfigurationRequest(&urb, sizeof(_URB_SELECT_CONFIGURATION), NULL); NTSTATUS status = SendAwaitUrb(fdo, &urb); if(!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - Error %X trying to deconfigure device\n", status)); } } if(pdx->pcd) { ExFreePool(pdx->pcd); pdx->pcd = NULL; } }
VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolDevUnconfigure(PDEVICE_OBJECT pDevObj) { USHORT cbUrb = sizeof (struct _URB_SELECT_CONFIGURATION); PURB pUrb = VBoxUsbToolUrbAlloc(URB_FUNCTION_SELECT_CONFIGURATION, cbUrb); Assert(pUrb); if (!pUrb) return STATUS_INSUFFICIENT_RESOURCES; UsbBuildSelectConfigurationRequest(pUrb, (USHORT)cbUrb, NULL); NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb, RT_INDEFINITE_WAIT); Assert(NT_SUCCESS(Status)); VBoxUsbToolUrbFree(pUrb); return Status; }
NTSTATUS IsoUsb_SelectInterface( IN PDEVICE_OBJECT DeviceObject, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ) /*++ Routine Description: Initializes an 82930 with (possibly) multiple interfaces; This minidriver only supports one interface (with multiple endpoints). Arguments: DeviceObject - pointer to the device object for this instance of the 82930 device. ConfigurationDescriptor - pointer to the USB configuration descriptor containing the interface and endpoint descriptors. Return Value: NT status code --*/ { PDEVICE_EXTENSION deviceExtension; NTSTATUS ntStatus; PURB urb = NULL; ULONG i; PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL; PUSBD_INTERFACE_INFORMATION Interface = NULL; USHORT siz; PUCHAR pInf; ISOUSB_KdPrint( DBGLVL_MEDIUM,("enter IsoUsb_SelectInterface\n")); deviceExtension = DeviceObject->DeviceExtension; ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_SelectInterface() called with NULL Interface\n")); // // IsoUsb driver only supports one interface, we must parse // the configuration descriptor for the interface // and remember the pipes. // urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz); if (urb) { // // USBD_ParseConfigurationDescriptorEx searches a given configuration // descriptor and returns a pointer to an interface that matches the // given search criteria. We only support one interface on this device // interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, //search from start of config descriptro -1, // interface number not a criteria; we only support one interface -1, // not interested in alternate setting here either -1, // interface class not a criteria -1, // interface subclass not a criteria -1 // interface protocol not a criteria ); if ( !interfaceDescriptor ) { ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_SelectInterface() ParseConfigurationDescriptorEx() failed\n returning STATUS_INSUFFICIENT_RESOURCES\n")); ExFreePool(urb); return STATUS_INSUFFICIENT_RESOURCES; } Interface = &urb->UrbSelectConfiguration.Interface; // allocate space for an array of pipe information structs; // in this basic sample, just used to track if opened/closed deviceExtension->PipeInfo = ExAllocatePool( NonPagedPool, Interface->NumberOfPipes * sizeof ( ISOUSB_PIPEINFO ) ); if ( !deviceExtension->PipeInfo ) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(deviceExtension->PipeInfo, Interface->NumberOfPipes * sizeof ( ISOUSB_PIPEINFO ) ); pInf = (PUCHAR ) deviceExtension->PipeInfo; for (i=0; i< Interface->NumberOfPipes; i++) { // // Perform any pipe initialization here; // We set the max transfer size and any Pipe flags we use; USBD sets the rest // of the Interface struct members // Interface->Pipes[i].MaximumTransferSize = deviceExtension->MaximumTransferSize; ( (PISOUSB_PIPEINFO) pInf)->fPipeOpened = FALSE; pInf += sizeof ( ISOUSB_PIPEINFO ); } UsbBuildSelectConfigurationRequest(urb, (USHORT) siz, ConfigurationDescriptor); ntStatus = IsoUsb_CallUSBD(DeviceObject, urb); deviceExtension->UsbConfigurationHandle = urb->UrbSelectConfiguration.ConfigurationHandle; } else { ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_SelectInterface() USBD_CreateConfigurationRequest() failed\n returning STATUS_INSUFFICIENT_RESOURCES\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; } if (NT_SUCCESS(ntStatus)) { // // Save the configuration handle for this device // deviceExtension->UsbConfigurationHandle = urb->UrbSelectConfiguration.ConfigurationHandle; deviceExtension->UsbInterface = ExAllocatePool(NonPagedPool, Interface->Length); if (deviceExtension->UsbInterface) { ULONG j; // // save a copy of the interface information returned // RtlCopyMemory(deviceExtension->UsbInterface, Interface, Interface->Length); // // Dump the interface to the debugger // ISOUSB_KdPrint( DBGLVL_MEDIUM,("---------\n")); ISOUSB_KdPrint( DBGLVL_MEDIUM,("NumberOfPipes 0x%x\n", deviceExtension->UsbInterface->NumberOfPipes)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("Length 0x%x\n", deviceExtension->UsbInterface->Length)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("Alt Setting 0x%x\n", deviceExtension->UsbInterface->AlternateSetting)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("Interface Number 0x%x\n", deviceExtension->UsbInterface->InterfaceNumber)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("Class, subclass, protocol 0x%x 0x%x 0x%x\n", deviceExtension->UsbInterface->Class, deviceExtension->UsbInterface->SubClass, deviceExtension->UsbInterface->Protocol)); // Dump the pipe info for (j=0; j<Interface->NumberOfPipes; j++) { PUSBD_PIPE_INFORMATION pipeInformation; pipeInformation = &deviceExtension->UsbInterface->Pipes[j]; ISOUSB_KdPrint( DBGLVL_MEDIUM,("---------\n")); ISOUSB_KdPrint( DBGLVL_MEDIUM,("PipeType 0x%x\n", pipeInformation->PipeType)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("Interval 0x%x\n", pipeInformation->Interval)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("Handle 0x%x\n", pipeInformation->PipeHandle)); ISOUSB_KdPrint( DBGLVL_MEDIUM,("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize)); } ISOUSB_KdPrint( DBGLVL_MEDIUM,("---------\n")); } } if (urb) { // don't call the ISOUSB_ExFreePool since the buffer was // alloced by USBD_CreateConfigurationRequest, not ISOUSB_ExAllocatePool() ExFreePool(urb); } ISOUSB_KdPrint( DBGLVL_HIGH,("exit IsoUsb_SelectInterface (%x)\n", ntStatus)); return ntStatus; }