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.

568 lines
18 KiB

  1. // This is the migration dll for NT5 upgrades.
  2. // As per the Migration Extension Interface of NT5 Setup, this DLL needs to
  3. // implement the folowing six functions:
  4. // QueryVersion
  5. // Initialize9x
  6. // MigrateUser9x (called once for every user)
  7. // MigrateSystem9x
  8. // InitializeNT
  9. // MigrateUserNT (called once for every user)
  10. // MigrateSystemNT
  11. //
  12. // Written : ShabbirS (5/7/99)
  13. // Revision:
  14. //
  15. #include "pch.h"
  16. #include <ole2.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. #include <excppkg.h>
  21. #ifdef __cplusplus
  22. }
  23. #endif /* __cplusplus */
  24. #include "sdsutils.h"
  25. #include "advpub.h"
  26. #include "migrate.h"
  27. #include "utils.h"
  28. #include "resource.h"
  29. // Constants:
  30. #define CP_USASCII 1252
  31. #define END_OF_CODEPAGES -1
  32. // Globals that are passed back to Setup.
  33. //////////////////////////////////////////
  34. // Vendor Info:
  35. VENDORINFO g_VendorInfo = { "Microsoft Corporation",
  36. " ",
  37. "http://www.microsoft.com/support",
  38. "Please contact Microsoft Technical Support for assistance with this problem. "};
  39. // Product ID:
  40. char g_cszProductID[] = "Microsoft Internet Explorer";
  41. // Version number of this Migration Dll
  42. UINT g_uVersion = 3;
  43. // Array of integers specifying the CodePages we use. (Terminated with -1)
  44. int g_rCodePages[] = {CP_USASCII, END_OF_CODEPAGES};
  45. // Multi-SZ ie double Null terminated list of strings.
  46. char *g_lpNameBuf = NULL;
  47. DWORD g_dwNameBufSize = 0;
  48. char *g_lpWorkingDir = NULL;
  49. char *g_lpSourceDirs = NULL;
  50. char *g_lpMediaDir = NULL;
  51. char g_szMigrateInf[MAX_PATH];
  52. char g_szPrivateInf[MAX_PATH];
  53. LONG
  54. CALLBACK
  55. QueryVersion( OUT LPCSTR *ProductID,
  56. OUT LPUINT DllVersion,
  57. OUT LPINT *CodePageArray, OPTIONAL
  58. OUT LPCSTR *ExeNameBuf, OPTIONAL
  59. OUT PVENDORINFO *VendorInfo
  60. )
  61. {
  62. // NOTE: There is timing restriction on the return from this function
  63. // So keep this as short and sweet as possible.
  64. VENDORINFO myVendorInfo;
  65. LONG lRet = ERROR_SUCCESS;
  66. AppendString(&g_lpNameBuf, &g_dwNameBufSize, cszRATINGSFILE);
  67. AppendString(&g_lpNameBuf, &g_dwNameBufSize, cszIEXPLOREFILE);
  68. // Pass back to Setup the product name.
  69. *ProductID = g_cszProductID;
  70. // Pass back to Setup the version number of this DLL.
  71. *DllVersion = g_uVersion;
  72. // We will use English messages only but don't specify a code page or
  73. // the migration dll won't run on alternate code pages.
  74. *CodePageArray = NULL;
  75. // Pass back to Setup the list of files we want detected on this system.
  76. *ExeNameBuf = g_lpNameBuf;
  77. // Pass back the VendorInfo.
  78. if (LoadString(g_hInstance, IDS_COMPANY, myVendorInfo.CompanyName, sizeof(myVendorInfo.CompanyName)) == 0)
  79. lstrcpy(myVendorInfo.CompanyName, "Microsoft Corporation");
  80. if (LoadString(g_hInstance, IDS_SUPPORTNUMBER, myVendorInfo.SupportNumber, sizeof(myVendorInfo.SupportNumber)) == 0)
  81. lstrcpy(myVendorInfo.SupportNumber, " ");
  82. if (LoadString(g_hInstance, IDS_SUPPORTURL, myVendorInfo.SupportUrl, sizeof(myVendorInfo.SupportUrl)) == 0)
  83. lstrcpy(myVendorInfo.SupportUrl, "http://www.microsoft.com/support");
  84. if (LoadString(g_hInstance, IDS_INSTRUCTIONS, myVendorInfo.InstructionsToUser, sizeof(myVendorInfo.InstructionsToUser)) == 0)
  85. lstrcpy(myVendorInfo.InstructionsToUser, "Please contact Microsoft Technical Support for assistance with this problem. ");
  86. *VendorInfo = &myVendorInfo;
  87. #ifdef DEBUG
  88. char szDebugMsg[MAX_PATH*3];
  89. wsprintf(szDebugMsg,"IE6:ProductID: %s \r\n", *ProductID);
  90. SetupLogError(szDebugMsg, LogSevInformation);
  91. #endif
  92. return lRet;
  93. }
  94. LONG
  95. CALLBACK
  96. Initialize9x( IN LPCSTR WorkingDir,
  97. IN LPCSTR SourceDirs,
  98. IN LPCSTR MediaDirs
  99. )
  100. {
  101. // Called by NT Setup if QUeryVersion returned SUCCESS
  102. // At this point we have been relocated to some specific location
  103. // on the local drive by the Setup process.
  104. INT len;
  105. // Keep track of our new location (ie. the Working Directory).
  106. // NT Setup will create the "MIGRATE.INF" file in this dir and use that
  107. // to exchange info with us.
  108. // Also we can use this Dir for saving our private stuff. NT Setup will
  109. // ensure this folder stays till end of NT Migration. After that it will
  110. // be cleaned.
  111. len = lstrlen(WorkingDir) + 1;
  112. g_lpWorkingDir = (char *) LocalAlloc(LPTR,sizeof(char)*len);
  113. if (!g_lpWorkingDir)
  114. {
  115. return GetLastError();
  116. }
  117. CopyMemory(g_lpWorkingDir, WorkingDir, len);
  118. len = lstrlen(MediaDirs) + 1;
  119. g_lpMediaDir = (char *) LocalAlloc(LPTR,sizeof(char)*len);
  120. if (!g_lpMediaDir)
  121. {
  122. return GetLastError();
  123. }
  124. CopyMemory(g_lpMediaDir, MediaDirs, len);
  125. // Also keep track of the NT installation files path (ie Sources Dir).
  126. // NOTE: Right now we don't need it, so skip doing it.
  127. // Generate the path names to Migrate.inf and the private files
  128. // (private.inf) that we need
  129. GenerateFilePaths();
  130. // If NT Setup has succeeded in getting path to Ratings.Pol, it implies
  131. // Ratings information exists. Enable our private marker to do the right
  132. // thing in MigrateSystemNT phase.
  133. if (GetRatingsPathFromMigInf(NULL))
  134. { // Put a marker in PRIVATE.INF so that MigrateSystemNT phase knows
  135. // that it has to munge the Rating.
  136. // Private.Inf does not exist at this point so why this check!!!
  137. // if (GetFileAttributes(g_szPrivateInf) != 0xffffffff)
  138. WritePrivateProfileString(cszIEPRIVATE, cszRATINGS, "Yes", g_szPrivateInf);
  139. // Flush the cached entries to disk.
  140. WritePrivateProfileString(NULL,NULL,NULL,g_szPrivateInf);
  141. #ifdef DEBUG
  142. SetupLogError("IE6: Created PRIVATE.INF\r\n", LogSevInformation);
  143. #endif
  144. }
  145. return ERROR_SUCCESS;
  146. }
  147. LONG
  148. CALLBACK
  149. MigrateUser9x( IN HWND ParentWnd,
  150. IN LPCSTR UnattendFile,
  151. IN HKEY UserRegKey,
  152. IN LPCSTR UserName,
  153. LPVOID Reserved
  154. )
  155. {
  156. // This function is called by NT Setup for each user.
  157. // Currently for the Ratings scenario, we don't need any PerUser action.
  158. #ifdef DEBUG
  159. SetupLogError("IE6: Skipping MigrateUser9x \r\n", LogSevInformation);
  160. #endif
  161. return ERROR_SUCCESS;
  162. }
  163. LONG
  164. CALLBACK
  165. MigrateSystem9x( IN HWND ParentWnd,
  166. IN LPCSTR AnswerFile,
  167. LPVOID Reserved
  168. )
  169. {
  170. // This function is called once by NT Setup to let us save System wide info.
  171. //
  172. // we are writing the "incompatibility report here if IE5.5 is installed and
  173. // the user does not have the full migration pack installed.
  174. //
  175. char szCab[MAX_PATH];
  176. WORD wVer[4];
  177. char szBuf[MAX_PATH];
  178. // Check if we have the full exception pack which re-installs IE5.5
  179. // NOTE: g_lpMediaDir is the location where the migration dll was installed/registered
  180. // This is the same location where the INF is.
  181. lstrcpy(szCab, g_lpMediaDir);
  182. AddPath(szCab, "ieexinst.inf");
  183. if (GetPrivateProfileString("Info", "Version", "", szBuf , MAX_PATH, szCab) != 0)
  184. {
  185. // Convert version
  186. ConvertVersionString( szBuf, wVer, '.' );
  187. if ((wVer[0] == 5) && (wVer[1] == 50))
  188. {
  189. // We don't have the full exception pack.
  190. // generate the "incompatibility report"
  191. // g_szMigrateInf
  192. lstrcpy(szBuf, g_lpMediaDir);
  193. GetParentDir(szBuf);
  194. if (LoadString(g_hInstance, IDS_INCOMPAT_MSG, szCab, sizeof(szCab)))
  195. {
  196. WritePrivateProfileString(cszMIGINF_INCOMPAT_MSG, g_cszProductID, szCab, g_szMigrateInf);
  197. WritePrivateProfileString(g_cszProductID, szBuf, "Report", g_szMigrateInf);
  198. WritePrivateProfileString(NULL,NULL,NULL,g_szMigrateInf);
  199. }
  200. }
  201. }
  202. WritePrivateProfileString(cszMIGINF_HANDLED, "HKLM\\Software\\Microsoft\\Active Setup\\ClsidFeature", "Registry", g_szMigrateInf);
  203. WritePrivateProfileString(cszMIGINF_HANDLED, "HKLM\\Software\\Microsoft\\Active Setup\\FeatureComponentID", "Registry", g_szMigrateInf);
  204. WritePrivateProfileString(cszMIGINF_HANDLED, "HKLM\\Software\\Microsoft\\Active Setup\\MimeFeature", "Registry", g_szMigrateInf);
  205. WritePrivateProfileString(NULL,NULL,NULL,g_szMigrateInf);
  206. #ifdef DEBUG
  207. SetupLogError("IE6: MigrateSystem9x \r\n", LogSevInformation);
  208. #endif
  209. return ERROR_SUCCESS;
  210. }
  211. LONG
  212. CALLBACK
  213. InitializeNT (
  214. IN LPCWSTR WorkingDirectory,
  215. IN LPCWSTR SourceDirectories,
  216. LPVOID Reserved
  217. )
  218. {
  219. INT Length;
  220. LPCWSTR p;
  221. //
  222. // Save our working directory and source directory. We
  223. // convert UNICODE to ANSI, and we use the system code page.
  224. //
  225. //
  226. // Compute length of source directories
  227. //
  228. p = SourceDirectories;
  229. while (*p) {
  230. p = wcschr (p, 0) + 1;
  231. }
  232. p++;
  233. Length = (p - SourceDirectories) / sizeof (WCHAR);
  234. //
  235. // Convert the directories from UNICODE to DBCS. This DLL is
  236. // compiled in ANSI.
  237. //
  238. g_lpWorkingDir = (LPSTR) LocalAlloc(LPTR, MAX_PATH);
  239. if (!g_lpWorkingDir) {
  240. return GetLastError();
  241. }
  242. WideCharToMultiByte (
  243. CP_ACP,
  244. 0,
  245. WorkingDirectory,
  246. -1,
  247. g_lpWorkingDir,
  248. MAX_PATH,
  249. NULL,
  250. NULL
  251. );
  252. // Also save the SourceDirectories that points to the Windows
  253. // NT media (i.e. e:\i386) and optional directories specified on
  254. // the WINNT32 command line. Not used currently, so skip.
  255. // Now generate the derived file names
  256. GenerateFilePaths();
  257. #ifdef DEBUG
  258. SetupLogError("IE6: Done InitializeNT \r\n", LogSevInformation);
  259. #endif
  260. return ERROR_SUCCESS;
  261. }
  262. LONG
  263. CALLBACK
  264. MigrateUserNT (
  265. IN HINF UnattendInfHandle,
  266. IN HKEY UserRegKey,
  267. IN LPCWSTR UserName,
  268. LPVOID Reserved
  269. )
  270. {
  271. // No per-user settings for Ratings upgrade.
  272. #ifdef DEBUG
  273. SetupLogError("IE6: Skipping MigrateUserNT \r\n", LogSevInformation);
  274. #endif
  275. return ERROR_SUCCESS;
  276. }
  277. #define PACKAGE_GUID "{89820200-ECBD-11cf-8B85-00AA005B4383}"
  278. #define PACKAGE_DIRECTORY "%windir%\\RegisteredPackages\\"
  279. LONG
  280. CALLBACK
  281. MigrateSystemNT (
  282. IN HINF UnattendInfHandle,
  283. LPVOID Reserved
  284. )
  285. { // NOTE: This phase MUST finish in 60 seconds or will be terminated.
  286. // Check if our PRIVATE.INF exists and perform relevant actions based on its contents.
  287. CHAR szBuffer[3+10];
  288. if (GetFileAttributes(g_szPrivateInf) != 0xffffffff)
  289. {
  290. GetPrivateProfileString(cszIEPRIVATE, cszRATINGS, "", szBuffer, sizeof(szBuffer), g_szPrivateInf);
  291. if (lstrcmpi(szBuffer,"Yes")==0)
  292. {
  293. UpgradeRatings();
  294. SetupLogError("IE Migration: Upgraded Ratings info.\r\n", LogSevInformation);
  295. }
  296. }
  297. else
  298. {
  299. SetupLogError("IE Migration: No Rating migration. Private.Inf does not exist.\r\n",LogSevInformation);
  300. }
  301. #if 0
  302. // Do the W2K IE5.5 migration work here.
  303. // 1. Copy all files from the IE location to the registered migration pack location
  304. // 2. Register the migration pack
  305. SETUP_OS_COMPONENT_DATA ComponentData,cd;
  306. SETUP_OS_EXCEPTION_DATA ExceptionData,ed;
  307. GUID MyGuid;
  308. PWSTR GuidString;
  309. PSTR t;
  310. BOOL bContinue = FALSE;
  311. WCHAR szMsg[1024];
  312. char szPath[MAX_PATH];
  313. LPWSTR pszwPath;
  314. WORD wVer[4];
  315. char szBuf[MAX_PATH];
  316. char szInf[MAX_PATH];
  317. char szGUID[MAX_PATH];
  318. char szCab[MAX_PATH];
  319. char szDir[MAX_PATH];
  320. #ifdef DEBUG
  321. char sz[1024];
  322. #endif
  323. HRESULT hr;
  324. char szCabs[1024];
  325. LPSTR pCab = NULL;
  326. // Get the INF which is installed in the W2K folder.
  327. // This INF tells us the info about the IE exception pack.
  328. // g_lpWorkingDir contains all fiels and sub folders which are in the same place
  329. // as the registerd migration dll. Since we install the files in the same folder, we can use it.
  330. lstrcpy(szInf, g_lpWorkingDir);
  331. AddPath(szInf, "ieexinst.inf");
  332. #ifdef DEBUG
  333. wsprintf(sz, "IE exception INF :%s:\r\n", szInf);
  334. SetupLogError(sz,LogSevInformation);
  335. #endif
  336. if (GetFileAttributes(szInf) != (DWORD)-1)
  337. {
  338. // Get the GUID
  339. if (GetPrivateProfileString("Info", "ComponentId", "", szGUID, sizeof(szGUID), szInf) == 0)
  340. lstrcpy(szGUID, PACKAGE_GUID);
  341. ExpandEnvironmentStrings( PACKAGE_DIRECTORY, szDir, sizeof(szDir));
  342. if (GetFileAttributes(szDir) == (DWORD)-1)
  343. CreateDirectory( szDir, NULL );
  344. AddPath(szDir, szGUID);
  345. if (GetFileAttributes(szDir) == (DWORD)-1)
  346. CreateDirectory( szDir, NULL );
  347. // BUGBUG:
  348. // The extraction of the CAB file(s) should be done after we found out
  349. // If the user has already a newer exception pack registered.
  350. // This check is done below. Could not change it anymore, because of
  351. // time constrains. Found this in the code review
  352. //
  353. // Extract all CABs into the package fodler.
  354. #ifdef DEBUG
  355. wsprintf(sz, "cab folder :%s:\r\n", g_lpWorkingDir);
  356. SetupLogError(sz,LogSevInformation);
  357. wsprintf(sz, "extract folder :%s:\r\n", szDir);
  358. SetupLogError(sz,LogSevInformation);
  359. #endif
  360. if (GetPrivateProfileSection("Cab.List", szCabs, sizeof(szCabs), szInf) != 0)
  361. {
  362. pCab = szCabs;
  363. while (*pCab != '\0')
  364. {
  365. lstrcpy(szCab, g_lpWorkingDir);
  366. AddPath(szCab, pCab);
  367. #ifdef DEBUG
  368. wsprintf(sz, "Extract :%s: to :%s:\r\n", szCab, szDir);
  369. SetupLogError(sz,LogSevInformation);
  370. #endif
  371. hr = ExtractFiles(szCab, szDir, 0, NULL, NULL, 0);
  372. pCab += (lstrlen(pCab) + 1);
  373. }
  374. bContinue = TRUE;
  375. }
  376. }
  377. if (bContinue)
  378. {
  379. if (GetPrivateProfileString("Info", "Version", "", szBuf , MAX_PATH, szInf) != 0)
  380. {
  381. // Convert version
  382. ConvertVersionString( szBuf, wVer, '.' );
  383. ComponentData.SizeOfStruct = sizeof(SETUP_OS_COMPONENT_DATA);
  384. ExceptionData.SizeOfStruct = sizeof(SETUP_OS_EXCEPTION_DATA);
  385. pszwPath = MakeWideStrFromAnsi(szGUID);
  386. if (pszwPath)
  387. {
  388. IIDFromString( pszwPath, &MyGuid);
  389. CoTaskMemFree(pszwPath);
  390. if (SetupQueryRegisteredOsComponent(
  391. &MyGuid,
  392. &ComponentData,
  393. &ExceptionData))
  394. {
  395. if ((ComponentData.VersionMajor < wVer[0]) ||
  396. ((ComponentData.VersionMajor == wVer[0]) && (ComponentData.VersionMinor <= wVer[1])) )
  397. {
  398. bContinue = SetupUnRegisterOsComponent(&MyGuid);
  399. SetupLogError("IE6: SetupUnRegisterOsComponent.\r\n",LogSevInformation);
  400. }
  401. // BUGBUG: Missing the below else. Found in code review
  402. // else
  403. // bContinue = FALSE;
  404. }
  405. }
  406. else
  407. bContinue = FALSE;
  408. }
  409. else
  410. bContinue = FALSE;
  411. }
  412. if (bContinue)
  413. {
  414. SetupLogError("IE6: Preparing SetupRegisterOsComponent.\r\n",LogSevInformation);
  415. ExpandEnvironmentStrings( PACKAGE_DIRECTORY, szPath, sizeof(szPath));
  416. AddPath( szPath, szGUID );
  417. ComponentData.VersionMajor = wVer[0];
  418. ComponentData.VersionMinor = wVer[1];
  419. RtlMoveMemory(&ComponentData.ComponentGuid, &MyGuid,sizeof(GUID));
  420. t = szPath + lstrlen(szPath);
  421. *t = '\0';
  422. GetPrivateProfileString("Info", "InfFile", "", szBuf, MAX_PATH, szInf);
  423. AddPath( szPath, szBuf);
  424. pszwPath = MakeWideStrFromAnsi(szPath);
  425. if (pszwPath)
  426. {
  427. wcscpy(ExceptionData.ExceptionInfName, pszwPath);
  428. CoTaskMemFree(pszwPath);
  429. }
  430. *t = '\0';
  431. GetPrivateProfileString("Info", "CatalogFile", "", szBuf, MAX_PATH, szInf);
  432. AddPath( szPath, szBuf);
  433. pszwPath = MakeWideStrFromAnsi(szPath);
  434. if (pszwPath)
  435. {
  436. wcscpy(ExceptionData.CatalogFileName, pszwPath);
  437. CoTaskMemFree(pszwPath);
  438. }
  439. LoadString(g_hInstance, IDS_FRIENDLYNAME, szPath, sizeof(szPath));
  440. pszwPath = MakeWideStrFromAnsi(szPath);
  441. if (pszwPath)
  442. {
  443. wcscpy(ComponentData.FriendlyName, pszwPath);
  444. CoTaskMemFree(pszwPath);
  445. }
  446. wsprintfW(szMsg, L"IE6: ExceptionData\r\n\tInf: %ws\r\n\tCatalog: %ws\r\n",
  447. ExceptionData.ExceptionInfName,ExceptionData.CatalogFileName);
  448. SetupLogErrorW(szMsg,LogSevInformation);
  449. if (SetupRegisterOsComponent(&ComponentData, &ExceptionData))
  450. {
  451. SetupLogError("IE6: SetupRegisterOsComponent succeeded.\r\n",LogSevInformation);
  452. #ifdef DEBUG
  453. cd.SizeOfStruct = sizeof(SETUP_OS_COMPONENT_DATA);
  454. ed.SizeOfStruct = sizeof(SETUP_OS_EXCEPTION_DATA);
  455. if (SetupQueryRegisteredOsComponent( &MyGuid, &cd, &ed))
  456. {
  457. StringFromIID(cd.ComponentGuid, &GuidString);
  458. wsprintfW(szMsg, L"IE6: Component Data\r\n\tName: %ws\r\n\tGuid: %ws\r\n\tVersionMajor: %d\r\n\tVersionMinor: %d\r\n",
  459. cd.FriendlyName,GuidString,cd.VersionMajor,cd.VersionMinor);
  460. SetupLogErrorW(szMsg,LogSevInformation);
  461. wsprintfW(szMsg, L"IE6: ExceptionData\r\n\tInf: %ws\r\n\tCatalog: %ws\r\n",
  462. ed.ExceptionInfName,ed.CatalogFileName);
  463. SetupLogErrorW(szMsg,LogSevInformation);
  464. CoTaskMemFree( GuidString );
  465. }
  466. #endif
  467. }
  468. }
  469. // In future, check for other settings here and perform necessary upgrade actions.
  470. #endif
  471. #ifdef DEBUG
  472. SetupLogError("IE6: Done MigrateSystemNT \r\n", LogSevInformation);
  473. #endif
  474. return ERROR_SUCCESS;
  475. }