Leaked source code of windows server 2003
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.

395 lines
14 KiB

  1. // ---------------------------------------------------------------------------
  2. // MAIN.CPP
  3. // ---------------------------------------------------------------------------
  4. // Copyright (c) 1999 Microsoft Corporation
  5. //
  6. // Migration DLL for Outlook Express and Windows Address Book moving from
  7. // Win9X to NT5.
  8. //
  9. // ---------------------------------------------------------------------------
  10. #include "pch.hxx"
  11. #include <setupapi.h>
  12. #include <strings.h>
  13. #include "resource.h"
  14. #include "detect.h"
  15. #include "main.h"
  16. // Used for resources
  17. static HMODULE s_hInst = NULL;
  18. // These settings are init'd during Initialize9x and used later
  19. static LPSTR s_pszMigratePath = NULL;
  20. static TCHAR s_szOEVer[VERLEN] = "";
  21. static SETUPVER s_svOEInterimVer = VER_NONE;
  22. static TCHAR s_szWABVer[VERLEN] = "";
  23. static SETUPVER s_svWABInterimVer = VER_NONE;
  24. static const char c_szMigrateINF[] = "migrate.inf";
  25. // Dll Entry point
  26. INT WINAPI DllMain(IN HINSTANCE hInstance,
  27. IN DWORD dwReason,
  28. PVOID pvReserved)
  29. {
  30. UNREFERENCED_PARAMETER(pvReserved);
  31. // Validate Params
  32. Assert(hInstance);
  33. switch (dwReason)
  34. {
  35. case DLL_PROCESS_ATTACH :
  36. DisableThreadLibraryCalls(hInstance);
  37. // Open Error Log. FALSE indicates that any current
  38. // log is not deleted. Use SetupErrorLog() to record
  39. // any errors encountered within the Migration DLL.
  40. //SetupOpenLog(FALSE);
  41. // Need this global to figure out the others
  42. s_hInst = hInstance;
  43. break;
  44. case DLL_PROCESS_DETACH :
  45. //SetupCloseLog();
  46. if (s_pszMigratePath)
  47. {
  48. GlobalFree(s_pszMigratePath);
  49. s_pszMigratePath = NULL;
  50. }
  51. break;
  52. default:
  53. break;
  54. }
  55. return TRUE;
  56. }
  57. ////////////////////////////////////
  58. // QueryVersion()
  59. EXPORT_FUNCTION LONG CALLBACK QueryVersion(OUT LPCSTR *ppcszProductID,
  60. OUT UINT *pnDllVersion,
  61. OUT INT **ppnCodePageArray, // Optional
  62. OUT LPCSTR *ppcszExeNamesBuf, // Optional
  63. OUT VENDORINFO **ppVendorInfo)
  64. {
  65. // These need to be static as their addresses are given to setup
  66. // - ie. they need to live as long as they can.
  67. static CHAR s_szProductID[CCHMAX_STRINGRES] = "";
  68. static CHAR s_szCompany[CCHMAX_STRINGRES] = "";
  69. static CHAR s_szPhone[CCHMAX_STRINGRES] = "";
  70. static CHAR s_szURL[CCHMAX_STRINGRES] = "";
  71. static CHAR s_szInstructions[CCHMAX_STRINGRES] = "";
  72. static VENDORINFO s_VendInfo;
  73. // Validate Params
  74. Assert(ppcszProductID);
  75. Assert(pnDllVersion);
  76. Assert(ppnCodePageArray);
  77. Assert(ppcszExeNamesBuf);
  78. Assert(ppVendorInfo);
  79. // Validate global state
  80. Assert(s_hInst);
  81. // Initialize statics
  82. LoadStringA(s_hInst, IDS_PRODUCTID, s_szProductID, ARRAYSIZE(s_szProductID));
  83. LoadStringA(s_hInst, IDS_COMPANY, s_szCompany, ARRAYSIZE(s_szCompany));
  84. LoadStringA(s_hInst, IDS_PHONE, s_szPhone, ARRAYSIZE(s_szPhone));
  85. LoadStringA(s_hInst, IDS_URL, s_szURL, ARRAYSIZE(s_szURL));
  86. LoadStringA(s_hInst, IDS_INSTRUCTIONS, s_szInstructions, ARRAYSIZE(s_szInstructions));
  87. StrCpyN(s_VendInfo.CompanyName, s_szCompany, ARRAYSIZE(s_VendInfo.CompanyName));
  88. StrCpyN(s_VendInfo.SupportNumber, s_szPhone, ARRAYSIZE(s_VendInfo.SupportNumber));
  89. StrCpyN(s_VendInfo.SupportUrl, s_szURL, ARRAYSIZE(s_VendInfo.SupportNumber));
  90. StrCpyN(s_VendInfo.InstructionsToUser, s_szInstructions, ARRAYSIZE(s_VendInfo.InstructionsToUser));
  91. // Return information
  92. *ppcszProductID = s_szProductID;
  93. *pnDllVersion = MIGDLL_VERSION;
  94. // We don't have locale-specific migration work
  95. *ppnCodePageArray = NULL;
  96. // We don't need setup to locate any exes for us
  97. *ppcszExeNamesBuf = NULL;
  98. *ppVendorInfo = &s_VendInfo;
  99. return ERROR_SUCCESS;
  100. }
  101. ////////////////////////////////////
  102. // Initialize9x()
  103. EXPORT_FUNCTION LONG CALLBACK Initialize9x (IN LPCSTR pszWorkingDir,
  104. IN LPCSTR pszSourceDirs,
  105. LPVOID pvReserved)
  106. {
  107. BOOL fWABInstalled = FALSE;
  108. BOOL fOEInstalled = FALSE;
  109. INT nLen;
  110. INT nLenEnd;
  111. INT nLenSlash;
  112. LONG lRet = ERROR_NOT_INSTALLED;
  113. UNREFERENCED_PARAMETER(pszSourceDirs);
  114. UNREFERENCED_PARAMETER(pvReserved);
  115. // Validate Params
  116. Assert(pszWorkingDir);
  117. Assert(pszSourceDirs);
  118. // See if either the WAB or OE is installed
  119. fOEInstalled = LookForApp(APP_OE, s_szOEVer, ARRAYSIZE(s_szOEVer), s_svOEInterimVer);
  120. fWABInstalled = LookForApp(APP_WAB, s_szWABVer, ARRAYSIZE(s_szWABVer), s_svWABInterimVer);
  121. // If OE is installed, WAB better be too
  122. Assert(!fOEInstalled || fWABInstalled);
  123. if (fWABInstalled || fOEInstalled)
  124. {
  125. // Validate global state
  126. Assert(NULL == s_pszMigratePath);
  127. // ---- Figure out largest needed size and slash terminate
  128. // Parameter length (without null)
  129. nLenEnd = lstrlenA(pszWorkingDir);
  130. // Space for a slash
  131. if (*CharPrev(pszWorkingDir, pszWorkingDir + nLenEnd) != '\\')
  132. nLenSlash = 1;
  133. else
  134. nLenSlash = 0;
  135. // Space for migrate.inf and a NULL (null is incl in ARRAYSIZE)
  136. nLen = nLenEnd + nLenSlash + ARRAYSIZE(c_szMigrateINF);
  137. // Allocate the space
  138. s_pszMigratePath = (LPSTR)GlobalAlloc(GMEM_FIXED, nLen * sizeof(*s_pszMigratePath));
  139. if (NULL != s_pszMigratePath)
  140. {
  141. // Build path from working dir, slash and filename
  142. StrCpyN(s_pszMigratePath, pszWorkingDir, nLen);
  143. if (nLenSlash)
  144. s_pszMigratePath[nLenEnd] = '\\';
  145. StrCpyN(&s_pszMigratePath[nLenEnd+nLenSlash], c_szMigrateINF, nLen - (nLenEnd+nLenSlash));
  146. lRet = ERROR_SUCCESS;
  147. }
  148. }
  149. // Return ERROR_NOT_INSTALLED to stop further calls to this DLL.
  150. return lRet;
  151. }
  152. ////////////////////////////////////
  153. // MigrateUser9x()
  154. EXPORT_FUNCTION LONG CALLBACK MigrateUser9x (IN HWND hwndParent,
  155. IN LPCSTR pcszAnswerFile,
  156. IN HKEY hkeyUser,
  157. IN LPCSTR pcszUserName,
  158. LPVOID pvReserved)
  159. {
  160. UNREFERENCED_PARAMETER(hwndParent);
  161. UNREFERENCED_PARAMETER(pcszAnswerFile);
  162. UNREFERENCED_PARAMETER(hkeyUser);
  163. UNREFERENCED_PARAMETER(pcszUserName);
  164. UNREFERENCED_PARAMETER(pvReserved);
  165. // Validate Params
  166. Assert(pcszAnswerFile);
  167. Assert(hkeyUser);
  168. Assert(pcszUserName);
  169. // We will migrate per-user settings in the per-user stub
  170. // Nothing to do now
  171. return ERROR_NOT_INSTALLED;
  172. }
  173. ////////////////////////////////////
  174. // MigrateSystem9x()
  175. EXPORT_FUNCTION LONG CALLBACK MigrateSystem9x(IN HWND hwndParent,
  176. IN LPCSTR pcszAnswerFile,
  177. LPVOID pvReserved)
  178. {
  179. UNREFERENCED_PARAMETER(hwndParent);
  180. UNREFERENCED_PARAMETER(pcszAnswerFile);
  181. UNREFERENCED_PARAMETER(pvReserved);
  182. // Validate Params
  183. Assert(pcszAnswerFile);
  184. // Validate global state
  185. Assert(s_pszMigratePath);
  186. Assert(s_pszMigratePath[0]);
  187. // Record Version info
  188. if (s_szOEVer[0])
  189. WritePrivateProfileString("Outlook-Express", "PreviousVer", s_szOEVer, s_pszMigratePath);
  190. if (VER_NONE != s_svOEInterimVer)
  191. WritePrivateProfileStruct("Outlook-Express", "InterimVer",
  192. (LPVOID)&s_svOEInterimVer, sizeof(s_svOEInterimVer), s_pszMigratePath);
  193. if (s_szWABVer[0])
  194. WritePrivateProfileString("Windows-Address-Book", "PreviousVer", s_szWABVer, s_pszMigratePath);
  195. if (VER_NONE != s_svWABInterimVer)
  196. WritePrivateProfileStruct("Windows-Address-Book", "InterimVer",
  197. (LPVOID)&s_svWABInterimVer, sizeof(s_svWABInterimVer), s_pszMigratePath);
  198. // Modify Migrate.INF appropriately. Consider adding entries to
  199. // the following sections :
  200. // [HANDLED] - Files, Paths, and Registry entries you migrate (causing setup to leave files and paths alone; registry entries placed here are not copied into the NT5 registry automatically)
  201. // [MOVED] - Indicate Files that are moved, renamed, or deleted. Setup updates shell links to these files.
  202. // [INCOMPATIBLE MESSAGES] - Used to create a incompatibility report for this application. User will be provided the opportunity to read this before committing to the upgrade.
  203. // TODO : return ERROR_NOT_INSTALLED if your application requires no system wide changes.
  204. return (s_szOEVer[0] || s_szWABVer[0]) ? ERROR_SUCCESS : ERROR_NOT_INSTALLED;
  205. }
  206. ////////////////////////////////////
  207. // InitializeNT()
  208. EXPORT_FUNCTION LONG CALLBACK InitializeNT (IN LPCWSTR pcwszWorkingDir,
  209. IN LPCWSTR pcwszSourceDirs,
  210. LPVOID pvReserved)
  211. {
  212. int cb, cch;
  213. LONG lErr = ERROR_SUCCESS;
  214. UNREFERENCED_PARAMETER(pcwszSourceDirs);
  215. UNREFERENCED_PARAMETER(pvReserved);
  216. // Validate Params
  217. Assert(pcwszWorkingDir);
  218. Assert(pcwszSourceDirs);
  219. // Validate global state
  220. Assert(NULL == s_pszMigratePath);
  221. // Strings sent on NT side of setup are Unicode
  222. // How big a buffer do we need?
  223. cb = WideCharToMultiByte(CP_ACP, 0, pcwszWorkingDir, -1, NULL, 0, NULL, NULL);
  224. if (0 == cb)
  225. {
  226. // This will fail the entire OE/WAB migration
  227. lErr = GetLastError();
  228. goto exit;
  229. }
  230. // Try to alloc the buffer
  231. // Allow space for possible slash (+1) and migrate.inf (ARRAYSIZE - 1 for null)
  232. // NULL was included in WideCharToMultiByte's count
  233. s_pszMigratePath = (LPSTR)GlobalAlloc(GMEM_FIXED, cb +
  234. ((1+(ARRAYSIZE(c_szMigrateINF)-1))*sizeof(*s_pszMigratePath)));
  235. // Set cch to the number of characters that can be contained in s_pszMigratePath
  236. cch = cb / sizeof(*s_pszMigratePath) + (1+(ARRAYSIZE(c_szMigrateINF)-1));
  237. if (NULL == s_pszMigratePath)
  238. {
  239. // This will fail the entire OE/WAB migration
  240. lErr = ERROR_NOT_ENOUGH_MEMORY;
  241. goto exit;
  242. }
  243. // Do the conversion
  244. cb = WideCharToMultiByte(CP_ACP, 0, pcwszWorkingDir, -1, s_pszMigratePath, cb, NULL, NULL);
  245. if (0 == cb)
  246. {
  247. // This will fail the entire OE/WAB migration
  248. lErr = GetLastError();
  249. goto exit;
  250. }
  251. // WideCharToMultiByte includes NULL in count
  252. cb--;
  253. // Append a backslash if needed
  254. if ('\\' != *CharPrev(s_pszMigratePath, s_pszMigratePath + cb))
  255. s_pszMigratePath[cb++] = '\\';
  256. // Append the name of the inf
  257. StrCpyN(&s_pszMigratePath[cb], "migrate.inf", cch - cb);
  258. exit:
  259. return lErr;
  260. }
  261. ////////////////////////////////////
  262. // MigrateUserNT()
  263. EXPORT_FUNCTION LONG CALLBACK MigrateUserNT(IN HINF hinfAnswerFile,
  264. IN HKEY hkeyUser,
  265. IN LPCWSTR pcwszUserName,
  266. LPVOID pvReserved)
  267. {
  268. UNREFERENCED_PARAMETER(hinfAnswerFile);
  269. UNREFERENCED_PARAMETER(hkeyUser);
  270. UNREFERENCED_PARAMETER(pcwszUserName);
  271. UNREFERENCED_PARAMETER(pvReserved);
  272. // Validate Params
  273. Assert(hinfAnswerFile);
  274. Assert(hkeyUser);
  275. // pcwszUserName can be NULL
  276. // We will migrate per-user settings in the per-user stub
  277. // Nothing to do now
  278. return ERROR_SUCCESS;
  279. }
  280. ////////////////////////////////////
  281. // MigrateSystemNT()
  282. EXPORT_FUNCTION LONG CALLBACK MigrateSystemNT(IN HINF hinfAnswerFile,
  283. LPVOID pvReserved)
  284. {
  285. HKEY hkey;
  286. DWORD dwDisp;
  287. UNREFERENCED_PARAMETER(hinfAnswerFile);
  288. UNREFERENCED_PARAMETER(pvReserved);
  289. // Validate params
  290. Assert(hinfAnswerFile);
  291. // Validate global state
  292. Assert(s_pszMigratePath);
  293. Assert(s_pszMigratePath[0]);
  294. // Read information we gathered from Win9x
  295. GetPrivateProfileString("Outlook-Express", "PreviousVer", "", s_szOEVer, ARRAYSIZE(s_szOEVer), s_pszMigratePath);
  296. GetPrivateProfileStruct("Outlook-Express", "InterimVer", (LPVOID)&s_svOEInterimVer, sizeof(s_svOEInterimVer), s_pszMigratePath);
  297. GetPrivateProfileString("Windows-Address-Book", "PreviousVer", "", s_szWABVer, ARRAYSIZE(s_szWABVer), s_pszMigratePath);
  298. GetPrivateProfileStruct("Windows-Address-Book", "InterimVer", (LPVOID)&s_svWABInterimVer, sizeof(s_svWABInterimVer), s_pszMigratePath);
  299. // Update machine with information
  300. if (s_szOEVer[0])
  301. {
  302. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szRegVerInfo, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dwDisp))
  303. {
  304. RegSetValueEx(hkey, c_szRegPrevVer, 0, REG_SZ, (LPBYTE)s_szOEVer, lstrlenA(s_szOEVer)+1);
  305. if (s_svOEInterimVer != VER_NONE)
  306. RegSetValueEx(hkey, c_szRegInterimVer, 0, REG_DWORD, (LPBYTE)&s_svOEInterimVer, sizeof(s_svOEInterimVer));
  307. RegCloseKey(hkey);
  308. }
  309. }
  310. if (s_szWABVer[0])
  311. {
  312. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szRegWABVerInfo, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dwDisp))
  313. {
  314. RegSetValueEx(hkey, c_szRegPrevVer, 0, REG_SZ, (LPBYTE)s_szWABVer, lstrlenA(s_szWABVer)+1);
  315. if (s_svWABInterimVer != VER_NONE)
  316. RegSetValueEx(hkey, c_szRegInterimVer, 0, REG_DWORD, (LPBYTE)&s_svWABInterimVer, sizeof(s_svWABInterimVer));
  317. RegCloseKey(hkey);
  318. }
  319. }
  320. return ERROR_SUCCESS;
  321. }