⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbcounterdevice.cpp

📁 WDM设备驱动程序开发(武安河)配套光盘实例源码。
💻 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 + -