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.

1595 lines
50 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: CompChck.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: This module contains win32 only conponents checking and installing
  8. //
  9. // Copyright (c) 1998-1999 Microsoft Corporation
  10. //
  11. // Author: Fengsun Created 10/21/97
  12. //
  13. //+----------------------------------------------------------------------------
  14. /////////////////////////////////////////////////////////////////////
  15. //
  16. // All the functions in this file are WIN32 implementation only
  17. //
  18. #include "cmmaster.h"
  19. #include "CompChck.h"
  20. #include "cmexitwin.cpp"
  21. #include "winuserp.h"
  22. //
  23. // CSDVersion key contains the service pack that has been installed
  24. //
  25. const TCHAR* const c_pszRegRas = TEXT("SOFTWARE\\Microsoft\\RAS");
  26. const TCHAR* const c_pszCheckComponentsMutex = TEXT("Connection Manager Components Checking");
  27. const TCHAR* const c_pszRegComponentsChecked = TEXT("ComponentsChecked");
  28. const TCHAR* const c_pszSetupPPTPCommand = TEXT("rundll.exe rnasetup.dll,InstallOptionalComponent VPN");
  29. //
  30. // Functions internal to this file
  31. //
  32. static HRESULT CheckComponents(HWND hWndParent, LPCTSTR pszServiceName, DWORD dwComponentsToCheck, OUT DWORD& dwComponentsMissed,
  33. BOOL fIgnoreRegKey, BOOL fUnattended );
  34. static BOOL InstallComponents(DWORD dwComponentsToInstall, HWND hWndParent, LPCTSTR pszServiceName);
  35. static BOOL MarkComponentsChecked(DWORD dwComponentsChecked);
  36. static BOOL ReadComponentsChecked(LPDWORD pdwComponentsChecked);
  37. static BOOL IsPPTPInstalled(void);
  38. static BOOL InstallPPTP(void);
  39. static BOOL IsScriptingInstalled(void);
  40. static HRESULT ConfigSystem(HWND hwndParent,
  41. DWORD dwfOptions,
  42. LPBOOL pbReboot);
  43. static HRESULT InetNeedSystemComponents(DWORD dwfOptions,
  44. LPBOOL pbNeedSysComponents);
  45. static HRESULT InetNeedModem(LPBOOL pbNeedModem);
  46. static void DisplayMessageToInstallServicePack(HWND hWndParent, LPCTSTR pszServiceName);
  47. static inline HINSTANCE LoadInetCfg(void)
  48. {
  49. return (LoadLibraryExA("cnetcfg.dll", NULL, 0));
  50. }
  51. //+----------------------------------------------------------------------------
  52. //
  53. // Function IsPPTPInstalled
  54. //
  55. // Synopsis Check to see if PPTP is already installed
  56. //
  57. // Arguments None
  58. //
  59. // Returns TRUE - PPTP has been installed
  60. // FALSE - otherwise
  61. //
  62. // History 3/25/97 VetriV Created
  63. //
  64. //-----------------------------------------------------------------------------
  65. BOOL IsPPTPInstalled(void)
  66. {
  67. BOOL bReturnCode = FALSE;
  68. HKEY hKey = NULL;
  69. DWORD dwSize = 0, dwType = 0;
  70. LONG lrc = 0;
  71. TCHAR szData[MAX_PATH+1];
  72. if (OS_NT)
  73. {
  74. if (GetOSMajorVersion() >= 5)
  75. {
  76. //
  77. // PPTP is always installed on NT5
  78. //
  79. bReturnCode = TRUE;
  80. }
  81. else
  82. {
  83. if (RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  84. TEXT("SOFTWARE\\Microsoft\\RASPPTP"),
  85. 0,
  86. KEY_READ,
  87. &hKey) == 0)
  88. {
  89. RegCloseKey(hKey);
  90. bReturnCode = TRUE;
  91. }
  92. }
  93. }
  94. else
  95. {
  96. hKey = NULL;
  97. lrc = RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  98. TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OptionalComponents\\VPN"),
  99. 0,
  100. KEY_READ,
  101. &hKey);
  102. if (ERROR_SUCCESS == lrc)
  103. {
  104. dwSize = MAX_PATH;
  105. lrc = RegQueryValueExU(hKey, TEXT("Installed"), 0,
  106. &dwType, (LPBYTE)szData, &dwSize);
  107. if (ERROR_SUCCESS == lrc)
  108. {
  109. if (0 == lstrcmpiU(szData, TEXT("1")))
  110. {
  111. //
  112. // On 9X, we need to check for Dial-Up Adapter #2. If its
  113. // not present then tunneling won't work unless we install
  114. // PPTP to install the Adapter #2.
  115. //
  116. //
  117. // On early versions of Win9x Dial-up Adapter was localized, but on WinME, WinSE,
  118. // or machines that have DUN 1.3 installed it isn't. Thus, lets try the unlocalized
  119. // first and then if that fails we can try the localized version.
  120. //
  121. const TCHAR * const c_pszDialupAdapter = TEXT("Dial-up Adapter");
  122. LPTSTR pszAdapter = NULL;
  123. LPTSTR pszKey = CmStrCpyAlloc(TEXT("System\\CurrentControlSet\\Control\\PerfStats\\Enum\\"));
  124. CmStrCatAlloc(&pszKey, c_pszDialupAdapter);
  125. CmStrCatAlloc(&pszKey, TEXT(" #2"));
  126. //
  127. // Close the key that we opened above, and try the one for the adapter
  128. //
  129. RegCloseKey(hKey);
  130. hKey = NULL;
  131. if (ERROR_SUCCESS == RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  132. pszKey,
  133. 0,
  134. KEY_QUERY_VALUE,
  135. &hKey))
  136. {
  137. bReturnCode = TRUE;
  138. }
  139. else
  140. {
  141. CmFree (pszKey);
  142. pszAdapter = CmLoadString(g_hInst, IDS_REG_DIALUP_ADAPTER);
  143. pszKey = CmStrCpyAlloc(TEXT("System\\CurrentControlSet\\Control\\PerfStats\\Enum\\"));
  144. CmStrCatAlloc(&pszKey, pszAdapter);
  145. CmStrCatAlloc(&pszKey, TEXT(" #2"));
  146. //
  147. // Close the key that we opened above, and try the one for the adapter
  148. //
  149. RegCloseKey(hKey);
  150. hKey = NULL;
  151. if (ERROR_SUCCESS == RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  152. pszKey,
  153. 0,
  154. KEY_QUERY_VALUE,
  155. &hKey))
  156. {
  157. bReturnCode = TRUE;
  158. }
  159. }
  160. CmFree(pszKey);
  161. CmFree(pszAdapter);
  162. }
  163. }
  164. }
  165. if (hKey)
  166. {
  167. RegCloseKey(hKey);
  168. hKey = NULL;
  169. }
  170. }
  171. return bReturnCode;
  172. }
  173. //+----------------------------------------------------------------------------
  174. //
  175. // Function InstallPPTP
  176. //
  177. // Synopsis Install PPTP on Windows 95 and NT
  178. //
  179. // Arguments None
  180. //
  181. // Returns TRUE -- if was successfully installed
  182. // FALSE -- Otherwise
  183. //
  184. // History 3/25/97 VetriV Created
  185. // 7/8/97 VetriV Added code to setup PPTP on Memphis
  186. //
  187. //-----------------------------------------------------------------------------
  188. BOOL InstallPPTP(void)
  189. {
  190. BOOL bReturnCode = FALSE;
  191. STARTUPINFO si;
  192. PROCESS_INFORMATION pi;
  193. MSG msg ;
  194. if (OS_NT || OS_W95)
  195. {
  196. //
  197. // Don't know how to install/configure PPTP on NT.
  198. // We let the admin wrestle with MSDUNXX on W95
  199. //
  200. return FALSE;
  201. }
  202. else
  203. {
  204. TCHAR szCommand[128];
  205. ZeroMemory(&pi, sizeof(pi));
  206. ZeroMemory(&si, sizeof(si));
  207. si.cb = sizeof(STARTUPINFO);
  208. //
  209. // NOTE: The original version called "msdun12.exe /q /R:N" to install tunneling
  210. // on Windows 95. Now we use 98 approach only and call the following:
  211. // "rundll.exe rnasetup.dll,InstallOptionalComponent VPN".
  212. //
  213. MYDBGASSERT(1353 < LOWORD(GetOSBuildNumber()));
  214. lstrcpyU(szCommand, c_pszSetupPPTPCommand);
  215. if (NULL == CreateProcessU(NULL, szCommand,
  216. NULL, NULL, FALSE, 0,
  217. NULL, NULL, &si, &pi))
  218. {
  219. CMTRACE1(TEXT("InstallPPTP() CreateProcess() failed, GLE=%u."), GetLastError());
  220. }
  221. else
  222. {
  223. CMTRACE(TEXT("InstallPPTP() Launched PPTP Install. Waiting for exit."));
  224. //
  225. // wait for event or msgs. Dispatch msgs. Exit when event is signalled.
  226. //
  227. while((MsgWaitForMultipleObjects(1, &pi.hProcess,
  228. FALSE, INFINITE,
  229. QS_ALLINPUT) == (WAIT_OBJECT_0 + 1)))
  230. {
  231. //
  232. // read all of the messages in this next loop
  233. // removing each message as we read it
  234. //
  235. while (PeekMessageU(&msg, NULL, 0, 0, PM_REMOVE))
  236. {
  237. CMTRACE(TEXT("InstallPPTP() Got Message"));
  238. //
  239. // how to handle quit message?
  240. //
  241. DispatchMessageU(&msg);
  242. if (msg.message == WM_QUIT)
  243. {
  244. CMTRACE(TEXT("InstallPPTP() Got Quit Message"));
  245. goto done;
  246. }
  247. }
  248. }
  249. done:
  250. CloseHandle(pi.hThread);
  251. CloseHandle(pi.hProcess);
  252. //
  253. // PPTP was successfully installed
  254. //
  255. bReturnCode = TRUE;
  256. CMTRACE(TEXT("InstallPPTP() done"));
  257. }
  258. }
  259. return bReturnCode;
  260. }
  261. //+----------------------------------------------------------------------------
  262. //
  263. // Function IsMSDUN12Installed
  264. //
  265. // Synopsis Check if MSDUN 1.2 or higher is installed.
  266. //
  267. // Arguments none
  268. //
  269. // Returns TRUE - MSDUN 1.2 is installed
  270. //
  271. // History 8/12/97 nickball from ICW for 11900
  272. //
  273. //-----------------------------------------------------------------------------
  274. #define DUN_12_Version "1.2"
  275. BOOL IsMSDUN12Installed()
  276. {
  277. CHAR szBuffer[MAX_PATH] = {"\0"};
  278. HKEY hkey = NULL;
  279. BOOL bRC = FALSE;
  280. DWORD dwType = 0;
  281. DWORD dwSize = sizeof(szBuffer);
  282. //
  283. // Try to open the Version key
  284. //
  285. if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  286. "System\\CurrentControlSet\\Services\\RemoteAccess",
  287. 0,
  288. KEY_READ,
  289. &hkey))
  290. {
  291. return FALSE;
  292. }
  293. //
  294. // The key exists, check the value
  295. //
  296. if (ERROR_SUCCESS == RegQueryValueExA(hkey, "Version", NULL, &dwType,
  297. (LPBYTE)szBuffer, &dwSize))
  298. {
  299. //
  300. // If the entry starts with "1.2", (eg. "1.2c") its a hit
  301. //
  302. bRC = (szBuffer == CmStrStrA(szBuffer, DUN_12_Version));
  303. }
  304. RegCloseKey(hkey);
  305. return bRC;
  306. }
  307. //+----------------------------------------------------------------------------
  308. //
  309. // Function IsISDN11Installed
  310. //
  311. // Synopsis Check if ISDN 1.1 is installed
  312. //
  313. // Arguments none
  314. //
  315. // Returns TRUE - ISDN 1.1 is installed
  316. //
  317. // Note: MSDUN12 superscedes ISDN1.1, but ISDN1.1 does provide scripting
  318. //
  319. // History 8/12/97 nickball
  320. //
  321. //-----------------------------------------------------------------------------
  322. BOOL IsISDN11Installed()
  323. {
  324. CHAR szBuffer[MAX_PATH] = {"\0"};
  325. HKEY hkey = NULL;
  326. BOOL bRC = FALSE;
  327. DWORD dwType = 0;
  328. DWORD dwSize = sizeof(szBuffer);
  329. if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  330. "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\OptionalComponents\\MSISDN",
  331. 0,
  332. KEY_READ,
  333. &hkey))
  334. {
  335. goto IsISDN11InstalledExit;
  336. }
  337. if (ERROR_SUCCESS != RegQueryValueExA(hkey,
  338. "Installed",
  339. NULL,
  340. &dwType,
  341. (LPBYTE)szBuffer,
  342. &dwSize))
  343. {
  344. goto IsISDN11InstalledExit;
  345. }
  346. if (0 == lstrcmpA("1", szBuffer))
  347. {
  348. bRC = TRUE;
  349. }
  350. IsISDN11InstalledExit:
  351. return bRC;
  352. }
  353. //+----------------------------------------------------------------------------
  354. //
  355. // Function IsScriptingInstalled
  356. //
  357. // Synopsis Check to see if scripting is already installed
  358. //
  359. // Arguments None
  360. //
  361. // Returns TRUE - scripting has been installed
  362. //
  363. // History 3/5/97 VetriV From ICW code
  364. //
  365. //-----------------------------------------------------------------------------
  366. BOOL IsScriptingInstalled(void)
  367. {
  368. BOOL bReturnCode = FALSE;
  369. HKEY hkey = NULL;
  370. DWORD dwSize = 0, dwType = 0;
  371. LONG lrc = 0;
  372. HINSTANCE hInst = NULL;
  373. CHAR szData[MAX_PATH+1];
  374. if (OS_NT)
  375. {
  376. //
  377. // NT comes with Scripting installed
  378. //
  379. bReturnCode = TRUE;
  380. }
  381. else
  382. {
  383. //
  384. // OSR2 and higher releases of Windows 95 have scripting installed
  385. //
  386. if (1111 <= LOWORD(GetOSBuildNumber()))
  387. {
  388. bReturnCode = TRUE;
  389. }
  390. else
  391. {
  392. //
  393. // Must be Gold 95, check for installed scripting
  394. //
  395. if (IsMSDUN12Installed() || IsISDN11Installed())
  396. {
  397. bReturnCode = TRUE;
  398. }
  399. else
  400. {
  401. hkey = NULL;
  402. lrc = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  403. "System\\CurrentControlSet\\Services\\RemoteAccess\\Authentication\\SMM_FILES\\PPP",
  404. 0,
  405. KEY_READ,
  406. &hkey);
  407. if (ERROR_SUCCESS == lrc)
  408. {
  409. dwSize = MAX_PATH;
  410. lrc = RegQueryValueExA(hkey, "Path", 0, &dwType, (LPBYTE)szData, &dwSize);
  411. if (ERROR_SUCCESS == lrc)
  412. {
  413. if (0 == lstrcmpiA(szData,"smmscrpt.dll"))
  414. {
  415. bReturnCode = TRUE;
  416. }
  417. }
  418. }
  419. if (hkey)
  420. {
  421. RegCloseKey(hkey);
  422. hkey = NULL;
  423. }
  424. //
  425. // Verify that the DLL can be loaded
  426. //
  427. if (bReturnCode)
  428. {
  429. hInst = LoadLibraryExA("smmscrpt.dll", NULL, 0);
  430. if (hInst)
  431. {
  432. FreeLibrary(hInst);
  433. }
  434. else
  435. {
  436. bReturnCode = FALSE;
  437. }
  438. hInst = NULL;
  439. }
  440. }
  441. }
  442. }
  443. return bReturnCode;
  444. }
  445. //+----------------------------------------------------------------------------
  446. // Function VerifyRasServicesRunning
  447. //
  448. // Synopsis Make sure that the RAS services are enabled and running
  449. //
  450. // Arguments hWndDlg: - Window Handle of parent window
  451. // pszServiceName - Service name for titles
  452. // fUnattended: - if TRUE, do not do not popup any UI
  453. //
  454. // Return FALSE - if the services couldn't be started
  455. //
  456. // History 2/26/97 VetriV Copied from ICW code
  457. //-----------------------------------------------------------------------------
  458. BOOL VerifyRasServicesRunning(HWND hWndDlg, LPCTSTR pszServiceName, BOOL fUnattended)
  459. {
  460. BOOL bReturnCode = FALSE;
  461. HINSTANCE hInstance = NULL;
  462. HRESULT (WINAPI *pfn)(void);
  463. hInstance = LoadInetCfg();
  464. if (!hInstance)
  465. {
  466. CMTRACE1(TEXT("VerifyRasServicesRunning() LoadLibrary() failed, GLE=%u."), GetLastError());
  467. }
  468. else
  469. {
  470. pfn = (HRESULT (WINAPI *)(void))GetProcAddress(hInstance, "InetStartServices");
  471. if (pfn)
  472. {
  473. LPTSTR pszDisabledMsg;
  474. LPTSTR pszExitMsg;
  475. pszDisabledMsg = CmFmtMsg(g_hInst, IDS_SERVICEDISABLED);
  476. pszExitMsg = CmFmtMsg(g_hInst, IDS_WANTTOEXIT);
  477. //
  478. // Check RAS Services
  479. //
  480. do
  481. {
  482. HRESULT hr = pfn();
  483. if (ERROR_SUCCESS == hr)
  484. {
  485. bReturnCode = TRUE;
  486. break;
  487. }
  488. else
  489. {
  490. CMTRACE1(TEXT("VerifyRasServicesRunning() InetStartServices() failed, GLE=%u."), hr);
  491. }
  492. //
  493. // Do not retry if unattended
  494. //
  495. if (!fUnattended)
  496. {
  497. bReturnCode = FALSE;
  498. break;
  499. }
  500. //
  501. // Check the error code of OpenService
  502. // Do not ask user to retry for certain errors
  503. //
  504. if (hr == ERROR_SERVICE_DOES_NOT_EXIST || hr == ERROR_FILE_NOT_FOUND ||
  505. hr == ERROR_ACCESS_DENIED)
  506. {
  507. LPTSTR pszNotInstalledMsg = CmFmtMsg(g_hInst, IDS_SERVICENOTINSTALLED);
  508. //
  509. // Report the error and Exit
  510. //
  511. MessageBoxEx(hWndDlg, pszNotInstalledMsg, pszServiceName,
  512. MB_OK|MB_ICONSTOP,
  513. LANG_USER_DEFAULT);
  514. CmFree(pszNotInstalledMsg);
  515. bReturnCode = FALSE;
  516. break;
  517. }
  518. //
  519. // Report the error and allow the user to retry
  520. //
  521. if (IDYES != MessageBoxEx(hWndDlg,pszDisabledMsg,pszServiceName,
  522. MB_YESNO | MB_DEFBUTTON1
  523. | MB_ICONWARNING,
  524. LANG_USER_DEFAULT))
  525. {
  526. //
  527. // Confirm Exit
  528. //
  529. if (IDYES == MessageBoxEx(hWndDlg, pszExitMsg, pszServiceName,
  530. MB_APPLMODAL | MB_ICONQUESTION
  531. | MB_YESNO | MB_DEFBUTTON2,
  532. LANG_USER_DEFAULT))
  533. {
  534. bReturnCode = FALSE;
  535. break;
  536. }
  537. }
  538. } while (1);
  539. CmFree(pszDisabledMsg);
  540. CmFree(pszExitMsg);
  541. }
  542. else
  543. {
  544. CMTRACE1(TEXT("VerifyRasServicesRunning() GetProcAddress() failed, GLE=%u."), GetLastError());
  545. }
  546. FreeLibrary(hInstance);
  547. }
  548. return bReturnCode;
  549. }
  550. //+----------------------------------------------------------------------------
  551. // Function CheckAndInstallComponents
  552. //
  553. // Synopsis Make sure the system is setup for dialing
  554. //
  555. // Arguments dwComponentsToCheck - Components to be checked
  556. // hWndParent - Window Handle of parent window
  557. // pszServiceName - Long service name for error titles
  558. // fIgnoreRegKey: - Whether ignore ComponetsChecked registry key
  559. // Default is TRUE, check the components even if their bit is set
  560. // in registry
  561. // fUnattended: if TRUE, do not try to install missed components,
  562. // do not popup any UI
  563. // Defualt is FALSE, install.
  564. //
  565. // Return Other - if system could not be configured
  566. // or if the we have to reboot to continue
  567. // ERROR_SUCCESS - Check and install successfully
  568. //
  569. // History 3/13/97 VetriV
  570. // 6/24/97 byao Modified. Set pArgs->dwExitCode accordingly
  571. // 11/6/97 fengsun changed parameters, do not pass pArgs
  572. //-----------------------------------------------------------------------------
  573. DWORD CheckAndInstallComponents(DWORD dwComponentsToCheck, HWND hWndParent, LPCTSTR pszServiceName,
  574. BOOL fIgnoreRegKey, BOOL fUnattended)
  575. {
  576. MYDBGASSERT( (dwComponentsToCheck &
  577. ~(CC_RNA | CC_TCPIP | CC_MODEM | CC_PPTP | CC_SCRIPTING | CC_RASRUNNING | CC_CHECK_BINDINGS) ) == 0 );
  578. if (dwComponentsToCheck == 0)
  579. {
  580. return ERROR_SUCCESS;
  581. }
  582. //
  583. // Open the mutex, so only one CM instance can call this function.
  584. // The destructor of CNamedMutex will release the mutex
  585. //
  586. CNamedMutex theMutex;
  587. if (!theMutex.Lock(c_pszCheckComponentsMutex))
  588. {
  589. //
  590. // Another instance of cm is checking components. Return here
  591. //
  592. LPTSTR pszMsg = CmLoadString(g_hInst, IDMSG_COMPONENTS_CHECKING_INPROCESS);
  593. MessageBoxEx(hWndParent, pszMsg, pszServiceName,
  594. MB_OK | MB_ICONERROR,
  595. LANG_USER_DEFAULT);
  596. CmFree(pszMsg);
  597. return ERROR_CANCELLED;
  598. }
  599. //
  600. // Find components missed
  601. //
  602. DWORD dwComponentsMissed = 0;
  603. DWORD dwRet = CheckComponents(hWndParent, pszServiceName, dwComponentsToCheck, dwComponentsMissed,
  604. fIgnoreRegKey, fUnattended);
  605. if (dwRet == ERROR_SUCCESS)
  606. {
  607. MYDBGASSERT(dwComponentsMissed == 0);
  608. return ERROR_SUCCESS;
  609. }
  610. if (dwRet == E_ACCESSDENIED && OS_NT5)
  611. {
  612. //
  613. // On NT5, non-admin user does not have access to check components
  614. // Continue.
  615. //
  616. return ERROR_SUCCESS;
  617. }
  618. if (fUnattended)
  619. {
  620. //
  621. // Do not try to install if fUnattended is TRUE
  622. //
  623. return dwRet;
  624. }
  625. if (dwComponentsMissed & ~CC_RASRUNNING)
  626. {
  627. //
  628. // Prompt user before configuring system
  629. // If modem is not installed, expilitly say that
  630. //
  631. LPTSTR pszMsg;
  632. if (dwComponentsMissed == CC_MODEM)
  633. {
  634. //
  635. // On NT4, if RAS is installed and modem is not installed or
  636. // not configured for dialout, then we cannot programmatically
  637. // install and configure modem for the user (limitation of NT RAS
  638. // install/configuration). So, we will display a message to user
  639. // to manually go and install and/or configure modem from NCPA
  640. //
  641. if (OS_NT4)
  642. {
  643. pszMsg = CmFmtMsg(g_hInst, IDMSG_INSTALLMODEM_MANUALLY_MSG);
  644. MessageBoxEx(hWndParent, pszMsg, pszServiceName,
  645. MB_OK | MB_ICONERROR,
  646. LANG_USER_DEFAULT);
  647. CmFree(pszMsg);
  648. return ERROR_CANCELLED;
  649. }
  650. else
  651. {
  652. pszMsg = CmFmtMsg(g_hInst, IDMSG_NOMODEM_MSG);
  653. }
  654. }
  655. else
  656. {
  657. pszMsg = CmFmtMsg(g_hInst, IDMSG_NORAS_MSG);
  658. }
  659. int iRes = MessageBoxEx(hWndParent, pszMsg, pszServiceName,
  660. MB_YESNO | MB_DEFBUTTON1 | MB_ICONWARNING,
  661. LANG_USER_DEFAULT);
  662. CmFree(pszMsg);
  663. if (IDYES != iRes)
  664. {
  665. return ERROR_CANCELLED;
  666. }
  667. if (!InstallComponents(dwComponentsMissed, hWndParent, pszServiceName))
  668. {
  669. //
  670. // Some time, GetLastError returns ERROR_SUCCESS
  671. //
  672. return (GetLastError() == ERROR_SUCCESS ? ERROR_CANCELLED : GetLastError());
  673. }
  674. }
  675. //
  676. // We can not do anything if RAS can not be started on NT
  677. //
  678. if (dwComponentsMissed & CC_RASRUNNING)
  679. {
  680. return dwRet;
  681. }
  682. else
  683. {
  684. return ERROR_SUCCESS;
  685. }
  686. }
  687. //+----------------------------------------------------------------------------
  688. // Function MarkComponentsChecked
  689. //
  690. // Synopsis Mark(in registry) what components have been checked.
  691. //
  692. // Arguments DWORD dwComponentsInstalled - a dword(bitwise OR'ed)
  693. //
  694. // Return TRUE - success
  695. // FALSE - otherwise
  696. //
  697. // History 08/07/97 Fengsun - created
  698. // 08/11/97 henryt - changed return type.
  699. // 07/03/98 nickball - create if can't open
  700. //-----------------------------------------------------------------------------
  701. BOOL MarkComponentsChecked(DWORD dwComponentsChecked)
  702. {
  703. HKEY hKeyCm;
  704. //
  705. // Try to open the key for writing
  706. //
  707. LONG lRes = RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  708. c_pszRegCmRoot,
  709. 0,
  710. KEY_SET_VALUE ,
  711. &hKeyCm);
  712. //
  713. // If we can't open it the key may not be there, try to create it.
  714. //
  715. if (ERROR_SUCCESS != lRes)
  716. {
  717. DWORD dwDisposition;
  718. lRes = RegCreateKeyExU(HKEY_LOCAL_MACHINE,
  719. c_pszRegCmRoot,
  720. 0,
  721. TEXT(""),
  722. REG_OPTION_NON_VOLATILE,
  723. KEY_SET_VALUE,
  724. NULL,
  725. &hKeyCm,
  726. &dwDisposition);
  727. }
  728. //
  729. // On success, update the ComponentsChecked value, then close
  730. //
  731. if (ERROR_SUCCESS == lRes)
  732. {
  733. lRes = RegSetValueExU(hKeyCm, c_pszRegComponentsChecked, NULL, REG_DWORD,
  734. (BYTE*)&dwComponentsChecked, sizeof(dwComponentsChecked));
  735. RegCloseKey(hKeyCm);
  736. }
  737. return (ERROR_SUCCESS == lRes);
  738. }
  739. //+----------------------------------------------------------------------------
  740. // Function ReadComponentsChecked
  741. //
  742. // Synopsis Read(from registry) what components have been checked.
  743. //
  744. // Arguments LPDWORD pdwComponentsInstalled - a ptr dword(bitwise OR'ed)
  745. //
  746. // Return TRUE - success
  747. // FALSE - otherwise
  748. //
  749. // History 8/7/97 fengsun original code
  750. // 8/11/97 henryt created the func.
  751. //-----------------------------------------------------------------------------
  752. BOOL ReadComponentsChecked(
  753. LPDWORD pdwComponentsChecked
  754. )
  755. {
  756. BOOL fSuccess = FALSE;
  757. HKEY hKeyCm;
  758. DWORD dwType;
  759. DWORD dwSize = sizeof(DWORD);
  760. *pdwComponentsChecked = 0;
  761. if (RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  762. c_pszRegCmRoot,
  763. 0,
  764. KEY_QUERY_VALUE ,
  765. &hKeyCm) == ERROR_SUCCESS)
  766. {
  767. if ((RegQueryValueExU(hKeyCm,
  768. c_pszRegComponentsChecked,
  769. NULL,
  770. &dwType,
  771. (BYTE*)pdwComponentsChecked,
  772. &dwSize) == ERROR_SUCCESS) &&
  773. (dwType == REG_DWORD) &&
  774. (dwSize == sizeof(DWORD)))
  775. {
  776. fSuccess = TRUE;
  777. }
  778. RegCloseKey(hKeyCm);
  779. }
  780. return fSuccess;
  781. }
  782. //+----------------------------------------------------------------------------
  783. //
  784. // Function: ClearComponentsChecked
  785. //
  786. // Synopsis: Clear the component checked flag in registry back to 0
  787. //
  788. // Arguments: None
  789. //
  790. // Returns: Nothing
  791. //
  792. // History: fengsun Created Header 2/19/98
  793. //
  794. //+----------------------------------------------------------------------------
  795. void ClearComponentsChecked()
  796. {
  797. MarkComponentsChecked(0);
  798. }
  799. //+----------------------------------------------------------------------------
  800. // Function CheckComponents
  801. //
  802. // Synopsis Checks to see if the system has all the components
  803. // required of the service profile (like PPTP, TCP,...)
  804. // installed and configured
  805. //
  806. // Arguments hWndParent -Window Handle of parent window
  807. // pszServiceName - Service Name for title
  808. // dwComponentsToCheck:- Components to check
  809. // dwComponentsMissed: - OUT components missed
  810. // fIgnoreRegKey: - Whether ignore ComponetsChecked registry key
  811. // Default is FALSE, not check the components whose bit is set
  812. // in registry
  813. // fUnattended: if TRUE, do not do not popup any UI
  814. //
  815. // Return ERROR_SUCCESS- system does not need configuration
  816. // Other - otherwise
  817. //
  818. // History 5/5/97 VetriV
  819. // 6/26/97 byao Modified: update pArgs->dwExitCode when
  820. // components needed
  821. // 8/11/97 henryt Performance changes. Added CC_* flags.
  822. // 9/30/97 henryt added pfPptpNotInstalled
  823. // 11/6/97 fengsun changed parameters, do not pass pArgs
  824. //-----------------------------------------------------------------------------
  825. HRESULT CheckComponents(HWND hWndParent, LPCTSTR pszServiceName, DWORD dwComponentsToCheck, OUT DWORD& dwComponentsMissed,
  826. BOOL fIgnoreRegKey, BOOL fUnattended )
  827. {
  828. DWORD dwComponentsAlreadyChecked = 0; // Components already checked, to be saved into registry
  829. ReadComponentsChecked(&dwComponentsAlreadyChecked);
  830. CMTRACE1(TEXT("CheckComponents: dwComponentsToCheck = 0x%x"), dwComponentsToCheck);
  831. CMTRACE1(TEXT("CheckComponents: dwComponentsAlreadyChecked = 0x%x"), dwComponentsAlreadyChecked);
  832. //
  833. // If this is NT4 and we have successfully checked RAS installation
  834. // previously, double-check by examining Reg key. We do this because
  835. // the user may have removed RAS since our last component check in
  836. // which case an unpleasant message is displayed to the user when
  837. // we try to load RASAPI32.DLL
  838. //
  839. if (dwComponentsAlreadyChecked & CC_RNA)
  840. {
  841. if (OS_NT4)
  842. {
  843. //
  844. // RAS was installed properly at some point, but if
  845. // we can't open the key, then mark it as un-checked.
  846. //
  847. HKEY hKeyCm;
  848. DWORD dwRes = RegOpenKeyExU(HKEY_LOCAL_MACHINE,
  849. c_pszRegRas,
  850. 0,
  851. KEY_QUERY_VALUE ,
  852. &hKeyCm);
  853. if (ERROR_SUCCESS == dwRes)
  854. {
  855. RegCloseKey(hKeyCm);
  856. }
  857. else
  858. {
  859. dwComponentsAlreadyChecked &= ~CC_RNA;
  860. }
  861. }
  862. }
  863. if (!fIgnoreRegKey)
  864. {
  865. //
  866. // Do not check those components already marked as checked in the registry
  867. //
  868. dwComponentsToCheck &= ~dwComponentsAlreadyChecked;
  869. }
  870. CMTRACE1(TEXT("CheckComponents: Now only checking components = 0x%x"), dwComponentsToCheck);
  871. HRESULT hrRet = S_OK; // return value
  872. dwComponentsMissed = 0; // Components not installed
  873. //
  874. // Check for DUN and TCP
  875. //
  876. if (dwComponentsToCheck & (CC_RNA | CC_TCPIP | CC_CHECK_BINDINGS))
  877. {
  878. BOOL bNeedSystemComponents = FALSE;
  879. if (dwComponentsToCheck & CC_CHECK_BINDINGS)
  880. {
  881. //
  882. // If we to check if PPP is bound to TCP
  883. //
  884. hrRet = InetNeedSystemComponents(INETCFG_INSTALLRNA |
  885. INETCFG_INSTALLTCP,
  886. &bNeedSystemComponents);
  887. }
  888. else
  889. {
  890. //
  891. // If we do not want to check if TCP is bound (in case of shims)
  892. // check just if TCP is installed
  893. //
  894. hrRet = InetNeedSystemComponents(INETCFG_INSTALLRNA |
  895. INETCFG_INSTALLTCPONLY,
  896. &bNeedSystemComponents);
  897. }
  898. if ((FAILED(hrRet)) || (TRUE == bNeedSystemComponents))
  899. {
  900. //
  901. // Set the Missing components properly - RNA and/or TCP missing
  902. // whether binding is missing or not depends on
  903. // if CC_REVIEW_BINDINGS was set or not
  904. //
  905. dwComponentsMissed |= (CC_RNA | CC_TCPIP);
  906. if (dwComponentsToCheck & CC_CHECK_BINDINGS)
  907. {
  908. dwComponentsMissed |= CC_CHECK_BINDINGS;
  909. }
  910. if (SUCCEEDED(hrRet))
  911. {
  912. hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED);
  913. }
  914. }
  915. }
  916. //
  917. // Check for Modem
  918. // Note: Should not even run the modem check is RNA is not installed
  919. //
  920. if (dwComponentsToCheck & CC_MODEM)
  921. {
  922. BOOL bNeedModem = FALSE;
  923. hrRet = InetNeedModem(&bNeedModem);
  924. if (FAILED(hrRet))
  925. {
  926. dwComponentsMissed |= (CC_MODEM | CC_RNA);
  927. }
  928. else
  929. {
  930. if (TRUE == bNeedModem)
  931. {
  932. dwComponentsMissed |= CC_MODEM;
  933. hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED);
  934. }
  935. }
  936. }
  937. //
  938. // Check if PPTP is installed, IsPPTPInstalled always returns TRUE for NT5
  939. //
  940. if (dwComponentsToCheck & CC_PPTP)
  941. {
  942. if (FALSE == IsPPTPInstalled())
  943. {
  944. dwComponentsMissed |= CC_PPTP;
  945. hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED);
  946. }
  947. }
  948. //
  949. // Check for scripting
  950. // if PPTP is installed then we have scripting also
  951. // - msdun12.exe (used to install PPTP on Win95 contains scripting)
  952. if (dwComponentsToCheck & CC_SCRIPTING)
  953. {
  954. if ((FALSE == IsScriptingInstalled()) && (FALSE == IsPPTPInstalled()))
  955. {
  956. dwComponentsMissed |= CC_SCRIPTING;
  957. hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED);
  958. }
  959. }
  960. //
  961. // Check if RAS services are running
  962. // This is basically for NT4 and becomes a NOP on Windows 95 or NT5
  963. // On NT5, CM is started by Connection Folder. RAS is automaticlly
  964. // started when ConnFolder is launched or CM desktop icon is clicked. If RAS service
  965. // failed to launch, CM will not be execute at all.
  966. //
  967. if (OS_NT && (dwComponentsToCheck & CC_RASRUNNING))
  968. {
  969. if (FALSE == VerifyRasServicesRunning(hWndParent, pszServiceName, !fUnattended))
  970. {
  971. //
  972. // Don't let the user continue if RAS is not running
  973. //
  974. dwComponentsMissed |= CC_RASRUNNING;
  975. DWORD dwRet = ( GetLastError() == ERROR_SUCCESS )?
  976. ERROR_PROTOCOL_NOT_CONFIGURED : GetLastError();
  977. hrRet = HRESULT_FROM_WIN32(dwRet);
  978. }
  979. }
  980. //
  981. // Update the components already checked
  982. // Plus Components just checked, including those failed
  983. // Minus components missed
  984. //
  985. DWORD dwComponentsCheckedNew = (dwComponentsAlreadyChecked | dwComponentsToCheck) & ~dwComponentsMissed;
  986. //
  987. // Update only if there is some change
  988. //
  989. if (dwComponentsCheckedNew != dwComponentsAlreadyChecked)
  990. {
  991. MarkComponentsChecked(dwComponentsCheckedNew);
  992. }
  993. return hrRet;
  994. }
  995. //+----------------------------------------------------------------------------
  996. // Function InstallComponents
  997. //
  998. // Synopsis Installs all components required for the profile
  999. // (PPTP, TCP, DUN, Modem,...)
  1000. //
  1001. // Arguments hWndDlg - Window Handle of parent window
  1002. // pszServiceName - Name of the service for title
  1003. // dwComponentsToInstall - Componets to install
  1004. //
  1005. // Return FALSE - if system could not be configured
  1006. // TRUE - otherwise
  1007. //
  1008. // History 3/13/97 VetriV Created
  1009. // 5/5/97 VetriV Renamed function as InstallComponents
  1010. // (used to be ConfigureSystemForDialing)
  1011. // 9/30/97 henryt added fInstallPptpOnly
  1012. // 11/6/97 fengsun changed parameters, do not pass pArgs
  1013. // 2/3/98 VetriV changed code to inform user to reinstall
  1014. // service pack if any component was installed
  1015. // by this function and user had some SP
  1016. // installed in the system
  1017. //-----------------------------------------------------------------------------
  1018. BOOL InstallComponents(DWORD dwComponentsToInstall, HWND hWndDlg, LPCTSTR pszServiceName)
  1019. {
  1020. //
  1021. // We are not allowed to configure the system at WinLogon because we have
  1022. // no idea who the user is. It could be just a random person walking up to the box.
  1023. //
  1024. if (!IsLogonAsSystem())
  1025. {
  1026. BOOL bReboot = FALSE;
  1027. CMTRACE1(TEXT("InstallComponents: dwComponentsToInstall = 0x%x"), dwComponentsToInstall);
  1028. //
  1029. // We can not do any thing if RAS is not running
  1030. //
  1031. MYDBGASSERT(!(dwComponentsToInstall & CC_RASRUNNING));
  1032. //
  1033. // Disable the window, and enable it on return
  1034. // The property sheet also need to be disabled
  1035. //
  1036. CFreezeWindow FreezeWindow(hWndDlg, TRUE);
  1037. DWORD hRes = ERROR_SUCCESS;
  1038. //
  1039. // Do not install modem here. Install modem after reboot
  1040. //
  1041. if (dwComponentsToInstall & (CC_RNA | CC_MODEM | INETCFG_INSTALLTCP | INETCFG_INSTALLTCPONLY))
  1042. {
  1043. DWORD dwInetComponent = 0;
  1044. dwInetComponent |= (dwComponentsToInstall & CC_RNA ? INETCFG_INSTALLRNA :0) |
  1045. (dwComponentsToInstall & CC_MODEM ? INETCFG_INSTALLMODEM :0);
  1046. //
  1047. // Only way to check bindings is by installing TCP
  1048. // This case will also cover the more common case of installing TCP
  1049. // and checking for bindings
  1050. //
  1051. if (CC_CHECK_BINDINGS & dwComponentsToInstall)
  1052. {
  1053. dwInetComponent |= INETCFG_INSTALLTCP;
  1054. }
  1055. else if (CC_TCPIP & dwComponentsToInstall)
  1056. {
  1057. //
  1058. // If bindings check is not turned on
  1059. //
  1060. dwInetComponent |= INETCFG_INSTALLTCPONLY;
  1061. }
  1062. if (dwInetComponent)
  1063. {
  1064. hRes = ConfigSystem(hWndDlg,dwInetComponent, &bReboot);
  1065. }
  1066. }
  1067. if (ERROR_SUCCESS == hRes)
  1068. {
  1069. //
  1070. // Check for scripting
  1071. // if PPTP is installed than we have scripting also
  1072. // - because msdun12.exe (used to install PPTP on Win95
  1073. // contains scripting)
  1074. // and install if it is needed
  1075. //
  1076. if ((dwComponentsToInstall & CC_SCRIPTING) &&
  1077. !(dwComponentsToInstall & CC_PPTP) )
  1078. {
  1079. LPTSTR pszNoScriptMsg = CmFmtMsg(g_hInst, IDMSG_NO_SCRIPT_INST_MSG_95);
  1080. if (pszNoScriptMsg)
  1081. {
  1082. MessageBoxEx(hWndDlg, pszNoScriptMsg, pszServiceName,
  1083. MB_OK | MB_ICONSTOP, LANG_USER_DEFAULT);
  1084. CmFree(pszNoScriptMsg);
  1085. }
  1086. return FALSE;
  1087. }
  1088. //
  1089. // Check if PPTP is required and not already installed install it
  1090. //
  1091. if (dwComponentsToInstall & CC_PPTP)
  1092. {
  1093. if (TRUE == InstallPPTP()) // Note: Always fails on 95 by design
  1094. {
  1095. //
  1096. // We have to reboot after installing PPTP
  1097. //
  1098. bReboot = TRUE;
  1099. }
  1100. else
  1101. {
  1102. LPTSTR pszMsg;
  1103. //
  1104. // Don't let the user continue PPTP is not installed
  1105. //
  1106. if (OS_NT)
  1107. {
  1108. if (IsServicePackInstalled())
  1109. {
  1110. //
  1111. // we need to tell the user to re-apply the service pack after manual
  1112. // install of PPTP.
  1113. //
  1114. pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_NT_SP); // NT
  1115. }
  1116. else
  1117. {
  1118. pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_NT); // NT
  1119. }
  1120. }
  1121. else if (OS_W98)
  1122. {
  1123. pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_98); // W98
  1124. }
  1125. else
  1126. {
  1127. pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_95); // default
  1128. }
  1129. if (pszMsg)
  1130. {
  1131. MessageBoxEx(hWndDlg, pszMsg, pszServiceName,
  1132. MB_OK | MB_ICONSTOP, LANG_USER_DEFAULT);
  1133. CmFree(pszMsg);
  1134. }
  1135. return FALSE;
  1136. }
  1137. }
  1138. }
  1139. if ((ERROR_SUCCESS == hRes) && bReboot)
  1140. {
  1141. if (OS_NT && (TRUE == IsServicePackInstalled()))
  1142. {
  1143. //
  1144. // If service pack is installed, then display message asking
  1145. // user to re-install the service pack and exit without rebooting
  1146. // We do this because rebooting after installing RAS, without
  1147. // reinstalling the service pack can cause BlueScreen!
  1148. //
  1149. DisplayMessageToInstallServicePack(hWndDlg, pszServiceName);
  1150. return FALSE;
  1151. }
  1152. else
  1153. {
  1154. //
  1155. // Display reboot message and is user wants reboot the sytem
  1156. //
  1157. LPTSTR pszMsg = CmFmtMsg(g_hInst,IDMSG_REBOOT_MSG);
  1158. int iRes = IDNO;
  1159. if (pszMsg)
  1160. {
  1161. iRes = MessageBoxEx(hWndDlg,
  1162. pszMsg,
  1163. pszServiceName,
  1164. MB_YESNO | MB_DEFBUTTON1 |
  1165. MB_ICONWARNING | MB_SETFOREGROUND,
  1166. LANG_USER_DEFAULT);
  1167. CmFree(pszMsg);
  1168. }
  1169. else
  1170. {
  1171. CMASSERTMSG(FALSE, TEXT("InstallComponents: CmFmtMsg failed to load IDMSG_REBOOT_MSG"));
  1172. }
  1173. if (IDYES == iRes)
  1174. {
  1175. //
  1176. // Shutdown Windows, CM will quit gracefully on
  1177. // WM_ENDSESSION message
  1178. // What shall we do if MyExitWindowsEx() fialed
  1179. //
  1180. DWORD dwReason = OS_NT51 ? (SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_RECONFIG) : 0;
  1181. MyExitWindowsEx(EWX_REBOOT, dwReason);
  1182. //
  1183. // Caller will return failed
  1184. //
  1185. return FALSE;
  1186. }
  1187. else
  1188. {
  1189. //
  1190. // If user do not want to reboot, shall we quit CM
  1191. //
  1192. }
  1193. }
  1194. }
  1195. if (ERROR_SUCCESS == hRes)
  1196. {
  1197. return TRUE;
  1198. }
  1199. }
  1200. //
  1201. // Configuration check failed message, if install is not canceled
  1202. //
  1203. LPTSTR pszMsg = CmFmtMsg(g_hInst,IDMSG_CONFIG_FAILED_MSG);
  1204. if (pszMsg)
  1205. {
  1206. MessageBoxEx(hWndDlg, pszMsg, pszServiceName, MB_OK|MB_ICONSTOP,
  1207. LANG_USER_DEFAULT);
  1208. CmFree(pszMsg);
  1209. }
  1210. else
  1211. {
  1212. CMASSERTMSG(FALSE, TEXT("InstallComponents: CmFmtMsg failed to load IDMSG_CONFIG_FAILED_MSG"));
  1213. }
  1214. return FALSE;
  1215. }
  1216. //+----------------------------------------------------------------------------
  1217. // Function ConfigSystem
  1218. //
  1219. // Synopsis Use inetcfg.dll to configure system settings,
  1220. // like install modem, rna etc.
  1221. //
  1222. // Arguments hWndDlg - Window Handle of parent window
  1223. // dwfOptions - Components to be configured
  1224. // pbReboot - Will be set to true if system has to rebooted
  1225. // as result of the configuration
  1226. //
  1227. // Returns ERROR_SUCCESS if successful
  1228. // Failure code otherwise
  1229. //
  1230. // History Old code
  1231. //-----------------------------------------------------------------------------
  1232. HRESULT ConfigSystem(HWND hwndParent,
  1233. DWORD dwfOptions,
  1234. LPBOOL pbReboot)
  1235. {
  1236. HRESULT hRes = ERROR_SUCCESS;
  1237. HINSTANCE hLibrary = NULL;
  1238. HRESULT (WINAPI *pfn)(HWND,DWORD,LPBOOL);
  1239. hLibrary = LoadInetCfg();
  1240. if (!hLibrary)
  1241. {
  1242. CMTRACE1(TEXT("ConfigSystem() LoadLibrary() failed, GLE=%u."), GetLastError());
  1243. hRes = GetLastError();
  1244. goto done;
  1245. }
  1246. pfn = (HRESULT (WINAPI *)(HWND,DWORD,LPBOOL)) GetProcAddress(hLibrary, "InetConfigSystem");
  1247. if (!pfn)
  1248. {
  1249. CMTRACE1(TEXT("ConfigSystem() GetProcAddress() failed, GLE=%u."), GetLastError());
  1250. hRes = GetLastError();
  1251. goto done;
  1252. }
  1253. hRes = pfn(hwndParent,dwfOptions,pbReboot);
  1254. #ifdef DEBUG
  1255. if (hRes != ERROR_SUCCESS)
  1256. {
  1257. CMTRACE1(TEXT("ConfigSystem() InetConfigSystem() failed, GLE=%u."), hRes);
  1258. }
  1259. #endif
  1260. done:
  1261. if (hLibrary)
  1262. {
  1263. FreeLibrary(hLibrary);
  1264. hLibrary = NULL;
  1265. }
  1266. return (hRes);
  1267. }
  1268. //+----------------------------------------------------------------------------
  1269. // Function InetNeedSystemComponents
  1270. //
  1271. // Synopsis Use inetcfg.dll to check if we need to configure system settings
  1272. // like rna etc.
  1273. //
  1274. // Arguments dwfOptions - Components to be configured
  1275. // pbNeedSysComponents - Will be set to true if we need to
  1276. // configure system settings
  1277. //
  1278. // Returns ERROR_SUCCESS if successful
  1279. // Failure code otherwise
  1280. //
  1281. // History 5/5/97 VetriV Created
  1282. //-----------------------------------------------------------------------------
  1283. HRESULT InetNeedSystemComponents(DWORD dwfOptions,
  1284. LPBOOL pbNeedSysComponents)
  1285. {
  1286. HRESULT hRes = ERROR_SUCCESS;
  1287. HINSTANCE hLibrary = NULL;
  1288. HRESULT (WINAPI *pfnInetNeedSystemComponents)(DWORD, LPBOOL);
  1289. hLibrary = LoadInetCfg();
  1290. if (!hLibrary)
  1291. {
  1292. hRes = GetLastError();
  1293. CMTRACE1(TEXT("InetNeedSystemComponents() LoadLibrary() failed, GLE=%u."), hRes);
  1294. goto done;
  1295. }
  1296. pfnInetNeedSystemComponents = (HRESULT (WINAPI *)(DWORD,LPBOOL)) GetProcAddress(hLibrary, "InetNeedSystemComponents");
  1297. if (!pfnInetNeedSystemComponents)
  1298. {
  1299. hRes = GetLastError();
  1300. CMTRACE1(TEXT("InetNeedSystemComponents() GetProcAddress() failed, GLE=%u."), hRes);
  1301. goto done;
  1302. }
  1303. hRes = pfnInetNeedSystemComponents(dwfOptions, pbNeedSysComponents);
  1304. #ifdef DEBUG
  1305. if (hRes != ERROR_SUCCESS)
  1306. {
  1307. CMTRACE1(TEXT("InetNeedSystemComponents() failed, GLE=%u."), hRes);
  1308. }
  1309. #endif
  1310. done:
  1311. if (hLibrary)
  1312. {
  1313. FreeLibrary(hLibrary);
  1314. hLibrary = NULL;
  1315. }
  1316. return (hRes);
  1317. }
  1318. //+----------------------------------------------------------------------------
  1319. // Function InetNeedModem
  1320. //
  1321. // Synopsis Use inetcfg.dll to check if we need to install/configure modem
  1322. //
  1323. // Arguments pbNeedModem - Will be set to true if we need to
  1324. // install/configure modem
  1325. //
  1326. // Returns ERROR_SUCCESS if successful
  1327. // Failure code otherwise
  1328. //
  1329. // History 5/5/97 VetriV Created
  1330. //-----------------------------------------------------------------------------
  1331. HRESULT InetNeedModem(LPBOOL pbNeedModem)
  1332. {
  1333. HRESULT hRes = ERROR_SUCCESS;
  1334. HINSTANCE hLibrary = NULL;
  1335. HRESULT (WINAPI *pfnInetNeedModem)(LPBOOL);
  1336. hLibrary = LoadInetCfg();
  1337. if (!hLibrary)
  1338. {
  1339. hRes = GetLastError();
  1340. CMTRACE1(TEXT("InetNeedModem() LoadLibrary() failed, GLE=%u."), hRes);
  1341. goto done;
  1342. }
  1343. pfnInetNeedModem = (HRESULT (WINAPI *)(LPBOOL)) GetProcAddress(hLibrary, "InetNeedModem");
  1344. if (!pfnInetNeedModem)
  1345. {
  1346. hRes = GetLastError();
  1347. CMTRACE1(TEXT("InetNeedModem() GetProcAddress() failed, GLE=%u."), hRes);
  1348. goto done;
  1349. }
  1350. hRes = pfnInetNeedModem(pbNeedModem);
  1351. #ifdef DEBUG
  1352. if (hRes != ERROR_SUCCESS)
  1353. {
  1354. CMTRACE1(TEXT("InetNeedModem() failed, GLE=%u."), hRes);
  1355. }
  1356. #endif
  1357. done:
  1358. if (hLibrary)
  1359. {
  1360. FreeLibrary(hLibrary);
  1361. hLibrary = NULL;
  1362. }
  1363. return (hRes);
  1364. }
  1365. //+----------------------------------------------------------------------------
  1366. // Function DisplayMessageToInstallServicePack
  1367. //
  1368. // Synopsis Display a message to user informing them to reinstall
  1369. // Service Pack
  1370. //
  1371. // Arguments hWndParent - Window handle to parent
  1372. // pszServiceName - Service name for title
  1373. //
  1374. // Returns None
  1375. //
  1376. // History 2/4/98 VetriV Created
  1377. //-----------------------------------------------------------------------------
  1378. void DisplayMessageToInstallServicePack(HWND hWndParent, LPCTSTR pszServiceName)
  1379. {
  1380. LPTSTR pszMsg = CmFmtMsg(g_hInst,IDMSG_INSTALLSP_MSG);
  1381. if (pszMsg)
  1382. {
  1383. MessageBoxEx(hWndParent, pszMsg, pszServiceName, MB_OK | MB_ICONINFORMATION,
  1384. LANG_USER_DEFAULT);
  1385. CmFree(pszMsg);
  1386. }
  1387. else
  1388. {
  1389. CMASSERTMSG(FALSE, TEXT("DisplayMessageToInstallServicePack: CmFmtMsg failed to load IDMSG_INSTALLSP_MSG"));
  1390. }
  1391. return;
  1392. }