pppoenotify.cpp

来自「pppoe client」· C++ 代码 · 共 445 行

CPP
445
字号
// PPPOENotify.cpp : Implementation of CPPPOENotify

#include "stdafx.h"
#include "PPPOENotify.h"

#include <devguid.h>

#include <stdio.h>
#include <stdlib.h>

template<typename T>
void SafeRelease(T& p)
{
	if(p)
		p->Release(),p = NULL;
}

// CPPPOENotify
CPPPOENotify::CPPPOENotify():m_pNetCfg(NULL),m_pNetCfgComponent(NULL),m_pUnkContext(NULL)
{
	ATLTRACE("CPPPOENotify constructor...\n");
}

CPPPOENotify::~CPPPOENotify()
{
	SafeRelease(m_pNetCfg);
	SafeRelease(m_pNetCfgComponent);
	SafeRelease(m_pUnkContext);

	ATLTRACE("CPPPOENotify destructor...\n");
}

/////// for INetCfgComponentControl

// Initialize
// The Initialize method initializes the notify object of the network component and provides access to the component 
// and to all aspects of network configuration.
// we save those pointers and add a ref to it
HRESULT CPPPOENotify::Initialize(IN INetCfgComponent* pIComp,IN INetCfg* pINetCfg,IN BOOL fInstalling)
{
	ATLASSERT(pIComp);
	ATLASSERT(pINetCfg);

	ATLTRACE("INetCfgComponentControl::Initialize..\n");

	HRESULT hr = S_OK;

	if(fInstalling)
	{
		ATLTRACE("    this is an installation..\n");
	}
	else
	{
		ATLTRACE("   normal network cfg operation.read miniport guid...\n");

		// save the guid to reg
		WCHAR szMiniportguid[MAX_PATH + 1];

		HKEY hParamKey;
		LONG lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,_T("System\\CurrentControlSet\\Services\\TCPPPOE\\Parameters"),
									  0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hParamKey,NULL);
		if(lResult == ERROR_SUCCESS)
		{
			DWORD dwType;
			DWORD dwSize = sizeof(szMiniportguid);
			lResult = RegQueryValueExW(hParamKey,L"miniport",0,&dwType,reinterpret_cast<LPBYTE>(szMiniportguid),&dwSize);

			if(lResult != ERROR_SUCCESS)
			{
				ATLTRACE("   failed to read miniport device guid.\n");
			}
			else
			{
				if(dwType == REG_SZ)
				{
					CLSIDFromString(szMiniportguid,&m_guidMiniport);
					ATLTRACE("   miniport device guid = %ls\n",szMiniportguid);
				}
				else
					lResult = ERROR_INVALID_DATA;
			}
		}

		hr = HRESULT_FROM_WIN32(lResult);
	}

	m_pNetCfg = pINetCfg;
	m_pNetCfgComponent = pIComp;

	m_pNetCfg->AddRef();
	m_pNetCfgComponent->AddRef();

	m_dwChangeType = -1;

	return hr;
}

// ApplyRegistryChanges
// The ApplyRegistryChanges method directs the notify object of the network component to apply to the 
// operating system the proposed changes for the component's network configuration state. 
HRESULT CPPPOENotify::ApplyRegistryChanges()
{
	ATLTRACE("INetCfgComponentControl::ApplyRegistryChanges..\n");

	return S_OK;
}

// ApplyPnpChanges
// The ApplyPnpChanges method informs the notify object of the network component that it can send 
// configuration information to the component's driver.
HRESULT CPPPOENotify::ApplyPnpChanges(IN INetCfgPnpReconfigCallback* pICallback)
{
	ATLTRACE("INetCfgComponentControl::ApplyPnpChanges..\n");

	return S_OK;
}

// CancelChanges
// The CancelChanges method directs the notify object of the network component to disregard any proposed 
// changes for the component's network configuration state. 
HRESULT CPPPOENotify::CancelChanges()
{
	ATLTRACE("INetCfgComponentControl::CancelChanges..\n");

	return S_OK;
}

/////////// for INetCfgComponentSetup

// ReadAnswerFile
// The ReadAnswerFile method directs the notify object of the network component to open a specific file for 
// unattended setup and retrieve the parameters required to configure the network component.
HRESULT CPPPOENotify::ReadAnswerFile(IN PCWSTR szAnswerFile,IN PCWSTR szAnswerSections)
{
	ATLTRACE("INetCfgComponentSetup::ReadAnswerFile..\n");

	return S_OK;
}

// Upgrade
// The Upgrade method directs the notify object of the network component to perform the operations required when 
// the operating system changes to a new, improved, or different version. 
HRESULT CPPPOENotify::Upgrade(IN DWORD dwSetupFlags,IN DWORD dwUpgradeFromBuildNo)
{
	ATLTRACE("INetCfgComponentSetup::Upgrade..\n");

	return S_OK;
}

// Install
// The Install method directs the notify object of the network component to perform operations required to install the component
HRESULT CPPPOENotify::Install(IN DWORD dwSetupFlags)
{
	ATLTRACE("INetCfgComponentSetup::Install..\n");

	ATLTRACE("    setup flags is 0x%x\n",dwSetupFlags);

	return InstallMiniport();
}

// do install
HRESULT CPPPOENotify::InstallMiniport()
{
	INetCfgClass       *pncClass;
	INetCfgClassSetup  *pncClassSetup;
	INetCfgComponent   *pnccMiniport;
	HRESULT            hr;

	hr = m_pNetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NET,IID_INetCfgClass,(void **)&pncClass);
	if(hr == S_OK) 
	{
		ATLTRACE("   query net cfg class ok.\n");

		hr = pncClass->QueryInterface(IID_INetCfgClassSetup,(void **)&pncClassSetup);

		if(hr == S_OK) 
		{
			ATLTRACE("   query net cfg class setup ok.\n");

			hr = pncClassSetup->Install(L"TC_COPPPOEMP",NULL,0,0,NULL,NULL,&pnccMiniport);

			if(hr == S_OK)
			{
				ATLTRACE("   setup pppoe miniport ok\n");

				hr = pnccMiniport->GetInstanceGuid(&m_guidMiniport);

				if(hr != S_OK) 
				{
					ATLTRACE("   failed to get the instance guid, uninstalling  the miniport.\n");

					pncClassSetup->DeInstall(pnccMiniport,NULL,NULL);
				}

				SafeRelease(pnccMiniport);

				// save the guid to reg
				WCHAR szMiniportguid[MAX_PATH + 1];
				StringFromGUID2(m_guidMiniport,szMiniportguid,MAX_PATH + 1);

				HKEY hParamKey;
				LONG lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,_T("System\\CurrentControlSet\\Services\\TCPPPOE\\Parameters"),
											  0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hParamKey,NULL);
				if(lResult == ERROR_SUCCESS)
				{
					ATLTRACE("   create param key ok\n");
					lResult = RegSetValueExW(hParamKey,L"miniport",0,REG_SZ,
											 reinterpret_cast<BYTE CONST*>(szMiniportguid),
											 static_cast<DWORD>((wcslen(szMiniportguid) + 1) * sizeof(WCHAR)));

					if(lResult != ERROR_SUCCESS)
					{
						ATLTRACE("   failed to set miniport guid name.\n");
					}
					else
						ATLTRACE("   set guid name ok\n");
				}

				hr = HRESULT_FROM_WIN32(lResult);
			}
			else 
			{
				ATLTRACE("   failed to install the miniport.\n");
			}

			SafeRelease( pncClassSetup );
		}
		else 
		{
			ATLTRACE("   QueryInterface failed.\n");
		}

		SafeRelease( pncClass );
	}
	else 
	{
		ATLTRACE("   QueryNetCfgClass failed.\n");
	}

	return hr;
}

// do remove
HRESULT CPPPOENotify::RemoveMiniport()
{
	// remove the miniport device
	INetCfgClass       *pncClass;
	INetCfgClassSetup  *pncClassSetup;
	INetCfgComponent   *pnccMiniport;

	HRESULT hr = m_pNetCfg->QueryNetCfgClass(&GUID_DEVCLASS_NET,IID_INetCfgClass,(void **)&pncClass);
	if(hr == S_OK) 
	{
		ATLTRACE("   query net cfg class ok.\n");

		hr = pncClass->QueryInterface(IID_INetCfgClassSetup,(void **)&pncClassSetup);
		if(hr == S_OK) 
		{
			ATLTRACE("   query net cfg class setup ok.\n");

			hr = FindInstance(m_guidMiniport,&pnccMiniport);

			if(hr == S_OK) 
			{
				ATLTRACE("   found the miniport instance to uninstall.\n");

				hr = pncClassSetup->DeInstall(pnccMiniport,NULL,NULL);

				SafeRelease(pnccMiniport);

				if(hr == S_OK)
				{
					ATLTRACE("   miniport uninstall ok.\n");
				}
				else
					ATLTRACE("   miniport uninstall failed 0x%x.\n",hr);
			}
			else 
			{
				ATLTRACE("   can't find the miniport instance to uninstall.\n");
			}

			SafeRelease(pncClassSetup);
		}
		else 
		{
			ATLTRACE("   QueryInterface failed.\n");
		}

		SafeRelease(pncClass);
	}
	else 
	{
		ATLTRACE("   QueryNetCfgClass failed.\n");
	}

	return hr;
}

// Removing
// The Removing method directs the notify object of the network component to perform operations required 
// for the component's removal. 
HRESULT CPPPOENotify::Removing()
{
	ATLTRACE("INetCfgComponentSetup::Removing..\n");

	return RemoveMiniport();
}

