PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
NTSTATUS Status;
+ ULONG Index;
//
// get current stack location
}
case IRP_MN_REMOVE_DEVICE:
{
- DPRINT1("IRP_MN_REMOVE_DEVICE\n");
+ //
+ // remove us from the fdo's pdo list
+ //
+ for(Index = 0; Index < PDODeviceExtension->FDODeviceExtension->FunctionDescriptorCount; Index++)
+ {
+ if (PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] == DeviceObject)
+ {
+ //
+ // remove us
+ //
+ PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] = NULL;
+ break;
+ }
+ }
- /* Complete the IRP */
+ //
+ // Complete the IRP
+ //
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* Delete the device object */
+ //
+ // Delete the device object
+ //
IoDeleteDevice(DeviceObject);
-
return STATUS_SUCCESS;
}
case IRP_MN_QUERY_CAPABILITIES:
{
PIO_STACK_LOCATION IoStack;
PPDO_DEVICE_EXTENSION PDODeviceExtension;
- PURB Urb;
+ PURB Urb, NewUrb;
PUSBD_INTERFACE_INFORMATION InterfaceInformation;
ULONG InterfaceInformationCount, Index, InterfaceIndex;
PUSBD_INTERFACE_LIST_ENTRY Entry;
ULONG NeedSelect, FoundInterface;
+ NTSTATUS Status;
//
// get current stack location
NeedSelect = FALSE;
if (Entry->InterfaceDescriptor->bAlternateSetting == InterfaceInformation->AlternateSetting)
{
- for(InterfaceIndex = 0; InterfaceIndex < Entry->InterfaceDescriptor->bNumEndpoints; InterfaceIndex++)
+
+ for(InterfaceIndex = 0; InterfaceIndex < InterfaceInformation->NumberOfPipes; InterfaceIndex++)
{
if (InterfaceInformation->Pipes[InterfaceIndex].MaximumTransferSize != Entry->Interface->Pipes[InterfaceIndex].MaximumTransferSize)
{
//
// interface is already selected
//
- ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
- RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
+ RtlCopyMemory(InterfaceInformation, Entry->Interface, min(InterfaceInformation->Length, Entry->Interface->Length));
}
else
{
//
- // FIXME select interface
+ // select interface
//
- UNIMPLEMENTED
- ASSERT(FALSE);
+ DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes);
+ ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
+
+ //
+ // build urb
+ //
+ NewUrb = AllocateItem(NonPagedPool, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation->NumberOfPipes));
+ if (!NewUrb)
+ {
+ //
+ // no memory
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // now prepare interface urb
+ //
+ UsbBuildSelectInterfaceRequest(NewUrb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation->NumberOfPipes), PDODeviceExtension->ConfigurationHandle, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting);
+
+ //
+ // now select the interface
+ //
+ Status = USBCCGP_SyncUrbRequest(PDODeviceExtension->NextDeviceObject, NewUrb);
+ DPRINT1("SelectInterface Status %x\n", Status);
+
+ //
+ // did it succeeed
+ //
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // update configuration info
+ //
+ ASSERT(Entry->Interface->Length == NewUrb->UrbSelectInterface.Interface.Length);
+ ASSERT(InterfaceInformation->Length == NewUrb->UrbSelectInterface.Interface.Length);
+ RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
+
+ //
+ // update provided interface information
+ //
+ RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
+ }
+
+ //
+ // free urb
+ //
+ FreeItem(NewUrb);
}
//
//
Urb = (PURB)IoStack->Parameters.Others.Argument1;
ASSERT(Urb);
- DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
+ DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
if (Urb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
{
return Status;
}
}
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_GET_PORT_STATUS)
+ {
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
+ return Status;
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT)
+ {
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
+ return Status;
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT)
+ {
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
+ return Status;
+ }