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.

2053 lines
55 KiB

  1. #include <cdlpch.h>
  2. #include <windows.h>
  3. #include <objbase.h>
  4. #include <winbase.h>
  5. #include <softpub.h>
  6. #include "capi.h"
  7. //#include <stdlib.h>
  8. #include <stdio.h>
  9. //#include <stdlib.h>
  10. //#include <string.h>
  11. //#include <tchar.h>
  12. #include <crtdbg.h>
  13. #include <urlmon.h>
  14. #include <wininet.h>
  15. #include <shellapi.h>
  16. #include <commctrl.h>
  17. #include <shlwapi.h>
  18. #include <shfusion.h>
  19. #include "webjitres.h"
  20. #include "webjit.h"
  21. #include "mluisupp.h"
  22. #undef SAFERELEASE
  23. #define SAFERELEASE(p) if ((p) != NULL) { (p)->Release(); (p) = NULL; };
  24. #undef SAFEDELETE
  25. #define SAFEDELETE(p) if ((p) != NULL) { delete (p); (p) = NULL; };
  26. #undef ARRAY_ELEMENTS
  27. #define ARRAY_ELEMENTS(array) \
  28. (sizeof(array)/sizeof(array[0]))
  29. BOOL IsUIRestricted();
  30. BOOL IsWin32X86();
  31. BOOL IsNTAdmin();
  32. extern BOOL g_bLockedDown;
  33. extern HMODULE g_hInst;
  34. HRESULT EnsureSecurityManager ();
  35. CWebJit::CWebJit(WEBJIT_PARAM* pWebJitParam)
  36. {
  37. DEBUG_ENTER((DBG_DOWNLOAD,
  38. None,
  39. "CWebJit::CWebJit",
  40. "this=%#x, %.200q, %.200wq, %#x, %#x",
  41. this, pWebJitParam->lpszResource, pWebJitParam->pwszComponentId, pWebJitParam->dwFlags, pWebJitParam->hWndParent
  42. ));
  43. m_fInited = FALSE;
  44. m_hWintrustMod = NULL;
  45. m_fInitedCC = FALSE;
  46. m_hComCtlMod = NULL;
  47. m_szResource = pWebJitParam->lpszResource;
  48. m_dwFlags = pWebJitParam->dwFlags;
  49. m_pwszComponentId = pWebJitParam->pwszComponentId;
  50. m_hWndParent = pWebJitParam->hWndParent;
  51. m_pQueryInstalled = pWebJitParam->pQueryInstalled;
  52. m_pwszUrl = NULL;
  53. m_cRef = 1;
  54. m_dwTotal = m_dwCurrent = 0;
  55. m_hDialog = NULL;
  56. m_hProcess = 0;
  57. m_pBinding = NULL;
  58. m_pStm = NULL;
  59. m_pMk = NULL;
  60. m_pbc = NULL;
  61. m_hCacheFile = NULL;
  62. m_dwRetVal = 0;
  63. m_dwDownloadSpeed = 0;
  64. m_hDownloadResult = S_OK;
  65. m_fResultIn = FALSE;
  66. m_fAborted = FALSE;
  67. m_fCalledAbort = FALSE;
  68. m_State = WJSTATE_INIT;
  69. m_hrInternal = S_OK;
  70. m_pwszMimeType = NULL;
  71. m_pwszRedirectUrl = NULL;
  72. m_pwszCacheFile = NULL;
  73. m_fHtml = FALSE;
  74. m_fDownloadInited = FALSE;
  75. m_pTempBuffer = NULL;
  76. m_bReading = FALSE;
  77. m_bStartedReadTimer = FALSE;
  78. DEBUG_LEAVE(0);
  79. }
  80. CWebJit::~CWebJit()
  81. {
  82. DEBUG_ENTER((DBG_DOWNLOAD,
  83. None,
  84. "CWebJit::~CWebJit",
  85. "this=%#x, aborted?=%B, result=%#x, redirect=%.200wq, m_hProcess=%#x (%d)",
  86. this, m_fAborted, m_hDownloadResult, (m_pwszRedirectUrl ? m_pwszRedirectUrl : L"NONE"), m_hProcess, m_hProcess
  87. ));
  88. if (m_fInited)
  89. {
  90. FreeLibrary(m_hWintrustMod);
  91. }
  92. if (m_fInitedCC)
  93. {
  94. FreeLibrary(m_hComCtlMod);
  95. }
  96. if (m_hProcess)
  97. {
  98. CloseHandle(m_hProcess);
  99. }
  100. ReleaseAll();
  101. if (m_pwszUrl)
  102. delete [] m_pwszUrl;
  103. if (m_pwszMimeType)
  104. delete [] m_pwszMimeType;
  105. if (m_pwszCacheFile)
  106. delete [] m_pwszCacheFile;
  107. if (m_pwszRedirectUrl)
  108. delete [] m_pwszRedirectUrl;
  109. if (m_pTempBuffer)
  110. delete [] m_pTempBuffer;
  111. DEBUG_LEAVE(0);
  112. }
  113. VOID CWebJit::ReleaseAll()
  114. {
  115. DEBUG_ENTER((DBG_DOWNLOAD,
  116. None,
  117. "CWebJit::ReleaseAll",
  118. "this=%#x, %#x, %#x, %#x, %#x",
  119. this, m_pStm, m_pMk, m_pBinding, m_pbc
  120. ));
  121. SAFERELEASE(m_pStm);
  122. SAFERELEASE(m_pMk);
  123. SAFERELEASE(m_pBinding);
  124. SAFERELEASE(m_pbc);
  125. DEBUG_LEAVE(0);
  126. }
  127. STDMETHODIMP CWebJit::QueryInterface(REFIID riid, void ** ppv)
  128. {
  129. *ppv = NULL;
  130. if (riid == IID_IUnknown)
  131. {
  132. *ppv = (void*)this;
  133. }
  134. else if (riid == IID_IBindStatusCallback)
  135. {
  136. *ppv = (void*)(IBindStatusCallback*)this;
  137. }
  138. else if (riid == IID_IAuthenticate)
  139. {
  140. *ppv = (void*)(IAuthenticate*)this;
  141. }
  142. if (*ppv)
  143. {
  144. ((IUnknown *)*ppv)->AddRef();
  145. return S_OK;
  146. }
  147. return E_NOINTERFACE;
  148. }
  149. STDMETHODIMP_(ULONG) CWebJit::AddRef()
  150. {
  151. return m_cRef++;
  152. }
  153. STDMETHODIMP_(ULONG) CWebJit::Release()
  154. {
  155. if (--m_cRef == 0)
  156. {
  157. delete this;
  158. return 0;
  159. }
  160. return m_cRef;
  161. }
  162. // IBindStatusCallback methods
  163. STDMETHODIMP CWebJit::OnStartBinding(DWORD dwReserved, IBinding* pbinding)
  164. {
  165. if (m_fAborted)
  166. {
  167. goto abort;
  168. }
  169. m_pBinding = pbinding;
  170. m_pBinding->AddRef();
  171. return S_OK;
  172. abort:
  173. return E_FAIL;
  174. }
  175. STDMETHODIMP CWebJit::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR pwzStatusText)
  176. {
  177. DEBUG_ENTER((DBG_DOWNLOAD,
  178. Hresult,
  179. "CWebJit::OnProgress",
  180. "this=%#x, %#x, %#x, %d (%#x), %.200wq",
  181. this, ulProgress, ulProgressMax, ulStatusCode, ulStatusCode, pwzStatusText
  182. ));
  183. if (m_fAborted)
  184. {
  185. goto abort;
  186. }
  187. switch(ulStatusCode)
  188. {
  189. case BINDSTATUS_BEGINDOWNLOADDATA:
  190. {
  191. m_dwTotal = ulProgressMax;
  192. HWND hProgressBar = GetDlgItem(m_hDialog, IDC_PROGRESS1);
  193. if (m_dwTotal)
  194. {
  195. ShowWindow(hProgressBar, SW_SHOWNORMAL);
  196. ShowWindow(GetDlgItem(m_hDialog, IDC_REMAINING_SIZE), SW_SHOWNORMAL);
  197. ShowWindow(GetDlgItem(m_hDialog, IDC_REMAINING_TIME), SW_SHOWNORMAL);
  198. UpdateProgressUI();
  199. }
  200. SendMessage(hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,65535));
  201. }
  202. break;
  203. case BINDSTATUS_CACHEFILENAMEAVAILABLE:
  204. {
  205. //ASSERT (pwzStatusText && (*pwzStatusText != L'\0'));
  206. int nWideLen = lstrlenW(pwzStatusText);
  207. m_pwszCacheFile = new WCHAR[nWideLen+1];
  208. if (!m_pwszCacheFile)
  209. {
  210. m_hrInternal = E_OUTOFMEMORY;
  211. goto abort;
  212. }
  213. StrCpyW(m_pwszCacheFile, pwzStatusText);
  214. }
  215. break;
  216. case BINDSTATUS_MIMETYPEAVAILABLE:
  217. {
  218. //ASSERT (pwzStatusText && (*pwzStatusText != L'\0'));
  219. int nWideLen = lstrlenW(pwzStatusText);
  220. m_pwszMimeType = new WCHAR[nWideLen+1];
  221. if (!m_pwszMimeType)
  222. {
  223. m_hrInternal = E_OUTOFMEMORY;
  224. goto abort;
  225. }
  226. StrCpyW(m_pwszMimeType, pwzStatusText);
  227. }
  228. break;
  229. case BINDSTATUS_REDIRECTING:
  230. {
  231. //ASSERT (pwzStatusText && (*pwzStatusText != L'\0'));
  232. int nWideLen = lstrlenW(pwzStatusText);
  233. if (m_pwszRedirectUrl)
  234. {
  235. delete [] m_pwszRedirectUrl;
  236. }
  237. m_pwszRedirectUrl = new WCHAR[nWideLen+1];
  238. if (!m_pwszRedirectUrl)
  239. {
  240. m_hrInternal = E_OUTOFMEMORY;
  241. goto abort;
  242. }
  243. StrCpyW(m_pwszRedirectUrl, pwzStatusText);
  244. }
  245. break;
  246. }
  247. DEBUG_LEAVE(S_OK);
  248. return S_OK;
  249. abort:
  250. if (!m_fCalledAbort && m_pBinding)
  251. {
  252. m_pBinding->Abort();
  253. m_fCalledAbort = TRUE;
  254. }
  255. DEBUG_LEAVE(S_OK);
  256. return S_OK;
  257. }
  258. STDMETHODIMP CWebJit::OnStopBinding(HRESULT hrResult, LPCWSTR szError)
  259. {
  260. UpdateDownloadResult(hrResult, TRUE);
  261. return S_OK;
  262. }
  263. STDMETHODIMP CWebJit::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindInfo)
  264. {
  265. // clear BINDINFO but keep its size
  266. DWORD cbSize = pbindInfo->cbSize;
  267. memset(pbindInfo, 0, cbSize);
  268. pbindInfo->cbSize = cbSize;
  269. *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_RESYNCHRONIZE | BINDF_PREFERDEFAULTHANDLER | BINDF_NEEDFILE;
  270. pbindInfo->dwBindVerb = BINDVERB_GET;
  271. return S_OK;
  272. }
  273. STDMETHODIMP CWebJit::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pfmtetc, STGMEDIUM* pstgmed)
  274. {
  275. DEBUG_ENTER((DBG_DOWNLOAD,
  276. Dword,
  277. "CWebJit::OnDataAvailable",
  278. "this=%#x, %#x, %#x, %#x, %#x, %#x / %#x",
  279. this, grfBSCF, dwSize, pstgmed->pstm, pfmtetc->tymed, m_dwCurrent, m_dwTotal
  280. ));
  281. HRESULT hr;
  282. if (m_fAborted)
  283. {
  284. goto abort;
  285. }
  286. if (!m_pStm)
  287. {
  288. m_pStm = pstgmed->pstm;
  289. m_pStm->AddRef();
  290. }
  291. if (!m_hCacheFile && m_pBinding)
  292. {
  293. IWinInetHttpInfo* pHttpInfo = NULL;
  294. hr = QueryInterface(IID_IWinInetHttpInfo, (void**)&pHttpInfo);
  295. if (SUCCEEDED(hr))
  296. {
  297. DWORD dwSize = sizeof(m_hCacheFile);
  298. hr = pHttpInfo->QueryOption(WININETINFO_OPTION_LOCK_HANDLE, &m_hCacheFile, &dwSize);
  299. pHttpInfo->Release();
  300. }
  301. }
  302. PostMessage(m_hDialog, WM_DATA_AVAILABLE, 0, 0);
  303. DEBUG_LEAVE(m_dwCurrent);
  304. return S_OK;
  305. abort:
  306. if (!m_fCalledAbort && m_pBinding)
  307. {
  308. m_pBinding->Abort();
  309. m_fCalledAbort = TRUE;
  310. }
  311. DEBUG_LEAVE(E_ABORT);
  312. return S_OK;
  313. }
  314. VOID CWebJit::ReadData()
  315. {
  316. DEBUG_ENTER((DBG_DOWNLOAD,
  317. Dword,
  318. "CWebJit::ReadData",
  319. "this=%#x, %#x, %#x / %#x",
  320. this, m_pStm, m_dwCurrent, m_dwTotal
  321. ));
  322. HRESULT hr = E_FAIL;
  323. HRESULT hrAbort = S_OK;
  324. //reentrancy guard
  325. if (m_bReading)
  326. {
  327. goto leave;
  328. }
  329. m_bReading = TRUE;
  330. if (m_fAborted)
  331. {
  332. goto abort;
  333. }
  334. if (m_State >= WJSTATE_VERIFYING)
  335. {
  336. // redundant timer messages
  337. goto end;
  338. }
  339. HWND hProgressBar = GetDlgItem(m_hDialog, IDC_PROGRESS1);
  340. DWORD dwRead;
  341. hr = m_pStm->Read(m_pTempBuffer, TEMPREADBUFFERSIZE, &dwRead);
  342. if (SUCCEEDED(hr)
  343. || ( (hr == E_PENDING) && (dwRead > 0) ) )
  344. {
  345. m_dwCurrent += dwRead;
  346. //UpdateProgressUI();
  347. if (m_dwTotal)
  348. SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)((m_dwCurrent*1.00/m_dwTotal)*65535), 0);
  349. }
  350. end:
  351. // if we are done reading OR we have been aborted
  352. if (((hr == S_FALSE)
  353. && (m_dwTotal ? (m_dwCurrent == m_dwTotal) : TRUE))
  354. || (hr == E_ABORT))
  355. {
  356. // handle cases where Abort failed to prevent leak.
  357. if ((hrAbort == INET_E_RESULT_DISPATCHED)
  358. || (hrAbort == E_FAIL)
  359. && m_pStm)
  360. {
  361. HRESULT hrTemp;
  362. do
  363. {
  364. hrTemp = m_pStm->Read(m_pTempBuffer, TEMPREADBUFFERSIZE, &dwRead);
  365. if (SUCCEEDED(hrTemp)
  366. || ((hrTemp==E_PENDING) && (dwRead>0)))
  367. {
  368. m_dwCurrent += dwRead;
  369. }
  370. }
  371. while ((hrTemp == NOERROR) && m_pStm);
  372. }
  373. // and have already received OnStopBinding
  374. if (m_State == WJSTATE_DOWNLOADED)
  375. {
  376. if (m_pMk)
  377. {
  378. if (hr == E_ABORT)
  379. {
  380. m_hDownloadResult = E_ABORT;
  381. }
  382. //abort or finished read after osb.
  383. ReleaseAll();
  384. if (SUCCEEDED(m_hDownloadResult))
  385. {
  386. PostMessage(m_hDialog, WM_DOWNLOAD_DONE, 0, 0);
  387. }
  388. else
  389. {
  390. PostMessage(m_hDialog, WM_DOWNLOAD_ERROR, (WPARAM)m_hDownloadResult, 0);
  391. }
  392. }
  393. }
  394. m_State = WJSTATE_FINISHED_READ;
  395. }
  396. m_bReading = FALSE;
  397. leave:
  398. DEBUG_LEAVE(m_dwCurrent);
  399. return;
  400. abort:
  401. hr = E_ABORT;
  402. if (!m_fCalledAbort && m_pBinding)
  403. {
  404. m_fCalledAbort = TRUE;
  405. hrAbort = m_pBinding->Abort();
  406. }
  407. goto end;
  408. }
  409. STDMETHODIMP CWebJit::OnObjectAvailable(REFIID riid, IUnknown* punk)
  410. {
  411. return S_OK;
  412. }
  413. STDMETHODIMP CWebJit::Authenticate(HWND* phwnd, LPWSTR *pszUsername,LPWSTR *pszPassword)
  414. {
  415. DEBUG_ENTER((DBG_DOWNLOAD,
  416. Hresult,
  417. "CWebJit::Authenticate",
  418. "this=%#x",
  419. this
  420. ));
  421. *phwnd = m_hDialog;
  422. *pszUsername = 0;
  423. *pszPassword = 0;
  424. DEBUG_LEAVE(S_OK);
  425. return S_OK;
  426. }
  427. DWORD CWebJit::GetDownloadSpeed()
  428. {
  429. //using iejit.htx guesstimates/logic
  430. DWORD dwDownloadSpeed = 120; //default to 28.8kbps modem.
  431. DWORD dwFlags;
  432. if (InternetGetConnectedState(&dwFlags, NULL))
  433. {
  434. if (dwFlags & INTERNET_CONNECTION_LAN)
  435. {
  436. dwDownloadSpeed = 800; //KB/min
  437. }
  438. else if (dwFlags & INTERNET_CONNECTION_MODEM)
  439. {
  440. dwDownloadSpeed = 120; //based on 28.8kbps
  441. }
  442. }
  443. return dwDownloadSpeed;
  444. }
  445. BOOL CWebJit::UpdateProgressUI()
  446. {
  447. DWORD dwDownloadTime;
  448. BOOL bRetVal = TRUE;
  449. CHAR szMsg[1000];
  450. int nRet;
  451. DWORD dwDownloadSize;
  452. if (!m_dwDownloadSpeed)
  453. {
  454. m_dwDownloadSpeed = GetDownloadSpeed();
  455. }
  456. if (!m_dwTotal)
  457. {
  458. // didn't get a total length - can't display progress.
  459. bRetVal = FALSE;
  460. goto exit;
  461. }
  462. dwDownloadSize = m_dwTotal - m_dwCurrent;
  463. dwDownloadTime = dwDownloadSize/m_dwDownloadSpeed/1024;
  464. nRet = MLLoadStringA(IDS_TIME, szMsg, ARRAY_ELEMENTS(szMsg));
  465. if (dwDownloadTime >= 60)
  466. {
  467. DWORD dwDownloadHr = dwDownloadTime / 60;
  468. DWORD dwDownloadMin = dwDownloadTime % 60;
  469. if(dwDownloadHr == 1)
  470. {
  471. nRet += MLLoadStringA(IDS_hr1_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  472. }
  473. else if ((sizeof(szMsg) - nRet) > 2)
  474. {
  475. wsprintfA(szMsg+nRet, "%2d", dwDownloadHr);
  476. nRet += 2;
  477. nRet += MLLoadStringA(IDS_hrs_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  478. }
  479. if((dwDownloadMin > 0)
  480. && ((sizeof(szMsg) - nRet) > 3))
  481. {
  482. wsprintfA(szMsg+nRet, " %2d", dwDownloadMin);
  483. nRet += 3;
  484. nRet += MLLoadStringA(IDS_MINUTES_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  485. }
  486. }
  487. else if(dwDownloadTime < 60)
  488. {
  489. if((dwDownloadSize != 0) && (dwDownloadTime == 0))
  490. {
  491. nRet += MLLoadStringA(IDS_LessThanAMinute_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  492. }
  493. else if ((sizeof(szMsg) - nRet) > 2)
  494. {
  495. wsprintfA(szMsg+nRet, "%2d", dwDownloadTime);
  496. nRet += 2;
  497. nRet += MLLoadStringA(IDS_MINUTES_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  498. }
  499. }
  500. SetDlgItemTextA(m_hDialog, IDC_REMAINING_TIME, szMsg);
  501. nRet = MLLoadStringA(IDS_SIZE, szMsg, ARRAY_ELEMENTS(szMsg));
  502. if ((dwDownloadSize > (1024*1024))
  503. && ((sizeof(szMsg) - nRet) > 3))
  504. {
  505. DWORD dwMbSize = dwDownloadSize/(1024*1024);
  506. wsprintfA(szMsg+nRet, "%d", dwMbSize);
  507. nRet += (dwMbSize<10) ? 1 : ((dwMbSize<100) ? 2 : 3);
  508. nRet += MLLoadStringA(IDS_MEGABYTE_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  509. }
  510. else if ((sizeof(szMsg) - nRet) > 3)
  511. {
  512. DWORD dwKbSize = dwDownloadSize/1024;
  513. wsprintfA(szMsg+nRet, "%d", dwKbSize);
  514. nRet += (dwKbSize<10) ? 1 : ((dwKbSize<100) ? 2 : 3);
  515. nRet += MLLoadStringA(IDS_KILOBYTES_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
  516. }
  517. SetDlgItemTextA(m_hDialog, IDC_REMAINING_SIZE, szMsg);
  518. SendMessage(GetDlgItem(m_hDialog, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)((m_dwCurrent*1.00/m_dwTotal)*65535), 0);
  519. exit:
  520. return bRetVal;
  521. }
  522. BOOL CWebJit::IsConnected(BOOL* pfIsOffline)
  523. {
  524. BOOL bRetVal = TRUE;
  525. DWORD dwFlags = 0;
  526. bRetVal = InternetGetConnectedState(&dwFlags, NULL);
  527. if (dwFlags & INTERNET_CONNECTION_OFFLINE)
  528. {
  529. *pfIsOffline = TRUE;
  530. }
  531. else
  532. {
  533. *pfIsOffline = FALSE;
  534. }
  535. return bRetVal;
  536. }
  537. VOID CWebJit::UpdateDownloadResult(HRESULT hr, BOOL fFromOnStopBinding)
  538. {
  539. DEBUG_ENTER((DBG_DOWNLOAD,
  540. Hresult,
  541. "CWebJit::UpdateDownloadResult",
  542. "this=%#x, hr=%#x, OnStopBinding?=%B, fResultIn?=%B, previous hr=%#x",
  543. this, hr, fFromOnStopBinding, m_fResultIn, m_hDownloadResult
  544. ));
  545. if (fFromOnStopBinding)
  546. {
  547. if (m_fResultIn)
  548. {
  549. // If the result from BindToStorage was successful, use this one.
  550. if ((SUCCEEDED(m_hDownloadResult))
  551. || (m_hDownloadResult == E_PENDING))
  552. {
  553. m_hDownloadResult = hr;
  554. }
  555. goto NextStep;
  556. }
  557. else
  558. {
  559. m_hDownloadResult = hr;
  560. m_fResultIn = TRUE;
  561. }
  562. }
  563. else
  564. {
  565. if (m_fResultIn)
  566. {
  567. if (SUCCEEDED(m_hDownloadResult)
  568. && !((hr == MK_S_ASYNCHRONOUS) || (hr == E_PENDING)))
  569. {
  570. m_hDownloadResult = hr;
  571. }
  572. goto NextStep;
  573. }
  574. else
  575. {
  576. m_hDownloadResult = hr;
  577. m_fResultIn = TRUE;
  578. if (!((hr == MK_S_ASYNCHRONOUS) || (hr == E_PENDING)))
  579. {
  580. goto NextStep;
  581. }
  582. }
  583. }
  584. exit:
  585. DEBUG_LEAVE(m_hDownloadResult);
  586. return;
  587. NextStep:
  588. if (m_fAborted)
  589. {
  590. m_hDownloadResult = E_ABORT;
  591. }
  592. else if (m_State < WJSTATE_FINISHED_READ)
  593. {
  594. m_State = WJSTATE_DOWNLOADED;
  595. }
  596. if ((m_State == WJSTATE_FINISHED_READ)
  597. || m_fAborted
  598. || FAILED(m_hDownloadResult))
  599. {
  600. // if we either aborted or
  601. // if all the data has been read
  602. if (m_pMk)
  603. {
  604. ReleaseAll();
  605. if (SUCCEEDED(m_hDownloadResult))
  606. {
  607. PostMessage(m_hDialog, WM_DOWNLOAD_DONE, 0, 0);
  608. }
  609. else
  610. {
  611. PostMessage(m_hDialog, WM_DOWNLOAD_ERROR, (WPARAM)m_hDownloadResult, 0);
  612. }
  613. }
  614. }
  615. //Release(); //balanced by Release in UpdateDownloadResult
  616. goto exit;
  617. }
  618. HRESULT CWebJit::VerifyMimeAndExtension()
  619. {
  620. DEBUG_ENTER((DBG_DOWNLOAD,
  621. Hresult,
  622. "CWebJit::VerifyMimeAndExtension",
  623. "this=%#x, cache file=%.200wq, mime type=%.80wq",
  624. this, m_pwszCacheFile, m_pwszMimeType
  625. ));
  626. HRESULT hr = S_OK;
  627. if (m_pwszMimeType)
  628. {
  629. if (!StrCmpIW(m_pwszMimeType, L"text/html"))
  630. {
  631. m_fHtml = TRUE;
  632. }
  633. else if (StrCmpIW(m_pwszMimeType, L"application/x-msdownload")
  634. && StrCmpIW(m_pwszMimeType, L"application/octet-stream"))
  635. {
  636. hr = NO_MIME_MATCH;
  637. }
  638. }
  639. //disable .exe check for now
  640. /*
  641. int dwStrlen = lstrlenW(m_pwszCacheFile);
  642. if ((dwStrlen < 4)
  643. || (StrCmpIW(m_pwszCacheFile+dwStrlen-4, L".exe")))
  644. {
  645. hr = NO_EXT_MATCH;
  646. }
  647. exit:
  648. */
  649. DEBUG_LEAVE(hr);
  650. return hr;
  651. }
  652. BOOL CWebJit::NeedHostSecMgr()
  653. {
  654. DEBUG_ENTER((DBG_DOWNLOAD,
  655. Bool,
  656. "CWebJit::NeedHostSecMgr",
  657. "this=%#x",
  658. this
  659. ));
  660. BOOL fNeed = FALSE;
  661. BOOL fWhistler = FALSE;
  662. OSVERSIONINFO VerInfo;
  663. VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  664. if (GetVersionEx(&VerInfo))
  665. {
  666. if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  667. {
  668. if ((VerInfo.dwMajorVersion >= 5)
  669. && (VerInfo.dwMinorVersion >= 1))
  670. {
  671. fWhistler = TRUE;
  672. }
  673. }
  674. }
  675. if (fWhistler
  676. && !StrCmpIW(m_pwszComponentId, L"JAVAVMJIT"))
  677. {
  678. //if installed VM older than 5.00.2752.0
  679. const static char * szRequiredVersion = "5,00,2752,0";
  680. DWORD dwHi;
  681. DWORD dwLo;
  682. if (m_pQueryInstalled
  683. && (m_pQueryInstalled->dwVersionHi || m_pQueryInstalled->dwVersionLo)
  684. && (SUCCEEDED(GetVersionFromString(szRequiredVersion, &dwHi, &dwLo)))
  685. && ((m_pQueryInstalled->dwVersionHi < dwHi)
  686. || ((m_pQueryInstalled->dwVersionHi == dwHi)
  687. && (m_pQueryInstalled->dwVersionLo < dwLo))))
  688. {
  689. fNeed = TRUE;
  690. }
  691. }
  692. DEBUG_LEAVE(fNeed);
  693. return fNeed;
  694. }
  695. VOID CWebJit::ProcessFile()
  696. {
  697. DEBUG_ENTER((DBG_DOWNLOAD,
  698. Hresult,
  699. "CWebJit::ProcessFile",
  700. "this=%#x",
  701. this
  702. ));
  703. HRESULT hr = VerifyMimeAndExtension();
  704. if (hr == S_OK)
  705. {
  706. if (!m_fHtml)
  707. {
  708. hr = VerifyTrust(FALSE);
  709. if (FAILED(hr) && NeedHostSecMgr())
  710. {
  711. HRESULT hrTemp = VerifyTrust(TRUE);
  712. // use the hrTemp from the second call only if the call actually succeeds.
  713. if (hrTemp == S_OK)
  714. {
  715. hr = hrTemp;
  716. }
  717. }
  718. }
  719. if (SUCCEEDED(hr))
  720. {
  721. if ((hr = ExecFile()) == S_OK)
  722. {
  723. //enable this code if we need to exit the dialog while navigating browser to error html page
  724. //because the error page has been execed into the same process.
  725. if (m_fHtml && (NULL == GetProcessHandle()))
  726. {
  727. SendMessage(m_hDialog, WM_DONT_WAIT, 0, 0);
  728. }
  729. else
  730. {
  731. SendMessage(m_hDialog, WM_START_TIMER, (WPARAM)1, 0);
  732. }
  733. goto success;
  734. }
  735. }
  736. }
  737. SendMessage(m_hDialog, WM_PROCESS_ERROR, hr, 0);
  738. success:
  739. DEBUG_LEAVE(hr);
  740. return;
  741. }
  742. HRESULT CWebJit::CanWebJit()
  743. {
  744. DEBUG_ENTER((DBG_DOWNLOAD,
  745. Hresult,
  746. "CWebJit::CanWebJit",
  747. "this=%#x",
  748. this
  749. ));
  750. HRESULT hr = S_OK;
  751. #define REGSTR_PATH_NT5_LOCKDOWN_TEST "Software\\Microsoft\\Code Store Database\\NT5LockDownTest"
  752. if (g_bNT5OrGreater)
  753. {
  754. HKEY hkeyLockedDown = 0;
  755. // Test for lock-down. If we cannot write to HKLM, then we are in
  756. // a locked-down environment, and should abort right away.
  757. if (RegCreateKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_NT5_LOCKDOWN_TEST,
  758. &hkeyLockedDown) != ERROR_SUCCESS)
  759. {
  760. // We are in lock-down mode; abort.
  761. g_bLockedDown = TRUE;
  762. hr = E_ACCESSDENIED;
  763. }
  764. else
  765. {
  766. // Not locked-down. Delete the key, and continue
  767. RegCloseKey(hkeyLockedDown);
  768. RegDeleteKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_NT5_LOCKDOWN_TEST);
  769. g_bLockedDown = FALSE;
  770. }
  771. }
  772. //JAVA VM specific checks.. If we have too many component specific checks eventually,
  773. // make function pointers and key off those.
  774. if (SUCCEEDED(hr) && g_bNT5OrGreater
  775. && !StrCmpIW(m_pwszComponentId, L"JAVAVMJIT"))
  776. {
  777. if (!IsWin32X86())
  778. {
  779. hr = HRESULT_FROM_WIN32(ERROR_INSTALL_PLATFORM_UNSUPPORTED);
  780. }
  781. else if(!IsNTAdmin())
  782. {
  783. hr = E_ACCESSDENIED;
  784. }
  785. }
  786. DEBUG_LEAVE(hr);
  787. return hr;
  788. }
  789. HRESULT CWebJit::SetupDownload()
  790. {
  791. DEBUG_ENTER((DBG_DOWNLOAD,
  792. Hresult,
  793. "CWebJit::SetupDownload",
  794. "this=%#x",
  795. this
  796. ));
  797. int cchWideChar;
  798. HRESULT hr;
  799. if (FAILED(hr = CanWebJit()))
  800. {
  801. goto exit;
  802. }
  803. m_pTempBuffer = new CHAR[TEMPREADBUFFERSIZE];
  804. if (!m_pTempBuffer)
  805. {
  806. hr = E_OUTOFMEMORY;
  807. goto exit;
  808. }
  809. cchWideChar = MultiByteToWideChar(CP_ACP, 0, m_szResource, -1, NULL, 0);
  810. if (!cchWideChar)
  811. {
  812. hr = HRESULT_FROM_WIN32(GetLastError());
  813. goto exit;
  814. }
  815. m_pwszUrl = new WCHAR[cchWideChar+1];
  816. if (!m_pwszUrl)
  817. {
  818. hr = E_OUTOFMEMORY;
  819. goto exit;
  820. }
  821. cchWideChar = MultiByteToWideChar(CP_ACP, 0, m_szResource, -1, m_pwszUrl, cchWideChar);
  822. if (!cchWideChar)
  823. {
  824. hr = HRESULT_FROM_WIN32(GetLastError());
  825. goto exit;
  826. }
  827. hr = CreateAsyncBindCtx(NULL, (IBindStatusCallback *)this, NULL, &m_pbc );
  828. if (FAILED(hr))
  829. {
  830. goto exit;
  831. }
  832. hr = CreateURLMoniker(NULL, m_pwszUrl, &m_pMk);
  833. if (FAILED(hr))
  834. {
  835. goto exit;
  836. }
  837. exit:
  838. DEBUG_LEAVE(hr);
  839. return hr;
  840. }
  841. HRESULT CWebJit::StartDownload()
  842. {
  843. DEBUG_ENTER((DBG_DOWNLOAD,
  844. Hresult,
  845. "CWebJit::StartDownload",
  846. "this=%#x",
  847. this
  848. ));
  849. //AddRef(); //balanced by Release in UpdateDownloadResult
  850. m_State = WJSTATE_BINDING;
  851. UpdateStatusString();
  852. BOOL bRetVal = FALSE;
  853. HRESULT hr;
  854. hr = m_pMk->BindToStorage(m_pbc, 0, IID_IStream, (void**)&m_pStm);
  855. DEBUG_LEAVE(hr);
  856. return hr;
  857. }
  858. HRESULT CWebJit::ExecFile()
  859. {
  860. DEBUG_ENTER((DBG_DOWNLOAD,
  861. Hresult,
  862. "CWebJit::ExecFile",
  863. "this=%#x",
  864. this
  865. ));
  866. HRESULT hr = S_OK;
  867. if (m_fAborted)
  868. {
  869. hr = E_ABORT;
  870. goto exit;
  871. }
  872. else
  873. {
  874. m_State = WJSTATE_READY_TO_EXEC;
  875. }
  876. SHELLEXECUTEINFOW shExecInfo;
  877. memset(&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
  878. shExecInfo.cbSize = sizeof(shExecInfo);
  879. shExecInfo.fMask = SEE_MASK_FLAG_DDEWAIT /*don't need in urlmon*/
  880. | SEE_MASK_FLAG_NO_UI
  881. | SEE_MASK_NOCLOSEPROCESS
  882. | SEE_MASK_NO_CONSOLE
  883. | SEE_MASK_UNICODE /* ?? */;
  884. shExecInfo.lpVerb = L"open";
  885. //ASSERT (m_pwszCacheFile && (*m_pwszCacheFile != L'\0'))
  886. if (m_fHtml)
  887. {
  888. if (!m_pwszRedirectUrl)
  889. { hr = EXEC_ERROR;
  890. goto exit;
  891. }
  892. shExecInfo.lpFile = m_pwszRedirectUrl;
  893. }
  894. else
  895. shExecInfo.lpFile = m_pwszCacheFile;
  896. shExecInfo.nShow = SW_SHOWNORMAL;
  897. if (!ShellExecuteExWrapW(&shExecInfo))
  898. {
  899. hr = EXEC_ERROR;
  900. goto exit;
  901. }
  902. m_hProcess = shExecInfo.hProcess;
  903. exit:
  904. if (m_hCacheFile && !InternetUnlockRequestFile(m_hCacheFile))
  905. {
  906. //nothing.
  907. }
  908. DEBUG_LEAVE(hr);
  909. return hr;
  910. }
  911. #define MAX_ERROR_SIZE 2000
  912. #define START_ERROR_STRING(ERROR_IDS) \
  913. nRet = MLLoadStringW(ERROR_IDS, wszError, MAX_ERROR_SIZE);
  914. #define APPEND_ERROR_STRING(ERROR_IDS) \
  915. StrCatW(wszError, L" "); \
  916. nRet += MLLoadStringW(ERROR_IDS, wszError+nRet+1, MAX_ERROR_SIZE-nRet-1)+1;
  917. HRESULT CWebJit::DisplayError(HRESULT hr, UINT nMsgError)
  918. {
  919. DEBUG_ENTER((DBG_DOWNLOAD,
  920. Hresult,
  921. "CWebJit::DisplayError",
  922. "this=%#x, %#x, %#x",
  923. this, hr, nMsgError
  924. ));
  925. int nRet = 0;
  926. BOOL fIsOffline;
  927. WCHAR wszError[MAX_ERROR_SIZE];
  928. WCHAR wszTitle[200];
  929. ULONG_PTR uCookie = 0;
  930. if (m_fAborted)
  931. goto exit;
  932. if (m_hrInternal)
  933. {
  934. hr = m_hrInternal;
  935. nMsgError = WM_INTERNAL_ERROR;
  936. }
  937. START_ERROR_STRING(IDS_ERROROCCURED);
  938. if (nRet)
  939. {
  940. *(wszError+nRet) = L'\0';
  941. SetDlgItemTextWrapW(m_hDialog, IDC_TEXT, wszError);
  942. }
  943. ShowWindow(GetDlgItem(m_hDialog, IDCANCEL), SW_HIDE);
  944. if (!IsConnected(&fIsOffline))
  945. {
  946. fIsOffline = TRUE;
  947. }
  948. nRet = 0;
  949. switch(nMsgError)
  950. {
  951. case WM_INTERNAL_ERROR:
  952. {
  953. START_ERROR_STRING(IDS_INTERNAL);
  954. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  955. }
  956. break;
  957. case WM_SETUP_ERROR:
  958. {
  959. if (hr == E_ACCESSDENIED)
  960. {
  961. START_ERROR_STRING(IDS_INSTALLFAIL);
  962. APPEND_ERROR_STRING(IDS_ADMINRIGHTS);
  963. }
  964. else if (hr == HRESULT_FROM_WIN32(ERROR_INSTALL_PLATFORM_UNSUPPORTED))
  965. {
  966. START_ERROR_STRING(IDS_PLATFORMNOT);
  967. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  968. }
  969. else
  970. {
  971. START_ERROR_STRING(IDS_SETUP);
  972. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  973. }
  974. }
  975. break;
  976. case WM_DOWNLOAD_ERROR:
  977. {
  978. switch(hr)
  979. {
  980. case E_ABORT:
  981. {
  982. hr = CANCELLED;
  983. }
  984. break;
  985. case INET_E_OBJECT_NOT_FOUND:
  986. {
  987. if (fIsOffline)
  988. {
  989. START_ERROR_STRING(IDS_OFFLINEALERT);
  990. APPEND_ERROR_STRING(IDS_OFFLINEALERT2);
  991. }
  992. else
  993. {
  994. START_ERROR_STRING(IDS_DLFAIL);
  995. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  996. }
  997. }
  998. break;
  999. case INET_E_RESOURCE_NOT_FOUND:
  1000. {
  1001. START_ERROR_STRING(IDS_SERVERERROR);
  1002. APPEND_ERROR_STRING(IDS_IBUSY);
  1003. APPEND_ERROR_STRING(IDS_NOTCONNECTED);
  1004. }
  1005. break;
  1006. case INET_E_DOWNLOAD_FAILURE:
  1007. {
  1008. if (fIsOffline)
  1009. {
  1010. START_ERROR_STRING(IDS_OFFLINEALERT);
  1011. APPEND_ERROR_STRING(IDS_OFFLINEALERT2);
  1012. }
  1013. else
  1014. {
  1015. START_ERROR_STRING(IDS_DLFAIL);
  1016. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  1017. }
  1018. }
  1019. break;
  1020. }
  1021. if (!nRet
  1022. && (hr >= INET_E_ERROR_FIRST)
  1023. && (hr <= INET_E_ERROR_LAST))
  1024. {
  1025. START_ERROR_STRING(IDS_DLFAIL);
  1026. APPEND_ERROR_STRING(IDS_IBUSY);
  1027. APPEND_ERROR_STRING(IDS_NOTCONNECTED);
  1028. }
  1029. }
  1030. break;
  1031. case WM_PROCESS_ERROR:
  1032. {
  1033. switch(hr)
  1034. {
  1035. case TRUST_E_SUBJECT_NOT_TRUSTED:
  1036. {
  1037. START_ERROR_STRING(IDS_CERTREFUSE);
  1038. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  1039. }
  1040. break;
  1041. case TRUST_E_FAIL:
  1042. {
  1043. START_ERROR_STRING(IDS_SECURITYHIGH);
  1044. APPEND_ERROR_STRING(IDS_SECURITYHIGH1);
  1045. APPEND_ERROR_STRING(IDS_SECURITYHIGH2);
  1046. APPEND_ERROR_STRING(IDS_SECURITYHIGH3);
  1047. }
  1048. break;
  1049. case E_ACCESSDENIED:
  1050. {
  1051. START_ERROR_STRING(IDS_INSTALLFAIL);
  1052. APPEND_ERROR_STRING(IDS_ADMINRIGHTS);
  1053. }
  1054. break;
  1055. }
  1056. if (!nRet)
  1057. {
  1058. START_ERROR_STRING(IDS_PROCESS);
  1059. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  1060. hr = HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
  1061. }
  1062. }
  1063. break;
  1064. }
  1065. if (!nRet)
  1066. {
  1067. START_ERROR_STRING(IDS_UNKNOWNERROR);
  1068. APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
  1069. }
  1070. *(wszError+nRet) = L'\0';
  1071. nRet = MLLoadStringW(IDS_ERRORTITLE, wszTitle, ARRAY_ELEMENTS(wszTitle));
  1072. SHActivateContext(&uCookie);
  1073. MessageBoxW(m_hDialog, wszError, nRet ? wszTitle : NULL, MB_OK);
  1074. if (uCookie)
  1075. {
  1076. SHDeactivateContext(uCookie);
  1077. }
  1078. exit:
  1079. DEBUG_LEAVE(hr);
  1080. return hr;
  1081. }
  1082. HRESULT CWebJit::VerifyTrust(BOOL fUseHostSecMgr)
  1083. {
  1084. DEBUG_ENTER((DBG_DOWNLOAD,
  1085. Hresult,
  1086. "CWebJit::VerifyTrust",
  1087. "this=%#x, %B",
  1088. this, fUseHostSecMgr
  1089. ));
  1090. HRESULT hr = E_FAIL;
  1091. LPWSTR pwszUnescapedUrl = NULL;
  1092. HANDLE hFile = INVALID_HANDLE_VALUE;
  1093. #define COR_POLICY_PROVIDER_DOWNLOAD \
  1094. { 0xd41e4f1d, 0xa407, 0x11d1, {0x8b, 0xc9, 0x0, 0xc0, 0x4f, 0xa3, 0xa, 0x41 } }
  1095. GUID guidCor = COR_POLICY_PROVIDER_DOWNLOAD;
  1096. if (m_fAborted)
  1097. {
  1098. hr = E_ABORT;
  1099. goto exit;
  1100. }
  1101. else
  1102. {
  1103. m_State = WJSTATE_VERIFYING;
  1104. }
  1105. UpdateStatusString();
  1106. hFile = CreateFileWrapW(m_pwszCacheFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  1107. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  1108. if (!hFile)
  1109. {
  1110. hr = HRESULT_FROM_WIN32(GetLastError());
  1111. goto exit;
  1112. }
  1113. DWORD dwWideChar = lstrlenW(m_pwszUrl)+1;
  1114. pwszUnescapedUrl = new WCHAR[dwWideChar];
  1115. if (pwszUnescapedUrl)
  1116. {
  1117. hr = UrlUnescapeW(m_pwszUrl, pwszUnescapedUrl, &dwWideChar, 0);
  1118. }
  1119. LPCWSTR pwszDisplayUrl = (hr == S_OK) ? pwszUnescapedUrl : m_pwszUrl;
  1120. if(!SUCCEEDED(hr = EnsureSecurityManager()))
  1121. {
  1122. goto exit;
  1123. }
  1124. WINTRUST_DATA WintrustData;
  1125. ZeroMemory(&WintrustData, sizeof(WINTRUST_DATA));
  1126. WintrustData.cbStruct = sizeof(WINTRUST_DATA);
  1127. if ((m_hDialog == INVALID_HANDLE_VALUE) || IsUIRestricted()) //urlmon only
  1128. WintrustData.dwUIChoice = WTD_UI_NONE;
  1129. else
  1130. WintrustData.dwUIChoice = WTD_UI_ALL;
  1131. WintrustData.dwUnionChoice = WTD_CHOICE_FILE;
  1132. JAVA_POLICY_PROVIDER javaPolicyData;
  1133. ZeroMemory(&javaPolicyData, sizeof(JAVA_POLICY_PROVIDER));
  1134. javaPolicyData.cbSize = sizeof(JAVA_POLICY_PROVIDER);
  1135. javaPolicyData.VMBased = FALSE;
  1136. javaPolicyData.fNoBadUI = FALSE;
  1137. javaPolicyData.pwszZone = pwszDisplayUrl;
  1138. javaPolicyData.pZoneManager = fUseHostSecMgr ? ((LPVOID)(IInternetHostSecurityManager *)this) : NULL;
  1139. WintrustData.pPolicyCallbackData = &javaPolicyData;
  1140. WINTRUST_FILE_INFO WintrustFileInfo;
  1141. ZeroMemory(&WintrustFileInfo, sizeof(WINTRUST_FILE_INFO));
  1142. WintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
  1143. WintrustFileInfo.pcwszFilePath = pwszDisplayUrl;
  1144. WintrustFileInfo.hFile = hFile;
  1145. WintrustData.pFile = &WintrustFileInfo;
  1146. hr = WinVerifyTrust(m_hDialog, &guidCor, &WintrustData);
  1147. if (hr == TRUST_E_PROVIDER_UNKNOWN)
  1148. {
  1149. GUID guidJava = JAVA_POLICY_PROVIDER_DOWNLOAD;
  1150. hr = WinVerifyTrust(m_hDialog, &guidJava, &WintrustData);
  1151. }
  1152. if (hr == S_OK)
  1153. {
  1154. DWORD dwZone;
  1155. if ((javaPolicyData.pbJavaTrust == NULL)
  1156. || (!javaPolicyData.pbJavaTrust->fAllActiveXPermissions)
  1157. || (g_pSecurityManager
  1158. && (SUCCEEDED(g_pSecurityManager->MapUrlToZone(m_pwszUrl, &dwZone, 0)))
  1159. && (dwZone == URLZONE_LOCAL_MACHINE)
  1160. && (FAILED(javaPolicyData.pbJavaTrust->hVerify))))
  1161. {
  1162. hr = TRUST_E_FAIL;
  1163. }
  1164. }
  1165. else if (SUCCEEDED(hr))
  1166. {
  1167. // BUGBUG: this works around a wvt bug that returns 0x57 (success) when
  1168. // you hit No to an usigned control
  1169. hr = TRUST_E_FAIL;
  1170. }
  1171. else if (hr == TRUST_E_SUBJECT_NOT_TRUSTED && WintrustData.dwUIChoice == WTD_UI_NONE)
  1172. {
  1173. // if we didn't ask for the UI to be out up there has been no UI
  1174. // work around WVT bvug that it returns us this special error code
  1175. // without putting up UI.
  1176. hr = TRUST_E_FAIL; // this will put up mshtml ui after the fact
  1177. // that security settings prevented us
  1178. }
  1179. if (javaPolicyData.pbJavaTrust)
  1180. CoTaskMemFree(javaPolicyData.pbJavaTrust);
  1181. exit:
  1182. if (pwszUnescapedUrl)
  1183. delete [] pwszUnescapedUrl;
  1184. if (hFile != INVALID_HANDLE_VALUE)
  1185. CloseHandle(hFile);
  1186. DEBUG_LEAVE(hr);
  1187. return hr;
  1188. }
  1189. VOID CWebJit::ProcessAbort()
  1190. {
  1191. DEBUG_ENTER((DBG_DOWNLOAD,
  1192. None,
  1193. "CWebJit::ProcessAbort",
  1194. "this=%#x, currentState=%d",
  1195. this, m_State
  1196. ));
  1197. ShowWindow(m_hDialog, SW_HIDE);
  1198. m_fAborted = TRUE;
  1199. switch (m_State)
  1200. {
  1201. case WJSTATE_INIT:
  1202. Terminate(CANCELLED);
  1203. break;
  1204. case WJSTATE_BINDING:
  1205. if (m_pBinding && !m_fCalledAbort)
  1206. {
  1207. m_fCalledAbort = TRUE;
  1208. m_pBinding->Abort();
  1209. }
  1210. break;
  1211. case WJSTATE_DOWNLOADED:
  1212. case WJSTATE_FINISHED_READ:
  1213. case WJSTATE_VERIFYING:
  1214. case WJSTATE_READY_TO_EXEC:
  1215. case WJSTATE_WAITING_PROCESS:
  1216. case WJSTATE_DONE:
  1217. default:
  1218. break;
  1219. }
  1220. DEBUG_LEAVE(0);
  1221. }
  1222. VOID CWebJit::Terminate(DWORD dwRetVal)
  1223. {
  1224. DEBUG_ENTER((DBG_DOWNLOAD,
  1225. None,
  1226. "CWebJit::Terminate",
  1227. "this=%#x, dwRetVal=%#x, currentState=%d",
  1228. this, dwRetVal, m_State
  1229. ));
  1230. m_dwRetVal = dwRetVal;
  1231. //Release();
  1232. if (m_fAborted)
  1233. m_dwRetVal = CANCELLED;
  1234. else if (m_hrInternal)
  1235. m_dwRetVal = m_hrInternal;
  1236. EndDialog(m_hDialog, (INT_PTR)m_dwRetVal);
  1237. DEBUG_LEAVE(0);
  1238. return;
  1239. }
  1240. HRESULT CWebJit::Init(void)
  1241. {
  1242. HRESULT hr = S_OK;
  1243. if (m_fInited)
  1244. {
  1245. goto exit;
  1246. }
  1247. #define WINTRUST TEXT("wintrust.dll")
  1248. m_hWintrustMod = LoadLibrary( WINTRUST );
  1249. if (NULL == m_hWintrustMod)
  1250. {
  1251. hr = ERROR_MOD_NOT_FOUND;
  1252. goto exit;
  1253. }
  1254. #define CHECKAPI(_fn) \
  1255. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(m_hWintrustMod, #_fn); \
  1256. if (!(_pfn##_fn)) \
  1257. { \
  1258. FreeLibrary(m_hWintrustMod); \
  1259. \
  1260. hr = ERROR_MOD_NOT_FOUND;\
  1261. goto exit;\
  1262. }
  1263. CHECKAPI(WinVerifyTrust);
  1264. m_fInited = TRUE;
  1265. exit:
  1266. return hr;
  1267. }
  1268. HRESULT CWebJit::InitCC(void)
  1269. {
  1270. HRESULT hr = S_OK;
  1271. if (m_fInitedCC)
  1272. {
  1273. goto exit;
  1274. }
  1275. #define COMCTL TEXT("comctl32.dll")
  1276. m_hComCtlMod = LoadLibrary( COMCTL );
  1277. if (NULL == m_hComCtlMod)
  1278. {
  1279. hr = ERROR_MOD_NOT_FOUND;
  1280. goto exit;
  1281. }
  1282. #define CHECKCCAPI(_fn) \
  1283. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(m_hComCtlMod, #_fn); \
  1284. if (!(_pfn##_fn)) \
  1285. { \
  1286. FreeLibrary(m_hComCtlMod); \
  1287. \
  1288. hr = ERROR_MOD_NOT_FOUND;\
  1289. goto exit;\
  1290. }
  1291. CHECKCCAPI(InitCommonControlsEx);
  1292. m_fInitedCC = TRUE;
  1293. exit:
  1294. return hr;
  1295. }
  1296. BOOL CWebJit::InitCommonControlsForWebJit()
  1297. {
  1298. INITCOMMONCONTROLSEX sInitComm;
  1299. sInitComm.dwSize = sizeof(INITCOMMONCONTROLSEX);
  1300. sInitComm.dwICC = ICC_PROGRESS_CLASS;
  1301. return InitCommonControlsEx(&sInitComm);
  1302. }
  1303. UINT MapComponentToResourceId(LPCWSTR pwszComponentId)
  1304. {
  1305. typedef struct
  1306. {
  1307. LPCWSTR pwszComponentId;
  1308. UINT nResource;
  1309. }
  1310. ComponentToResourceType;
  1311. ComponentToResourceType MapComponentToResource[] =
  1312. {
  1313. { L"JAVAVMJIT", IDS_JAVAVMJIT },
  1314. { L"WMPLAYER", IDS_MEDIAPLAYER }
  1315. };
  1316. UINT nRet = (UINT)-1;
  1317. for (DWORD i = 0; i < ARRAY_ELEMENTS(MapComponentToResource); i++ )
  1318. {
  1319. if (!StrCmpIW(pwszComponentId, MapComponentToResource[i].pwszComponentId))
  1320. {
  1321. nRet = MapComponentToResource[i].nResource;
  1322. break;
  1323. }
  1324. }
  1325. return nRet;
  1326. }
  1327. UINT MapComponentToHelpId(LPCWSTR pwszComponentId)
  1328. {
  1329. typedef struct
  1330. {
  1331. LPCWSTR pwszComponentId;
  1332. UINT nResource;
  1333. }
  1334. ComponentToHelpId;
  1335. ComponentToHelpId MapComponentToHelpIds[] =
  1336. {
  1337. { L"JAVAVMJIT", 50464 },
  1338. { L"WMPLAYER", 50475 }
  1339. };
  1340. UINT nRet = 0;
  1341. for (DWORD i = 0; i < ARRAY_ELEMENTS(MapComponentToHelpIds); i++ )
  1342. {
  1343. if (!StrCmpIW(pwszComponentId, MapComponentToHelpIds[i].pwszComponentId))
  1344. {
  1345. nRet = MapComponentToHelpIds[i].nResource;
  1346. break;
  1347. }
  1348. }
  1349. return nRet;
  1350. }
  1351. BOOL CenterWindow(HWND hwndChild, HWND hwndParent)
  1352. {
  1353. RECT rChild, rParent;
  1354. int wChild, hChild, wParent, hParent;
  1355. int wScreen, hScreen, xNew, yNew;
  1356. HDC hdc;
  1357. // Get the Height and Width of the child window
  1358. GetWindowRect (hwndChild, &rChild);
  1359. wChild = rChild.right - rChild.left;
  1360. hChild = rChild.bottom - rChild.top;
  1361. // Get the Height and Width of the parent window
  1362. GetWindowRect (hwndParent, &rParent);
  1363. wParent = rParent.right - rParent.left;
  1364. hParent = rParent.bottom - rParent.top;
  1365. // Get the display limits
  1366. hdc = GetDC (hwndChild);
  1367. wScreen = GetDeviceCaps (hdc, HORZRES);
  1368. hScreen = GetDeviceCaps (hdc, VERTRES);
  1369. ReleaseDC (hwndChild, hdc);
  1370. // Calculate new X position, then adjust for screen
  1371. xNew = rParent.left + ((wParent - wChild) /2);
  1372. if (xNew < 0)
  1373. {
  1374. xNew = 0;
  1375. }
  1376. else if ((xNew+wChild) > wScreen)
  1377. {
  1378. xNew = wScreen - wChild;
  1379. }
  1380. // Calculate new Y position, then adjust for screen
  1381. yNew = rParent.top + ((hParent - hChild) /2);
  1382. if (yNew < 0)
  1383. {
  1384. yNew = 0;
  1385. }
  1386. else if ((yNew+hChild) > hScreen)
  1387. {
  1388. yNew = hScreen - hChild;
  1389. }
  1390. // Set it, and return
  1391. return SetWindowPos (hwndChild, NULL,
  1392. xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  1393. }
  1394. VOID CWebJit::UpdateStatusString()
  1395. {
  1396. CHAR szFormat[400];
  1397. CHAR szMessage[800];
  1398. CHAR szComponent[400];
  1399. int nRet;
  1400. UINT id;
  1401. nRet = MLLoadStringA(MapComponentToResourceId(m_pwszComponentId), szComponent, ARRAY_ELEMENTS(szComponent));
  1402. if (!nRet)
  1403. goto exit;
  1404. switch(m_State)
  1405. {
  1406. case WJSTATE_BINDING:
  1407. id = IDS_DOWNLOADING;
  1408. break;
  1409. case WJSTATE_VERIFYING:
  1410. id = IDS_CHECKTRUST;
  1411. break;
  1412. case WJSTATE_WAITING_PROCESS:
  1413. id = IDS_INSTALLING;
  1414. break;
  1415. }
  1416. nRet = MLLoadStringA(id, szFormat, ARRAY_ELEMENTS(szFormat));
  1417. if (!nRet)
  1418. goto exit;
  1419. if (wsprintfA(szMessage, szFormat, szComponent))
  1420. {
  1421. SetDlgItemTextA(m_hDialog, IDC_TEXT, szMessage);
  1422. }
  1423. exit:
  1424. return;
  1425. }
  1426. BOOL CWebJit::SetupWindow()
  1427. {
  1428. WCHAR szMsg[1000];
  1429. BOOL bRet = FALSE;
  1430. int nRet = MLLoadStringW(IDS_DOWNLOAD_MSG, szMsg, ARRAY_ELEMENTS(szMsg));
  1431. if (nRet)
  1432. {
  1433. StrCatW(szMsg, L"\n\n");
  1434. int nRet2;
  1435. nRet2 = MLLoadStringW(MapComponentToResourceId(m_pwszComponentId), szMsg+nRet+2, ARRAY_ELEMENTS(szMsg)-nRet-2);
  1436. if (nRet2)
  1437. {
  1438. *(szMsg+nRet+nRet2+2) = L'\0';
  1439. bRet = TRUE;
  1440. if (!SetDlgItemTextWrapW(m_hDialog, IDC_TEXT, szMsg))
  1441. {
  1442. bRet = FALSE;
  1443. }
  1444. }
  1445. }
  1446. if (!(m_dwFlags & FIEF_FLAG_FORCE_JITUI))
  1447. {
  1448. EnableWindow(GetDlgItem(m_hDialog, IDC_CHECK1), TRUE);
  1449. }
  1450. CenterWindow(m_hDialog, m_hWndParent);
  1451. return bRet;
  1452. }
  1453. DWORD mapIDCsToIDHs[] =
  1454. {
  1455. IDC_TEXT, 0, //This value is changed depending on component being WebJited
  1456. IDDOWNLOAD, 50621,
  1457. IDCANCEL, 50462,
  1458. IDOK, 50510,
  1459. IDC_CHECK1, 50620,
  1460. IDC_REMAINING_SIZE, 50457,
  1461. IDC_REMAINING_TIME, 50458,
  1462. 0,0
  1463. };
  1464. DWORD* GetMapArray(CWebJit* pWebJit)
  1465. {
  1466. DWORD* pdwMapArray = new DWORD[ARRAY_ELEMENTS(mapIDCsToIDHs)];
  1467. if (pdwMapArray)
  1468. {
  1469. memcpy(pdwMapArray, mapIDCsToIDHs, sizeof(mapIDCsToIDHs));
  1470. pdwMapArray[1] = MapComponentToHelpId(pWebJit->GetComponentIdName());
  1471. }
  1472. return pdwMapArray;
  1473. }
  1474. INT_PTR CALLBACK WebJitProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1475. {
  1476. CWebJit* pWebJit = (CWebJit *)GetWindowLongPtr(hDlg, DWLP_USER);
  1477. DWORD* pdwMapArray;
  1478. HRESULT hr;
  1479. //ASSERT (pWebJit || (message == WM_INITDIALOG));
  1480. switch(message)
  1481. {
  1482. case WM_INITDIALOG:
  1483. pWebJit = ((WEBJIT_PARAM*)lParam)->pWebJit;
  1484. if (pWebJit)
  1485. {
  1486. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pWebJit);
  1487. pWebJit->SetWindowHandle(hDlg);
  1488. pWebJit->SetupWindow();
  1489. return TRUE;
  1490. }
  1491. else
  1492. {
  1493. return FALSE;
  1494. }
  1495. case WM_COMMAND:
  1496. switch (LOWORD(wParam))
  1497. {
  1498. case IDC_CHECK1:
  1499. {
  1500. if (SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETCHECK, 0, 0) == BST_CHECKED)
  1501. {
  1502. EnableWindow(GetDlgItem(hDlg, IDDOWNLOAD), FALSE);
  1503. ShowWindow(GetDlgItem(hDlg, IDDOWNLOAD), SW_HIDE);
  1504. ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOWNORMAL);
  1505. EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
  1506. }
  1507. else
  1508. {
  1509. EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
  1510. ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
  1511. ShowWindow(GetDlgItem(hDlg, IDDOWNLOAD), SW_SHOWNORMAL);
  1512. EnableWindow(GetDlgItem(hDlg, IDDOWNLOAD), TRUE);
  1513. }
  1514. return TRUE;
  1515. }
  1516. case IDOK:
  1517. {
  1518. if (SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETSTATE, 0, 0) == BST_CHECKED)
  1519. {
  1520. //Never download any of these components.
  1521. pWebJit->Terminate(NEVERASK);
  1522. }
  1523. return TRUE;
  1524. }
  1525. case IDDOWNLOAD:
  1526. {
  1527. if (SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETSTATE, 0, 0) == BST_CHECKED)
  1528. {
  1529. //Never download any of these components.
  1530. pWebJit->Terminate(NEVERASK);
  1531. return TRUE;
  1532. }
  1533. if (!pWebJit->IsDownloadInited())
  1534. {
  1535. pWebJit->SetDownloadInited();
  1536. }
  1537. else
  1538. {
  1539. return TRUE;
  1540. }
  1541. EnableWindow(GetDlgItem(hDlg, IDDOWNLOAD), FALSE);
  1542. EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), FALSE);
  1543. SetFocus(GetDlgItem(hDlg, IDCANCEL));
  1544. HRESULT hr;
  1545. hr = pWebJit->SetupDownload();
  1546. if (FAILED(hr))
  1547. {
  1548. //synchronous failure.
  1549. SendMessage(hDlg, WM_SETUP_ERROR, (WPARAM)hr, 0);
  1550. return TRUE;
  1551. }
  1552. hr = pWebJit->StartDownload();
  1553. pWebJit->UpdateDownloadResult(hr, FALSE);
  1554. return TRUE;
  1555. }
  1556. case IDCANCEL:
  1557. pWebJit->ProcessAbort();
  1558. return TRUE;
  1559. }
  1560. break;
  1561. case WM_DATA_AVAILABLE:
  1562. if (!pWebJit->IsReadTimerStarted())
  1563. {
  1564. pWebJit->SetReadTimerStarted();
  1565. SetTimer(hDlg, TIMER_DOWNLOAD, TIMER_DOWNLOAD_INTERVAL, NULL);
  1566. }
  1567. pWebJit->ReadData();
  1568. return TRUE;
  1569. case WM_DOWNLOAD_DONE:
  1570. KillTimer(hDlg, TIMER_DOWNLOAD);
  1571. ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS1), SW_HIDE);
  1572. ShowWindow(GetDlgItem(hDlg, IDC_REMAINING_TIME), SW_HIDE);
  1573. ShowWindow(GetDlgItem(hDlg, IDC_REMAINING_SIZE), SW_HIDE);
  1574. pWebJit->ProcessFile();
  1575. return TRUE;
  1576. case WM_START_TIMER:
  1577. if (wParam == 1)
  1578. {
  1579. pWebJit->SetState(WJSTATE_WAITING_PROCESS);
  1580. pWebJit->UpdateStatusString();
  1581. SetTimer(hDlg, TIMER_EXEC_POLL, TIMER_EXEC_POLL_INTERVAL, NULL);
  1582. }
  1583. return TRUE;
  1584. case WM_SETUP_ERROR:
  1585. case WM_DOWNLOAD_ERROR:
  1586. case WM_PROCESS_ERROR:
  1587. KillTimer(hDlg, TIMER_DOWNLOAD);
  1588. hr = pWebJit->DisplayError((HRESULT)wParam, message);
  1589. pWebJit->Terminate(hr);
  1590. return TRUE;
  1591. case WM_DONT_WAIT:
  1592. pWebJit->SetState(WJSTATE_DONE);
  1593. pWebJit->Terminate(SUCCESS);
  1594. return TRUE;
  1595. case WM_TIMER:
  1596. if (wParam == TIMER_EXEC_POLL)
  1597. {
  1598. if (pWebJit->GetProcessHandle()
  1599. && (WAIT_OBJECT_0 == WaitForSingleObject(pWebJit->GetProcessHandle(), 0)))
  1600. {
  1601. KillTimer(hDlg, TIMER_EXEC_POLL);
  1602. pWebJit->SetState(WJSTATE_DONE);
  1603. pWebJit->Terminate(SUCCESS);
  1604. }
  1605. else if (pWebJit->IsAborted())
  1606. {
  1607. KillTimer(hDlg, TIMER_EXEC_POLL);
  1608. pWebJit->Terminate(CANCELLED);
  1609. }
  1610. }
  1611. else if (wParam == TIMER_DOWNLOAD)
  1612. {
  1613. pWebJit->ReadData();
  1614. }
  1615. return TRUE;
  1616. case WM_HELP:// F1
  1617. pdwMapArray = pWebJit ? GetMapArray(pWebJit) : NULL;
  1618. if (pdwMapArray)
  1619. {
  1620. ResWinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  1621. IDS_WEBJITHELPFILE,
  1622. HELP_WM_HELP,
  1623. (ULONG_PTR)(LPSTR)pdwMapArray);
  1624. delete [] pdwMapArray;
  1625. }
  1626. break;
  1627. case WM_CONTEXTMENU:// right mouse click
  1628. pdwMapArray = pWebJit ? GetMapArray(pWebJit) : NULL;
  1629. if (pdwMapArray)
  1630. {
  1631. ResWinHelp(hDlg,
  1632. IDS_WEBJITHELPFILE,
  1633. HELP_CONTEXTMENU,
  1634. (ULONG_PTR)(LPSTR)pdwMapArray);
  1635. delete [] pdwMapArray;
  1636. }
  1637. break;
  1638. }
  1639. return FALSE;
  1640. }
  1641. //from setup/iexpress/wextract/wextract.c
  1642. typedef HRESULT (*CHECKTOKENMEMBERSHIP)(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember);
  1643. BOOL CheckToken(BOOL *pfIsAdmin)
  1644. {
  1645. DEBUG_ENTER((DBG_DOWNLOAD,
  1646. Bool,
  1647. "CWebJit::CheckToken",
  1648. NULL
  1649. ));
  1650. BOOL bNewNT5check = FALSE;
  1651. HINSTANCE hAdvapi32 = NULL;
  1652. CHECKTOKENMEMBERSHIP pf;
  1653. PSID AdministratorsGroup;
  1654. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  1655. hAdvapi32 = LoadLibrary("advapi32.dll");
  1656. if (hAdvapi32)
  1657. {
  1658. pf = (CHECKTOKENMEMBERSHIP)GetProcAddress(hAdvapi32, "CheckTokenMembership");
  1659. if (pf)
  1660. {
  1661. bNewNT5check = TRUE;
  1662. *pfIsAdmin = FALSE;
  1663. if(AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
  1664. DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup) )
  1665. {
  1666. pf(NULL, AdministratorsGroup, pfIsAdmin);
  1667. FreeSid(AdministratorsGroup);
  1668. }
  1669. }
  1670. FreeLibrary(hAdvapi32);
  1671. }
  1672. DEBUG_LEAVE(bNewNT5check);
  1673. return bNewNT5check;
  1674. }
  1675. // IsNTAdmin();
  1676. // Returns true if our process has admin priviliges.
  1677. // Returns false otherwise.
  1678. BOOL IsNTAdmin()
  1679. {
  1680. DEBUG_ENTER((DBG_DOWNLOAD,
  1681. Bool,
  1682. "CWebJit::IsNTAdmin",
  1683. NULL
  1684. ));
  1685. static int fIsAdmin = 2;
  1686. HANDLE hAccessToken;
  1687. PTOKEN_GROUPS ptgGroups;
  1688. DWORD dwReqSize;
  1689. UINT i;
  1690. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  1691. PSID AdministratorsGroup;
  1692. BOOL bRet;
  1693. OSVERSIONINFO osvi;
  1694. //
  1695. // If we have cached a value, return the cached value. Note I never
  1696. // set the cached value to false as I want to retry each time in
  1697. // case a previous failure was just a temp. problem (ie net access down)
  1698. //
  1699. bRet = FALSE;
  1700. ptgGroups = NULL;
  1701. if( fIsAdmin != 2 )
  1702. {
  1703. DEBUG_LEAVE(fIsAdmin);
  1704. return (BOOL)fIsAdmin;
  1705. }
  1706. osvi.dwOSVersionInfoSize = sizeof(osvi);
  1707. GetVersionEx(&osvi);
  1708. if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
  1709. {
  1710. fIsAdmin = TRUE; // If we are not running under NT return TRUE.
  1711. DEBUG_LEAVE(fIsAdmin);
  1712. return (BOOL)fIsAdmin;
  1713. }
  1714. if (!CheckToken(&bRet))
  1715. {
  1716. if(!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hAccessToken ) )
  1717. {
  1718. DEBUG_LEAVE(FALSE);
  1719. return FALSE;
  1720. }
  1721. // See how big of a buffer we need for the token information
  1722. if(!GetTokenInformation( hAccessToken, TokenGroups, NULL, 0, &dwReqSize))
  1723. {
  1724. // GetTokenInfo should the buffer size we need - Alloc a buffer
  1725. if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  1726. ptgGroups = (PTOKEN_GROUPS) LocalAlloc(LMEM_FIXED, dwReqSize);
  1727. }
  1728. // ptgGroups could be NULL for a coupla reasons here:
  1729. // 1. The alloc above failed
  1730. // 2. GetTokenInformation actually managed to succeed the first time (possible?)
  1731. // 3. GetTokenInfo failed for a reason other than insufficient buffer
  1732. // Any of these seem justification for bailing.
  1733. // So, make sure it isn't null, then get the token info
  1734. if(ptgGroups && GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, dwReqSize, &dwReqSize))
  1735. {
  1736. if(AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
  1737. DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup) )
  1738. {
  1739. // Search thru all the groups this process belongs to looking for the
  1740. // Admistrators Group.
  1741. for( i=0; i < ptgGroups->GroupCount; i++ )
  1742. {
  1743. if( EqualSid(ptgGroups->Groups[i].Sid, AdministratorsGroup) )
  1744. {
  1745. // Yea! This guy looks like an admin
  1746. fIsAdmin = TRUE;
  1747. bRet = TRUE;
  1748. break;
  1749. }
  1750. }
  1751. FreeSid(AdministratorsGroup);
  1752. }
  1753. }
  1754. if(ptgGroups)
  1755. LocalFree(ptgGroups);
  1756. // BUGBUG: Close handle here? doc's aren't clear whether this is needed.
  1757. CloseHandle(hAccessToken);
  1758. }
  1759. else if (bRet)
  1760. fIsAdmin = TRUE;
  1761. DEBUG_LEAVE(bRet);
  1762. return bRet;
  1763. }
  1764. BOOL IsWin32X86()
  1765. {
  1766. OSVERSIONINFO osvi;
  1767. SYSTEM_INFO sysinfo;
  1768. GetSystemInfo(&sysinfo);
  1769. osvi.dwOSVersionInfoSize = sizeof(osvi);
  1770. GetVersionEx(&osvi);
  1771. if (((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
  1772. || (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
  1773. && (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL))
  1774. {
  1775. return TRUE;
  1776. }
  1777. return FALSE;
  1778. }