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

📄 test.cpp

📁 学习了2个月时间 走了不少弯路 现奉上搜集到的驱动开发入门笔记 共勉!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Test.cpp - WMI test program
// Copyright (C) 1999 by Walter Oney
// All rights reserved

#include "stdafx.h"
#include <initguid.h>
#include "..\sys\guids.h"
#include <winioctl.h>
#include "..\sys\ioctls.h"

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

void ReportError(LPCTSTR fcn, DWORD code);
void ReportInfo(IWbemServices* services, LPCWSTR classname);
void ReceiveEvent(IWbemServices* services, LPCWSTR classname);
void CallMethod(IWbemServices* services, LPCWSTR classname, LPCWSTR methname);

///////////////////////////////////////////////////////////////////////////////

int main(int argc, LPTSTR argv[])
	{							// main
	// Initialize COM and get a pointer to the WbemLocator interface. We must use
	// the DCOM flavor of services on a computer where DCOM is installed. WBEMTEST
	// loads ole32.dll and uses GetProcAddress to learn these addresses. This test
	// program simply assumes that it's running in a DCOM-enabled environment.

	HRESULT hr = CoInitializeEx(NULL, 0);
	if (!SUCCEEDED(hr))
		{						// can't initialize COM
		ReportError(_T("CoInitialize"), hr);
		return 1;
		}						// can't initialize COM

	hr = CoInitializeSecurity(NULL, -1, NULL, NULL, 
		RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, 
		NULL, 0, 0);
	if (!SUCCEEDED(hr))
		{						// can't fix security
		ReportError(_T("CoInitializeSecurity"), hr);
		CoUninitialize();
		return 1;
		}						// can't fix security

	IWbemLocator* locator;
	hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (PVOID*) &locator);
	if (SUCCEEDED(hr))
		{						// found locator

		// Connect to the WMI server on this computer. Note that ConnectServer requires
		// us to allocate a system string for the namespace argument -- a constant causes
		// a crash in the WMI server.

		IWbemServices* services;
		BSTR pnamespace = SysAllocString(L"root\\WMI");
		hr = locator->ConnectServer(pnamespace, NULL, NULL, 0, 0, NULL, NULL, &services);
		SysFreeString(pnamespace);
		if (SUCCEEDED(hr))
			{					// found server

			// Set the interface security to allow the server to impersonate us. Failing to
			// to do this causes an "access denied" failure in CreateInstanceEnum.

			IClientSecurity* security;
			hr = services->QueryInterface(IID_IClientSecurity, (PVOID*) &security);
			if (SUCCEEDED(hr))
				{				// set security
				hr = security->SetBlanket(services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
					NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE,
					NULL, EOAC_NONE);
				if (!SUCCEEDED(hr))
					ReportError(_T("IClientSecurity::SetBlanket"), hr);
				security->Release();
				}				// set security

			// Report WMI information about the specified class

			ReportInfo(services, L"wmiextra_expensive");

			// Test event reception

			ReceiveEvent(services, L"wmiextra_event");

			// Test method invocation

			CallMethod(services, L"wmiextra_method", L"AnswerMethod");

			services->Release();
			}					// found server
		else
			ReportError(_T("IWbemLocator::ConnectServer"), hr);

		locator->Release();
		}						// found locator
	else
		ReportError(_T("CoCreateInstance(WbemLocator)"), hr);

	CoUninitialize();
	return 0;
	}							// main

///////////////////////////////////////////////////////////////////////////////

void ReportInfo(IWbemServices* services, LPCWSTR classname)
	{							// ReportInfo

	// Open an instance enumerator for the class.

	IEnumWbemClassObject* enumerator = NULL;
	BSTR pclass = SysAllocString(classname);
	HRESULT hr = services->CreateInstanceEnum(pclass, WBEM_FLAG_SHALLOW | WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator);

	if (SUCCEEDED(hr))
		{						// enumerate instances
		while (TRUE)
			{					// for each instance
			ULONG junk;				
			IWbemClassObject* cop = NULL;
			hr = enumerator->Next(INFINITE, 1, &cop, &junk); // i.e., no timeout, 1 object wanted
			if (hr == WBEM_S_FALSE)
				break;
			if (hr)
				{
				ReportError(_T("IEnumWbemClassObject::Next"), hr);
				break;
				}

			VARIANT instname;
			BSTR propname;

			// Determine the instance name

			propname = SysAllocString(L"InstanceName");
			hr = cop->Get(propname, 0, &instname, NULL, NULL);
			SysFreeString(propname);

			if (!SUCCEEDED(hr))
				{				// can't get instance name
				ReportError(_T("IWbemClassObject::Get(InstanceName)"), hr);
				cop->Release();
				continue;
				}				// can't get instance name

			// Determine the current value of the property
			
			VARIANT answer;
			propname = SysAllocString(L"ExpensiveData");
			hr = cop->Get(propname, 0, &answer, NULL, NULL);

			if (!SUCCEEDED(hr))
				{				// can't get instance name
				ReportError(_T("IWbemClassObject::Get(ExpensiveData)"), hr);
				SysFreeString(propname);
				cop->Release();
				continue;
				}				// can't get instance name

			printf(_T("The answer from %ws was %d\n"), instname.bstrVal, answer.lVal);

			SysFreeString(propname);
			VariantClear(&instname);
			VariantClear(&answer);
			
			cop->Release();
			}
		enumerator->Release();
		}
	else
		ReportError("CreateInstanceEnum", hr);

	SysFreeString(pclass);
	}							// ReportInfo

///////////////////////////////////////////////////////////////////////////////

void ReceiveEvent(IWbemServices* services, LPCWSTR classname)
	{							// ReceiveEvent
	BSTR language = SysAllocString(L"WQL");

	WCHAR query[256];
	wcscpy(query, L"select * from ");
	wcscat(query, classname);
	BSTR pquery = SysAllocString(query);

	IEnumWbemClassObject* enumerator = NULL;
	HRESULT hr = services->ExecNotificationQuery(language, pquery,
		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &enumerator);
	SysFreeString(pquery);
	SysFreeString(language);

	if (!SUCCEEDED(hr))
		{
		ReportError(_T("IWbemServices::ExecNotificationQuery"), hr);
		return;
		}

	// For purposes of this simple-minded test, send our driver an IOCTL that will make
	// it generate an event. Then poll a few times for the event we expect to have
	// delivered

	HANDLE hDevice = CreateFile(_T("\\\\.\\WMIEXTRA"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hDevice == INVALID_HANDLE_VALUE)
		ReportError(_T("CreateFile"), GetLastError());
	else
		{						// trigger event
		DWORD junk;
		if (DeviceIoControl(hDevice, IOCTL_FIRE_EVENT, NULL, 0, NULL, 0, &junk, NULL))
			{					// wait for event
			for (int i = 0; i < 10; ++i)
				{				// poll
				IWbemClassObject* cop = NULL;
				hr = enumerator->Next(1000, 1, &cop, &junk);
				if (hr == WBEM_S_FALSE || hr == WBEM_S_TIMEDOUT)
					continue;
				if (hr)
					{
					ReportError(_T("IEnumWbemClassObject::Next"), hr);
					break;
					}

				BSTR propname;
				VARIANT instname, evdata;

				// Determine which instance signalled the event

				propname = SysAllocString(L"InstanceName");
				hr = cop->Get(propname, 0, &instname, NULL, NULL);
				SysFreeString(propname);

				if (SUCCEEDED(hr))
					{

					// Get the event data and print a message

					propname = SysAllocString(L"EventInfo");
					hr = cop->Get(propname, 0, &evdata, NULL, NULL);
					if (SUCCEEDED(hr))
						{
						printf(_T("Instance %ws signalled event with data %d after %d poll(s)\n"), instname.bstrVal, evdata.lVal, i);
						}
					else
						ReportError(_T("IWbemClassObject::Get(EventInfo)"), hr);

					VariantClear(&instname);
					}
				else
					ReportError(_T("IWbemClassObject::Get(InstanceName)"), hr);

				cop->Release();
				break;
				}				// poll

			if (i >= 10)
				puts(_T("No events found after 10 attempts"));
			}					// wait for event
		else
			ReportError(_T("DeviceIoControl"), GetLastError());

		CloseHandle(hDevice);
		}						// trigger event

	enumerator->Release();
	}							// ReceiveEvent

⌨️ 快捷键说明

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