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.

1711 lines
50 KiB

  1. #include "pch.h"
  2. #include "fixie.h"
  3. HANDLE g_hHeap = NULL;
  4. HWND g_hWnd = NULL;
  5. HWND g_hProgress = NULL;
  6. int g_nNumGuids = 0;
  7. HRESULT g_hr = E_FAIL;
  8. char g_szLogFileName[MAX_PATH];
  9. LPSTORAGE g_pIStorage = NULL;
  10. LPSTREAM g_pIStream = NULL;
  11. DWORD g_dwPlatform = NULL;
  12. LCIFCOMPONENT g_pLinkCif = NULL;
  13. // #40352 - always repair the Icons. g_bRestoreIcons does not get changed anywhere else.
  14. BOOL g_bRestoreIcons = TRUE;
  15. BOOL g_bQuiet = FALSE;
  16. BOOL g_bRunningWin95;
  17. BOOL g_bNeedReboot = FALSE;
  18. LPSTR g_pszError = NULL;
  19. // Used for the progress bar
  20. // start and end for each section (out of 100)
  21. int g_nVerifyAllFilesStart = 0;
  22. int g_nVerifyAllFilesEnd = 10;
  23. int g_nRunSetupCommandPreROEXStart = 10;
  24. int g_nRunSetupCommandPreROEXEnd = 11;
  25. int g_nRunSetupCommandAllROEXStart = 11;
  26. int g_nRunSetupCommandAllROEXEnd = 21;
  27. int g_nDoRunOnceExProcessStart = 21;
  28. int g_nDoRunOnceExProcessEnd = 80;
  29. int g_nRunSetupCommandAllPostROEXStart = 80;
  30. int g_nRunSetupCommandAllPostROEXEnd = 90;
  31. int g_nRestoreIconsStart = 90;
  32. int g_nRestoreIconsEnd = 100;
  33. int g_nProgressStart = 0;
  34. int g_nProgressEnd = 100;
  35. const char c_gszRegstrPathIExplore[] = REGSTR_PATH_APPPATHS "\\iexplore.exe";
  36. const char c_gszLogFileName[] = "Fix IE Log.txt";
  37. char g_szFixIEInf[MAX_STRING];
  38. const char c_gszFixIEInfName[] = "fixie.inf";
  39. const char c_gszIERnOnceDLL[] = "iernonce.dll";
  40. const char c_gszMainSectionName[] = "FixIE";
  41. const char c_gszPreSectionName[] = "PreROEX";
  42. const char c_gszRegRestoreIcons[] = "Software\\Microsoft\\Active Setup\\Installed Components";
  43. char g_szModifiedMainSectionName[MAX_STRING];
  44. char g_szCryptoSectionName[MAX_STRING];
  45. const char c_gszWin95[] = "";
  46. const char c_gszMillen[] = ".Millen";
  47. const char c_gszNTx86[] = ".NT";
  48. const char c_gszW2K[] = ".W2K";
  49. const char c_gszNTalpha[] = ".Alpha";
  50. const char c_gszCrypto[] = ".Crypto";
  51. LPSTR MakeAnsiStrFromWide(LPWSTR pwsz);
  52. LPWSTR MakeWideStrFromAnsi(LPSTR psz);
  53. void ConvertIStreamToFile(LPSTORAGE *pIStorage, LPSTREAM *pIStream);
  54. void MakePath(LPSTR lpPath);
  55. void LogTimeDate();
  56. HRESULT MyRunSetupCommand(HWND hwnd, LPCSTR lpszInfFile, LPCSTR lpszSection, DWORD dwFlags);
  57. DWORD GetStringField(LPSTR szStr, UINT uField, LPSTR szBuf, UINT cBufSize);
  58. LPSTR FindChar(LPSTR pszStr, char ch);
  59. // Reboot stuff
  60. BOOL MyNTReboot();
  61. HRESULT LaunchProcess(LPCSTR pszCmd, HANDLE *phProc, LPCSTR pszDir, UINT uShow);
  62. BOOL MyRestartDialog(HWND hParent, BOOL bShowPrompt, UINT nIdMessage);
  63. VOID MyConvertVersionString(LPSTR lpszVersion, LPDWORD pdwMSVer, LPDWORD pdwLSVer);
  64. VOID MyGetVersionFromFile(LPSTR lpszFilename, LPDWORD pdwMSVer, LPDWORD pdwLSVer);
  65. int DisplayMessage(char* pszMessage, UINT uStyle);
  66. int LoadSz(UINT id, LPSTR pszBuf, UINT cMaxSize);
  67. VOID GetPlatform();
  68. BOOL CheckForNT4_SP4();
  69. VOID GetInfFile();
  70. VOID AddComponent(ICifComponent *pCifComp);
  71. VOID WriteToLog(char *pszFormatString, ...);
  72. HRESULT InitComponentList();
  73. HRESULT VerifyAllFiles();
  74. HRESULT RunSetupCommandPreROEX();
  75. HRESULT RunSetupCommandAllROEX();
  76. HRESULT RunSetupCommandAllPostROEX();
  77. HRESULT DoRunOnceExProcess();
  78. HRESULT RestoreIcons();
  79. HRESULT Process();
  80. void AddRegMunger();
  81. DWORD RunProcess(LPVOID lp);
  82. INT_PTR CALLBACK DlgProcFixIE(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  83. INT_PTR CALLBACK DlgProcConfirm(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  84. INT_PTR CALLBACK DlgProcReinstall(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  85. void uiCenterDialog( HWND hwndDlg );
  86. void RunOnceExProcessCallback(int nCurrent, int nMax, LPSTR pszError);
  87. void LogError(char *pszFormatString, ...);
  88. void VersionToString(DWORD dwMSVer, DWORD dwLSVer, LPSTR pszVersion);
  89. HRESULT FixIE(BOOL bConfirm, DWORD dwFlags)
  90. {
  91. HRESULT hr = S_OK;
  92. HANDLE hMutex ;
  93. OSVERSIONINFO VerInfo;
  94. // allow only one instance running at a time
  95. // ALSO : mutex wrt to IESetup.EXE. Hence use specific named mutex only
  96. hMutex = CreateMutex(NULL, TRUE, "Ie4Setup.Mutext");
  97. if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))
  98. {
  99. CloseHandle(hMutex);
  100. return S_FALSE;
  101. }
  102. VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  103. GetVersionEx(&VerInfo);
  104. if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  105. {
  106. // If the user does not have Admin rights, bail out.
  107. if ( !IsNTAdmin(0, NULL))
  108. {
  109. char szMsg[MAX_STRING];
  110. LoadSz(IDS_NEED_ADMIN, szMsg, sizeof(szMsg));
  111. DisplayMessage(szMsg, MB_OK|MB_ICONEXCLAMATION);
  112. if (hMutex)
  113. CloseHandle(hMutex);
  114. return S_OK;
  115. }
  116. }
  117. if (bConfirm)
  118. {
  119. if (DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_CONFIRM), NULL, DlgProcConfirm) == IDNO)
  120. {
  121. WriteToLog("\r\nUser selected not to repair.\r\n");
  122. if (g_pIStream)
  123. ConvertIStreamToFile(&g_pIStorage, &g_pIStream);
  124. if (hMutex)
  125. CloseHandle(hMutex);
  126. return S_OK;
  127. }
  128. }
  129. // #40352 - always repair Icons. No need to check if flag is set for it.
  130. ////////////////////////////////////////////////////////////////
  131. // else
  132. // {
  133. // g_bRestoreIcons = dwFlags & FIXIE_ICONS;
  134. // }
  135. ////////////////////////////////////////////////////////////////
  136. if (g_bRestoreIcons)
  137. {
  138. WriteToLog("Restore icon set to true.\r\n");
  139. }
  140. else
  141. {
  142. WriteToLog("Restore icon set to false.\r\n");
  143. }
  144. if (dwFlags & FIXIE_QUIET)
  145. {
  146. g_bQuiet = TRUE;
  147. WriteToLog("Quiet mode on.\r\n");
  148. }
  149. else
  150. {
  151. WriteToLog("Quiet mode off.\r\n");
  152. }
  153. // Get the heap - used for HeapAlloc and HeapReAlloc
  154. g_hHeap = GetProcessHeap();
  155. InitCommonControls();
  156. GetPlatform();
  157. WriteToLog("Main section name: %1\r\n",g_szModifiedMainSectionName);
  158. // if running on NT5 or Millennium or
  159. // If NT4-SP4, don't process the Crypto files else process them too.
  160. if ( (g_dwPlatform == PLATFORM_MILLEN) || (g_dwPlatform == PLATFORM_NT5) ||
  161. ((g_dwPlatform == PLATFORM_NT4 || g_dwPlatform == PLATFORM_NT4ALPHA) && CheckForNT4_SP4()))
  162. {
  163. // Null string the Crypto section name
  164. *g_szCryptoSectionName = '\0';
  165. WriteToLog("No Crypto section to be processed!\r\n");
  166. }
  167. else
  168. {
  169. lstrcpy(g_szCryptoSectionName, c_gszMainSectionName);
  170. lstrcat(g_szCryptoSectionName, c_gszCrypto);
  171. WriteToLog("Crypto section name: %1\r\n",g_szCryptoSectionName);
  172. }
  173. GetInfFile();
  174. WriteToLog("Inf file used: %1\r\n",g_szFixIEInf);
  175. WriteToLog("\r\nFixIE started.\r\n\r\n");
  176. if (!g_bQuiet)
  177. {
  178. if (DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_FIXIE), NULL, DlgProcFixIE) == -1)
  179. {
  180. WriteToLog("\r\nERROR - Display dialog failed!\r\n\r\n");
  181. hr = E_FAIL;
  182. }
  183. else
  184. {
  185. hr = g_hr;
  186. }
  187. }
  188. else
  189. {
  190. hr = Process();
  191. }
  192. if (SUCCEEDED(hr))
  193. {
  194. WriteToLog("\r\nFixIE successful!\r\n");
  195. // Success, so ask user to reboot
  196. MyRestartDialog(g_hWnd, !g_bQuiet, IDS_REBOOT);
  197. }
  198. else
  199. {
  200. WriteToLog("\r\nERROR - FixIE failed!\r\n\r\n");
  201. if (g_bNeedReboot)
  202. {
  203. MyRestartDialog(g_hWnd, !g_bQuiet, IDS_REBOOTFILE);
  204. }
  205. else
  206. {
  207. DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_REINSTALL), NULL, DlgProcReinstall);
  208. }
  209. }
  210. if (g_pszError)
  211. HeapFree(g_hHeap,0,g_pszError);
  212. if (g_pIStream)
  213. ConvertIStreamToFile(&g_pIStorage, &g_pIStream);
  214. if (hMutex)
  215. CloseHandle(hMutex);
  216. return hr;
  217. }
  218. HRESULT Process()
  219. {
  220. HRESULT hr = S_OK;
  221. WriteToLog("\r\nInside Process.\r\n");
  222. // Get all the components that are successfully installed for the current platform
  223. if (SUCCEEDED(hr))
  224. {
  225. hr = InitComponentList();
  226. if (SUCCEEDED(hr))
  227. {
  228. WriteToLog("\r\nInitComponentList succeeded!\r\n\r\n");
  229. WriteToLog("There are a total of %1!ld! installed components.\r\n\r\n",g_nNumGuids);
  230. }
  231. else
  232. {
  233. WriteToLog("\r\nERROR - InitComponentList failed!\r\n\r\n");
  234. }
  235. }
  236. // Verify all the files in the VFS sections exists and have valid version #s
  237. if (SUCCEEDED(hr))
  238. {
  239. hr = VerifyAllFiles();
  240. if (SUCCEEDED(hr))
  241. {
  242. WriteToLog("\r\nVerifyAllFiles succeeded!\r\n\r\n");
  243. }
  244. else
  245. {
  246. WriteToLog("\r\nERROR - VerifyAllFiles failed!\r\n\r\n");
  247. }
  248. }
  249. // Run RunSetupCommand on the PreROEX section
  250. if (SUCCEEDED(hr))
  251. {
  252. hr = RunSetupCommandPreROEX();
  253. if (SUCCEEDED(hr))
  254. {
  255. WriteToLog("\r\nRunSetupCommandPreROEX succeeded!\r\n\r\n");
  256. }
  257. else
  258. {
  259. WriteToLog("\r\nERROR - RunSetupCommandPreROEX failed!\r\n\r\n");
  260. }
  261. }
  262. // Run RunSetupCommand on all the ROEX sections
  263. if (SUCCEEDED(hr))
  264. {
  265. hr = RunSetupCommandAllROEX();
  266. if (SUCCEEDED(hr))
  267. {
  268. WriteToLog("\r\nRunSetupCommandAllROEX succeeded!\r\n\r\n");
  269. }
  270. else
  271. {
  272. WriteToLog("\r\nERROR - RunSetupCommandAllROEX failed!\r\n\r\n");
  273. }
  274. }
  275. // Call runonceexprocess
  276. if (SUCCEEDED(hr))
  277. {
  278. hr = DoRunOnceExProcess();
  279. if (SUCCEEDED(hr))
  280. {
  281. WriteToLog("\r\nDoRunOnceExProcess succeeded!\r\n\r\n");
  282. }
  283. else
  284. {
  285. WriteToLog("\r\nERROR - DoRunOnceExProcess failed!\r\n\r\n");
  286. }
  287. }
  288. // If there are any errors, then set hr to E_FAIL
  289. if (g_pszError)
  290. hr = E_FAIL;
  291. // Run RunSetupCommand on all the PostROEX sections
  292. if (SUCCEEDED(hr))
  293. {
  294. hr = RunSetupCommandAllPostROEX();
  295. if (SUCCEEDED(hr))
  296. {
  297. WriteToLog("\r\nRunSetupCommandAllPostROEX succeeded!\r\n\r\n");
  298. }
  299. else
  300. {
  301. WriteToLog("\r\nERROR - RunSetupCommandAllPostROEX failed!\r\n\r\n");
  302. }
  303. }
  304. // Restore icons
  305. if (SUCCEEDED(hr) && g_bRestoreIcons)
  306. {
  307. hr = RestoreIcons();
  308. if (SUCCEEDED(hr))
  309. {
  310. WriteToLog("\r\nRestoreIcons succeeded!\r\n\r\n");
  311. }
  312. else
  313. {
  314. WriteToLog("\r\nERROR - RestoreIcons failed!\r\n\r\n");
  315. }
  316. }
  317. return hr;
  318. }
  319. DWORD RunProcess(LPVOID lp)
  320. {
  321. WriteToLog("\r\nInside RunProcess.\r\n");
  322. SendMessage(g_hProgress, PBM_SETRANGE, 0, MAKELPARAM(g_nProgressStart, g_nProgressEnd));
  323. SendMessage(g_hProgress, PBM_SETPOS, g_nProgressStart, 0);
  324. g_hr = Process();
  325. SendMessage(g_hProgress, PBM_SETPOS, g_nProgressEnd, 0);
  326. // terminate the dialog box
  327. PostMessage((HWND) lp, WM_FINISHED, 0, 0L);
  328. return 0;
  329. }
  330. INT_PTR CALLBACK DlgProcConfirm(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  331. {
  332. switch (uMsg)
  333. {
  334. case WM_INITDIALOG:
  335. uiCenterDialog(hWnd);
  336. g_hWnd = hWnd;
  337. break;
  338. case WM_COMMAND:
  339. switch( wParam )
  340. {
  341. case IDYES:
  342. case IDNO:
  343. // #40352 - Icon check box no longer exists. Always repair icons.
  344. // g_bRestoreIcons = (IsDlgButtonChecked(hWnd, IDC_REPAIR_ICONS) == BST_CHECKED);
  345. g_hWnd = NULL;
  346. EndDialog(hWnd, wParam);
  347. break;
  348. case IDCANCEL:
  349. g_hWnd = NULL;
  350. EndDialog(hWnd, IDNO);
  351. break;
  352. default:
  353. return FALSE;
  354. }
  355. break;
  356. default:
  357. return(FALSE);
  358. }
  359. return(TRUE);
  360. }
  361. INT_PTR CALLBACK DlgProcReinstall(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  362. {
  363. static LPSTR pszMessage;
  364. switch (uMsg)
  365. {
  366. case WM_INITDIALOG:
  367. uiCenterDialog(hWnd);
  368. if (!g_pszError)
  369. {
  370. EnableWindow(GetDlgItem(hWnd, IDC_DETAILS), FALSE);
  371. }
  372. else
  373. {
  374. char szString[MAX_STRING];
  375. LoadSz(IDS_FOLLOWINGERROR, szString, sizeof(szString));
  376. pszMessage = (LPSTR)HeapAlloc(g_hHeap, 0, lstrlen(g_pszError) + sizeof(szString) + 1);
  377. lstrcpy(pszMessage, szString);
  378. lstrcat(pszMessage, g_pszError);
  379. }
  380. g_hWnd = hWnd;
  381. break;
  382. case WM_COMMAND:
  383. switch( wParam )
  384. {
  385. case IDOK:
  386. case IDCANCEL:
  387. g_hWnd = NULL;
  388. HeapFree(g_hHeap, 0, pszMessage);
  389. EndDialog(hWnd, wParam);
  390. break;
  391. case IDC_DETAILS:
  392. // Display failure messages.
  393. char szTitle[MAX_STRING];
  394. GetWindowText(hWnd, szTitle, sizeof(szTitle));
  395. MessageBox(hWnd, pszMessage, szTitle, MB_OK);
  396. break;
  397. default:
  398. return FALSE;
  399. }
  400. break;
  401. default:
  402. return(FALSE);
  403. }
  404. return(TRUE);
  405. }
  406. INT_PTR CALLBACK DlgProcFixIE(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  407. {
  408. static HANDLE s_hThread = NULL;
  409. DWORD dwThread;
  410. switch (uMsg)
  411. {
  412. case WM_INITDIALOG:
  413. uiCenterDialog(hWnd);
  414. g_hWnd = hWnd;
  415. g_hProgress = GetDlgItem(hWnd, IDC_PROGRESS);
  416. if ((s_hThread = CreateThread(NULL, 0, RunProcess, (LPVOID) hWnd, 0, &dwThread)) == NULL)
  417. PostMessage(hWnd, WM_FINISHED, 0, 0L);
  418. break;
  419. case WM_FINISHED:
  420. if (s_hThread != NULL)
  421. {
  422. while (MsgWaitForMultipleObjects(1, &s_hThread, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
  423. {
  424. MSG msg;
  425. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  426. {
  427. TranslateMessage(&msg);
  428. DispatchMessage(&msg);
  429. }
  430. }
  431. CloseHandle(s_hThread);
  432. s_hThread = NULL;
  433. }
  434. g_hWnd = NULL;
  435. EndDialog(hWnd, 0);
  436. break;
  437. default:
  438. return(FALSE);
  439. }
  440. return(TRUE);
  441. }
  442. void RunOnceExProcessCallback(int nCurrent, int nMax, LPSTR pszError)
  443. {
  444. int nStart = g_nDoRunOnceExProcessStart;
  445. int nEnd = g_nDoRunOnceExProcessEnd;
  446. WriteToLog("Current=%1!ld! ; Max=%2!ld! ; Error=%3\r\n", nCurrent, nMax, pszError);
  447. if (g_hProgress && nMax)
  448. {
  449. SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurrent/nMax, 0);
  450. }
  451. if (pszError)
  452. {
  453. LogError(pszError);
  454. }
  455. }
  456. void LogError(char *pszFormatString, ...)
  457. {
  458. va_list args;
  459. char *pszFullErrMsg = NULL;
  460. LPSTR pszErrorPreFail = NULL;
  461. // If error string does not exist, then malloc it
  462. if (!g_pszError)
  463. {
  464. g_pszError = (LPSTR)HeapAlloc(g_hHeap, 0, BUFFERSIZE);
  465. if ( ! g_pszError )
  466. return; // Is it OK to fail quietly here ?
  467. *g_pszError = '\0';
  468. }
  469. va_start(args, pszFormatString);
  470. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
  471. (LPCVOID) pszFormatString, 0, 0, (LPTSTR) &pszFullErrMsg, 0, &args);
  472. if (pszFullErrMsg)
  473. {
  474. // Make room for new string and newline
  475. while (lstrlen(g_pszError)+lstrlen(pszFullErrMsg)+2>(int)HeapSize(g_hHeap, 0, g_pszError))
  476. {
  477. WriteToLog("Error string size is %1!ld!", HeapSize(g_hHeap, 0, g_pszError));
  478. pszErrorPreFail = g_pszError;
  479. #pragma prefast(suppress: 308, "PREfast noise - pointer was saved")
  480. g_pszError = (LPSTR)HeapReAlloc(g_hHeap, 0, g_pszError, HeapSize(g_hHeap, 0, g_pszError)+BUFFERSIZE);
  481. if(!g_pszError)
  482. {
  483. if (pszErrorPreFail)
  484. HeapFree(g_hHeap, 0, pszErrorPreFail);
  485. break;
  486. }
  487. WriteToLog(", increasing it to %1!ld!\r\n", HeapSize(g_hHeap, 0, g_pszError));
  488. }
  489. if ( g_pszError )
  490. {
  491. // Add string and then add newline
  492. lstrcat(g_pszError, pszFullErrMsg);
  493. lstrcat(g_pszError, "\n");
  494. }
  495. LocalFree(pszFullErrMsg);
  496. }
  497. }
  498. HRESULT RestoreIcons()
  499. {
  500. HRESULT hr = S_OK;
  501. const char szIEAccess[] = "Software\\Microsoft\\Active Setup\\Installed Components\\>{26923b43-4d38-484f-9b9e-de460746276c}";
  502. int nStart = g_nRestoreIconsStart;
  503. int nEnd = g_nRestoreIconsEnd;
  504. int nCurGuid = 0;
  505. LCIFCOMPONENT pComp = g_pLinkCif;
  506. char szKey[MAX_PATH];
  507. lstrcpy(szKey, c_gszRegRestoreIcons);
  508. char* pszEnd = szKey + lstrlen(szKey);
  509. while (pComp && SUCCEEDED(hr))
  510. {
  511. // Add guid to end
  512. AddPath(szKey, pComp->szGuid);
  513. // Delete key
  514. if (RegDeleteKey(HKEY_CURRENT_USER, szKey) == ERROR_SUCCESS)
  515. {
  516. WriteToLog("Reg key HKCU\\%1 deleted\r\n", szKey);
  517. }
  518. else
  519. {
  520. WriteToLog("Reg key HKCU\\%1 cannot be deleted\r\n", szKey);
  521. }
  522. // Remove the guid
  523. *pszEnd = '\0';
  524. nCurGuid++;
  525. if (g_hProgress)
  526. SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
  527. pComp = pComp->next;
  528. }
  529. RegDeleteKey(HKEY_CURRENT_USER, szIEAccess);
  530. return hr;
  531. }
  532. HRESULT DoRunOnceExProcess()
  533. {
  534. HRESULT hr = E_FAIL;
  535. int nStart = g_nDoRunOnceExProcessStart;
  536. int nEnd = g_nDoRunOnceExProcessEnd;
  537. // Load iernonce.dll
  538. HINSTANCE hIERnOnceDLL;
  539. char szDLLPath[MAX_PATH];
  540. GetSystemDirectory(szDLLPath, sizeof(szDLLPath));
  541. AddPath(szDLLPath, c_gszIERnOnceDLL);
  542. hIERnOnceDLL = LoadLibrary(szDLLPath);
  543. if (hIERnOnceDLL)
  544. {
  545. RUNONCEEXPROCESS fpRunOnceExProcess;
  546. INITCALLBACK fpInitCallback;
  547. // Add callback and set to quiet
  548. if (fpInitCallback = (INITCALLBACK)GetProcAddress(hIERnOnceDLL, achInitCallback))
  549. {
  550. fpInitCallback(&RunOnceExProcessCallback, TRUE);
  551. }
  552. else
  553. {
  554. WriteToLog("\r\nERROR - GetProcAddress on %1 failed!\r\n\r\n", achInitCallback);
  555. }
  556. // Run RunOnceExProcess
  557. if (fpRunOnceExProcess = (RUNONCEEXPROCESS)GetProcAddress(hIERnOnceDLL, achRunOnceExProcess))
  558. {
  559. hr = fpRunOnceExProcess(g_hWnd, NULL, NULL, 1);
  560. }
  561. else
  562. {
  563. WriteToLog("\r\nERROR - GetProcAddress on %1 failed!\r\n\r\n", achRunOnceExProcess);
  564. }
  565. FreeLibrary(hIERnOnceDLL);
  566. }
  567. else
  568. {
  569. WriteToLog("\r\nERROR - %1 cannot be loaded!\r\n\r\n", szDLLPath);
  570. }
  571. if (g_hProgress)
  572. SendMessage(g_hProgress, PBM_SETPOS, nEnd, 0);
  573. return hr;
  574. }
  575. HRESULT RunSetupCommandPreROEX()
  576. {
  577. HRESULT hr = S_OK;
  578. int nStart = g_nRunSetupCommandPreROEXStart;
  579. int nEnd = g_nRunSetupCommandPreROEXEnd;
  580. hr = MyRunSetupCommand(g_hWnd, g_szFixIEInf, c_gszPreSectionName, 0);
  581. if (g_hProgress)
  582. SendMessage(g_hProgress, PBM_SETPOS, nEnd, 0);
  583. return hr;
  584. }
  585. HRESULT RunSetupCommandAllPostROEX()
  586. {
  587. HRESULT hr = S_OK;
  588. int nStart = g_nRunSetupCommandAllPostROEXStart;
  589. int nEnd = g_nRunSetupCommandAllPostROEXEnd;
  590. int nCurGuid = 0;
  591. LCIFCOMPONENT pComp = g_pLinkCif;
  592. while (pComp && SUCCEEDED(hr))
  593. {
  594. if ( *(pComp->szPostROEX) != '\0')
  595. hr = MyRunSetupCommand(g_hWnd, g_szFixIEInf, pComp->szPostROEX, 0);
  596. nCurGuid++;
  597. if (g_hProgress)
  598. SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
  599. pComp = pComp->next;
  600. }
  601. return hr;
  602. }
  603. HRESULT RunSetupCommandAllROEX()
  604. {
  605. HRESULT hr = S_OK;
  606. int nStart = g_nRunSetupCommandAllROEXStart;
  607. int nEnd = g_nRunSetupCommandAllROEXEnd;
  608. int nCurGuid = 0;
  609. LCIFCOMPONENT pComp = g_pLinkCif;
  610. while (pComp && SUCCEEDED(hr))
  611. {
  612. if ( *(pComp->szROEX) != '\0')
  613. hr = MyRunSetupCommand(g_hWnd, g_szFixIEInf, pComp->szROEX, 0);
  614. nCurGuid++;
  615. if (g_hProgress)
  616. SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
  617. pComp = pComp->next;
  618. }
  619. return hr;
  620. }
  621. HRESULT VerifyAllFiles()
  622. {
  623. HRESULT hr = S_OK;
  624. char szError[MAX_STRING];
  625. int nStart = g_nVerifyAllFilesStart;
  626. int nEnd = g_nVerifyAllFilesEnd;
  627. int nCurGuid = 0;
  628. LCIFCOMPONENT pComp = g_pLinkCif;
  629. char szMessage[MAX_STRING];
  630. char szLocation[MAX_PATH];
  631. GetSystemDirectory(szLocation, sizeof(szLocation));
  632. char *pTmp = szLocation + lstrlen(szLocation);
  633. LPSTR lpVFSSection = NULL;
  634. while (pComp)
  635. {
  636. lpVFSSection = (LPSTR)LocalAlloc(LPTR, MAX_CONTENT);
  637. if(!lpVFSSection) {
  638. return E_FAIL;
  639. }
  640. WriteToLog("Looking up %1...\r\n", pComp->szVFS);
  641. if (GetPrivateProfileSection(pComp->szVFS, lpVFSSection, MAX_CONTENT, g_szFixIEInf))
  642. {
  643. LPSTR lpVFSLine = lpVFSSection;
  644. while (*lpVFSLine)
  645. {
  646. int nLength = lstrlen(lpVFSLine);
  647. // Need to allow new-line comments.
  648. if ( *lpVFSLine == ';' )
  649. {
  650. lpVFSLine += nLength + 1;
  651. continue; // Go on with next iteration of the WHILE loop
  652. }
  653. WriteToLog(" Verifying %1\r\n", lpVFSLine);
  654. char szFile[MAX_STRING];
  655. // Find '=' so that file and versions can be seperated
  656. char* pChar;
  657. pChar = ANSIStrChr(lpVFSLine, '=');
  658. // if can't find '=' or '=' is last character then make sure file exists
  659. if (!pChar || (*(pChar+1)=='\0'))
  660. {
  661. // Kill the '=' if it exists
  662. if (pChar)
  663. *pChar = '\0';
  664. // Get the filename
  665. lstrcpy(szFile, lpVFSLine);
  666. // Add the filename to the path
  667. AddPath(szLocation, szFile);
  668. // If can't find file, then set error
  669. if (GetFileAttributes(szLocation) == 0xFFFFFFFF)
  670. {
  671. hr = E_FAIL;
  672. if (GetLastError() == ERROR_FILE_NOT_FOUND)
  673. {
  674. WriteToLog(" ERROR - File %1 does not exist.\r\n", szFile);
  675. LoadSz(IDS_FILEMISSING, szError, sizeof(szError));
  676. LogError(szError, szFile);
  677. }
  678. else
  679. {
  680. WriteToLog(" ERROR - File %1 exists but cannot be accessed.\r\n", szFile);
  681. LoadSz(IDS_FILELOCKED, szError, sizeof(szError));
  682. LogError(szError, szFile);
  683. g_bNeedReboot = TRUE;
  684. }
  685. }
  686. else
  687. {
  688. WriteToLog(" File %1 exists.\r\n", szFile);
  689. }
  690. // Reset the location to just the path again
  691. *pTmp = '\0';
  692. }
  693. else // Make sure version in the given limits
  694. {
  695. *pChar = '\0';
  696. pChar++;
  697. // Get the filename
  698. lstrcpy(szFile, lpVFSLine);
  699. DWORD dwMSVer;
  700. DWORD dwLSVer;
  701. // Add the filename to the path
  702. AddPath(szLocation, szFile);
  703. // Get the version of that file
  704. MyGetVersionFromFile(szLocation, &dwMSVer, &dwLSVer);
  705. // If file cannot be read then report error
  706. if (dwMSVer==0 && dwLSVer==0 && GetFileAttributes(szLocation) == 0xFFFFFFFF)
  707. {
  708. hr = E_FAIL;
  709. if (GetLastError() == ERROR_FILE_NOT_FOUND)
  710. {
  711. WriteToLog(" ERROR - File %1 does not exist.\r\n", szFile);
  712. LoadSz(IDS_FILEMISSING, szError, sizeof(szError));
  713. LogError(szError, szFile);
  714. }
  715. else
  716. {
  717. WriteToLog(" ERROR - File %1 exists but cannot be accessed.\r\n", szFile);
  718. LoadSz(IDS_FILELOCKED, szError, sizeof(szError));
  719. LogError(szError, szFile);
  720. g_bNeedReboot = TRUE;
  721. }
  722. }
  723. else
  724. {
  725. // Find '-' so that if there are more than one versions then they are seperated
  726. char* pChar2;
  727. pChar2 = ANSIStrChr(pChar, '-');
  728. if (pChar2)
  729. {
  730. BOOL bVerifyError = FALSE;
  731. char szVersionFound[MAX_VER];
  732. char szVersionLow[MAX_VER];
  733. char szVersionHigh[MAX_VER];
  734. VersionToString(dwMSVer, dwLSVer, szVersionFound);
  735. *pChar2 = '\0';
  736. pChar2++;
  737. // pChar points to first version
  738. // pChar2 points to second version
  739. // '-' found
  740. // so it's one of: xxxx- ; -xxxx ; xxxx-xxxx
  741. if (lstrlen(pChar)) // Low version exists
  742. {
  743. DWORD dwMSVerLow = 0;
  744. DWORD dwLSVerLow = 0;
  745. MyConvertVersionString(pChar, &dwMSVerLow, &dwLSVerLow);
  746. VersionToString(dwMSVerLow, dwLSVerLow, szVersionLow);
  747. // Make sure this version is greater than low version
  748. if ((dwMSVerLow<dwMSVer) || ((dwMSVerLow==dwMSVer) && (dwLSVerLow<=dwLSVer)))
  749. {
  750. }
  751. else
  752. {
  753. bVerifyError = TRUE;
  754. }
  755. }
  756. if (lstrlen(pChar2)) // High version exists
  757. {
  758. DWORD dwMSVerHigh = 0;
  759. DWORD dwLSVerHigh = 0;
  760. MyConvertVersionString(pChar2, &dwMSVerHigh, &dwLSVerHigh);
  761. VersionToString(dwMSVerHigh, dwLSVerHigh, szVersionHigh);
  762. // Make sure this version is lesser than high version
  763. if ((dwMSVerHigh>dwMSVer) || ((dwMSVerHigh==dwMSVer) && (dwLSVerHigh>=dwLSVer)))
  764. {
  765. }
  766. else
  767. {
  768. bVerifyError = TRUE;
  769. }
  770. }
  771. if (bVerifyError)
  772. {
  773. WriteToLog(" ERROR - File %1 (version %2) version check failed.\r\n", szFile, szVersionFound);
  774. hr = E_FAIL;
  775. if (lstrlen(pChar)&&lstrlen(pChar2))
  776. {
  777. LoadSz(IDS_VERSIONINBETWEEN, szError, sizeof(szError));
  778. LogError(szError, szVersionFound, szFile, szVersionLow, szVersionHigh);
  779. }
  780. else if (lstrlen(pChar))
  781. {
  782. LoadSz(IDS_VERSIONGREATER, szError, sizeof(szError));
  783. LogError(szError, szVersionFound, szFile, szVersionLow);
  784. }
  785. else if (lstrlen(pChar2))
  786. {
  787. LoadSz(IDS_VERSIONLESS, szError, sizeof(szError));
  788. LogError(szError, szVersionFound, szFile, szVersionHigh);
  789. }
  790. }
  791. else
  792. {
  793. WriteToLog(" File %1 version checked.\r\n", szFile);
  794. }
  795. }
  796. else // no '-' is found
  797. {
  798. // so it's a unique version
  799. // the current version must be exact
  800. DWORD dwMSVerExact = 0;
  801. DWORD dwLSVerExact = 0;
  802. MyConvertVersionString(pChar, &dwMSVerExact, &dwLSVerExact);
  803. char szVersionFound[MAX_VER];
  804. char szVersionRequired[MAX_VER];
  805. VersionToString(dwMSVer, dwLSVer, szVersionFound);
  806. VersionToString(dwMSVerExact, dwLSVerExact, szVersionRequired);
  807. // If it is not an exact match then signal error occured
  808. if ((dwMSVerExact==dwMSVer) && (dwLSVerExact==dwLSVer))
  809. {
  810. WriteToLog(" File %1 version checked.\r\n", szFile);
  811. }
  812. else
  813. {
  814. WriteToLog(" ERROR - File %1 (version %2) version check failed.\r\n", szFile, szVersionFound);
  815. LoadSz(IDS_VERSIONEXACT, szError, sizeof(szError));
  816. LogError(szError, szVersionFound, szFile, szVersionRequired);
  817. hr = E_FAIL;
  818. }
  819. }
  820. }
  821. // Reset the location to just the path again
  822. *pTmp = '\0';
  823. }
  824. lpVFSLine += nLength + 1;
  825. }
  826. }
  827. nCurGuid++;
  828. if (g_hProgress)
  829. SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
  830. pComp = pComp->next;
  831. }
  832. if (lpVFSSection)
  833. LocalFree(lpVFSSection);
  834. return hr;
  835. }
  836. void VersionToString(DWORD dwMSVer, DWORD dwLSVer, LPSTR pszVersion)
  837. {
  838. wsprintf(pszVersion, "%d.%d.%d.%d", HIWORD(dwMSVer), LOWORD(dwMSVer), HIWORD(dwLSVer), LOWORD(dwLSVer));
  839. }
  840. VOID GetInfFile()
  841. {
  842. DWORD dwType;
  843. DWORD dwSize = sizeof(g_szFixIEInf);
  844. HKEY hKey;
  845. *g_szFixIEInf = '\0';
  846. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_gszRegstrPathIExplore, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
  847. {
  848. if ((RegQueryValueEx(hKey, NULL, 0, &dwType, (LPBYTE)g_szFixIEInf, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
  849. {
  850. GetParentDir(g_szFixIEInf);
  851. }
  852. RegCloseKey(hKey);
  853. }
  854. AddPath(g_szFixIEInf, c_gszFixIEInfName);
  855. }
  856. VOID GetPlatform()
  857. {
  858. LPCSTR pTemp = NULL;
  859. OSVERSIONINFO VerInfo;
  860. VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  861. GetVersionEx(&VerInfo);
  862. lstrcpy(g_szModifiedMainSectionName, c_gszMainSectionName);
  863. if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  864. {
  865. // Running NT
  866. g_bRunningWin95 = FALSE;
  867. SYSTEM_INFO System_info;
  868. GetSystemInfo(&System_info);
  869. if (System_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA)
  870. {
  871. g_dwPlatform = PLATFORM_NT5ALPHA;
  872. if (VerInfo.dwMajorVersion == 4)
  873. g_dwPlatform = PLATFORM_NT4ALPHA;
  874. pTemp = c_gszNTalpha;
  875. }
  876. else
  877. {
  878. g_dwPlatform = PLATFORM_NT5;
  879. pTemp = c_gszW2K;
  880. if (VerInfo.dwMajorVersion == 4)
  881. {
  882. g_dwPlatform = PLATFORM_NT4;
  883. pTemp = c_gszNTx86;
  884. }
  885. }
  886. }
  887. else
  888. {
  889. // Running Windows 9x
  890. // Assume Win98
  891. g_bRunningWin95 = TRUE;
  892. g_dwPlatform = PLATFORM_WIN98;
  893. pTemp = c_gszWin95;
  894. if (VerInfo.dwMinorVersion == 0)
  895. {
  896. g_dwPlatform = PLATFORM_WIN95;
  897. }
  898. else if (VerInfo.dwMinorVersion == 90)
  899. {
  900. pTemp = c_gszMillen;
  901. g_dwPlatform = PLATFORM_MILLEN;
  902. }
  903. }
  904. if (pTemp)
  905. lstrcat(g_szModifiedMainSectionName, pTemp);
  906. }
  907. #define REGSTR_CCS_CONTROL_WINDOWS REGSTR_PATH_CURRENT_CONTROL_SET "\\WINDOWS"
  908. #define CSDVERSION "CSDVersion"
  909. #define NTSP4_VERSION 0x0600
  910. // version updated to SP6!
  911. BOOL CheckForNT4_SP4()
  912. {
  913. HKEY hKey;
  914. DWORD dwCSDVersion;
  915. DWORD dwSize;
  916. BOOL bNTSP4 = -1;
  917. if ( bNTSP4 == -1)
  918. {
  919. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_CCS_CONTROL_WINDOWS, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
  920. {
  921. // assign the default
  922. bNTSP4 = FALSE;
  923. dwSize = sizeof(dwCSDVersion);
  924. if (RegQueryValueEx(hKey, CSDVERSION, NULL, NULL, (unsigned char*)&dwCSDVersion, &dwSize) == ERROR_SUCCESS)
  925. {
  926. bNTSP4 = (LOWORD(dwCSDVersion) >= NTSP4_VERSION);
  927. }
  928. RegCloseKey(hKey);
  929. }
  930. }
  931. return bNTSP4;
  932. }
  933. HRESULT InitComponentList()
  934. {
  935. HRESULT hr = E_FAIL;
  936. ICifFile *pCifFile = NULL;
  937. IEnumCifComponents *pEnumCifComponents = NULL;
  938. ICifComponent *pCifComponent = NULL;
  939. hr = GetICifFileFromFile(&pCifFile, "iesetup.cif");
  940. if (SUCCEEDED(hr))
  941. {
  942. hr = pCifFile->EnumComponents(&pEnumCifComponents, g_dwPlatform , NULL);
  943. if (SUCCEEDED(hr))
  944. {
  945. while (pEnumCifComponents->Next(&pCifComponent) == S_OK)
  946. {
  947. if (pCifComponent->IsComponentInstalled() == ICI_INSTALLED)
  948. AddComponent(pCifComponent);
  949. }
  950. pEnumCifComponents->Release();
  951. }
  952. else
  953. {
  954. WriteToLog("\r\nERROR - Cannot pCifFile->EnumComponents!\r\n\r\n");
  955. }
  956. pCifFile->Release();
  957. }
  958. else
  959. {
  960. WriteToLog("\r\nERROR - Cannot GetICifFileFromFile!\r\n\r\n");
  961. }
  962. return hr;
  963. }
  964. VOID AddLink(LPSTR szGuid, ICifComponent *pCifComp, LPSTR szGuidProfileString)
  965. {
  966. char szID[MAX_STRING];
  967. LCIFCOMPONENT pComp;
  968. char *pStart = szGuidProfileString;
  969. char *pChar;
  970. LCIFCOMPONENT pTemp = g_pLinkCif;
  971. LCIFCOMPONENT pLast = NULL;
  972. pCifComp->GetID(szID, sizeof(szID));
  973. WriteToLog("Add component %1 with GUID %2\r\n", szID, szGuid);
  974. // Initialize all the members of the new LCIFCOMPONENT link.
  975. pComp = (LCIFCOMPONENT)LocalAlloc(LPTR, sizeof(LINKEDCIFCOMPONENT));
  976. pComp->pCifComponent = pCifComp;
  977. lstrcpy(pComp->szGuid, szGuid);
  978. *(pComp->szVFS) = '\0';
  979. *(pComp->szROEX) = '\0';
  980. *(pComp->szPostROEX) = '\0';
  981. pComp->next = NULL;
  982. GetStringField(szGuidProfileString, 0, pComp->szVFS, sizeof(pComp->szVFS));
  983. GetStringField(szGuidProfileString, 1, pComp->szROEX, sizeof(pComp->szROEX));
  984. GetStringField(szGuidProfileString, 2, pComp->szPostROEX, sizeof(pComp->szPostROEX));
  985. WriteToLog(" VFS = %1\r\n",pComp->szVFS);
  986. WriteToLog(" ROEX = %1\r\n", pComp->szROEX);
  987. WriteToLog(" PostROEX = %1\r\n", pComp->szPostROEX);
  988. // Add the new link to the linklist pointed to be g_pLinkCif
  989. while (pTemp)
  990. {
  991. pLast = pTemp;
  992. pTemp = pTemp->next;
  993. }
  994. if (pLast)
  995. pLast->next = pComp;
  996. else
  997. g_pLinkCif = pComp;
  998. // Increment global count of number of guids
  999. g_nNumGuids++;
  1000. if (pTemp)
  1001. {
  1002. pComp->next = pTemp;
  1003. }
  1004. }
  1005. VOID AddComponent(ICifComponent *pCifComp)
  1006. {
  1007. char szGuid[MAX_STRING];
  1008. if (SUCCEEDED(pCifComp->GetGUID(szGuid, sizeof(szGuid))))
  1009. {
  1010. char szGuidProfileString[MAX_STRING];
  1011. if (GetPrivateProfileString(g_szModifiedMainSectionName, szGuid, "", szGuidProfileString, sizeof(szGuidProfileString), g_szFixIEInf))
  1012. {
  1013. AddLink(szGuid, pCifComp, szGuidProfileString);
  1014. }
  1015. // If a valid Crypto section exists, process this GUID entry under it too.
  1016. if ( *g_szCryptoSectionName )
  1017. {
  1018. if (GetPrivateProfileString(g_szCryptoSectionName, szGuid, "", szGuidProfileString, sizeof(szGuidProfileString), g_szFixIEInf))
  1019. {
  1020. AddLink(szGuid, pCifComp, szGuidProfileString);
  1021. }
  1022. }
  1023. }
  1024. }
  1025. VOID MyConvertVersionString(LPSTR lpszVersion, LPDWORD pdwMSVer, LPDWORD pdwLSVer)
  1026. {
  1027. WORD wVer[4];
  1028. ConvertVersionString(lpszVersion, wVer, '.' );
  1029. *pdwMSVer = (DWORD)wVer[0] << 16; // Make hi word of MS version
  1030. *pdwMSVer += (DWORD)wVer[1]; // Make lo word of MS version
  1031. *pdwLSVer = (DWORD)wVer[2] << 16; // Make hi word of LS version
  1032. *pdwLSVer += (DWORD)wVer[3]; // Make lo word of LS version
  1033. }
  1034. VOID MyGetVersionFromFile(LPSTR lpszFilename, LPDWORD pdwMSVer, LPDWORD pdwLSVer)
  1035. {
  1036. unsigned uiSize;
  1037. DWORD dwVerInfoSize;
  1038. DWORD dwHandle;
  1039. VS_FIXEDFILEINFO * lpVSFixedFileInfo;
  1040. void FAR *lpBuffer;
  1041. LPVOID lpVerBuffer;
  1042. *pdwMSVer = *pdwLSVer = 0L;
  1043. dwVerInfoSize = GetFileVersionInfoSize(lpszFilename, &dwHandle);
  1044. if (dwVerInfoSize)
  1045. {
  1046. // Alloc the memory for the version stamping
  1047. lpBuffer = LocalAlloc(LPTR, dwVerInfoSize);
  1048. if (lpBuffer)
  1049. {
  1050. // Read version stamping info
  1051. if (GetFileVersionInfo(lpszFilename, dwHandle, dwVerInfoSize, lpBuffer))
  1052. {
  1053. // Get the value for Translation
  1054. if (VerQueryValue(lpBuffer, "\\", (LPVOID*)&lpVSFixedFileInfo, &uiSize) &&
  1055. (uiSize))
  1056. {
  1057. *pdwMSVer = lpVSFixedFileInfo->dwFileVersionMS;
  1058. *pdwLSVer = lpVSFixedFileInfo->dwFileVersionLS;
  1059. }
  1060. }
  1061. LocalFree(lpBuffer);
  1062. }
  1063. }
  1064. return ;
  1065. }
  1066. VOID WriteToLog(char *pszFormatString, ...)
  1067. {
  1068. va_list args;
  1069. char *pszFullErrMsg = NULL;
  1070. DWORD dwBytesWritten;
  1071. if (!g_pIStream)
  1072. {
  1073. char szTmp[MAX_PATH];
  1074. LPWSTR pwsz = NULL;
  1075. if (GetWindowsDirectory(g_szLogFileName, sizeof(g_szLogFileName)))
  1076. {
  1077. AddPath(g_szLogFileName, c_gszLogFileName);
  1078. if (GetFileAttributes(g_szLogFileName) != 0xFFFFFFFF)
  1079. {
  1080. // Make a backup of the current log file
  1081. lstrcpyn(szTmp, g_szLogFileName, lstrlen(g_szLogFileName) - 2 ); // don't copy extension
  1082. lstrcat(szTmp, "BAK");
  1083. SetFileAttributes(szTmp, FILE_ATTRIBUTE_NORMAL);
  1084. DeleteFile(szTmp);
  1085. MoveFile(g_szLogFileName, szTmp);
  1086. }
  1087. pwsz = MakeWideStrFromAnsi(g_szLogFileName);
  1088. if ((pwsz) &&
  1089. (!FAILED(StgCreateDocfile(pwsz,
  1090. STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
  1091. 0, &g_pIStorage))) )
  1092. {
  1093. g_pIStorage->CreateStream( L"CONTENTS",
  1094. STGM_READWRITE| STGM_SHARE_EXCLUSIVE,
  1095. 0, 0, &g_pIStream );
  1096. if (g_pIStream == NULL)
  1097. {
  1098. // Could not open the stream, close the storage and delete the file
  1099. g_pIStorage->Release();
  1100. g_pIStorage = NULL;
  1101. DeleteFile(g_szLogFileName);
  1102. }
  1103. }
  1104. if (pwsz)
  1105. CoTaskMemFree(pwsz);
  1106. WriteToLog("Logging information for FixIE ...\r\n");
  1107. LogTimeDate();
  1108. WriteToLog("\r\n");
  1109. }
  1110. }
  1111. if (g_pIStream)
  1112. {
  1113. va_start(args, pszFormatString);
  1114. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
  1115. (LPCVOID) pszFormatString, 0, 0, (LPTSTR) &pszFullErrMsg, 0, &args);
  1116. if (pszFullErrMsg)
  1117. {
  1118. g_pIStream->Write(pszFullErrMsg, lstrlen(pszFullErrMsg), &dwBytesWritten);
  1119. LocalFree(pszFullErrMsg);
  1120. }
  1121. }
  1122. }
  1123. void ConvertIStreamToFile(LPSTORAGE *pIStorage, LPSTREAM *pIStream)
  1124. {
  1125. HANDLE fh;
  1126. char szTempFile[MAX_PATH]; // Should use the logfilename
  1127. LPVOID lpv = NULL;
  1128. LARGE_INTEGER li;
  1129. DWORD dwl;
  1130. ULONG ul;
  1131. HRESULT hr;
  1132. lstrcpy (szTempFile, g_szLogFileName);
  1133. MakePath(szTempFile);
  1134. if (GetTempFileName(szTempFile, "~VS", 0, szTempFile) != 0)
  1135. {
  1136. fh = CreateFile(szTempFile, GENERIC_READ|GENERIC_WRITE,
  1137. 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1138. if (fh != INVALID_HANDLE_VALUE)
  1139. {
  1140. lpv = (LPSTR)LocalAlloc(LPTR, BUFFERSIZE);
  1141. if (lpv)
  1142. {
  1143. LISet32(li, 0);
  1144. (*pIStream)->Seek(li, STREAM_SEEK_SET, NULL); // Set the seek pointer to the beginning
  1145. do
  1146. {
  1147. hr = (*pIStream)->Read(lpv, BUFFERSIZE, &ul);
  1148. if(SUCCEEDED(hr))
  1149. {
  1150. if (!WriteFile(fh, lpv, ul, &dwl, NULL))
  1151. hr = E_FAIL;
  1152. }
  1153. }
  1154. while ((SUCCEEDED(hr)) && (ul == BUFFERSIZE));
  1155. LocalFree(lpv);
  1156. }
  1157. CloseHandle(fh);
  1158. // Need to release stream and storage to close the storage file.
  1159. (*pIStream)->Release();
  1160. (*pIStorage)->Release();
  1161. *pIStream = NULL;
  1162. *pIStorage = NULL;
  1163. if (SUCCEEDED(hr))
  1164. {
  1165. DeleteFile(g_szLogFileName);
  1166. MoveFile(szTempFile, g_szLogFileName);
  1167. }
  1168. }
  1169. }
  1170. if (*pIStream)
  1171. {
  1172. // If we did not manage to convert the file to a text file
  1173. (*pIStream)->Release();
  1174. (*pIStorage)->Release();
  1175. *pIStream = NULL;
  1176. *pIStorage = NULL;
  1177. }
  1178. return ;
  1179. }
  1180. LPWSTR MakeWideStrFromAnsi(LPSTR psz)
  1181. {
  1182. LPWSTR pwsz;
  1183. int i;
  1184. // arg checking.
  1185. //
  1186. if (!psz)
  1187. return NULL;
  1188. // compute the length
  1189. //
  1190. i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
  1191. if (i <= 0) return NULL;
  1192. pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
  1193. if (!pwsz) return NULL;
  1194. MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
  1195. pwsz[i - 1] = 0;
  1196. return pwsz;
  1197. }
  1198. LPSTR MakeAnsiStrFromWide(LPWSTR pwsz)
  1199. {
  1200. LPSTR psz;
  1201. int i;
  1202. // arg checking.
  1203. //
  1204. if (!pwsz)
  1205. return NULL;
  1206. // compute the length
  1207. //
  1208. i = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);
  1209. if (i <= 0) return NULL;
  1210. psz = (LPSTR) CoTaskMemAlloc(i * sizeof(CHAR));
  1211. if (!psz) return NULL;
  1212. WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, i, NULL, NULL);
  1213. psz[i - 1] = 0;
  1214. return psz;
  1215. }
  1216. void MakePath(LPSTR lpPath)
  1217. {
  1218. LPSTR lpTmp;
  1219. lpTmp = CharPrev( lpPath, lpPath+lstrlen(lpPath));
  1220. // chop filename off
  1221. //
  1222. while ( (lpTmp > lpPath) && *lpTmp && (*lpTmp != '\\') )
  1223. lpTmp = CharPrev( lpPath, lpTmp );
  1224. if ( *CharPrev( lpPath, lpTmp ) != ':' )
  1225. *lpTmp = '\0';
  1226. else
  1227. *CharNext( lpTmp ) = '\0';
  1228. return;
  1229. }
  1230. void LogTimeDate()
  1231. {
  1232. SYSTEMTIME SystemTime;
  1233. GetLocalTime(&SystemTime);
  1234. WriteToLog("Date:%1!d!/%2!d!/%3!d! (M/D/Y) Time:%4!d!:%5!d!:%6!d!\r\n",
  1235. SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,
  1236. SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
  1237. }
  1238. HRESULT MyRunSetupCommand(HWND hwnd, LPCSTR lpszInfFile, LPCSTR lpszSection, DWORD dwFlags)
  1239. {
  1240. HRESULT hr = E_FAIL;
  1241. char szSourceDir[MAX_PATH];
  1242. lstrcpy(szSourceDir, lpszInfFile);
  1243. GetParentDir(szSourceDir);
  1244. WriteToLog("Run setup command. File:%1: Section:%2:\r\n",lpszInfFile, lpszSection);
  1245. dwFlags |= (RSC_FLAG_INF | RSC_FLAG_NGCONV | RSC_FLAG_QUIET);
  1246. hr = RunSetupCommand(hwnd, lpszInfFile, lpszSection, szSourceDir, NULL, NULL, dwFlags, NULL);
  1247. WriteToLog("RunSetupCommand returned :%1!lx!:\r\n", hr);
  1248. if (!SUCCEEDED(hr))
  1249. WriteToLog("\r\nERROR - RunSetupCommand failed\r\n\r\n");
  1250. return hr;
  1251. }
  1252. void uiCenterDialog( HWND hwndDlg )
  1253. {
  1254. RECT rc;
  1255. RECT rcScreen;
  1256. int x, y;
  1257. int cxDlg, cyDlg;
  1258. int cxScreen;
  1259. int cyScreen;
  1260. SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0);
  1261. cxScreen = rcScreen.right - rcScreen.left;
  1262. cyScreen = rcScreen.bottom - rcScreen.top;
  1263. GetWindowRect(hwndDlg,&rc);
  1264. x = rc.left; // Default is to leave the dialog where the template
  1265. y = rc.top; // was going to place it.
  1266. cxDlg = rc.right - rc.left;
  1267. cyDlg = rc.bottom - rc.top;
  1268. y = rcScreen.top + ((cyScreen - cyDlg) / 2);
  1269. x = rcScreen.left + ((cxScreen - cxDlg) / 2);
  1270. // Position the dialog.
  1271. //
  1272. SetWindowPos(hwndDlg, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  1273. }
  1274. BOOL MyNTReboot()
  1275. {
  1276. HANDLE hToken;
  1277. TOKEN_PRIVILEGES tkp;
  1278. // get a token from this process
  1279. if ( !OpenProcessToken( GetCurrentProcess(),
  1280. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
  1281. {
  1282. return FALSE;
  1283. }
  1284. // get the LUID for the shutdown privilege
  1285. LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid );
  1286. tkp.PrivilegeCount = 1;
  1287. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1288. //get the shutdown privilege for this proces
  1289. if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
  1290. {
  1291. return FALSE;
  1292. }
  1293. // shutdown the system and force all applications to close
  1294. if (!ExitWindowsEx( EWX_REBOOT, 0 ) )
  1295. {
  1296. return FALSE;
  1297. }
  1298. return TRUE;
  1299. }
  1300. HRESULT LaunchProcess(LPCSTR pszCmd, HANDLE *phProc, LPCSTR pszDir, UINT uShow)
  1301. {
  1302. STARTUPINFO startInfo;
  1303. PROCESS_INFORMATION processInfo;
  1304. HRESULT hr = S_OK;
  1305. BOOL fRet;
  1306. if(phProc)
  1307. *phProc = NULL;
  1308. // Create process on pszCmd
  1309. ZeroMemory(&startInfo, sizeof(startInfo));
  1310. startInfo.cb = sizeof(startInfo);
  1311. startInfo.dwFlags |= STARTF_USESHOWWINDOW;
  1312. startInfo.wShowWindow = (USHORT)uShow;
  1313. fRet = CreateProcess(NULL, (LPSTR) pszCmd, NULL, NULL, FALSE,
  1314. NORMAL_PRIORITY_CLASS, NULL, pszDir, &startInfo, &processInfo);
  1315. if(!fRet)
  1316. return E_FAIL;
  1317. if(phProc)
  1318. *phProc = processInfo.hProcess;
  1319. else
  1320. CloseHandle(processInfo.hProcess);
  1321. CloseHandle(processInfo.hThread);
  1322. return S_OK;
  1323. }
  1324. #define SOFTBOOT_CMDLINE "softboot.exe /s:,60"
  1325. // Display a dialog asking the user to restart Windows, with a button that
  1326. // will do it for them if possible.
  1327. //
  1328. BOOL MyRestartDialog(HWND hParent, BOOL bShowPrompt, UINT nIdMessage)
  1329. {
  1330. char szBuf[MAX_STRING];
  1331. char szTitle[MAX_STRING];
  1332. UINT id = IDYES;
  1333. if(bShowPrompt)
  1334. {
  1335. LoadSz(IDS_TITLE, szTitle, sizeof(szTitle));
  1336. LoadSz(nIdMessage, szBuf, sizeof(szBuf));
  1337. id = MessageBox(hParent, szBuf, szTitle, MB_ICONQUESTION | MB_YESNO | MB_TASKMODAL | MB_SETFOREGROUND);
  1338. }
  1339. if ( id == IDYES )
  1340. {
  1341. // path to softboot plus a little slop for the command line
  1342. char szBuf[MAX_PATH + 10];
  1343. szBuf[0] = 0;
  1344. GetSystemDirectory(szBuf, sizeof(szBuf));
  1345. AddPath(szBuf, SOFTBOOT_CMDLINE);
  1346. if(FAILED(LaunchProcess(szBuf, NULL, NULL, SW_SHOWNORMAL)))
  1347. {
  1348. if(g_bRunningWin95)
  1349. {
  1350. ExitWindowsEx( EWX_REBOOT , 0 );
  1351. }
  1352. else
  1353. {
  1354. MyNTReboot();
  1355. }
  1356. }
  1357. }
  1358. return (id == IDYES);
  1359. }
  1360. int LoadSz(UINT id, LPSTR pszBuf, UINT cMaxSize)
  1361. {
  1362. if(cMaxSize == 0)
  1363. return 0;
  1364. pszBuf[0] = 0;
  1365. return LoadString(g_hInstance, id, pszBuf, cMaxSize);
  1366. }
  1367. DWORD GetStringField(LPSTR szStr, UINT uField, LPSTR szBuf, UINT cBufSize)
  1368. {
  1369. LPSTR pszBegin = szStr;
  1370. LPSTR pszEnd;
  1371. UINT i = 0;
  1372. DWORD dwToCopy;
  1373. if(cBufSize == 0)
  1374. return 0;
  1375. szBuf[0] = 0;
  1376. if(szStr == NULL)
  1377. return 0;
  1378. while(*pszBegin != 0 && i < uField)
  1379. {
  1380. pszBegin = FindChar(pszBegin, ',');
  1381. if(*pszBegin != 0)
  1382. pszBegin++;
  1383. i++;
  1384. }
  1385. // we reached end of string, no field
  1386. if(*pszBegin == 0)
  1387. {
  1388. return 0;
  1389. }
  1390. pszEnd = FindChar(pszBegin, ',');
  1391. while(pszBegin <= pszEnd && *pszBegin == ' ')
  1392. pszBegin++;
  1393. while(pszEnd > pszBegin && *(pszEnd - 1) == ' ')
  1394. pszEnd--;
  1395. if(pszEnd > (pszBegin + 1) && *pszBegin == '"' && *(pszEnd-1) == '"')
  1396. {
  1397. pszBegin++;
  1398. pszEnd--;
  1399. }
  1400. dwToCopy = (DWORD)(pszEnd - pszBegin + 1);
  1401. if(dwToCopy > cBufSize)
  1402. dwToCopy = cBufSize;
  1403. lstrcpynA(szBuf, pszBegin, dwToCopy);
  1404. return dwToCopy - 1;
  1405. }
  1406. LPSTR FindChar(LPSTR pszStr, char ch)
  1407. {
  1408. while( *pszStr != 0 && *pszStr != ch )
  1409. pszStr++;
  1410. return pszStr;
  1411. }
  1412. int DisplayMessage(char* pszMessage, UINT uStyle)
  1413. {
  1414. int iReturn = 0;
  1415. if (!g_bQuiet)
  1416. {
  1417. char szTitle[MAX_STRING];
  1418. LoadSz(IDS_TITLE, szTitle, sizeof(szTitle));
  1419. iReturn = MessageBox(g_hWnd, pszMessage, szTitle, uStyle);
  1420. }
  1421. return iReturn;
  1422. }