2054 lines
55 KiB
C++
2054 lines
55 KiB
C++
#include <cdlpch.h>
|
|
#include <windows.h>
|
|
#include <objbase.h>
|
|
#include <winbase.h>
|
|
#include <softpub.h>
|
|
#include "capi.h"
|
|
//#include <stdlib.h>
|
|
#include <stdio.h>
|
|
//#include <stdlib.h>
|
|
//#include <string.h>
|
|
//#include <tchar.h>
|
|
#include <crtdbg.h>
|
|
#include <urlmon.h>
|
|
#include <wininet.h>
|
|
#include <shellapi.h>
|
|
#include <commctrl.h>
|
|
#include <shlwapi.h>
|
|
#include <shfusion.h>
|
|
#include "webjitres.h"
|
|
#include "webjit.h"
|
|
#include "mluisupp.h"
|
|
|
|
#undef SAFERELEASE
|
|
#define SAFERELEASE(p) if ((p) != NULL) { (p)->Release(); (p) = NULL; };
|
|
#undef SAFEDELETE
|
|
#define SAFEDELETE(p) if ((p) != NULL) { delete (p); (p) = NULL; };
|
|
#undef ARRAY_ELEMENTS
|
|
#define ARRAY_ELEMENTS(array) \
|
|
(sizeof(array)/sizeof(array[0]))
|
|
|
|
BOOL IsUIRestricted();
|
|
BOOL IsWin32X86();
|
|
BOOL IsNTAdmin();
|
|
extern BOOL g_bLockedDown;
|
|
extern HMODULE g_hInst;
|
|
|
|
HRESULT EnsureSecurityManager ();
|
|
|
|
CWebJit::CWebJit(WEBJIT_PARAM* pWebJitParam)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
None,
|
|
"CWebJit::CWebJit",
|
|
"this=%#x, %.200q, %.200wq, %#x, %#x",
|
|
this, pWebJitParam->lpszResource, pWebJitParam->pwszComponentId, pWebJitParam->dwFlags, pWebJitParam->hWndParent
|
|
));
|
|
|
|
m_fInited = FALSE;
|
|
m_hWintrustMod = NULL;
|
|
m_fInitedCC = FALSE;
|
|
m_hComCtlMod = NULL;
|
|
|
|
m_szResource = pWebJitParam->lpszResource;
|
|
m_dwFlags = pWebJitParam->dwFlags;
|
|
m_pwszComponentId = pWebJitParam->pwszComponentId;
|
|
m_hWndParent = pWebJitParam->hWndParent;
|
|
m_pQueryInstalled = pWebJitParam->pQueryInstalled;
|
|
m_pwszUrl = NULL;
|
|
m_cRef = 1;
|
|
m_dwTotal = m_dwCurrent = 0;
|
|
m_hDialog = NULL;
|
|
m_hProcess = 0;
|
|
m_pBinding = NULL;
|
|
m_pStm = NULL;
|
|
m_pMk = NULL;
|
|
m_pbc = NULL;
|
|
m_hCacheFile = NULL;
|
|
m_dwRetVal = 0;
|
|
m_dwDownloadSpeed = 0;
|
|
|
|
m_hDownloadResult = S_OK;
|
|
m_fResultIn = FALSE;
|
|
|
|
m_fAborted = FALSE;
|
|
m_fCalledAbort = FALSE;
|
|
|
|
m_State = WJSTATE_INIT;
|
|
|
|
m_hrInternal = S_OK;
|
|
m_pwszMimeType = NULL;
|
|
m_pwszRedirectUrl = NULL;
|
|
m_pwszCacheFile = NULL;
|
|
m_fHtml = FALSE;
|
|
m_fDownloadInited = FALSE;
|
|
m_pTempBuffer = NULL;
|
|
m_bReading = FALSE;
|
|
m_bStartedReadTimer = FALSE;
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
CWebJit::~CWebJit()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
None,
|
|
"CWebJit::~CWebJit",
|
|
"this=%#x, aborted?=%B, result=%#x, redirect=%.200wq, m_hProcess=%#x (%d)",
|
|
this, m_fAborted, m_hDownloadResult, (m_pwszRedirectUrl ? m_pwszRedirectUrl : L"NONE"), m_hProcess, m_hProcess
|
|
));
|
|
|
|
if (m_fInited)
|
|
{
|
|
FreeLibrary(m_hWintrustMod);
|
|
}
|
|
if (m_fInitedCC)
|
|
{
|
|
FreeLibrary(m_hComCtlMod);
|
|
}
|
|
if (m_hProcess)
|
|
{
|
|
CloseHandle(m_hProcess);
|
|
}
|
|
|
|
ReleaseAll();
|
|
if (m_pwszUrl)
|
|
delete [] m_pwszUrl;
|
|
if (m_pwszMimeType)
|
|
delete [] m_pwszMimeType;
|
|
if (m_pwszCacheFile)
|
|
delete [] m_pwszCacheFile;
|
|
if (m_pwszRedirectUrl)
|
|
delete [] m_pwszRedirectUrl;
|
|
if (m_pTempBuffer)
|
|
delete [] m_pTempBuffer;
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
VOID CWebJit::ReleaseAll()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
None,
|
|
"CWebJit::ReleaseAll",
|
|
"this=%#x, %#x, %#x, %#x, %#x",
|
|
this, m_pStm, m_pMk, m_pBinding, m_pbc
|
|
));
|
|
|
|
SAFERELEASE(m_pStm);
|
|
SAFERELEASE(m_pMk);
|
|
SAFERELEASE(m_pBinding);
|
|
SAFERELEASE(m_pbc);
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::QueryInterface(REFIID riid, void ** ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if (riid == IID_IUnknown)
|
|
{
|
|
*ppv = (void*)this;
|
|
}
|
|
else if (riid == IID_IBindStatusCallback)
|
|
{
|
|
*ppv = (void*)(IBindStatusCallback*)this;
|
|
}
|
|
else if (riid == IID_IAuthenticate)
|
|
{
|
|
*ppv = (void*)(IAuthenticate*)this;
|
|
}
|
|
|
|
if (*ppv)
|
|
{
|
|
((IUnknown *)*ppv)->AddRef();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWebJit::AddRef()
|
|
{
|
|
return m_cRef++;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWebJit::Release()
|
|
{
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
// IBindStatusCallback methods
|
|
STDMETHODIMP CWebJit::OnStartBinding(DWORD dwReserved, IBinding* pbinding)
|
|
{
|
|
if (m_fAborted)
|
|
{
|
|
goto abort;
|
|
}
|
|
|
|
m_pBinding = pbinding;
|
|
m_pBinding->AddRef();
|
|
|
|
return S_OK;
|
|
|
|
abort:
|
|
return E_FAIL;
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR pwzStatusText)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::OnProgress",
|
|
"this=%#x, %#x, %#x, %d (%#x), %.200wq",
|
|
this, ulProgress, ulProgressMax, ulStatusCode, ulStatusCode, pwzStatusText
|
|
));
|
|
|
|
if (m_fAborted)
|
|
{
|
|
goto abort;
|
|
}
|
|
|
|
switch(ulStatusCode)
|
|
{
|
|
case BINDSTATUS_BEGINDOWNLOADDATA:
|
|
{
|
|
m_dwTotal = ulProgressMax;
|
|
HWND hProgressBar = GetDlgItem(m_hDialog, IDC_PROGRESS1);
|
|
if (m_dwTotal)
|
|
{
|
|
ShowWindow(hProgressBar, SW_SHOWNORMAL);
|
|
ShowWindow(GetDlgItem(m_hDialog, IDC_REMAINING_SIZE), SW_SHOWNORMAL);
|
|
ShowWindow(GetDlgItem(m_hDialog, IDC_REMAINING_TIME), SW_SHOWNORMAL);
|
|
UpdateProgressUI();
|
|
}
|
|
SendMessage(hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0,65535));
|
|
}
|
|
break;
|
|
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
|
|
{
|
|
//ASSERT (pwzStatusText && (*pwzStatusText != L'\0'));
|
|
int nWideLen = lstrlenW(pwzStatusText);
|
|
m_pwszCacheFile = new WCHAR[nWideLen+1];
|
|
if (!m_pwszCacheFile)
|
|
{
|
|
m_hrInternal = E_OUTOFMEMORY;
|
|
goto abort;
|
|
}
|
|
StrCpyW(m_pwszCacheFile, pwzStatusText);
|
|
}
|
|
break;
|
|
case BINDSTATUS_MIMETYPEAVAILABLE:
|
|
{
|
|
//ASSERT (pwzStatusText && (*pwzStatusText != L'\0'));
|
|
int nWideLen = lstrlenW(pwzStatusText);
|
|
m_pwszMimeType = new WCHAR[nWideLen+1];
|
|
if (!m_pwszMimeType)
|
|
{
|
|
m_hrInternal = E_OUTOFMEMORY;
|
|
goto abort;
|
|
}
|
|
StrCpyW(m_pwszMimeType, pwzStatusText);
|
|
}
|
|
break;
|
|
case BINDSTATUS_REDIRECTING:
|
|
{
|
|
//ASSERT (pwzStatusText && (*pwzStatusText != L'\0'));
|
|
int nWideLen = lstrlenW(pwzStatusText);
|
|
if (m_pwszRedirectUrl)
|
|
{
|
|
delete [] m_pwszRedirectUrl;
|
|
}
|
|
m_pwszRedirectUrl = new WCHAR[nWideLen+1];
|
|
if (!m_pwszRedirectUrl)
|
|
{
|
|
m_hrInternal = E_OUTOFMEMORY;
|
|
goto abort;
|
|
}
|
|
StrCpyW(m_pwszRedirectUrl, pwzStatusText);
|
|
}
|
|
break;
|
|
}
|
|
|
|
DEBUG_LEAVE(S_OK);
|
|
return S_OK;
|
|
|
|
abort:
|
|
if (!m_fCalledAbort && m_pBinding)
|
|
{
|
|
m_pBinding->Abort();
|
|
m_fCalledAbort = TRUE;
|
|
}
|
|
|
|
DEBUG_LEAVE(S_OK);
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::OnStopBinding(HRESULT hrResult, LPCWSTR szError)
|
|
{
|
|
UpdateDownloadResult(hrResult, TRUE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindInfo)
|
|
{
|
|
// clear BINDINFO but keep its size
|
|
DWORD cbSize = pbindInfo->cbSize;
|
|
memset(pbindInfo, 0, cbSize);
|
|
|
|
pbindInfo->cbSize = cbSize;
|
|
*pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_RESYNCHRONIZE | BINDF_PREFERDEFAULTHANDLER | BINDF_NEEDFILE;
|
|
pbindInfo->dwBindVerb = BINDVERB_GET;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pfmtetc, STGMEDIUM* pstgmed)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Dword,
|
|
"CWebJit::OnDataAvailable",
|
|
"this=%#x, %#x, %#x, %#x, %#x, %#x / %#x",
|
|
this, grfBSCF, dwSize, pstgmed->pstm, pfmtetc->tymed, m_dwCurrent, m_dwTotal
|
|
));
|
|
|
|
HRESULT hr;
|
|
if (m_fAborted)
|
|
{
|
|
goto abort;
|
|
}
|
|
|
|
if (!m_pStm)
|
|
{
|
|
m_pStm = pstgmed->pstm;
|
|
m_pStm->AddRef();
|
|
}
|
|
|
|
if (!m_hCacheFile && m_pBinding)
|
|
{
|
|
IWinInetHttpInfo* pHttpInfo = NULL;
|
|
hr = QueryInterface(IID_IWinInetHttpInfo, (void**)&pHttpInfo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwSize = sizeof(m_hCacheFile);
|
|
hr = pHttpInfo->QueryOption(WININETINFO_OPTION_LOCK_HANDLE, &m_hCacheFile, &dwSize);
|
|
pHttpInfo->Release();
|
|
}
|
|
}
|
|
|
|
PostMessage(m_hDialog, WM_DATA_AVAILABLE, 0, 0);
|
|
|
|
DEBUG_LEAVE(m_dwCurrent);
|
|
return S_OK;
|
|
|
|
abort:
|
|
if (!m_fCalledAbort && m_pBinding)
|
|
{
|
|
m_pBinding->Abort();
|
|
m_fCalledAbort = TRUE;
|
|
}
|
|
|
|
DEBUG_LEAVE(E_ABORT);
|
|
return S_OK;
|
|
}
|
|
|
|
VOID CWebJit::ReadData()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Dword,
|
|
"CWebJit::ReadData",
|
|
"this=%#x, %#x, %#x / %#x",
|
|
this, m_pStm, m_dwCurrent, m_dwTotal
|
|
));
|
|
|
|
HRESULT hr = E_FAIL;
|
|
HRESULT hrAbort = S_OK;
|
|
|
|
//reentrancy guard
|
|
if (m_bReading)
|
|
{
|
|
goto leave;
|
|
}
|
|
m_bReading = TRUE;
|
|
|
|
if (m_fAborted)
|
|
{
|
|
goto abort;
|
|
}
|
|
|
|
if (m_State >= WJSTATE_VERIFYING)
|
|
{
|
|
// redundant timer messages
|
|
goto end;
|
|
}
|
|
|
|
HWND hProgressBar = GetDlgItem(m_hDialog, IDC_PROGRESS1);
|
|
|
|
DWORD dwRead;
|
|
hr = m_pStm->Read(m_pTempBuffer, TEMPREADBUFFERSIZE, &dwRead);
|
|
if (SUCCEEDED(hr)
|
|
|| ( (hr == E_PENDING) && (dwRead > 0) ) )
|
|
{
|
|
m_dwCurrent += dwRead;
|
|
//UpdateProgressUI();
|
|
if (m_dwTotal)
|
|
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)((m_dwCurrent*1.00/m_dwTotal)*65535), 0);
|
|
}
|
|
|
|
end:
|
|
// if we are done reading OR we have been aborted
|
|
if (((hr == S_FALSE)
|
|
&& (m_dwTotal ? (m_dwCurrent == m_dwTotal) : TRUE))
|
|
|| (hr == E_ABORT))
|
|
{
|
|
// handle cases where Abort failed to prevent leak.
|
|
if ((hrAbort == INET_E_RESULT_DISPATCHED)
|
|
|| (hrAbort == E_FAIL)
|
|
&& m_pStm)
|
|
{
|
|
HRESULT hrTemp;
|
|
do
|
|
{
|
|
hrTemp = m_pStm->Read(m_pTempBuffer, TEMPREADBUFFERSIZE, &dwRead);
|
|
if (SUCCEEDED(hrTemp)
|
|
|| ((hrTemp==E_PENDING) && (dwRead>0)))
|
|
{
|
|
m_dwCurrent += dwRead;
|
|
}
|
|
}
|
|
while ((hrTemp == NOERROR) && m_pStm);
|
|
}
|
|
|
|
// and have already received OnStopBinding
|
|
if (m_State == WJSTATE_DOWNLOADED)
|
|
{
|
|
if (m_pMk)
|
|
{
|
|
if (hr == E_ABORT)
|
|
{
|
|
m_hDownloadResult = E_ABORT;
|
|
}
|
|
//abort or finished read after osb.
|
|
ReleaseAll();
|
|
|
|
if (SUCCEEDED(m_hDownloadResult))
|
|
{
|
|
PostMessage(m_hDialog, WM_DOWNLOAD_DONE, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
PostMessage(m_hDialog, WM_DOWNLOAD_ERROR, (WPARAM)m_hDownloadResult, 0);
|
|
}
|
|
}
|
|
}
|
|
m_State = WJSTATE_FINISHED_READ;
|
|
}
|
|
m_bReading = FALSE;
|
|
|
|
leave:
|
|
DEBUG_LEAVE(m_dwCurrent);
|
|
return;
|
|
|
|
abort:
|
|
hr = E_ABORT;
|
|
|
|
if (!m_fCalledAbort && m_pBinding)
|
|
{
|
|
m_fCalledAbort = TRUE;
|
|
hrAbort = m_pBinding->Abort();
|
|
}
|
|
|
|
goto end;
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::OnObjectAvailable(REFIID riid, IUnknown* punk)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CWebJit::Authenticate(HWND* phwnd, LPWSTR *pszUsername,LPWSTR *pszPassword)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::Authenticate",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
|
|
*phwnd = m_hDialog;
|
|
*pszUsername = 0;
|
|
*pszPassword = 0;
|
|
|
|
DEBUG_LEAVE(S_OK);
|
|
return S_OK;
|
|
}
|
|
|
|
DWORD CWebJit::GetDownloadSpeed()
|
|
{
|
|
//using iejit.htx guesstimates/logic
|
|
DWORD dwDownloadSpeed = 120; //default to 28.8kbps modem.
|
|
DWORD dwFlags;
|
|
if (InternetGetConnectedState(&dwFlags, NULL))
|
|
{
|
|
if (dwFlags & INTERNET_CONNECTION_LAN)
|
|
{
|
|
dwDownloadSpeed = 800; //KB/min
|
|
}
|
|
else if (dwFlags & INTERNET_CONNECTION_MODEM)
|
|
{
|
|
dwDownloadSpeed = 120; //based on 28.8kbps
|
|
}
|
|
}
|
|
|
|
return dwDownloadSpeed;
|
|
}
|
|
|
|
BOOL CWebJit::UpdateProgressUI()
|
|
{
|
|
DWORD dwDownloadTime;
|
|
BOOL bRetVal = TRUE;
|
|
CHAR szMsg[1000];
|
|
int nRet;
|
|
DWORD dwDownloadSize;
|
|
|
|
if (!m_dwDownloadSpeed)
|
|
{
|
|
m_dwDownloadSpeed = GetDownloadSpeed();
|
|
}
|
|
if (!m_dwTotal)
|
|
{
|
|
// didn't get a total length - can't display progress.
|
|
bRetVal = FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
dwDownloadSize = m_dwTotal - m_dwCurrent;
|
|
|
|
dwDownloadTime = dwDownloadSize/m_dwDownloadSpeed/1024;
|
|
nRet = MLLoadStringA(IDS_TIME, szMsg, ARRAY_ELEMENTS(szMsg));
|
|
if (dwDownloadTime >= 60)
|
|
{
|
|
DWORD dwDownloadHr = dwDownloadTime / 60;
|
|
DWORD dwDownloadMin = dwDownloadTime % 60;
|
|
|
|
if(dwDownloadHr == 1)
|
|
{
|
|
nRet += MLLoadStringA(IDS_hr1_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
else if ((sizeof(szMsg) - nRet) > 2)
|
|
{
|
|
wsprintfA(szMsg+nRet, "%2d", dwDownloadHr);
|
|
nRet += 2;
|
|
nRet += MLLoadStringA(IDS_hrs_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
|
|
if((dwDownloadMin > 0)
|
|
&& ((sizeof(szMsg) - nRet) > 3))
|
|
{
|
|
wsprintfA(szMsg+nRet, " %2d", dwDownloadMin);
|
|
nRet += 3;
|
|
nRet += MLLoadStringA(IDS_MINUTES_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
}
|
|
else if(dwDownloadTime < 60)
|
|
{
|
|
if((dwDownloadSize != 0) && (dwDownloadTime == 0))
|
|
{
|
|
nRet += MLLoadStringA(IDS_LessThanAMinute_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
else if ((sizeof(szMsg) - nRet) > 2)
|
|
{
|
|
wsprintfA(szMsg+nRet, "%2d", dwDownloadTime);
|
|
nRet += 2;
|
|
nRet += MLLoadStringA(IDS_MINUTES_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
}
|
|
SetDlgItemTextA(m_hDialog, IDC_REMAINING_TIME, szMsg);
|
|
|
|
nRet = MLLoadStringA(IDS_SIZE, szMsg, ARRAY_ELEMENTS(szMsg));
|
|
if ((dwDownloadSize > (1024*1024))
|
|
&& ((sizeof(szMsg) - nRet) > 3))
|
|
{
|
|
DWORD dwMbSize = dwDownloadSize/(1024*1024);
|
|
wsprintfA(szMsg+nRet, "%d", dwMbSize);
|
|
nRet += (dwMbSize<10) ? 1 : ((dwMbSize<100) ? 2 : 3);
|
|
nRet += MLLoadStringA(IDS_MEGABYTE_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
else if ((sizeof(szMsg) - nRet) > 3)
|
|
{
|
|
DWORD dwKbSize = dwDownloadSize/1024;
|
|
wsprintfA(szMsg+nRet, "%d", dwKbSize);
|
|
nRet += (dwKbSize<10) ? 1 : ((dwKbSize<100) ? 2 : 3);
|
|
nRet += MLLoadStringA(IDS_KILOBYTES_TEXT, szMsg+nRet, ARRAY_ELEMENTS(szMsg)-nRet);
|
|
}
|
|
SetDlgItemTextA(m_hDialog, IDC_REMAINING_SIZE, szMsg);
|
|
|
|
SendMessage(GetDlgItem(m_hDialog, IDC_PROGRESS1), PBM_SETPOS, (WPARAM)((m_dwCurrent*1.00/m_dwTotal)*65535), 0);
|
|
|
|
exit:
|
|
return bRetVal;
|
|
}
|
|
|
|
BOOL CWebJit::IsConnected(BOOL* pfIsOffline)
|
|
{
|
|
BOOL bRetVal = TRUE;
|
|
DWORD dwFlags = 0;
|
|
|
|
bRetVal = InternetGetConnectedState(&dwFlags, NULL);
|
|
|
|
if (dwFlags & INTERNET_CONNECTION_OFFLINE)
|
|
{
|
|
*pfIsOffline = TRUE;
|
|
}
|
|
else
|
|
{
|
|
*pfIsOffline = FALSE;
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
VOID CWebJit::UpdateDownloadResult(HRESULT hr, BOOL fFromOnStopBinding)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::UpdateDownloadResult",
|
|
"this=%#x, hr=%#x, OnStopBinding?=%B, fResultIn?=%B, previous hr=%#x",
|
|
this, hr, fFromOnStopBinding, m_fResultIn, m_hDownloadResult
|
|
));
|
|
|
|
if (fFromOnStopBinding)
|
|
{
|
|
if (m_fResultIn)
|
|
{
|
|
// If the result from BindToStorage was successful, use this one.
|
|
if ((SUCCEEDED(m_hDownloadResult))
|
|
|| (m_hDownloadResult == E_PENDING))
|
|
{
|
|
m_hDownloadResult = hr;
|
|
}
|
|
goto NextStep;
|
|
}
|
|
else
|
|
{
|
|
m_hDownloadResult = hr;
|
|
m_fResultIn = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_fResultIn)
|
|
{
|
|
if (SUCCEEDED(m_hDownloadResult)
|
|
&& !((hr == MK_S_ASYNCHRONOUS) || (hr == E_PENDING)))
|
|
{
|
|
m_hDownloadResult = hr;
|
|
}
|
|
goto NextStep;
|
|
}
|
|
else
|
|
{
|
|
m_hDownloadResult = hr;
|
|
m_fResultIn = TRUE;
|
|
|
|
if (!((hr == MK_S_ASYNCHRONOUS) || (hr == E_PENDING)))
|
|
{
|
|
goto NextStep;
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
DEBUG_LEAVE(m_hDownloadResult);
|
|
return;
|
|
|
|
NextStep:
|
|
if (m_fAborted)
|
|
{
|
|
m_hDownloadResult = E_ABORT;
|
|
}
|
|
else if (m_State < WJSTATE_FINISHED_READ)
|
|
{
|
|
m_State = WJSTATE_DOWNLOADED;
|
|
}
|
|
|
|
if ((m_State == WJSTATE_FINISHED_READ)
|
|
|| m_fAborted
|
|
|| FAILED(m_hDownloadResult))
|
|
{
|
|
// if we either aborted or
|
|
// if all the data has been read
|
|
|
|
if (m_pMk)
|
|
{
|
|
ReleaseAll();
|
|
|
|
if (SUCCEEDED(m_hDownloadResult))
|
|
{
|
|
PostMessage(m_hDialog, WM_DOWNLOAD_DONE, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
PostMessage(m_hDialog, WM_DOWNLOAD_ERROR, (WPARAM)m_hDownloadResult, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Release(); //balanced by Release in UpdateDownloadResult
|
|
goto exit;
|
|
}
|
|
|
|
HRESULT CWebJit::VerifyMimeAndExtension()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::VerifyMimeAndExtension",
|
|
"this=%#x, cache file=%.200wq, mime type=%.80wq",
|
|
this, m_pwszCacheFile, m_pwszMimeType
|
|
));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_pwszMimeType)
|
|
{
|
|
if (!StrCmpIW(m_pwszMimeType, L"text/html"))
|
|
{
|
|
m_fHtml = TRUE;
|
|
}
|
|
else if (StrCmpIW(m_pwszMimeType, L"application/x-msdownload")
|
|
&& StrCmpIW(m_pwszMimeType, L"application/octet-stream"))
|
|
{
|
|
hr = NO_MIME_MATCH;
|
|
}
|
|
}
|
|
|
|
//disable .exe check for now
|
|
/*
|
|
int dwStrlen = lstrlenW(m_pwszCacheFile);
|
|
|
|
if ((dwStrlen < 4)
|
|
|| (StrCmpIW(m_pwszCacheFile+dwStrlen-4, L".exe")))
|
|
{
|
|
hr = NO_EXT_MATCH;
|
|
}
|
|
exit:
|
|
*/
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
BOOL CWebJit::NeedHostSecMgr()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Bool,
|
|
"CWebJit::NeedHostSecMgr",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
BOOL fNeed = FALSE;
|
|
BOOL fWhistler = FALSE;
|
|
|
|
OSVERSIONINFO VerInfo;
|
|
VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
|
if (GetVersionEx(&VerInfo))
|
|
{
|
|
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
if ((VerInfo.dwMajorVersion >= 5)
|
|
&& (VerInfo.dwMinorVersion >= 1))
|
|
{
|
|
fWhistler = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fWhistler
|
|
&& !StrCmpIW(m_pwszComponentId, L"JAVAVMJIT"))
|
|
{
|
|
//if installed VM older than 5.00.2752.0
|
|
const static char * szRequiredVersion = "5,00,2752,0";
|
|
DWORD dwHi;
|
|
DWORD dwLo;
|
|
if (m_pQueryInstalled
|
|
&& (m_pQueryInstalled->dwVersionHi || m_pQueryInstalled->dwVersionLo)
|
|
&& (SUCCEEDED(GetVersionFromString(szRequiredVersion, &dwHi, &dwLo)))
|
|
&& ((m_pQueryInstalled->dwVersionHi < dwHi)
|
|
|| ((m_pQueryInstalled->dwVersionHi == dwHi)
|
|
&& (m_pQueryInstalled->dwVersionLo < dwLo))))
|
|
{
|
|
fNeed = TRUE;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(fNeed);
|
|
return fNeed;
|
|
}
|
|
|
|
VOID CWebJit::ProcessFile()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::ProcessFile",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
|
|
HRESULT hr = VerifyMimeAndExtension();
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
if (!m_fHtml)
|
|
{
|
|
hr = VerifyTrust(FALSE);
|
|
|
|
if (FAILED(hr) && NeedHostSecMgr())
|
|
{
|
|
HRESULT hrTemp = VerifyTrust(TRUE);
|
|
|
|
// use the hrTemp from the second call only if the call actually succeeds.
|
|
if (hrTemp == S_OK)
|
|
{
|
|
hr = hrTemp;
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ((hr = ExecFile()) == S_OK)
|
|
{
|
|
//enable this code if we need to exit the dialog while navigating browser to error html page
|
|
//because the error page has been execed into the same process.
|
|
if (m_fHtml && (NULL == GetProcessHandle()))
|
|
{
|
|
SendMessage(m_hDialog, WM_DONT_WAIT, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
SendMessage(m_hDialog, WM_START_TIMER, (WPARAM)1, 0);
|
|
}
|
|
|
|
goto success;
|
|
}
|
|
}
|
|
}
|
|
|
|
SendMessage(m_hDialog, WM_PROCESS_ERROR, hr, 0);
|
|
|
|
success:
|
|
DEBUG_LEAVE(hr);
|
|
return;
|
|
}
|
|
|
|
HRESULT CWebJit::CanWebJit()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::CanWebJit",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
#define REGSTR_PATH_NT5_LOCKDOWN_TEST "Software\\Microsoft\\Code Store Database\\NT5LockDownTest"
|
|
|
|
if (g_bNT5OrGreater)
|
|
{
|
|
HKEY hkeyLockedDown = 0;
|
|
|
|
// Test for lock-down. If we cannot write to HKLM, then we are in
|
|
// a locked-down environment, and should abort right away.
|
|
|
|
if (RegCreateKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_NT5_LOCKDOWN_TEST,
|
|
&hkeyLockedDown) != ERROR_SUCCESS)
|
|
{
|
|
// We are in lock-down mode; abort.
|
|
g_bLockedDown = TRUE;
|
|
hr = E_ACCESSDENIED;
|
|
}
|
|
else
|
|
{
|
|
// Not locked-down. Delete the key, and continue
|
|
RegCloseKey(hkeyLockedDown);
|
|
RegDeleteKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_NT5_LOCKDOWN_TEST);
|
|
g_bLockedDown = FALSE;
|
|
}
|
|
}
|
|
|
|
//JAVA VM specific checks.. If we have too many component specific checks eventually,
|
|
// make function pointers and key off those.
|
|
if (SUCCEEDED(hr) && g_bNT5OrGreater
|
|
&& !StrCmpIW(m_pwszComponentId, L"JAVAVMJIT"))
|
|
{
|
|
if (!IsWin32X86())
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INSTALL_PLATFORM_UNSUPPORTED);
|
|
}
|
|
else if(!IsNTAdmin())
|
|
{
|
|
hr = E_ACCESSDENIED;
|
|
}
|
|
}
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebJit::SetupDownload()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::SetupDownload",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
|
|
int cchWideChar;
|
|
HRESULT hr;
|
|
|
|
if (FAILED(hr = CanWebJit()))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
m_pTempBuffer = new CHAR[TEMPREADBUFFERSIZE];
|
|
if (!m_pTempBuffer)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
cchWideChar = MultiByteToWideChar(CP_ACP, 0, m_szResource, -1, NULL, 0);
|
|
if (!cchWideChar)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto exit;
|
|
}
|
|
|
|
m_pwszUrl = new WCHAR[cchWideChar+1];
|
|
if (!m_pwszUrl)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
cchWideChar = MultiByteToWideChar(CP_ACP, 0, m_szResource, -1, m_pwszUrl, cchWideChar);
|
|
if (!cchWideChar)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto exit;
|
|
}
|
|
|
|
hr = CreateAsyncBindCtx(NULL, (IBindStatusCallback *)this, NULL, &m_pbc );
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
hr = CreateURLMoniker(NULL, m_pwszUrl, &m_pMk);
|
|
if (FAILED(hr))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebJit::StartDownload()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::StartDownload",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
|
|
//AddRef(); //balanced by Release in UpdateDownloadResult
|
|
m_State = WJSTATE_BINDING;
|
|
UpdateStatusString();
|
|
|
|
BOOL bRetVal = FALSE;
|
|
HRESULT hr;
|
|
|
|
hr = m_pMk->BindToStorage(m_pbc, 0, IID_IStream, (void**)&m_pStm);
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebJit::ExecFile()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::ExecFile",
|
|
"this=%#x",
|
|
this
|
|
));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_fAborted)
|
|
{
|
|
hr = E_ABORT;
|
|
goto exit;
|
|
}
|
|
else
|
|
{
|
|
m_State = WJSTATE_READY_TO_EXEC;
|
|
}
|
|
|
|
SHELLEXECUTEINFOW shExecInfo;
|
|
|
|
memset(&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
|
|
|
|
shExecInfo.cbSize = sizeof(shExecInfo);
|
|
shExecInfo.fMask = SEE_MASK_FLAG_DDEWAIT /*don't need in urlmon*/
|
|
| SEE_MASK_FLAG_NO_UI
|
|
| SEE_MASK_NOCLOSEPROCESS
|
|
| SEE_MASK_NO_CONSOLE
|
|
| SEE_MASK_UNICODE /* ?? */;
|
|
shExecInfo.lpVerb = L"open";
|
|
//ASSERT (m_pwszCacheFile && (*m_pwszCacheFile != L'\0'))
|
|
if (m_fHtml)
|
|
{
|
|
if (!m_pwszRedirectUrl)
|
|
{ hr = EXEC_ERROR;
|
|
goto exit;
|
|
}
|
|
shExecInfo.lpFile = m_pwszRedirectUrl;
|
|
}
|
|
else
|
|
shExecInfo.lpFile = m_pwszCacheFile;
|
|
shExecInfo.nShow = SW_SHOWNORMAL;
|
|
|
|
if (!ShellExecuteExWrapW(&shExecInfo))
|
|
{
|
|
hr = EXEC_ERROR;
|
|
goto exit;
|
|
}
|
|
|
|
m_hProcess = shExecInfo.hProcess;
|
|
|
|
exit:
|
|
if (m_hCacheFile && !InternetUnlockRequestFile(m_hCacheFile))
|
|
{
|
|
//nothing.
|
|
}
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
#define MAX_ERROR_SIZE 2000
|
|
#define START_ERROR_STRING(ERROR_IDS) \
|
|
nRet = MLLoadStringW(ERROR_IDS, wszError, MAX_ERROR_SIZE);
|
|
#define APPEND_ERROR_STRING(ERROR_IDS) \
|
|
StrCatW(wszError, L" "); \
|
|
nRet += MLLoadStringW(ERROR_IDS, wszError+nRet+1, MAX_ERROR_SIZE-nRet-1)+1;
|
|
|
|
HRESULT CWebJit::DisplayError(HRESULT hr, UINT nMsgError)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::DisplayError",
|
|
"this=%#x, %#x, %#x",
|
|
this, hr, nMsgError
|
|
));
|
|
|
|
int nRet = 0;
|
|
BOOL fIsOffline;
|
|
WCHAR wszError[MAX_ERROR_SIZE];
|
|
WCHAR wszTitle[200];
|
|
ULONG_PTR uCookie = 0;
|
|
|
|
if (m_fAborted)
|
|
goto exit;
|
|
|
|
if (m_hrInternal)
|
|
{
|
|
hr = m_hrInternal;
|
|
nMsgError = WM_INTERNAL_ERROR;
|
|
}
|
|
|
|
START_ERROR_STRING(IDS_ERROROCCURED);
|
|
if (nRet)
|
|
{
|
|
*(wszError+nRet) = L'\0';
|
|
SetDlgItemTextWrapW(m_hDialog, IDC_TEXT, wszError);
|
|
}
|
|
ShowWindow(GetDlgItem(m_hDialog, IDCANCEL), SW_HIDE);
|
|
|
|
if (!IsConnected(&fIsOffline))
|
|
{
|
|
fIsOffline = TRUE;
|
|
}
|
|
|
|
nRet = 0;
|
|
switch(nMsgError)
|
|
{
|
|
case WM_INTERNAL_ERROR:
|
|
{
|
|
START_ERROR_STRING(IDS_INTERNAL);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
break;
|
|
case WM_SETUP_ERROR:
|
|
{
|
|
if (hr == E_ACCESSDENIED)
|
|
{
|
|
START_ERROR_STRING(IDS_INSTALLFAIL);
|
|
APPEND_ERROR_STRING(IDS_ADMINRIGHTS);
|
|
}
|
|
else if (hr == HRESULT_FROM_WIN32(ERROR_INSTALL_PLATFORM_UNSUPPORTED))
|
|
{
|
|
START_ERROR_STRING(IDS_PLATFORMNOT);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
else
|
|
{
|
|
START_ERROR_STRING(IDS_SETUP);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
}
|
|
break;
|
|
case WM_DOWNLOAD_ERROR:
|
|
{
|
|
switch(hr)
|
|
{
|
|
case E_ABORT:
|
|
{
|
|
hr = CANCELLED;
|
|
}
|
|
break;
|
|
case INET_E_OBJECT_NOT_FOUND:
|
|
{
|
|
if (fIsOffline)
|
|
{
|
|
START_ERROR_STRING(IDS_OFFLINEALERT);
|
|
APPEND_ERROR_STRING(IDS_OFFLINEALERT2);
|
|
}
|
|
else
|
|
{
|
|
START_ERROR_STRING(IDS_DLFAIL);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
}
|
|
break;
|
|
case INET_E_RESOURCE_NOT_FOUND:
|
|
{
|
|
START_ERROR_STRING(IDS_SERVERERROR);
|
|
APPEND_ERROR_STRING(IDS_IBUSY);
|
|
APPEND_ERROR_STRING(IDS_NOTCONNECTED);
|
|
}
|
|
break;
|
|
case INET_E_DOWNLOAD_FAILURE:
|
|
{
|
|
if (fIsOffline)
|
|
{
|
|
START_ERROR_STRING(IDS_OFFLINEALERT);
|
|
APPEND_ERROR_STRING(IDS_OFFLINEALERT2);
|
|
}
|
|
else
|
|
{
|
|
START_ERROR_STRING(IDS_DLFAIL);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (!nRet
|
|
&& (hr >= INET_E_ERROR_FIRST)
|
|
&& (hr <= INET_E_ERROR_LAST))
|
|
{
|
|
START_ERROR_STRING(IDS_DLFAIL);
|
|
APPEND_ERROR_STRING(IDS_IBUSY);
|
|
APPEND_ERROR_STRING(IDS_NOTCONNECTED);
|
|
}
|
|
}
|
|
break;
|
|
case WM_PROCESS_ERROR:
|
|
{
|
|
switch(hr)
|
|
{
|
|
case TRUST_E_SUBJECT_NOT_TRUSTED:
|
|
{
|
|
START_ERROR_STRING(IDS_CERTREFUSE);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
break;
|
|
case TRUST_E_FAIL:
|
|
{
|
|
START_ERROR_STRING(IDS_SECURITYHIGH);
|
|
APPEND_ERROR_STRING(IDS_SECURITYHIGH1);
|
|
APPEND_ERROR_STRING(IDS_SECURITYHIGH2);
|
|
APPEND_ERROR_STRING(IDS_SECURITYHIGH3);
|
|
}
|
|
break;
|
|
case E_ACCESSDENIED:
|
|
{
|
|
START_ERROR_STRING(IDS_INSTALLFAIL);
|
|
APPEND_ERROR_STRING(IDS_ADMINRIGHTS);
|
|
}
|
|
break;
|
|
}
|
|
if (!nRet)
|
|
{
|
|
START_ERROR_STRING(IDS_PROCESS);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
hr = HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!nRet)
|
|
{
|
|
START_ERROR_STRING(IDS_UNKNOWNERROR);
|
|
APPEND_ERROR_STRING(IDS_PRODUCTUPDATES);
|
|
}
|
|
|
|
*(wszError+nRet) = L'\0';
|
|
|
|
nRet = MLLoadStringW(IDS_ERRORTITLE, wszTitle, ARRAY_ELEMENTS(wszTitle));
|
|
|
|
SHActivateContext(&uCookie);
|
|
|
|
MessageBoxW(m_hDialog, wszError, nRet ? wszTitle : NULL, MB_OK);
|
|
|
|
if (uCookie)
|
|
{
|
|
SHDeactivateContext(uCookie);
|
|
}
|
|
|
|
exit:
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebJit::VerifyTrust(BOOL fUseHostSecMgr)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Hresult,
|
|
"CWebJit::VerifyTrust",
|
|
"this=%#x, %B",
|
|
this, fUseHostSecMgr
|
|
));
|
|
|
|
HRESULT hr = E_FAIL;
|
|
LPWSTR pwszUnescapedUrl = NULL;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
|
|
#define COR_POLICY_PROVIDER_DOWNLOAD \
|
|
{ 0xd41e4f1d, 0xa407, 0x11d1, {0x8b, 0xc9, 0x0, 0xc0, 0x4f, 0xa3, 0xa, 0x41 } }
|
|
|
|
GUID guidCor = COR_POLICY_PROVIDER_DOWNLOAD;
|
|
|
|
if (m_fAborted)
|
|
{
|
|
hr = E_ABORT;
|
|
goto exit;
|
|
}
|
|
else
|
|
{
|
|
m_State = WJSTATE_VERIFYING;
|
|
}
|
|
|
|
UpdateStatusString();
|
|
|
|
hFile = CreateFileWrapW(m_pwszCacheFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
if (!hFile)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
goto exit;
|
|
}
|
|
|
|
DWORD dwWideChar = lstrlenW(m_pwszUrl)+1;
|
|
pwszUnescapedUrl = new WCHAR[dwWideChar];
|
|
if (pwszUnescapedUrl)
|
|
{
|
|
hr = UrlUnescapeW(m_pwszUrl, pwszUnescapedUrl, &dwWideChar, 0);
|
|
}
|
|
|
|
LPCWSTR pwszDisplayUrl = (hr == S_OK) ? pwszUnescapedUrl : m_pwszUrl;
|
|
|
|
if(!SUCCEEDED(hr = EnsureSecurityManager()))
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
WINTRUST_DATA WintrustData;
|
|
ZeroMemory(&WintrustData, sizeof(WINTRUST_DATA));
|
|
WintrustData.cbStruct = sizeof(WINTRUST_DATA);
|
|
if ((m_hDialog == INVALID_HANDLE_VALUE) || IsUIRestricted()) //urlmon only
|
|
WintrustData.dwUIChoice = WTD_UI_NONE;
|
|
else
|
|
WintrustData.dwUIChoice = WTD_UI_ALL;
|
|
WintrustData.dwUnionChoice = WTD_CHOICE_FILE;
|
|
|
|
JAVA_POLICY_PROVIDER javaPolicyData;
|
|
ZeroMemory(&javaPolicyData, sizeof(JAVA_POLICY_PROVIDER));
|
|
javaPolicyData.cbSize = sizeof(JAVA_POLICY_PROVIDER);
|
|
javaPolicyData.VMBased = FALSE;
|
|
javaPolicyData.fNoBadUI = FALSE;
|
|
|
|
javaPolicyData.pwszZone = pwszDisplayUrl;
|
|
javaPolicyData.pZoneManager = fUseHostSecMgr ? ((LPVOID)(IInternetHostSecurityManager *)this) : NULL;
|
|
WintrustData.pPolicyCallbackData = &javaPolicyData;
|
|
|
|
WINTRUST_FILE_INFO WintrustFileInfo;
|
|
ZeroMemory(&WintrustFileInfo, sizeof(WINTRUST_FILE_INFO));
|
|
WintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
|
|
WintrustFileInfo.pcwszFilePath = pwszDisplayUrl;
|
|
WintrustFileInfo.hFile = hFile;
|
|
WintrustData.pFile = &WintrustFileInfo;
|
|
|
|
hr = WinVerifyTrust(m_hDialog, &guidCor, &WintrustData);
|
|
if (hr == TRUST_E_PROVIDER_UNKNOWN)
|
|
{
|
|
GUID guidJava = JAVA_POLICY_PROVIDER_DOWNLOAD;
|
|
hr = WinVerifyTrust(m_hDialog, &guidJava, &WintrustData);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
DWORD dwZone;
|
|
if ((javaPolicyData.pbJavaTrust == NULL)
|
|
|| (!javaPolicyData.pbJavaTrust->fAllActiveXPermissions)
|
|
|| (g_pSecurityManager
|
|
&& (SUCCEEDED(g_pSecurityManager->MapUrlToZone(m_pwszUrl, &dwZone, 0)))
|
|
&& (dwZone == URLZONE_LOCAL_MACHINE)
|
|
&& (FAILED(javaPolicyData.pbJavaTrust->hVerify))))
|
|
{
|
|
hr = TRUST_E_FAIL;
|
|
}
|
|
}
|
|
else if (SUCCEEDED(hr))
|
|
{
|
|
// BUGBUG: this works around a wvt bug that returns 0x57 (success) when
|
|
// you hit No to an usigned control
|
|
hr = TRUST_E_FAIL;
|
|
}
|
|
else if (hr == TRUST_E_SUBJECT_NOT_TRUSTED && WintrustData.dwUIChoice == WTD_UI_NONE)
|
|
{
|
|
// if we didn't ask for the UI to be out up there has been no UI
|
|
// work around WVT bvug that it returns us this special error code
|
|
// without putting up UI.
|
|
hr = TRUST_E_FAIL; // this will put up mshtml ui after the fact
|
|
// that security settings prevented us
|
|
}
|
|
|
|
if (javaPolicyData.pbJavaTrust)
|
|
CoTaskMemFree(javaPolicyData.pbJavaTrust);
|
|
|
|
exit:
|
|
if (pwszUnescapedUrl)
|
|
delete [] pwszUnescapedUrl;
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
CloseHandle(hFile);
|
|
|
|
DEBUG_LEAVE(hr);
|
|
return hr;
|
|
}
|
|
|
|
VOID CWebJit::ProcessAbort()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
None,
|
|
"CWebJit::ProcessAbort",
|
|
"this=%#x, currentState=%d",
|
|
this, m_State
|
|
));
|
|
|
|
ShowWindow(m_hDialog, SW_HIDE);
|
|
|
|
m_fAborted = TRUE;
|
|
switch (m_State)
|
|
{
|
|
case WJSTATE_INIT:
|
|
Terminate(CANCELLED);
|
|
break;
|
|
case WJSTATE_BINDING:
|
|
if (m_pBinding && !m_fCalledAbort)
|
|
{
|
|
m_fCalledAbort = TRUE;
|
|
m_pBinding->Abort();
|
|
}
|
|
break;
|
|
case WJSTATE_DOWNLOADED:
|
|
case WJSTATE_FINISHED_READ:
|
|
case WJSTATE_VERIFYING:
|
|
case WJSTATE_READY_TO_EXEC:
|
|
case WJSTATE_WAITING_PROCESS:
|
|
case WJSTATE_DONE:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
DEBUG_LEAVE(0);
|
|
}
|
|
|
|
VOID CWebJit::Terminate(DWORD dwRetVal)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
None,
|
|
"CWebJit::Terminate",
|
|
"this=%#x, dwRetVal=%#x, currentState=%d",
|
|
this, dwRetVal, m_State
|
|
));
|
|
|
|
m_dwRetVal = dwRetVal;
|
|
//Release();
|
|
if (m_fAborted)
|
|
m_dwRetVal = CANCELLED;
|
|
else if (m_hrInternal)
|
|
m_dwRetVal = m_hrInternal;
|
|
EndDialog(m_hDialog, (INT_PTR)m_dwRetVal);
|
|
|
|
DEBUG_LEAVE(0);
|
|
return;
|
|
}
|
|
|
|
HRESULT CWebJit::Init(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_fInited)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
#define WINTRUST TEXT("wintrust.dll")
|
|
|
|
m_hWintrustMod = LoadLibrary( WINTRUST );
|
|
|
|
if (NULL == m_hWintrustMod)
|
|
{
|
|
hr = ERROR_MOD_NOT_FOUND;
|
|
goto exit;
|
|
}
|
|
|
|
#define CHECKAPI(_fn) \
|
|
*(FARPROC*)&(_pfn##_fn) = GetProcAddress(m_hWintrustMod, #_fn); \
|
|
if (!(_pfn##_fn)) \
|
|
{ \
|
|
FreeLibrary(m_hWintrustMod); \
|
|
\
|
|
hr = ERROR_MOD_NOT_FOUND;\
|
|
goto exit;\
|
|
}
|
|
|
|
CHECKAPI(WinVerifyTrust);
|
|
|
|
m_fInited = TRUE;
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWebJit::InitCC(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_fInitedCC)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
#define COMCTL TEXT("comctl32.dll")
|
|
|
|
m_hComCtlMod = LoadLibrary( COMCTL );
|
|
|
|
if (NULL == m_hComCtlMod)
|
|
{
|
|
hr = ERROR_MOD_NOT_FOUND;
|
|
goto exit;
|
|
}
|
|
|
|
#define CHECKCCAPI(_fn) \
|
|
*(FARPROC*)&(_pfn##_fn) = GetProcAddress(m_hComCtlMod, #_fn); \
|
|
if (!(_pfn##_fn)) \
|
|
{ \
|
|
FreeLibrary(m_hComCtlMod); \
|
|
\
|
|
hr = ERROR_MOD_NOT_FOUND;\
|
|
goto exit;\
|
|
}
|
|
|
|
CHECKCCAPI(InitCommonControlsEx);
|
|
|
|
m_fInitedCC = TRUE;
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
BOOL CWebJit::InitCommonControlsForWebJit()
|
|
{
|
|
INITCOMMONCONTROLSEX sInitComm;
|
|
sInitComm.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
sInitComm.dwICC = ICC_PROGRESS_CLASS;
|
|
|
|
return InitCommonControlsEx(&sInitComm);
|
|
}
|
|
|
|
UINT MapComponentToResourceId(LPCWSTR pwszComponentId)
|
|
{
|
|
typedef struct
|
|
{
|
|
LPCWSTR pwszComponentId;
|
|
UINT nResource;
|
|
}
|
|
ComponentToResourceType;
|
|
|
|
ComponentToResourceType MapComponentToResource[] =
|
|
{
|
|
{ L"JAVAVMJIT", IDS_JAVAVMJIT },
|
|
{ L"WMPLAYER", IDS_MEDIAPLAYER }
|
|
};
|
|
UINT nRet = (UINT)-1;
|
|
|
|
for (DWORD i = 0; i < ARRAY_ELEMENTS(MapComponentToResource); i++ )
|
|
{
|
|
if (!StrCmpIW(pwszComponentId, MapComponentToResource[i].pwszComponentId))
|
|
{
|
|
nRet = MapComponentToResource[i].nResource;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
UINT MapComponentToHelpId(LPCWSTR pwszComponentId)
|
|
{
|
|
typedef struct
|
|
{
|
|
LPCWSTR pwszComponentId;
|
|
UINT nResource;
|
|
}
|
|
ComponentToHelpId;
|
|
|
|
ComponentToHelpId MapComponentToHelpIds[] =
|
|
{
|
|
{ L"JAVAVMJIT", 50464 },
|
|
{ L"WMPLAYER", 50475 }
|
|
};
|
|
UINT nRet = 0;
|
|
|
|
for (DWORD i = 0; i < ARRAY_ELEMENTS(MapComponentToHelpIds); i++ )
|
|
{
|
|
if (!StrCmpIW(pwszComponentId, MapComponentToHelpIds[i].pwszComponentId))
|
|
{
|
|
nRet = MapComponentToHelpIds[i].nResource;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
BOOL CenterWindow(HWND hwndChild, HWND hwndParent)
|
|
{
|
|
RECT rChild, rParent;
|
|
int wChild, hChild, wParent, hParent;
|
|
int wScreen, hScreen, xNew, yNew;
|
|
HDC hdc;
|
|
|
|
// Get the Height and Width of the child window
|
|
GetWindowRect (hwndChild, &rChild);
|
|
wChild = rChild.right - rChild.left;
|
|
hChild = rChild.bottom - rChild.top;
|
|
|
|
// Get the Height and Width of the parent window
|
|
GetWindowRect (hwndParent, &rParent);
|
|
wParent = rParent.right - rParent.left;
|
|
hParent = rParent.bottom - rParent.top;
|
|
|
|
// Get the display limits
|
|
hdc = GetDC (hwndChild);
|
|
wScreen = GetDeviceCaps (hdc, HORZRES);
|
|
hScreen = GetDeviceCaps (hdc, VERTRES);
|
|
ReleaseDC (hwndChild, hdc);
|
|
|
|
// Calculate new X position, then adjust for screen
|
|
xNew = rParent.left + ((wParent - wChild) /2);
|
|
if (xNew < 0)
|
|
{
|
|
xNew = 0;
|
|
}
|
|
else if ((xNew+wChild) > wScreen)
|
|
{
|
|
xNew = wScreen - wChild;
|
|
}
|
|
|
|
// Calculate new Y position, then adjust for screen
|
|
yNew = rParent.top + ((hParent - hChild) /2);
|
|
if (yNew < 0)
|
|
{
|
|
yNew = 0;
|
|
}
|
|
else if ((yNew+hChild) > hScreen)
|
|
{
|
|
yNew = hScreen - hChild;
|
|
}
|
|
|
|
// Set it, and return
|
|
return SetWindowPos (hwndChild, NULL,
|
|
xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
|
}
|
|
|
|
VOID CWebJit::UpdateStatusString()
|
|
{
|
|
CHAR szFormat[400];
|
|
CHAR szMessage[800];
|
|
CHAR szComponent[400];
|
|
int nRet;
|
|
UINT id;
|
|
|
|
nRet = MLLoadStringA(MapComponentToResourceId(m_pwszComponentId), szComponent, ARRAY_ELEMENTS(szComponent));
|
|
if (!nRet)
|
|
goto exit;
|
|
|
|
switch(m_State)
|
|
{
|
|
case WJSTATE_BINDING:
|
|
id = IDS_DOWNLOADING;
|
|
break;
|
|
case WJSTATE_VERIFYING:
|
|
id = IDS_CHECKTRUST;
|
|
break;
|
|
case WJSTATE_WAITING_PROCESS:
|
|
id = IDS_INSTALLING;
|
|
break;
|
|
}
|
|
|
|
nRet = MLLoadStringA(id, szFormat, ARRAY_ELEMENTS(szFormat));
|
|
if (!nRet)
|
|
goto exit;
|
|
|
|
if (wsprintfA(szMessage, szFormat, szComponent))
|
|
{
|
|
SetDlgItemTextA(m_hDialog, IDC_TEXT, szMessage);
|
|
}
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
|
|
BOOL CWebJit::SetupWindow()
|
|
{
|
|
WCHAR szMsg[1000];
|
|
BOOL bRet = FALSE;
|
|
|
|
int nRet = MLLoadStringW(IDS_DOWNLOAD_MSG, szMsg, ARRAY_ELEMENTS(szMsg));
|
|
if (nRet)
|
|
{
|
|
StrCatW(szMsg, L"\n\n");
|
|
int nRet2;
|
|
nRet2 = MLLoadStringW(MapComponentToResourceId(m_pwszComponentId), szMsg+nRet+2, ARRAY_ELEMENTS(szMsg)-nRet-2);
|
|
|
|
if (nRet2)
|
|
{
|
|
*(szMsg+nRet+nRet2+2) = L'\0';
|
|
|
|
bRet = TRUE;
|
|
|
|
if (!SetDlgItemTextWrapW(m_hDialog, IDC_TEXT, szMsg))
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(m_dwFlags & FIEF_FLAG_FORCE_JITUI))
|
|
{
|
|
EnableWindow(GetDlgItem(m_hDialog, IDC_CHECK1), TRUE);
|
|
}
|
|
|
|
CenterWindow(m_hDialog, m_hWndParent);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
DWORD mapIDCsToIDHs[] =
|
|
{
|
|
IDC_TEXT, 0, //This value is changed depending on component being WebJited
|
|
IDDOWNLOAD, 50621,
|
|
IDCANCEL, 50462,
|
|
IDOK, 50510,
|
|
IDC_CHECK1, 50620,
|
|
IDC_REMAINING_SIZE, 50457,
|
|
IDC_REMAINING_TIME, 50458,
|
|
0,0
|
|
};
|
|
|
|
DWORD* GetMapArray(CWebJit* pWebJit)
|
|
{
|
|
DWORD* pdwMapArray = new DWORD[ARRAY_ELEMENTS(mapIDCsToIDHs)];
|
|
if (pdwMapArray)
|
|
{
|
|
memcpy(pdwMapArray, mapIDCsToIDHs, sizeof(mapIDCsToIDHs));
|
|
pdwMapArray[1] = MapComponentToHelpId(pWebJit->GetComponentIdName());
|
|
}
|
|
return pdwMapArray;
|
|
}
|
|
|
|
INT_PTR CALLBACK WebJitProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CWebJit* pWebJit = (CWebJit *)GetWindowLongPtr(hDlg, DWLP_USER);
|
|
DWORD* pdwMapArray;
|
|
HRESULT hr;
|
|
//ASSERT (pWebJit || (message == WM_INITDIALOG));
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pWebJit = ((WEBJIT_PARAM*)lParam)->pWebJit;
|
|
if (pWebJit)
|
|
{
|
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pWebJit);
|
|
pWebJit->SetWindowHandle(hDlg);
|
|
pWebJit->SetupWindow();
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_CHECK1:
|
|
{
|
|
if (SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETCHECK, 0, 0) == BST_CHECKED)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDDOWNLOAD), FALSE);
|
|
ShowWindow(GetDlgItem(hDlg, IDDOWNLOAD), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOWNORMAL);
|
|
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
|
|
ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDDOWNLOAD), SW_SHOWNORMAL);
|
|
EnableWindow(GetDlgItem(hDlg, IDDOWNLOAD), TRUE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
case IDOK:
|
|
{
|
|
if (SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETSTATE, 0, 0) == BST_CHECKED)
|
|
{
|
|
//Never download any of these components.
|
|
pWebJit->Terminate(NEVERASK);
|
|
}
|
|
return TRUE;
|
|
}
|
|
case IDDOWNLOAD:
|
|
{
|
|
if (SendDlgItemMessage(hDlg, IDC_CHECK1, BM_GETSTATE, 0, 0) == BST_CHECKED)
|
|
{
|
|
//Never download any of these components.
|
|
pWebJit->Terminate(NEVERASK);
|
|
return TRUE;
|
|
}
|
|
|
|
if (!pWebJit->IsDownloadInited())
|
|
{
|
|
pWebJit->SetDownloadInited();
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDDOWNLOAD), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_CHECK1), FALSE);
|
|
SetFocus(GetDlgItem(hDlg, IDCANCEL));
|
|
|
|
HRESULT hr;
|
|
hr = pWebJit->SetupDownload();
|
|
if (FAILED(hr))
|
|
{
|
|
//synchronous failure.
|
|
SendMessage(hDlg, WM_SETUP_ERROR, (WPARAM)hr, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
hr = pWebJit->StartDownload();
|
|
|
|
pWebJit->UpdateDownloadResult(hr, FALSE);
|
|
return TRUE;
|
|
}
|
|
case IDCANCEL:
|
|
pWebJit->ProcessAbort();
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_DATA_AVAILABLE:
|
|
if (!pWebJit->IsReadTimerStarted())
|
|
{
|
|
pWebJit->SetReadTimerStarted();
|
|
SetTimer(hDlg, TIMER_DOWNLOAD, TIMER_DOWNLOAD_INTERVAL, NULL);
|
|
}
|
|
|
|
pWebJit->ReadData();
|
|
return TRUE;
|
|
|
|
case WM_DOWNLOAD_DONE:
|
|
KillTimer(hDlg, TIMER_DOWNLOAD);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_PROGRESS1), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_REMAINING_TIME), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_REMAINING_SIZE), SW_HIDE);
|
|
pWebJit->ProcessFile();
|
|
return TRUE;
|
|
|
|
case WM_START_TIMER:
|
|
if (wParam == 1)
|
|
{
|
|
pWebJit->SetState(WJSTATE_WAITING_PROCESS);
|
|
pWebJit->UpdateStatusString();
|
|
SetTimer(hDlg, TIMER_EXEC_POLL, TIMER_EXEC_POLL_INTERVAL, NULL);
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_SETUP_ERROR:
|
|
case WM_DOWNLOAD_ERROR:
|
|
case WM_PROCESS_ERROR:
|
|
KillTimer(hDlg, TIMER_DOWNLOAD);
|
|
hr = pWebJit->DisplayError((HRESULT)wParam, message);
|
|
pWebJit->Terminate(hr);
|
|
return TRUE;
|
|
|
|
case WM_DONT_WAIT:
|
|
pWebJit->SetState(WJSTATE_DONE);
|
|
pWebJit->Terminate(SUCCESS);
|
|
return TRUE;
|
|
|
|
case WM_TIMER:
|
|
if (wParam == TIMER_EXEC_POLL)
|
|
{
|
|
if (pWebJit->GetProcessHandle()
|
|
&& (WAIT_OBJECT_0 == WaitForSingleObject(pWebJit->GetProcessHandle(), 0)))
|
|
{
|
|
KillTimer(hDlg, TIMER_EXEC_POLL);
|
|
pWebJit->SetState(WJSTATE_DONE);
|
|
pWebJit->Terminate(SUCCESS);
|
|
}
|
|
else if (pWebJit->IsAborted())
|
|
{
|
|
KillTimer(hDlg, TIMER_EXEC_POLL);
|
|
pWebJit->Terminate(CANCELLED);
|
|
}
|
|
}
|
|
else if (wParam == TIMER_DOWNLOAD)
|
|
{
|
|
pWebJit->ReadData();
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_HELP:// F1
|
|
pdwMapArray = pWebJit ? GetMapArray(pWebJit) : NULL;
|
|
if (pdwMapArray)
|
|
{
|
|
ResWinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
|
|
IDS_WEBJITHELPFILE,
|
|
HELP_WM_HELP,
|
|
(ULONG_PTR)(LPSTR)pdwMapArray);
|
|
delete [] pdwMapArray;
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:// right mouse click
|
|
pdwMapArray = pWebJit ? GetMapArray(pWebJit) : NULL;
|
|
if (pdwMapArray)
|
|
{
|
|
ResWinHelp(hDlg,
|
|
IDS_WEBJITHELPFILE,
|
|
HELP_CONTEXTMENU,
|
|
(ULONG_PTR)(LPSTR)pdwMapArray);
|
|
delete [] pdwMapArray;
|
|
}
|
|
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//from setup/iexpress/wextract/wextract.c
|
|
|
|
typedef HRESULT (*CHECKTOKENMEMBERSHIP)(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember);
|
|
|
|
BOOL CheckToken(BOOL *pfIsAdmin)
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Bool,
|
|
"CWebJit::CheckToken",
|
|
NULL
|
|
));
|
|
|
|
BOOL bNewNT5check = FALSE;
|
|
HINSTANCE hAdvapi32 = NULL;
|
|
CHECKTOKENMEMBERSHIP pf;
|
|
PSID AdministratorsGroup;
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
hAdvapi32 = LoadLibrary("advapi32.dll");
|
|
if (hAdvapi32)
|
|
{
|
|
pf = (CHECKTOKENMEMBERSHIP)GetProcAddress(hAdvapi32, "CheckTokenMembership");
|
|
if (pf)
|
|
{
|
|
bNewNT5check = TRUE;
|
|
*pfIsAdmin = FALSE;
|
|
if(AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup) )
|
|
{
|
|
pf(NULL, AdministratorsGroup, pfIsAdmin);
|
|
FreeSid(AdministratorsGroup);
|
|
}
|
|
}
|
|
FreeLibrary(hAdvapi32);
|
|
}
|
|
|
|
DEBUG_LEAVE(bNewNT5check);
|
|
return bNewNT5check;
|
|
}
|
|
|
|
// IsNTAdmin();
|
|
// Returns true if our process has admin priviliges.
|
|
// Returns false otherwise.
|
|
BOOL IsNTAdmin()
|
|
{
|
|
DEBUG_ENTER((DBG_DOWNLOAD,
|
|
Bool,
|
|
"CWebJit::IsNTAdmin",
|
|
NULL
|
|
));
|
|
|
|
static int fIsAdmin = 2;
|
|
HANDLE hAccessToken;
|
|
PTOKEN_GROUPS ptgGroups;
|
|
DWORD dwReqSize;
|
|
UINT i;
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|
PSID AdministratorsGroup;
|
|
BOOL bRet;
|
|
OSVERSIONINFO osvi;
|
|
|
|
//
|
|
// If we have cached a value, return the cached value. Note I never
|
|
// set the cached value to false as I want to retry each time in
|
|
// case a previous failure was just a temp. problem (ie net access down)
|
|
//
|
|
|
|
bRet = FALSE;
|
|
ptgGroups = NULL;
|
|
|
|
if( fIsAdmin != 2 )
|
|
{
|
|
DEBUG_LEAVE(fIsAdmin);
|
|
return (BOOL)fIsAdmin;
|
|
}
|
|
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
|
GetVersionEx(&osvi);
|
|
if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
|
{
|
|
fIsAdmin = TRUE; // If we are not running under NT return TRUE.
|
|
|
|
DEBUG_LEAVE(fIsAdmin);
|
|
return (BOOL)fIsAdmin;
|
|
}
|
|
|
|
if (!CheckToken(&bRet))
|
|
{
|
|
if(!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hAccessToken ) )
|
|
{
|
|
DEBUG_LEAVE(FALSE);
|
|
return FALSE;
|
|
}
|
|
// See how big of a buffer we need for the token information
|
|
if(!GetTokenInformation( hAccessToken, TokenGroups, NULL, 0, &dwReqSize))
|
|
{
|
|
// GetTokenInfo should the buffer size we need - Alloc a buffer
|
|
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
ptgGroups = (PTOKEN_GROUPS) LocalAlloc(LMEM_FIXED, dwReqSize);
|
|
|
|
}
|
|
|
|
// ptgGroups could be NULL for a coupla reasons here:
|
|
// 1. The alloc above failed
|
|
// 2. GetTokenInformation actually managed to succeed the first time (possible?)
|
|
// 3. GetTokenInfo failed for a reason other than insufficient buffer
|
|
// Any of these seem justification for bailing.
|
|
|
|
// So, make sure it isn't null, then get the token info
|
|
if(ptgGroups && GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, dwReqSize, &dwReqSize))
|
|
{
|
|
if(AllocateAndInitializeSid( &NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup) )
|
|
{
|
|
// Search thru all the groups this process belongs to looking for the
|
|
// Admistrators Group.
|
|
|
|
for( i=0; i < ptgGroups->GroupCount; i++ )
|
|
{
|
|
if( EqualSid(ptgGroups->Groups[i].Sid, AdministratorsGroup) )
|
|
{
|
|
// Yea! This guy looks like an admin
|
|
fIsAdmin = TRUE;
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
FreeSid(AdministratorsGroup);
|
|
}
|
|
}
|
|
if(ptgGroups)
|
|
LocalFree(ptgGroups);
|
|
|
|
// BUGBUG: Close handle here? doc's aren't clear whether this is needed.
|
|
CloseHandle(hAccessToken);
|
|
}
|
|
else if (bRet)
|
|
fIsAdmin = TRUE;
|
|
|
|
DEBUG_LEAVE(bRet);
|
|
return bRet;
|
|
}
|
|
|
|
BOOL IsWin32X86()
|
|
{
|
|
OSVERSIONINFO osvi;
|
|
SYSTEM_INFO sysinfo;
|
|
GetSystemInfo(&sysinfo);
|
|
|
|
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
|
GetVersionEx(&osvi);
|
|
if (((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
|| (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
|
|
&& (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|