📄 computer00usbdevice.cpp
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::DeviceControl
// Dispatch routine for IRP_MJ_DEVICE_CONTROL requests.
//
// Arguments:
// IN I
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::DeviceControl(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
switch (I.IoctlCode())
{
case EP1_READ:
status = EP1_READ_Handler(I);
break;
case EP1_WRITE:
status = EP1_WRITE_Handler(I);
break;
case EP2_READ:
status = EP2_READ_Handler(I);
break;
case EP2_WRITE:
status = EP2_WRITE_Handler(I);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
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)
{
I.PnpComplete(this, status);
}
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::EP1_READ_Handler
// Handler for ioctl EP1_READ. The DeviceControl
// method will complete the IRP.
//
// Arguments:
// IN I
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP1_READ_Handler(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = I.IoctlInputBufferSize();
ULONG outputSize = I.IoctlOutputBufferSize();
// Buffered ioctl - using the same buffer so read the buffer before writing the buffer
PVOID inputBuffer = I.IoctlBuffer();
PVOID outputBuffer = I.IoctlBuffer();
// TODO: Validate the parameters of the IRP. Replace "FALSE"
// in the following line with error checking code that
// evaulates to TRUE if the request is not valid.
/*if (FALSE)*/
//注意:当读数据时,应该将数据保存在应用程序提供的输出缓冲中,
//因为驱动程序将会将读到的数据输出给应用程序
if(outputBuffer==NULL) //如果缓冲区为无效地址
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
}
else //如果参数有效
{
// TODO: copy data
// To satisfy the ioctl now, transfer data using the
// caller's buffers at "inputBuffer" and/or "outputBuffer".
// Then, indicate how much data was transferred:
/**************以下为圈圈新增代码************/
if(outputSize==0) //如果读数据长度为0,则不用传输数据
{
I.Information() = 0;
}
else //数据长度不为0
{
//创建一个中断传输的URB,用来从端点1读取数据
PURB pUrb=Ep1In.BuildInterruptTransfer(outputBuffer, //接收数据的缓冲区
outputSize, //读数据的数据字节数
TRUE, //TRUE表示设备传输的字节数可以少于指定的字节数
NULL, //连接下一个传输的URB,这里没有,置为NULL
NULL, //指向一个已经存在的URB。置为NULL,分配一个新的URB
TRUE); //TURE表示读数据
if(pUrb==NULL) //如果分配失败
{
status=STATUS_INSUFFICIENT_RESOURCES; //设置状态为资源不足
I.Information()=0; //数据传输为0
}
else
{
//提交URB,并设置等待3秒后就超时
status=Ep1In.SubmitUrb(pUrb,NULL,NULL,3000);
//获取实际读到的数据字节数
I.Information()=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb; //删除刚刚分配的URB
}
}
/*************新增代码完毕****************/
}
T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::EP1_WRITE_Handler
// Handler for ioctl EP1_WRITE. The DeviceControl
// method will complete the IRP.
//
// Arguments:
// IN I
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP1_WRITE_Handler(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = I.IoctlInputBufferSize();
ULONG outputSize = I.IoctlOutputBufferSize();
// Buffered ioctl - using the same buffer so read the buffer before writing the buffer
PVOID inputBuffer = I.IoctlBuffer();
PVOID outputBuffer = I.IoctlBuffer();
// TODO: Validate the parameters of the IRP. Replace "FALSE"
// in the following line with error checking code that
// evaulates to TRUE if the request is not valid.
/*if (FALSE)*/
//注意:当发送数据时,应该将从输入缓冲区中获取数据,
//因为应用程序会将数据放在输入缓冲区中
if(inputBuffer==NULL) //如果输入缓冲区为无效地址
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
}
else
{
// TODO: copy data
// To satisfy the ioctl now, transfer data using the
// caller's buffers at "inputBuffer" and/or "outputBuffer".
// Then, indicate how much data was transferred:
/**************以下为圈圈新增代码************/
if(inputSize==0) //如果输出数据长度为0,则不用传输数据
{
I.Information() = 0;
}
else //数据长度不为0
{
//创建一个中断传输的URB,用来往端点1发送数据
PURB pUrb=Ep1Out.BuildInterruptTransfer( inputBuffer, //发送数据的缓冲区
inputSize, //发送数据的数据字节数
FALSE, //FALSE表示设备传输的字节少数不可以于指定的字节数
NULL, //连接下一个传输的URB,这里没有,置为NULL
NULL, //指向一个已经存在的URB。置为NULL,分配一个新的URB
FALSE); //FALSE表示发送数据
if(pUrb==NULL) //如果分配失败
{
status=STATUS_INSUFFICIENT_RESOURCES; //设置状态为资源不足
I.Information()=0; //数据传输为0
}
else
{
//提交URB,并无限等待
status=Ep1Out.SubmitUrb(pUrb,NULL,NULL,0);
//获取实际发送数据的字节数
I.Information()=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb; //删除刚刚分配的URB
}
}
/*************新增代码完毕****************/
}
T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::EP2_READ_Handler
// Handler for ioctl EP2_READ. The DeviceControl
// method will complete the IRP.
//
// Arguments:
// IN I
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP2_READ_Handler(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = I.IoctlInputBufferSize();
ULONG outputSize = I.IoctlOutputBufferSize();
// Buffered ioctl - using the same buffer so read the buffer before writing the buffer
PVOID inputBuffer = I.IoctlBuffer();
PVOID outputBuffer = I.IoctlBuffer();
// TODO: Validate the parameters of the IRP. Replace "FALSE"
// in the following line with error checking code that
// evaulates to TRUE if the request is not valid.
/*if (FALSE)*/
//注意:当读数据时,应该将数据保存在应用程序提供的输出缓冲中,
//因为驱动程序将会将读到的数据输出给应用程序
if(outputBuffer==NULL) //如果缓冲区为无效地址
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
}
else //如果参数有效
{
// TODO: copy data
// To satisfy the ioctl now, transfer data using the
// caller's buffers at "inputBuffer" and/or "outputBuffer".
// Then, indicate how much data was transferred:
/**************以下为圈圈新增代码************/
if(outputSize==0) //如果读数据长度为0,则不用传输数据
{
I.Information() = 0;
}
else //数据长度不为0
{
//创建一个批量传输的URB,用来从端点2读取数据
PURB pUrb=Ep2In.BuildBulkTransfer( outputBuffer, //接收数据的缓冲区
outputSize, //读数据的数据字节数
TRUE, //TURE表示读数据
NULL, //连接下一个传输的URB,这里没有,置为NULL
TRUE, //TRUE表示设备传输的字节数可以少于指定的字节数
NULL); //指向一个已经存在的URB。置为NULL,分配一个新的URB
if(pUrb==NULL) //如果分配失败
{
status=STATUS_INSUFFICIENT_RESOURCES; //设置状态为资源不足
I.Information()=0; //数据传输为0
}
else
{
//提交URB,并设置等待3秒后就超时
status=Ep2In.SubmitUrb(pUrb,NULL,NULL,3000);
//获取实际读到的数据字节数
I.Information()=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb; //删除刚刚分配的URB
}
}
/*************新增代码完毕****************/
}
T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::EP2_WRITE_Handler
// Handler for ioctl EP2_WRITE. The DeviceControl
// method will complete the IRP.
//
// Arguments:
// IN I
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP2_WRITE_Handler(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = I.IoctlInputBufferSize();
ULONG outputSize = I.IoctlOutputBufferSize();
// Buffered ioctl - using the same buffer so read the buffer before writing the buffer
PVOID inputBuffer = I.IoctlBuffer();
PVOID outputBuffer = I.IoctlBuffer();
// TODO: Validate the parameters of the IRP. Replace "FALSE"
// in the following line with error checking code that
// evaulates to TRUE if the request is not valid.
/*if (FALSE)*/
//注意:当发送数据时,应该将从输入缓冲区中获取数据,
//因为应用程序会将数据放在输入缓冲区中
if(inputBuffer==NULL) //如果输入缓冲区为无效地址
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
}
else
{
// TODO: copy data
// To satisfy the ioctl now, transfer data using the
// caller's buffers at "inputBuffer" and/or "outputBuffer".
// Then, indicate how much data was transferred:
/**************以下为圈圈新增代码************/
if(inputSize==0) //如果输出数据长度为0,则不用传输数据
{
I.Information() = 0;
}
else //数据长度不为0
{
//创建一个批量传输的URB,用来往端点2发送数据
PURB pUrb=Ep2Out.BuildBulkTransfer( inputBuffer, //发送数据的缓冲区
inputSize, //发送数据的数据字节数
FALSE, //FALSE表示发送数据
NULL, //连接下一个传输的URB,这里没有,置为NULL
FALSE, //FALSE表示设备传输的字节少数不可以于指定的字节数
NULL); //指向一个已经存在的URB。置为NULL,分配一个新的URB
if(pUrb==NULL) //如果分配失败
{
status=STATUS_INSUFFICIENT_RESOURCES; //设置状态为资源不足
I.Information()=0; //数据传输为0
}
else
{
//提交URB,并无限等待
status=Ep2Out.SubmitUrb(pUrb,NULL,NULL,0);
//获取实际发送数据的字节数
I.Information()=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb; //删除刚刚分配的URB
}
}
/*************新增代码完毕****************/
}
T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::CleanUp
// Dispatch routine for IRP_MJ_CLEANUP requests.
//
// Arguments:
// IN I
// the cleanup IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::CleanUp(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: At this point, perform custom processing for IRP_MJ_CLEANUP
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::Invalidate
// This method performs resource cleanup.
// This function is called from OnStopDevice, OnRemoveDevice and
// OnStartDevice (in error conditions). It calls the Invalidate
// member funcitons for each resource to free the underlying system
// resource if allocated. It is safe to call Invalidate more than
// once for a resource, or for an uninitialized resource.
//
// Arguments:
// none
//
// Return Value:
// none
//
VOID Computer00UsbDevice::Invalidate()
{
NTSTATUS status = STATUS_SUCCESS;
status = m_Lower.DeActivateConfiguration();
if (!NT_SUCCESS(status))
{
T.Trace(TraceWarning, __FUNCTION__" DeActivateConfiguration failed, STATUS %x\n", status);
}
m_Lower.ReleaseResources();
// Free our registry value buffer
if (DeviceName != NULL)
{
delete DeviceName;
DeviceName = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -