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.

207 lines
6.5 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: uninstallcm.cpp
  4. //
  5. // Module: CMSTP.EXE
  6. //
  7. // Synopsis: This source file contains the code for installing Connection Manager.
  8. //
  9. // Copyright (c) 1997-1999 Microsoft Corporation
  10. //
  11. // Author: quintinb Created 07/14/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. #include "installerfuncs.h"
  16. //+----------------------------------------------------------------------------
  17. //
  18. // Function: CheckAndPromptForCmakAndProfiles
  19. //
  20. // Synopsis: This function checks to see if CM profiles are installed or if
  21. // CMAK 1.21 is installed. If it is, then uninstalling CM will make
  22. // the profiles and CMAK unusable and we want to prompt the user
  23. // to make sure they know what they are doing.
  24. //
  25. // Arguments: HINSTANCE hInstance - Exe instance handle to access resources
  26. //
  27. // Returns: BOOL - returns TRUE if it is okay to continue with the uninstall
  28. //
  29. // History: quintinb Created Header 10/21/98
  30. //
  31. //+----------------------------------------------------------------------------
  32. BOOL CheckAndPromptForCmakAndProfiles(HINSTANCE hInstance, LPCTSTR pszTitle)
  33. {
  34. BOOL bCmakInstalled = FALSE;
  35. BOOL bCmProfiles = FALSE;
  36. TCHAR szMsg[2*MAX_PATH+1];
  37. //
  38. // First check to see if CMAK is installed. If it is and has a version of 1.21
  39. // (build 1886 or newer) then we must prompt the user before uninstalling.
  40. // Otherwise, if you uninstall CM out from under it, CMAK will no longer
  41. // function.
  42. //
  43. DWORD dwFirst121VersionNumber = 0;
  44. const int c_Cmak121Version = 1886;
  45. int iShiftAmount = ((sizeof(DWORD)/2) * 8);
  46. //
  47. // Construct the current version and build numbers
  48. //
  49. dwFirst121VersionNumber = (HIBYTE(VER_PRODUCTVERSION_W) << iShiftAmount) + (LOBYTE(VER_PRODUCTVERSION_W));
  50. CmakVersion CmakVer;
  51. if (CmakVer.IsPresent())
  52. {
  53. if ((dwFirst121VersionNumber < CmakVer.GetVersionNumber()) ||
  54. (c_Cmak121Version < CmakVer.GetBuildNumber()))
  55. {
  56. bCmakInstalled = TRUE;
  57. }
  58. }
  59. //
  60. // Now check to see if we have CM profiles installed.
  61. //
  62. HKEY hKey;
  63. DWORD dwNumValues;
  64. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_pszRegCmMappings, 0,
  65. KEY_READ, &hKey))
  66. {
  67. if ((ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
  68. &dwNumValues, NULL, NULL, NULL, NULL)) && (dwNumValues > 0))
  69. {
  70. //
  71. // Then we have mappings values, so we need to migrate them.
  72. //
  73. bCmProfiles = TRUE;
  74. }
  75. RegCloseKey(hKey);
  76. }
  77. if (bCmProfiles)
  78. {
  79. MYVERIFY(0 != LoadString(hInstance, bCmakInstalled ? IDS_UNINSTCM_BOTH : IDS_UNINSTCM_WCM, szMsg, 2*MAX_PATH));
  80. MYDBGASSERT(TEXT('\0') != szMsg[0]);
  81. if (IDNO == MessageBox(NULL, szMsg, pszTitle, MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION))
  82. {
  83. return FALSE;
  84. }
  85. }
  86. else if (bCmakInstalled)
  87. {
  88. //
  89. // Just CMAK is installed
  90. //
  91. MYVERIFY(0 != LoadString(hInstance, IDS_UNINSTCM_WCMAK, szMsg, 2*MAX_PATH));
  92. MYDBGASSERT(TEXT('\0') != szMsg[0]);
  93. if (IDNO == MessageBox(NULL, szMsg, pszTitle, MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION))
  94. {
  95. return FALSE;
  96. }
  97. }
  98. return TRUE;
  99. }
  100. //+----------------------------------------------------------------------------
  101. //
  102. // Function: PromptUserToUninstallCm
  103. //
  104. // Synopsis: This function prompts the user to see if they wish to uninstall
  105. // Connection Manager. It also deals with the warning prompts if
  106. // the user has CMAK or CM profiles installed.
  107. //
  108. // Arguments: HINSTANCE hInstance - Instance handle to load resources with.
  109. //
  110. // Returns: BOOL - Returns TRUE if CM should be uninstalled, FALSE otherwise
  111. //
  112. // History: quintinb Created 6/28/99
  113. //
  114. //+----------------------------------------------------------------------------
  115. BOOL PromptUserToUninstallCm(HINSTANCE hInstance)
  116. {
  117. BOOL bReturn = FALSE;
  118. TCHAR szMsg[MAX_PATH+1] = {TEXT("")};
  119. TCHAR szTitle[MAX_PATH+1] = {TEXT("")};
  120. //
  121. // Load the Cmstp Title just in case we need to show error messages.
  122. //
  123. MYVERIFY(0 != LoadString(hInstance, IDS_CM_UNINST_TITLE, szTitle, MAX_PATH));
  124. MYDBGASSERT(TEXT('\0') != szTitle[0]);
  125. //
  126. // Now show the uninstall prompt to see if the user wants to uninstall CM
  127. //
  128. MYVERIFY(0 != LoadString(hInstance, IDS_CM_UNINST_PROMPT, szMsg, MAX_PATH));
  129. MYDBGASSERT(TEXT('\0') != szMsg[0]);
  130. if (IDYES == MessageBox(NULL, szMsg, szTitle, MB_YESNO | MB_DEFBUTTON2))
  131. {
  132. //
  133. // Check to see if CMAK is installed or if there are profiles that are installed.
  134. //
  135. if (CheckAndPromptForCmakAndProfiles(hInstance, szTitle))
  136. {
  137. bReturn = TRUE;
  138. }
  139. }
  140. return bReturn;
  141. }
  142. //+----------------------------------------------------------------------------
  143. //
  144. // Function: UninstallCm
  145. //
  146. // Synopsis: Uninstalls connection manager.
  147. //
  148. // Arguments: HINSTANCE hInstance - instance handle to access resources
  149. // LPCTSTR szInfPath - path to the instcm.inf file to use to uninstall cm with
  150. //
  151. // Returns: HRESULT -- Standard COM Error Codes
  152. //
  153. // History: Created Header 10/21/98
  154. //
  155. //+----------------------------------------------------------------------------
  156. HRESULT UninstallCm(HINSTANCE hInstance, LPCTSTR szInfPath)
  157. {
  158. MYDBGASSERT((szInfPath) && (TEXT('\0') != szInfPath[0]));
  159. //
  160. // Load the Cmstp Title just in case we need to show error messages.
  161. //
  162. TCHAR szTitle[MAX_PATH+1] = {TEXT("")};
  163. TCHAR szMsg[MAX_PATH+1] = {TEXT("")};
  164. MYVERIFY(0 != LoadString(hInstance, IDS_CM_UNINST_TITLE, szTitle, MAX_PATH));
  165. MYDBGASSERT(TEXT('\0') != szTitle[0]);
  166. //
  167. // Protect /x on NT5 and win98 SR1. We don't want CM uninstalled on Native Platforms.
  168. //
  169. HRESULT hr = S_FALSE;
  170. if (!CmIsNative())
  171. {
  172. if (SUCCEEDED(LaunchInfSection(szInfPath, TEXT("1.2Legacy_Uninstall"), szTitle, FALSE))) // bQuiet = FALSE
  173. {
  174. MYVERIFY(0 != LoadString(hInstance, IDS_CM_UNINST_SUCCESS, szMsg, MAX_PATH));
  175. MYDBGASSERT(TEXT('\0') != szMsg[0]);
  176. MYVERIFY(IDOK == MessageBox(NULL, szMsg, szTitle, MB_OK));
  177. hr = S_OK;
  178. }
  179. else
  180. {
  181. CMASSERTMSG(FALSE, TEXT("Connection Manager Uninstall Failed."));
  182. }
  183. }
  184. return hr;
  185. }