📄 usbcounterdevice.cpp
字号:
// USBCounterDevice.cpp
// Implementation of USBCounterDevice device class
//
// Generated by DriverWizard version DriverStudio 3.1.0 (Build 1722)
// Requires Compuware's DriverWorks classes
//
#pragma warning(disable:4065) // Allow switch statement with no cases
#include <vdw.h>
#include <kusb.h>
#include "..\USBCounterDeviceinterface.h"
#include "USBCounter.h"
#include "USBCounterDevice.h"
#include "..\USBCounterioctl.h"
#pragma hdrstop("USBCounter.pch")
extern KTrace t; // Global driver trace object
GUID USBCounterDevice_Guid = USBCounterDevice_CLASS_GUID;
USBCounterDevice::USBCounterDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(Pdo, &USBCounterDevice_Guid)
{
t << "Entering USBCounterDevice (constructor)\n";
// Check constructor status
if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
return;
}
// Remember our unit number
m_Unit = Unit;
// Initialize the lower device
m_Lower.Initialize(this, Pdo);
// Initialize the interface object. The wizard generates code
// to support a single interface. You may create and add additional
// interfaces. By default, the wizard uses InterfaceNumber 0 (the
// first interface descriptor), ConfigurationValue 1 (the first
// configuration descriptor), and initial interface alternate
// setting of 0. If your device has multiple interfaces or alternate
// settings for an interface, you can add additional KUsbInterface
// objects or adjust the parameters passed to this function.
m_Interface.Initialize(
m_Lower, //KUsbLowerDevice
0, //InterfaceNumber
1, //ConfigurationValue
0 //Initial Interface Alternate Setting
); //初试化USB设备接口
// Initialize each Pipe object
m_Endpoint1IN.Initialize(m_Lower, 0x81, 8); //初试化USB设备端点
// Inform the base class of the lower edge device object
SetLowerDevice(&m_Lower);
// Initialize the PnP Policy settings to the "standard" policy
SetPnpPolicy();
// Initialize the Power Policy settings to the "standard" policy
// SetPowerPolicy();
// TODO: Customize the PnP Policy for this device by setting
// flags in m_Policies.
m_pItem.Initialize(Pdo); //初试化工作项
}
USBCounterDevice::~USBCounterDevice()
{
t << "Entering ~USBCounterDevice() (destructor)\n";
}
NTSTATUS USBCounterDevice::DefaultPnp(KIrp I)
{
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
NTSTATUS USBCounterDevice::DefaultPower(KIrp I)
{
I.IndicatePowerIrpProcessed();
I.CopyParametersDown();
return m_Lower.PnpPowerCall(this, I);
}
NTSTATUS USBCounterDevice::SystemControl(KIrp I)
{
I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Lower.PnpCall(this, I);
}
NTSTATUS USBCounterDevice::OnStartDevice(KIrp I)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
t << "Entering OnStartDevice\n";
AC_STATUS acStatus = AC_SUCCESS;
I.Information() = 0;
// The default Pnp policy has already cleared the IRP with the lower device
//By default, the wizard passes a ConfigurationValue of 1 to
//ActivateConfiguration(). This corresponds to the first configuration
//that the device reports in its configuration descriptor. If the device
//supports multiple configurations, pass the appropriate
//ConfigurationValue of the configuration to activate here.
acStatus = m_Lower.ActivateConfiguration(
1 // ConfigurationValue 1 (the first configuration)
); //激活USB设备配置
if ((acStatus == AC_SUCCESS) || (acStatus == AC_FAILED_TO_OPEN_PIPE_OBJECT))
{
status = STATUS_SUCCESS;
GetStringDescriptors(); //调用获取设备描述符例程
m_kIrp = KIrp::Allocate( m_Lower.StackRequirement() ); //创建IRP
if ( m_kIrp == NULL )
{
m_Lower.DeActivateConfiguration();
m_Lower.ReleaseResources();
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
// allocate and initialize an URB
m_pUrb = m_Endpoint1IN.BuildInterruptTransfer(
m_buffer, // transfer buffer
1, // transfer buffer size
TRUE, // Short Ok
NULL, // link urb
NULL // new urb
); //创建新的中断传输URB
if ( m_pUrb == NULL )
{
KIrp::Deallocate(m_kIrp);
m_Lower.DeActivateConfiguration();
m_Lower.ReleaseResources();
status = STATUS_INSUFFICIENT_RESOURCES;
}
}
}
return status; // base class completes the IRP
}
NTSTATUS USBCounterDevice::OnStopDevice(KIrp I)
{
t << "Entering OnStopDevice\n";
m_Lower.DeActivateConfiguration(); //中止USB设备当前活动配置
return STATUS_SUCCESS;
}
NTSTATUS USBCounterDevice::OnRemoveDevice(KIrp I)
{
t << "Entering OnStopDevice\n";
//删除IRP和URB
if ( m_kIrp != NULL ) KIrp::Deallocate(m_kIrp);
if ( m_pUrb != NULL ) delete m_pUrb;
// Device removed, release the system resources used by the USB lower device.
m_Lower.ReleaseResources(); //释放动态分配的USB资源
return STATUS_SUCCESS;
}
// USBCounterDevice::OnQueryCapabilities
//
// Handler for IRP_MJ_PNP subfunction IRP_MN_QUERY_CAPABILITIES
//
// This function is implemented to allow surprise removal of the counter
//
NTSTATUS USBCounterDevice::OnQueryCapabilities(KIrp I)
{
I.CopyParametersDown();
I.SetCompletionRoutine(LinkTo(OnQueryCapabilitiesComplete), this);
return m_Lower.PnpCall(this, I);
}
NTSTATUS USBCounterDevice::OnQueryCapabilitiesComplete(KIrp I)
{
if (I->PendingReturned) I.MarkPending();
I.DeviceCapabilities()->SurpriseRemovalOK = TRUE;
//当USB设备被意外拔去后,系统便不再出现警示界面提示
return STATUS_SUCCESS;
}
NTSTATUS USBCounterDevice::Create(KIrp I)
{
return I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
}
NTSTATUS USBCounterDevice::Close(KIrp I)
{
return I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
}
NTSTATUS USBCounterDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
t << "Entering Device Control, " << I << EOL;
switch (I.IoctlCode())
{
case READ_COUNTER:
status = ReadCounterAsynch(I);
break;
case RESET_COUNTER:
status = ResetCounter();
break;
default:
status = STATUS_INVALID_PARAMETER;
break;
}
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}
void USBCounterDevice::GetStringDescriptors(void)
{
NTSTATUS status = STATUS_SUCCESS;
PWCHAR String = (PWCHAR) new (NonPagedPool) WCHAR[MAXIMUM_USB_STRING_LENGTH];
if(NULL == String)
{
//error during allocation
t << "ERROR: Memory allocation error in GetStringDescriptors().\n";
return;
}
USB_DEVICE_DESCRIPTOR desc;
status = m_Lower.GetDeviceDescriptor( &desc ); //获取设备描述符
if ( !NT_SUCCESS(status) )
{
t << "ERROR: Could not get Device Descriptor.\n";
delete String;
return;
}
//下面显示设备描述符信息
t << "Index of Manufacturer string = " << desc.iManufacturer << "\n";
t << "Index of Product string = " << desc.iProduct << "\n";
t << "Index of Serial Number string = " << desc.iSerialNumber << "\n";
t << "Number of configurations = " << desc.bNumConfigurations << "\n";
t << "Index of configuration string = " << m_Lower.m_Config->iConfiguration << "\n";
t << "***** USB Counter String Descriptors *****\n";
for(UCHAR i = 0; i <= NUM_STRING_DESCRIPTORS; i++)
{
RtlZeroMemory(String, MAXIMUM_USB_STRING_LENGTH * sizeof(WCHAR));
if(NT_SUCCESS(status = m_Lower.GetStringDescriptor(
i,
String,
MAXIMUM_USB_STRING_LENGTH,
0x109)))
{
if (i==0)
{
PUSHORT languageid = (PUSHORT)String;
t << "String " << i << ": " << *languageid << "\n";
}
else
t << "String " << i << ": " << String << "\n";
}
else
{
t << "GetStringDescriptor returns status = " << ULONG(status) << "\n";
}
}
delete String;
}
NTSTATUS USBCounterDevice::ResetCounter()
{ //复位计数值
PURB pUrb;
NTSTATUS status;
UCHAR buffer[8];
memset(buffer, 0, 8);
pUrb = m_Lower.BuildVendorRequest(
buffer, // transfer buffer
8, // transfer buffer size
0, // request reserved bits
0, // request
0, // Value
TRUE, // In (??)
TRUE, // Short Ok
NULL, // link urb
0, // index
URB_FUNCTION_VENDOR_ENDPOINT // function
); //创建控制传输URB
if ( pUrb == NULL )
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
// submit the URB to USBD
status = m_Lower.SubmitUrb(pUrb);
//将URB发送给系统USB总线驱动程序进行处理
delete pUrb;
}
return status;
}
NTSTATUS USBCounterDevice::ReadCounterAsynch(KIrp I)
{ //获取计数值
I.Information() = 0;
m_pUrb = m_Endpoint1IN.BuildInterruptTransfer(
m_buffer, // transfer buffer
1, // transfer buffer size
TRUE, // Short Ok
NULL, // link urb
m_pUrb // urb
); //创建中断传输URB,原来的m_pUrb
if ( m_pUrb == NULL )
{
return STATUS_INSUFFICIENT_RESOURCES;;
}
PVOID CI = InterlockedCompareExchangePointer( (PVOID*)&CurrentIrp(), PVOID( PIRP(I)), NULL);
// Allow only one request at a time
if ( CI != NULL ) return STATUS_DEVICE_BUSY;
CancelSpinLock::Acquire();
if ( I.WasCanceled() )
{
CurrentIrp() = NULL;
CancelSpinLock::Release();
return STATUS_CANCELLED;
}
I.SetCancelRoutine( LinkTo(Cancel) );
CancelSpinLock::Release();
I.MarkPending();
t << "Submit URB\n";
// submit the URB to USBD
//IncrementOutstandingRequestCount();
m_Endpoint1IN.SubmitUrb(m_kIrp, m_pUrb, LinkTo(ReadCounterComplete), this);
//将URB发送给系统USB总线驱动程序进行处理,并设置完成例程
return STATUS_PENDING;
}
NTSTATUS USBCounterDevice::ReadCounterComplete(KIrp I)
{
NTSTATUS status;
t << "Completion routine\n";
KIrp Current( CurrentIrp() );
// If there is no current IRP, just release resources and return
if ( !Current.IsNull() )
{
CancelSpinLock::Acquire();
if ( Current.WasCanceled() )
{
CancelSpinLock::Release();
}
else
{
Current.SetCancelRoutine(NULL);
CancelSpinLock::Release();
CurrentIrp() = NULL;
if ( I.Status() != STATUS_SUCCESS )
{ //URB传输错误
status = I.Status();
}
else
{ //URB传输正确
status = STATUS_SUCCESS;
// find the buffer pointer in the URB
PUCHAR buffer = (PUCHAR)m_pUrb->UrbBulkOrInterruptTransfer.TransferBuffer;
//源数据
// Dump the buffer
PUCHAR IrpBuffer = PUCHAR(Current.IoctlBuffer());
//目的数据
IrpBuffer[0] = buffer[0]; //拷贝数据
Current.Information() = 1;
}
Current.PnpComplete(this, status);
}
}
//DecrementOutstandingRequestCount();
// return indicates that system is to quit processing IRP completion
return STATUS_MORE_PROCESSING_REQUIRED;
}
VOID USBCounterDevice::Cancel(KIrp I)
{
if ( (PIRP)I == CurrentIrp() )
{
CurrentIrp() = NULL;
CancelSpinLock::Release(I.CancelIrql());
I.Information() = 0;
I.PnpComplete(this, STATUS_CANCELLED);
IncrementOutstandingRequestCount();
m_pItem.Queue(LinkTo(Workitem), this); //排队工作项
}
else
CancelSpinLock::Release(I.CancelIrql());
}
VOID USBCounterDevice::Workitem()
{
m_Endpoint1IN.Abort(); //放弃中断传输
DecrementOutstandingRequestCount();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -