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.

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