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.

3035 lines
83 KiB

  1. //=--------------------------------------------------------------------------=
  2. // inseng.cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. //
  7. #include "asctlpch.h"
  8. #include "ipserver.h"
  9. #include <wininet.h>
  10. #include "util.h"
  11. #include "globals.h"
  12. #include "asinsctl.h"
  13. #include "dispids.h"
  14. #include "resource.h"
  15. #include "util2.h"
  16. #include <mshtml.h>
  17. // for ASSERT and FAIL
  18. //
  19. SZTHISFILE
  20. WCHAR wszInsFile [] = L"InstallList";
  21. WCHAR wszBaseUrl [] = L"BaseUrl";
  22. WCHAR wszCabName [] = L"CabName";
  23. #define EVENT_ONSTARTINSTALL 0
  24. #define EVENT_ONSTARTCOMPONENT 1
  25. #define EVENT_ONSTOPCOMPONENT 2
  26. #define EVENT_ONSTOPINSTALL 3
  27. #define EVENT_ONENGINESTATUSCHANGE 4
  28. #define EVENT_ONENGINEPROBLEM 5
  29. #define EVENT_ONCHECKFREESPACE 6
  30. #define EVENT_ONCOMPONENTPROGRESS 7
  31. #define EVENT_ONSTARTINSTALLEX 8
  32. #define EVENT_CANCEL 10
  33. static VARTYPE rgI4[] = { VT_I4 };
  34. static VARTYPE rgI4_2[] = { VT_I4, VT_I4 };
  35. static VARTYPE rgStartComponent[] = { VT_BSTR, VT_I4, VT_BSTR };
  36. static VARTYPE rgStopComponent[] = { VT_BSTR, VT_I4, VT_I4, VT_BSTR, VT_I4 };
  37. static VARTYPE rgStopInstall[] = { VT_I4, VT_BSTR, VT_I4 };
  38. static VARTYPE rgEngineProblem[] = { VT_I4 };
  39. static VARTYPE rgCheckFreeSpace[] = { VT_BSTR, VT_I4, VT_BSTR, VT_I4, VT_BSTR, VT_I4 };
  40. static VARTYPE rgComponentProgress[] = { VT_BSTR, VT_I4, VT_BSTR, VT_BSTR, VT_I4, VT_I4 };
  41. #define WM_INSENGCALLBACK WM_USER+34
  42. static EVENTINFO rgEvents [] = {
  43. { DISPID_ONSTARTINSTALL, 1, rgI4 }, // (long percentDone)
  44. { DISPID_ONSTARTCOMPONENT, 3, rgStartComponent },
  45. { DISPID_ONSTOPCOMPONENT, 5, rgStopComponent },
  46. { DISPID_ONSTOPINSTALL, 3, rgStopInstall },
  47. { DISPID_ENGINESTATUSCHANGE, 2, rgI4_2 },
  48. { DISPID_ONENGINEPROBLEM, 1, rgEngineProblem },
  49. { DISPID_ONCHECKFREESPACE, 6, rgCheckFreeSpace },
  50. { DISPID_ONCOMPONENTPROGRESS, 6, rgComponentProgress },
  51. { DISPID_ONSTARTINSTALLEX, 2, rgI4_2 },
  52. };
  53. UINT g_uCDAutorunMsg;
  54. unsigned long g_ulOldAutorunSetting;
  55. const char g_cszIEJITInfo[] = "Software\\Microsoft\\Active Setup\\JITInfo";
  56. const char g_cszPolicyExplorer[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
  57. const char g_cszAutorunSetting[] = "NoDriveTypeAutoRun";
  58. //=---------------------------------------------
  59. // SetAutorunSetting
  60. //=---------------------------------------------
  61. unsigned long SetAutorunSetting(unsigned long ulValue)
  62. {
  63. HKEY hKey;
  64. unsigned long ulOldSetting;
  65. unsigned long ulNewSetting = ulValue;
  66. DWORD dwSize = sizeof(unsigned long);
  67. if( RegOpenKeyEx(HKEY_CURRENT_USER, g_cszPolicyExplorer , 0, KEY_READ|KEY_WRITE, &hKey ) == ERROR_SUCCESS )
  68. {
  69. if( RegQueryValueEx(hKey, g_cszAutorunSetting, 0, NULL, (unsigned char*)&ulOldSetting, &dwSize ) == ERROR_SUCCESS )
  70. {
  71. RegSetValueEx(hKey, g_cszAutorunSetting, 0, REG_BINARY, (const unsigned char*)&ulNewSetting, 4);
  72. }
  73. else
  74. ulOldSetting = WINDOWS_DEFAULT_AUTOPLAY_VALUE;
  75. RegFlushKey( hKey );
  76. RegCloseKey( hKey );
  77. }
  78. return ulOldSetting;
  79. }
  80. //=--------------------------------------------------------------------------=
  81. // CInstallEngineCtl::Create
  82. //=--------------------------------------------------------------------------=
  83. // global static function that creates an instance of the control an returns
  84. // an IUnknown pointer for it.
  85. //
  86. // Parameters:
  87. // IUnknown * - [in] controlling unknown for aggregation
  88. //
  89. // Output:
  90. // IUnknown * - new object.
  91. //
  92. // Notes:
  93. //
  94. IUnknown *CInstallEngineCtl::Create(IUnknown *pUnkOuter)
  95. {
  96. // make sure we return the private unknown so that we support aggegation
  97. // correctly!
  98. //
  99. BOOL bSuccess;
  100. CInstallEngineCtl *pNew = new CInstallEngineCtl(pUnkOuter, &bSuccess);
  101. if(bSuccess)
  102. return pNew->PrivateUnknown();
  103. else
  104. {
  105. delete pNew;
  106. return NULL;
  107. }
  108. }
  109. //=--------------------------------------------------------------------------=
  110. // CInstallEngineCtl::CInstallEngineCtl
  111. //=--------------------------------------------------------------------------=
  112. //
  113. // Parameters:
  114. // IUnknown * - [in]
  115. //
  116. // Notes:
  117. //
  118. #pragma warning(disable:4355) // using 'this' in constructor, safe here
  119. CInstallEngineCtl::CInstallEngineCtl(IUnknown *pUnkOuter, BOOL *pbSuccess)
  120. : COleControl(pUnkOuter, OBJECT_INSTALLENGINECTL, (IDispatch *)this)
  121. {
  122. HRESULT hr;
  123. DWORD dwVersion = 0;
  124. *pbSuccess = TRUE;
  125. _hIcon = NULL;
  126. // null out all base urls
  127. ZeroMemory( _rpszUrlList, sizeof(LPSTR) * MAX_URLS);
  128. _uCurrentUrl = 0;
  129. _pProgDlg = NULL;
  130. _pinseng = NULL;
  131. _pszErrorString = NULL;
  132. _hDone = NULL;
  133. _hResult = NOERROR;
  134. m_readyState = READYSTATE_COMPLETE;
  135. _uAllowGrovel = 0xffffffff;
  136. _fNeedReboot = FALSE;
  137. _szDownloadDir[0] = 0;
  138. _fEventToFire = FALSE;
  139. _dwSavedEngineStatus = 0;
  140. _dwSavedSubStatus = 0;
  141. _dwFreezeEvents = 0;
  142. _dwProcessComponentsFlags = 0;
  143. _dwMSTrustKey = (DWORD)-1;
  144. _uCurrentUrl = 0xffffffff;
  145. _fReconcileCif = FALSE;
  146. _fLocalCifSet = FALSE;
  147. _fDoingIEInstall = FALSE;
  148. _uInstallMode = 0;
  149. _uInstallPad = 0;
  150. _strCurrentID = NULL;
  151. _strCurrentName = NULL;
  152. _strCurrentString = NULL;
  153. _fInstalling = FALSE;
  154. _bCancelPending = FALSE;
  155. _bDeleteURLList = FALSE;
  156. _bNewWebSites = FALSE;
  157. _fJITInstall = FALSE;
  158. // Register for the special CD Autorun message.
  159. g_uCDAutorunMsg = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
  160. hr = CoCreateInstance(CLSID_InstallEngine, NULL, CLSCTX_INPROC_SERVER,
  161. IID_IInstallEngine2,(void **) &_pinseng);
  162. if(_pinseng)
  163. {
  164. _pinseng->SetDownloadDir(NULL);
  165. _pinseng->SetInstallOptions(INSTALLOPTIONS_DOWNLOAD |
  166. INSTALLOPTIONS_INSTALL |
  167. INSTALLOPTIONS_DONTALLOWXPLATFORM);
  168. _pinseng->SetHWND(GetActiveWindow());
  169. _pinseng->RegisterInstallEngineCallback((IInstallEngineCallback *)this);
  170. }
  171. else
  172. *pbSuccess = FALSE;
  173. _dwLastPhase = 0xffffffff;
  174. // set up our initial size ... + 6 so we can have raised edge
  175. m_Size.cx = 6 + GetSystemMetrics(SM_CXICON);
  176. m_Size.cy = 6 + GetSystemMetrics(SM_CYICON);
  177. #ifdef TESTCERT
  178. UpdateTrustState();
  179. #endif
  180. SetControlFont();
  181. }
  182. #pragma warning(default:4355) // using 'this' in constructor
  183. //=--------------------------------------------------------------------------=
  184. // CInstallEngineCtl::~CInstallEngineCtl
  185. //=--------------------------------------------------------------------------=
  186. //
  187. // Notes:
  188. //
  189. CInstallEngineCtl::~CInstallEngineCtl()
  190. {
  191. if(_pinseng)
  192. {
  193. _pinseng->SetHWND(NULL);
  194. _pinseng->UnregisterInstallEngineCallback();
  195. _pinseng->Release();
  196. }
  197. for(int i = 0; i < MAX_URLS; i++)
  198. if(_rpszUrlList[i])
  199. delete _rpszUrlList[i];
  200. // Is all this needed? Only in case where OnStopInstall is never called...
  201. if(_pProgDlg)
  202. delete _pProgDlg;
  203. if(_pszErrorString)
  204. free(_pszErrorString);
  205. if (_dwMSTrustKey != (DWORD)-1)
  206. WriteMSTrustKey(FALSE, _dwMSTrustKey);
  207. #ifdef TESTCERT
  208. ResetTestrootCertInTrustState();
  209. #endif
  210. // delete ActiveSetup value from IE4\Options
  211. WriteActiveSetupValue(FALSE);
  212. if (g_hFont)
  213. {
  214. DeleteObject(g_hFont);
  215. g_hFont = NULL;
  216. }
  217. }
  218. //=--------------------------------------------------------------------------=
  219. // CInstallEngineCtl:RegisterClassData
  220. //=--------------------------------------------------------------------------=
  221. // register the window class information for your control here.
  222. // this information will automatically get cleaned up for you on DLL shutdown.
  223. //
  224. // Output:
  225. // BOOL - FALSE means fatal error.
  226. //
  227. // Notes:
  228. //
  229. BOOL CInstallEngineCtl::RegisterClassData()
  230. {
  231. WNDCLASS wndclass;
  232. // TODO: register any additional information you find interesting here.
  233. // this method is only called once for each type of control
  234. //
  235. memset(&wndclass, 0, sizeof(WNDCLASS));
  236. wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  237. wndclass.lpfnWndProc = COleControl::ControlWindowProc;
  238. wndclass.hInstance = g_hInstance;
  239. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  240. wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
  241. wndclass.lpszClassName = WNDCLASSNAMEOFCONTROL(OBJECT_INSTALLENGINECTL);
  242. return RegisterClass(&wndclass);
  243. }
  244. //=--------------------------------------------------------------------------=
  245. // CInstallEngineCtl::BeforeCreateWindow
  246. //=--------------------------------------------------------------------------=
  247. // called just before the window is created. Great place to set up the
  248. // window title, etc, so that they're passed in to the call to CreateWindowEx.
  249. // speeds things up slightly.
  250. //
  251. // Notes:
  252. //
  253. void CInstallEngineCtl::BeforeCreateWindow()
  254. {
  255. }
  256. //=--------------------------------------------------------------------------=
  257. // Function name here
  258. //=--------------------------------------------------------------------------=
  259. // Function description
  260. //
  261. // Parameters:
  262. //
  263. // Returns:
  264. //
  265. // Notes:
  266. //
  267. BOOL CInstallEngineCtl::AfterCreateWindow()
  268. {
  269. MarkJITInstall();
  270. return TRUE;
  271. }
  272. //=--------------------------------------------------------------------------=
  273. // CInstallEngineCtl::InternalQueryInterface
  274. //=--------------------------------------------------------------------------=
  275. // qi for things only we support.
  276. //
  277. // Parameters:
  278. // Parameters:
  279. // REFIID - [in] interface they want
  280. // void ** - [out] where they want to put the resulting object ptr.
  281. //
  282. // Output:
  283. // HRESULT - S_OK, E_NOINTERFACE
  284. //
  285. // Notes:
  286. //
  287. HRESULT CInstallEngineCtl::InternalQueryInterface(REFIID riid, void **ppvObjOut)
  288. {
  289. IUnknown *pUnk;
  290. *ppvObjOut = NULL;
  291. // TODO: if you want to support any additional interrfaces, then you should
  292. // indicate that here. never forget to call COleControl's version in the
  293. // case where you don't support the given interface.
  294. //
  295. if (DO_GUIDS_MATCH(riid, IID_IInstallEngine)) {
  296. pUnk = (IUnknown *)(IInstallEngine *)this;
  297. } else{
  298. return COleControl::InternalQueryInterface(riid, ppvObjOut);
  299. }
  300. pUnk->AddRef();
  301. *ppvObjOut = (void *)pUnk;
  302. return S_OK;
  303. }
  304. //=--------------------------------------------------------------------------=
  305. // CInstallEngineCtl::LoadTextState
  306. //=--------------------------------------------------------------------------=
  307. // load in our text state for this control.
  308. //
  309. // Parameters:
  310. // IPropertyBag * - [in] property bag to read from
  311. // IErrorLog * - [in] errorlog object to use with proeprty bag
  312. //
  313. // Output:
  314. // HRESULT
  315. //
  316. // Notes:
  317. // - NOTE: if you have a binary object, then you should pass an unknown
  318. // pointer to the property bag, and it will QI it for IPersistStream, and
  319. // get said object to do a Load()
  320. //
  321. STDMETHODIMP CInstallEngineCtl::LoadTextState(IPropertyBag *pPropertyBag, IErrorLog *pErrorLog)
  322. {
  323. VARIANT v;
  324. VARIANT v2;
  325. HRESULT hr;
  326. VariantInit(&v);
  327. v.vt = VT_BSTR;
  328. v.bstrVal = NULL;
  329. VariantInit(&v2);
  330. v2.vt = VT_BSTR;
  331. v2.bstrVal = NULL;
  332. // try to load in the property. if we can't get it, then leave
  333. // things at their default.
  334. //
  335. v.vt = VT_BSTR;
  336. v.bstrVal = NULL;
  337. hr = pPropertyBag->Read(::wszBaseUrl, &v, pErrorLog);
  338. if(SUCCEEDED(hr))
  339. hr = put_BaseUrl(v.bstrVal);
  340. VariantClear(&v);
  341. //
  342. // IMPORTANT: Trident no longer defaults to VT_BSTR if no variant type is specified
  343. //
  344. v.vt = VT_BSTR;
  345. v.bstrVal = NULL;
  346. hr = pPropertyBag->Read(::wszCabName, &v, pErrorLog);
  347. if(SUCCEEDED(hr))
  348. hr = pPropertyBag->Read(::wszInsFile, &v2, pErrorLog);
  349. if(SUCCEEDED(hr))
  350. {
  351. hr = SetCifFile(v.bstrVal, v2.bstrVal);
  352. }
  353. VariantClear(&v);
  354. VariantClear(&v2);
  355. return S_OK;
  356. }
  357. //=--------------------------------------------------------------------------=
  358. // CInstallEngineCtl::LoadBinaryState
  359. //=--------------------------------------------------------------------------=
  360. // loads in our binary state using streams.
  361. //
  362. // Parameters:
  363. // IStream * - [in] stream to write to.
  364. //
  365. // Output:
  366. // HRESULT
  367. //
  368. // Notes:
  369. //
  370. const DWORD STREAMHDR_MAGIC = 12345678L;
  371. STDMETHODIMP CInstallEngineCtl::LoadBinaryState(IStream *pStream)
  372. {
  373. DWORD sh;
  374. HRESULT hr;
  375. // first read in the streamhdr, and make sure we like what we're getting
  376. //
  377. hr = pStream->Read(&sh, sizeof(sh), NULL);
  378. RETURN_ON_FAILURE(hr);
  379. // sanity check
  380. //
  381. if (sh != STREAMHDR_MAGIC )
  382. return E_UNEXPECTED;
  383. return(S_OK);
  384. }
  385. //=--------------------------------------------------------------------------=
  386. // CInstallEngineCtl::SaveTextState
  387. //=--------------------------------------------------------------------------=
  388. // saves out the text state for this control using a property bag.
  389. //
  390. // Parameters:
  391. // IPropertyBag * - [in] the property bag with which to work.
  392. // BOOL - [in] if TRUE, then write out ALL properties, even
  393. // if they're their the default value ...
  394. //
  395. // Output:
  396. // HRESULT
  397. //
  398. // Notes:
  399. //
  400. STDMETHODIMP CInstallEngineCtl::SaveTextState(IPropertyBag *pPropertyBag, BOOL fWriteDefaults)
  401. {
  402. return S_OK;
  403. }
  404. //=--------------------------------------------------------------------------=
  405. // CInstallEngineCtl::SaveBinaryState
  406. //=--------------------------------------------------------------------------=
  407. // save out the binary state for this control, using the given IStream object.
  408. //
  409. // Parameters:
  410. // IStream * - [in] save to which you should save.
  411. //
  412. // Output:
  413. // HRESULT
  414. //
  415. // Notes:
  416. // - it is important that you seek to the end of where you saved your
  417. // properties when you're done with the IStream.
  418. //
  419. STDMETHODIMP CInstallEngineCtl::SaveBinaryState(IStream *pStream)
  420. {
  421. DWORD sh = STREAMHDR_MAGIC;
  422. HRESULT hr;
  423. // write out the stream hdr.
  424. //
  425. hr = pStream->Write(&sh, sizeof(sh), NULL);
  426. RETURN_ON_FAILURE(hr);
  427. // write out he control state information
  428. //
  429. return hr;
  430. }
  431. //=--------------------------------------------------------------------------=
  432. // CInstallEngineCtl::OnDraw
  433. //=--------------------------------------------------------------------------=
  434. //
  435. // Parameters:
  436. // DWORD - [in] drawing aspect
  437. // HDC - [in] HDC to draw to
  438. // LPCRECTL - [in] rect we're drawing to
  439. // LPCRECTL - [in] window extent and origin for meta-files
  440. // HDC - [in] HIC for target device
  441. // BOOL - [in] can we optimize dc handling?
  442. //
  443. // Output:
  444. // HRESULT
  445. //
  446. // Notes:
  447. //
  448. HRESULT CInstallEngineCtl::OnDraw(DWORD dvAspect, HDC hdcDraw, LPCRECTL prcBounds,
  449. LPCRECTL prcWBounds, HDC hicTargetDevice, BOOL fOptimize)
  450. {
  451. // To provide visual appearence in DESIGN MODE only
  452. if(DesignMode())
  453. {
  454. if(!_hIcon)
  455. _hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_INSTALLENGINE));
  456. DrawEdge(hdcDraw, (LPRECT)(LPCRECT)prcBounds, EDGE_RAISED, BF_RECT | BF_MIDDLE);
  457. if(_hIcon)
  458. DrawIcon(hdcDraw, prcBounds->left + 3, prcBounds->top + 3, _hIcon);
  459. }
  460. return S_OK;
  461. }
  462. //=--------------------------------------------------------------------------=
  463. // CInstallEngineCtl::WindowProc
  464. //=--------------------------------------------------------------------------=
  465. // window procedure for this control. nothing terribly exciting.
  466. //
  467. // Parameters:
  468. // see win32sdk on window procs.
  469. //
  470. // Notes:
  471. //
  472. typedef HRESULT (WINAPI *CHECKFORVERSIONCONFLICT) ();
  473. LRESULT CInstallEngineCtl::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
  474. {
  475. // TODO: handle any messages here, like in a normal window
  476. // proc. note that for special keys, you'll want to override and
  477. // implement OnSpecialKey.
  478. //
  479. LRESULT lres;
  480. CALLBACK_PARAMS *pcbp;
  481. switch (msg)
  482. {
  483. case WM_ERASEBKGND:
  484. if (KeepTransparent(m_hwnd, msg, wParam, lParam, &lres))
  485. return lres;
  486. break;
  487. case WM_ACTIVATE:
  488. case WM_ACTIVATEAPP:
  489. {
  490. DWORD fActive = LOWORD(wParam);
  491. if(fActive == WA_ACTIVE || fActive == WA_CLICKACTIVE ||
  492. fActive == TRUE)
  493. {
  494. CHECKFORVERSIONCONFLICT pVerCon;
  495. HINSTANCE hInseng= LoadLibrary("inseng.dll");
  496. if(hInseng)
  497. {
  498. pVerCon = (CHECKFORVERSIONCONFLICT)
  499. GetProcAddress(hInseng, "CheckForVersionConflict");
  500. if(pVerCon)
  501. pVerCon();
  502. FreeLibrary(hInseng);
  503. }
  504. }
  505. }
  506. return TRUE;
  507. case WM_INSENGCALLBACK:
  508. pcbp = (CALLBACK_PARAMS *) lParam;
  509. switch(wParam)
  510. {
  511. case EVENT_ONENGINESTATUSCHANGE:
  512. FireEvent( &::rgEvents[EVENT_ONENGINESTATUSCHANGE],
  513. pcbp->dwStatus, pcbp->dwSubstatus );
  514. break;
  515. case EVENT_ONSTARTINSTALL:
  516. FireEvent(&::rgEvents[EVENT_ONSTARTINSTALL], (long) pcbp->dwSize);
  517. break;
  518. case EVENT_ONSTARTCOMPONENT:
  519. FireEvent(&::rgEvents[EVENT_ONSTARTCOMPONENT],
  520. pcbp->strID, (long) pcbp->dwSize, pcbp->strName);
  521. break;
  522. case EVENT_ONSTOPCOMPONENT:
  523. FireEvent(&::rgEvents[EVENT_ONSTOPCOMPONENT], pcbp->strID, (long) pcbp->dwResult,
  524. (long) pcbp->dwPhase, pcbp->strName, (long) pcbp->dwStatus);
  525. break;
  526. case EVENT_ONSTOPINSTALL:
  527. FireEvent(&::rgEvents[EVENT_ONSTOPINSTALL], (long) pcbp->dwResult,
  528. pcbp->strString, (long) pcbp->dwStatus);
  529. break;
  530. case EVENT_ONENGINEPROBLEM:
  531. FireEvent(&::rgEvents[EVENT_ONENGINEPROBLEM], (long) pcbp->dwStatus);
  532. break;
  533. case EVENT_ONCHECKFREESPACE:
  534. FireEvent(&::rgEvents[EVENT_ONCHECKFREESPACE], pcbp->chWin,
  535. (long) pcbp->dwWin, pcbp->chInstall,
  536. (long) pcbp->dwInstall, pcbp->chDL, (long) pcbp->dwDL);
  537. break;
  538. case EVENT_ONCOMPONENTPROGRESS:
  539. FireEvent(&::rgEvents[EVENT_ONCOMPONENTPROGRESS], pcbp->strID,
  540. (long) pcbp->dwPhase, pcbp->strName, pcbp->strString,
  541. (long)pcbp->dwDL, (long) pcbp->dwSize);
  542. break;
  543. case EVENT_CANCEL:
  544. Abort(0);
  545. break;
  546. case EVENT_ONSTARTINSTALLEX:
  547. FireEvent(&::rgEvents[EVENT_ONSTARTINSTALLEX], (long) pcbp->dwDL, (long) pcbp->dwSize);
  548. break;
  549. default:
  550. break;
  551. }
  552. break;
  553. default:
  554. break;
  555. }
  556. return OcxDefWindowProc(msg, wParam, lParam);
  557. }
  558. //=--------------------------------------------------------------------------=
  559. // Function name here
  560. //=--------------------------------------------------------------------------=
  561. // Function description
  562. //
  563. // Parameters:
  564. //
  565. // Returns:
  566. //
  567. // Notes:
  568. STDMETHODIMP CInstallEngineCtl::FreezeEvents(BOOL bFreeze)
  569. {
  570. if(bFreeze)
  571. _dwFreezeEvents++;
  572. else
  573. {
  574. if(_dwFreezeEvents)
  575. {
  576. _dwFreezeEvents--;
  577. // if we go to zero, fire our EngineStatus change event if we have one
  578. if(_dwFreezeEvents == 0 && _fEventToFire)
  579. {
  580. _FireEngineStatusChange(_dwSavedEngineStatus, _dwSavedSubStatus);
  581. _fEventToFire = FALSE;
  582. }
  583. }
  584. }
  585. return S_OK;
  586. }
  587. //=--------------------------------------------------------------------------=
  588. // Function name here
  589. //=--------------------------------------------------------------------------=
  590. // Function description
  591. //
  592. // Parameters:
  593. //
  594. // Returns:
  595. //
  596. // Notes:
  597. //
  598. STDMETHODIMP CInstallEngineCtl::get_EngineStatus(long * theenginestatus)
  599. {
  600. if(!_pinseng)
  601. return E_UNEXPECTED;
  602. return _pinseng->GetEngineStatus((DWORD *)theenginestatus);
  603. }
  604. //=--------------------------------------------------------------------------=
  605. // Function name here
  606. //=--------------------------------------------------------------------------=
  607. // Function description
  608. //
  609. // Parameters:
  610. //
  611. // Returns:
  612. //
  613. // Notes:
  614. //
  615. STDMETHODIMP CInstallEngineCtl::get_ReadyState(long * thestate)
  616. {
  617. CHECK_POINTER(thestate);
  618. *thestate = m_readyState;
  619. return(NOERROR);
  620. }
  621. //=--------------------------------------------------------------------------=
  622. // Function name here
  623. //=--------------------------------------------------------------------------=
  624. // Function description
  625. //
  626. // Parameters:
  627. //
  628. // Returns:
  629. //
  630. // Notes:
  631. //
  632. STDMETHODIMP CInstallEngineCtl::Abort(long lFlag)
  633. {
  634. if(!_pinseng)
  635. {
  636. _bCancelPending = TRUE;
  637. return E_UNEXPECTED;
  638. }
  639. if ( _pinseng->Abort(lFlag) != NOERROR )
  640. _bCancelPending = TRUE;
  641. return NOERROR;
  642. }
  643. void CInstallEngineCtl::_FireCancel(DWORD dwStatus)
  644. {
  645. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_CANCEL, NULL);
  646. }
  647. STDMETHODIMP CInstallEngineCtl::SetLocalCif(BSTR strCif, long FAR* lResult)
  648. {
  649. *lResult = E_FAIL;
  650. //Allow SetLocalCif only for local cif file. See windows# 541710 and winseraid #24036
  651. if (strCif[1] == L'\\')
  652. return E_ACCESSDENIED;
  653. if(!_pinseng)
  654. return E_UNEXPECTED;
  655. MAKE_ANSIPTR_FROMWIDE(pszCif, strCif);
  656. *lResult = _pinseng->SetLocalCif(pszCif);
  657. if(SUCCEEDED(*lResult))
  658. _fLocalCifSet = TRUE;
  659. return NOERROR;
  660. }
  661. //=--------------------------------------------------------------------------=
  662. // Function name here
  663. //=--------------------------------------------------------------------------=
  664. // Function description
  665. //
  666. // Parameters:
  667. //
  668. // Returns:
  669. //
  670. // Notes:
  671. //
  672. STDMETHODIMP CInstallEngineCtl::SetCifFile(BSTR strCabName, BSTR strCifName)
  673. {
  674. HRESULT hr;
  675. if(!_pinseng)
  676. return E_UNEXPECTED;
  677. MAKE_ANSIPTR_FROMWIDE(pszCabName, strCabName);
  678. MAKE_ANSIPTR_FROMWIDE(pszCifName, strCifName);
  679. if(_fLocalCifSet)
  680. {
  681. // if we are using a local cif, we won't get the new cif right away
  682. _fReconcileCif = TRUE;
  683. lstrcpyn(_szCifCab, pszCabName, sizeof(_szCifCab));
  684. lstrcpyn(_szCifFile, pszCifName, sizeof(_szCifFile));
  685. hr = S_OK;
  686. }
  687. else
  688. {
  689. // If we did not check yet, do it.
  690. if (_dwMSTrustKey == (DWORD)-1)
  691. {
  692. _dwMSTrustKey = MsTrustKeyCheck();
  693. // If MS is not a trusted provider.
  694. // Make it for the duration of the install
  695. if (_dwMSTrustKey != 0)
  696. WriteMSTrustKey(TRUE, _dwMSTrustKey);
  697. }
  698. hr = _pinseng->SetCifFile(pszCabName, pszCifName);
  699. }
  700. return hr;
  701. }
  702. #define IE_KEY "Software\\Microsoft\\Internet Explorer"
  703. #define VERSION_KEY "Version"
  704. LONG CInstallEngineCtl::_OpenJITKey(HKEY *phKey, REGSAM samAttr)
  705. {
  706. char szTemp[MAX_PATH];
  707. WORD rdwVer[4] = { 0 };
  708. HKEY hIE;
  709. DWORD dwDumb;
  710. DWORD dwVer;
  711. if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, IE_KEY, 0, KEY_READ, &hIE) == ERROR_SUCCESS)
  712. {
  713. dwDumb = sizeof(szTemp);
  714. if(RegQueryValueEx(hIE, VERSION_KEY, 0, NULL, (LPBYTE)szTemp, &dwDumb) == ERROR_SUCCESS)
  715. {
  716. ConvertVersionString(szTemp, rdwVer, '.');
  717. }
  718. RegCloseKey(hIE);
  719. }
  720. dwVer = rdwVer[0];
  721. wsprintf(szTemp, "%s\\%d", g_cszIEJITInfo, dwVer);
  722. return(RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTemp, 0, samAttr, phKey));
  723. }
  724. void CInstallEngineCtl::_DeleteURLList()
  725. {
  726. HKEY hJITKey;
  727. if ( _OpenJITKey(&hJITKey, KEY_READ) == ERROR_SUCCESS )
  728. {
  729. RegDeleteKey(hJITKey, "URLList");
  730. RegCloseKey(hJITKey);
  731. }
  732. }
  733. void CInstallEngineCtl::_WriteURLList()
  734. {
  735. HKEY hJITKey;
  736. HKEY hUrlKey;
  737. char cNull = '\0';
  738. if ( _OpenJITKey(&hJITKey, KEY_READ) == ERROR_SUCCESS )
  739. {
  740. if (RegCreateKeyEx(hJITKey, "URLList", 0, NULL, REG_OPTION_NON_VOLATILE,
  741. KEY_WRITE, NULL, &hUrlKey, NULL) == ERROR_SUCCESS)
  742. {
  743. for(UINT i=0; i < MAX_URLS; i++)
  744. {
  745. if ( _rpszUrlList[i] )
  746. {
  747. RegSetValueEx(hUrlKey, _rpszUrlList[i], 0, REG_SZ, (const unsigned char *) &cNull, sizeof(cNull));
  748. }
  749. }
  750. RegCloseKey(hUrlKey);
  751. }
  752. RegCloseKey(hJITKey);
  753. }
  754. }
  755. void CInstallEngineCtl::_WriteRegionToReg(LPSTR szRegion)
  756. {
  757. HKEY hJITKey;
  758. if (_OpenJITKey(&hJITKey, KEY_WRITE) == ERROR_SUCCESS)
  759. {
  760. RegSetValueEx(hJITKey, "DownloadSiteRegion", 0, REG_SZ, (const unsigned char *) szRegion, strlen(szRegion)+1);
  761. RegCloseKey(hJITKey);
  762. }
  763. }
  764. STDMETHODIMP CInstallEngineCtl::SetSitesFile(BSTR strUrl, BSTR strRegion, BSTR strLocale, long FAR* lResult)
  765. {
  766. char szBuf[INTERNET_MAX_URL_LENGTH];
  767. DWORD dwSize;
  768. HKEY hKey;
  769. HKEY hUrlKey;
  770. UINT uUrlNum = 0;
  771. HRESULT hr = E_FAIL;
  772. MAKE_ANSIPTR_FROMWIDE(pszUrl, strUrl);
  773. MAKE_ANSIPTR_FROMWIDE(pszRegion, strRegion);
  774. MAKE_ANSIPTR_FROMWIDE(pszLocale, strLocale);
  775. // first check to see if we should use local stuff
  776. if(pszUrl[0] == 0)
  777. {
  778. _fDoingIEInstall = TRUE;
  779. // find the ie major version, add it to JIT key
  780. if(_OpenJITKey(&hKey, KEY_READ) == ERROR_SUCCESS)
  781. {
  782. dwSize = sizeof(_uInstallMode);
  783. RegQueryValueEx(hKey, "InstallType", NULL, NULL, (BYTE *) &_uInstallMode, &dwSize);
  784. /*
  785. if(_uInstallMode == WEBINSTALL)
  786. {
  787. if(RegOpenKeyEx(hKey, "URLList", 0, KEY_READ, &hUrlKey) == ERROR_SUCCESS)
  788. {
  789. // need to read out urls and put them in rpszUrlList
  790. for(int i = 0; uUrlNum < MAX_URLS; i++)
  791. {
  792. dwSize = sizeof(szBuf);
  793. if(RegEnumValue(hUrlKey, i, szBuf, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
  794. {
  795. _rpszUrlList[uUrlNum] = new char[dwSize + 1];
  796. if(_rpszUrlList[uUrlNum])
  797. {
  798. lstrcpy(_rpszUrlList[uUrlNum], szBuf);
  799. // we found at least one url so "NOERROR"
  800. uUrlNum++;
  801. }
  802. }
  803. else
  804. break;
  805. }
  806. RegCloseKey(hUrlKey);
  807. }
  808. if (uUrlNum > 0)
  809. {
  810. // We got atleast one URL from the registry.
  811. // Check if the URLs are still valid.
  812. hr = _PickWebSites(NULL, NULL, NULL, TRUE, TRUE);
  813. }
  814. }
  815. else */if(_uInstallMode == WEBINSTALL_DIFFERENTMACHINE)
  816. {
  817. hr = NOERROR;
  818. }
  819. _szDownloadDir[0] = 0;
  820. dwSize = sizeof(_szDownloadDir);
  821. if(RegQueryValueEx(hKey, "UNCDownloadDir", NULL, NULL, (BYTE *) (_szDownloadDir), &dwSize) == ERROR_SUCCESS)
  822. {
  823. // if its a web install, set download dir to UNCDownloadDir
  824. if(_uInstallMode == WEBINSTALL || _uInstallMode == WEBINSTALL_DIFFERENTMACHINE)
  825. {
  826. if(GetFileAttributes(_szDownloadDir) != 0xffffffff)
  827. _pinseng->SetDownloadDir(_szDownloadDir);
  828. }
  829. else if(_uInstallMode == CDINSTALL ||
  830. _uInstallMode == NETWORKINSTALL ||
  831. _uInstallMode == LOCALINSTALL)
  832. {
  833. // setup szBuf with file:// at beginning
  834. lstrcpy(szBuf, "file://");
  835. lstrcat(szBuf, _szDownloadDir);
  836. _rpszUrlList[uUrlNum] = new char[lstrlen(szBuf) + 1];
  837. if(_rpszUrlList[uUrlNum])
  838. {
  839. lstrcpy(_rpszUrlList[uUrlNum], szBuf);
  840. // we found at least one url so "NOERROR"
  841. uUrlNum++;
  842. hr = NOERROR;
  843. }
  844. }
  845. }
  846. RegCloseKey(hKey);
  847. }
  848. }
  849. if (hr != NOERROR)
  850. {
  851. hr = _PickWebSites(pszUrl, pszRegion, pszLocale, FALSE);
  852. }
  853. if(SUCCEEDED(hr) && _rpszUrlList[0])
  854. {
  855. _uCurrentUrl = 0;
  856. _pinseng->SetBaseUrl(_rpszUrlList[_uCurrentUrl]);
  857. }
  858. *lResult = hr;
  859. return NOERROR;
  860. }
  861. //=--------------------------------------------------------------------------=
  862. // Function name here
  863. //=--------------------------------------------------------------------------=
  864. // Function description
  865. //
  866. // Parameters:
  867. //
  868. // Returns:
  869. //
  870. // Notes:
  871. //
  872. STDMETHODIMP CInstallEngineCtl::put_BaseUrl(BSTR strBaseUrl)
  873. {
  874. if(!_pinseng)
  875. return E_UNEXPECTED;
  876. MAKE_ANSIPTR_FROMWIDE(pszBaseUrl, strBaseUrl);
  877. return _pinseng->SetBaseUrl(pszBaseUrl);
  878. }
  879. //=--------------------------------------------------------------------------=
  880. // Function name here
  881. //=--------------------------------------------------------------------------=
  882. // Function description
  883. //
  884. // Parameters:
  885. //
  886. // Returns:
  887. //
  888. // Notes:
  889. //
  890. STDMETHODIMP CInstallEngineCtl::put_DownloadDir(BSTR strDownloadDir)
  891. {
  892. // Due to security issues, this method is effectively being disabled.
  893. return S_OK;
  894. if(!_pinseng)
  895. return E_UNEXPECTED;
  896. MAKE_ANSIPTR_FROMWIDE(pszDownloadDir, strDownloadDir);
  897. return _pinseng->SetDownloadDir(pszDownloadDir);
  898. }
  899. //=--------------------------------------------------------------------------=
  900. // Function name here
  901. //=--------------------------------------------------------------------------=
  902. // Function description
  903. //
  904. // Parameters:
  905. //
  906. // Returns:
  907. //
  908. // Notes:
  909. //
  910. STDMETHODIMP CInstallEngineCtl::IsComponentInstalled(BSTR strComponentID, long *lResult)
  911. {
  912. if(!_pinseng)
  913. return E_UNEXPECTED;
  914. // Ask about grovelling for installed apps here
  915. //
  916. // add code to automatically enable grovel if the specified event is signalled
  917. //
  918. const TCHAR szEnableGrovelEventName[] = TEXT("WindowsUpdateCriticalUpdateGrovelEnable");
  919. if(_uAllowGrovel == 0xffffffff)
  920. {
  921. HANDLE evAllowGrovel = OpenEvent(
  922. EVENT_ALL_ACCESS,
  923. FALSE,
  924. szEnableGrovelEventName
  925. );
  926. if (evAllowGrovel != NULL)
  927. {
  928. if (WaitForSingleObject(evAllowGrovel, 0) == WAIT_OBJECT_0)
  929. {
  930. //
  931. // if the event is signaled, we reset the event, and set _uAllowGrovel=1 which
  932. // means we've already agreed on groveling
  933. //
  934. _uAllowGrovel = 1;
  935. }
  936. CloseHandle(evAllowGrovel);
  937. }
  938. }
  939. if (_uAllowGrovel == 0xffffffff)
  940. {
  941. LPSTR pszTitle;
  942. char szMess[512];
  943. _pinseng->GetDisplayName(NULL, &pszTitle);
  944. LoadSz(IDS_GROVELMESSAGE, szMess, sizeof(szMess));
  945. ModalDialog(TRUE);
  946. if(MessageBox(m_hwnd, szMess, pszTitle, MB_YESNO | MB_ICONQUESTION) == IDNO)
  947. _uAllowGrovel = 0;
  948. else
  949. _uAllowGrovel = 1;
  950. ModalDialog(FALSE);
  951. if(pszTitle)
  952. CoTaskMemFree(pszTitle);
  953. }
  954. if (_uAllowGrovel != 1)
  955. {
  956. *lResult = ICI_UNKNOWN;
  957. return NOERROR;
  958. }
  959. else
  960. {
  961. MAKE_ANSIPTR_FROMWIDE(pszComponentID, strComponentID);
  962. return _pinseng->IsComponentInstalled(pszComponentID, (DWORD *)lResult);
  963. }
  964. }
  965. STDMETHODIMP CInstallEngineCtl::get_DisplayName(BSTR ComponentID, BSTR *name)
  966. {
  967. LPSTR psz;
  968. MAKE_ANSIPTR_FROMWIDE(pszID, ComponentID);
  969. _pinseng->GetDisplayName(pszID, &psz);
  970. if(psz)
  971. {
  972. *name = BSTRFROMANSI(psz);
  973. CoTaskMemFree(psz);
  974. }
  975. return NOERROR;
  976. }
  977. //=--------------------------------------------------------------------------=
  978. // Function name here
  979. //=--------------------------------------------------------------------------=
  980. // Function description
  981. //
  982. // Parameters:
  983. //
  984. // Returns:
  985. //
  986. // Notes:
  987. //
  988. STDMETHODIMP CInstallEngineCtl::get_Size(BSTR strComponentID, long *lResult)
  989. {
  990. HRESULT hr;
  991. COMPONENT_SIZES cs;
  992. if(!_pinseng)
  993. return E_UNEXPECTED;
  994. cs.cbSize = sizeof(COMPONENT_SIZES);
  995. MAKE_ANSIPTR_FROMWIDE(pszComponentID, strComponentID);
  996. hr = _pinseng->GetSizes(pszComponentID, &cs);
  997. *lResult = cs.dwDownloadSize;
  998. return hr;
  999. }
  1000. //=--------------------------------------------------------------------------=
  1001. // Function name here
  1002. //=--------------------------------------------------------------------------=
  1003. // Function description
  1004. //
  1005. // Parameters:
  1006. //
  1007. // Returns:
  1008. //
  1009. // Notes:
  1010. //
  1011. STDMETHODIMP CInstallEngineCtl::get_TotalDownloadSize(long *totalsize)
  1012. {
  1013. HRESULT hr;
  1014. COMPONENT_SIZES cs;
  1015. if(!_pinseng)
  1016. return E_UNEXPECTED;
  1017. cs.cbSize = sizeof(COMPONENT_SIZES);
  1018. hr = _pinseng->GetSizes(NULL, &cs);
  1019. *totalsize = cs.dwDownloadSize;
  1020. return hr;
  1021. }
  1022. //=--------------------------------------------------------------------------=
  1023. // Function name here
  1024. //=--------------------------------------------------------------------------=
  1025. // Function description
  1026. //
  1027. // Parameters:
  1028. //
  1029. // Returns:
  1030. //
  1031. // Notes:
  1032. //
  1033. STDMETHODIMP CInstallEngineCtl::get_TotalDependencySize(long *totaldepsize)
  1034. {
  1035. HRESULT hr;
  1036. COMPONENT_SIZES cs;
  1037. if(!_pinseng)
  1038. return E_UNEXPECTED;
  1039. cs.cbSize = sizeof(COMPONENT_SIZES);
  1040. hr = _pinseng->GetSizes(NULL, &cs);
  1041. *totaldepsize = cs.dwDependancySize;
  1042. return hr;
  1043. }
  1044. //=--------------------------------------------------------------------------=
  1045. // Function name here
  1046. //=--------------------------------------------------------------------------=
  1047. // Function description
  1048. //
  1049. // Parameters:
  1050. //
  1051. // Returns:
  1052. //
  1053. // Notes:
  1054. //
  1055. STDMETHODIMP CInstallEngineCtl::SetAction(BSTR strComponentID, long action, long *lResult)
  1056. {
  1057. if(!_pinseng)
  1058. return E_UNEXPECTED;
  1059. MAKE_ANSIPTR_FROMWIDE(pszComponentID, strComponentID);
  1060. *lResult = 0;
  1061. HRESULT hr = _pinseng->SetAction(pszComponentID, action, 0xffffffff);
  1062. if(hr == E_PENDING)
  1063. {
  1064. char szTitle[128];
  1065. char szErrBuf[256];
  1066. LoadSz(IDS_TITLE, szTitle, sizeof(szTitle));
  1067. LoadSz(IDS_ERRDOINGINSTALL, szErrBuf, sizeof(szErrBuf));
  1068. MsgBox(szTitle, szErrBuf);
  1069. }
  1070. if(hr == S_FALSE)
  1071. *lResult = 1;
  1072. return NOERROR;
  1073. }
  1074. //=--------------------------------------------------------------------------=
  1075. // Function name here
  1076. //=--------------------------------------------------------------------------=
  1077. // Function description
  1078. //
  1079. // Parameters:
  1080. //
  1081. // Returns:
  1082. //
  1083. // Notes:
  1084. //
  1085. STDMETHODIMP CInstallEngineCtl::ProcessComponents(long lFlags)
  1086. {
  1087. DWORD status;
  1088. HANDLE hThread;
  1089. if(!_pinseng)
  1090. return E_UNEXPECTED;
  1091. if(!_fInstalling)
  1092. {
  1093. _fInstalling = TRUE;
  1094. // make sure engine is ready
  1095. _pinseng->GetEngineStatus(&status);
  1096. if(status == ENGINESTATUS_READY)
  1097. {
  1098. // spawn thread to do install
  1099. _dwProcessComponentsFlags = lFlags;
  1100. // only allow certain options thru script
  1101. _dwProcessComponentsFlags &= 0xffffffef;
  1102. if ((hThread = CreateThread(NULL, 0, DoInstall, (LPVOID) this, 0, &status)) != NULL)
  1103. CloseHandle(hThread);
  1104. }
  1105. }
  1106. return NOERROR;
  1107. }
  1108. void CInstallEngineCtl::_DoInstall()
  1109. {
  1110. HRESULT hr = NOERROR;
  1111. char szBuf[512];
  1112. char szTitle[128];
  1113. BOOL fNeedWebSites = FALSE;
  1114. DWORD dwMSTrustKey = (DWORD)-1;
  1115. AddRef();
  1116. _hDone = CreateEvent(NULL, FALSE, FALSE, NULL);
  1117. _dwInstallStatus = 0;
  1118. if(!_hDone)
  1119. hr = E_FAIL;
  1120. // If we did not check yet, do it.
  1121. if (dwMSTrustKey == (DWORD)-1)
  1122. {
  1123. dwMSTrustKey = MsTrustKeyCheck();
  1124. // If MS is not a trusted provider. Make it for the duration of the install
  1125. if (dwMSTrustKey != 0)
  1126. WriteMSTrustKey(TRUE, dwMSTrustKey, _fJITInstall);
  1127. }
  1128. // Add reg value so that if IE4 base is installed, it would think that it
  1129. // is being run from Active Setup. This would prevent softboot from being
  1130. // kicked off by IE4 base.
  1131. WriteActiveSetupValue(TRUE);
  1132. if(_fDoingIEInstall)
  1133. {
  1134. // figure out whether we need to hit the web or not
  1135. // for beta1 we assume we never do for CD/NETWORK
  1136. COMPONENT_SIZES Sizes;
  1137. if(_uInstallMode == WEBINSTALL || _uInstallMode == WEBINSTALL_DIFFERENTMACHINE)
  1138. {
  1139. ZeroMemory(&Sizes, sizeof(COMPONENT_SIZES));
  1140. Sizes.cbSize = sizeof(COMPONENT_SIZES);
  1141. if(SUCCEEDED(_pinseng->GetSizes(NULL, &Sizes)))
  1142. {
  1143. if(Sizes.dwDownloadSize == 0)
  1144. {
  1145. // in webdownload case, with everything local, no need to reoncile cif
  1146. _fReconcileCif = FALSE;
  1147. }
  1148. else
  1149. {
  1150. // if we don't have any web sites then we need them
  1151. if(!_rpszUrlList[0])
  1152. fNeedWebSites = TRUE;
  1153. }
  1154. }
  1155. }
  1156. else
  1157. {
  1158. // for CD, NETWORK, LOCALINSTALL, here we check for path
  1159. hr = _CheckInstallPath(&fNeedWebSites);
  1160. // no need to reconcile the cif - it won't even be there!
  1161. _fReconcileCif = FALSE;
  1162. }
  1163. }
  1164. if(SUCCEEDED(hr))
  1165. {
  1166. _dwInstallStatus = 0;
  1167. if(!(_dwProcessComponentsFlags & PROCESSCOMPONENT_NOPROGRESSUI))
  1168. {
  1169. _pProgDlg = new CProgressDlg(g_hInstance, m_hwnd, m_hwndParent, this);
  1170. if(_pProgDlg)
  1171. _pProgDlg->DisplayWindow(TRUE);
  1172. }
  1173. }
  1174. if(SUCCEEDED(hr) && fNeedWebSites)
  1175. {
  1176. // member boolean to track whether whether websites need to
  1177. // be written back to the URLList.
  1178. _bNewWebSites = TRUE;
  1179. hr = _PickWebSites(NULL, NULL, NULL, FALSE);
  1180. if(SUCCEEDED(hr))
  1181. {
  1182. _pinseng->SetBaseUrl(_rpszUrlList[0]);
  1183. _uCurrentUrl = 0;
  1184. }
  1185. }
  1186. if ( SUCCEEDED(hr) && _bCancelPending )
  1187. {
  1188. hr = E_ABORT;
  1189. _bCancelPending = FALSE;
  1190. }
  1191. if(SUCCEEDED(hr) && _fReconcileCif)
  1192. {
  1193. hr = _pinseng->SetCifFile(_szCifCab, _szCifFile);
  1194. if(SUCCEEDED(hr))
  1195. {
  1196. WaitForEvent(_hDone, NULL);
  1197. hr = _hResult;
  1198. _fReconcileCif = FALSE;
  1199. }
  1200. }
  1201. if ( SUCCEEDED(hr) && _bCancelPending )
  1202. {
  1203. hr = E_ABORT;
  1204. _bCancelPending = FALSE;
  1205. }
  1206. if(SUCCEEDED(hr))
  1207. {
  1208. hr = _CheckForDiskSpace();
  1209. }
  1210. if(SUCCEEDED(hr))
  1211. {
  1212. COMPONENT_SIZES cs;
  1213. cs.cbSize = sizeof(COMPONENT_SIZES);
  1214. if(SUCCEEDED(_pinseng->GetSizes(NULL, &cs)))
  1215. {
  1216. _FireOnStartInstallExEvent(cs.dwDownloadSize, cs.dwInstallSize + cs.dwWinDriveSize);
  1217. }
  1218. if ( SUCCEEDED(hr) && _bCancelPending )
  1219. {
  1220. hr = E_ABORT;
  1221. _bCancelPending = FALSE;
  1222. }
  1223. if ( SUCCEEDED(hr) )
  1224. {
  1225. hr = _pinseng->DownloadComponents(_dwProcessComponentsFlags);
  1226. if(SUCCEEDED(hr))
  1227. {
  1228. WaitForEvent(_hDone, NULL);
  1229. hr = _hResult;
  1230. }
  1231. }
  1232. }
  1233. if(SUCCEEDED(hr))
  1234. {
  1235. // Prepare the install
  1236. // Create the error string
  1237. _pszErrorString = (char *) malloc(ERROR_STRING_SIZE);
  1238. _iErrorStringSize = ERROR_STRING_SIZE;
  1239. if(_pszErrorString)
  1240. LoadSz(IDS_SUMMARYHEADING, _pszErrorString, 2048);
  1241. else
  1242. hr = E_OUTOFMEMORY;
  1243. }
  1244. if(SUCCEEDED(hr))
  1245. {
  1246. if(_pProgDlg && (_dwProcessComponentsFlags & PROCESSCOMPONENT_NOINSTALLUI))
  1247. _pProgDlg->DisplayWindow(FALSE);
  1248. hr = _pinseng->InstallComponents(EXECUTEJOB_IGNORETRUST);
  1249. if(SUCCEEDED(hr))
  1250. {
  1251. WaitForEvent(_hDone, NULL);
  1252. hr = _hResult;
  1253. }
  1254. }
  1255. if (dwMSTrustKey != (DWORD)-1)
  1256. {
  1257. WriteMSTrustKey(FALSE, dwMSTrustKey);
  1258. }
  1259. dwMSTrustKey = (DWORD)-1;
  1260. // delete ActiveSetup value from IE4\Options
  1261. WriteActiveSetupValue(FALSE);
  1262. if(_pProgDlg)
  1263. {
  1264. delete _pProgDlg;
  1265. _pProgDlg = NULL;
  1266. }
  1267. LoadSz(IDS_FINISH_TITLE, szTitle, sizeof(szTitle));
  1268. // show appropriate summary ui
  1269. if( !(_dwProcessComponentsFlags & PROCESSCOMPONENT_NOSUMMARYUI))
  1270. {
  1271. if(SUCCEEDED(hr))
  1272. {
  1273. if(_pszErrorString)
  1274. MsgBox(szTitle, _pszErrorString);
  1275. }
  1276. else if(hr == E_ABORT)
  1277. {
  1278. LoadSz(IDS_INSTALLCANCELLED, szBuf, sizeof(szBuf));
  1279. MsgBox(szTitle, szBuf);
  1280. }
  1281. else if( _pszErrorString )
  1282. {
  1283. MsgBox(szTitle, _pszErrorString);
  1284. }
  1285. else
  1286. {
  1287. LoadSz(IDS_ERRGENERAL, szBuf, sizeof(szBuf));
  1288. MsgBox(szTitle, szBuf);
  1289. }
  1290. }
  1291. if(SUCCEEDED(hr))
  1292. {
  1293. if(_dwInstallStatus & STOPINSTALL_REBOOTNEEDED)
  1294. {
  1295. if(!(_dwProcessComponentsFlags & PROCESSCOMPONENT_DELAYREBOOT))
  1296. {
  1297. if( !MyRestartDialog(m_hwnd, TRUE) )
  1298. _dwInstallStatus |= STOPINSTALL_REBOOTREFUSED;
  1299. }
  1300. else
  1301. _fNeedReboot = TRUE;
  1302. }
  1303. }
  1304. _FireOnStopInstallEvent(hr, NULL, _dwInstallStatus);
  1305. _dwProcessComponentsFlags = 0;
  1306. if(_pszErrorString)
  1307. {
  1308. free(_pszErrorString);
  1309. _pszErrorString = NULL;
  1310. }
  1311. if(_hDone)
  1312. {
  1313. CloseHandle(_hDone);
  1314. _hDone = NULL;
  1315. }
  1316. _fInstalling = FALSE;
  1317. Release();
  1318. }
  1319. HRESULT CInstallEngineCtl::_PickWebSites(LPCSTR pszSites, LPCSTR pszLocale, LPCSTR pszRegion, BOOL bKeepExisting)
  1320. {
  1321. UINT uCurrentUrl;
  1322. char szUrl[INTERNET_MAX_URL_LENGTH];
  1323. char szRegion[MAX_DISPLAYNAME_LENGTH];
  1324. char szLocale[3];
  1325. HRESULT hr = NOERROR;
  1326. HKEY hKey;
  1327. DWORD dwSize;
  1328. szRegion[0] = 0;
  1329. szUrl[0] = 0;
  1330. szLocale[0] = 0;
  1331. if(!bKeepExisting)
  1332. {
  1333. for(uCurrentUrl = 0; uCurrentUrl < MAX_URLS; uCurrentUrl++)
  1334. {
  1335. if(_rpszUrlList[uCurrentUrl])
  1336. {
  1337. delete _rpszUrlList[uCurrentUrl];
  1338. _rpszUrlList[uCurrentUrl] = 0;
  1339. }
  1340. }
  1341. }
  1342. // find the first empty url
  1343. for(uCurrentUrl = 0; uCurrentUrl < MAX_URLS && _rpszUrlList[uCurrentUrl]; uCurrentUrl++);
  1344. // fill out all our fields
  1345. if(!pszSites || (*pszSites == '\0'))
  1346. {
  1347. // read info out of JIT key
  1348. if(_OpenJITKey(&hKey, KEY_READ) == ERROR_SUCCESS)
  1349. {
  1350. dwSize = sizeof(szUrl);
  1351. RegQueryValueEx(hKey, "DownloadSiteURL", NULL, NULL, (BYTE *) szUrl, &dwSize);
  1352. if(!pszLocale ||(*pszLocale == '\0'))
  1353. {
  1354. dwSize = sizeof(szLocale);
  1355. RegQueryValueEx(hKey, "Local", NULL, NULL, (BYTE *) szLocale, &dwSize);
  1356. }
  1357. else
  1358. lstrcpyn(szLocale, pszLocale, sizeof(szLocale));
  1359. if(!pszRegion||(*pszRegion == '\0'))
  1360. {
  1361. dwSize = sizeof(szRegion);
  1362. RegQueryValueEx(hKey, "DownloadSiteRegion", NULL, NULL, (BYTE *) szRegion, &dwSize);
  1363. }
  1364. else
  1365. lstrcpyn(szRegion, pszRegion, sizeof(szRegion));
  1366. RegCloseKey(hKey);
  1367. }
  1368. }
  1369. else
  1370. {
  1371. lstrcpyn(szUrl, pszSites, INTERNET_MAX_URL_LENGTH);
  1372. if(pszLocale)
  1373. lstrcpyn(szLocale, pszLocale, sizeof(szLocale));
  1374. if(pszRegion)
  1375. lstrcpyn(szRegion, pszRegion, sizeof(szRegion));
  1376. }
  1377. if(szUrl[0])
  1378. {
  1379. SITEQUERYPARAMS SiteParam;
  1380. IDownloadSiteMgr *pISitemgr;
  1381. IDownloadSite **ppISite = NULL;
  1382. IDownloadSite *pISite;
  1383. DOWNLOADSITE *psite;
  1384. BYTE *pPicks = NULL;
  1385. UINT uNumToPick;
  1386. UINT uFirstSite = 0xffffffff;
  1387. UINT j;
  1388. UINT uNumSites = 0;
  1389. ZeroMemory(&SiteParam, sizeof(SITEQUERYPARAMS));
  1390. SiteParam.cbSize = sizeof(SITEQUERYPARAMS);
  1391. // if we have a locale, use it
  1392. if(szLocale[0])
  1393. SiteParam.pszLang = szLocale;
  1394. hr = CoCreateInstance(CLSID_DownloadSiteMgr, NULL,
  1395. CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER,
  1396. IID_IDownloadSiteMgr, (LPVOID *)&pISitemgr);
  1397. if (SUCCEEDED(hr))
  1398. {
  1399. hr = pISitemgr->Initialize(szUrl, &SiteParam);
  1400. if (SUCCEEDED(hr))
  1401. {
  1402. // assume we fail. if we add at least one url, set to OK
  1403. hr = E_FAIL;
  1404. while (SUCCEEDED(pISitemgr->EnumSites(uNumSites, &pISite)))
  1405. {
  1406. pISite->Release();
  1407. uNumSites++;
  1408. }
  1409. ppISite = new IDownloadSite *[uNumSites];
  1410. for(j=0; j < uNumSites;j++)
  1411. {
  1412. pISitemgr->EnumSites(j, &(ppISite[j]));
  1413. }
  1414. // if we don't have a region, show ui
  1415. // NOTE: szRegion better be valid and
  1416. // better have atleast MAX_DISPLAYNAME_LENGTH buffer size
  1417. if(!szRegion[0])
  1418. {
  1419. _PickRegionAndFirstSite(ppISite, uNumSites, szRegion, &uFirstSite);
  1420. }
  1421. pPicks = new BYTE[uNumSites];
  1422. // zero out picks array
  1423. for(j=0; j < uNumSites; j++)
  1424. pPicks[j] = 0;
  1425. // find out number of urls we will add
  1426. uNumToPick = MAX_URLS - uCurrentUrl;
  1427. if(uNumToPick > uNumSites)
  1428. uNumToPick = uNumSites;
  1429. if(uNumToPick > 0)
  1430. {
  1431. if(uFirstSite != 0xffffffff)
  1432. {
  1433. pPicks[uFirstSite] = 1;
  1434. uNumToPick--;
  1435. }
  1436. _PickRandomSites(ppISite, pPicks, uNumSites, uNumToPick, szRegion);
  1437. }
  1438. // now all sites we want are marked with one in pPicks
  1439. for(j = 0; j < uNumSites; j++)
  1440. {
  1441. if(pPicks[j])
  1442. {
  1443. if(SUCCEEDED(ppISite[j]->GetData(&psite)))
  1444. {
  1445. _rpszUrlList[uCurrentUrl] = new char[lstrlen(psite->pszUrl) + 1];
  1446. if(_rpszUrlList[uCurrentUrl])
  1447. {
  1448. lstrcpy(_rpszUrlList[uCurrentUrl], psite->pszUrl);
  1449. uCurrentUrl++;
  1450. hr = NOERROR;
  1451. }
  1452. }
  1453. }
  1454. }
  1455. }
  1456. for(j = 0; j < uNumSites; j++)
  1457. ppISite[j]->Release();
  1458. if(ppISite)
  1459. delete ppISite;
  1460. if(pPicks)
  1461. delete pPicks;
  1462. pISitemgr->Release();
  1463. }
  1464. }
  1465. else
  1466. hr = E_FAIL;
  1467. return hr;
  1468. }
  1469. void CInstallEngineCtl::_PickRandomSites(IDownloadSite **ppISite, BYTE *pPicks, UINT uNumSites, UINT uNumToPick, LPSTR pszRegion)
  1470. {
  1471. UINT uStart, uIncrement, uFirst;
  1472. uStart = GetTickCount() % uNumSites;
  1473. if(uNumSites > 1)
  1474. uIncrement = GetTickCount() % (uNumSites - 1);
  1475. while(uNumToPick)
  1476. {
  1477. // if already picked or not in correct region, find next
  1478. uFirst = uStart;
  1479. while(pPicks[uStart] || !IsSiteInRegion(ppISite[uStart], pszRegion))
  1480. {
  1481. uStart++;
  1482. if(uStart >= uNumSites)
  1483. uStart -= uNumSites;
  1484. if(uStart == uFirst)
  1485. break;
  1486. }
  1487. if(!pPicks[uStart])
  1488. {
  1489. pPicks[uStart] = 1;
  1490. uStart += uIncrement;
  1491. if(uStart >= uNumSites)
  1492. uStart -= uNumSites;
  1493. uNumToPick--;
  1494. }
  1495. else
  1496. break;
  1497. }
  1498. }
  1499. typedef struct
  1500. {
  1501. IDownloadSite **ppISite;
  1502. UINT uNumSites;
  1503. LPSTR pszRegion;
  1504. UINT uFirstSite;
  1505. } SITEDLGPARAMS;
  1506. void FillRegionList(SITEDLGPARAMS *psiteparams, HWND hDlg)
  1507. {
  1508. DOWNLOADSITE *pSite;
  1509. HWND hRegion = GetDlgItem(hDlg, IDC_REGIONS);
  1510. for(UINT i = 0; i < psiteparams->uNumSites; i++)
  1511. {
  1512. psiteparams->ppISite[i]->GetData(&pSite);
  1513. if(ComboBox_FindStringExact(hRegion, 0, pSite->pszRegion) == CB_ERR)
  1514. ComboBox_AddString(hRegion, pSite->pszRegion);
  1515. }
  1516. ComboBox_SetCurSel(hRegion, 0);
  1517. }
  1518. void FillSiteList(SITEDLGPARAMS *psiteparams, HWND hDlg)
  1519. {
  1520. char szRegion[MAX_DISPLAYNAME_LENGTH];
  1521. int uPos;
  1522. DOWNLOADSITE *pSite;
  1523. HWND hSite = GetDlgItem(hDlg, IDC_SITES);
  1524. ListBox_ResetContent(hSite);
  1525. ComboBox_GetText(GetDlgItem(hDlg, IDC_REGIONS), szRegion, MAX_DISPLAYNAME_LENGTH);
  1526. // copy the new Region name into the psiteparams struct.
  1527. if ( psiteparams->pszRegion)
  1528. lstrcpyn(psiteparams->pszRegion, szRegion, MAX_DISPLAYNAME_LENGTH);
  1529. for(UINT i = 0; i < psiteparams->uNumSites; i++)
  1530. {
  1531. if(IsSiteInRegion(psiteparams->ppISite[i], szRegion))
  1532. {
  1533. psiteparams->ppISite[i]->GetData(&pSite);
  1534. uPos = ListBox_AddString(hSite, pSite->pszFriendlyName);
  1535. if(uPos != LB_ERR)
  1536. ListBox_SetItemData(hSite, uPos, i);
  1537. }
  1538. }
  1539. ListBox_SetCurSel(hSite, 0);
  1540. }
  1541. INT_PTR CALLBACK SiteListDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1542. {
  1543. SITEDLGPARAMS *psiteparam;
  1544. switch (uMsg)
  1545. {
  1546. case WM_INITDIALOG:
  1547. // Do some init stuff
  1548. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) lParam);
  1549. psiteparam = (SITEDLGPARAMS *) lParam;
  1550. FillRegionList(psiteparam, hwnd);
  1551. FillSiteList(psiteparam, hwnd);
  1552. return FALSE;
  1553. case WM_COMMAND:
  1554. psiteparam = (SITEDLGPARAMS *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
  1555. switch (LOWORD(wParam))
  1556. {
  1557. case IDOK:
  1558. // get the region
  1559. ComboBox_GetText(GetDlgItem(hwnd, IDC_REGIONS), psiteparam->pszRegion, MAX_PATH);
  1560. psiteparam->uFirstSite = (UINT)ListBox_GetItemData(GetDlgItem(hwnd, IDC_SITES),
  1561. ListBox_GetCurSel(GetDlgItem(hwnd, IDC_SITES)));
  1562. EndDialog(hwnd, IDOK);
  1563. break;
  1564. case IDC_REGIONS:
  1565. if (HIWORD(wParam) == CBN_SELCHANGE)
  1566. {
  1567. FillSiteList(psiteparam, hwnd);
  1568. }
  1569. break;
  1570. default:
  1571. return FALSE;
  1572. }
  1573. break;
  1574. default:
  1575. return(FALSE);
  1576. }
  1577. return TRUE;
  1578. }
  1579. void CInstallEngineCtl::_PickRegionAndFirstSite(IDownloadSite **ppISite, UINT uNumSites, LPSTR szRegion, UINT *puFirstSite)
  1580. {
  1581. SITEDLGPARAMS siteparam;
  1582. siteparam.ppISite = ppISite;
  1583. siteparam.uNumSites = uNumSites;
  1584. siteparam.pszRegion = szRegion;
  1585. DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_SITELIST), _pProgDlg ? _pProgDlg->GetHWND() : m_hwnd,
  1586. SiteListDlgProc, (LPARAM)&siteparam);
  1587. *puFirstSite = siteparam.uFirstSite;
  1588. _WriteRegionToReg(siteparam.pszRegion);
  1589. }
  1590. HRESULT CInstallEngineCtl::_CheckInstallPath(BOOL *pfNeedWebSites)
  1591. {
  1592. // MAX_PATH and enough to hold "file://" (if needed)
  1593. char szBuf[MAX_PATH + 10];
  1594. HKEY hKey = NULL;
  1595. DWORD dwSize;
  1596. *pfNeedWebSites = FALSE;
  1597. HRESULT hr = NOERROR;
  1598. if(!_PathIsIEInstallPoint(_szDownloadDir))
  1599. {
  1600. // If Win9x, turn-off the AutoRun thing before showing the Dlg.
  1601. if (g_fSysWin95)
  1602. g_ulOldAutorunSetting = SetAutorunSetting((unsigned long)WINDOWS_AUTOPLAY_OFF);
  1603. // create and show the dialog
  1604. INT_PTR ret = DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_LOCATE), m_hwnd,
  1605. LocationDlgProc, (LPARAM)this);
  1606. // Now reset the AutoRun settings for Win9x
  1607. if (g_fSysWin95)
  1608. SetAutorunSetting(g_ulOldAutorunSetting);
  1609. if(ret == IDCANCEL)
  1610. {
  1611. hr = E_ABORT;
  1612. }
  1613. else if(ret == IDC_INTERNET)
  1614. {
  1615. *pfNeedWebSites = TRUE;
  1616. }
  1617. else
  1618. {
  1619. // mike wants to copy new _szDownloadDir back into the registry...
  1620. // take what we have and replace the current baseurl with it
  1621. if(_rpszUrlList[0])
  1622. {
  1623. delete _rpszUrlList[0];
  1624. _rpszUrlList[0] = 0;
  1625. }
  1626. lstrcpy(szBuf, "file://");
  1627. lstrcat(szBuf, _szDownloadDir);
  1628. _rpszUrlList[0] = new char[lstrlen(szBuf) + 1];
  1629. if(_rpszUrlList[0])
  1630. {
  1631. lstrcpy(_rpszUrlList[0], szBuf);
  1632. _pinseng->SetBaseUrl(_rpszUrlList[0]);
  1633. }
  1634. else
  1635. hr = E_OUTOFMEMORY;
  1636. }
  1637. }
  1638. return hr;
  1639. }
  1640. //=--------------------------------------------------------------------------=
  1641. // Function name here
  1642. //=--------------------------------------------------------------------------=
  1643. // Function description
  1644. //
  1645. // Parameters:
  1646. //
  1647. // Returns:
  1648. //
  1649. // Notes: For the CD AutoSplash suppression code, the values for iHandledAutoCD are
  1650. // iHandledAutoCD == -1 ===> no need to suppress AutoCD.
  1651. // iHandledAutoCD == 0 ===> need to suppress but not suppressed yet
  1652. // iHandledAutoCD == 1 ===> finished suppressing AutoCD.
  1653. //=--------------------------------------------------------------------------=
  1654. #define AUTOCD_WAIT 30
  1655. #define AUTOCD_SLEEP 500
  1656. INT_PTR CALLBACK LocationDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1657. {
  1658. // Code to suppress the AutoRun when the CD is inserted.
  1659. static HCURSOR hCurOld = NULL;
  1660. static int iHandledAutoCD = -1; // -1 ==> do not need to suppress AutoCD
  1661. static int iCount = 0;
  1662. CInstallEngineCtl *pctl = (CInstallEngineCtl *) GetWindowLongPtr(hDlg, DWLP_USER);
  1663. // Special case handling for the Autorun message.
  1664. // When this dialog receives the AutoRun message, suppres it.
  1665. if ( uMsg == g_uCDAutorunMsg)
  1666. {
  1667. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LONG_PTR)1);
  1668. iHandledAutoCD = 1; // 1 ==> finished suppressing the AutoCD Splash
  1669. return TRUE;
  1670. }
  1671. switch(uMsg)
  1672. {
  1673. case WM_INITDIALOG:
  1674. {
  1675. char szBuf[MAX_PATH];
  1676. char szBuf2[MAX_PATH];
  1677. UINT drvType;
  1678. HWND hwndCb = GetDlgItem(hDlg, IDC_LOCATIONLIST);
  1679. int defSelect = 0;
  1680. int pos;
  1681. LPSTR psz = NULL;
  1682. // Setup the default behaviour for AutoCD suppression
  1683. iHandledAutoCD = -1; // -1 ==> do not need to suppress AutoCD
  1684. pctl = (CInstallEngineCtl *) lParam;
  1685. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pctl);
  1686. pctl->_pinseng->GetDisplayName(NULL, &psz);
  1687. SetWindowText(hDlg, psz);
  1688. szBuf2[0] = 0;
  1689. if(pctl->_uInstallMode == CDINSTALL)
  1690. {
  1691. // Only if this dialog involves CD insertion, do we need to bother about
  1692. // CDINSTALL - need to handle AutoRun suppression.
  1693. // This method is needed only if we are running on NT.
  1694. if ( g_fSysWinNT )
  1695. iHandledAutoCD = 0; // 0 ==> we need to suppress, but not suppressed yet.
  1696. LoadSz(IDS_CDNOTFOUND, szBuf, sizeof(szBuf));
  1697. SetDlgItemText(hDlg, IDC_TEXT1, szBuf);
  1698. if(LoadSz(IDS_CDPLEASEINSERT, szBuf, sizeof(szBuf)))
  1699. wsprintf(szBuf2, szBuf, psz);
  1700. SetDlgItemText(hDlg, IDC_TEXT2, szBuf2);
  1701. lstrcpy(szBuf, "x:\\");
  1702. for(char chDir = 'A'; chDir <= 'Z'; chDir++)
  1703. {
  1704. szBuf[0] = chDir;
  1705. drvType = GetDriveType(szBuf);
  1706. if(drvType != DRIVE_UNKNOWN && drvType != DRIVE_NO_ROOT_DIR)
  1707. {
  1708. pos = ComboBox_AddString(hwndCb, szBuf);
  1709. if(ANSIStrStrI(pctl->_szDownloadDir, szBuf))
  1710. defSelect = pos;
  1711. }
  1712. }
  1713. }
  1714. else
  1715. {
  1716. LoadSz(IDS_NETWORKNOTFOUND, szBuf, sizeof(szBuf));
  1717. SetDlgItemText(hDlg, IDC_TEXT1, szBuf);
  1718. if(LoadSz(IDS_NETWORKPLEASEFIND, szBuf, sizeof(szBuf)))
  1719. wsprintf(szBuf2, szBuf, psz);
  1720. SetDlgItemText(hDlg, IDC_TEXT2, szBuf2);
  1721. ComboBox_AddString(hwndCb, pctl->_szDownloadDir);
  1722. defSelect = 0;
  1723. }
  1724. // add internet to list
  1725. // it is important that the internet is last; we depend on it later
  1726. LoadSz(IDS_INTERNET, szBuf, sizeof(szBuf));
  1727. ComboBox_AddString(hwndCb, szBuf);
  1728. ComboBox_SetCurSel(hwndCb, defSelect);
  1729. if(psz)
  1730. CoTaskMemFree(psz);
  1731. }
  1732. return TRUE;
  1733. case WM_COMMAND:
  1734. switch (LOWORD(wParam))
  1735. {
  1736. case IDC_BROWSE:
  1737. {
  1738. char szBuf[MAX_PATH];
  1739. char szBuf2[MAX_PATH];
  1740. HWND hwndCb = GetDlgItem(hDlg, IDC_LOCATIONLIST);
  1741. LPSTR psz;
  1742. szBuf2[0] = 0;
  1743. pctl->_pinseng->GetDisplayName(NULL, &psz);
  1744. if(LoadSz(IDS_FINDFOLDER, szBuf, sizeof(szBuf)))
  1745. wsprintf(szBuf2, szBuf, psz);
  1746. szBuf[0] = 0;
  1747. ComboBox_GetText(hwndCb, szBuf, sizeof(szBuf));
  1748. if(BrowseForDir(hDlg, szBuf, szBuf2))
  1749. {
  1750. ComboBox_SetText(hwndCb, szBuf);
  1751. }
  1752. if(psz)
  1753. CoTaskMemFree(psz);
  1754. }
  1755. break;
  1756. case IDOK:
  1757. {
  1758. HWND hwndCb = GetDlgItem(hDlg, IDC_LOCATIONLIST);
  1759. char szBuf[MAX_PATH];
  1760. char szBuf2[MAX_PATH];
  1761. // If User selected INTERNET, go on irresepective of CD or not.
  1762. // I am counting on the fact that the last item I added was internet!
  1763. int iSel = ComboBox_GetCurSel(hwndCb);
  1764. if(iSel == ComboBox_GetCount(hwndCb) - 1)
  1765. {
  1766. EndDialog(hDlg, IDC_INTERNET);
  1767. }
  1768. else
  1769. {
  1770. // If Splash suppression needs to be done, wait for it before continuing.
  1771. if ( iHandledAutoCD == 0 ) // i.e. need to suppress, but NOT suppressed yet.
  1772. {
  1773. // Change cursor to WAIT for the very first time only.
  1774. if (hCurOld == NULL)
  1775. hCurOld = SetCursor(LoadCursor(NULL,(IDC_WAIT)));
  1776. // Wait for the DlgBox to suppress the AutoCD (if possible)
  1777. if ( iHandledAutoCD != 1
  1778. && iCount < AUTOCD_WAIT )
  1779. {
  1780. Sleep(AUTOCD_SLEEP);
  1781. PostMessage(hDlg, uMsg, wParam, lParam);
  1782. iCount ++;
  1783. }
  1784. else
  1785. {
  1786. // Enough of waiting, pretend supressed and move on.
  1787. iHandledAutoCD = 1;
  1788. PostMessage(hDlg,uMsg,wParam,lParam);
  1789. }
  1790. }
  1791. else
  1792. {
  1793. if ( hCurOld )
  1794. {
  1795. // Now that we have finished waiting for suppression, restore cursor.
  1796. SetCursor(hCurOld);
  1797. hCurOld = NULL;
  1798. }
  1799. ComboBox_GetText(hwndCb, szBuf, sizeof(szBuf));
  1800. if(pctl->_uInstallMode == CDINSTALL)
  1801. {
  1802. if(lstrlen(szBuf) == 3)
  1803. {
  1804. // this is just drive letter. add dir to it
  1805. lstrcpy(szBuf + 3, pctl->_szDownloadDir + 3);
  1806. }
  1807. }
  1808. if(pctl->_PathIsIEInstallPoint(szBuf))
  1809. {
  1810. lstrcpy(pctl->_szDownloadDir, szBuf);
  1811. EndDialog(hDlg, IDOK);
  1812. }
  1813. else
  1814. {
  1815. // NOT VALID: Need to start again on this dialog.
  1816. LPSTR psz;
  1817. pctl->_pinseng->GetDisplayName(NULL, &psz);
  1818. LoadSz(IDS_NOTVALIDLOCATION, szBuf, sizeof(szBuf));
  1819. wsprintf(szBuf2, szBuf, psz);
  1820. MessageBox(hDlg, szBuf2, psz, MB_OK | MB_ICONSTOP);
  1821. // If there was a need for AutoSplash suppression on our way here, we need to
  1822. // re-initialize our need to AutoSplash suppression for the next round.
  1823. if ( iHandledAutoCD != -1) // -1 ==> No suppression required.
  1824. {
  1825. iHandledAutoCD = 0;
  1826. hCurOld = NULL;
  1827. iCount = 0;
  1828. }
  1829. }
  1830. }
  1831. }
  1832. }
  1833. break;
  1834. case IDCANCEL:
  1835. EndDialog(hDlg, IDCANCEL);
  1836. break;
  1837. default:
  1838. return FALSE;
  1839. }
  1840. break;
  1841. default:
  1842. return FALSE;
  1843. }
  1844. return TRUE;
  1845. }
  1846. BOOL CInstallEngineCtl::_PathIsIEInstallPoint(LPCSTR pszPath)
  1847. {
  1848. // in the future this can actually check the path for the files we need
  1849. return(GetFileAttributes(pszPath) != 0xffffffff);
  1850. }
  1851. //=--------------------------------------------------------------------------=
  1852. // Function name here
  1853. //=--------------------------------------------------------------------------=
  1854. // Function description
  1855. //
  1856. // Parameters:
  1857. //
  1858. // Returns:
  1859. //
  1860. // Notes:
  1861. //
  1862. STDMETHODIMP CInstallEngineCtl::FinalizeInstall(long lFlags)
  1863. {
  1864. if(lFlags & FINALIZE_DOREBOOT)
  1865. {
  1866. if(_fNeedReboot)
  1867. {
  1868. MyRestartDialog(m_hwnd, !(lFlags & FINALIZE_NOREBOOTPROMPT));
  1869. }
  1870. }
  1871. return NOERROR;
  1872. }
  1873. //=--------------------------------------------------------------------------=
  1874. // Function name here
  1875. //=--------------------------------------------------------------------------=
  1876. // Function description
  1877. //
  1878. // Parameters:
  1879. //
  1880. // Returns:
  1881. //
  1882. // Notes:
  1883. //
  1884. STDMETHODIMP CInstallEngineCtl::HandleEngineProblem(long lAction)
  1885. {
  1886. _dwAction = (DWORD) lAction;
  1887. return NOERROR;
  1888. }
  1889. STDMETHODIMP CInstallEngineCtl::CheckFreeSpace(long lPad, long FAR* lEnough)
  1890. {
  1891. *lEnough = 1;
  1892. _uInstallPad = lPad;
  1893. return NOERROR;
  1894. }
  1895. BOOL CInstallEngineCtl::_IsEnoughSpace(LPSTR szSpace1, DWORD dwSize1, LPSTR szSpace2, DWORD dwSize2,
  1896. LPSTR szSpace3, DWORD dwSize3)
  1897. {
  1898. COMPONENT_SIZES cs;
  1899. char szRoot[5] = "?:\\";
  1900. BOOL fEnough = TRUE;
  1901. char szBuf[MAX_DISPLAYNAME_LENGTH];
  1902. UINT pArgs[2];
  1903. cs.cbSize = sizeof(COMPONENT_SIZES);
  1904. // clear out strings
  1905. szSpace1[0] = 0;
  1906. szSpace2[0] = 0;
  1907. szSpace3[0] = 0;
  1908. if(SUCCEEDED(_pinseng->GetSizes(NULL, &cs)))
  1909. {
  1910. if(cs.chWinDrive)
  1911. {
  1912. szRoot[0] = cs.chWinDrive;
  1913. if(GetSpace(szRoot) < (DWORD) (_uInstallPad + (long) cs.dwWinDriveReq))
  1914. {
  1915. LoadSz(IDS_DISKSPACE, szBuf, sizeof(szBuf));
  1916. pArgs[0] = (UINT) cs.dwWinDriveReq + _uInstallPad;
  1917. pArgs[1] = (UINT) szRoot[0];
  1918. FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1919. (LPCVOID) szBuf, 0, 0, szSpace1, dwSize1, (va_list *) pArgs);
  1920. fEnough = FALSE;
  1921. }
  1922. }
  1923. if(cs.chInstallDrive)
  1924. {
  1925. szRoot[0] = cs.chInstallDrive;
  1926. if(GetSpace(szRoot) < cs.dwInstallDriveReq)
  1927. {
  1928. LoadSz(IDS_DISKSPACE, szBuf, sizeof(szBuf));
  1929. pArgs[0] = (UINT) cs.dwInstallDriveReq;
  1930. pArgs[1] = (UINT) szRoot[0];
  1931. FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1932. (LPCVOID) szBuf, 0, 0, szSpace2, dwSize2, (va_list *) pArgs);
  1933. fEnough = FALSE;
  1934. }
  1935. }
  1936. if(cs.chDownloadDrive)
  1937. {
  1938. szRoot[0] = cs.chDownloadDrive;
  1939. if(GetSpace(szRoot) < cs.dwDownloadDriveReq)
  1940. {
  1941. LoadSz(IDS_DISKSPACE, szBuf, sizeof(szBuf));
  1942. pArgs[0] = (UINT) cs.dwDownloadDriveReq;
  1943. pArgs[1] = (UINT) szRoot[0];
  1944. FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1945. (LPCVOID) szBuf, 0, 0, szSpace3, dwSize3, (va_list *) pArgs);
  1946. fEnough = FALSE;
  1947. }
  1948. }
  1949. }
  1950. else
  1951. fEnough = FALSE;
  1952. return fEnough;
  1953. }
  1954. HRESULT CInstallEngineCtl::_CheckForDiskSpace()
  1955. {
  1956. HRESULT hr = NOERROR;
  1957. char szBuf1[MAX_DISPLAYNAME_LENGTH];
  1958. char szBuf2[MAX_DISPLAYNAME_LENGTH];
  1959. char szBuf3[MAX_DISPLAYNAME_LENGTH];
  1960. if(!_IsEnoughSpace(szBuf1, sizeof(szBuf1),szBuf2, sizeof(szBuf2), szBuf3, sizeof(szBuf3) ))
  1961. hr = _ShowDiskSpaceDialog();
  1962. return hr;
  1963. }
  1964. HRESULT CInstallEngineCtl::_ShowDiskSpaceDialog()
  1965. {
  1966. HWND hwnd;
  1967. if(_pProgDlg)
  1968. hwnd = _pProgDlg->GetHWND();
  1969. else
  1970. hwnd = m_hwnd;
  1971. // create and show the dialog
  1972. INT_PTR ret = DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_DISKSPACE), hwnd,
  1973. DiskSpaceDlgProc, (LPARAM) this);
  1974. if(ret == IDOK)
  1975. return NOERROR;
  1976. else
  1977. return E_ABORT;
  1978. }
  1979. //=--------------------------------------------------------------------------=
  1980. // Function name here
  1981. //=--------------------------------------------------------------------------=
  1982. // Function description
  1983. //
  1984. // Parameters:
  1985. //
  1986. // Returns:
  1987. //
  1988. // Notes:
  1989. //
  1990. //=--------------------------------------------------------------------------=
  1991. // Function name here
  1992. //=--------------------------------------------------------------------------=
  1993. // Function description
  1994. //
  1995. // Parameters:
  1996. //
  1997. // Returns:
  1998. //
  1999. // Notes:
  2000. INT_PTR CALLBACK DiskSpaceDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2001. {
  2002. CInstallEngineCtl *pctl = (CInstallEngineCtl *) GetWindowLongPtr(hDlg, DWLP_USER);
  2003. switch(uMsg)
  2004. {
  2005. case WM_INITDIALOG:
  2006. {
  2007. char szBuf1[MAX_DISPLAYNAME_LENGTH];
  2008. char szBuf2[MAX_DISPLAYNAME_LENGTH];
  2009. char szBuf3[MAX_DISPLAYNAME_LENGTH];
  2010. pctl = (CInstallEngineCtl *) lParam;
  2011. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pctl);
  2012. pctl->_IsEnoughSpace(szBuf1, sizeof(szBuf1), szBuf2, sizeof(szBuf2), szBuf3, sizeof(szBuf3));
  2013. SetDlgItemText(hDlg, IDC_SPACE1, szBuf1);
  2014. SetDlgItemText(hDlg, IDC_SPACE2, szBuf2);
  2015. SetDlgItemText(hDlg, IDC_SPACE3, szBuf3);
  2016. }
  2017. return TRUE;
  2018. case WM_COMMAND:
  2019. switch (LOWORD(wParam))
  2020. {
  2021. case IDOK:
  2022. {
  2023. char szBuf1[MAX_DISPLAYNAME_LENGTH];
  2024. char szBuf2[MAX_DISPLAYNAME_LENGTH];
  2025. char szBuf3[MAX_DISPLAYNAME_LENGTH];
  2026. if(!pctl->_IsEnoughSpace(szBuf1, sizeof(szBuf1), szBuf2, sizeof(szBuf2), szBuf3, sizeof(szBuf3)))
  2027. {
  2028. SetDlgItemText(hDlg, IDC_SPACE1, szBuf1);
  2029. SetDlgItemText(hDlg, IDC_SPACE2, szBuf2);
  2030. SetDlgItemText(hDlg, IDC_SPACE3, szBuf3);
  2031. }
  2032. else
  2033. EndDialog(hDlg, IDOK);
  2034. }
  2035. break;
  2036. case IDCANCEL:
  2037. EndDialog(hDlg, IDCANCEL);
  2038. break;
  2039. default:
  2040. return FALSE;
  2041. }
  2042. break;
  2043. default:
  2044. return FALSE;
  2045. }
  2046. return TRUE;
  2047. }
  2048. //=--------------------------------------------------------------------------=
  2049. // Function name here
  2050. //=--------------------------------------------------------------------------=
  2051. // Function description
  2052. //
  2053. // Parameters:
  2054. //
  2055. // Returns:
  2056. //
  2057. // Notes:
  2058. //
  2059. STDMETHODIMP CInstallEngineCtl::OnEngineStatusChange(DWORD dwEngineStatus, DWORD sub)
  2060. {
  2061. BOOL fSetEvent = FALSE;
  2062. if((_dwOldStatus == ENGINESTATUS_LOADING)&&(_dwOldStatus != dwEngineStatus))
  2063. {
  2064. if (_dwMSTrustKey != (DWORD)-1)
  2065. {
  2066. WriteMSTrustKey(FALSE, _dwMSTrustKey);
  2067. }
  2068. _dwMSTrustKey = (DWORD)-1;
  2069. }
  2070. if((_dwOldStatus == ENGINESTATUS_LOADING) && (_dwOldStatus != dwEngineStatus) && _hDone)
  2071. {
  2072. _hResult = sub;
  2073. fSetEvent = TRUE;
  2074. }
  2075. else
  2076. {
  2077. if(_dwFreezeEvents)
  2078. {
  2079. _fEventToFire = TRUE;
  2080. _dwSavedEngineStatus = dwEngineStatus;
  2081. _dwSavedSubStatus = sub;
  2082. }
  2083. else
  2084. {
  2085. _FireEngineStatusChange(dwEngineStatus, sub);
  2086. }
  2087. }
  2088. _dwOldStatus = dwEngineStatus;
  2089. if(fSetEvent)
  2090. SetEvent(_hDone);
  2091. return NOERROR;
  2092. }
  2093. //=--------------------------------------------------------------------------=
  2094. // Function name here
  2095. //=--------------------------------------------------------------------------=
  2096. // Function description
  2097. //
  2098. // Parameters:
  2099. //
  2100. // Returns:
  2101. //
  2102. // Notes:
  2103. //
  2104. void CInstallEngineCtl::_FireEngineStatusChange(DWORD dwEngineStatus, DWORD sub)
  2105. {
  2106. CALLBACK_PARAMS cbp = { 0 };
  2107. cbp.dwStatus = dwEngineStatus;
  2108. cbp.dwSubstatus = sub;
  2109. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONENGINESTATUSCHANGE, (LPARAM) &cbp);
  2110. }
  2111. //=--------------------------------------------------------------------------=
  2112. // Function name here
  2113. //=--------------------------------------------------------------------------=
  2114. // Function description
  2115. //
  2116. // Parameters:
  2117. //
  2118. // Returns:
  2119. //
  2120. // Notes:
  2121. //
  2122. STDMETHODIMP CInstallEngineCtl::OnStartInstall(DWORD dwDLSize, DWORD dwTotalSize)
  2123. {
  2124. if(_pszErrorString)
  2125. {
  2126. // if we get OnStartInstall and we are installing,
  2127. // We intentionally swallow this onStartInstall
  2128. if(_pProgDlg)
  2129. _pProgDlg->SetInsProgGoal(dwTotalSize);
  2130. }
  2131. else
  2132. {
  2133. // this is OnStartInstall for download
  2134. if(_pProgDlg)
  2135. _pProgDlg->SetDownloadProgGoal(dwDLSize);
  2136. _FireOnStartInstallEvent(dwDLSize);
  2137. }
  2138. return NOERROR;
  2139. }
  2140. //=--------------------------------------------------------------------------=
  2141. // Function name here
  2142. //=--------------------------------------------------------------------------=
  2143. // Function description
  2144. //
  2145. // Parameters:
  2146. //
  2147. // Returns:
  2148. //
  2149. // Notes:
  2150. //
  2151. void CInstallEngineCtl::_FireOnStartInstallEvent(DWORD dwTotalSize)
  2152. {
  2153. CALLBACK_PARAMS cbp = { 0 };
  2154. cbp.dwSize = dwTotalSize;
  2155. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONSTARTINSTALL, (LPARAM) &cbp);
  2156. }
  2157. void CInstallEngineCtl::_FireOnStartInstallExEvent(DWORD dwDLSize, DWORD dwInsSize)
  2158. {
  2159. CALLBACK_PARAMS cbp = { 0 };
  2160. cbp.dwSize = dwInsSize;
  2161. cbp.dwDL = dwDLSize;
  2162. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONSTARTINSTALLEX, (LPARAM) &cbp);
  2163. }
  2164. //=--------------------------------------------------------------------------=
  2165. // Function name here
  2166. //=--------------------------------------------------------------------------=
  2167. // Function description
  2168. //
  2169. // Parameters:
  2170. //
  2171. // Returns:
  2172. //
  2173. // Notes:
  2174. //
  2175. STDMETHODIMP CInstallEngineCtl::OnStartComponent(LPCSTR pszID, DWORD dwDLSize,
  2176. DWORD dwInstallSize, LPCSTR pszName)
  2177. {
  2178. _strCurrentID = BSTRFROMANSI(pszID);
  2179. _strCurrentName = BSTRFROMANSI(pszName);
  2180. _strCurrentString = BSTRFROMANSI("");
  2181. _FireOnStartComponentEvent(pszID, dwDLSize, pszName);
  2182. return NOERROR;
  2183. }
  2184. //=--------------------------------------------------------------------------=
  2185. // Function name here
  2186. //=--------------------------------------------------------------------------=
  2187. // Function description
  2188. //
  2189. // Parameters:
  2190. //
  2191. // Returns:
  2192. //
  2193. // Notes:
  2194. //
  2195. STDMETHODIMP CInstallEngineCtl::OnEngineProblem(DWORD dwProblem, LPDWORD pdwAction)
  2196. {
  2197. HRESULT hr = S_FALSE;
  2198. if((dwProblem == ENGINEPROBLEM_DOWNLOADFAIL) && _rpszUrlList[0])
  2199. {
  2200. // if we have at least one url in list, do switching ourselves
  2201. if( ((_uCurrentUrl + 1) < MAX_URLS) && _rpszUrlList[_uCurrentUrl + 1])
  2202. {
  2203. _uCurrentUrl++;
  2204. _pinseng->SetBaseUrl(_rpszUrlList[_uCurrentUrl]);
  2205. *pdwAction = DOWNLOADFAIL_RETRY;
  2206. hr = S_OK;
  2207. }
  2208. }
  2209. else
  2210. {
  2211. _dwAction = 0;
  2212. _FireOnEngineProblem(dwProblem);
  2213. *pdwAction = _dwAction;
  2214. if(*pdwAction != 0)
  2215. hr = S_OK;
  2216. }
  2217. return hr;
  2218. }
  2219. //=--------------------------------------------------------------------------=
  2220. // Function name here
  2221. //=--------------------------------------------------------------------------=
  2222. // Function description
  2223. //
  2224. // Parameters:
  2225. //
  2226. // Returns:
  2227. //
  2228. // Notes:
  2229. //
  2230. void CInstallEngineCtl::_FireOnEngineProblem(DWORD dwProblem)
  2231. {
  2232. CALLBACK_PARAMS cbp = { 0 };
  2233. cbp.dwStatus = dwProblem;
  2234. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONENGINEPROBLEM, (LPARAM) &cbp);
  2235. }
  2236. //=--------------------------------------------------------------------------=
  2237. // Function name here
  2238. //=--------------------------------------------------------------------------=
  2239. // Function description
  2240. //
  2241. // Parameters:
  2242. //
  2243. // Returns:
  2244. //
  2245. // Notes:
  2246. //
  2247. void CInstallEngineCtl::_FireOnStartComponentEvent(LPCSTR pszID, DWORD dwTotalSize, LPCSTR pszName)
  2248. {
  2249. CALLBACK_PARAMS cbp = { 0 };
  2250. cbp.strID = BSTRFROMANSI(pszID);
  2251. cbp.strName = BSTRFROMANSI(pszName);
  2252. cbp.dwSize = dwTotalSize;
  2253. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONSTARTCOMPONENT, (LPARAM) &cbp);
  2254. SysFreeString(cbp.strID);
  2255. SysFreeString(cbp.strName);
  2256. }
  2257. //=--------------------------------------------------------------------------=
  2258. // Function name here
  2259. //=--------------------------------------------------------------------------=
  2260. // Function description
  2261. //
  2262. // Parameters:
  2263. //
  2264. // Returns:
  2265. //
  2266. // Notes:
  2267. //
  2268. STDMETHODIMP CInstallEngineCtl::OnComponentProgress(LPCSTR pszID, DWORD dwPhase, LPCSTR pszString, LPCSTR pszMsgString, ULONG ulSofar, ULONG ulMax)
  2269. {
  2270. char szBuf[512];
  2271. char szRes[512];
  2272. // _FireOnComponentProgress(dwPhase, ulSofar, ulMax);
  2273. if(!_pProgDlg)
  2274. return NOERROR;
  2275. if(dwPhase != _dwLastPhase)
  2276. {
  2277. _dwLastPhase = dwPhase;
  2278. // Set up progress for this phase
  2279. UINT id;
  2280. switch(dwPhase)
  2281. {
  2282. case INSTALLSTATUS_INITIALIZING :
  2283. id = IDS_PREPARE;
  2284. break;
  2285. case INSTALLSTATUS_DOWNLOADING :
  2286. id = IDS_DOWNLOADING;
  2287. break;
  2288. case INSTALLSTATUS_EXTRACTING :
  2289. id = IDS_EXTRACTING;
  2290. break;
  2291. case INSTALLSTATUS_CHECKINGTRUST :
  2292. id = IDS_CHECKTRUST;
  2293. break;
  2294. case INSTALLSTATUS_RUNNING :
  2295. id = IDS_INSTALLING;
  2296. break;
  2297. default :
  2298. id = IDS_NOPHASE;
  2299. }
  2300. LoadSz(id, szRes, sizeof(szRes));
  2301. wsprintf(szBuf, szRes, pszString);
  2302. // Setup text for this phase
  2303. _pProgDlg->SetProgText(szBuf);
  2304. }
  2305. if(dwPhase == INSTALLSTATUS_DOWNLOADING)
  2306. _pProgDlg->SetDownloadProgress(ulSofar);
  2307. else if(dwPhase == INSTALLSTATUS_RUNNING)
  2308. _pProgDlg->SetInsProgress(ulSofar);
  2309. return NOERROR;
  2310. }
  2311. void CInstallEngineCtl::_FireOnComponentProgress(DWORD dwPhase, DWORD dwSoFar, DWORD dwTotal)
  2312. {
  2313. CALLBACK_PARAMS cbp = { 0 };
  2314. cbp.strID = _strCurrentID;
  2315. cbp.strName = _strCurrentName;
  2316. cbp.strString = _strCurrentString;
  2317. cbp.dwPhase = dwPhase;
  2318. cbp.dwSize = dwTotal;
  2319. cbp.dwDL = dwSoFar;
  2320. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONCOMPONENTPROGRESS, (LPARAM) &cbp);
  2321. }
  2322. //=--------------------------------------------------------------------------=
  2323. // Function name here
  2324. //=--------------------------------------------------------------------------=
  2325. // Function description
  2326. //
  2327. // Parameters:
  2328. //
  2329. // Returns:
  2330. //
  2331. // Notes:
  2332. //
  2333. STDMETHODIMP CInstallEngineCtl::OnStopComponent(LPCSTR pszID, HRESULT hrError, DWORD dwPhase, LPCSTR pszString, DWORD dwStatus)
  2334. {
  2335. char szBuf[512];
  2336. char szRes[512];
  2337. void *pTemp;
  2338. if(_strCurrentID)
  2339. {
  2340. SysFreeString(_strCurrentID);
  2341. _strCurrentID = NULL;
  2342. }
  2343. if(_strCurrentName)
  2344. {
  2345. SysFreeString(_strCurrentName);
  2346. _strCurrentName = NULL;
  2347. }
  2348. if(_strCurrentString)
  2349. {
  2350. SysFreeString(_strCurrentString);
  2351. _strCurrentString = NULL;
  2352. }
  2353. if(_pszErrorString)
  2354. {
  2355. if(FAILED(hrError))
  2356. {
  2357. // failed AND installing
  2358. UINT id;
  2359. switch(dwPhase)
  2360. {
  2361. case INSTALLSTATUS_INITIALIZING :
  2362. id = IDS_ERRPREPARE;
  2363. break;
  2364. case INSTALLSTATUS_DOWNLOADING :
  2365. case INSTALLSTATUS_COPYING :
  2366. id = IDS_ERRDOWNLOAD;
  2367. break;
  2368. case INSTALLSTATUS_DEPENDENCY :
  2369. id = IDS_ERRDEPENDENCY;
  2370. break;
  2371. case INSTALLSTATUS_EXTRACTING :
  2372. id = IDS_ERREXTRACTING;
  2373. break;
  2374. case INSTALLSTATUS_RUNNING :
  2375. id = IDS_ERRINSTALLING;
  2376. break;
  2377. case INSTALLSTATUS_CHECKINGTRUST :
  2378. id = IDS_ERRNOTTRUSTED;
  2379. break;
  2380. default :
  2381. id = IDS_NOPHASE;
  2382. }
  2383. LoadSz(id, szRes, sizeof(szRes));
  2384. }
  2385. else
  2386. {
  2387. LoadSz(IDS_SUCCEEDED, szRes, sizeof(szRes));
  2388. }
  2389. // After loading the appropriate message into szRes, now tag it to _pszErrorString.
  2390. // Make sure that _pszErrorString is big enough for the new data being appended
  2391. wsprintf(szBuf, szRes, pszString);
  2392. // This is assuming only ANSI characters. None of the strings in this control must be UNICODE!!
  2393. if ( lstrlen(szBuf) >= (_iErrorStringSize - lstrlen(_pszErrorString)) )
  2394. {
  2395. // Realloc _pszErrorString by ERROR_STRING_INCREMENT
  2396. pTemp = realloc(_pszErrorString, _iErrorStringSize + ERROR_STRING_INCREMENT);
  2397. if ( pTemp != NULL )
  2398. { // realloc succeeded. Update the string pointer and sizes.
  2399. _pszErrorString = (char *) pTemp;
  2400. _iErrorStringSize += ERROR_STRING_INCREMENT;
  2401. }
  2402. else
  2403. { // No memory. Abandon summary logging.
  2404. free(_pszErrorString);
  2405. _pszErrorString = NULL;
  2406. }
  2407. }
  2408. if (_pszErrorString)
  2409. lstrcat(_pszErrorString, szBuf);
  2410. }
  2411. if ( FAILED(hrError) && hrError != E_ABORT &&
  2412. (dwPhase == INSTALLSTATUS_DOWNLOADING || dwPhase == INSTALLSTATUS_CHECKINGTRUST) )
  2413. {
  2414. _bDeleteURLList = TRUE;
  2415. }
  2416. _FireOnStopComponentEvent(pszID, hrError, dwPhase, pszString, dwStatus);
  2417. return NOERROR;
  2418. }
  2419. //=--------------------------------------------------------------------------=
  2420. // Function name here
  2421. //=--------------------------------------------------------------------------=
  2422. // Function description
  2423. //
  2424. // Parameters:
  2425. //
  2426. // Returns:
  2427. //
  2428. // Notes:
  2429. //
  2430. void CInstallEngineCtl::_FireOnStopComponentEvent(LPCSTR pszID, HRESULT hrError, DWORD dwPhase, LPCSTR pszString, DWORD dwStatus)
  2431. {
  2432. CALLBACK_PARAMS cbp = { 0 };
  2433. cbp.strID = BSTRFROMANSI(pszID);
  2434. cbp.strName = BSTRFROMANSI(pszString);
  2435. cbp.dwResult = (DWORD) hrError;
  2436. cbp.dwPhase = dwPhase;
  2437. cbp.dwStatus = dwStatus;
  2438. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONSTOPCOMPONENT, (LPARAM) &cbp);
  2439. SysFreeString(cbp.strID);
  2440. SysFreeString(cbp.strName);
  2441. }
  2442. //=--------------------------------------------------------------------------=
  2443. // Function name here
  2444. //=--------------------------------------------------------------------------=
  2445. // Function description
  2446. //
  2447. // Parameters:
  2448. //
  2449. // Returns:
  2450. //
  2451. // Notes:
  2452. //
  2453. STDMETHODIMP CInstallEngineCtl::OnStopInstall(HRESULT hrError, LPCSTR szError, DWORD dwStatus)
  2454. {
  2455. _hResult = hrError;
  2456. _dwInstallStatus = dwStatus;
  2457. if ( _bDeleteURLList )
  2458. _DeleteURLList();
  2459. else
  2460. if ( _bNewWebSites )
  2461. _WriteURLList();
  2462. SetEvent(_hDone);
  2463. return NOERROR;
  2464. }
  2465. //=--------------------------------------------------------------------------=
  2466. // Function name here
  2467. //=--------------------------------------------------------------------------=
  2468. // Function description
  2469. //
  2470. // Parameters:
  2471. //
  2472. // Returns:
  2473. //
  2474. // Notes:
  2475. //
  2476. void CInstallEngineCtl::_FireOnStopInstallEvent(HRESULT hrError, LPCSTR szError, DWORD dwStatus)
  2477. {
  2478. CALLBACK_PARAMS cbp = { 0 };
  2479. cbp.dwResult = (DWORD) hrError;
  2480. cbp.dwStatus = dwStatus;
  2481. cbp.strString = BSTRFROMANSI( szError ? szError : "");
  2482. SendMessage(m_hwnd, WM_INSENGCALLBACK, (WPARAM) EVENT_ONSTOPINSTALL, (LPARAM) &cbp);
  2483. SysFreeString(cbp.strString);
  2484. }
  2485. void CInstallEngineCtl::MarkJITInstall()
  2486. {
  2487. HRESULT hr = S_OK;
  2488. IOleClientSite *pClientSite = NULL;
  2489. IHTMLDocument2 *pDoc = NULL;
  2490. BSTR bstrURL = NULL;
  2491. IOleContainer *pContainer = NULL;
  2492. hr = GetClientSite(&pClientSite);
  2493. if (SUCCEEDED(hr))
  2494. {
  2495. hr = pClientSite->GetContainer(&pContainer);
  2496. if (SUCCEEDED(hr))
  2497. {
  2498. hr = pContainer->QueryInterface(IID_IHTMLDocument2, (LPVOID *)&pDoc);
  2499. if (SUCCEEDED(hr))
  2500. {
  2501. hr = pDoc->get_URL(&bstrURL);
  2502. if (SUCCEEDED(hr) && bstrURL)
  2503. {
  2504. HKEY hKeyActiveSetup;
  2505. char szJITPage[INTERNET_MAX_URL_LENGTH] = "";
  2506. DWORD dwSize = INTERNET_MAX_URL_LENGTH;
  2507. DWORD dwType;
  2508. BSTR bstrJITPage = NULL;
  2509. if (ERROR_SUCCESS == RegOpenKeyEx(
  2510. HKEY_LOCAL_MACHINE,
  2511. TEXT("Software\\Microsoft\\Active Setup"),
  2512. 0,
  2513. KEY_READ,
  2514. &hKeyActiveSetup))
  2515. {
  2516. if (ERROR_SUCCESS == RegQueryValueEx(
  2517. hKeyActiveSetup,
  2518. TEXT("JITSetupPage"),
  2519. NULL,
  2520. &dwType,
  2521. (LPBYTE) szJITPage,
  2522. &dwSize
  2523. ))
  2524. {
  2525. bstrJITPage = BSTRFROMANSI(szJITPage);
  2526. if (bstrJITPage)
  2527. {
  2528. if (0 == lstrcmpiW(bstrJITPage, bstrURL))
  2529. {
  2530. // If the URL points to an internal resource,
  2531. // it's probably safe to assume this is a JIT install.
  2532. _fJITInstall = TRUE;
  2533. }
  2534. SysFreeString(bstrJITPage);
  2535. }
  2536. }
  2537. RegCloseKey(hKeyActiveSetup);
  2538. }
  2539. SysFreeString(bstrURL);
  2540. }
  2541. pDoc->Release();
  2542. }
  2543. pContainer->Release();
  2544. }
  2545. pClientSite->Release();
  2546. }
  2547. }
  2548. DWORD WINAPI DoInstall(LPVOID pv)
  2549. {
  2550. CInstallEngineCtl *p = (CInstallEngineCtl *) pv;
  2551. HRESULT hr = CoInitialize(NULL);
  2552. p->_DoInstall();
  2553. if(SUCCEEDED(hr))
  2554. CoUninitialize();
  2555. return 0;
  2556. }