📄 computer00usbdevice.cpp
字号:
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
I.CopyParametersDown();
I.SetCompletionRoutine(LinkTo(OnQueryCapabilitiesComplete), this, TRUE, TRUE, TRUE);
status = m_Lower.PnpCall(this, I);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::OnQueryCapabilitiesComplete
// Completion routine for IRP_MJ_PNP subfcn IRP_MN_QUERY_CAPABILITIES.
// The system calls OnQueryCapabilities to query the device capabilities.
// The Bus driver fills in the device capabilities structure.
// This method is called when the IRP is completed to alter the
// device capabilities reported by the bus driver.
//
// Arguments:
// IN I
// the query capabilities IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::OnQueryCapabilitiesComplete(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.");
NTSTATUS status = I.Status();
if (I->PendingReturned)
I.MarkPending();
if (NT_SUCCESS(status))
{
// TODO: Adjust device capabilities structure as required.
I.DeviceCapabilities()->SurpriseRemovalOK = TRUE;
}
T.Trace(TraceInfo, __FUNCTION__"--.");
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::TestBusInterface
// This routine uses the USB direct client interface to
// query information.
//
// Arguments:
// none
//
// Return Value:
// none
//
void Computer00UsbDevice::TestBusInterface()
{
#if (_WDM_ && (WDM_MAJORVERSION > 1 ||((WDM_MAJORVERSION == 1) && (WDM_MINORVERSION >= 0x20))))
if (m_fBusIntfAvailable)
{
T.Trace(TraceInfo, "USB Bus Interface Version: %u\n", m_BusIntf.Version());
T.Trace(TraceInfo, "High Speed Device: %S\n", (m_BusIntf.IsDeviceHighSpeed()?"TRUE":"FALSE"));
USBD_VERSION_INFORMATION UsbVerInfo;
RtlZeroMemory(&UsbVerInfo, sizeof(USBD_VERSION_INFORMATION));
ULONG HcdCapabilities = 0;
m_BusIntf.GetUSBDIVersion(&UsbVerInfo, &HcdCapabilities);
T.Trace(TraceInfo, "USBDI_Version: %u\n", UsbVerInfo.USBDI_Version);
T.Trace(TraceInfo, "Supported_USB_Version: %u\n", UsbVerInfo.Supported_USB_Version);
ULONG TotalBW, ConsumedBW;
NTSTATUS Status = m_BusIntf.GetBandwidth(&TotalBW,&ConsumedBW);
if (STATUS_SUCCESS == Status)
{
T.Trace(TraceInfo, "Total Bandwidth: %u\n", TotalBW);
T.Trace(TraceInfo, "Consumed Bandwidth: %u\n", ConsumedBW);
}
PWSTR HcName = NULL;
Status = m_BusIntf.GetControllerName(HcName);
if (STATUS_SUCCESS == Status && HcName)
{
T.Trace(TraceInfo, "HC Name: %s\n", HcName);
delete HcName;
}
ULONG CurrentFrame;
m_BusIntf.QueryBusTime(&CurrentFrame);
T.Trace(TraceInfo, "Current Frame: %u\n", CurrentFrame);
}
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::OnDevicePowerUp
// Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER
// for a request to go to power on state from low power state
// This function was called by the framework from the completion
// routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
// The bus driver has completed the IRP and this driver can now
// access the hardware device.
// This routine runs at DISPATCH_LEVEL.
//
// Arguments:
// IN I
// the power IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::OnDevicePowerUp(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: Add device-specific code to:
// Restore any context to the hardware device that
// was saved during the handling of a power down request.
// See the OnDeviceSleep function.
// Do NOT complete this IRP.
// The base class will handle completion of the IRP
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::OnDeviceSleep
// Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER
// for a request to go to a low power state from a high power state
// This function was called by the framework from the IRP_MJ_POWER
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.
// This routine runs at PASSIVE_LEVEL.
//
// Arguments:
// IN I
// the power IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::OnDeviceSleep(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: Add device-specific code to:
// Save any context to the hardware device that will be required
// during a power up request. See the OnDevicePowerUp function.
// Do NOT complete this IRP. The base class handles forwarding
// this IRP to the PDO.
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::Create
// Dispatch routine for IRP_MJ_CREATE requests.
//
// Arguments:
// IN I
// the create IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::Create(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
// TODO: For any IRP, to display the contents of the IRP
// in a formatted way, use the KTrace << operator:
// T << I;
NTSTATUS status = STATUS_SUCCESS;
// For devices that expose an interface instead of symbolic
// link, DO_EXCLUSIVE flag is not used by the I/O manager.
// So, exclusivity must be enforced here.
if (m_OpenCounter.Test() > 0)
{
status = STATUS_SHARING_VIOLATION;
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
// TODO: At this point, perform custom processing for IRP_MJ_CREATE
// Generally a create IRP is targeted at our FDO, so its not needed
// to pass it down to the PDO.
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::Close
// Dispatch routine for IRP_MJ_CLOSE requests.
//
// Arguments:
// IN I
// the close IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::Close(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
// TODO: At this point, perform custom processing for IRP_MJ_CLOSE
// Generally a close IRP is targeted at our FDO, so we don't need
// to pass it down to the PDO.
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::Read
// Dispatch routine for IRP_MJ_READ requests.
//
// Arguments:
// IN I
// the read IRP
//
// Return Value:
// NTSTATUS
// 注:用/**/方式注释掉的代码为向导生成的代码
NTSTATUS Computer00UsbDevice::Read(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
//原来向导生成在后面,从后面移动上来
// Get a pointer to the caller's buffer.
PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();
ULONG readSize = I.ReadSize();
ULONG bytesRead = 0;
// 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(pBuffer==NULL) //如果准备的读缓冲区为无效地址,则返回参数无效
{
status = STATUS_INVALID_PARAMETER; //状态设置为无效参数
I.Information() = 0; //读取字节数为0
I.PnpComplete(status); //完成该IO操作
//调试信息
T.Trace(TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status; //返回状态
}
// Always ok to read 0 elements
if (I.ReadSize() == 0) //如果读长度为0,那么总是成功的
{
I.Information() = 0; //读字节数为0
I.PnpComplete(this, status); //完成该IO
//调试信息
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
/*
移动到了上面
// Get a pointer to the caller's buffer.
PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();
ULONG readSize = I.ReadSize();
ULONG bytesRead = 0;
*/
// TODO: At this point, perform any processing for IRP_MJ_READ
// To satisfy the read now, transfer data from the driver
// to the caller's buffer at "pBuffer". Then, indicate
// how much data was transferred:
/**************以下为圈圈新增代码************/
//创建一个中断传输的URB,用来从端点1读取数据
PURB pUrb=Ep1In.BuildInterruptTransfer( pBuffer, //接收数据的缓冲区
readSize, //读数据的数据字节数
TRUE, //TRUE表示设备传输的字节数可以少于指定的字节数
NULL, //连接下一个传输的URB,这里没有,置为NULL
NULL, //指向一个已经存在的URB。置为NULL,分配一个新的URB
TRUE); //TURE表示读数据
if(pUrb==NULL) //如果分配失败
{
status=STATUS_INSUFFICIENT_RESOURCES; //设置状态为资源不足
}
else
{
//提交URB,并设置等待3秒后就超时
status=Ep1In.SubmitUrb(pUrb,NULL,NULL,3000);
//获取实际读到的数据字节数
bytesRead=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb; //删除刚刚分配的URB
}
/*************新增代码完毕****************/
//保存传输数据的字节数
I.Information() = bytesRead;
//完成该IRP
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Computer00UsbDevice::Write
// Dispatch routine for IRP_MJ_WRITE requests.
//
// Arguments:
// IN I
// the write IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Computer00UsbDevice::Write(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
//原来向导生成在后面,从后面移动上来
// Get a pointer to the caller's buffer.
PUCHAR pBuffer = (PUCHAR) I.BufferedWriteSource();
ULONG writeSize = I.WriteSize();
ULONG bytesSent = 0;
// 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(pBuffer==NULL) //如果要发送的数据缓冲区为无效地址,则返回参数无效
{
status = STATUS_INVALID_PARAMETER; //状态为无效参数
I.Information() = 0; //传输字节为0
I.PnpComplete(status); //完成该IRP
T.Trace(TraceWarning, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
// Always ok to write 0 elements
if (I.WriteSize() == 0) //如果读长度为0,那么总是成功的
{
I.Information() = 0;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
/*
移动到了上面
// Get a pointer to the caller's buffer.
//PUCHAR pBuffer = (PUCHAR) I.BufferedWriteSource();
//ULONG writeSize = I.WriteSize();
//ULONG bytesSent = 0;
*/
// TODO: At this point, perform any processing for IRP_MJ_WRITE
// To satisfy the write now, transfer data to the driver
// from the caller's buffer at "pBuffer". Then, indicate
// how much data was transferred:
/**************以下为圈圈新增代码************/
//创建一个中断传输的URB,用来往端点1发送数据
PURB pUrb=Ep1Out.BuildInterruptTransfer( pBuffer, //发送数据的缓冲区
writeSize, //发送数据的数据字节数
FALSE, //FALSE表示设备传输的字节少数不可以于指定的字节数
NULL, //连接下一个传输的URB,这里没有,置为NULL
NULL, //指向一个已经存在的URB。置为NULL,分配一个新的URB
FALSE); //FALSE表示发送数据
if(pUrb==NULL) //如果分配失败
{
status=STATUS_INSUFFICIENT_RESOURCES; //设置状态为资源不足
}
else
{
//提交URB,并无限等待
status=Ep1Out.SubmitUrb(pUrb,NULL,NULL,0);
//获取实际发送的数据字节数
bytesSent=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
delete pUrb; //删除刚刚分配的URB
}
/*************新增代码完毕****************/
I.Information() = bytesSent;
I.PnpComplete(this, status);
T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -