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

📄 wmisampledevice.cpp

📁 windows 2000/xpWDM设备驱动程序开发光盘代码
💻 CPP
字号:
// WMISampleDevice.cpp
// Implementation of WMISampleDevice device class
//
// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336)
// Requires Compuware's DriverWorks classes
//

#pragma warning(disable:4065) // Allow switch statement with no cases
		  
#include <vdw.h>
#include "..\WMISampleDeviceinterface.h"

#include "WMISample.h"
#include "WMISampleDevice.h"
#include "..\WMISampleioctl.h"

#pragma hdrstop("WMISample.pch")

extern KTrace t;			// Global driver trace object	

GUID WMISampleDevice_Guid = WMISampleDevice_CLASS_GUID;

KWmiDataBlock<SampleActivity, WMISampleDevice>::METHOD ActivityMethods[] = {
	WMISampleDevice::ResetActivityStatistics,
};	//声明方法指针数组

WMISampleDevice::WMISampleDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
	KPnpDevice(Pdo, &WMISampleDevice_Guid),
	m_SamplePdoInfo(
		m_Wmi,
		&DRIVERWORKS_SAMPLE_PDO_INFORMATION
		),
	m_SampleControl(
		m_Wmi,
		&DRIVERWORKS_SAMPLE_CONTROL_GUID
		),
	m_SampleEvent(
		m_Wmi,
		&DRIVERWORKS_SAMPLE_EVENT_GUID,
		WMIREG_FLAG_EVENT_ONLY_GUID
		),
	m_SampleActivity(
		m_Wmi,
		&DRIVERWORKS_SAMPLE_DATA_GUID,
		WMIREG_FLAG_EXPENSIVE
		)
	//上面将m_Wmi传递给设备对象的所有数据块的构造函数
{

	// 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);

    // Inform the base class of the lower edge device object
	SetLowerDevice(&m_Lower);

	// Initialize the PnP Policy settings to the "standard" policy
	SetPnpPolicy();

// TODO:	Customize the PnP Policy for this device by setting
//			flags in m_Policies.
	((SamplePdoInfo*)m_SamplePdoInfo)->Initialize(Pdo);
	//初试化字符串信息

}

WMISampleDevice::~WMISampleDevice()
{
}

NTSTATUS WMISampleDevice::DefaultPnp(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

NTSTATUS WMISampleDevice::DefaultPower(KIrp I) 
{
	I.IndicatePowerIrpProcessed();
	I.CopyParametersDown();
	return m_Lower.PnpPowerCall(this, I);
}

////////////////////////////////////////////////////////////////////////////////
//  WMISampleDevice::SystemControl
//
//	Routine Description:
//		Default handler for IRP_MJ_SYSTEM_CONTROL
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result returned from lower device
//
//	Comments:
//		This routine just passes the IRP through to the next device since this driver
//		is not a WMI provider.
//

NTSTATUS WMISampleDevice::SystemControl(KIrp I) 
{
	ASSERT (m_Wmi != NULL);

	//分发WMI IRP,即调用KWmiDataBlock的成员函数或WMI方法。
	if ( m_Wmi != NULL )
		return m_Wmi->DispatchSystemControl(*this, I);
	else
	{
		I.ForceReuseOfCurrentStackLocationInCalldown();
		return m_Lower.PnpCall(this, I);
	}
}

NTSTATUS WMISampleDevice::OnStartDevice(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	xClicks=0;
	I.Information() = 0;

	ASSERT(m_Wmi != NULL);
	// Perform WMI initialization
	if ( m_Wmi != NULL )
	{
		// Here we set the method pointer array for the block which has associated
		// methods. If we had other blocks for CIM classes with methods, those would
		// also require a corresponding call to m_Wmi->SetMethods.

		//设置方法处理函数。如果别的数据块也含有方法,也需调用SetMethods。
		m_Wmi->SetMethods(1, ActivityMethods);

		//注册WMI数据块信息。
		// Now register the blocks for this device with WMI.
	   status = m_Wmi->Register(*this, L"MofResource");
	}
	return status;
}

NTSTATUS WMISampleDevice::OnStopDevice(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	ASSERT(m_Wmi != NULL);
	if ( m_Wmi != NULL )
	{
		//注销WMI数据块信息。
		m_Wmi->Deregister();

		//解除方法处理函数。
		m_Wmi->SetMethods(0, ActivityMethods);
	}
	return status;

}

NTSTATUS WMISampleDevice::OnRemoveDevice(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	ASSERT(m_Wmi != NULL);
	if ( m_Wmi != NULL )
	{
		//  This call tells WMI that the blocks for this device are unavailable.
		m_Wmi->Deregister();

		// This call to SetMethods releases the method pointer array.
		m_Wmi->SetMethods(0, ActivityMethods);
	}
	return status;
}

NTSTATUS WMISampleDevice::Create(KIrp I)
{
	return I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
}


NTSTATUS WMISampleDevice::Close(KIrp I)
{
	return I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
}

NTSTATUS WMISampleDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status = STATUS_SUCCESS;
	t << "DeviceControl\n";
	switch (I.IoctlCode())
	{
		case INCX:
			xClicks++;	//事件计数值加1
			break;

		case DECX:
			xClicks--;	//事件计数值减1
			break;

		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			break;
	}

	if ( m_SampleActivity.TestCollectionEnabled()) {
		//允许数据采集
		SampleActivity* pActivity=m_SampleActivity;
		pActivity->m_xClicks=xClicks;
	}
	if ( m_SampleEvent.TestEventsEnabled()) {
		//允许数据发送
		SampleControl* pControl=m_SampleControl;
		if (xClicks > pControl->m_xEventThreshold)
		{
			SampleEvent* pEvent = m_SampleEvent;
			pEvent->m_xClicks = xClicks;
			m_SampleEvent.FireEvent();
		}
	}
	return I.PnpComplete(this, status);
}

/////////////////////////////////////////////////////////////////////
// MouseFilterDevice::ResetActivityStatistics
//
//		Zero out all stats
//
// Input
//		pActivityStats		pointer to activity stats struct
//
// Output
//		all stats reset
//
// Notes:
//		This routine implements a WMI method.

NTSTATUS WMISampleDevice::ResetActivityStatistics(
	SampleActivity* pActivityStats,
	ULONG inSize,
	ULONG outSize,
	PUCHAR Buffer,
	PULONG pBufferUsed
	)
{	//方法处理函数
	xClicks=0;
	pActivityStats->m_xClicks = 0;
	*pBufferUsed = 0;

	return STATUS_SUCCESS;

	UNREFERENCED_PARAMETER(inSize);
	UNREFERENCED_PARAMETER(outSize);
	UNREFERENCED_PARAMETER(Buffer);
}

/////////////////////////////////////////////////////////////////////
// KWmiDataBlock<SamplePdoInfo>::Query
//
//		Specialization of KWmiDataBlock<>::Query for SamplePdoInfo
//
// Input
// 		pIrp				current IRP
//		BufferSize			size of output buffer
//		pPdoInfo			output struct
//		pBufferUsed			addr of var to get count of bytes written
// 		Last				true if last request for IRP
//
// Note
//		This specialization of the template form is required because
//		the block contains variably sized data ( a string ).
//
NTSTATUS KWmiDataBlock<SamplePdoInfo>::Query(
	PIRP pIrp,
	ULONG BufferSize,
	SamplePdoInfo* pPdoInfo,
	PULONG pBufferUsed,
	BOOLEAN Last
	)
{	//字符串查询例程,必须自己创建
	USHORT usBufferSize = USHORT(BufferSize);
	SamplePdoInfo* pInfo = *this;
	USHORT* pOutput = reinterpret_cast<USHORT*>(pPdoInfo);
	ULONG SizeRequired;

	if ( (pInfo->m_pPdoName == NULL) || (pInfo->m_pPdoRegistryPath == NULL) )
	{
		*pOutput++ = 0;
		*pOutput++ = 0;
		*pBufferUsed = 2*sizeof(USHORT);
		return STATUS_SUCCESS;
	}
	SizeRequired = pInfo->m_pPdoName->Size() + pInfo->m_pPdoRegistryPath->Size();

	if (BufferSize < SizeRequired)
		return STATUS_BUFFER_TOO_SMALL;
	else
		*pBufferUsed = SizeRequired;

	pInfo->m_pPdoName->Get(pOutput, usBufferSize);
	pInfo->m_pPdoRegistryPath->Get(pOutput, usBufferSize);

	return STATUS_SUCCESS;

	UNREFERENCED_PARAMETER(Last);
	UNREFERENCED_PARAMETER(pIrp);
}

////////////////////////////////////////////////////////////////////////
// SamplePdoInfo::Initialize
//
//	Initialization Method for SamplePdoInfo
//
NTSTATUS SamplePdoInfo::Initialize(PDEVICE_OBJECT Pdo)
{	//初试化字符串信息
	WCHAR Scratch[100];
	NTSTATUS status;
	ULONG Length;

	status = IoGetDeviceProperty(
		Pdo,
		DevicePropertyPhysicalDeviceObjectName,
		sizeof Scratch - sizeof(WCHAR),
		Scratch,
		&Length
		);	//获取设备名

	if ( !NT_SUCCESS(status) )
	{
		return status;
	}

	m_pPdoName = new (Scratch, static_cast<USHORT>(Length)) KWmiString();

	status = IoGetDeviceProperty(
		Pdo,
		DevicePropertyDriverKeyName,
		sizeof Scratch - sizeof(WCHAR),
		Scratch,
		&Length
		); 	//获取设备注册表路径

	if ( !NT_SUCCESS(status) )
	{
		return status;
	}

	m_pPdoRegistryPath = new(Scratch, static_cast<USHORT>(Length)) KWmiString();

	return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -