⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb.cpp

📁 一个通用的usb驱动程序列程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -