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; }