Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

565 lines
14 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft
  4. //
  5. // AlgSetup.cpp : Implementation of CAlgSetup
  6. //
  7. // JPDup 2001.01.01
  8. //
  9. //#include "pch.h"
  10. #pragma hdrstop
  11. #include "resource.h"
  12. #include "htmlhelp.h"
  13. #include "sautil.h"
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CConfirmation
  16. //
  17. class CConfirmation : public CDialogImpl<CConfirmation>
  18. {
  19. public:
  20. CConfirmation(
  21. LPCTSTR pszPublisher,
  22. LPCTSTR pszProduct,
  23. LPCTSTR pszPorts
  24. )
  25. {
  26. m_pszCompany = pszPublisher;
  27. m_pszProduct = pszProduct;
  28. m_pszPorts = pszPorts;
  29. }
  30. ~CConfirmation()
  31. {
  32. }
  33. enum { IDD = IDD_CONFIRMATION };
  34. BEGIN_MSG_MAP(CConfirmation)
  35. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  36. COMMAND_ID_HANDLER(IDOK, OnOK)
  37. COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
  38. MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
  39. END_MSG_MAP()
  40. // Handler prototypes:
  41. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  42. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  43. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  44. LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  45. {
  46. SetDlgItemText(IDC_EDIT_COMPANY, m_pszCompany);
  47. SetDlgItemText(IDC_EDIT_PRODUCT, m_pszProduct);
  48. SetDlgItemText(IDC_EDIT_PORTS, m_pszPorts);
  49. return 1; // Let the system set the focus
  50. }
  51. LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  52. {
  53. EndDialog(wID);
  54. return 0;
  55. }
  56. LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  57. {
  58. EndDialog(wID);
  59. return 0;
  60. }
  61. LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  62. {
  63. if ( CID_SA_ST_ICFLink == wParam )
  64. {
  65. UINT nCode = ((NMHDR* )lParam)->code;
  66. if ( NM_CLICK == nCode || NM_RETURN == nCode )
  67. {
  68. // one help topic per SKU,
  69. LPWSTR pszHelpTopic = NULL;
  70. OSVERSIONINFOEXW verInfo = {0};
  71. ULONGLONG ConditionMask = 0;
  72. verInfo.dwOSVersionInfoSize = sizeof(verInfo);
  73. verInfo.wProductType = VER_NT_WORKSTATION;
  74. verInfo.wSuiteMask = VER_SUITE_PERSONAL;
  75. VER_SET_CONDITION(ConditionMask, VER_PRODUCT_TYPE, VER_LESS_EQUAL);
  76. if ( 0 != VerifyVersionInfo(&verInfo, VER_PRODUCT_TYPE, ConditionMask) )
  77. {
  78. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR);
  79. if ( 0 != VerifyVersionInfo(&verInfo, VER_PRODUCT_TYPE | VER_SUITENAME, ConditionMask) )
  80. {
  81. // personal
  82. pszHelpTopic = TEXT("netcfg.chm::/hnw_plugin_using.htm");
  83. }
  84. else
  85. {
  86. // pro
  87. pszHelpTopic = TEXT("netcfg.chm::/hnw_plugin_using.htm");
  88. }
  89. }
  90. else
  91. {
  92. // server
  93. pszHelpTopic = TEXT("netcfg.chm::/hnw_plugin_using.htm");
  94. }
  95. HtmlHelp(NULL, pszHelpTopic, HH_DISPLAY_TOPIC, 0);
  96. return 0;
  97. }
  98. }
  99. return 1;
  100. }
  101. ULONG_PTR m_nSHFusion;
  102. LPCTSTR m_pszCompany;
  103. LPCTSTR m_pszProduct;
  104. LPCTSTR m_pszPorts;
  105. };
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CDlgInstallError
  108. class CDlgInstallError : public CDialogImpl<CDlgInstallError>
  109. {
  110. public:
  111. CDlgInstallError(
  112. LONG nLastError
  113. )
  114. {
  115. m_nLastError = nLastError;
  116. //SHActivateContext(&m_nSHFusion);
  117. }
  118. ~CDlgInstallError()
  119. {
  120. //SHDeactivateContext(m_nSHFusion);
  121. }
  122. enum { IDD = IDD_INSTALLERROR };
  123. BEGIN_MSG_MAP(CDlgInstallError)
  124. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  125. COMMAND_ID_HANDLER(IDOK, OnOK)
  126. COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
  127. END_MSG_MAP()
  128. // Handler prototypes:
  129. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  130. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  131. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  132. LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  133. {
  134. LPVOID lpMsgBuf;
  135. FormatMessage(
  136. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  137. FORMAT_MESSAGE_FROM_SYSTEM |
  138. FORMAT_MESSAGE_IGNORE_INSERTS,
  139. NULL,
  140. m_nLastError,
  141. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  142. (LPTSTR) &lpMsgBuf,
  143. 0,
  144. NULL
  145. );
  146. SetDlgItemInt(IDC_EDIT_LASTERROR_CODE, m_nLastError, false);
  147. SetDlgItemText(IDC_EDIT_LASTERROR, (LPCTSTR)lpMsgBuf);
  148. // Free the buffer.
  149. LocalFree( lpMsgBuf );
  150. return 1; // Let the system set the focus
  151. }
  152. LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  153. {
  154. EndDialog(wID);
  155. return 0;
  156. }
  157. LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  158. {
  159. EndDialog(wID);
  160. return 0;
  161. }
  162. //
  163. // Properties
  164. //
  165. private:
  166. ULONG_PTR m_nSHFusion;
  167. LONG m_nLastError;
  168. };
  169. //
  170. //
  171. //
  172. STDMETHODIMP
  173. CAlgSetup::Add(
  174. BSTR pszProgID,
  175. BSTR pszPublisher,
  176. BSTR pszProduct,
  177. BSTR pszVersion,
  178. short nProtocol,
  179. BSTR pszPorts
  180. )
  181. {
  182. USES_CONVERSION;
  183. LONG lRet;
  184. //
  185. // Open the main ALG hive
  186. //
  187. CRegKey RegKeyISV;
  188. lRet = RegKeyISV.Create(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\ALG"));
  189. if ( ERROR_SUCCESS != lRet )
  190. {
  191. //
  192. // The OS is not setup correctly
  193. // ALG hive should have been present.
  194. //
  195. return HRESULT_FROM_WIN32(lRet);
  196. }
  197. lRet = RegKeyISV.Create(RegKeyISV, TEXT("ISV"));
  198. if ( ERROR_SUCCESS != lRet )
  199. {
  200. //
  201. // Weird we are able to create/open the parent hive but not the ISV hive
  202. //
  203. return HRESULT_FROM_WIN32(lRet);
  204. }
  205. //
  206. // Will attempt to Open/Create the ALG hive key to see if the user has ADMINI rights
  207. // if not then we will reject the install no need to confirm the install since he can't write to the registry
  208. //
  209. CRegKey KeyThisAlgModule;
  210. lRet = KeyThisAlgModule.Create(RegKeyISV, OLE2T(pszProgID));
  211. if ( ERROR_SUCCESS != lRet )
  212. {
  213. CDlgInstallError DlgInstallError(lRet);
  214. DlgInstallError.DoModal();
  215. return HRESULT_FROM_WIN32(lRet);
  216. }
  217. //
  218. //
  219. // Confirm that the ALG of the company/product is wanted by the user
  220. //
  221. //
  222. HANDLE hActivationContext;
  223. ULONG_PTR ulCookie;
  224. HRESULT hrLuna = ActivateLuna(&hActivationContext, &ulCookie);
  225. INITCOMMONCONTROLSEX CommonControlsEx;
  226. CommonControlsEx.dwSize = sizeof(CommonControlsEx);
  227. CommonControlsEx.dwICC = ICC_LINK_CLASS;
  228. if(InitCommonControlsEx(&CommonControlsEx))
  229. {
  230. CConfirmation DlgConfirm(
  231. OLE2T(pszPublisher),
  232. OLE2T(pszProduct),
  233. OLE2T(pszPorts)
  234. );
  235. if ( DlgConfirm.DoModal() != IDOK )
  236. {
  237. RegKeyISV.DeleteSubKey(OLE2T(pszProgID)); // Roll back created/test key
  238. return S_FALSE;
  239. }
  240. }
  241. if(SUCCEEDED(hrLuna))
  242. {
  243. DeactivateLuna(hActivationContext, ulCookie);
  244. }
  245. //
  246. // Write the news ALG plugin
  247. //
  248. KeyThisAlgModule.SetValue( OLE2T(pszPublisher), TEXT("Publisher") );
  249. KeyThisAlgModule.SetValue( OLE2T(pszProduct), TEXT("Product") );
  250. KeyThisAlgModule.SetValue( OLE2T(pszVersion), TEXT("Version") );
  251. KeyThisAlgModule.SetValue( nProtocol, TEXT("Protocol") );
  252. KeyThisAlgModule.SetValue( OLE2T(pszPorts), TEXT("Ports") );
  253. // This will trigger the ALG.exe to refresh his load ALG modules
  254. RegKeyISV.SetValue(L"Enable", OLE2T(pszProgID) );
  255. //
  256. // Add this ALG Module to the uninstall registry key in order to appear in the "Add/Remove Program"
  257. //
  258. CRegKey RegKeyUninstall;
  259. RegKeyUninstall.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
  260. RegKeyUninstall.Create(RegKeyUninstall, OLE2T(pszProgID));
  261. TCHAR szDisplayName[256];
  262. wsprintf(
  263. szDisplayName,
  264. TEXT("Firewall Plugin Module from %s for %s version %s"),
  265. OLE2T(pszPublisher),
  266. OLE2T(pszProduct),
  267. OLE2T(pszVersion)
  268. );
  269. RegKeyUninstall.SetValue( szDisplayName, TEXT("DisplayName"));
  270. //
  271. // Setup the Add/Remove Program registry information in order to have the ALG be removed from the system
  272. //
  273. TCHAR szRunCommand[256];
  274. wsprintf(
  275. szRunCommand,
  276. TEXT("RunDll32 %%SystemRoot%%\\system32\\hnetcfg.dll,AlgUninstall %s"),
  277. OLE2T(pszProgID)
  278. );
  279. lRet = RegSetValueEx(
  280. RegKeyUninstall, // handle to key
  281. TEXT("UninstallString"), // value name
  282. 0, // reserved
  283. REG_EXPAND_SZ, // value type
  284. (const BYTE*)szRunCommand, // value data
  285. (lstrlen(szRunCommand)+1)*sizeof(TCHAR) // size of value data
  286. );
  287. //RegKeyUninstall.SetValue(szRunCommand, TEXT("UninstallString"));
  288. return S_OK;
  289. }
  290. //
  291. //
  292. //
  293. STDMETHODIMP
  294. CAlgSetup::Remove(
  295. BSTR pszProgID
  296. )
  297. {
  298. USES_CONVERSION;
  299. TCHAR szRegPath[MAX_PATH];
  300. wsprintf(szRegPath,TEXT("SOFTWARE\\Microsoft\\ALG\\ISV"), OLE2T(pszProgID));
  301. CRegKey KeyAlgISV;
  302. //
  303. // Open the ISV hive
  304. //
  305. LONG lRet = KeyAlgISV.Open(HKEY_LOCAL_MACHINE, szRegPath);
  306. if ( ERROR_SUCCESS != lRet )
  307. {
  308. CDlgInstallError DlgInstallError(lRet);
  309. DlgInstallError.DoModal();
  310. return HRESULT_FROM_WIN32(lRet);
  311. }
  312. //
  313. // Remove the ALG plugin key
  314. //
  315. lRet = KeyAlgISV.DeleteSubKey(OLE2T(pszProgID));
  316. if ( ERROR_SUCCESS != lRet && lRet != ERROR_FILE_NOT_FOUND )
  317. {
  318. CDlgInstallError DlgInstallError(lRet);
  319. DlgInstallError.DoModal();
  320. return HRESULT_FROM_WIN32(lRet);
  321. }
  322. // This will trigger the ALG.exe to refresh his load ALG modules
  323. KeyAlgISV.DeleteValue(OLE2T(pszProgID) );
  324. //
  325. // Remove from the Add/Remove Uninstall reg key
  326. //
  327. CRegKey RegKeyUninstall;
  328. RegKeyUninstall.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
  329. RegKeyUninstall.DeleteSubKey(OLE2T(pszProgID));
  330. return S_OK;
  331. }
  332. #define SIZE_PORTS (ALG_SETUP_PORTS_LIST_BYTE_SIZE/sizeof(TCHAR))
  333. //
  334. //
  335. //
  336. bool
  337. IsPortAlreadyAssign(
  338. IN LPCTSTR pszPort
  339. )
  340. {
  341. CRegKey RegKeyISV;
  342. LRESULT lRet = RegKeyISV.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\ALG\\ISV"), KEY_READ);
  343. DWORD dwIndex=0;
  344. TCHAR szAlgModuleProgID[256];
  345. DWORD dwKeyNameSize;
  346. LONG nRet;
  347. bool bPortAlreadyAssign=false;
  348. TCHAR* szPorts = new TCHAR[SIZE_PORTS];
  349. do
  350. {
  351. dwKeyNameSize = 256;
  352. nRet = RegEnumKeyEx(
  353. RegKeyISV.m_hKey, // handle to key to enumerate
  354. dwIndex, // subkey index
  355. szAlgModuleProgID, // subkey name
  356. &dwKeyNameSize, // size of subkey buffer
  357. NULL, // reserved
  358. NULL, // class string buffer
  359. NULL, // size of class string buffer
  360. NULL // last write time
  361. );
  362. dwIndex++;
  363. if ( ERROR_NO_MORE_ITEMS == nRet )
  364. break; // All items are enumerated we are done here
  365. if ( ERROR_SUCCESS == nRet )
  366. {
  367. CRegKey KeyALG;
  368. nRet = KeyALG.Open(RegKeyISV, szAlgModuleProgID, KEY_READ);
  369. if ( ERROR_SUCCESS == nRet )
  370. {
  371. //
  372. // str search to see if the port is in the ports list string
  373. // example is 21 is in "39, 999, 21, 45"
  374. //
  375. ULONG nSizeOfPortsList = SIZE_PORTS;
  376. nRet = KeyALG.QueryValue(szPorts, TEXT("Ports"), &nSizeOfPortsList);
  377. if ( ERROR_SUCCESS == nRet )
  378. {
  379. if ( wcsstr(szPorts, pszPort) != NULL )
  380. {
  381. bPortAlreadyAssign = true;
  382. }
  383. }
  384. }
  385. }
  386. } while ( ERROR_SUCCESS == nRet && bPortAlreadyAssign==false);
  387. delete szPorts;
  388. return bPortAlreadyAssign;
  389. }
  390. //
  391. //
  392. // This
  393. //
  394. void CALLBACK
  395. AlgUninstall(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
  396. {
  397. CComObject<CAlgSetup>* pAlgSetup;
  398. HRESULT hr = CComObject<CAlgSetup>::CreateInstance(&pAlgSetup);
  399. if ( SUCCEEDED(hr) )
  400. {
  401. TCHAR szConfirmRemove[512];
  402. TCHAR szTitle[512];
  403. LoadString(_Module.GetResourceInstance(), IDS_ADD_REMOVE, szTitle, 512);
  404. LoadString(_Module.GetResourceInstance(), IDS_REMOVE_ALG_PLUGIN, szConfirmRemove, 512);
  405. int nRet = MessageBox(
  406. GetFocus(),
  407. szConfirmRemove,
  408. szTitle,
  409. MB_YESNO|MB_ICONQUESTION
  410. );
  411. if ( IDYES == nRet )
  412. {
  413. CComBSTR bstrAlgToRemove;
  414. bstrAlgToRemove = lpszCmdLine;
  415. pAlgSetup->Remove(bstrAlgToRemove);
  416. }
  417. delete pAlgSetup;
  418. }
  419. }