////// for INetCfgComponentNotifyBinding

// QueryBindingPath
// The QueryBindingPath method informs the notify object that a binding path is about to be added to its network component.
// This method directs the notify object to evaluate the change and to accept or reject it. 
HRESULT CPPPOENotify::QueryBindingPath(IN DWORD dwChangeFlag,IN INetCfgBindingPath* pncbp)
{
	ATLTRACE("INetCfgComponentNotifyBinding::QueryBindingPath..\n");

	return S_OK;
}

// NotifyBindingPath
// The NotifyBindingPath method informs the notify object that a change occurred to the binding path of its network 
// component. This method directs the notify object to perform operations related to the change.
HRESULT CPPPOENotify::NotifyBindingPath(IN DWORD dwChangeFlag,IN INetCfgBindingPath* pncbp)
{
	ATLTRACE("INetCfgComponentNotifyBinding::NotifyBindingPath..\n");

	IEnumNetCfgBindingInterface *iBindInterfaceEnum = NULL;	INetCfgBindingInterface *iBindInterface = NULL;	LPWSTR lpwName = NULL;	ULONG dwIfaceCount;	pncbp->EnumBindingInterfaces(&iBindInterfaceEnum);	while(S_OK == iBindInterfaceEnum->Next(1, &iBindInterface, &dwIfaceCount) && (dwIfaceCount == 1)) 	{		// %ls		iBindInterface->GetName(&lpwName);		ATLTRACE("        %ls\n",lpwName);	}

	return S_OK;
}

//////// for INetCfgComponentNotifyGlobal

// GetSupportedNotifications
// The GetSupportedNotifications method retrieves the types of notifications that the notify object of the network 
// component requires from the network configuration subsystem.
HRESULT CPPPOENotify::GetSupportedNotifications(OUT DWORD* pdwNotificationFlag)
{
	ATLTRACE("INetCfgComponentNotifyGlobal::GetSupportedNotifications..\n");

	*pdwNotificationFlag = NCN_NET | NCN_NETTRANS | NCN_ADD | NCN_REMOVE;

	return S_OK;
}

// SysQueryBindingPath
// The SysQueryBindingPath method informs the notify object of the network component that the addition of a binding path
// is about to occur.This method also directs the object to evaluate the change and to accept or reject it. 
HRESULT CPPPOENotify::SysQueryBindingPath(IN DWORD dwChangeFlag,IN INetCfgBindingPath* pncbp)
{
	ATLTRACE("INetCfgComponentNotifyGlobal::SysQueryBindingPath..\n");

	return S_OK;
}

// SysNotifyBindingPath
HRESULT CPPPOENotify::SysNotifyBindingPath(IN DWORD dwChangeFlag,IN INetCfgBindingPath* pncbp)
{
	ATLTRACE("INetCfgComponentNotifyGlobal::SysNotifyBindingPath..\n");

	return S_OK;
}

// SysNotifyComponent
HRESULT CPPPOENotify::SysNotifyComponent(IN DWORD dwChangeFlag,IN INetCfgComponent* pncbp)
{
	ATLTRACE("INetCfgComponentNotifyGlobal::SysNotifyComponent..\n");

	return S_OK;
}

// find miniport instance
HRESULT CPPPOENotify::FindInstance (GUID &guidInstance,INetCfgComponent **ppnccMiniport)
{
	IEnumNetCfgComponent  *pencc;
	INetCfgComponent      *pncc;
	GUID                  guid;
	WCHAR                 szGuid[MAX_PATH+1];
	ULONG                 ulCount;
	BOOL                  found;
	HRESULT               hr;

	ATLTRACE("CPPPOENotify::FindInstance.\n" );

	hr = m_pNetCfg->EnumComponents(&GUID_DEVCLASS_NET,&pencc);

	if(hr == S_OK) 
	{
		StringFromGUID2(guidInstance,szGuid,MAX_PATH+1);

		ATLTRACE("  looking for component with InstanceGuid %S\n",szGuid);

		hr = pencc->Next(1,&pncc,&ulCount);

		for(found=FALSE; (hr == S_OK) && (found == FALSE); ) 
		{
			hr = pncc->GetInstanceGuid(&guid);

			if(hr == S_OK) 
			{
				StringFromGUID2(guid,szGuid,MAX_PATH+1 );

				ATLTRACE("  found component with InstanceGuid %S\n",szGuid );

				found = IsEqualGUID(guid,guidInstance);

				if(found == FALSE) 
				{

					SafeRelease(pncc);

					hr = pencc->Next(1,&pncc,&ulCount);
				}
				else 
				{
					*ppnccMiniport = pncc;
				}
			}
		}   

		SafeRelease(pencc);
	}
	else 
	{
		ATLTRACE("   EnumComponents failed(HRESULT = %x).\n",hr);
	}

	return hr;
}

⌨️ 快捷键说明

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