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.

352 lines
7.0 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. interface.c
  5. Abstract:
  6. Implements the APIs exposed by osuninst.dll
  7. Author:
  8. Jim Schmidt (jimschm) 19-Jan-2001
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. #include "undop.h"
  14. HANDLE g_hHeap;
  15. HINSTANCE g_hInst;
  16. #ifndef UNICODE
  17. #error UNICODE required
  18. #endif
  19. BOOL g_Initialized = FALSE;
  20. //
  21. // Entry point for DLL
  22. //
  23. BOOL WINAPI MigUtil_Entry (HINSTANCE, DWORD, PVOID);
  24. BOOL
  25. pCallEntryPoints (
  26. DWORD Reason
  27. )
  28. {
  29. SuppressAllLogPopups (TRUE);
  30. if (!MigUtil_Entry (g_hInst, Reason, NULL)) {
  31. return FALSE;
  32. }
  33. //
  34. // Add others here if needed (don't forget to prototype above)
  35. //
  36. return TRUE;
  37. }
  38. BOOL
  39. WINAPI
  40. DllMain (
  41. IN HINSTANCE hInstance,
  42. IN DWORD dwReason,
  43. IN LPVOID lpReserved
  44. )
  45. {
  46. switch (dwReason) {
  47. case DLL_PROCESS_ATTACH:
  48. g_hInst = hInstance;
  49. break;
  50. case DLL_PROCESS_DETACH:
  51. if (g_Initialized) {
  52. pCallEntryPoints (DLL_PROCESS_DETACH);
  53. g_Initialized = FALSE;
  54. break;
  55. }
  56. }
  57. return TRUE;
  58. }
  59. VOID
  60. DeferredInit (
  61. VOID
  62. )
  63. {
  64. if (g_Initialized) {
  65. return;
  66. }
  67. g_Initialized = TRUE;
  68. g_hHeap = GetProcessHeap();
  69. pCallEntryPoints (DLL_PROCESS_ATTACH);
  70. }
  71. DWORD
  72. pUninstallStatusToWin32Error (
  73. UNINSTALLSTATUS Status
  74. )
  75. {
  76. DWORD result = E_UNEXPECTED;
  77. switch (Status) {
  78. case Uninstall_Valid:
  79. result = ERROR_SUCCESS;
  80. break;
  81. case Uninstall_DidNotFindRegistryEntries:
  82. result = ERROR_RESOURCE_NOT_PRESENT;
  83. break;
  84. case Uninstall_DidNotFindDirOrFiles:
  85. result = ERROR_FILE_NOT_FOUND;
  86. break;
  87. case Uninstall_InvalidOsVersion:
  88. result = ERROR_OLD_WIN_VERSION;
  89. break;
  90. case Uninstall_NotEnoughPrivileges:
  91. result = ERROR_ACCESS_DENIED;
  92. break;
  93. case Uninstall_FileWasModified:
  94. result = ERROR_FILE_INVALID;
  95. break;
  96. case Uninstall_Unsupported:
  97. result = ERROR_CALL_NOT_IMPLEMENTED;
  98. break;
  99. case Uninstall_NewImage:
  100. result = ERROR_INVALID_TIME;
  101. break;
  102. case Uninstall_Exception:
  103. result = ERROR_NOACCESS;
  104. break;
  105. case Uninstall_OldImage:
  106. result = ERROR_TIMEOUT;
  107. break;
  108. case Uninstall_NotEnoughMemory:
  109. result = ERROR_NOT_ENOUGH_MEMORY;
  110. break;
  111. default:
  112. break;
  113. }
  114. SetLastError (result);
  115. return result;
  116. }
  117. BOOL
  118. pGetVersionDword (
  119. IN HKEY Key,
  120. IN PCTSTR ValueName,
  121. OUT PDWORD ValueData
  122. )
  123. {
  124. PDWORD data;
  125. data = (PDWORD) GetRegValueDword (Key, ValueName);
  126. if (!data) {
  127. return FALSE;
  128. }
  129. *ValueData = *data;
  130. MemFree (g_hHeap, 0, data);
  131. return TRUE;
  132. }
  133. UNINSTALLSTATUS
  134. IsUninstallImageValid (
  135. UNINSTALLTESTCOMPONENT ComponentType,
  136. OSVERSIONINFOEX *BackedUpOsVersion OPTIONAL
  137. )
  138. {
  139. UNINSTALLSTATUS status = Uninstall_Valid;
  140. DWORD orgVersionSize;
  141. HKEY key = NULL;
  142. ULONG error;
  143. PDWORD value;
  144. HKEY versionKey = NULL;
  145. OSVERSIONINFOEX ourVersion = {
  146. sizeof (OSVERSIONINFOEX),
  147. 4,
  148. 10,
  149. 1998,
  150. VER_PLATFORM_WIN32_NT,
  151. TEXT(""),
  152. 0,
  153. 0,
  154. 0,
  155. 0
  156. };
  157. DeferredInit();
  158. __try {
  159. //
  160. // Fill in version structure if possible, default to Win98 gold if not
  161. //
  162. key = OpenRegKeyStr (S_WINLOGON_REGKEY);
  163. if (key) {
  164. value = (PDWORD) GetRegValueDword (key, S_WIN9XUPG_FLAG_VALNAME);
  165. if (!value) {
  166. //
  167. // It is not looking like a Win9x upgrade!
  168. //
  169. DEBUGMSG ((DBG_VERBOSE, "Can't find %s in WinLogon reg key", S_WIN9XUPG_FLAG_VALNAME));
  170. status = Uninstall_DidNotFindRegistryEntries;
  171. } else {
  172. if (*value) {
  173. //
  174. // Version info should be present
  175. //
  176. versionKey = OpenRegKey (key, TEXT("PrevOsVersion"));
  177. if (versionKey) {
  178. pGetVersionDword (versionKey, MEMDB_ITEM_MAJOR_VERSION, &ourVersion.dwMajorVersion);
  179. pGetVersionDword (versionKey, MEMDB_ITEM_MINOR_VERSION, &ourVersion.dwMinorVersion);
  180. pGetVersionDword (versionKey, MEMDB_ITEM_BUILD_NUMBER, &ourVersion.dwBuildNumber);
  181. pGetVersionDword (versionKey, MEMDB_ITEM_PLATFORM_ID, &ourVersion.dwPlatformId);
  182. } else {
  183. DEBUGMSG ((DBG_VERBOSE, "Did not find PrevOsVersion; defaulting to Win98 gold"));
  184. }
  185. } else {
  186. DEBUGMSG ((DBG_VERBOSE, "Not a Win9x upgrade"));
  187. status = Uninstall_DidNotFindRegistryEntries;
  188. }
  189. MemFree (g_hHeap, 0, value);
  190. }
  191. }
  192. }
  193. __finally {
  194. if (versionKey)
  195. CloseRegKey (versionKey);
  196. if (key)
  197. CloseRegKey (key);
  198. }
  199. //
  200. // ComponentType is provided to allow special-case behavior to be
  201. // performed. For example, maybe we want to warn on FAT-to-NTFS
  202. // conversion when coming from Win9x, but we don't care when coming
  203. // from Win2k.
  204. //
  205. if (status == Uninstall_Valid) {
  206. status = SanityCheck (QUICK_CHECK, NULL, NULL);
  207. if (ComponentType == Uninstall_FatToNtfsConversion) {
  208. if (status == Uninstall_OldImage) {
  209. //
  210. // Do not suppress convert.exe warning even if uninstall is old
  211. //
  212. status = Uninstall_Valid;
  213. }
  214. }
  215. }
  216. if (status == Uninstall_Valid) {
  217. if (BackedUpOsVersion) {
  218. __try {
  219. orgVersionSize = BackedUpOsVersion->dwOSVersionInfoSize;
  220. orgVersionSize = min (orgVersionSize, sizeof (ourVersion));
  221. CopyMemory (BackedUpOsVersion, &ourVersion, orgVersionSize);
  222. BackedUpOsVersion->dwOSVersionInfoSize = orgVersionSize;
  223. }
  224. __except (1) {
  225. status = Uninstall_Exception;
  226. }
  227. }
  228. }
  229. pUninstallStatusToWin32Error (status);
  230. return status;
  231. }
  232. ULONGLONG
  233. GetUninstallImageSize (
  234. VOID
  235. )
  236. {
  237. ULONGLONG diskSpace;
  238. DeferredInit();
  239. //
  240. // SanityCheck returns the disk space used by the uninstall image,
  241. // regardless if it is valid or not.
  242. //
  243. SanityCheck (QUICK_CHECK, NULL, &diskSpace);
  244. return diskSpace;
  245. }
  246. BOOL
  247. RemoveUninstallImage (
  248. VOID
  249. )
  250. {
  251. DeferredInit();
  252. return DoCleanup();
  253. }
  254. BOOL
  255. ExecuteUninstall (
  256. VOID
  257. )
  258. {
  259. UNINSTALLSTATUS status;
  260. DeferredInit();
  261. status = SanityCheck (VERIFY_CAB, NULL, NULL);
  262. if (status != Uninstall_Valid && status != Uninstall_OldImage) {
  263. pUninstallStatusToWin32Error (status);
  264. return FALSE;
  265. }
  266. return DoUninstall();
  267. }