www.pudn.com > data-bulktransfer.rar > TestDispatch.c


#include "usbdriver.h" 
 
ULONG UsbGetCurrentFrameNumber(IN PDEVICE_OBJECT fdo); 
ULONG UsbGetDeviceDescriptor(IN PDEVICE_OBJECT fdo, 
							 PVOID pvOutputBuffer); 
ULONG UsbGetStringDescriptor(IN PDEVICE_OBJECT fdo, 
                             UCHAR             Index, 
                             USHORT            LanguageId, 
                             PVOID             pvOutputBuffer, 
                             ULONG             ulLength); 
ULONG UsbGetConfigDescriptor(IN PDEVICE_OBJECT fdo, 
                             PVOID   pvOutputBuffer, 
                             ULONG   ulLength); 
NTSTATUS Bulk_Read_Write(IN  PDEVICE_OBJECT fdo,IN  PIRP Irp); 
NTSTATUS UsbResetPipe(IN PDEVICE_OBJECT fdo, ULONG PipeNum); 
NTSTATUS UsbAbortPipe(IN PDEVICE_OBJECT fdo, IN USBD_PIPE_HANDLE PipeHandle); 
// 
NTSTATUS TestCreate(IN PDEVICE_OBJECT fdo, IN PIRP Irp) 
{ 
	NTSTATUS ntStatus=STATUS_SUCCESS; 
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension; 
 
    pdx->OpenHandles++; 
							 
    Irp->IoStatus.Status = STATUS_SUCCESS; 
    Irp->IoStatus.Information = 0; 
    IoCompleteRequest (Irp, IO_NO_INCREMENT); 
    return ntStatus; 
} 
// 
NTSTATUS TestClose(IN PDEVICE_OBJECT fdo, IN PIRP Irp) 
{ 
   NTSTATUS ntStatus=STATUS_SUCCESS; 
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension; 
 
   pdx->OpenHandles--; 
 
   Irp->IoStatus.Status = STATUS_SUCCESS; 
   Irp->IoStatus.Information = 0; 
   IoCompleteRequest (Irp, IO_NO_INCREMENT); 
   return ntStatus; 
} 
// 
NTSTATUS TestIOCTL(IN PDEVICE_OBJECT fdo,IN PIRP Irp) 
{ 
	NTSTATUS ntStatus; 
	PIO_STACK_LOCATION IrpStack; 
    PDEVICE_EXTENSION pdx; 
    ULONG IoControlCode; 
    PVOID IoBuffer; 
    ULONG InputBufferLength; 
    ULONG OutputBufferLength; 
    ULONG length; 
    PUCHAR pch; 
 
	pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension; 
    if (!LockDevice(fdo)) 
		return CompleteRequest(Irp, STATUS_DELETE_PENDING, 0); 
 
   IrpStack = IoGetCurrentIrpStackLocation (Irp); 
   Irp->IoStatus.Status = STATUS_SUCCESS; 
   Irp->IoStatus.Information = 0; 
 
   IoBuffer           = Irp->AssociatedIrp.SystemBuffer; 
   InputBufferLength  = IrpStack->Parameters.DeviceIoControl.InputBufferLength; 
   OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; 
   IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; 
 
   switch (IoControlCode) { 
       case IOCTL_EZUSB_GET_CURRENT_FRAME_NUMBER: 
		   { 
			   ULONG frameNumber = 0; 
 
               if (OutputBufferLength < sizeof(ULONG)) { 
				   Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 
                   break; 
			   } 
               frameNumber = UsbGetCurrentFrameNumber (fdo); 
               if (frameNumber) { 
				   *((PULONG)IoBuffer) = frameNumber; 
                   Irp->IoStatus.Information = sizeof(ULONG); 
                   Irp->IoStatus.Status = STATUS_SUCCESS; 
			   } 
               else 
				   Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 
		   } 
           break; 
 
       case IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR: 
		  { 
              length = UsbGetDeviceDescriptor (fdo, IoBuffer); 
              Irp->IoStatus.Information = length; 
              Irp->IoStatus.Status = STATUS_SUCCESS; 
		  } 
		  break; 
      case IOCTL_Ezusb_GET_STRING_DESCRIPTOR: 
		  { 
			  PGET_STRING_DESCRIPTOR_IN Input = IoBuffer; 
 
              if ((InputBufferLength = sizeof(GET_STRING_DESCRIPTOR_IN)) && 
                  (OutputBufferLength > 0)) { 
				  length = UsbGetStringDescriptor (fdo, 
                                                   Input->Index, 
                                                   Input->LanguageId, 
                                                   IoBuffer, 
                                                   OutputBufferLength); 
                  if (length) { 
					  Irp->IoStatus.Information = length; 
                      Irp->IoStatus.Status = STATUS_SUCCESS; 
				  } 
                  else 
					  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 
			  } 
              else             
               Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 
		  }       
          break; 
 
         case IOCTL_Ezusb_GET_CONFIGURATION_DESCRIPTOR: 
			 { 
                 length = UsbGetConfigDescriptor (fdo, IoBuffer, OutputBufferLength); 
                 Irp->IoStatus.Information = length; 
                 Irp->IoStatus.Status = STATUS_SUCCESS; 
			 } 
             break; 
  
         case IOCTL_EZUSB_BULK_WRITE: 
         case IOCTL_EZUSB_BULK_READ: 
			 Irp->IoStatus.Status = Bulk_Read_Write(fdo,Irp); 
			 break; 
 
         case IOCTL_Ezusb_RESETPIPE: 
			 { 
				 ULONG pipenum = *((PULONG) IoBuffer); 
                 Irp->IoStatus.Status = UsbResetPipe(fdo,pipenum); 
			 } 
             break; 
 
         case IOCTL_Ezusb_ABORTPIPE: 
			 { 
				 int pipenum = *((PULONG) IoBuffer); 
                 UsbAbortPipe(fdo,(USBD_PIPE_HANDLE) pdx->Interface->Pipes[pipenum].PipeHandle); 
                 Irp->IoStatus.Information = 0; 
                 Irp->IoStatus.Status = STATUS_SUCCESS; 
			 }       
             break; 
 
         default: 
			  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 
     }  
    UnlockDevice(fdo); 
    ntStatus = Irp->IoStatus.Status; 
    IoCompleteRequest (Irp,IO_NO_INCREMENT); 
    return ntStatus; 
} 
// 
ULONG UsbGetCurrentFrameNumber(IN PDEVICE_OBJECT fdo) 
{ 
	NTSTATUS  ntStatus = STATUS_SUCCESS; 
	PURB urb = NULL; 
    PDEVICE_EXTENSION   pdx; 
    ULONG  frameNumber = 0; 
     
    pdx = fdo->DeviceExtension; 
    urb = ExAllocatePool(NonPagedPool,sizeof(struct _URB_GET_CURRENT_FRAME_NUMBER)); 
    if (urb == NULL) 
		return 0; 
    RtlZeroMemory(urb,sizeof(struct _URB_GET_CURRENT_FRAME_NUMBER)); 
   
	urb->UrbHeader.Length = sizeof(struct _URB_GET_CURRENT_FRAME_NUMBER); 
    urb->UrbHeader.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER; 
  
	ntStatus = UsbCallUSBDI(fdo, urb); 
    if (NT_SUCCESS(ntStatus)) { 
		frameNumber = urb->UrbGetCurrentFrameNumber.FrameNumber; 
    } 
 
    ExFreePool(urb); 
    return frameNumber; 
} 
// 
ULONG UsbGetDeviceDescriptor(IN PDEVICE_OBJECT fdo, 
							 PVOID pvOutputBuffer) 
{ 
	NTSTATUS ntStatus = STATUS_SUCCESS; 
    PURB     urb = NULL; 
    ULONG    length = 0; 
    PDEVICE_EXTENSION   pdx = NULL; 
 
    pdx = fdo->DeviceExtension; 
    urb = ExAllocatePool(NonPagedPool,  
                         sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 
    if (urb==NULL) 
		return STATUS_NO_MEMORY;         
 
    if (pvOutputBuffer==NULL)  
		return STATUS_INVALID_PARAMETER; 
 
    UsbBuildGetDescriptorRequest(urb, 
                                 (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_DEVICE_DESCRIPTOR_TYPE,     
                                 0,                              
                                 0,                              
                                 pvOutputBuffer,                 
                                 NULL,                           
                                 sizeof(USB_DEVICE_DESCRIPTOR),  
                                 NULL);                          
                                                                  
    ntStatus = UsbCallUSBDI(fdo, urb); 
 
    if (NT_SUCCESS(ntStatus)) { 
		length = urb->UrbControlDescriptorRequest.TransferBufferLength; 
	} 
	else 
		length = 0; 
    ExFreePool(urb); 
    return length; 
} 
// 
ULONG UsbGetStringDescriptor(IN PDEVICE_OBJECT fdo, 
                             UCHAR             Index, 
                             USHORT            LanguageId, 
                             PVOID             pvOutputBuffer, 
                             ULONG             ulLength) 
{ 
	NTSTATUS ntStatus = STATUS_SUCCESS; 
    PURB     urb = NULL; 
    ULONG    length = 0; 
 
    urb = ExAllocatePool(NonPagedPool,  
                         sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 
                          
    if (urb==NULL) 
		return STATUS_NO_MEMORY;         
 
    if (pvOutputBuffer==NULL) 
		return STATUS_INVALID_PARAMETER; 
 
    UsbBuildGetDescriptorRequest(urb, 
                                 (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST), 
                                  USB_STRING_DESCRIPTOR_TYPE,   
                                  Index,                        
                                  LanguageId,                   
                                  pvOutputBuffer,               
                                  NULL,                         
                                  ulLength,                     
                                  NULL);                        
                                                                   
    ntStatus = UsbCallUSBDI(fdo, urb); 
 
    if (NT_SUCCESS(ntStatus))  { 
         length = urb->UrbControlDescriptorRequest.TransferBufferLength; 
	} 
    else 
         length = 0; 
    ExFreePool(urb); 
    return length; 
} 
// 
ULONG UsbGetConfigDescriptor(IN PDEVICE_OBJECT fdo, 
                             PVOID   pvOutputBuffer, 
                             ULONG   ulLength) 
{ 
	NTSTATUS  ntStatus = STATUS_SUCCESS; 
    PURB      urb = NULL; 
    ULONG     length = 0; 
 
    urb = ExAllocatePool(NonPagedPool,  
                         sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST)); 
                          
    if (urb==NULL) 
		return STATUS_NO_MEMORY;         
    
    if (pvOutputBuffer==NULL) 
		return STATUS_INVALID_PARAMETER; 
 
   	UsbBuildGetDescriptorRequest(urb, 
                                 (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST), 
                                 USB_CONFIGURATION_DESCRIPTOR_TYPE,  
                                 0,                         
                                 0,                         
                                 pvOutputBuffer,            
                                 NULL,                      
                                 ulLength,                  
                                 NULL);                     
                                                                   
    ntStatus = UsbCallUSBDI(fdo, urb); 
 
    if (NT_SUCCESS(ntStatus)) { 
         length = urb->UrbControlDescriptorRequest.TransferBufferLength; 
	} 
    else 
        length = 0; 
    ExFreePool(urb); 
    return length; 
} 
// 
NTSTATUS Bulk_Read_Write(IN  PDEVICE_OBJECT fdo,IN  PIRP Irp) 
{ 
	NTSTATUS ntStatus; 
	PURB                       urb = NULL; 
    ULONG                      urbSize = 0; 
    ULONG                      transferFlags = 0; 
    PUSBD_INTERFACE_INFORMATION interfaceInfo = NULL; 
    PUSBD_PIPE_INFORMATION     pipeInfo = NULL; 
    USBD_PIPE_HANDLE           pipeHandle = NULL; 
	PDEVICE_EXTENSION pdx = fdo->DeviceExtension; 
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation (Irp); 
    PBULK_TRANSFER_CONTROL bulkControl = (PBULK_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer; 
    ULONG bufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; 
    
   interfaceInfo = pdx->Interface; 
   if (!interfaceInfo) 
	   return STATUS_UNSUCCESSFUL; 
    
   if (bulkControl->pipeNum > interfaceInfo->NumberOfPipes) 
       return STATUS_INVALID_PARAMETER; 
 
   pipeInfo = &(interfaceInfo->Pipes[bulkControl->pipeNum]); 
   if (!((pipeInfo->PipeType == UsbdPipeTypeBulk) || 
         (pipeInfo->PipeType == UsbdPipeTypeInterrupt)))  
       return STATUS_INVALID_PARAMETER; 
    
   pipeHandle = pipeInfo->PipeHandle; 
   if (!pipeHandle) 
       return STATUS_UNSUCCESSFUL; 
    
   if (bufferLength > pipeInfo->MaximumTransferSize)  
      return STATUS_INVALID_PARAMETER; 
 
   urbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); 
   urb = ExAllocatePool(NonPagedPool,urbSize); 
   if (!urb) 
	   return STATUS_NO_MEMORY; 
 
   transferFlags = USBD_SHORT_TRANSFER_OK; 
   if (USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress)) 
	   transferFlags |= USBD_TRANSFER_DIRECTION_IN; 
 
   UsbBuildInterruptOrBulkTransferRequest(urb,  
                                          (USHORT) urbSize,  
					                      pipeHandle,  
							              NULL,  
							              Irp->MdlAddress,  
							              bufferLength,  
							              transferFlags, 
							              NULL);   
   ntStatus = UsbCallUSBDI(fdo, urb); 
   if (NT_SUCCESS(ntStatus))  
	   Irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength; 
 
   ExFreePool(urb); 
   return ntStatus; 
} 
// 
NTSTATUS UsbResetPipe(IN PDEVICE_OBJECT fdo, ULONG PipeNum) 
{ 
   NTSTATUS ntStatus; 
   PDEVICE_EXTENSION             pdx = fdo->DeviceExtension; 
   PUSBD_INTERFACE_INFORMATION   interfaceInfo = NULL; 
   USBD_PIPE_HANDLE              pipeHandle = NULL; 
   PURB urb; 
   USBD_VERSION_INFORMATION      VersionInformation; 
    
   interfaceInfo = pdx->Interface; 
   if (!interfaceInfo) 
   { 
       return STATUS_UNSUCCESSFUL; 
   } 
    
   if (PipeNum > interfaceInfo->NumberOfPipes) 
   { 
      return STATUS_INVALID_PARAMETER; 
   } 
 
   pipeHandle = interfaceInfo->Pipes[PipeNum].PipeHandle; 
 
   urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); 
 
   if (urb) 
   { 
      urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST); 
      urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE; 
      urb->UrbPipeRequest.PipeHandle = pipeHandle; 
 
      USBD_GetUSBDIVersion(&VersionInformation); 
      if (VersionInformation.USBDI_Version < 0x101)  
      { 
         urb->UrbHeader.Length -= sizeof(ULONG); 
      } 
 
      ntStatus = UsbCallUSBDI(fdo, urb); 
 
      ExFreePool(urb); 
   } 
   else 
   { 
      ntStatus = STATUS_INSUFFICIENT_RESOURCES; 
   } 
 
   return ntStatus; 
} 
// 
NTSTATUS UsbAbortPipe(IN PDEVICE_OBJECT fdo, IN USBD_PIPE_HANDLE PipeHandle) 
{ 
   NTSTATUS ntStatus; 
   PURB urb; 
   USBD_VERSION_INFORMATION VersionInformation; 
 
   urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); 
 
   if (urb) 
   { 
      RtlZeroMemory(urb,sizeof(struct _URB_PIPE_REQUEST)); 
      urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST); 
      urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE; 
      urb->UrbPipeRequest.PipeHandle = PipeHandle; 
 
      USBD_GetUSBDIVersion(&VersionInformation); 
      if (VersionInformation.USBDI_Version < 0x101)  
      { 
         urb->UrbHeader.Length -= sizeof(ULONG); 
      } 
 
      ntStatus = UsbCallUSBDI(fdo, urb); 
 
      ExFreePool(urb); 
   } 
   else 
   { 
      ntStatus = STATUS_INSUFFICIENT_RESOURCES; 
   } 
 
   return ntStatus; 
}