NTSTATUS NTAPI ProcessorPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpSp; ULONG_PTR Information = 0; NTSTATUS Status = STATUS_NOT_SUPPORTED; DPRINT("ProcessorPnp()\n"); IrpSp = IoGetCurrentIrpStackLocation(Irp); switch (IrpSp->MinorFunction) { case IRP_MN_START_DEVICE: DPRINT(" IRP_MN_START_DEVICE received\n"); /* Call lower driver */ Status = ForwardIrpAndWait(DeviceObject, Irp); if (NT_SUCCESS(Status)) { Status = ProcessorStartDevice(DeviceObject, IrpSp->Parameters.StartDevice.AllocatedResources, IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated); } break; case IRP_MN_QUERY_REMOVE_DEVICE: DPRINT(" IRP_MN_QUERY_REMOVE_DEVICE\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_REMOVE_DEVICE: DPRINT(" IRP_MN_REMOVE_DEVICE received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_CANCEL_REMOVE_DEVICE: DPRINT(" IRP_MN_CANCEL_REMOVE_DEVICE\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_STOP_DEVICE: DPRINT(" IRP_MN_STOP_DEVICE received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_QUERY_STOP_DEVICE: DPRINT(" IRP_MN_QUERY_STOP_DEVICE received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_CANCEL_STOP_DEVICE: DPRINT(" IRP_MN_CANCEL_STOP_DEVICE\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_QUERY_DEVICE_RELATIONS: DPRINT(" IRP_MN_QUERY_DEVICE_RELATIONS\n"); switch (IrpSp->Parameters.QueryDeviceRelations.Type) { case BusRelations: DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); break; case RemovalRelations: DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); default: DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", IrpSp->Parameters.QueryDeviceRelations.Type); return ForwardIrpAndForget(DeviceObject, Irp); } break; case IRP_MN_SURPRISE_REMOVAL: DPRINT(" IRP_MN_SURPRISE_REMOVAL received\n"); return ForwardIrpAndForget(DeviceObject, Irp); case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0xd */ DPRINT(" IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); return ForwardIrpAndForget(DeviceObject, Irp); default: DPRINT(" Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS USBHUB_ParentFDOStartDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PHUB_DEVICE_EXTENSION HubDeviceExtension; PURB Urb, ConfigurationUrb; PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; PUSBD_INTERFACE_LIST_ENTRY InterfaceList; ULONG Index; NTSTATUS Status; // get hub device extension HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension; // Send the StartDevice to lower device object Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp); if (!NT_SUCCESS(Status)) { // failed to start pdo DPRINT1("Failed to start the RootHub PDO\n"); return Status; } // FIXME get capabilities Urb = ExAllocatePool(NonPagedPool, sizeof(URB)); if (!Urb) { // no memory DPRINT1("No memory\n"); return STATUS_INSUFFICIENT_RESOURCES; } // lets get device descriptor UsbBuildGetDescriptorRequest(Urb, sizeof(Urb->UrbControlDescriptorRequest), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, &HubDeviceExtension->HubDeviceDescriptor, NULL, sizeof(USB_DEVICE_DESCRIPTOR), NULL); // get hub device descriptor Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); if (!NT_SUCCESS(Status)) { // failed to get device descriptor of hub DPRINT1("Failed to get hub device descriptor with Status %x!\n", Status); ExFreePool(Urb); return Status; } // now get configuration descriptor UsbBuildGetDescriptorRequest(Urb, sizeof(Urb->UrbControlDescriptorRequest), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, &HubDeviceExtension->HubConfigDescriptor, NULL, sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR), NULL); // request configuration descriptor Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); if (!NT_SUCCESS(Status)) { // failed to get configuration descriptor DPRINT1("Failed to get hub configuration descriptor with status %x\n", Status); ExFreePool(Urb); return Status; } // sanity checks ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength == sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR)); ASSERT(HubDeviceExtension->HubConfigDescriptor.bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE); ASSERT(HubDeviceExtension->HubConfigDescriptor.bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR)); ASSERT(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces == 1); ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bNumEndpoints == 1); ASSERT(HubDeviceExtension->HubEndPointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE); ASSERT(HubDeviceExtension->HubEndPointDescriptor.bLength == sizeof(USB_ENDPOINT_DESCRIPTOR)); ASSERT(HubDeviceExtension->HubEndPointDescriptor.bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT); ASSERT(HubDeviceExtension->HubEndPointDescriptor.bEndpointAddress == 0x81); // interrupt in // Build hub descriptor request UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_DEVICE, sizeof(Urb->UrbControlVendorClassRequest), USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, 0, USB_REQUEST_GET_DESCRIPTOR, USB_DEVICE_CLASS_RESERVED, 0, &HubDeviceExtension->HubDescriptor, NULL, sizeof(USB_HUB_DESCRIPTOR), NULL); // send request Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status); ExFreePool(Urb); return STATUS_UNSUCCESSFUL; } // sanity checks ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == sizeof(USB_HUB_DESCRIPTOR)); ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts); ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29); // store number of ports DPRINT1("NumberOfPorts %lu\n", HubDeviceExtension->HubDescriptor.bNumberOfPorts); HubDeviceExtension->UsbExtHubInfo.NumberOfPorts = HubDeviceExtension->HubDescriptor.bNumberOfPorts; // allocate interface list InterfaceList = ExAllocatePool(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1)); if (!InterfaceList) { // no memory DPRINT1("No memory\n"); return STATUS_INSUFFICIENT_RESOURCES; } // zero list RtlZeroMemory(InterfaceList, sizeof(USBD_INTERFACE_LIST_ENTRY) * (HubDeviceExtension->HubConfigDescriptor.bNumInterfaces + 1)); // grab all interface descriptors for(Index = 0; Index < HubDeviceExtension->HubConfigDescriptor.bNumInterfaces; Index++) { // Get the first Configuration Descriptor InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor, &HubDeviceExtension->HubConfigDescriptor, Index, 0, -1, -1, -1); // store in list InterfaceList[Index].InterfaceDescriptor = InterfaceDescriptor; } // now create configuration request ConfigurationUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor, (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList); if (ConfigurationUrb == NULL) { // failed to build urb DPRINT1("Failed to build configuration urb\n"); ExFreePool(Urb); return STATUS_INSUFFICIENT_RESOURCES; } // send request Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, ConfigurationUrb, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to get Hub Descriptor Status %x!\n", Status); ExFreePool(Urb); ExFreePool(ConfigurationUrb); return STATUS_UNSUCCESSFUL; } // store configuration & pipe handle HubDeviceExtension->ConfigurationHandle = ConfigurationUrb->UrbSelectConfiguration.ConfigurationHandle; HubDeviceExtension->PipeHandle = ConfigurationUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle; DPRINT("Hub Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle); // free urb ExFreePool(ConfigurationUrb); ExFreePool(Urb); // FIXME build SCE interrupt request // FIXME create pdos return Status; }
NTSTATUS NTAPI SermousePnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { ULONG MinorFunction; PIO_STACK_LOCATION Stack; ULONG_PTR Information = 0; NTSTATUS Status; Stack = IoGetCurrentIrpStackLocation(Irp); MinorFunction = Stack->MinorFunction; Information = Irp->IoStatus.Information; switch (MinorFunction) { /* FIXME: do all these minor functions IRP_MN_QUERY_REMOVE_DEVICE 0x1 IRP_MN_REMOVE_DEVICE 0x2 IRP_MN_CANCEL_REMOVE_DEVICE 0x3 IRP_MN_STOP_DEVICE 0x4 IRP_MN_QUERY_STOP_DEVICE 0x5 IRP_MN_CANCEL_STOP_DEVICE 0x6 IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7 IRP_MN_QUERY_INTERFACE (optional) 0x8 IRP_MN_QUERY_CAPABILITIES (optional) 0x9 IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional or required) 0xd IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16 IRP_MN_SURPRISE_REMOVAL 0x17 */ case IRP_MN_START_DEVICE: /* 0x0 */ { TRACE_(SERMOUSE, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); /* Call lower driver */ Status = ForwardIrpAndWait(DeviceObject, Irp); if (NT_SUCCESS(Status)) Status = SermouseStartDevice(DeviceObject, Irp); break; } case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x7 */ { switch (Stack->Parameters.QueryDeviceRelations.Type) { case BusRelations: { PDEVICE_RELATIONS DeviceRelations = NULL; TRACE_(SERMOUSE, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n"); DeviceRelations = ExAllocatePoolWithTag(PagedPool, FIELD_OFFSET(DEVICE_RELATIONS, Objects), SERMOUSE_TAG); if (!DeviceRelations) { WARN_(SERMOUSE, "ExAllocatePoolWithTag() failed\n"); Status = STATUS_NO_MEMORY; } else { DeviceRelations->Count = 0; Status = STATUS_SUCCESS; Information = (ULONG_PTR)DeviceRelations; } break; } default: { TRACE_(SERMOUSE, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", Stack->Parameters.QueryDeviceRelations.Type); return ForwardIrpAndForget(DeviceObject, Irp); } } break; } default: { TRACE_(SERMOUSE, "IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } } Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI PciIdeXFdoPnpDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { ULONG MinorFunction; PIO_STACK_LOCATION Stack; ULONG_PTR Information = Irp->IoStatus.Information; NTSTATUS Status; Stack = IoGetCurrentIrpStackLocation(Irp); MinorFunction = Stack->MinorFunction; switch (MinorFunction) { case IRP_MN_START_DEVICE: /* 0x00 */ { DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); /* Call lower driver */ Status = ForwardIrpAndWait(DeviceObject, Irp); if (NT_SUCCESS(Status)) Status = PciIdeXFdoStartDevice(DeviceObject, Irp); break; } case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */ { DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n"); Status = STATUS_UNSUCCESSFUL; break; } case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */ { switch (Stack->Parameters.QueryDeviceRelations.Type) { case BusRelations: { PDEVICE_RELATIONS DeviceRelations = NULL; DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); Status = PciIdeXFdoQueryBusRelations(DeviceObject, &DeviceRelations); Information = (ULONG_PTR)DeviceRelations; break; } default: { DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", Stack->Parameters.QueryDeviceRelations.Type); Status = STATUS_NOT_IMPLEMENTED; break; } } break; } case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */ { DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n"); Information |= PNP_DEVICE_NOT_DISABLEABLE; Status = STATUS_SUCCESS; break; } case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */ { DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); return ForwardIrpAndForget(DeviceObject, Irp); } default: { DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } } Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS FdoPnpControl( PDEVICE_OBJECT DeviceObject, PIRP Irp) /* * FUNCTION: Handle Plug and Play IRPs for the PCI device object * ARGUMENTS: * DeviceObject = Pointer to functional device object of the PCI driver * Irp = Pointer to IRP that should be handled * RETURNS: * Status */ { PFDO_DEVICE_EXTENSION DeviceExtension; PIO_STACK_LOCATION IrpSp; NTSTATUS Status = Irp->IoStatus.Status; DPRINT("Called\n"); DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; IrpSp = IoGetCurrentIrpStackLocation(Irp); switch (IrpSp->MinorFunction) { #if 0 case IRP_MN_CANCEL_REMOVE_DEVICE: Status = STATUS_NOT_IMPLEMENTED; break; case IRP_MN_CANCEL_STOP_DEVICE: Status = STATUS_NOT_IMPLEMENTED; break; case IRP_MN_DEVICE_USAGE_NOTIFICATION: Status = STATUS_NOT_IMPLEMENTED; break; case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: Status = STATUS_NOT_IMPLEMENTED; break; #endif case IRP_MN_QUERY_DEVICE_RELATIONS: if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) break; Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; #if 0 case IRP_MN_QUERY_PNP_DEVICE_STATE: Status = STATUS_NOT_IMPLEMENTED; break; case IRP_MN_QUERY_REMOVE_DEVICE: Status = STATUS_NOT_IMPLEMENTED; break; #endif case IRP_MN_START_DEVICE: DPRINT("IRP_MN_START_DEVICE received\n"); Status = ForwardIrpAndWait(DeviceObject, Irp); if (NT_SUCCESS(Status)) Status = FdoStartDevice(DeviceObject, Irp); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; case IRP_MN_QUERY_STOP_DEVICE: /* We don't support stopping yet */ Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; case IRP_MN_STOP_DEVICE: /* We can't fail this one so we fail the QUERY_STOP request that precedes it */ break; #if 0 case IRP_MN_SURPRISE_REMOVAL: Status = STATUS_NOT_IMPLEMENTED; break; #endif case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: break; case IRP_MN_REMOVE_DEVICE: /* Detach the device object from the device stack */ IoDetachDevice(DeviceExtension->Ldo); /* Delete the device object */ IoDeleteDevice(DeviceObject); /* Return success */ Status = STATUS_SUCCESS; break; default: DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction); break; } Irp->IoStatus.Status = Status; IoSkipCurrentIrpStackLocation(Irp); Status = IoCallDriver(DeviceExtension->Ldo, Irp); DPRINT("Leaving. Status 0x%X\n", Status); return Status; }
NTSTATUS NTAPI i8042Pnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION Stack; ULONG MinorFunction; I8042_DEVICE_TYPE DeviceType; ULONG_PTR Information = 0; NTSTATUS Status; Stack = IoGetCurrentIrpStackLocation(Irp); MinorFunction = Stack->MinorFunction; DeviceType = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type; switch (MinorFunction) { case IRP_MN_START_DEVICE: /* 0x00 */ { TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); /* Call lower driver (if any) */ if (DeviceType != PhysicalDeviceObject) { Status = ForwardIrpAndWait(DeviceObject, Irp); if (NT_SUCCESS(Status)) Status = i8042PnpStartDevice( DeviceObject, Stack->Parameters.StartDevice.AllocatedResources, Stack->Parameters.StartDevice.AllocatedResourcesTranslated); } else Status = STATUS_SUCCESS; break; } case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x07 */ { switch (Stack->Parameters.QueryDeviceRelations.Type) { case BusRelations: { PDEVICE_RELATIONS DeviceRelations; TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); if (DeviceRelations) { DeviceRelations->Count = 0; Information = (ULONG_PTR)DeviceRelations; Status = STATUS_SUCCESS; } else Status = STATUS_INSUFFICIENT_RESOURCES; break; } case RemovalRelations: { TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); } default: ERR_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", Stack->Parameters.QueryDeviceRelations.Type); ASSERT(FALSE); return ForwardIrpAndForget(DeviceObject, Irp); } break; } case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0x0d */ { TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); /* Nothing to do */ Status = Irp->IoStatus.Status; break; } case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */ { TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n"); /* Nothing much to tell */ Information = 0; Status = STATUS_SUCCESS; break; } default: { ERR_(I8042PRT, "IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } } Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; ULONG MinorFunction; ULONG_PTR Information = 0; PHUB_DEVICE_EXTENSION DeviceExtension; IrpSp = IoGetCurrentIrpStackLocation(Irp); MinorFunction = IrpSp->MinorFunction; DeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension; switch (MinorFunction) { case IRP_MN_START_DEVICE: /* 0x0 */ { PURB Urb; ULONG Result = 0; PUSB_INTERFACE_DESCRIPTOR Pid; /* Theres only one descriptor on hub */ USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}}; PURB ConfigUrb = NULL; /* We differ from windows on hubpdo because we dont have usbport.sys which manages all usb device objects */ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); /* Allocating size including the sizeof USBD_INTERFACE_LIST_ENTRY */ Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG); RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY)); /* Get the hubs PDO */ QueryRootHub(DeviceExtension->LowerDevice, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO, &DeviceExtension->RootHubPdo, &DeviceExtension->RootHubFdo); ASSERT(DeviceExtension->RootHubPdo); ASSERT(DeviceExtension->RootHubFdo); DPRINT1("RootPdo %x, RootFdo %x\n", DeviceExtension->RootHubPdo, DeviceExtension->RootHubFdo); /* Send the START_DEVICE irp down to the PDO of RootHub */ Status = ForwardIrpAndWait(DeviceExtension->RootHubPdo, Irp); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to start the RootHub PDO\n"); ASSERT(FALSE); } /* Get the current number of hubs */ QueryRootHub(DeviceExtension->RootHubPdo,IOCTL_INTERNAL_USB_GET_HUB_COUNT, &DeviceExtension->HubCount, NULL); /* Get the Direct Call Interfaces */ Status = QueryInterface(DeviceExtension->RootHubPdo, USB_BUS_INTERFACE_HUB_GUID, sizeof(USB_BUS_INTERFACE_HUB_V5), 5, (PVOID)&DeviceExtension->HubInterface); if (!NT_SUCCESS(Status)) { DPRINT1("UsbhubM Failed to get HUB_GUID interface with status 0x%08lx\n", Status); return STATUS_UNSUCCESSFUL; } Status = QueryInterface(DeviceExtension->RootHubPdo, USB_BUS_INTERFACE_USBDI_GUID, sizeof(USB_BUS_INTERFACE_USBDI_V2), 2, (PVOID)&DeviceExtension->UsbDInterface); if (!NT_SUCCESS(Status)) { DPRINT1("UsbhubM Failed to get USBDI_GUID interface with status 0x%08lx\n", Status); return STATUS_UNSUCCESSFUL; } /* Get roothub device handle */ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, &DeviceExtension->RootHubUsbDevice, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Usbhub: GetRootHubDeviceHandle failed with status 0x%08lx\n", Status); return Status; } Status = DeviceExtension->HubInterface.QueryDeviceInformation(DeviceExtension->RootHubPdo, DeviceExtension->RootHubUsbDevice, &DeviceExtension->DeviceInformation, sizeof(USB_DEVICE_INFORMATION_0), &Result); DPRINT("Status %x, Result %x\n", Status, Result); DPRINT("InformationLevel %x\n", DeviceExtension->DeviceInformation.InformationLevel); DPRINT("ActualLength %x\n", DeviceExtension->DeviceInformation.ActualLength); DPRINT("PortNumber %x\n", DeviceExtension->DeviceInformation.PortNumber); DPRINT("DeviceDescriptor %x\n", DeviceExtension->DeviceInformation.DeviceDescriptor); DPRINT("HubAddress %x\n", DeviceExtension->DeviceInformation.HubAddress); DPRINT("NumberofPipes %x\n", DeviceExtension->DeviceInformation.NumberOfOpenPipes); /* Get roothubs device descriptor */ UsbBuildGetDescriptorRequest(Urb, sizeof(Urb->UrbControlDescriptorRequest), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, &DeviceExtension->HubDeviceDescriptor, NULL, sizeof(USB_DEVICE_DESCRIPTOR), NULL); Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice; Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Usbhub: Failed to get HubDeviceDescriptor!\n"); } DumpDeviceDescriptor(&DeviceExtension->HubDeviceDescriptor); /* Get roothubs configuration descriptor */ UsbBuildGetDescriptorRequest(Urb, sizeof(Urb->UrbControlDescriptorRequest), USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0, &DeviceExtension->HubConfigDescriptor, NULL, sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR), NULL); Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice; Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Usbhub: Failed to get RootHub Configuration with status %x\n", Status); ASSERT(FALSE); } ASSERT(DeviceExtension->HubConfigDescriptor.wTotalLength); DumpFullConfigurationDescriptor(&DeviceExtension->HubConfigDescriptor); //DPRINT1("DeviceExtension->HubConfigDescriptor.wTotalLength %x\n", DeviceExtension->HubConfigDescriptor.wTotalLength); Status = DeviceExtension->HubInterface.GetExtendedHubInformation(DeviceExtension->RootHubPdo, DeviceExtension->RootHubPdo, &DeviceExtension->UsbExtHubInfo, sizeof(USB_EXTHUB_INFORMATION_0), &Result); if (!NT_SUCCESS(Status)) { DPRINT1("Usbhub: Failed to extended hub information. Unable to determine the number of ports!\n"); ASSERT(FALSE); } DPRINT1("DeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", DeviceExtension->UsbExtHubInfo.NumberOfPorts); UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_DEVICE, sizeof(Urb->UrbControlVendorClassRequest), USBD_TRANSFER_DIRECTION_IN, 0, USB_DEVICE_CLASS_RESERVED, 0, 0, &DeviceExtension->HubDescriptor, NULL, sizeof(USB_HUB_DESCRIPTOR), NULL); Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice; Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); DPRINT1("bDescriptorType %x\n", DeviceExtension->HubDescriptor.bDescriptorType); /* Select the configuration */ /* Get the first one */ Pid = USBD_ParseConfigurationDescriptorEx(&DeviceExtension->HubConfigDescriptor, &DeviceExtension->HubConfigDescriptor, -1, -1, -1, -1, -1); ASSERT(Pid != NULL); InterfaceList[0].InterfaceDescriptor = Pid; ConfigUrb = USBD_CreateConfigurationRequestEx(&DeviceExtension->HubConfigDescriptor, (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList); ASSERT(ConfigUrb != NULL); Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, ConfigUrb, NULL); DeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle; DeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle; DPRINT1("Configuration Handle %x\n", DeviceExtension->ConfigurationHandle); ExFreePool(ConfigUrb); Status = DeviceExtension->HubInterface.Initialize20Hub(DeviceExtension->RootHubPdo, DeviceExtension->RootHubUsbDevice, 1); DPRINT1("Status %x\n", Status); { int PortLoop; USHORT PortStatusAndChange[2]; for (PortLoop=0; PortLoop< DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++) { DPRINT1("Port %x\n", PortLoop); UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_OTHER, sizeof(Urb->UrbControlVendorClassRequest), USBD_TRANSFER_DIRECTION_IN, 0, USB_REQUEST_SET_FEATURE, PORT_POWER, 1, 0, 0, 0, 0); Urb->UrbOSFeatureDescriptorRequest.MS_FeatureDescriptorIndex = PortLoop + 1; Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); DPRINT1("Status %x\n", Status); UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_OTHER, sizeof(Urb->UrbControlVendorClassRequest), USBD_TRANSFER_DIRECTION_OUT, 0, USB_REQUEST_GET_STATUS, 0, PortLoop + 1, &PortStatusAndChange, 0, sizeof(PortStatusAndChange), 0); Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL); DPRINT1("Status %x\n", Status); DPRINT1("PortStatus = %x\n", PortStatusAndChange[0]); DPRINT1("PortChange = %x\n", PortStatusAndChange[1]); } } ExFreePool(Urb); break; } case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */ { switch (IrpSp->Parameters.QueryDeviceRelations.Type) { case BusRelations: { PDEVICE_RELATIONS DeviceRelations = NULL; DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); Status = UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations); Information = (ULONG_PTR)DeviceRelations; break; } case RemovalRelations: { DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); } default: DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", IrpSp->Parameters.QueryDeviceRelations.Type); return ForwardIrpAndForget(DeviceObject, Irp); } break; } case IRP_MN_QUERY_BUS_INFORMATION: { DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n"); break; } case IRP_MN_QUERY_ID: { DPRINT1("IRP_MN_QUERY_ID\n"); break; } case IRP_MN_QUERY_CAPABILITIES: { DPRINT1("IRP_MN_QUERY_CAPABILITIES\n"); break; } default: { DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } } Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
static NTSTATUS NTAPI ClassDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { //PCLASS_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status = STATUS_NOT_SUPPORTED; TRACE_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL\n"); if (!((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsClassDO) return ForwardIrpAndForget(DeviceObject, Irp); //DeviceExtension = (PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; switch (IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: case IOCTL_KEYBOARD_QUERY_INDICATORS: case IOCTL_KEYBOARD_QUERY_TYPEMATIC: { /* FIXME: We hope that all devices will return the same result. * Ask only the first one */ PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; if (Head->Flink != Head) { /* We have at least one device */ PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Head->Flink, PORT_DEVICE_EXTENSION, ListEntry); IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->DeviceObject, Irp); } break; } case IOCTL_KEYBOARD_SET_INDICATORS: case IOCTL_KEYBOARD_SET_TYPEMATIC: /* not in MSDN, would seem logical */ { /* Send it to all associated Port devices */ PLIST_ENTRY Head = &((PCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ListHead; PLIST_ENTRY Entry = Head->Flink; Status = STATUS_SUCCESS; while (Entry != Head) { PPORT_DEVICE_EXTENSION DevExt = CONTAINING_RECORD(Entry, PORT_DEVICE_EXTENSION, ListEntry); NTSTATUS IntermediateStatus; IoGetCurrentIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; IntermediateStatus = ForwardIrpAndWait(DevExt->DeviceObject, Irp); if (!NT_SUCCESS(IntermediateStatus)) Status = IntermediateStatus; Entry = Entry->Flink; } break; } default: WARN_(CLASS_NAME, "IRP_MJ_DEVICE_CONTROL / unknown I/O control code 0x%lx\n", IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode); ASSERT(FALSE); break; } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }