📄 whusb20dispatch.c
字号:
//////////////////////////////////////////////////////////////////////////////
//文件名称:Whceb01Dispatch.cpp
//文件功能:驱动分发例程,对设备的IOCTL操作在Whceb01DeviceControl例程中实现
//文件作者:张伟标
//工作部门:研究一室
//创建时间:2004年1月9日
//修改记录:
//版权所有:维豪信息技术有限公司
//
//Copyright 2004 WellHope Information Technology Corporation, Ltd.
//All rights reserved.
#include "Whusb20.h"
#include "Whusb20Ioctl.h"
/*******************************************************************************
函数名: WhAllocateMemory()
功能描述: 分配一定长度的内存
参数:
Length: 要分配内存的长度
返回值:
分配到的内存地址
*******************************************************************************/
LPVOID WhAllocateMemory( ULONG Length )
{
// 分配内存
return ExAllocatePool(NonPagedPool, Length);
}
void WhFreeMemory( LPVOID BaseAddr )
{
ExFreePool( BaseAddr );
}
/////////////////////////////////////////////////////////////////////////////
// Whceb01Create:
//
// Description:
// Handle IRP_MJ_CREATE requests
//
// Arguments:
// Pointer to our FDO
// Pointer to the IRP
// IrpStack->Parameters.Create.xxx has create parameters
// IrpStack->FileObject->FileName has file name of device
//
// Return Value:
// This function returns STATUS_XXX
NTSTATUS Whceb01Create( IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
NTSTATUS status;
PWHCEB01_DEVICE_EXTENSION dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
ULONG size = 0;
PIO_STACK_LOCATION IrpStack ;
LARGE_INTEGER timeout,timeout1;
PWHCEB01_CHANNEL pChannelInfo = NULL;
ULONG i = 0;
int Count = 0;
timeout.QuadPart = WHCEB01_TIMEOUT;
timeout1.QuadPart = -10000;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
TRACE0( "--------start--Whceb01Create----------------");
if( dx->IODisabled)
return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0);
status = KeWaitForSingleObject( &dx->ChannelMutex ,
Executive,
KernelMode,
FALSE,
&timeout
//NULL
);
if(STATUS_TIMEOUT == status)
{//资源已经被其它线程占用
TRACE1("-----------等待CEB信号量超时---- status =0x%x--",status);
TRACE0("-----------设备忙,无法打开句柄--调用Whjk05Create---完毕--");
status = CompleteIrp( Irp,STATUS_UNSUCCESSFUL,0);
return status;
}
//为该设备分配内存
pChannelInfo = ( PWHCEB01_CHANNEL )WhAllocateMemory( sizeof( PWHCEB01_CHANNEL ) );
if( pChannelInfo == NULL )
{
TRACE0("No more memory when allcate a channel infomation");
KeReleaseMutex( &dx->ChannelMutex , FALSE );
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
pChannelInfo->ChannelNum = CHNL_ERROR;
InterlockedIncrement(&dx->OpenHandleCount);
while( Count < 5000 )
{
for( i = 0 ; i < VALID_CHANNEL ; i ++ )
{
if( !dx->ChannelisUsed[i] )
{
pChannelInfo->ChannelNum = i;
pChannelInfo->InputHandle = dx->hWhceb01InterruptInHandle[i];
pChannelInfo->OutputHandle = dx->hWhceb01InterruptOutHandle[i];
dx->ChannelisUsed[i] = TRUE;
break;
}
}
if( pChannelInfo->ChannelNum != CHNL_ERROR )
break;
else
{
status = KeWaitForSingleObject( &dx->WaitEvent ,
Executive,
KernelMode,
FALSE,
&timeout1
//NULL
);
Count ++;
}
}
KeReleaseMutex( &dx->ChannelMutex , FALSE );
if( pChannelInfo->ChannelNum == CHNL_ERROR )
{
WhFreeMemory( pChannelInfo );
CompleteIrp( Irp , STATUS_INSUFFICIENT_RESOURCES , 0 );
return STATUS_INSUFFICIENT_RESOURCES;
}
TRACE1( "Current Channel is 0x%x" , pChannelInfo->ChannelNum );
IrpStack->FileObject->FsContext = pChannelInfo;
TRACE1( "Create File , Handle is 0x%X", pChannelInfo );
TRACE0( "------end----Whceb01Create----------------");
// Complete successfully
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
/////////////////////////////////////////////////////////////////////////////
// Whceb01Close:
//
// Description:
// Handle IRP_MJ_CLOSE requests
// Allow closes to complete if device not started
//
// Arguments:
// Pointer to our FDO
// Pointer to the IRP
//
// Return Value:
// This function returns STATUS_XXX
NTSTATUS Whceb01Close( IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PWHCEB01_DEVICE_EXTENSION dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
PWHCEB01_CHANNEL pChannelInfo = NULL;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
TRACE0("-------Whceb01Closed!--------");
InterlockedDecrement(&dx->OpenHandleCount);
pChannelInfo = ( PWHCEB01_CHANNEL )IrpStack->FileObject->FsContext;
if( pChannelInfo != NULL )
{
dx->ChannelisUsed[pChannelInfo->ChannelNum] = FALSE;
if( dx->GotResources )
WhFreeMemory( pChannelInfo );
}
// Complete successfully
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
/////////////////////////////////////////////////////////////////////////////
// Whceb01Read:
//
// Description:
// Handle IRP_MJ_READ requests
//
// Arguments:
// Pointer to our FDO
// Pointer to the IRP
// IrpStack->Parameters.Read.xxx has read parameters
// User buffer at: AssociatedIrp.SystemBuffer (buffered I/O)
// MdlAddress (direct I/O)
//
// Return Value:
// This function returns STATUS_XXX
NTSTATUS Whceb01Read( IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PWHCEB01_DEVICE_EXTENSION dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status = STATUS_SUCCESS;
ULONG BytesTxd = 0;
PIO_STACK_LOCATION IrpStack ;
LONGLONG FilePointer;
ULONG ReadLen;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
TRACE0( "Read" );
if( dx->IODisabled)
return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0);
if (!LockDevice(dx))
return CompleteIrp( Irp, STATUS_DELETE_PENDING, 0);
// Get call parameters
FilePointer = IrpStack->Parameters.Read.ByteOffset.QuadPart;
ReadLen = IrpStack->Parameters.Read.Length;
#ifdef DEBUG_INTERFACE
TRACE2("Read %d bytes from file pointer %d",(int)ReadLen,(int)FilePointer);
#endif//DEBUG_INTERFACE
// Check file pointer
if( FilePointer<0)
status = STATUS_INVALID_PARAMETER;
else
{
status = UsbDoInterruptTransfer( dx, Irp->AssociatedIrp.SystemBuffer, &ReadLen);
BytesTxd = ReadLen;
}
#ifdef DEBUG_INTERFACE
TRACE2("Read: %x %d bytes returned",status,(int)BytesTxd);
#endif//DEBUG_INTERFACE
// Complete IRP
CompleteIrp(Irp,status,BytesTxd);
UnlockDevice(dx);
return status;
}
/////////////////////////////////////////////////////////////////////////////
// Whceb01Write:
//
// Description:
// Handle IRP_MJ_WRITE requests
//
// Arguments:
// Pointer to our FDO
// Pointer to the IRP
// IrpStack->Parameters.Write.xxx has write parameters
// User buffer at: AssociatedIrp.SystemBuffer (buffered I/O)
// MdlAddress (direct I/O)
//
// Return Value:
// This function returns STATUS_XXX
NTSTATUS Whceb01Write( IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PWHCEB01_DEVICE_EXTENSION dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status = STATUS_SUCCESS;
ULONG BytesTxd = 0;
LONGLONG FilePointer;
ULONG WriteLen;
PUCHAR pData ;
PIO_STACK_LOCATION IrpStack;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
TRACE0( "Write" );
if( dx->IODisabled)
return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0);
if (!LockDevice(dx))
return CompleteIrp( Irp, STATUS_DELETE_PENDING, 0);
// Get call parameters
FilePointer = IrpStack->Parameters.Write.ByteOffset.QuadPart;
WriteLen = IrpStack->Parameters.Write.Length;
#ifdef DEBUG_INTERFACE
TRACE2("Write %d bytes from file pointer %d",(int)WriteLen,(int)FilePointer);
#endif//DEBUG_INTERFACE
if( FilePointer<0 || WriteLen<1)
status = STATUS_INVALID_PARAMETER;
else
{
// Only ever write one byte
BytesTxd = 1;
pData = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
UsbSendOutputReport( dx, *pData);
}
#ifdef DEBUG_INTERFACE
TRACE1("Write: %d bytes written",(int)BytesTxd);
#endif//DEBUG_INTERFACE
// Complete IRP
CompleteIrp(Irp,status,BytesTxd);
UnlockDevice(dx);
return status;
}
/////////////////////////////////////////////////////////////////////////////
// Whceb01DeviceControl:
//
// Description:
// Handle IRP_MJ_DEVICE_CONTROL requests
//
// Arguments:
// Pointer to our FDO
// Pointer to the IRP
// Buffered: AssociatedIrp.SystemBuffer (and IrpStack->Parameters.DeviceIoControl.Type3InputBuffer)
// Direct: MdlAddress
//
// IrpStack->Parameters.DeviceIoControl.InputBufferLength
// IrpStack->Parameters.DeviceIoControl.OutputBufferLength
//
// Return Value:
// This function returns STATUS_XXX
NTSTATUS Whceb01DeviceControl( IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PWHCEB01_DEVICE_EXTENSION dx = (PWHCEB01_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status = STATUS_SUCCESS;
ULONG BytesTxd = 0;
ULONG OutputLength;
ULONG InputLength;
ULONG ControlCode;
PIO_STACK_LOCATION IrpStack;
PUCHAR tempBuf;
PWHCEB01_CHANNEL pChannel = NULL;
PVOID pOutputBuffer = NULL;
TRACE0( "DeviceControl" );
if( dx->IODisabled)
return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0);
if (!LockDevice(dx))
return CompleteIrp( Irp, STATUS_DELETE_PENDING, 0);
IrpStack = IoGetCurrentIrpStackLocation(Irp);
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
tempBuf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
pChannel = ( PWHCEB01_CHANNEL )IrpStack->FileObject->FsContext;
if( NULL == pChannel )
{
TRACE0( "输入句柄无效!" );
CompleteIrp( Irp , STATUS_INVALID_PARAMETER , 0 );
UnlockDevice( dx );
return STATUS_INVALID_PARAMETER;
}
TRACE3( "Current Channel is 0x%x,In Addr:0x%X,Out Addr:0x%X." , pChannel->ChannelNum ,pChannel->InputHandle , pChannel->OutputHandle );
TRACE3("DeviceIoControl: Control code %x InputLength %d OutputLength %d",
ControlCode, InputLength, OutputLength);
switch( ControlCode)
{
/////// Set read timeout
case IOCTL_WHCEB01_SET_READ_TIMEOUT:
if( InputLength!=4)
status = STATUS_INVALID_PARAMETER;
else
{
dx->UsbTimeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
#ifdef DEBUG_INTERFACE
TRACE1( "USB timeout set to %d",dx->UsbTimeout);
#endif//DEBUG_INTERFACE
}
break;
/////// Get device descriptor
case IOCTL_WHCEB01_GET_DEVICE_DESCRIPTOR:
{
PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
ULONG size;
NTSTATUS status = UsbGetDeviceDescriptor( dx, deviceDescriptor, &size);
if( NT_SUCCESS(status))
{
BytesTxd = size;
if( BytesTxd>OutputLength)
BytesTxd = OutputLength;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,deviceDescriptor,BytesTxd);
}
FreeIfAllocated(deviceDescriptor);
break;
}
/////// Get configuration and other descriptors
case IOCTL_WHCEB01_GET_CONFIGURATION_DESCRIPTORS:
{
PUSB_CONFIGURATION_DESCRIPTOR Descriptors = NULL;
ULONG size;
NTSTATUS status = UsbGetConfigurationDescriptors( dx, &Descriptors, 0, &size);
if( NT_SUCCESS(status))
{
BytesTxd = size;
if( BytesTxd>OutputLength)
BytesTxd = OutputLength;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,Descriptors,BytesTxd);
}
FreeIfAllocated(Descriptors);
break;
}
/////// Get HID Report descriptor
case IOCTL_WHCEB01_GET_SPECIFIED_DESCRIPTOR:
{
if( InputLength!=8)
status = STATUS_INVALID_PARAMETER;
else
{
PULONG pData = (PULONG)Irp->AssociatedIrp.SystemBuffer;
UCHAR type = (UCHAR)*pData++;
ULONG size = *pData;
PVOID Descriptor = NULL;
NTSTATUS status = UsbGetSpecifiedDescriptor( dx, Descriptor, type, &size);
if( NT_SUCCESS(status))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -