📄 ezusbdevice.cpp
字号:
status = m_Lower.SubmitUrb(&u);
if( NT_SUCCESS(status) )
{
I.Information() = u.UrbControlDescriptorRequest.TransferBufferLength;
status = STATUS_SUCCESS;
}
else
{
status = STATUS_UNSUCCESSFUL;
}
}
else
{
status = STATUS_INVALID_PARAMETER;
}
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_BULK_READ:
t << "IOCTL_EZUSB_BULK_READ \n";
status = BulkReadWrite(I);
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_BULK_WRITE:
t << "IOCTL_EZUSB_BULK_WRITE \n";
status = BulkReadWrite(I);
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_CURRENT_FRAME_NUM:
{
t << "IOCTL_EZUSB_GET_CURRENT_FRAME_NUM \n";
if (dwOutputBufferSize < sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
break;
}
ULONG nFrameNum = m_Lower.GetCurrentFrameNumber();
if( -1 != nFrameNum )
{
*(reinterpret_cast<PULONG>(pBuffer)) = nFrameNum;
I.Information() = sizeof(ULONG);
status = STATUS_SUCCESS;
}
else
{
status = STATUS_UNSUCCESSFUL;
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST:
t << "IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST \n";
status = VendorRequest(I);
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_LAST_ERROR:
t << "IOCTL_EZUSB_GET_LAST_ERROR \n";
if (dwOutputBufferSize >= sizeof(ULONG))
{
*(reinterpret_cast<PULONG>(pBuffer)) = m_LastFailedUrbStatus;
status = STATUS_SUCCESS;
I.Information() = sizeof(ULONG);
}
else
{
status = STATUS_UNSUCCESSFUL;
}
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_ISO_READ:
t << "IOCTL_EZUSB_ISO_READ \n";
status = IsoReadWrite(I);
I.Information() = 0;
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_ISO_WRITE:
t << "IOCTL_EZUSB_ISO_WRITE \n";
status = IsoReadWrite(I);
I.Information() = 0;
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_ANCHOR_DOWNLOAD:
{
t << "IOCTL_EZUSB_ANCHOR_DOWNLOAD \n";
PANCHOR_DOWNLOAD_CONTROL p = reinterpret_cast<PANCHOR_DOWNLOAD_CONTROL>(pBuffer);
if ( dwInputBufferSize != sizeof(ANCHOR_DOWNLOAD_CONTROL) ||
dwOutputBufferSize == 0)
{
t << "Error: Invalid Parameter\n";
status = STATUS_INVALID_PARAMETER;
}
else
{
ULONG dwTransferCount =
(dwOutputBufferSize + EZUSB_ANCHOR_DOWNLOAD_SEGMENT_SIZE - 1) /
EZUSB_ANCHOR_DOWNLOAD_SEGMENT_SIZE;
KMemory M(I.Mdl());
status = AnchorDownload(
p->Offset,
reinterpret_cast<PUCHAR>(M.MapToSystemSpace()),
dwOutputBufferSize,
EZUSB_ANCHOR_DOWNLOAD_SEGMENT_SIZE,
dwTransferCount
);
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_GET_DRIVER_VERSION:
{
t << "IOCTL_EZUSB_GET_DRIVER_VERSION \n";
PEZUSB_DRIVER_VERSION p = reinterpret_cast<PEZUSB_DRIVER_VERSION>(pBuffer);
if (dwOutputBufferSize >= sizeof(EZUSB_DRIVER_VERSION))
{
p->MajorVersion = EZUSB_MAJOR_VERSION;
p->MinorVersion = EZUSB_MINOR_VERSION;
p->BuildVersion = EZUSB_BUILD_VERSION;
status = STATUS_SUCCESS;
I.Information() = sizeof(EZUSB_DRIVER_VERSION);
}
else
{
status = STATUS_UNSUCCESSFUL;
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_START_ISO_STREAM:
t << "IOCTL_EZUSB_START_ISO_STREAM \n";
status = StartIsoStream(I);
I.Information() = 0;
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_STOP_ISO_STREAM:
t << "IOCTL_EZUSB_STOP_ISO_STREAM \n";
if( m_pIsoDM )
{
if( m_pIsoDM->IsStarted() )
{
status = m_pIsoDM->Stop(
TRUE, //wait for stop?
10 //timeout
);
}
}
status = STATUS_SUCCESS;
I.Information() = 0;
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
case IOCTL_EZUSB_READ_ISO_BUFFER:
t << "IOCTL_EZUSB_READ_ISO_BUFFER \n";
status = ReadIsoBuffer(I);
break;
///////////////////////////////////////////////////////////////////////////////////////////////////
default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}
// If the IRP's IOCTL handler deferred processing using some driver
// specific scheme, the status variable is set to STATUS_PENDING.
// In this case we simply return that status, and the IRP will be
// completed later. Otherwise, complete the IRP using the status
// returned by the IOCTL handler.
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}
//=============================================================================
// EzUsbDevice::VendorRequest - Handler for IOCTL_EZUSB_VENDOR_REQUEST
//
NTSTATUS EzUsbDevice::VendorRequest(PVENDOR_REQUEST_IN pVendorRequest, ULONG_PTR& nLength)
{
t << "Entering VendorRequest\n";
NTSTATUS status = STATUS_SUCCESS;
ULONG nBufferLength = pVendorRequest->wLength;
PUCHAR pBuffer = NULL;
BOOLEAN bIn = FALSE;
nLength = 0;
if(pVendorRequest->direction)
{
//IN transfer
pBuffer = reinterpret_cast<PUCHAR>(pVendorRequest);
bIn = TRUE;
}
else
{
//OUT transfer
pBuffer = new (NonPagedPool) UCHAR[nBufferLength];
if( pBuffer )
{
if( 1 == nBufferLength )
{
pBuffer[0] = pVendorRequest->bData;
}
else
{
PUCHAR pTemp = pBuffer;
for( UCHAR i = 0; i < nBufferLength; i++)
{
*pTemp = i;
pTemp++;
}
}
}
else
{
return STATUS_INSUFFICIENT_RESOURCES;
}
}
PURB pUrb = m_Lower.BuildVendorRequest(
pBuffer,
nBufferLength,
0,
pVendorRequest->bRequest,
pVendorRequest->wValue,
bIn,
FALSE,
NULL,
pVendorRequest->wIndex
);
if (pUrb) {
status = m_Lower.SubmitUrb(pUrb);
}
else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
if( NT_SUCCESS(status) )
{
if(pVendorRequest->direction)
{
nLength = pUrb->UrbControlVendorClassRequest.TransferBufferLength;
}
}
if(!pVendorRequest->direction)
{
delete pBuffer;
}
delete pUrb;
return status;
}
//=============================================================================
// EzUsbDevice::VendorRequest - Handler for IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST
//
NTSTATUS EzUsbDevice::VendorRequest(KIrp I)
{
t << "Entering VendorRequest\n";
NTSTATUS status = STATUS_SUCCESS;
//Check parameters
if(I.IoctlInputBufferSize() != sizeof(VENDOR_OR_CLASS_REQUEST_CONTROL))
{
return STATUS_INVALID_PARAMETER;
}
PVENDOR_OR_CLASS_REQUEST_CONTROL p =
reinterpret_cast<PVENDOR_OR_CLASS_REQUEST_CONTROL>( I.IoctlBuffer() );
USHORT nUrbFunction = 0;
// Determine the URB function based on input parameters
// requestType and recepient passed down from user mode
switch( (p->requestType << 2) | p->recepient )
{
case 0x04:
nUrbFunction = URB_FUNCTION_CLASS_DEVICE;
break;
case 0x05:
nUrbFunction = URB_FUNCTION_CLASS_INTERFACE;
break;
case 0x06:
nUrbFunction = URB_FUNCTION_CLASS_ENDPOINT;
break;
case 0x07:
nUrbFunction = URB_FUNCTION_CLASS_OTHER;
break;
case 0x08:
nUrbFunction = URB_FUNCTION_VENDOR_DEVICE;
break;
case 0x09:
nUrbFunction = URB_FUNCTION_VENDOR_INTERFACE;
break;
case 0x0A:
nUrbFunction = URB_FUNCTION_VENDOR_ENDPOINT;
break;
case 0x0B:
nUrbFunction = URB_FUNCTION_VENDOR_OTHER;
break;
default:
return STATUS_INVALID_PARAMETER;
break;
}
KMemory M(I.Mdl());
PURB pUrb = m_Lower.BuildVendorRequest(
M,
I.IoctlOutputBufferSize(),
0,
p->request,
p->value,
p->direction,
TRUE,
NULL,
p->index,
nUrbFunction
);
if (pUrb) {
status = m_Lower.SubmitUrb(pUrb);
}
else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
if( NT_SUCCESS(status) )
{
I.Information() = pUrb->UrbControlVendorClassRequest.TransferBufferLength;
}
delete pUrb;
return status;
}
//=============================================================================
// EzUsbDevice::FindPipe
//
// Since the applications in the development kit determine which pipe to
// use for a particular request to the USB device, the driver cannot be
// hard coded with KUsbPipe objects. Rather, the KUsbPipe object to use
// must be determined by a search of all the pipes. When a match is
// found by endpoint address, this KUsbPipe object is returned. Most
// drivers would not use this sort of logic. Instead a KUsbPipe object
// would be hardcoded to perform transfers.
//
KUsbPipe* EzUsbDevice::FindPipe(ULONG nPipeNum)
{
if (nPipeNum > m_UsbInterface.NumberOfPipes())
{
ASSERT( nPipeNum <= m_UsbInterface.NumberOfPipes() );
return NULL;
}
UCHAR byEndpointAddress = m_UsbInterface.Pipes(nPipeNum)->EndpointAddress;
int num = m_Lower.PipeArray().MaxInserted() + 1; //number of elements in the array
for( int i = 0; i < num; i++ )
{
if( m_Lower.PipeArray()[i]->m_EndpointAddress == byEndpointAddress )
break;
}
if( num == i )
{
t << "WARNING: No Pipe Object for Endpoint!\n";
return NULL;
}
return m_Lower.PipeArray()[i];
}
//=============================================================================
// EzUsbDevice::BulkReadWrite
//
// This routine handles Bulk reads and writes in response to
// IOCTL_EZUSB_BULK_READ and IOCTL_EZUSB_BULK_WRITE.
//
NTSTATUS EzUsbDevice::BulkReadWrite(KIrp I)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -