///////////////////////////////////////////////////////////////////////////// // // Microsoft // // AlgSetup.cpp : Implementation of CAlgSetup // // JPDup 2001.01.01 // //#include "pch.h" #pragma hdrstop #include "resource.h" #include "htmlhelp.h" #include "sautil.h" ///////////////////////////////////////////////////////////////////////////// // CConfirmation // class CConfirmation : public CDialogImpl { public: CConfirmation( LPCTSTR pszPublisher, LPCTSTR pszProduct, LPCTSTR pszPorts ) { m_pszCompany = pszPublisher; m_pszProduct = pszProduct; m_pszPorts = pszPorts; } ~CConfirmation() { } enum { IDD = IDD_CONFIRMATION }; BEGIN_MSG_MAP(CConfirmation) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) COMMAND_ID_HANDLER(IDOK, OnOK) COMMAND_ID_HANDLER(IDCANCEL, OnCancel) MESSAGE_HANDLER(WM_NOTIFY, OnNotify) END_MSG_MAP() // Handler prototypes: // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { SetDlgItemText(IDC_EDIT_COMPANY, m_pszCompany); SetDlgItemText(IDC_EDIT_PRODUCT, m_pszProduct); SetDlgItemText(IDC_EDIT_PORTS, m_pszPorts); return 1; // Let the system set the focus } LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; } LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; } LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if ( CID_SA_ST_ICFLink == wParam ) { UINT nCode = ((NMHDR* )lParam)->code; if ( NM_CLICK == nCode || NM_RETURN == nCode ) { // one help topic per SKU, LPWSTR pszHelpTopic = NULL; OSVERSIONINFOEXW verInfo = {0}; ULONGLONG ConditionMask = 0; verInfo.dwOSVersionInfoSize = sizeof(verInfo); verInfo.wProductType = VER_NT_WORKSTATION; verInfo.wSuiteMask = VER_SUITE_PERSONAL; VER_SET_CONDITION(ConditionMask, VER_PRODUCT_TYPE, VER_LESS_EQUAL); if ( 0 != VerifyVersionInfo(&verInfo, VER_PRODUCT_TYPE, ConditionMask) ) { VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR); if ( 0 != VerifyVersionInfo(&verInfo, VER_PRODUCT_TYPE | VER_SUITENAME, ConditionMask) ) { // personal pszHelpTopic = TEXT("netcfg.chm::/hnw_plugin_using.htm"); } else { // pro pszHelpTopic = TEXT("netcfg.chm::/hnw_plugin_using.htm"); } } else { // server pszHelpTopic = TEXT("netcfg.chm::/hnw_plugin_using.htm"); } HtmlHelp(NULL, pszHelpTopic, HH_DISPLAY_TOPIC, 0); return 0; } } return 1; } ULONG_PTR m_nSHFusion; LPCTSTR m_pszCompany; LPCTSTR m_pszProduct; LPCTSTR m_pszPorts; }; ///////////////////////////////////////////////////////////////////////////// // CDlgInstallError class CDlgInstallError : public CDialogImpl { public: CDlgInstallError( LONG nLastError ) { m_nLastError = nLastError; //SHActivateContext(&m_nSHFusion); } ~CDlgInstallError() { //SHDeactivateContext(m_nSHFusion); } enum { IDD = IDD_INSTALLERROR }; BEGIN_MSG_MAP(CDlgInstallError) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) COMMAND_ID_HANDLER(IDOK, OnOK) COMMAND_ID_HANDLER(IDCANCEL, OnCancel) END_MSG_MAP() // Handler prototypes: // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, m_nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); SetDlgItemInt(IDC_EDIT_LASTERROR_CODE, m_nLastError, false); SetDlgItemText(IDC_EDIT_LASTERROR, (LPCTSTR)lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); return 1; // Let the system set the focus } LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; } LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog(wID); return 0; } // // Properties // private: ULONG_PTR m_nSHFusion; LONG m_nLastError; }; // // // STDMETHODIMP CAlgSetup::Add( BSTR pszProgID, BSTR pszPublisher, BSTR pszProduct, BSTR pszVersion, short nProtocol, BSTR pszPorts ) { USES_CONVERSION; LONG lRet; // // Open the main ALG hive // CRegKey RegKeyISV; lRet = RegKeyISV.Create(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\ALG")); if ( ERROR_SUCCESS != lRet ) { // // The OS is not setup correctly // ALG hive should have been present. // return HRESULT_FROM_WIN32(lRet); } lRet = RegKeyISV.Create(RegKeyISV, TEXT("ISV")); if ( ERROR_SUCCESS != lRet ) { // // Weird we are able to create/open the parent hive but not the ISV hive // return HRESULT_FROM_WIN32(lRet); } // // Will attempt to Open/Create the ALG hive key to see if the user has ADMINI rights // if not then we will reject the install no need to confirm the install since he can't write to the registry // CRegKey KeyThisAlgModule; lRet = KeyThisAlgModule.Create(RegKeyISV, OLE2T(pszProgID)); if ( ERROR_SUCCESS != lRet ) { CDlgInstallError DlgInstallError(lRet); DlgInstallError.DoModal(); return HRESULT_FROM_WIN32(lRet); } // // // Confirm that the ALG of the company/product is wanted by the user // // HANDLE hActivationContext; ULONG_PTR ulCookie; HRESULT hrLuna = ActivateLuna(&hActivationContext, &ulCookie); INITCOMMONCONTROLSEX CommonControlsEx; CommonControlsEx.dwSize = sizeof(CommonControlsEx); CommonControlsEx.dwICC = ICC_LINK_CLASS; if(InitCommonControlsEx(&CommonControlsEx)) { CConfirmation DlgConfirm( OLE2T(pszPublisher), OLE2T(pszProduct), OLE2T(pszPorts) ); if ( DlgConfirm.DoModal() != IDOK ) { RegKeyISV.DeleteSubKey(OLE2T(pszProgID)); // Roll back created/test key return S_FALSE; } } if(SUCCEEDED(hrLuna)) { DeactivateLuna(hActivationContext, ulCookie); } // // Write the news ALG plugin // KeyThisAlgModule.SetValue( OLE2T(pszPublisher), TEXT("Publisher") ); KeyThisAlgModule.SetValue( OLE2T(pszProduct), TEXT("Product") ); KeyThisAlgModule.SetValue( OLE2T(pszVersion), TEXT("Version") ); KeyThisAlgModule.SetValue( nProtocol, TEXT("Protocol") ); KeyThisAlgModule.SetValue( OLE2T(pszPorts), TEXT("Ports") ); // This will trigger the ALG.exe to refresh his load ALG modules RegKeyISV.SetValue(L"Enable", OLE2T(pszProgID) ); // // Add this ALG Module to the uninstall registry key in order to appear in the "Add/Remove Program" // CRegKey RegKeyUninstall; RegKeyUninstall.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")); RegKeyUninstall.Create(RegKeyUninstall, OLE2T(pszProgID)); TCHAR szDisplayName[256]; wsprintf( szDisplayName, TEXT("Firewall Plugin Module from %s for %s version %s"), OLE2T(pszPublisher), OLE2T(pszProduct), OLE2T(pszVersion) ); RegKeyUninstall.SetValue( szDisplayName, TEXT("DisplayName")); // // Setup the Add/Remove Program registry information in order to have the ALG be removed from the system // TCHAR szRunCommand[256]; wsprintf( szRunCommand, TEXT("RunDll32 %%SystemRoot%%\\system32\\hnetcfg.dll,AlgUninstall %s"), OLE2T(pszProgID) ); lRet = RegSetValueEx( RegKeyUninstall, // handle to key TEXT("UninstallString"), // value name 0, // reserved REG_EXPAND_SZ, // value type (const BYTE*)szRunCommand, // value data (lstrlen(szRunCommand)+1)*sizeof(TCHAR) // size of value data ); //RegKeyUninstall.SetValue(szRunCommand, TEXT("UninstallString")); return S_OK; } // // // STDMETHODIMP CAlgSetup::Remove( BSTR pszProgID ) { USES_CONVERSION; TCHAR szRegPath[MAX_PATH]; wsprintf(szRegPath,TEXT("SOFTWARE\\Microsoft\\ALG\\ISV"), OLE2T(pszProgID)); CRegKey KeyAlgISV; // // Open the ISV hive // LONG lRet = KeyAlgISV.Open(HKEY_LOCAL_MACHINE, szRegPath); if ( ERROR_SUCCESS != lRet ) { CDlgInstallError DlgInstallError(lRet); DlgInstallError.DoModal(); return HRESULT_FROM_WIN32(lRet); } // // Remove the ALG plugin key // lRet = KeyAlgISV.DeleteSubKey(OLE2T(pszProgID)); if ( ERROR_SUCCESS != lRet && lRet != ERROR_FILE_NOT_FOUND ) { CDlgInstallError DlgInstallError(lRet); DlgInstallError.DoModal(); return HRESULT_FROM_WIN32(lRet); } // This will trigger the ALG.exe to refresh his load ALG modules KeyAlgISV.DeleteValue(OLE2T(pszProgID) ); // // Remove from the Add/Remove Uninstall reg key // CRegKey RegKeyUninstall; RegKeyUninstall.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")); RegKeyUninstall.DeleteSubKey(OLE2T(pszProgID)); return S_OK; } #define SIZE_PORTS (ALG_SETUP_PORTS_LIST_BYTE_SIZE/sizeof(TCHAR)) // // // bool IsPortAlreadyAssign( IN LPCTSTR pszPort ) { CRegKey RegKeyISV; LRESULT lRet = RegKeyISV.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\ALG\\ISV"), KEY_READ); DWORD dwIndex=0; TCHAR szAlgModuleProgID[256]; DWORD dwKeyNameSize; LONG nRet; bool bPortAlreadyAssign=false; TCHAR* szPorts = new TCHAR[SIZE_PORTS]; do { dwKeyNameSize = 256; nRet = RegEnumKeyEx( RegKeyISV.m_hKey, // handle to key to enumerate dwIndex, // subkey index szAlgModuleProgID, // subkey name &dwKeyNameSize, // size of subkey buffer NULL, // reserved NULL, // class string buffer NULL, // size of class string buffer NULL // last write time ); dwIndex++; if ( ERROR_NO_MORE_ITEMS == nRet ) break; // All items are enumerated we are done here if ( ERROR_SUCCESS == nRet ) { CRegKey KeyALG; nRet = KeyALG.Open(RegKeyISV, szAlgModuleProgID, KEY_READ); if ( ERROR_SUCCESS == nRet ) { // // str search to see if the port is in the ports list string // example is 21 is in "39, 999, 21, 45" // ULONG nSizeOfPortsList = SIZE_PORTS; nRet = KeyALG.QueryValue(szPorts, TEXT("Ports"), &nSizeOfPortsList); if ( ERROR_SUCCESS == nRet ) { if ( wcsstr(szPorts, pszPort) != NULL ) { bPortAlreadyAssign = true; } } } } } while ( ERROR_SUCCESS == nRet && bPortAlreadyAssign==false); delete szPorts; return bPortAlreadyAssign; } // // // This // void CALLBACK AlgUninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { CComObject* pAlgSetup; HRESULT hr = CComObject::CreateInstance(&pAlgSetup); if ( SUCCEEDED(hr) ) { TCHAR szConfirmRemove[512]; TCHAR szTitle[512]; LoadString(_Module.GetResourceInstance(), IDS_ADD_REMOVE, szTitle, 512); LoadString(_Module.GetResourceInstance(), IDS_REMOVE_ALG_PLUGIN, szConfirmRemove, 512); int nRet = MessageBox( GetFocus(), szConfirmRemove, szTitle, MB_YESNO|MB_ICONQUESTION ); if ( IDYES == nRet ) { CComBSTR bstrAlgToRemove; bstrAlgToRemove = lpszCmdLine; pAlgSetup->Remove(bstrAlgToRemove); } delete pAlgSetup; } }