📄 intpnp.c
字号:
// Read the first configuration descriptor
// This requires two steps:
// 1. Read the fixed sized configuration desciptor (CD)
// 2. Read the CD with all embedded interface and endpoint descriptors
//
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if(urb) {
siz = sizeof(USB_CONFIGURATION_DESCRIPTOR);
configurationDescriptor = ExAllocatePool(NonPagedPool, siz);
if(configurationDescriptor) {
UsbBuildGetDescriptorRequest(
urb,
(USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
sizeof(USB_CONFIGURATION_DESCRIPTOR),
NULL);
ntStatus = CallUSBD(DeviceObject, urb);
if(!NT_SUCCESS(ntStatus)) {
KdPrint( ("UsbBuildGetDescriptorRequest failed\n"));
goto ConfigureDevice_Exit;
}
}
else {
KdPrint( ("Failed to allocate mem for config Descriptor\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ConfigureDevice_Exit;
}
siz = configurationDescriptor->wTotalLength;
ExFreePool(configurationDescriptor);
configurationDescriptor = ExAllocatePool(NonPagedPool, siz);
if(configurationDescriptor) {
UsbBuildGetDescriptorRequest(
urb,
(USHORT)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
configurationDescriptor,
NULL,
siz,
NULL);
ntStatus = CallUSBD(DeviceObject, urb);
if(!NT_SUCCESS(ntStatus)) {
KdPrint(("Failed to read configuration descriptor"));
goto ConfigureDevice_Exit;
}
}
else {
KdPrint( ("Failed to alloc mem for config Descriptor\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ConfigureDevice_Exit;
}
}
else {
KdPrint( ("Failed to allocate memory for urb\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ConfigureDevice_Exit;
}
if(configurationDescriptor) {
//
// save a copy of configurationDescriptor in deviceExtension
// remember to free it later.
//
deviceExtension->UsbConfigurationDescriptor = configurationDescriptor;
if(configurationDescriptor->bmAttributes & REMOTE_WAKEUP_MASK)
{
//
// this configuration supports remote wakeup
//
deviceExtension->WaitWakeEnable = 1;
}
else
{
deviceExtension->WaitWakeEnable = 0;
}
ntStatus = SelectInterfaces(DeviceObject, configurationDescriptor);
}
else {
deviceExtension->UsbConfigurationDescriptor = NULL;
}
ConfigureDevice_Exit:
if(urb) {
ExFreePool(urb);
}
return ntStatus;
}
NTSTATUS
SelectInterfaces(
IN PDEVICE_OBJECT DeviceObject,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
/*++
Routine Description:
This helper routine selects the configuration
Arguments:
DeviceObject - pointer to device object
ConfigurationDescriptor - pointer to the configuration
descriptor for the device
Return Value:
NT status value
--*/
{
LONG numberOfInterfaces,
interfaceNumber,
interfaceindex;
ULONG i;
PURB urb;
PUCHAR pInf;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor;
PUSBD_INTERFACE_LIST_ENTRY interfaceList,
tmp;
PUSBD_INTERFACE_INFORMATION Interface;
//
// initialize the variables
//
urb = NULL;
Interface = NULL;
interfaceDescriptor = NULL;
deviceExtension = DeviceObject->DeviceExtension;
numberOfInterfaces = ConfigurationDescriptor->bNumInterfaces;
interfaceindex = interfaceNumber = 0;
//
// Parse the configuration descriptor for the interface;
//
tmp = interfaceList =
ExAllocatePool(
NonPagedPool,
sizeof(USBD_INTERFACE_LIST_ENTRY) * (numberOfInterfaces + 1));
if(!tmp) {
KdPrint( ("Failed to allocate mem for interfaceList\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
while(interfaceNumber < numberOfInterfaces) {
// We're using the non Ex extension version for Windows 98 compatibility
interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
ConfigurationDescriptor,
ConfigurationDescriptor,
interfaceindex,
0, -1, -1, -1);
//interfaceDescriptor = USBD_ParseConfigurationDescriptor(
// ConfigurationDescriptor,
// ConfigurationDescriptor,
// interfaceindex,
// 0, -1, -1, -1);
if(interfaceDescriptor) {
interfaceList->InterfaceDescriptor = interfaceDescriptor;
interfaceList->Interface = NULL;
interfaceList++;
interfaceNumber++;
}
interfaceindex++;
}
interfaceList->InterfaceDescriptor = NULL;
interfaceList->Interface = NULL;
// We're using the non Ex extension version for Windows 98 compatibility
urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, tmp);
//urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, tmp);
if(urb) {
Interface = &urb->UrbSelectConfiguration.Interface;
for(i=0; i<Interface->NumberOfPipes; i++) {
//
// perform pipe initialization here
// set the transfer size and any pipe flags we use
// USBD sets the rest of the Interface struct members
//
Interface->Pipes[i].MaximumTransferSize =
USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
}
ntStatus = CallUSBD(DeviceObject, urb);
if(NT_SUCCESS(ntStatus)) {
//
// save a copy of interface information in the device extension.
//
deviceExtension->UsbInterface = ExAllocatePool(NonPagedPool,
Interface->Length);
if(deviceExtension->UsbInterface) {
RtlCopyMemory(deviceExtension->UsbInterface,
Interface,
Interface->Length);
}
else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
KdPrint( ("memory alloc for UsbInterface failed\n"));
}
//
// Dump the interface to the debugger
//
Interface = &urb->UrbSelectConfiguration.Interface;
KdPrint( ("---------\n"));
KdPrint( ("NumberOfPipes 0x%x\n",
Interface->NumberOfPipes));
KdPrint( ("Length 0x%x\n",
Interface->Length));
KdPrint( ("Alt Setting 0x%x\n",
Interface->AlternateSetting));
KdPrint( ("Interface Number 0x%x\n",
Interface->InterfaceNumber));
KdPrint( ("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
Interface->Class,
Interface->SubClass,
Interface->Protocol));
//
// Initialize the PipeContext
// Dump the pipe info
//
deviceExtension->PipeContext = ExAllocatePool(
NonPagedPool,
Interface->NumberOfPipes *
sizeof(INTUSB_PIPE_CONTEXT));
if(deviceExtension->PipeContext) {
for(i=0; i<Interface->NumberOfPipes; i++) {
deviceExtension->PipeContext[i].PipeOpen = FALSE;
}
}
else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
KdPrint( ("memory alloc for UsbInterface failed\n"));
}
for(i=0; i<Interface->NumberOfPipes; i++) {
KdPrint( ("---------\n"));
KdPrint( ("PipeType 0x%x\n",
Interface->Pipes[i].PipeType));
KdPrint( ("EndpointAddress 0x%x\n",
Interface->Pipes[i].EndpointAddress));
KdPrint( ("MaxPacketSize 0x%x\n",
Interface->Pipes[i].MaximumPacketSize));
KdPrint( ("Interval 0x%x\n",
Interface->Pipes[i].Interval));
KdPrint( ("Handle 0x%x\n",
Interface->Pipes[i].PipeHandle));
KdPrint( ("MaximumTransferSize 0x%x\n",
Interface->Pipes[i].MaximumTransferSize));
}
KdPrint( ("---------\n"));
}
else {
KdPrint( ("Failed to select an interface\n"));
}
}
else {
KdPrint( ("USBD_CreateConfigurationRequestEx failed\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if(tmp) {
ExFreePool(tmp);
}
if(urb) {
ExFreePool(urb);
}
return ntStatus;
}
NTSTATUS
DeconfigureDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine is invoked when the device is removed or stopped.
This routine de-configures the usb device.
Arguments:
DeviceObject - pointer to device object
Return Value:
NT status value
--*/
{
PURB urb;
ULONG siz;
NTSTATUS ntStatus;
//
// initialize variables
//
siz = sizeof(struct _URB_SELECT_CONFIGURATION);
urb = ExAllocatePool(NonPagedPool, siz);
if(urb) {
UsbBuildSelectConfigurationRequest(urb, (USHORT)siz, NULL);
ntStatus = CallUSBD(DeviceObject, urb);
if(!NT_SUCCESS(ntStatus)) {
KdPrint( ("Failed to deconfigure device\n"));
}
ExFreePool(urb);
}
else {
KdPrint( ("Failed to allocate urb\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
return ntStatus;
}
NTSTATUS
CallUSBD(
IN PDEVICE_OBJECT DeviceObject,
IN PURB Urb
)
/*++
Routine Description:
This routine synchronously submits an urb down the stack.
Arguments:
DeviceObject - pointer to device object
Urb - USB request block
Return Value:
--*/
{
PIRP irp;
KEVENT event;
NTSTATUS ntStatus;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;
PDEVICE_EXTENSION deviceExtension;
//
// initialize the variables
//
irp = NULL;
deviceExtension = DeviceObject->DeviceExtension;
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
deviceExtension->TopOfStackDeviceObject,
NULL,
0,
NULL,
0,
TRUE,
&event,
&ioStatus);
if(!irp) {
KdPrint( ("IoBuildDeviceIoControlRequest failed\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
nextStack = IoGetNextIrpStackLocation(irp);
ASSERT(nextStack != NULL);
nextStack->Parameters.Others.Argument1 = Urb;
KdPrint( ("CallUSBD::"));
IntUsb_IoIncrement(deviceExtension);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
if(ntStatus == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
ntStatus = ioStatus.Status;
}
KdPrint( ("CallUSBD::"));
IntUsb_IoDecrement(deviceExtension);
return ntStatus;
}
NTSTATUS
HandleQueryStopDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine services the Irps of minor type IRP_MN_QUERY_STOP_DEVICE
Arguments:
DeviceObject - pointer to device object
Irp - I/O request packet sent by the pnp manager.
Return Value:
NT status value
--*/
{
KIRQL oldIrql;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -