📄 usb.cpp
字号:
#include "WdmUsb.h"
#include "Ioctl.h"
//------------------------Define---------------------------------------
NTSTATUS CallUSBDI(IN PWDMUSB_DEVICE_EXTENSION dx,IN PVOID UrbEtc,
IN ULONG IoControlCode=IOCTL_INTERNAL_USB_SUBMIT_URB,
IN ULONG Arg2=0);
//-----------------------Routines---------------------------------------
NTSTATUS UsbGetPortStatus(IN PWDMUSB_DEVICE_EXTENSION dx,OUT ULONG& PortStatus)
{
KdPrint(("Getting port status"));
PortStatus=0;
NTSTATUS status=CallUSBDI(dx,&PortStatus,IOCTL_INTERNAL_USB_GET_PORT_STATUS);
KdPrint(("Got Port status %x",PortStatus));
return status;
}
NTSTATUS UsbResetPort(IN PWDMUSB_DEVICE_EXTENSION dx)
{
KdPrint(("Reset Port"));
NTSTATUS status=CallUSBDI(dx,NULL,IOCTL_INTERNAL_USB_RESET_PORT);
KdPrint(("Port reset %x",status));
return status;
}
NTSTATUS UsbResetPipe(IN PWDMUSB_DEVICE_EXTENSION dx,IN PWDMUSB_PIPE Pipe)
{
KdPrint(("Reset Pipe"));
PURB urb=(PURB)ExAllocatePool(NonPagedPool,sizeof(struct _URB_PIPE_REQUEST));
if(urb==NULL)
{
KdPrint(("No URB memory"));
return STATUS_INSUFFICIENT_RESOURCES;
}
urb->UrbHeader.Length=(USHORT)sizeof(struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function=URB_FUNCTION_RESET_PIPE;
urb->UrbPipeRequest.PipeHandle=Pipe->PipeInfo->PipeHandle;
NTSTATUS status=CallUSBDI(dx,urb);
ExFreePool(urb);
return status;
}
NTSTATUS UsbResetDevice(IN PWDMUSB_DEVICE_EXTENSION dx)
{
ULONG PortStatus;
NTSTATUS status=UsbGetPortStatus(dx,PortStatus);
if(!NT_SUCCESS(status))
return status;
if(!(PortStatus&USBD_PORT_CONNECTED))
return STATUS_NO_SUCH_DEVICE;
if(PortStatus&USBD_PORT_ENABLED)
return status;
status=UsbResetPort(dx);
if(!NT_SUCCESS(status))
return status;
status=UsbGetPortStatus(dx,PortStatus);
if(!NT_SUCCESS(status))
return status;
if(!(PortStatus&USBD_PORT_CONNECTED)||!(PortStatus&USBD_PORT_ENABLED))
return STATUS_NO_SUCH_DEVICE;
return status;
}
NTSTATUS UsbConfigureDevice(IN PWDMUSB_DEVICE_EXTENSION dx)
{
UsbResetDevice(dx);
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
ULONG size;
NTSTATUS status=UsbGetDeviceDescriptor(dx,DeviceDescriptor,size);
if(!NT_SUCCESS(status))
{
KdPrint(("UsbConfigureDevice UsbGetDeviceDescriptor fail"));
return status;
}
if(dx->DeviceDescriptor)ExFreePool(dx->DeviceDescriptor);
dx->DeviceDescriptor=DeviceDescriptor;
KdPrint(("UsbConfigureDevice DeviceDescriptor size:%x",size));
status=UsbSelectConfiguration(dx);
if(!NT_SUCCESS(status))
{
ExFreePool(dx->DeviceDescriptor);
KdPrint(("UsbConfigureDevice UsbSelectConfiguration fail"));
return status;
}
UsbBuildPipeList(dx);
KdPrint(("UsbConfigureDevice UsbSelectConfiguration success"));
return status;
}
NTSTATUS UsbReconfigureDevice(IN PWDMUSB_DEVICE_EXTENSION dx)
{
KdPrint(("UsbReconfigureDevice"));
return UsbConfigureDevice(dx);
}
NTSTATUS UsbGetDeviceDescriptor(IN PWDMUSB_DEVICE_EXTENSION dx,
OUT PUSB_DEVICE_DESCRIPTOR& deviceDescriptor,
OUT ULONG& Size)
{
USHORT UrbSize=sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
PURB urb=(PURB)ExAllocatePool(NonPagedPool,UrbSize);
if(urb==NULL)
{
KdPrint(("No URB memory"));
return STATUS_INSUFFICIENT_RESOURCES;
}
ULONG sizeDescriptor=sizeof(USB_DEVICE_DESCRIPTOR);
deviceDescriptor=(PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool,sizeDescriptor);
if(deviceDescriptor==NULL)
{
ExFreePool(urb);
KdPrint(("No descriptor memory"));
return STATUS_INSUFFICIENT_RESOURCES;
}
UsbBuildGetDescriptorRequest(urb,
UrbSize,
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0,
deviceDescriptor,
NULL,
sizeDescriptor,
NULL);
KdPrint(("Getting device descriptor"));
NTSTATUS status=CallUSBDI(dx,urb);
if(!NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
{
KdPrint(("status %x URB status x",status,urb->UrbHeader.Status));
status=STATUS_UNSUCCESSFUL;
}
Size=urb->UrbControlDescriptorRequest.TransferBufferLength;
ExFreePool(urb);
return status;
}
NTSTATUS UsbGetConfigurationDescriptors(IN PWDMUSB_DEVICE_EXTENSION dx,
OUT PUSB_CONFIGURATION_DESCRIPTOR& descriptors,
IN UCHAR ConfigIndex,
OUT ULONG& DescriptorsSize)
{
NTSTATUS status;
USHORT UrbSize=sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
PURB urb=(PURB)ExAllocatePool(NonPagedPool,UrbSize);
if(urb==NULL)
{
KdPrint(("No URB memory"));
return STATUS_INSUFFICIENT_RESOURCES;
}
DescriptorsSize=sizeof(USB_CONFIGURATION_DESCRIPTOR);
descriptors=(PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePool(NonPagedPool,
DescriptorsSize+16);
if(descriptors==NULL)
{
KdPrint(("No Initial descriptor memory"));
status=STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
UsbBuildGetDescriptorRequest(urb,
UrbSize,
USB_CONFIGURATION_DESCRIPTOR_TYPE,
ConfigIndex,
0,
descriptors,
NULL,
DescriptorsSize,
NULL);
KdPrint(("Getting Base configuration descriptor"));
status=CallUSBDI(dx,urb);
if(!NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
{
KdPrint(("status %x URB status x",status,urb->UrbHeader.Status));
ExFreePool(descriptors);
status=STATUS_UNSUCCESSFUL;
goto fail;
}
KdPrint(("Got basic config descr. MaxPower %d units of 2mA",descriptors->MaxPower));
DescriptorsSize=descriptors->wTotalLength;
ExFreePool(descriptors);
descriptors=(PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePool(NonPagedPool,
DescriptorsSize+16);
if(descriptors==NULL)
{
KdPrint(("No full descriptor memory"));
status=STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
UsbBuildGetDescriptorRequest(urb,
UrbSize,
USB_CONFIGURATION_DESCRIPTOR_TYPE,
ConfigIndex,
0,
descriptors,
NULL,
DescriptorsSize,
NULL);
KdPrint(("Getting full descriptor memory"));
status=CallUSBDI(dx,urb);
if(!NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
{
KdPrint(("status %x URB status x",status,urb->UrbHeader.Status));
ExFreePool(descriptors);
status=STATUS_UNSUCCESSFUL;
goto fail;
}
DescriptorsSize=urb->UrbControlDescriptorRequest.TransferBufferLength;
fail:
ExFreePool(urb);
return status;
}
NTSTATUS UsbSelectConfiguration(IN PWDMUSB_DEVICE_EXTENSION dx)
{
LONG numberOfInterfaces,interfaceNumber,interfaceIndex;
PUSBD_INTERFACE_LIST_ENTRY interfaceList,tmp;
PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor=NULL;
PUSBD_INTERFACE_INFORMATION Interface=NULL;
PUSB_CONFIGURATION_DESCRIPTOR Descriptors=NULL;
dx->Configurationhandle=NULL;
ULONG size;
NTSTATUS status=UsbGetConfigurationDescriptors(dx,Descriptors,0,size);
if(!NT_SUCCESS(status))
{
KdPrint(("UsbGetConfigurationDescriptors faild &%x",status));
FreeIfAllocated(Descriptors);
return status;
}
numberOfInterfaces=Descriptors->bNumInterfaces;
interfaceIndex=interfaceNumber=0;
tmp=interfaceList=(PUSBD_INTERFACE_LIST_ENTRY)ExAllocatePool(NonPagedPool,
sizeof(USBD_INTERFACE_LIST_ENTRY)*(numberOfInterfaces+1));
if(tmp==NULL)
{
FreeIfAllocated(Descriptors);
return STATUS_INSUFFICIENT_RESOURCES;
}
while(interfaceNumber<numberOfInterfaces)
{
interfaceDescriptor=USBD_ParseConfigurationDescriptorEx(Descriptors,
Descriptors,
interfaceIndex,
0,-1,-1,-1);
if(interfaceDescriptor)
{
interfaceList->InterfaceDescriptor=interfaceDescriptor;
interfaceList->Interface=NULL;
interfaceList++;
interfaceNumber++;
}
interfaceIndex++;
}
interfaceList->InterfaceDescriptor=NULL;
interfaceList->Interface=NULL;
PURB urb=USBD_CreateConfigurationRequestEx(Descriptors,tmp);
if(urb)
{
Interface=&urb->UrbSelectConfiguration.Interface;
for(ULONG i=0;i<Interface->NumberOfPipes;i++)
Interface->Pipes[i].MaximumTransferSize=64*1024-1;
status=CallUSBDI(dx,urb);
if(NT_SUCCESS(status))
{
dx->Configurationhandle=urb->UrbSelectConfiguration.ConfigurationHandle;
if(dx->Interface!=NULL)ExFreePool(dx->Interface);
dx->Interface=(PUSBD_INTERFACE_INFORMATION)ExAllocatePool(NonPagedPool,
Interface->Length);
if(dx->Interface)
{
RtlCopyMemory(dx->Interface,Interface,Interface->Length);
#if DBG//////////////////start_DbgPrint/////////////////////////
DbgPrint("USBD12.SYS:-------------------\n");
DbgPrint("USBD12.SYS:NumberOfPipes 0x%x\n", dx->Interface->NumberOfPipes);
DbgPrint("USBD12.SYS:Length 0x%x\n", dx->Interface->Length);
DbgPrint("USBD12.SYS:Alt Setting 0x%x\n", dx->Interface->AlternateSetting);
DbgPrint("USBD12.SYS:Interface Number 0x%x\n", dx->Interface->InterfaceNumber);
DbgPrint("USBD12.SYS:Class, subclass, protocol 0x%x 0x%x 0x%x\n",dx->Interface->Class,
dx->Interface->SubClass,
dx->Interface->Protocol);
for (ULONG j=0; j<Interface->NumberOfPipes; j++)
{
PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &dx->Interface->Pipes[j];
DbgPrint("USBD12.SYS: ---------\n");
DbgPrint("USBD12.SYS:PipeType 0x%x\n", pipeInformation->PipeType);
DbgPrint("USBD12.SYS:EndpointAddress 0x%x\n", pipeInformation->EndpointAddress);
DbgPrint("USBD12.SYS:MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize);
DbgPrint("USBD12.SYS:Interval 0x%x\n", pipeInformation->Interval);//interval时间间隔10ms
DbgPrint("USBD12.SYS:Handle 0x%x\n", pipeInformation->PipeHandle);
DbgPrint("USBD12.SYS:MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize);
}
DbgPrint("USBD12.SYS: ---------\n");
#endif //////////////////end_DbgPrint///////////////////////////
}
else status=STATUS_INSUFFICIENT_RESOURCES;
}
}
else status=STATUS_INSUFFICIENT_RESOURCES;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -