www.pudn.com > PPPOE.rar > COPPPOENotify.cpp


// COPPPOENotify.cpp : Implementation of CCOPPPOENotify 
 
#include "stdafx.h" 
#include "COPPPOENotify.h" 
 
#include  
 
#include  
#include  
 
template 
void SafeRelease(T& p) 
{ 
	if(p) 
		p->Release(),p = NULL; 
} 
// CCOPPPOENotify 
 
// CPPPOENotify 
CCOPPPOENotify::CCOPPPOENotify():m_pNetCfg(NULL),m_pNetCfgComponent(NULL),m_pUnkContext(NULL) 
{ 
	ATLTRACE("CCOPPPOENotify constructor...\n"); 
} 
 
CCOPPPOENotify::~CCOPPPOENotify() 
{ 
	SafeRelease(m_pNetCfg); 
	SafeRelease(m_pNetCfgComponent); 
	SafeRelease(m_pUnkContext); 
 
	ATLTRACE("CCOPPPOENotify 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 CCOPPPOENotify::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\\TCCOPPPOE\\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(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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::Install(IN DWORD dwSetupFlags) 
{ 
	ATLTRACE("INetCfgComponentSetup::Install..\n"); 
 
	ATLTRACE("    setup flags is 0x%x\n",dwSetupFlags); 
 
	return InstallMiniport(); 
} 
 
// do install 
HRESULT CCOPPPOENotify::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\\TCCOPPPOE\\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(szMiniportguid), 
						static_cast((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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::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 CCOPPPOENotify::SysQueryBindingPath(IN DWORD dwChangeFlag,IN INetCfgBindingPath* pncbp) 
{ 
	ATLTRACE("INetCfgComponentNotifyGlobal::SysQueryBindingPath..\n"); 
 
	return S_OK; 
} 
 
// SysNotifyBindingPath 
HRESULT CCOPPPOENotify::SysNotifyBindingPath(IN DWORD dwChangeFlag,IN INetCfgBindingPath* pncbp) 
{ 
	ATLTRACE("INetCfgComponentNotifyGlobal::SysNotifyBindingPath..\n"); 
 
	return S_OK; 
} 
 
// SysNotifyComponent 
HRESULT CCOPPPOENotify::SysNotifyComponent(IN DWORD dwChangeFlag,IN INetCfgComponent* pncbp) 
{ 
	ATLTRACE("INetCfgComponentNotifyGlobal::SysNotifyComponent..\n"); 
 
	return S_OK; 
} 
 
// find miniport instance 
HRESULT CCOPPPOENotify::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; 
}