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.

1310 lines
46 KiB

  1. #include "migeng.h"
  2. #include "migutil.h"
  3. #include "miginf.h"
  4. extern "C" {
  5. #include "log.h"
  6. }
  7. // Globals
  8. HINF g_GlobalScriptHandle = INVALID_HANDLE_VALUE;
  9. TCHAR g_HTMLLog[MAX_PATH] = TEXT("");
  10. TCHAR g_HTMLAppList[MAX_PATH] = TEXT("");
  11. extern MigrationWizard* g_migwiz;
  12. HRESULT _Engine_UploadVars (MIG_PLATFORMTYPEID idPlatform)
  13. {
  14. HRESULT hr = S_OK;
  15. PCTSTR envVars = NULL;
  16. PCTSTR envString;
  17. PTSTR envStringCopy;
  18. PTSTR p;
  19. envVars = (PCTSTR) GetEnvironmentStrings();
  20. if (envVars) {
  21. envString = envVars;
  22. while (*envString)
  23. {
  24. p = _tcschr (envString, 0);
  25. if (p)
  26. {
  27. envStringCopy = (PTSTR) IsmGetMemory (((UINT)(p - envString + 1)) * sizeof (TCHAR));
  28. _tcscpy (envStringCopy, envString);
  29. p = _tcschr (envStringCopy, TEXT('='));
  30. //
  31. // Get rid of empty environment strings or the dummy env string starting
  32. // with '='
  33. //
  34. if (p && p != envStringCopy)
  35. {
  36. *p = 0;
  37. p = _tcsinc (p);
  38. if (p) {
  39. IsmSetEnvironmentString (idPlatform, S_SYSENVVAR_GROUP, envStringCopy, p);
  40. }
  41. }
  42. IsmReleaseMemory (envStringCopy);
  43. }
  44. envString = _tcschr (envString, 0);
  45. envString ++;
  46. }
  47. }
  48. return hr;
  49. }
  50. BOOL
  51. pGetCurrentUser (
  52. OUT PCTSTR *UserName,
  53. OUT PCTSTR *UserDomain
  54. )
  55. {
  56. HANDLE token;
  57. PTOKEN_USER tokenUser = NULL;
  58. SID_NAME_USE dontCare;
  59. DWORD bytesRequired;
  60. TCHAR userName[256];
  61. DWORD nameSize;
  62. TCHAR userDomain[256];
  63. DWORD domainSize;
  64. //
  65. // Open the process token.
  66. //
  67. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token)) {
  68. return FALSE;
  69. }
  70. bytesRequired = 0;
  71. if (GetTokenInformation (token, TokenUser, NULL, 0, &bytesRequired)) {
  72. return FALSE;
  73. }
  74. if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) {
  75. return FALSE;
  76. }
  77. tokenUser = (PTOKEN_USER) IsmGetMemory (bytesRequired);
  78. if (!GetTokenInformation (token, TokenUser, tokenUser, bytesRequired, &bytesRequired)) {
  79. IsmReleaseMemory (tokenUser);
  80. return FALSE;
  81. }
  82. nameSize = ARRAYSIZE (userName);
  83. domainSize = ARRAYSIZE (userDomain);
  84. ZeroMemory (userName, nameSize);
  85. ZeroMemory (userDomain, domainSize);
  86. LookupAccountSid (
  87. NULL,
  88. tokenUser->User.Sid,
  89. userName,
  90. &nameSize,
  91. userDomain,
  92. &domainSize,
  93. &dontCare
  94. );
  95. if (UserName) {
  96. *UserName = IsmDuplicateString (userName);
  97. }
  98. if (UserDomain) {
  99. *UserDomain = IsmDuplicateString (userDomain);
  100. }
  101. if (tokenUser) {
  102. IsmReleaseMemory (tokenUser);
  103. tokenUser = NULL;
  104. }
  105. return TRUE;
  106. }
  107. BOOL
  108. pIsUserAdmin (
  109. VOID
  110. )
  111. /*++
  112. Routine Description:
  113. This routine returns TRUE if the caller's process is a member of the
  114. Administrators local group.
  115. Caller is NOT expected to be impersonating anyone and IS expected to be
  116. able to open their own process and process token.
  117. Arguments:
  118. None.
  119. Return Value:
  120. TRUE - Caller has Administrators local group.
  121. FALSE - Caller does not have Administrators local group.
  122. --*/
  123. {
  124. HANDLE token;
  125. DWORD bytesRequired;
  126. PTOKEN_GROUPS groups;
  127. BOOL b;
  128. DWORD i;
  129. SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
  130. PSID administratorsGroup;
  131. //
  132. // Open the process token.
  133. //
  134. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token)) {
  135. return FALSE;
  136. }
  137. b = FALSE;
  138. groups = NULL;
  139. //
  140. // Get group information.
  141. //
  142. if (!GetTokenInformation (token, TokenGroups, NULL, 0, &bytesRequired) &&
  143. GetLastError() == ERROR_INSUFFICIENT_BUFFER
  144. ) {
  145. groups = (PTOKEN_GROUPS) HeapAlloc (GetProcessHeap (), 0, bytesRequired);
  146. b = GetTokenInformation (token, TokenGroups, groups, bytesRequired, &bytesRequired);
  147. }
  148. if (b) {
  149. b = AllocateAndInitializeSid (
  150. &ntAuthority,
  151. 2,
  152. SECURITY_BUILTIN_DOMAIN_RID,
  153. DOMAIN_ALIAS_RID_ADMINS,
  154. 0, 0, 0, 0, 0, 0,
  155. &administratorsGroup
  156. );
  157. if (b) {
  158. //
  159. // See if the user has the administrator group.
  160. //
  161. b = FALSE;
  162. for (i = 0 ; i < groups->GroupCount ; i++) {
  163. if (EqualSid (groups->Groups[i].Sid, administratorsGroup)) {
  164. b = TRUE;
  165. break;
  166. }
  167. }
  168. FreeSid (administratorsGroup);
  169. }
  170. }
  171. //
  172. // Clean up and return.
  173. //
  174. if (groups) {
  175. HeapFree (GetProcessHeap (), 0, groups);
  176. }
  177. CloseHandle (token);
  178. return b;
  179. }
  180. typedef BOOL (WINAPI GETDISKFREESPACEEX)(
  181. LPCTSTR lpDirectoryName,
  182. PULARGE_INTEGER lpFreeBytesAvailable,
  183. PULARGE_INTEGER lpTotalNumberOfBytes,
  184. PULARGE_INTEGER lpTotalNumberOfFreeBytes
  185. );
  186. typedef GETDISKFREESPACEEX *PGETDISKFREESPACEEX;
  187. BOOL
  188. pMightHaveDiskSpaceProblem (
  189. VOID
  190. )
  191. {
  192. TCHAR tempStorage[MAX_PATH];
  193. PTSTR tempPtr = NULL;
  194. ULARGE_INTEGER thisMediaMaxSize;
  195. ULARGE_INTEGER dummy1, dummy2;
  196. PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
  197. DWORD sectPerClust;
  198. DWORD bytesPerSect;
  199. DWORD freeClusters;
  200. DWORD totalClusters;
  201. if (IsmGetTempStorage (tempStorage, ARRAYSIZE(tempStorage))) {
  202. if (tempStorage [0] == TEXT('\\')) {
  203. // this is a UNC path
  204. _tcscat (tempStorage, TEXT("\\"));
  205. tempPtr = _tcschr (tempStorage, TEXT('\\'));
  206. if (tempPtr) {
  207. tempPtr = _tcschr (tempStorage, TEXT('\\'));
  208. if (tempPtr) {
  209. tempPtr = _tcschr (tempStorage, TEXT('\\'));
  210. if (tempPtr) {
  211. tempPtr = _tcschr (tempStorage, TEXT('\\'));
  212. if (tempPtr) {
  213. tempPtr ++;
  214. *tempPtr = 0;
  215. }
  216. }
  217. }
  218. }
  219. } else {
  220. // this is a normal path
  221. tempPtr = _tcschr (tempStorage, TEXT('\\'));
  222. if (tempPtr) {
  223. tempPtr ++;
  224. *tempPtr = 0;
  225. }
  226. }
  227. // Find out if GetDiskFreeSpaceEx is supported
  228. #ifdef UNICODE
  229. pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( GetModuleHandle (TEXT("kernel32.dll")), "GetDiskFreeSpaceExW");
  230. #else
  231. pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress( GetModuleHandle (TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
  232. #endif
  233. if (pGetDiskFreeSpaceEx) {
  234. if (!pGetDiskFreeSpaceEx (tempStorage, &dummy1, &dummy2, &thisMediaMaxSize)) {
  235. return FALSE;
  236. }
  237. } else {
  238. if (GetDiskFreeSpace (tempStorage, &sectPerClust, &bytesPerSect, &freeClusters, &totalClusters)) {
  239. thisMediaMaxSize.QuadPart = Int32x32To64 ((sectPerClust * bytesPerSect), freeClusters);
  240. } else {
  241. DWORD err = GetLastError ();
  242. return FALSE;
  243. }
  244. }
  245. if ((thisMediaMaxSize.HighPart == 0) &&
  246. (thisMediaMaxSize.LowPart < 1024 * 1024)
  247. ) {
  248. return TRUE;
  249. }
  250. }
  251. return FALSE;
  252. }
  253. BOOL
  254. pAddExtensions (
  255. VOID
  256. )
  257. {
  258. HKEY rootKey = NULL;
  259. LONG result;
  260. // open the root key
  261. result = RegOpenKeyEx (HKEY_CLASSES_ROOT, TEXT(""), 0, KEY_READ, &rootKey);
  262. if (result == ERROR_SUCCESS) {
  263. UINT index = 0;
  264. TCHAR extName [MAX_PATH + 1];
  265. // enumerate all subkeys
  266. while (result == ERROR_SUCCESS) {
  267. result = RegEnumKey (rootKey, index, extName, MAX_PATH + 1);
  268. if (result == ERROR_SUCCESS) {
  269. // see if this is an extension
  270. if (_tcsnextc (extName) == TEXT('.')) {
  271. HKEY subKey = NULL;
  272. PCTSTR extNamePtr = NULL;
  273. extNamePtr = _tcsinc (extName);
  274. if (extNamePtr) {
  275. BOOL foundExtension = FALSE;
  276. INFCONTEXT context;
  277. if (SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.Include"), extNamePtr, &context)) {
  278. foundExtension = TRUE;
  279. } else if (SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.Exclude"), extNamePtr, &context)) {
  280. foundExtension = FALSE;
  281. } else {
  282. // open it
  283. result = RegOpenKeyEx (rootKey, extName, 0, KEY_READ, &subKey);
  284. if (result == ERROR_SUCCESS) {
  285. TCHAR progIdName [MAX_PATH + 1];
  286. DWORD regType;
  287. DWORD size = (MAX_PATH + 1) * sizeof (TCHAR);
  288. // let's find the ProgId (query the default value)
  289. result = RegQueryValueEx (subKey, NULL, NULL, &regType, (PBYTE)progIdName, &size);
  290. if ((result == ERROR_SUCCESS) && (regType == REG_SZ)) {
  291. HKEY progIdKey = NULL;
  292. // let's open the prog ID key
  293. result = RegOpenKeyEx (rootKey, progIdName, 0, KEY_READ, &progIdKey);
  294. if (result == ERROR_SUCCESS) {
  295. HKEY shellKey = NULL;
  296. // open the shell subkey
  297. result = RegOpenKeyEx (progIdKey, TEXT("shell"), 0, KEY_READ, &shellKey);
  298. if (result == ERROR_SUCCESS) {
  299. UINT shellIdx = 0;
  300. TCHAR cmdName [MAX_PATH + 1];
  301. // enumerate all subkeys
  302. while (result == ERROR_SUCCESS) {
  303. result = RegEnumKey (shellKey, shellIdx, cmdName, MAX_PATH + 1);
  304. if (result == ERROR_SUCCESS) {
  305. if ((_tcsicmp (cmdName, TEXT("open")) == 0) ||
  306. (_tcsicmp (cmdName, TEXT("play")) == 0)
  307. ) {
  308. HKEY cmdKey = NULL;
  309. // open it
  310. result = RegOpenKeyEx (shellKey, cmdName, 0, KEY_READ, &cmdKey);
  311. if (result == ERROR_SUCCESS) {
  312. HKEY actionKey = NULL;
  313. // open the "command" subkey
  314. result = RegOpenKeyEx (cmdKey, TEXT("command"), 0, KEY_READ, &actionKey);
  315. if (result == ERROR_SUCCESS) {
  316. TCHAR commandLine [MAX_PATH + 1];
  317. DWORD size = (MAX_PATH + 1) * sizeof (TCHAR);
  318. // let's find the actual command line (query the default value)
  319. result = RegQueryValueEx (actionKey, NULL, NULL, &regType, (PBYTE)commandLine, &size);
  320. if ((result == ERROR_SUCCESS) && ((regType == REG_SZ) || (regType == REG_EXPAND_SZ))) {
  321. TCHAR exePath [MAX_PATH + 1];
  322. PTSTR exeStart = NULL;
  323. PTSTR exeStop = NULL;
  324. PTSTR exePtr = NULL;
  325. INFCONTEXT context;
  326. BOOL doubleCheck = FALSE;
  327. // now we have the command line. Let's see if the module that handle this command
  328. // is in our IGNORE list
  329. if (_tcsnextc (commandLine) == TEXT('\"')) {
  330. exeStart = _tcsinc (commandLine);
  331. if (exeStart) {
  332. exeStop = _tcschr (exeStart, TEXT('\"'));
  333. }
  334. } else {
  335. doubleCheck = TRUE;
  336. exeStart = commandLine;
  337. exeStop = _tcschr (exeStart, TEXT(' '));
  338. if (!exeStop) {
  339. exeStop = _tcschr (exeStart, 0);
  340. }
  341. }
  342. if (exeStart && exeStop) {
  343. CopyMemory (exePath, exeStart, (exeStop - exeStart) * sizeof (TCHAR));
  344. exePath [exeStop - exeStart] = 0;
  345. exePtr = _tcsrchr (exePath, TEXT('\\'));
  346. if (exePtr) {
  347. exePtr = _tcsinc (exePtr);
  348. }
  349. if (exePtr && !SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.IgnoreEXE"), exePtr, &context)) {
  350. foundExtension = TRUE;
  351. }
  352. }
  353. if (foundExtension && doubleCheck) {
  354. exeStop = NULL;
  355. exeStart = _tcsrchr (commandLine, TEXT('\\'));
  356. if (exeStart) {
  357. exeStart = _tcsinc (exeStart);
  358. if (exeStart) {
  359. exeStop = _tcschr (exeStart, TEXT(' '));
  360. if (!exeStop) {
  361. exeStop = _tcschr (exeStart, 0);
  362. }
  363. }
  364. }
  365. if (exeStart && exeStop) {
  366. CopyMemory (exePath, exeStart, (exeStop - exeStart) * sizeof (TCHAR));
  367. exePath [exeStop - exeStart] = 0;
  368. exePtr = _tcsrchr (exePath, TEXT('\\'));
  369. if (exePtr) {
  370. exePtr = _tcsinc (exePtr);
  371. } else {
  372. exePtr = exePath;
  373. }
  374. if (exePtr && SetupFindFirstLine (g_hMigWizInf, TEXT("EXT.IgnoreEXE"), exePtr, &context)) {
  375. foundExtension = FALSE;
  376. }
  377. }
  378. }
  379. }
  380. RegCloseKey (actionKey);
  381. }
  382. RegCloseKey (cmdKey);
  383. }
  384. }
  385. result = ERROR_SUCCESS;
  386. }
  387. shellIdx ++;
  388. }
  389. RegCloseKey (shellKey);
  390. }
  391. RegCloseKey (progIdKey);
  392. }
  393. }
  394. RegCloseKey (subKey);
  395. }
  396. }
  397. if (foundExtension) {
  398. //
  399. // Add the component to the engine, unless it already exists
  400. //
  401. // Check if it is already in the tree
  402. if (!IsmIsComponentSelected (extName + 1, COMPONENT_EXTENSION)) {
  403. // Not in the tree; select it if it exists as a component
  404. if (!IsmSelectComponent (extName + 1, COMPONENT_EXTENSION, TRUE)) {
  405. // Not a component; add the component
  406. IsmAddComponentAlias (
  407. NULL,
  408. MASTERGROUP_FILES_AND_FOLDERS,
  409. extName + 1,
  410. COMPONENT_EXTENSION,
  411. FALSE
  412. );
  413. }
  414. }
  415. }
  416. }
  417. }
  418. result = ERROR_SUCCESS;
  419. }
  420. index ++;
  421. }
  422. RegCloseKey (rootKey);
  423. }
  424. return TRUE;
  425. }
  426. HRESULT Engine_Initialize (PCTSTR ptszInfPath,
  427. BOOL fSource,
  428. BOOL fNetworkSupport,
  429. LPTSTR pszUsername,
  430. PMESSAGECALLBACK pMessageCallback,
  431. PBOOL pfNetworkDetected)
  432. {
  433. static HRESULT hr = E_FAIL;
  434. static BOOL fDidThis = FALSE;
  435. ERRUSER_EXTRADATA errExtraData;
  436. PTSTR iconLibRoot = NULL;
  437. TCHAR iconLibSrc[MAX_PATH] = TEXT("");
  438. TCHAR iconLibDest[MAX_PATH] = TEXT("");
  439. HANDLE iconLibHandle = INVALID_HANDLE_VALUE;
  440. BOOL iconLibFound = FALSE;
  441. DWORD err;
  442. PCTSTR userName = NULL;
  443. PCTSTR userDomain = NULL;
  444. PCTSTR currUserName = NULL;
  445. PCTSTR currUserDomain = NULL;
  446. ROLLBACK_USER_ERROR rollbackError;
  447. if (fDidThis) {
  448. return hr;
  449. }
  450. __try
  451. {
  452. TCHAR szLogPath[MAX_PATH];
  453. TCHAR szFullLogFile[MAX_PATH];
  454. DWORD dwLength;
  455. HRESULT hResult;
  456. PTSTR pszAppData;
  457. fDidThis = TRUE;
  458. LogDeleteOnNextInit();
  459. pszAppData = GetShellFolderPath (CSIDL_LOCAL_APPDATA, TEXT("LocalAppData"), FALSE, NULL);
  460. if (pszAppData) {
  461. wsprintf (szFullLogFile, TEXT("%s\\FASTWiz.log"), pszAppData);
  462. LogReInit (NULL, NULL, szFullLogFile, NULL );
  463. wsprintf (g_HTMLLog, TEXT("%s\\FASTWiz.html"), pszAppData);
  464. wsprintf (g_HTMLAppList, TEXT("%s\\FASTApp.html"), pszAppData);
  465. LocalFree (pszAppData);
  466. } else {
  467. dwLength = GetEnvironmentVariable (TEXT("USERPROFILE"), szLogPath, ARRAYSIZE(szLogPath));
  468. if (dwLength > 0 && dwLength < (MAX_PATH - 13) )
  469. {
  470. wsprintf (szFullLogFile, TEXT("%s\\FASTWiz.log"), szLogPath);
  471. LogReInit (NULL, NULL, szFullLogFile, NULL );
  472. wsprintf (g_HTMLLog, TEXT("%s\\FASTWiz.html"), szLogPath);
  473. wsprintf (g_HTMLAppList, TEXT("%s\\FASTApp.html"), szLogPath);
  474. }
  475. else if (g_migwiz->GetWin9X() && GetWindowsDirectory(szLogPath, ARRAYSIZE(szLogPath)))
  476. {
  477. wsprintf (szFullLogFile, TEXT("%s\\FASTWiz.log"), szLogPath);
  478. LogReInit (NULL, NULL, szFullLogFile, NULL);
  479. wsprintf (g_HTMLLog, TEXT("%s\\FASTWiz.html"), szLogPath);
  480. wsprintf (g_HTMLAppList, TEXT("%s\\FASTApp.html"), szLogPath);
  481. }
  482. else
  483. {
  484. LogReInit (NULL, NULL, TEXT("FASTWiz.log"), NULL);
  485. if (GetCurrentDirectory(ARRAYSIZE(g_HTMLLog), g_HTMLLog))
  486. {
  487. PathAppend(g_HTMLLog, TEXT("FASTWiz.html"));
  488. PathAppend(g_HTMLAppList, TEXT("FASTApp.html"));
  489. }
  490. else
  491. {
  492. _tcscpy (g_HTMLLog, TEXT("FASTWiz.html"));
  493. _tcscpy (g_HTMLAppList, TEXT("FASTApp.html"));
  494. }
  495. }
  496. }
  497. #ifndef DEBUG
  498. SuppressAllLogPopups (TRUE);
  499. #endif
  500. if (!IsmInitialize (ptszInfPath, pMessageCallback, NULL))
  501. {
  502. __leave;
  503. }
  504. hr = _Engine_UploadVars (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION);
  505. if (!SUCCEEDED(hr))
  506. {
  507. __leave;
  508. }
  509. hr = E_FAIL;
  510. if (!IsmSetPlatform (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION))
  511. {
  512. __leave;
  513. }
  514. if (!fSource)
  515. {
  516. // we will try to copy iconlib.dll from our directory into "Common AppData" directory
  517. // If we don't succeed, we will try to copy it to "Local AppData". If this one does
  518. // not succeed we will not set the S_ENV_ICONLIB env variable
  519. iconLibSrc [0] = 0;
  520. GetSystemDirectory (iconLibSrc, ARRAYSIZE(iconLibSrc));
  521. _tcscat (iconLibSrc, TEXT("\\usmt\\iconlib.dll"));
  522. iconLibFound = FALSE;
  523. iconLibRoot = GetShellFolderPath (CSIDL_COMMON_APPDATA, TEXT("AppData"), FALSE, NULL);
  524. if (iconLibRoot) {
  525. __try {
  526. _tcscpy (iconLibDest, iconLibRoot);
  527. _tcscat (iconLibDest, TEXT("\\Microsoft"));
  528. if (!CreateDirectory (iconLibDest, NULL)) {
  529. err = GetLastError ();
  530. if (err != ERROR_ALREADY_EXISTS) {
  531. __leave;
  532. }
  533. }
  534. _tcscat (iconLibDest, TEXT("\\USMT"));
  535. if (!CreateDirectory (iconLibDest, NULL)) {
  536. err = GetLastError ();
  537. if (err != ERROR_ALREADY_EXISTS) {
  538. __leave;
  539. }
  540. }
  541. _tcscat (iconLibDest, TEXT("\\iconlib.dll"));
  542. if (!CopyFile (iconLibSrc, iconLibDest, TRUE)) {
  543. err = GetLastError ();
  544. if (err != ERROR_FILE_EXISTS) {
  545. __leave;
  546. }
  547. // we found an iconlib.dll there. The only question now is: can we access it?
  548. // Let's try to open the file with write mode.
  549. iconLibHandle = CreateFile (
  550. iconLibDest,
  551. GENERIC_READ|GENERIC_WRITE,
  552. FILE_SHARE_READ|FILE_SHARE_WRITE,
  553. NULL,
  554. OPEN_EXISTING,
  555. FILE_ATTRIBUTE_NORMAL,
  556. NULL
  557. );
  558. if (iconLibHandle == INVALID_HANDLE_VALUE) {
  559. // something is wrong, we can't access this file
  560. err = GetLastError ();
  561. __leave;
  562. }
  563. CloseHandle (iconLibHandle);
  564. }
  565. iconLibFound = TRUE;
  566. }
  567. __finally {
  568. LocalFree (iconLibRoot);
  569. iconLibRoot = NULL;
  570. }
  571. }
  572. if (!iconLibFound) {
  573. iconLibRoot = GetShellFolderPath (CSIDL_LOCAL_APPDATA, TEXT("Local AppData"), TRUE, NULL);
  574. if (iconLibRoot) {
  575. __try {
  576. _tcscpy (iconLibDest, iconLibRoot);
  577. _tcscat (iconLibDest, TEXT("\\Microsoft"));
  578. if (!CreateDirectory (iconLibDest, NULL)) {
  579. err = GetLastError ();
  580. if (err != ERROR_ALREADY_EXISTS) {
  581. __leave;
  582. }
  583. }
  584. _tcscat (iconLibDest, TEXT("\\USMT"));
  585. if (!CreateDirectory (iconLibDest, NULL)) {
  586. err = GetLastError ();
  587. if (err != ERROR_ALREADY_EXISTS) {
  588. __leave;
  589. }
  590. }
  591. _tcscat (iconLibDest, TEXT("\\iconlib.dll"));
  592. if (!CopyFile (iconLibSrc, iconLibDest, TRUE)) {
  593. err = GetLastError ();
  594. if (err != ERROR_FILE_EXISTS) {
  595. __leave;
  596. }
  597. }
  598. iconLibFound = TRUE;
  599. }
  600. __finally {
  601. LocalFree (iconLibRoot);
  602. iconLibRoot = NULL;
  603. }
  604. }
  605. }
  606. // Set the icon lib data
  607. if (iconLibFound) {
  608. IsmSetEnvironmentString (PLATFORM_DESTINATION, NULL, S_ENV_ICONLIB, iconLibDest);
  609. }
  610. }
  611. //
  612. // Enable HKR migration
  613. //
  614. IsmSetEnvironmentFlag (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_ENV_HKCU_ON);
  615. //
  616. // Enable files migration
  617. //
  618. IsmSetEnvironmentFlag (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_ENV_ALL_FILES);
  619. //
  620. // Start ETM modules
  621. //
  622. if (!IsmStartEtmModules ()) {
  623. __leave;
  624. }
  625. // Set up the username
  626. if (pszUsername)
  627. {
  628. IsmSetEnvironmentString (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, TRANSPORT_ENVVAR_HOMENET_TAG, pszUsername);
  629. }
  630. //
  631. // Start the transport modules
  632. //
  633. if (!IsmStartTransport ()) {
  634. __leave;
  635. }
  636. // If we're network-enabled, start appropriate network stuff
  637. if (fNetworkSupport)
  638. {
  639. // try to detect another machine on network
  640. MIG_TRANSPORTSTORAGEID transportStorageId = IsmRegisterTransport (S_HOME_NETWORK_TRANSPORT);
  641. MIG_TRANSPORTID transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, 0);
  642. if (!transportId)
  643. {
  644. // Network is not supported
  645. fNetworkSupport = FALSE;
  646. }
  647. else
  648. {
  649. BOOL fNetworkDetected = FALSE;
  650. if (!IsmSetTransportStorage (
  651. fSource ? PLATFORM_SOURCE : PLATFORM_DESTINATION,
  652. transportId,
  653. transportStorageId,
  654. CAPABILITY_AUTOMATED,
  655. NULL,
  656. NULL,
  657. pfNetworkDetected
  658. ))
  659. {
  660. // Network is not supported
  661. fNetworkSupport = FALSE;
  662. }
  663. }
  664. }
  665. hr = S_OK;
  666. if (!fSource) {
  667. // now let's take care of the rollback if necessary
  668. __try {
  669. // get the current user name and domain
  670. if ((!pGetCurrentUser (&currUserName, &currUserDomain)) ||
  671. (!currUserName) ||
  672. (!currUserDomain)
  673. ) {
  674. __leave;
  675. }
  676. if (IsmSetRollbackJournalType (TRUE)) {
  677. if (IsmDoesRollbackDataExist (&userName, &userDomain, NULL, NULL, NULL)) {
  678. if ((StrCmpI (userName, currUserName) == 0) &&
  679. (StrCmpI (userDomain, currUserDomain) == 0)
  680. ) {
  681. // disable cancel, write the UNDO message in the UI
  682. DisableCancel ();
  683. PostMessageForWizard (WM_USER_ROLLBACK, 0, 0);
  684. IsmRollback ();
  685. __leave;
  686. }
  687. if (pIsUserAdmin ()) {
  688. // disable cancel, write the UNDO message in the UI
  689. DisableCancel ();
  690. PostMessageForWizard (WM_USER_ROLLBACK, 0, 0);
  691. IsmRollback ();
  692. __leave;
  693. }
  694. // display the message, we can't run
  695. rollbackError.UserName = userName;
  696. rollbackError.UserDomain = userDomain;
  697. IsmSendMessageToApp (ISMMESSAGE_EXECUTE_ROLLBACK, (ULONG_PTR)&rollbackError);
  698. IsmPreserveJournal (TRUE);
  699. hr = E_FAIL;
  700. __leave;
  701. }
  702. }
  703. if (IsmSetRollbackJournalType (FALSE)) {
  704. if (IsmDoesRollbackDataExist (NULL, NULL, NULL, NULL, NULL)) {
  705. // disable cancel, write the UNDO message in the UI
  706. DisableCancel ();
  707. PostMessageForWizard (WM_USER_ROLLBACK, 0, 0);
  708. IsmRollback ();
  709. __leave;
  710. }
  711. }
  712. }
  713. __finally {
  714. if (currUserName) {
  715. IsmReleaseMemory (currUserName);
  716. currUserName = NULL;
  717. }
  718. if (currUserDomain) {
  719. IsmReleaseMemory (currUserDomain);
  720. currUserDomain = NULL;
  721. }
  722. if (userName) {
  723. IsmReleaseMemory (userName);
  724. userName = NULL;
  725. }
  726. if (userDomain) {
  727. IsmReleaseMemory (userDomain);
  728. userDomain = NULL;
  729. }
  730. }
  731. // finally let's find a place for the rollback journal
  732. if (SUCCEEDED(hr)) {
  733. if ((!IsmSetRollbackJournalType (TRUE)) ||
  734. (!IsmCanWriteRollbackJournal ())
  735. ) {
  736. if ((!IsmSetRollbackJournalType (FALSE)) ||
  737. (!IsmCanWriteRollbackJournal ())
  738. ) {
  739. // log a warning - we can't create a rollback journal
  740. // BUGBUG - log the warning
  741. }
  742. }
  743. }
  744. }
  745. if (SUCCEEDED(hr)) {
  746. if (fSource) {
  747. pAddExtensions ();
  748. }
  749. }
  750. }
  751. __finally
  752. {
  753. // Empty
  754. }
  755. if (FAILED(hr)) {
  756. if (pMightHaveDiskSpaceProblem ()) {
  757. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  758. } else {
  759. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  760. }
  761. errExtraData.ErrorArea = ERRUSER_AREA_INIT;
  762. errExtraData.ObjectTypeId = 0;
  763. errExtraData.ObjectName = NULL;
  764. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  765. Engine_Terminate();
  766. }
  767. return hr;
  768. }
  769. HRESULT Engine_RegisterProgressBarCallback(PROGRESSBARFN pProgressCallback, ULONG_PTR pArg)
  770. {
  771. static HRESULT hr = E_FAIL;
  772. if (FAILED(hr)) // only register once
  773. {
  774. hr = IsmRegisterProgressBarCallback(pProgressCallback, pArg) ? S_OK : E_FAIL;
  775. }
  776. return hr;
  777. }
  778. HRESULT Engine_AppendScript(BOOL fSource, PCTSTR ptszInfPath)
  779. {
  780. HRESULT hr = E_FAIL;
  781. ENVENTRY_STRUCT infHandleStruct;
  782. if (g_GlobalScriptHandle == INVALID_HANDLE_VALUE)
  783. {
  784. g_GlobalScriptHandle = SetupOpenInfFile (ptszInfPath, NULL, INF_STYLE_WIN4 | INF_STYLE_OLDNT, NULL);
  785. if (g_GlobalScriptHandle != INVALID_HANDLE_VALUE)
  786. {
  787. hr = S_OK;
  788. }
  789. }
  790. else
  791. {
  792. if (SetupOpenAppendInfFile (ptszInfPath, g_GlobalScriptHandle, NULL))
  793. {
  794. hr = S_OK;
  795. }
  796. }
  797. if (SUCCEEDED(hr))
  798. {
  799. IsmAppendEnvironmentMultiSz (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_INF_FILE_MULTISZ, ptszInfPath);
  800. infHandleStruct.Type = ENVENTRY_BINARY;
  801. infHandleStruct.EnvBinaryData = (PBYTE)(&g_GlobalScriptHandle);
  802. infHandleStruct.EnvBinaryDataSize = sizeof (HINF);
  803. IsmSetEnvironmentValue (fSource?PLATFORM_SOURCE:PLATFORM_DESTINATION, NULL, S_GLOBAL_INF_HANDLE, &infHandleStruct);
  804. }
  805. return hr;
  806. }
  807. BOOL _LocalPathIsRoot(LPTSTR pszPath)
  808. {
  809. return (PathIsRoot(pszPath) ||
  810. ((2 == lstrlen(pszPath)) &&
  811. ((pszPath[0] >= TEXT('A') && pszPath[0] <= TEXT('Z')) || (pszPath[0] >= TEXT('a') && pszPath[0] <= TEXT('z'))) &&
  812. (pszPath[1] == TEXT(':'))));
  813. }
  814. HRESULT Engine_StartTransport (BOOL fSource, LPTSTR pszPath, PBOOL ImageIsValid, PBOOL ImageExists)
  815. {
  816. ERRUSER_EXTRADATA errExtraData;
  817. HRESULT hr = E_FAIL;
  818. MIG_TRANSPORTID transportId;
  819. MIG_TRANSPORTSTORAGEID transportStorageId;
  820. LPTSTR pszStoragePath;
  821. TCHAR szRootPath[4] = TEXT("A:\\");
  822. PTSTR lpExpStore = NULL;
  823. BOOL retryTrans = TRUE;
  824. BOOL tryUncFirst = (!fSource);
  825. TCHAR szSerialStr[] = TEXT("COM");
  826. TCHAR szParallelStr[] = TEXT("LPT");
  827. if (ImageIsValid) {
  828. *ImageIsValid = FALSE;
  829. }
  830. if (ImageExists) {
  831. *ImageExists = FALSE;
  832. }
  833. __try
  834. {
  835. if (pszPath) {
  836. //
  837. // Normal transport
  838. //
  839. //
  840. // Pick the specified transport
  841. //
  842. lpExpStore = (PTSTR)IsmExpandEnvironmentString (PLATFORM_SOURCE, S_SYSENVVAR_GROUP, pszPath, NULL);
  843. if (!lpExpStore) {
  844. // BUGBUG - fatal error
  845. __leave;
  846. }
  847. while (retryTrans) {
  848. if (_IsRemovableOrCDDrive(lpExpStore[0]) && _LocalPathIsRoot(lpExpStore) && (!tryUncFirst))
  849. {
  850. transportStorageId = IsmRegisterTransport (S_REMOVABLE_MEDIA_TRANSPORT);
  851. szRootPath[0] = lpExpStore[0];
  852. pszStoragePath = szRootPath;
  853. }
  854. else if ((_tcsnicmp (pszPath, szSerialStr, (sizeof (szSerialStr) / sizeof (TCHAR)) - 1) == 0) ||
  855. (_tcsnicmp (pszPath, szParallelStr, (sizeof (szParallelStr) / sizeof (TCHAR)) - 1) == 0)
  856. )
  857. {
  858. transportStorageId = IsmRegisterTransport (S_DIRECT_CABLE_TRANSPORT);
  859. pszStoragePath = lpExpStore;
  860. }
  861. else
  862. {
  863. transportStorageId = IsmRegisterTransport (S_RELIABLE_STORAGE_TRANSPORT);
  864. pszStoragePath = lpExpStore;
  865. }
  866. transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, 0);
  867. if (!transportId)
  868. {
  869. // BUGBUG - fatal error
  870. __leave;
  871. }
  872. if (!IsmSetTransportStorage (
  873. fSource ? PLATFORM_SOURCE : PLATFORM_DESTINATION,
  874. transportId,
  875. transportStorageId,
  876. CAPABILITY_COMPRESSED,
  877. pszStoragePath,
  878. ImageIsValid,
  879. ImageExists
  880. ))
  881. {
  882. if (tryUncFirst) {
  883. tryUncFirst = FALSE;
  884. continue;
  885. }
  886. // BUGBUG - fatal error
  887. __leave;
  888. }
  889. if ((!fSource && ImageIsValid && !(*ImageIsValid)) ||
  890. (!fSource && ImageExists && !(*ImageExists))
  891. ) {
  892. if (tryUncFirst) {
  893. tryUncFirst = FALSE;
  894. continue;
  895. }
  896. }
  897. retryTrans = FALSE;
  898. }
  899. IsmReleaseMemory (lpExpStore);
  900. lpExpStore = NULL;
  901. } else {
  902. // network transport
  903. transportStorageId = IsmRegisterTransport (S_HOME_NETWORK_TRANSPORT);
  904. transportId = IsmSelectTransport (transportStorageId, TRANSPORTTYPE_FULL, 0);
  905. if (!transportId)
  906. {
  907. // BUGBUG - fatal error
  908. __leave;
  909. }
  910. if (!IsmSetTransportStorage (
  911. fSource ? PLATFORM_SOURCE : PLATFORM_DESTINATION,
  912. transportId,
  913. transportStorageId,
  914. CAPABILITY_AUTOMATED,
  915. NULL,
  916. ImageIsValid,
  917. ImageExists
  918. ))
  919. {
  920. // BUGBUG - fatal error
  921. __leave;
  922. }
  923. }
  924. hr = S_OK;
  925. }
  926. __finally
  927. {
  928. if (lpExpStore) {
  929. IsmReleaseMemory (lpExpStore);
  930. lpExpStore = NULL;
  931. }
  932. }
  933. if (!SUCCEEDED(hr))
  934. {
  935. if (pMightHaveDiskSpaceProblem ()) {
  936. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  937. } else {
  938. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  939. }
  940. errExtraData.ErrorArea = ERRUSER_AREA_SAVE;
  941. errExtraData.ObjectTypeId = 0;
  942. errExtraData.ObjectName = NULL;
  943. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  944. }
  945. return hr;
  946. }
  947. HRESULT Engine_Parse ()
  948. {
  949. ERRUSER_EXTRADATA errExtraData;
  950. //
  951. // Execute the preparsing
  952. //
  953. if (!IsmExecute (EXECUTETYPE_EXECUTESOURCE_PARSING))
  954. {
  955. if (pMightHaveDiskSpaceProblem ()) {
  956. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  957. } else {
  958. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  959. }
  960. errExtraData.ErrorArea = ERRUSER_AREA_GATHER;
  961. errExtraData.ObjectTypeId = 0;
  962. errExtraData.ObjectName = NULL;
  963. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  964. return E_FAIL;
  965. }
  966. return S_OK;
  967. }
  968. HRESULT Engine_SelectComponentSet (UINT uSelectionGroup)
  969. {
  970. MIG_COMPONENT_ENUM mce;
  971. BOOL bSelected;
  972. BOOL bDefaultSetting;
  973. BOOL bDefaultFile;
  974. BOOL bCallIsm;
  975. TCHAR szComponentToSelect[256];
  976. UINT uGroupInUi;
  977. // uSelectionGroup is either
  978. // MIGINF_SELECT_OOBE
  979. // MIGINF_SELECT_SETTINGS
  980. // MIGINF_SELECT_FILES
  981. // MIGINF_SELECT_BOTH
  982. //
  983. // Enable all components for the type. Use the migwiz.inf to identify components
  984. // that are part of the single floppy or multi floppy configuration. Remove all
  985. // customized components.
  986. //
  987. // This loop pings the component name (such as RAS) or the alias name (such as DOC)
  988. // to determine if the component should be selected. It is optimized to stop pinging
  989. // after the component becomes selected (because a component might have many aliases).
  990. // We rely on the mce.Instance member, which will always be sequential, and will
  991. // always be 1 for the first alias of a component.
  992. //
  993. IsmRemoveAllUserSuppliedComponents();
  994. IsmSelectMasterGroup (MASTERGROUP_ALL, FALSE);
  995. if (IsmEnumFirstComponent (&mce, COMPONENTENUM_ALL_ALIASES, 0))
  996. {
  997. bSelected = FALSE;
  998. do {
  999. bCallIsm = FALSE;
  1000. if (mce.GroupId == COMPONENT_EXTENSION) {
  1001. bSelected = IsComponentEnabled (uSelectionGroup, TEXT("EXTENSIONS"));
  1002. bCallIsm = bSelected;
  1003. } else {
  1004. if (mce.Instance == 1)
  1005. {
  1006. bSelected = IsComponentEnabled (uSelectionGroup, mce.ComponentString);
  1007. bCallIsm = bSelected;
  1008. }
  1009. if (!bSelected)
  1010. {
  1011. bSelected = IsComponentEnabled (uSelectionGroup, mce.LocalizedAlias);
  1012. bCallIsm = bSelected;
  1013. }
  1014. }
  1015. if (bCallIsm)
  1016. {
  1017. IsmSelectComponent (mce.LocalizedAlias, mce.GroupId, bSelected);
  1018. mce.SkipToNextComponent = TRUE;
  1019. }
  1020. } while (IsmEnumNextComponent (&mce));
  1021. }
  1022. return S_OK;
  1023. }
  1024. HRESULT Engine_Execute(BOOL fSource)
  1025. {
  1026. ERRUSER_EXTRADATA errExtraData;
  1027. HRESULT hr = E_FAIL;
  1028. __try {
  1029. if (fSource)
  1030. {
  1031. //
  1032. // Enumerate the system, gather data and analyze
  1033. //
  1034. if (!IsmExecute (EXECUTETYPE_EXECUTESOURCE))
  1035. {
  1036. if (pMightHaveDiskSpaceProblem ()) {
  1037. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  1038. } else {
  1039. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  1040. }
  1041. errExtraData.ErrorArea = ERRUSER_AREA_GATHER;
  1042. errExtraData.ObjectTypeId = 0;
  1043. errExtraData.ObjectName = NULL;
  1044. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  1045. __leave;
  1046. }
  1047. //
  1048. // Finally, save the data
  1049. //
  1050. if (!IsmSave ()) {
  1051. if (pMightHaveDiskSpaceProblem ()) {
  1052. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  1053. } else {
  1054. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  1055. }
  1056. errExtraData.ErrorArea = ERRUSER_AREA_SAVE;
  1057. errExtraData.ObjectTypeId = 0;
  1058. errExtraData.ObjectName = NULL;
  1059. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  1060. __leave;
  1061. }
  1062. hr = S_OK;
  1063. }
  1064. else
  1065. {
  1066. //
  1067. // Try and retrieve the data
  1068. //
  1069. if (!IsmLoad ()) {
  1070. if (pMightHaveDiskSpaceProblem ()) {
  1071. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  1072. } else {
  1073. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  1074. }
  1075. errExtraData.ErrorArea = ERRUSER_AREA_LOAD;
  1076. errExtraData.ObjectTypeId = 0;
  1077. errExtraData.ObjectName = NULL;
  1078. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  1079. __leave;
  1080. }
  1081. //
  1082. // Apply saved state
  1083. //
  1084. if (!IsmExecute (EXECUTETYPE_EXECUTEDESTINATION)) {
  1085. if (pMightHaveDiskSpaceProblem ()) {
  1086. errExtraData.Error = ERRUSER_ERROR_DISKSPACE;
  1087. } else {
  1088. errExtraData.Error = ERRUSER_ERROR_UNKNOWN;
  1089. }
  1090. errExtraData.ErrorArea = ERRUSER_AREA_RESTORE;
  1091. errExtraData.ObjectTypeId = 0;
  1092. errExtraData.ObjectName = NULL;
  1093. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&errExtraData));
  1094. IsmRollback();
  1095. __leave;
  1096. }
  1097. DisableCancel();
  1098. hr = S_OK;
  1099. }
  1100. }
  1101. __finally {
  1102. }
  1103. return hr;
  1104. }
  1105. HRESULT Engine_Cancel ()
  1106. {
  1107. IsmSetCancel();
  1108. return S_OK;
  1109. }
  1110. HRESULT Engine_Terminate ()
  1111. {
  1112. static BOOL fDidThis = FALSE;
  1113. if (fDidThis) {
  1114. return E_FAIL;
  1115. }
  1116. fDidThis = TRUE;
  1117. IsmTerminate();
  1118. if (g_GlobalScriptHandle != INVALID_HANDLE_VALUE)
  1119. {
  1120. SetupCloseInfFile (g_GlobalScriptHandle);
  1121. g_GlobalScriptHandle = INVALID_HANDLE_VALUE;
  1122. }
  1123. return S_OK;
  1124. }