📄 usb.cpp
字号:
if(tmp)ExFreePool(tmp);
if(urb)ExFreePool(urb);
return status;
}
NTSTATUS UsbDeselectConfiguration(IN PWDMUSB_DEVICE_EXTENSION dx)
{
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;
}
UsbBuildSelectConfigurationRequest(urb,UrbSize,NULL);
KdPrint(("Deselecting Configuration"));
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;
}
ExFreePool(urb);
return status;
}
NTSTATUS UsbBuildPipeList(IN PWDMUSB_DEVICE_EXTENSION dx)
{
ULONG i;
WCHAR Name[]=L"\\PIPE00";
PUSBD_INTERFACE_INFORMATION Interface=dx->Interface;
KdPrint(("usbBuildPipeList"));
for(i=0;i<WDMUSB_MAX_PIPES;i++)
{
Name[6]='X';
RtlCopyMemory(dx->PipeList[i].Name,Name,sizeof(Name));
}
for(i=0;i<Interface->NumberOfPipes;i++)
{
Name[6]='0'+(USHORT)i;
RtlCopyMemory(dx->PipeList[i].Name,Name,sizeof(Name));
dx->PipeList[i].PipeInfo=&Interface->Pipes[i];
dx->PipeList[i].Opened=FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS UsbReadWriteRegister(IN PWDMUSB_DEVICE_EXTENSION dx,
IN PIRP Irp,IN BOOLEAN bWrite,
OUT ULONG& TranslatedSize)
{
KdPrint(("UsbReadWriteRegister starting"));
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
PVOID IoBuffer=Irp->AssociatedIrp.SystemBuffer;
PIO_BLOCK IoBlock=(PIO_BLOCK)IoBuffer;
ULONG InputBufferLength=IrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputBufferLength=IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
if((IoBuffer==NULL)||(InputBufferLength==0))
{
KdPrint(("UsbReadWriteRegister Error:IoBuffer:%x|inputBuflen:%d|outputbuflen:%d",
IoBuffer,InputBufferLength,OutputBufferLength));
return CompleteIrp(Irp,STATUS_INVALID_PARAMETER,0);
}
ULONG size=sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
PURB urb=(PURB)ExAllocatePool(NonPagedPool,size);
KdPrint(("UsbReadWriteRegister:IoBuffer=%p, wIndex= %x, wLength=%lx, wValue=%x",
IoBlock->pbyData,IoBlock->uIndex,IoBlock->uLength,IoBlock->uOffset));
if(bWrite)
{
UsbBuildVendorRequest(urb,
URB_FUNCTION_VENDOR_DEVICE,
(USHORT)size,
0,
0x0,
0x0C,
IoBlock->uOffset,
IoBlock->uIndex,
IoBlock->pbyData,
NULL,
IoBlock->uLength,
NULL);
}
else
{
UsbBuildVendorRequest(urb,
URB_FUNCTION_VENDOR_DEVICE,
(USHORT)size,
USBD_TRANSFER_DIRECTION_IN,
0x0,
0x0C,
IoBlock->uOffset,
IoBlock->uIndex,
IoBuffer,
NULL,
IoBlock->uLength,
NULL);
}
NTSTATUS status=CallUSBDI(dx,urb);
if(NT_SUCCESS(status))
{
if(bWrite)TranslatedSize=IoBlock->uLength;
else TranslatedSize=urb->UrbControlVendorClassRequest.TransferBufferLength;
}
ExFreePool(urb);
KdPrint(("UsbReadWriteRegister exit"));
return status;
}
//----------------------------Routines End-------------------------------------
NTSTATUS CallUSBDI(IN PWDMUSB_DEVICE_EXTENSION dx,IN PVOID UrbEtc,
IN ULONG IoControlCode,
IN ULONG Arg2)
{
IO_STATUS_BLOCK IoStatus;
KEVENT event;
KeInitializeEvent(&event,NotificationEvent,FALSE);
PIRP Irp=IoBuildDeviceIoControlRequest(IoControlCode,
dx->NextStackDevice,
NULL,
0,
NULL,
0,
TRUE,
&event,
&IoStatus);
PIO_STACK_LOCATION NextIrpStack=IoGetNextIrpStackLocation(Irp);
NextIrpStack->Parameters.Others.Argument1=UrbEtc;
NextIrpStack->Parameters.Others.Argument2=(PVOID)Arg2;
NTSTATUS status=IoCallDriver(dx->NextStackDevice,Irp);
if(status==STATUS_PENDING)
{
KdPrint(("CallUSBDI: wait for URB completion"));
status=KeWaitForSingleObject(&event,Suspended,KernelMode,FALSE,NULL);
status=IoStatus.Status;
}
KdPrint(("CallUSBDI returned %x",status));
return status;
}
//-----------------------usb read and write------------------------------
NTSTATUS UsbReadWriteCompletion(IN PDEVICE_OBJECT fdo,PIRP Irp,PWDMUSB_RW_CONTEXT ctx)
{
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
BOOLEAN read=(ctx->urb->UrbBulkOrInterruptTransfer.TransferFlags&
USBD_TRANSFER_DIRECTION_IN)!=0;
ctx->numxfer+=ctx->urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
NTSTATUS status=Irp->IoStatus.Status;
if(NT_SUCCESS(status)&&ctx->length)
{
ULONG seglen=ctx->length;
if(seglen>WDMUSB_MAX_TRANSFER_SIZE)
seglen=WDMUSB_MAX_TRANSFER_SIZE;//(ULONG_PTR)PAGE_ALIGN(ctx->va)+PAGE_SIZE-ctx->va;
IoBuildPartialMdl(Irp->MdlAddress,ctx->Mdl,(PVOID)ctx->va,seglen);
ctx->urb->UrbBulkOrInterruptTransfer.TransferBufferLength=seglen;
PIO_STACK_LOCATION NextStack=IoGetNextIrpStackLocation(Irp);
NextStack->MajorFunction=IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1=(PVOID)(PURB)ctx->urb;
NextStack->Parameters.DeviceIoControl.IoControlCode=IOCTL_INTERNAL_USB_SUBMIT_URB;
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)UsbReadWriteCompletion,
(PVOID)ctx,
TRUE,
TRUE,
TRUE);
ctx->va+=seglen;
ctx->length-=seglen;
IoCallDriver(dx->NextStackDevice,Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
if(NT_SUCCESS(status))
Irp->IoStatus.Information=ctx->numxfer;
ExFreePool(ctx->urb);
IoFreeMdl(ctx->Mdl);
ExFreePool(ctx);
UnlockDevice(dx);
return status;
}
NTSTATUS UsbReadWrite(IN PDEVICE_OBJECT fdo,PIRP Irp,BOOLEAN read)
{
NTSTATUS status=STATUS_SUCCESS;
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
if(dx->IODisabled)
return CompleteIrp(Irp,STATUS_DEVICE_NOT_CONNECTED,0);
if(!LockDevice(dx))
return CompleteIrp(Irp,STATUS_DELETE_PENDING,0);
status=PowerUpDevice(fdo);
if(!NT_SUCCESS(status))
return CompleteIrp(Irp,status,0);
PWDMUSB_PIPE hpipe;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT fileObject=IrpStack->FileObject;
if(fileObject&&fileObject->FsContext)
{
hpipe=(PWDMUSB_PIPE)fileObject->FsContext;
if((hpipe->PipeInfo->PipeType!=UsbdPipeTypeInterrupt)&&
(hpipe->PipeInfo->PipeType!=UsbdPipeTypeBulk))
{
UnlockDevice(dx);
return CompleteIrp(Irp,STATUS_INVALID_HANDLE,0);
}
}
ULONG length=Irp->MdlAddress?MmGetMdlByteCount(Irp->MdlAddress):0;
if(length>WDMUSB_BOARD_TRANSFER_SIZE)
{
UnlockDevice(dx);
return CompleteIrp(Irp,STATUS_INVALID_PARAMETER,0);
}
if(!length)
{
UnlockDevice(dx);
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
PWDMUSB_RW_CONTEXT ctx=(PWDMUSB_RW_CONTEXT)ExAllocatePool(NonPagedPool,
sizeof(WDMUSB_RW_CONTEXT));
if(ctx==NULL)
{
UnlockDevice(dx);
return CompleteIrp(Irp,STATUS_INSUFFICIENT_RESOURCES,0);
}
RtlZeroMemory(ctx,sizeof(WDMUSB_RW_CONTEXT));
ULONG_PTR va=(ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress);
ULONG urbflage=USBD_SHORT_TRANSFER_OK;
urbflage=(read?USBD_TRANSFER_DIRECTION_IN:USBD_TRANSFER_DIRECTION_OUT);
ULONG seglen=length;
if(seglen>WDMUSB_MAX_TRANSFER_SIZE)
seglen=WDMUSB_MAX_TRANSFER_SIZE;//(ULONG_PTR)PAGE_ALIGN(va)+PAGE_SIZE-va;
PMDL mdl=IoAllocateMdl((PVOID)va,length,FALSE,FALSE,NULL);
if(mdl==NULL)
{
ExFreePool(ctx);
UnlockDevice(dx);
return CompleteIrp(Irp,STATUS_INSUFFICIENT_RESOURCES,0);
}
IoBuildPartialMdl(Irp->MdlAddress,mdl,(PVOID)va,seglen);
PURB urb=(PURB)ExAllocatePool(NonPagedPool,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
if(urb==NULL)
{
ExFreePool(ctx);
IoFreeMdl(mdl);
UnlockDevice(dx);
return CompleteIrp(Irp,STATUS_INSUFFICIENT_RESOURCES,0);
}
UsbBuildInterruptOrBulkTransferRequest(urb,
sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER),
hpipe->PipeInfo->PipeHandle,
NULL,
mdl,
seglen,
urbflage,
NULL);
ctx->urb=urb;
ctx->va=va+seglen;
ctx->length=length-seglen;
ctx->Mdl=mdl;
ctx->numxfer=0;
PIO_STACK_LOCATION NextStack=IoGetNextIrpStackLocation(Irp);
NextStack->MajorFunction=IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1=(PVOID)(PURB)urb;
NextStack->Parameters.DeviceIoControl.IoControlCode=IOCTL_INTERNAL_USB_SUBMIT_URB;
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)UsbReadWriteCompletion,
(PVOID)ctx,
TRUE,
TRUE,
TRUE);
IoMarkIrpPending(Irp);
status=IoCallDriver(dx->NextStackDevice,Irp);
if(!NT_SUCCESS(status))
{
if((status!=STATUS_CANCELLED)&&(status!=STATUS_DEVICE_NOT_CONNECTED))
{
status=UsbResetPipe(dx,hpipe);
if(!NT_SUCCESS(status))
status=UsbResetDevice(dx);
}
}
return STATUS_PENDING;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -