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.

1740 lines
42 KiB

  1. //=--------------------------------------------------------------------------=
  2. // inseng.cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. //
  7. #include "inspch.h"
  8. #include "regstr.h"
  9. #include "globals.h"
  10. #include "insobj.h"
  11. #include "resource.h"
  12. #include "diskspac.h"
  13. #define GRPCONV "grpconv -o"
  14. #define BUFFERSIZE 4096
  15. //=--------------------------------------------------------------------------=
  16. // Function name here
  17. //=--------------------------------------------------------------------------=
  18. // Function description
  19. //
  20. // Parameters:
  21. //
  22. // Returns:
  23. //
  24. // Notes:
  25. //
  26. CInstallEngine::CInstallEngine(IUnknown **punk)
  27. {
  28. DWORD dwThreadID;
  29. HANDLE hThread;
  30. HKEY hKey = NULL;
  31. char szBuf[16];
  32. DWORD dwType;
  33. GetWindowsDirectory(g_szWindowsDir, sizeof(g_szWindowsDir));
  34. if(g_szWindowsDir[0] >= 'a' && g_szWindowsDir[0] <= 'z')
  35. g_szWindowsDir[0] -= 32;
  36. hThread = CreateThread(NULL, 0, CleanUpAllDirs, NULL, 0, &dwThreadID);
  37. CloseHandle(hThread);
  38. _chInsDrive = g_szWindowsDir[0];
  39. // Decide whether we are in stepping mode or not
  40. _uCommandMode = 0;
  41. _fSteppingMode = FALSE;
  42. _fResetTrust = TRUE;
  43. _fIgnoreTrust = FALSE;
  44. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, ACTIVESETUP_KEY,0, KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS)
  45. {
  46. // Get Steeping mode value. OK if not present
  47. DWORD dwSize = sizeof(szBuf);
  48. if(RegQueryValueEx(hKey, STEPPING_VALUE, NULL, &dwType, (LPBYTE) szBuf, &dwSize) == ERROR_SUCCESS)
  49. {
  50. if(szBuf[0] == 'y' || szBuf[0] == 'Y')
  51. _fSteppingMode = TRUE;
  52. }
  53. // Get CommandMode value. OK if not present
  54. dwSize = sizeof(szBuf);
  55. if(RegQueryValueEx(hKey, COMMAND_VALUE, NULL, &dwType, (LPBYTE) szBuf, &dwSize) == ERROR_SUCCESS)
  56. {
  57. _uCommandMode = AtoL(szBuf);
  58. // Once we read it, set it to zero
  59. // BUGBUG: beware of hardcoded "0" and 2 below (2 includes null terminator)
  60. RegSetValueEx(hKey, COMMAND_VALUE, 0, REG_SZ, (BYTE *) "0", 2 );
  61. }
  62. if(RegQueryValueEx(hKey, CHECKTRUST_VALUE, NULL, &dwType, (LPBYTE) szBuf, &dwSize) == ERROR_SUCCESS)
  63. {
  64. if(szBuf[0] == 'Y' || szBuf[0] == 'y')
  65. {
  66. _fIgnoreTrust = TRUE;
  67. _fResetTrust = FALSE;
  68. }
  69. // Once we read it, set it to zero
  70. // BUGBUG: beware of hardcoded "0" and 2 below (2 includes null terminator)
  71. RegDeleteValue(hKey, CHECKTRUST_VALUE);
  72. }
  73. RegCloseKey(hKey);
  74. }
  75. _hwndForUI = NULL;
  76. _pStmLog = NULL;
  77. _fIgnoreDownloadError = FALSE;
  78. _enginestatus = ENGINESTATUS_NOTREADY;
  79. _dwStatus = 0;
  80. _pcb = NULL;
  81. _cRef = 0;
  82. _dwDLRemaining = 0;
  83. _dwInstallRemaining = 0;
  84. _dwInstallOld = 0;
  85. _dwDLOld = 0;
  86. _fUseCache = FALSE;
  87. _dwInstallOptions = INSTALLOPTIONS_DOWNLOAD | INSTALLOPTIONS_INSTALL;
  88. _hContinue = NULL;
  89. _hAbort = NULL;
  90. _fCleanUpDir = FALSE;
  91. //init CCifFile
  92. _pCif = new CCifFile();
  93. _pCif->AddRef();
  94. _pCif->SetInstallEngine(this);
  95. // init downloader
  96. _pDL = new CDownloader();
  97. _pIns = new CInstaller(this);
  98. _szBaseUrl[0] = 0;
  99. _fSRLiteAvailable = IsPatchableIEVersion() && IsCorrectAdvpExt() && InitSRLiteLibs();
  100. if (!_fSRLiteAvailable)
  101. WriteToLog("Install engine failed to initialize the advpack extension DLL\r\n", FALSE);
  102. _pPDL = new CPatchDownloader(_fSRLiteAvailable);
  103. AddRef();
  104. *punk = (IInstallEngine *) this;
  105. }
  106. //=--------------------------------------------------------------------------=
  107. // CInstallEngine::~CInstallEngine
  108. //=--------------------------------------------------------------------------=
  109. // Destructor for InstallEngine class
  110. //
  111. // Parameters:
  112. //
  113. // Returns:
  114. //
  115. // Notes:
  116. //
  117. CInstallEngine::~CInstallEngine()
  118. {
  119. char szBuf[MAX_PATH];
  120. WriteToLog("Install Engine - object destroyed\r\n", TRUE);
  121. if(_fCleanUpDir)
  122. {
  123. lstrcpy(szBuf, _pCif->GetDownloadDir());
  124. }
  125. if(_hAbort)
  126. CloseHandle(_hAbort);
  127. if(_hContinue)
  128. CloseHandle(_hContinue);
  129. if(_pStmLog)
  130. _pStmLog->Release();
  131. _pcb = NULL;
  132. _pCif->Release();
  133. _pDL->Release();
  134. delete _pPDL;
  135. _pIns->Release();
  136. if(_fCleanUpDir)
  137. {
  138. CleanUpTempDir(szBuf);
  139. }
  140. FreeSRLiteLibs();
  141. DllRelease();
  142. }
  143. //************ IUnknown implementation ***************
  144. //=--------------------------------------------------------------------------=
  145. // Function name here
  146. //=--------------------------------------------------------------------------=
  147. // Function description
  148. //
  149. // Parameters:
  150. //
  151. // Returns:
  152. //
  153. // Notes:
  154. //
  155. STDMETHODIMP_(ULONG) CInstallEngine::AddRef()
  156. {
  157. return(_cRef++);
  158. }
  159. //=--------------------------------------------------------------------------=
  160. // Function name here
  161. //=--------------------------------------------------------------------------=
  162. // Function description
  163. //
  164. // Parameters:
  165. //
  166. // Returns:
  167. //
  168. // Notes:
  169. //
  170. STDMETHODIMP_(ULONG) CInstallEngine::Release()
  171. {
  172. ULONG temp = --_cRef;
  173. if(temp == 0)
  174. delete this;
  175. return temp;
  176. }
  177. //=--------------------------------------------------------------------------=
  178. // Function name here
  179. //=--------------------------------------------------------------------------=
  180. // Function description
  181. //
  182. // Parameters:
  183. //
  184. // Returns:
  185. //
  186. // Notes:
  187. //
  188. STDMETHODIMP CInstallEngine::QueryInterface(REFIID riid, void **ppv)
  189. {
  190. *ppv = NULL;
  191. if((riid == IID_IUnknown) || (riid == IID_IInstallEngine))
  192. *ppv = (IInstallEngine *)this;
  193. else if(riid == IID_IInstallEngineTiming)
  194. *ppv = (IInstallEngineTiming *)this;
  195. else if(riid == IID_IInstallEngine2)
  196. *ppv = (IInstallEngine2 *)this;
  197. if(*ppv == NULL)
  198. return E_NOINTERFACE;
  199. AddRef();
  200. return NOERROR;
  201. }
  202. //************* IInstallEngine interface ************
  203. //=--------------------------------------------------------------------------=
  204. // Function name here
  205. //=--------------------------------------------------------------------------=
  206. // Function description
  207. //
  208. // Parameters:
  209. //
  210. // Returns:
  211. //
  212. // Notes:
  213. //
  214. STDMETHODIMP CInstallEngine::SetLocalCif(LPCSTR pszCifPath)
  215. {
  216. HCURSOR hNew = NULL;
  217. HCURSOR hOld = NULL;
  218. OnEngineStatusChange(ENGINESTATUS_LOADING, 0);
  219. hNew = LoadCursor(NULL, IDC_WAIT);
  220. hOld = SetCursor(hNew);
  221. HRESULT hr = _pCif->SetCifFile(pszCifPath, FALSE);
  222. if(SUCCEEDED(hr))
  223. OnEngineStatusChange(ENGINESTATUS_READY, 0);
  224. else
  225. OnEngineStatusChange(ENGINESTATUS_NOTREADY, hr);
  226. SetCursor(hOld);
  227. return hr;
  228. }
  229. STDMETHODIMP CInstallEngine::GetICifFile(ICifFile **pic)
  230. {
  231. *pic = (ICifFile *) _pCif;
  232. (*pic)->AddRef();
  233. return NOERROR;
  234. }
  235. STDMETHODIMP CInstallEngine::GetEngineStatus(DWORD * theenginestatus)
  236. {
  237. *theenginestatus = _enginestatus;
  238. return(NOERROR);
  239. }
  240. //=--------------------------------------------------------------------------=
  241. // Function name here
  242. //=--------------------------------------------------------------------------=
  243. // Function description
  244. //
  245. // Parameters:
  246. //
  247. // Returns:
  248. //
  249. // Notes:
  250. //
  251. STDMETHODIMP CInstallEngine::Abort(DWORD lFlag)
  252. {
  253. // If we are NOT downLOADING or INSTALLING, an abort command makes no sense.
  254. if( !(_enginestatus == ENGINESTATUS_INSTALLING || _enginestatus == ENGINESTATUS_LOADING) )
  255. return E_UNEXPECTED;
  256. // if we are downloading, this will cause the abort to filter thru
  257. _pDL->Abort();
  258. // this will abort an install if possible
  259. _pIns->Abort();
  260. // any other time, we will pick this up just as soon as we can
  261. SetEvent(_hAbort);
  262. WriteToLog("Install Engine - Abort called\r\n", FALSE);
  263. return(NOERROR);
  264. }
  265. //=--------------------------------------------------------------------------=
  266. // Function name here
  267. //=--------------------------------------------------------------------------=
  268. // Function description
  269. //
  270. // Parameters:
  271. //
  272. // Returns:
  273. //
  274. // Notes:
  275. //
  276. STDMETHODIMP CInstallEngine::Suspend()
  277. {
  278. HRESULT hr;
  279. if(_enginestatus != ENGINESTATUS_INSTALLING)
  280. return E_UNEXPECTED;
  281. WriteToLog("Install Engine - Suspend called\r\n", FALSE);
  282. _pDL->Suspend();
  283. // we only catch suspend return, because it tells us "zsafe to cancel or not"
  284. hr = _pIns->Suspend();
  285. ResetEvent(_hContinue);
  286. // If we cant create the resume event, we will fail this call and not pause
  287. return hr;
  288. }
  289. //=--------------------------------------------------------------------------=
  290. // Function name here
  291. //=--------------------------------------------------------------------------=
  292. // Function description
  293. //
  294. // Parameters:
  295. //
  296. // Returns:
  297. //
  298. // Notes:
  299. //
  300. STDMETHODIMP CInstallEngine::Resume()
  301. {
  302. if(_enginestatus != ENGINESTATUS_INSTALLING)
  303. return E_UNEXPECTED;
  304. WriteToLog("Install Engine - Resume called\r\n", FALSE);
  305. _pDL->Resume();
  306. _pIns->Resume();
  307. SetEvent(_hContinue);
  308. return NOERROR;
  309. }
  310. //=--------------------------------------------------------------------------=
  311. // Function name here
  312. //=--------------------------------------------------------------------------=
  313. // Function description
  314. //
  315. // Parameters:
  316. //
  317. // Returns:
  318. //
  319. // Notes:
  320. //
  321. STDMETHODIMP CInstallEngine::SetCifFile(LPCSTR pszCabName, LPCSTR pszCifName)
  322. {
  323. HRESULT hr = NOERROR;
  324. HANDLE hThread;
  325. DWORD dwThreadID;
  326. if(_enginestatus == ENGINESTATUS_LOADING || _enginestatus == ENGINESTATUS_INSTALLING)
  327. return E_UNEXPECTED;
  328. SETCIFARGS *p = new SETCIFARGS;
  329. if (p == NULL)
  330. {
  331. hr = E_OUTOFMEMORY;
  332. goto Cleanup;
  333. }
  334. if(_szBaseUrl[0] != 0)
  335. {
  336. if (lstrlen(_szBaseUrl) + lstrlen(pszCabName) + 2 > INTERNET_MAX_URL_LENGTH)
  337. {
  338. hr = E_INVALIDARG;
  339. goto Cleanup;
  340. }
  341. p->szUrl[0] = '\0';
  342. lstrcpy(p->szUrl, _szBaseUrl);
  343. lstrcat(p->szUrl, "/");
  344. lstrcat(p->szUrl, pszCabName);
  345. }
  346. else
  347. {
  348. lstrcpy(p->szUrl, "file://");
  349. lstrcat(p->szUrl, _pCif->GetDownloadDir());
  350. SafeAddPath(p->szUrl, pszCabName, sizeof(p->szUrl));
  351. }
  352. lstrcpyn(p->szCif, pszCifName, MAX_PATH);
  353. p->pCif = _pCif;
  354. // do the actual downloading of the CIF file in a separate thread
  355. if ((hThread = CreateThread(NULL, 0, DownloadCifFile, (LPVOID) p, 0, &dwThreadID)) != NULL)
  356. CloseHandle(hThread);
  357. else
  358. {
  359. hr = HRESULT_FROM_WIN32(GetLastError());
  360. }
  361. Cleanup:
  362. if (FAILED(hr) && p != NULL)
  363. delete p;
  364. return hr;
  365. }
  366. //=--------------------------------------------------------------------------=
  367. // Function name here
  368. //=--------------------------------------------------------------------------=
  369. // Function description
  370. //
  371. // Parameters:
  372. //
  373. // Returns:
  374. //
  375. // Notes:
  376. //
  377. STDMETHODIMP CInstallEngine::SetBaseUrl(LPCSTR pszBaseName)
  378. {
  379. DWORD dwLen;
  380. if(_enginestatus == ENGINESTATUS_INSTALLING)
  381. if(!_IsValidBaseUrl(pszBaseName))
  382. return E_UNEXPECTED;
  383. lstrcpyn(_szBaseUrl, pszBaseName, INTERNET_MAX_URL_LENGTH);
  384. wsprintf(szLogBuf,"Install Engine - base url set to %s\r\n", pszBaseName);
  385. WriteToLog(szLogBuf, FALSE);
  386. return NOERROR;
  387. }
  388. //=--------------------------------------------------------------------------=
  389. // Function name here
  390. //=--------------------------------------------------------------------------=
  391. // Function description
  392. //
  393. // Parameters:
  394. //
  395. // Returns:
  396. //
  397. // Notes:
  398. //
  399. STDMETHODIMP CInstallEngine::SetDownloadDir(LPCSTR pszDLDir)
  400. {
  401. char szBuf[MAX_PATH];
  402. DWORD dwLen;
  403. DWORD dwVer;
  404. if(_enginestatus == ENGINESTATUS_INSTALLING)
  405. return E_UNEXPECTED;
  406. if(pszDLDir != NULL && lstrlen(pszDLDir) > (MAX_PATH - 20))
  407. return E_FAIL;
  408. // clean up what we have
  409. if(_fCleanUpDir)
  410. {
  411. DelNode(_pCif->GetDownloadDir(), 0);
  412. _fCleanUpDir = FALSE;
  413. }
  414. if(pszDLDir == NULL)
  415. {
  416. _fCleanUpDir = TRUE;
  417. if(FAILED(CreateTempDirOnMaxDrive(szBuf, sizeof(szBuf))))
  418. return E_FAIL;
  419. }
  420. else
  421. {
  422. _fCleanUpDir = FALSE;
  423. // Make sure the directory exists
  424. if(GetFileAttributes(pszDLDir) == 0xffffffff)
  425. CreateDirectory(pszDLDir, NULL);
  426. }
  427. _pCif->SetDownloadDir(pszDLDir ? pszDLDir : szBuf);
  428. wsprintf(szLogBuf,"Install Engine - download directory set to %s\r\n", _pCif->GetDownloadDir());
  429. WriteToLog(szLogBuf, FALSE);
  430. return NOERROR;
  431. }
  432. //=--------------------------------------------------------------------------=
  433. // Function name here
  434. //=--------------------------------------------------------------------------=
  435. // Function description
  436. //
  437. // Parameters:
  438. //
  439. // Returns:
  440. //
  441. // Notes:
  442. //
  443. STDMETHODIMP CInstallEngine::IsComponentInstalled(LPCSTR pszComponentID, DWORD *lResult)
  444. {
  445. DWORD dwResult = ICI_NOTINSTALLED;
  446. ICifComponent *pComp = NULL;
  447. if(SUCCEEDED(_pCif->FindComponent(pszComponentID, &pComp)))
  448. {
  449. dwResult = pComp->IsComponentInstalled();
  450. }
  451. *lResult = dwResult;
  452. return(pComp ? NOERROR : E_INVALIDARG);
  453. }
  454. STDMETHODIMP CInstallEngine::SetInstallDrive(CHAR chDrive)
  455. {
  456. HRESULT hr = E_INVALIDARG;
  457. if(chDrive >= 'a' && chDrive <= 'z')
  458. chDrive -= 32;
  459. if(chDrive >= 'A' && chDrive <= 'Z')
  460. {
  461. hr = NOERROR;
  462. _chInsDrive = chDrive;
  463. }
  464. return hr;
  465. }
  466. //=---------------------------------------------------------------------------=
  467. // Function name here
  468. //=---------------------------------------------------------------------------=
  469. // Function description
  470. //
  471. // Parameters
  472. //
  473. // Returns:
  474. //
  475. // Notes:
  476. //
  477. STDMETHODIMP CInstallEngine::SetInstallOptions(DWORD dwOptions)
  478. {
  479. _fUseCache = !(dwOptions & INSTALLOPTIONS_NOCACHE);
  480. _dwInstallOptions = dwOptions;
  481. return NOERROR;
  482. }
  483. //=---------------------------------------------------------------------------=
  484. // Function name here
  485. //=---------------------------------------------------------------------------=
  486. // Function description
  487. //
  488. // Parameters
  489. //
  490. // Returns:
  491. //
  492. // Notes:
  493. //
  494. STDMETHODIMP CInstallEngine::GetInstallOptions(DWORD *pdwOptions)
  495. {
  496. if (!pdwOptions)
  497. return E_POINTER;
  498. else
  499. {
  500. *pdwOptions = _dwInstallOptions;
  501. return NOERROR;
  502. }
  503. }
  504. //=---------------------------------------------------------------------------=
  505. // Function name here
  506. //=---------------------------------------------------------------------------=
  507. // Function description
  508. //
  509. // Parameters
  510. //
  511. // Returns:
  512. //
  513. // Notes:
  514. //
  515. STDMETHODIMP CInstallEngine::GetSizes(LPCSTR pszID, COMPONENT_SIZES *p)
  516. {
  517. if(!p)
  518. return E_POINTER;
  519. // work around bug in old versions of jobexec where it didn't init
  520. // this field properly
  521. if(p->cbSize > sizeof(COMPONENT_SIZES))
  522. p->cbSize = COMPONENTSIZES_SIZE_V1;
  523. DWORD dwSize = p->cbSize;
  524. ZeroMemory(p, p->cbSize);
  525. p->cbSize = dwSize;
  526. if(_enginestatus != ENGINESTATUS_READY)
  527. return E_UNEXPECTED;
  528. if(pszID != NULL)
  529. {
  530. ICifComponent *pComp = NULL;
  531. if(SUCCEEDED(_pCif->FindComponent(pszID, &pComp)))
  532. {
  533. DWORD dwWin, dwApp;
  534. p->dwDownloadSize = pComp->GetDownloadSize();
  535. pComp->GetInstalledSize(&dwWin, &dwApp);
  536. p->dwInstallSize = dwApp;
  537. p->dwWinDriveSize = dwWin;
  538. }
  539. else
  540. return E_INVALIDARG;
  541. }
  542. else
  543. _GetTotalSizes(p);
  544. return NOERROR;
  545. }
  546. //=---------------------------------------------------------------------------=
  547. // Function name here
  548. //=---------------------------------------------------------------------------=
  549. // Function description
  550. //
  551. // Parameters
  552. //
  553. // Returns:
  554. //
  555. // Notes:
  556. //
  557. void CInstallEngine::_GetTotalSizes(COMPONENT_SIZES *pSizes)
  558. {
  559. ICifComponent *pComp;
  560. DriveInfo drvinfo[3];
  561. LPSTR pszDep = NULL;
  562. UINT uTempDrive;
  563. UINT uWinDrive = 0;
  564. UINT uInstallDrive = 1;
  565. UINT uDownloadDrive = 2;
  566. LPCSTR pszDownloadDir = _pCif->GetDownloadDir();
  567. COMPONENT_SIZES Sizes;
  568. ZeroMemory(&Sizes, sizeof(COMPONENT_SIZES));
  569. // Fill in all arrays to start
  570. drvinfo[uWinDrive].InitDrive(g_szWindowsDir[0]);
  571. if(_dwInstallOptions & INSTALLOPTIONS_INSTALL)
  572. {
  573. // We know we can do a compare because these are always uppcase
  574. if(_chInsDrive != drvinfo[uWinDrive].Drive())
  575. {
  576. drvinfo[uInstallDrive].InitDrive(_chInsDrive);
  577. }
  578. else
  579. uInstallDrive = uWinDrive;
  580. }
  581. if(_dwInstallOptions & INSTALLOPTIONS_DOWNLOAD)
  582. {
  583. if(pszDownloadDir[0] == drvinfo[uWinDrive].Drive())
  584. uDownloadDrive = uWinDrive;
  585. else if(pszDownloadDir[0] == drvinfo[uInstallDrive].Drive())
  586. uDownloadDrive = uInstallDrive;
  587. else
  588. drvinfo[uDownloadDrive].InitDrive(pszDownloadDir[0]);
  589. }
  590. // do space for download phase (easy part)
  591. if(_dwInstallOptions & INSTALLOPTIONS_DOWNLOAD)
  592. {
  593. Sizes.dwDownloadSize = _GetActualDownloadSize(FALSE);
  594. Sizes.dwTotalDownloadSize = _GetTotalDownloadSize();
  595. Sizes.dwDependancySize = 0;
  596. // add download to download drive
  597. drvinfo[uDownloadDrive].UseSpace(Sizes.dwDownloadSize + Sizes.dwDependancySize, TRUE);
  598. // if going to cache
  599. // BUGBUG: we still assume cache is on windows drive
  600. if(_fUseCache)
  601. {
  602. drvinfo[uWinDrive].UseSpace(Sizes.dwDownloadSize + Sizes.dwDependancySize, TRUE);
  603. }
  604. }
  605. // do space for install (hard part)
  606. if(_dwInstallOptions & INSTALLOPTIONS_INSTALL)
  607. {
  608. // walk the install list in order (very important)
  609. // do any dependancy, then original
  610. IEnumCifComponents *penum;
  611. ICifComponent *pComp = NULL;
  612. _pCif->EnumComponents(&penum, 0, NULL);
  613. for(penum->Next(&pComp); pComp; penum->Next(&pComp))
  614. {
  615. if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
  616. {
  617. DWORD dwWin, dwApp;
  618. pComp->GetInstalledSize(&dwWin, &dwApp);
  619. // add install
  620. // add the install size
  621. Sizes.dwInstallSize += dwApp;
  622. // size that goes to windows dir
  623. Sizes.dwWinDriveSize += dwWin;
  624. drvinfo[uInstallDrive].UseSpace(dwApp, FALSE);
  625. drvinfo[uWinDrive].UseSpace(dwWin, FALSE);
  626. // Add (and then remove) temp space
  627. AddTempSpace(pComp->GetDownloadSize(), pComp->GetExtractSize(), drvinfo);
  628. }
  629. }
  630. penum->Release();
  631. }
  632. // fill in the required amounts
  633. Sizes.dwWinDriveReq = drvinfo[uWinDrive].MaxUsed();
  634. Sizes.chWinDrive = drvinfo[uWinDrive].Drive();
  635. if(uWinDrive != uInstallDrive)
  636. {
  637. Sizes.dwInstallDriveReq = drvinfo[uInstallDrive].MaxUsed();
  638. Sizes.chInstallDrive = drvinfo[uInstallDrive].Drive();
  639. }
  640. if((uDownloadDrive != uWinDrive) && (uDownloadDrive != uInstallDrive))
  641. {
  642. Sizes.dwDownloadDriveReq = drvinfo[uDownloadDrive].MaxUsed();
  643. Sizes.chDownloadDrive = drvinfo[uDownloadDrive].Drive();
  644. }
  645. CopyMemory((LPVOID)(&(pSizes->dwInstallSize)), (LPVOID)(&(Sizes.dwInstallSize)),
  646. pSizes->cbSize - sizeof(DWORD));
  647. }
  648. //=---------------------------------------------------------------------------=
  649. // Function name here
  650. //=---------------------------------------------------------------------------=
  651. // Function description
  652. //
  653. // Parameters
  654. //
  655. // Returns:
  656. //
  657. // Notes:
  658. //
  659. STDMETHODIMP CInstallEngine::SetAction(LPCSTR pszComponentID, DWORD action, DWORD dwPriority)
  660. {
  661. HRESULT hr = NOERROR;
  662. if(_enginestatus != ENGINESTATUS_READY)
  663. return E_UNEXPECTED;
  664. ICifComponent *pComp = NULL;
  665. if(pszComponentID == NULL || lstrlen(pszComponentID) == 0)
  666. {
  667. _pCif->ClearQueueState();
  668. }
  669. else
  670. {
  671. if(SUCCEEDED(_pCif->FindComponent(pszComponentID, &pComp)))
  672. {
  673. if(dwPriority != 0xffffffff)
  674. pComp->SetCurrentPriority(dwPriority);
  675. hr = pComp->SetInstallQueueState(action);
  676. }
  677. else
  678. hr = E_INVALIDARG;
  679. }
  680. return hr;
  681. }
  682. // the following two are now ridiculously inefficient. New clients should use the enumerators
  683. STDMETHODIMP CInstallEngine::EnumInstallIDs(UINT uIndex, LPSTR *ppszID)
  684. {
  685. HRESULT hr;
  686. UINT i = 0;
  687. *ppszID = NULL;
  688. IEnumCifComponents *penum;
  689. ICifComponent *pComp;
  690. _pCif->EnumComponents(&penum, 0, NULL);
  691. for(penum->Next(&pComp); pComp; penum->Next(&pComp))
  692. {
  693. if(pComp->GetInstallQueueState())
  694. {
  695. if(uIndex == i)
  696. break;
  697. i++;
  698. }
  699. }
  700. penum->Release();
  701. if(pComp)
  702. {
  703. char szID[MAX_ID_LENGTH];
  704. pComp->GetID(szID, sizeof(szID));
  705. *ppszID = COPYANSISTR(szID);
  706. hr = NOERROR;
  707. }
  708. else
  709. hr = E_FAIL;
  710. return hr;
  711. }
  712. STDMETHODIMP CInstallEngine::EnumDownloadIDs(UINT uIndex, LPSTR *ppszID)
  713. {
  714. HRESULT hr;
  715. UINT i = 0;
  716. *ppszID = NULL;
  717. IEnumCifComponents *penum;
  718. ICifComponent *pComp;
  719. _pCif->EnumComponents(&penum, 0, NULL);
  720. for(penum->Next(&pComp); pComp; penum->Next(&pComp))
  721. {
  722. if(pComp->GetInstallQueueState() && (pComp->IsComponentDownloaded() == S_FALSE))
  723. {
  724. if(uIndex == i)
  725. break;
  726. i++;
  727. }
  728. }
  729. penum->Release();
  730. if(pComp)
  731. {
  732. char szID[MAX_ID_LENGTH];
  733. pComp->GetID(szID, sizeof(szID));
  734. *ppszID = COPYANSISTR(szID);
  735. hr = NOERROR;
  736. }
  737. else
  738. hr = E_FAIL;
  739. return hr;
  740. }
  741. //=---------------------------------------------------------------------------=
  742. // Function name here
  743. //=---------------------------------------------------------------------------=
  744. // Function description
  745. //
  746. // Parameters
  747. //
  748. // Returns:
  749. //
  750. // Notes:
  751. //
  752. STDMETHODIMP CInstallEngine::DownloadComponents(DWORD lFlags)
  753. {
  754. DWORD dwThreadID;
  755. HRESULT hr = NOERROR;
  756. WriteToLog("Install Engine - Starting download phase\r\n", TRUE);
  757. if(_enginestatus == ENGINESTATUS_NOTREADY || _enginestatus == ENGINESTATUS_LOADING)
  758. hr = E_UNEXPECTED;
  759. // BUGBUG - add a downloading status? it really just a "busy" indication
  760. if(_enginestatus == ENGINESTATUS_INSTALLING)
  761. hr = E_PENDING;
  762. if(SUCCEEDED(hr))
  763. {
  764. OnEngineStatusChange(ENGINESTATUS_INSTALLING, 0);
  765. // since trust may be set globally, only turn it on, not off
  766. if(EXECUTEJOB_IGNORETRUST & lFlags)
  767. _fIgnoreTrust = TRUE;
  768. if(EXECUTEJOB_IGNOREDOWNLOADERROR & lFlags)
  769. _fIgnoreDownloadError = TRUE;
  770. else
  771. _fIgnoreDownloadError = FALSE;
  772. HANDLE h = CreateThread(NULL, 0, InitDownloader, this, 0, &dwThreadID);
  773. if(h == NULL)
  774. {
  775. // Won't be doing any downloading today.....
  776. hr = E_FAIL;
  777. }
  778. else
  779. CloseHandle(h);
  780. }
  781. return hr;
  782. }
  783. //=---------------------------------------------------------------------------=
  784. // Function name here
  785. //=---------------------------------------------------------------------------=
  786. // Function description
  787. //
  788. // Parameters
  789. //
  790. // Returns:
  791. //
  792. // Notes:
  793. //
  794. STDMETHODIMP CInstallEngine::InstallComponents(DWORD lFlags)
  795. {
  796. DWORD dwThreadID;
  797. HRESULT hr = NOERROR;
  798. WriteToLog("Install Engine - Starting install phase\r\n", TRUE);
  799. EnterCriticalSection(&g_cs);
  800. if(_enginestatus == ENGINESTATUS_NOTREADY || _enginestatus == ENGINESTATUS_LOADING)
  801. hr = E_UNEXPECTED;
  802. if(_enginestatus == ENGINESTATUS_INSTALLING)
  803. hr = E_PENDING;
  804. LeaveCriticalSection(&g_cs);
  805. if(SUCCEEDED(hr))
  806. {
  807. // We first check to see if all files are present
  808. // by seeing if we would download anything!!!
  809. //
  810. if(EXECUTEJOB_VERIFYFILES & lFlags)
  811. {
  812. WriteToLog("Checking for missing files\r\n", FALSE);
  813. if(_GetActualDownloadSize(TRUE) != 0)
  814. return E_FILESMISSING;
  815. }
  816. OnEngineStatusChange(ENGINESTATUS_INSTALLING, 0);
  817. // since trust may be set globally, only turn it on, not off
  818. if(EXECUTEJOB_IGNORETRUST & lFlags)
  819. _fIgnoreTrust = TRUE;
  820. HANDLE h = CreateThread(NULL, 0, InitInstaller, this, 0, &dwThreadID);
  821. if(h == NULL)
  822. {
  823. // Won't be doing any installing today.....
  824. hr = E_FAIL;
  825. }
  826. else
  827. CloseHandle(h);
  828. }
  829. return hr;
  830. }
  831. //=---------------------------------------------------------------------------=
  832. // Function name here
  833. //=---------------------------------------------------------------------------=
  834. // Function description
  835. //
  836. // Parameters
  837. //
  838. // Returns:
  839. //
  840. // Notes:
  841. //
  842. DWORD WINAPI InitInstaller(LPVOID pv)
  843. {
  844. CInstallEngine *pInsEng = (CInstallEngine *) pv;
  845. HRESULT hr = S_OK;
  846. BOOL fOneInstalled = FALSE;
  847. ICifComponent *pComp;
  848. EnableSage(FALSE);
  849. EnableScreenSaver(FALSE);
  850. EnableDiskCleaner(FALSE);
  851. pInsEng->_dwStatus = 0;
  852. pInsEng->_hAbort = CreateEvent(NULL, FALSE, FALSE, NULL);
  853. pInsEng->_hContinue = CreateEvent(NULL, TRUE, TRUE, NULL);
  854. //BUGBUG check for failure
  855. pInsEng->AddRef();
  856. pInsEng->OnStartInstall(0, pInsEng->_GetTotalInstallSize());
  857. // check trust the Cif cab if it has not been done so
  858. hr = pInsEng->CheckForContinue();
  859. // this is the install pass
  860. if(SUCCEEDED(hr))
  861. hr = pInsEng->_pCif->Install(&fOneInstalled);
  862. if(fOneInstalled && FNeedGrpConv())
  863. {
  864. if(!(pInsEng->GetStatus() & STOPINSTALL_REBOOTNEEDED))
  865. {
  866. // if we dont need a reboot launch grpconv immeadiatly
  867. HANDLE h = NULL;
  868. pInsEng->WriteToLog("Install Engine - No reboot required\r\n", FALSE);
  869. LaunchAndWait(GRPCONV, NULL, &h, NULL, SW_SHOWMINIMIZED);
  870. if(h)
  871. CloseHandle(h);
  872. }
  873. else
  874. {
  875. HKEY hKey;
  876. DWORD dumb;
  877. // otherwise put grpconv into runonce
  878. if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUNONCE,
  879. 0,0,0, KEY_SET_VALUE, NULL, &hKey, &dumb) == ERROR_SUCCESS)
  880. {
  881. RegSetValueEx(hKey, "GrpConv", 0, REG_SZ,
  882. (BYTE *) GRPCONV, sizeof(GRPCONV));
  883. RegCloseKey(hKey);
  884. }
  885. }
  886. }
  887. // reset to checking trust
  888. if(pInsEng->_fResetTrust)
  889. pInsEng->_fIgnoreTrust = FALSE;
  890. // Send a install all done message
  891. if(!(pInsEng->GetStatus() & STOPINSTALL_REBOOTNEEDED))
  892. {
  893. // If we don't need a reboot, enable the screen saver and sage.
  894. EnableScreenSaver(TRUE);
  895. EnableSage(TRUE);
  896. }
  897. EnableDiskCleaner(TRUE);
  898. CloseHandle(pInsEng->_hAbort);
  899. pInsEng->_hAbort = NULL;
  900. CloseHandle(pInsEng->_hContinue);
  901. pInsEng->_hContinue = NULL;
  902. pInsEng->OnStopInstall(hr, NULL, pInsEng->GetStatus());
  903. pInsEng->OnEngineStatusChange(ENGINESTATUS_READY, 0);
  904. pInsEng->Release();
  905. return 0;
  906. }
  907. //=---------------------------------------------------------------------------=
  908. // Function name here
  909. //=---------------------------------------------------------------------------=
  910. // Function description
  911. //
  912. // Parameters
  913. //
  914. // Returns:
  915. //
  916. // Notes:
  917. //
  918. DWORD WINAPI InitDownloader(LPVOID pv)
  919. {
  920. CInstallEngine *pInsEng = (CInstallEngine *) pv;
  921. HRESULT hr = S_OK;
  922. EnableSage(FALSE);
  923. EnableScreenSaver(FALSE);
  924. EnableDiskCleaner(FALSE);
  925. pInsEng->_hAbort = CreateEvent(NULL, FALSE, FALSE, NULL);
  926. pInsEng->_hContinue = CreateEvent(NULL, TRUE, TRUE, NULL);
  927. //BUGBUG check for failure
  928. pInsEng->AddRef();
  929. pInsEng->OnStartInstall(pInsEng->_GetActualDownloadSize(FALSE), 0);
  930. // check trust the Cif cab if it has not been done so
  931. hr = pInsEng->CheckForContinue();
  932. // this is the download pass
  933. if(SUCCEEDED(hr))
  934. {
  935. hr = pInsEng->_pCif->Download();
  936. }
  937. if(SUCCEEDED(hr))
  938. {
  939. pInsEng->WriteToLog("Install Engine - Download complete\r\n", FALSE);
  940. }
  941. // reset to checking trust
  942. if(pInsEng->_fResetTrust)
  943. pInsEng->_fIgnoreTrust = FALSE;
  944. CloseHandle(pInsEng->_hAbort);
  945. pInsEng->_hAbort = NULL;
  946. CloseHandle(pInsEng->_hContinue);
  947. pInsEng->_hContinue = NULL;
  948. EnableScreenSaver(TRUE);
  949. EnableSage(TRUE);
  950. EnableDiskCleaner(TRUE);
  951. // Send a install all done message
  952. EnterCriticalSection(&g_cs);
  953. pInsEng->OnStopInstall(hr, NULL, 0);
  954. pInsEng->OnEngineStatusChange(ENGINESTATUS_READY, 0);
  955. LeaveCriticalSection(&g_cs);
  956. pInsEng->Release();
  957. return 0;
  958. }
  959. //=---------------------------------------------------------------------------=
  960. // Function name here
  961. //=---------------------------------------------------------------------------=
  962. // Function description
  963. //
  964. // Parameters
  965. //
  966. // Returns:
  967. //
  968. // Notes:
  969. //
  970. DWORD CInstallEngine::_GetTotalDownloadSize()
  971. {
  972. DWORD dwTotalSize = 0;
  973. IEnumCifComponents *penum;
  974. ICifComponent *pComp = NULL;
  975. _pCif->EnumComponents(&penum, 0, NULL);
  976. for(penum->Next(&pComp); pComp; penum->Next(&pComp))
  977. {
  978. if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
  979. dwTotalSize += pComp->GetDownloadSize();
  980. }
  981. penum->Release();
  982. return dwTotalSize;
  983. }
  984. //=---------------------------------------------------------------------------=
  985. // Function name here
  986. //=---------------------------------------------------------------------------=
  987. // Function description
  988. //
  989. // Parameters
  990. //
  991. // Returns:
  992. //
  993. // Notes:
  994. //
  995. DWORD CInstallEngine::_GetActualDownloadSize(BOOL bLogMissing)
  996. {
  997. DWORD dwTotalSize = 0;
  998. IEnumCifComponents *penum;
  999. ICifComponent *pComp = NULL;
  1000. _pCif->EnumComponents(&penum, 0, NULL);
  1001. for( penum->Next(&pComp); pComp; penum->Next(&pComp))
  1002. {
  1003. if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
  1004. dwTotalSize += pComp->GetActualDownloadSize();
  1005. }
  1006. penum->Release();
  1007. return dwTotalSize;
  1008. }
  1009. //=---------------------------------------------------------------------------=
  1010. // Function name here
  1011. //=---------------------------------------------------------------------------=
  1012. // Function description
  1013. //
  1014. // Parameters
  1015. //
  1016. // Returns:
  1017. //
  1018. // Notes:
  1019. //
  1020. DWORD CInstallEngine::_GetTotalInstallSize()
  1021. {
  1022. DWORD dwTotalSize = 0;
  1023. DWORD dwWin, dwApp;
  1024. IEnumCifComponents *penum;
  1025. ICifComponent *pComp = NULL;
  1026. _pCif->EnumComponents(&penum, 0, NULL);
  1027. for(penum->Next(&pComp); pComp; penum->Next(&pComp))
  1028. {
  1029. if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
  1030. {
  1031. pComp->GetInstalledSize(&dwWin, &dwApp);
  1032. dwTotalSize += (dwWin + dwApp);
  1033. }
  1034. }
  1035. penum->Release();
  1036. return dwTotalSize;
  1037. }
  1038. //=---------------------------------------------------------------------------=
  1039. // Function name here
  1040. //=---------------------------------------------------------------------------=
  1041. // Function description
  1042. //
  1043. // Parameters
  1044. //
  1045. // Returns:
  1046. //
  1047. // Notes:
  1048. //
  1049. STDMETHODIMP CInstallEngine::LaunchExtraCommand(LPCSTR pszInfName, LPCSTR pszSection)
  1050. {
  1051. return E_NOTIMPL;
  1052. }
  1053. //=---------------------------------------------------------------------------=
  1054. // RegisterInstallEngineCallback
  1055. //=---------------------------------------------------------------------------=
  1056. // Register the callback interface
  1057. //
  1058. // Parameters:
  1059. // IInstallEngineCallback * - the callback interface
  1060. // HWND - For ui
  1061. //
  1062. // Returns:
  1063. //
  1064. // Notes:
  1065. //
  1066. STDMETHODIMP CInstallEngine::RegisterInstallEngineCallback(IInstallEngineCallback *pcb)
  1067. {
  1068. _pcb = pcb;
  1069. return NOERROR;
  1070. }
  1071. //=---------------------------------------------------------------------------=
  1072. // Function name here
  1073. //=---------------------------------------------------------------------------=
  1074. // Function description
  1075. //
  1076. // Parameters
  1077. //
  1078. // Returns:
  1079. //
  1080. // Notes:
  1081. //
  1082. STDMETHODIMP CInstallEngine::UnregisterInstallEngineCallback()
  1083. {
  1084. _pcb = NULL;
  1085. return NOERROR;
  1086. }
  1087. //=---------------------------------------------------------------------------=
  1088. // Function name here
  1089. //=---------------------------------------------------------------------------=
  1090. // Function description
  1091. //
  1092. // Parameters
  1093. //
  1094. // Returns:
  1095. //
  1096. // Notes:
  1097. //
  1098. STDMETHODIMP CInstallEngine::SetHWND(HWND h)
  1099. {
  1100. _hwndForUI = h;
  1101. return NOERROR;
  1102. }
  1103. //*********** IInstallEngineCallback implementation ************
  1104. //=---------------------------------------------------------------------------=
  1105. // Function name here
  1106. //=---------------------------------------------------------------------------=
  1107. // Function description
  1108. //
  1109. // Parameters
  1110. //
  1111. // Returns:
  1112. //
  1113. // Notes:
  1114. //
  1115. STDMETHODIMP CInstallEngine::OnEngineStatusChange(DWORD status,DWORD substatus)
  1116. {
  1117. _enginestatus = status;
  1118. if(_pcb)
  1119. _pcb->OnEngineStatusChange(_enginestatus, substatus);
  1120. return NOERROR;
  1121. }
  1122. //=---------------------------------------------------------------------------=
  1123. // Function name here
  1124. //=---------------------------------------------------------------------------=
  1125. // Function description
  1126. //
  1127. // Parameters
  1128. //
  1129. // Returns:
  1130. //
  1131. // Notes:
  1132. //
  1133. STDMETHODIMP CInstallEngine::OnStartInstall(DWORD dwDLSize, DWORD dwInstallSize)
  1134. {
  1135. _dwDLRemaining = dwDLSize;
  1136. _dwInstallRemaining = dwInstallSize;
  1137. wsprintf(szLogBuf, "\r\nOnStartInstall:\r\n Download: %d KB\r\n Install %d KB\r\n", dwDLSize, dwInstallSize);
  1138. WriteToLog(szLogBuf, TRUE);
  1139. if(_pcb)
  1140. _pcb->OnStartInstall(dwDLSize, dwInstallSize);
  1141. return NOERROR;
  1142. }
  1143. //=---------------------------------------------------------------------------=
  1144. // Function name here
  1145. //=---------------------------------------------------------------------------=
  1146. // Function description
  1147. //
  1148. // Parameters
  1149. //
  1150. // Returns:
  1151. //
  1152. // Notes:
  1153. //
  1154. STDMETHODIMP CInstallEngine::OnStartComponent(LPCSTR pszID, DWORD dwDLSize,
  1155. DWORD dwInstallSize, LPCSTR pszString)
  1156. {
  1157. wsprintf(szLogBuf, "OnStartComponent:\r\n ID: %s\r\n Download: %d KB\r\n Install %d KB\r\n",
  1158. pszID, dwDLSize, dwInstallSize);
  1159. WriteToLog(szLogBuf, TRUE);
  1160. _dwDLOld = 0;
  1161. _dwInstallOld = 0;
  1162. if(_pcb)
  1163. _pcb->OnStartComponent(pszID, dwDLSize, dwInstallSize, pszString);
  1164. return NOERROR;
  1165. }
  1166. //=---------------------------------------------------------------------------=
  1167. // Function name here
  1168. //=---------------------------------------------------------------------------=
  1169. // Function description
  1170. //
  1171. // Parameters
  1172. //
  1173. // Returns:
  1174. //
  1175. // Notes:
  1176. //
  1177. STDMETHODIMP CInstallEngine::OnEngineProblem(DWORD dwProblem, LPDWORD pdwAction)
  1178. {
  1179. HRESULT hr = S_FALSE;
  1180. if(_pcb)
  1181. hr = _pcb->OnEngineProblem(dwProblem, pdwAction);
  1182. return hr;
  1183. }
  1184. //=---------------------------------------------------------------------------=
  1185. // Function name here
  1186. //=---------------------------------------------------------------------------=
  1187. // Function description
  1188. //
  1189. // Parameters
  1190. //
  1191. // Returns:
  1192. //
  1193. // Notes:
  1194. //
  1195. STDMETHODIMP CInstallEngine::OnComponentProgress(LPCSTR pszID, DWORD dwPhase,
  1196. LPCSTR pszString, LPCSTR pszMsgString, ULONG prog, ULONG max)
  1197. {
  1198. DWORD dwNew;
  1199. if(dwPhase == INSTALLSTATUS_DOWNLOADING)
  1200. {
  1201. _dwDLOld = prog;
  1202. }
  1203. else if(dwPhase == INSTALLSTATUS_RUNNING)
  1204. {
  1205. _dwInstallOld = prog;
  1206. }
  1207. if(_pcb)
  1208. _pcb->OnComponentProgress(pszID, dwPhase, pszString, pszMsgString, prog, max);
  1209. return NOERROR;
  1210. }
  1211. //=---------------------------------------------------------------------------=
  1212. // Function name here
  1213. //=---------------------------------------------------------------------------=
  1214. // Function description
  1215. //
  1216. // Parameters
  1217. //
  1218. // Returns:
  1219. //
  1220. // Notes:
  1221. //
  1222. STDMETHODIMP CInstallEngine::OnStopComponent(LPCSTR pszID, HRESULT hError,
  1223. DWORD dwPhase, LPCSTR pszString, DWORD dwStatus)
  1224. {
  1225. // adjust remaining
  1226. if(_dwDLRemaining > _dwDLOld)
  1227. _dwDLRemaining -= _dwDLOld;
  1228. else
  1229. _dwDLRemaining = 0;
  1230. // adjust remaining
  1231. if(_dwInstallRemaining > _dwInstallOld)
  1232. _dwInstallRemaining -= _dwInstallOld;
  1233. else
  1234. _dwInstallRemaining = 0;
  1235. wsprintf(szLogBuf, "Timing rates: Download: %d, Install %d\r\n",
  1236. _pDL->GetBytesPerSecond(), _pIns->GetBytesPerSecond());
  1237. WriteToLog(szLogBuf, TRUE);
  1238. wsprintf(szLogBuf, "OnStopComponent:\r\n ID: %s\r\n HRESULT: %x (%s)\r\n Phase: %d\r\n Status: %d\r\n",
  1239. pszID, hError, SUCCEEDED(hError) ? STR_OK : STR_FAILED, dwPhase, dwStatus);
  1240. WriteToLog(szLogBuf, TRUE);
  1241. if(_pcb)
  1242. _pcb->OnStopComponent(pszID, hError, dwPhase, pszString, dwStatus);
  1243. return NOERROR;
  1244. }
  1245. //=---------------------------------------------------------------------------=
  1246. // Function name here
  1247. //=---------------------------------------------------------------------------=
  1248. // Function description
  1249. //
  1250. // Parameters
  1251. //
  1252. // Returns:
  1253. //
  1254. // Notes:
  1255. //
  1256. STDMETHODIMP CInstallEngine::OnStopInstall(HRESULT hrError, LPCSTR szError,
  1257. DWORD dwStatus)
  1258. {
  1259. _dwDLRemaining = 0;
  1260. _dwInstallRemaining = 0;
  1261. wsprintf(szLogBuf, "\r\nOnStopInstall:\r\n HRESULT: %x (%s)\r\n Status: %d\r\n",
  1262. hrError, SUCCEEDED(hrError) ? STR_OK : STR_FAILED, dwStatus);
  1263. WriteToLog(szLogBuf, TRUE);
  1264. if(_pcb)
  1265. _pcb->OnStopInstall(hrError, szError, dwStatus);
  1266. return NOERROR;
  1267. }
  1268. //=---------------------------------------------------------------------------=
  1269. // Function name here
  1270. //=---------------------------------------------------------------------------=
  1271. // Function description
  1272. //
  1273. // Parameters
  1274. //
  1275. // Returns:
  1276. //
  1277. // Notes:
  1278. //
  1279. STDMETHODIMP CInstallEngine::SetIStream(IStream *pstm)
  1280. {
  1281. if(_pStmLog)
  1282. _pStmLog->Release();
  1283. _pStmLog = pstm;
  1284. if(_pStmLog)
  1285. _pStmLog->AddRef();
  1286. return NOERROR;
  1287. }
  1288. //=---------------------------------------------------------------------------=
  1289. // Function name here
  1290. //=---------------------------------------------------------------------------=
  1291. // Function description
  1292. //
  1293. // Parameters
  1294. //
  1295. // Returns:
  1296. //
  1297. // Notes:
  1298. //
  1299. STDMETHODIMP CInstallEngine::GetDisplayName(LPCSTR pszComponentID, LPSTR *ppszName)
  1300. {
  1301. HRESULT hr = E_INVALIDARG;
  1302. char szTitle[MAX_DISPLAYNAME_LENGTH];
  1303. if(!ppszName)
  1304. return E_POINTER;
  1305. *ppszName = 0;
  1306. ICifComponent *pComp = NULL;
  1307. if(pszComponentID)
  1308. {
  1309. if(SUCCEEDED(_pCif->FindComponent(pszComponentID, &pComp)))
  1310. {
  1311. pComp->GetDescription(szTitle, sizeof(szTitle));
  1312. *ppszName = COPYANSISTR(szTitle);
  1313. if(!(*ppszName))
  1314. hr = E_OUTOFMEMORY;
  1315. else
  1316. hr = NOERROR;
  1317. }
  1318. }
  1319. else
  1320. {
  1321. _pCif->GetDescription(szTitle, sizeof(szTitle));
  1322. *ppszName = COPYANSISTR(szTitle);
  1323. if(!(*ppszName))
  1324. hr = E_OUTOFMEMORY;
  1325. else
  1326. hr = NOERROR;
  1327. }
  1328. return hr;
  1329. }
  1330. //************** IInstallEngineTiming **********************
  1331. //=---------------------------------------------------------------------------=
  1332. // Function name here
  1333. //=---------------------------------------------------------------------------=
  1334. // Function description
  1335. //
  1336. // Parameters
  1337. //
  1338. // Returns:
  1339. //
  1340. // Notes:
  1341. //
  1342. STDMETHODIMP CInstallEngine::GetRates(DWORD *pdwDownload, DWORD *pdwInstall)
  1343. {
  1344. *pdwDownload = _pDL->GetBytesPerSecond();
  1345. *pdwInstall = _pIns->GetBytesPerSecond();
  1346. return NOERROR;
  1347. }
  1348. STDMETHODIMP CInstallEngine::GetInstallProgress(INSTALLPROGRESS *pinsprog)
  1349. {
  1350. if(!pinsprog)
  1351. return E_POINTER;
  1352. DWORD dwTemp;
  1353. pinsprog->dwDownloadKBRemaining = _dwDLRemaining - _dwDLOld;
  1354. pinsprog->dwInstallKBRemaining = _dwInstallRemaining - _dwInstallOld;
  1355. dwTemp = _pDL->GetBytesPerSecond();
  1356. if(dwTemp == 0)
  1357. pinsprog->dwDownloadSecsRemaining = 0xffffffff;
  1358. else
  1359. pinsprog->dwDownloadSecsRemaining = (pinsprog->dwDownloadKBRemaining << 10)/dwTemp;
  1360. dwTemp = _pIns->GetBytesPerSecond();
  1361. if(dwTemp == 0)
  1362. pinsprog->dwInstallSecsRemaining = 0xffffffff;
  1363. else
  1364. pinsprog->dwInstallSecsRemaining = (pinsprog->dwInstallKBRemaining << 10)/dwTemp;
  1365. return NOERROR;
  1366. }
  1367. HRESULT CInstallEngine::CheckForContinue()
  1368. {
  1369. HRESULT hr = S_OK;
  1370. // Need to check Abort before AND after check for pause...
  1371. if(_pCif->CanCancel() && (WaitForSingleObject(_hAbort, 0) == WAIT_OBJECT_0))
  1372. {
  1373. hr = E_ABORT;
  1374. }
  1375. if(SUCCEEDED(hr))
  1376. {
  1377. WaitForEvent(_hContinue, NULL);
  1378. }
  1379. if(_pCif->CanCancel() && (WaitForSingleObject(_hAbort, 0) == WAIT_OBJECT_0))
  1380. {
  1381. hr = E_ABORT;
  1382. }
  1383. return hr;
  1384. }
  1385. #define STEPPINGMODE_NO "n"
  1386. void CInstallEngine::WriteToLog(char *sz, BOOL pause)
  1387. {
  1388. ULONG foo;
  1389. UINT ret;
  1390. HKEY hKey;
  1391. if(_fSteppingMode && pause)
  1392. {
  1393. ret = MessageBox(_hwndForUI, sz, "Stepping Mode Message", MB_OKCANCEL | MB_ICONINFORMATION);
  1394. if(ret == IDCANCEL)
  1395. {
  1396. // turn off stepping mode
  1397. _fSteppingMode = FALSE;
  1398. // Whack the key
  1399. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, ACTIVESETUP_KEY,0,
  1400. KEY_WRITE, &hKey) == ERROR_SUCCESS)
  1401. {
  1402. // I don't check for failure of delete - what would I do anyways?
  1403. RegSetValueEx(hKey, STEPPING_VALUE, 0, REG_SZ,
  1404. (BYTE *) STEPPINGMODE_NO, lstrlen(STEPPINGMODE_NO) + 1);
  1405. RegCloseKey(hKey);
  1406. }
  1407. }
  1408. }
  1409. if(_pStmLog)
  1410. _pStmLog->Write(sz, lstrlen(sz), &foo);
  1411. }
  1412. BOOL CInstallEngine::_IsValidBaseUrl(LPCSTR pszUrl)
  1413. {
  1414. BOOL bValid = TRUE;
  1415. if(!pszUrl)
  1416. bValid = FALSE;
  1417. return bValid;
  1418. }