739 lines
17 KiB
C++
739 lines
17 KiB
C++
|
//=======================================================================
|
||
|
//
|
||
|
// Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
// File: install.cpp
|
||
|
//
|
||
|
// Purpose: Install/uninstall components
|
||
|
//
|
||
|
//=======================================================================
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#include "install.h"
|
||
|
#include <advpub.h>
|
||
|
|
||
|
|
||
|
extern CState g_v3state; //defined in CV3.CPP
|
||
|
|
||
|
|
||
|
// This function installs an active setup catalog item.
|
||
|
void InstallActiveSetupItem(LPCTSTR szLocalDir, LPCTSTR pszCifFile, PSELECTITEMINFO pStatusInfo, IWUProgress* pProgress)
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
MSG msg;
|
||
|
HRESULT hr;
|
||
|
DWORD dwEngineStatus;
|
||
|
IInstallEngine2* pInsEng = NULL;
|
||
|
ICifFile* picif = NULL;
|
||
|
ICifComponent* pcomp = NULL;
|
||
|
IEnumCifComponents* penum = NULL;
|
||
|
CInstallEngineCallback* pCallback = NULL;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
//
|
||
|
// Create active setup engine
|
||
|
//
|
||
|
hr = CoCreateInstance(CLSID_InstallEngine, NULL, CLSCTX_INPROC_SERVER, IID_IInstallEngine2,(void **)&pInsEng);
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
|
||
|
// Tell active setup the direct and directory to use. This is the directory
|
||
|
// where we downloaded the files previously.
|
||
|
hr = pInsEng->SetDownloadDir(T2A(szLocalDir));
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
|
||
|
hr = pInsEng->SetLocalCif(T2A(pszCifFile));
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
|
||
|
//
|
||
|
// Create the callback object and register the install engines callback interface
|
||
|
//
|
||
|
pCallback = new CInstallEngineCallback;
|
||
|
if (!pCallback)
|
||
|
{
|
||
|
throw HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
pCallback->SetProgressPtr(pProgress);
|
||
|
|
||
|
pInsEng->RegisterInstallEngineCallback((IInstallEngineCallback *)pCallback);
|
||
|
|
||
|
pCallback->SetEnginePtr(pInsEng);
|
||
|
|
||
|
//
|
||
|
// Get a pointer to the CIF interface we need in order to enum the
|
||
|
// CIF components and we need to do that on this single item CIF
|
||
|
// becuase we need to tell the install engine what action to perform.
|
||
|
//
|
||
|
hr = pInsEng->GetICifFile(&picif);
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
|
||
|
hr = picif->EnumComponents(&penum, 0, NULL);
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
|
||
|
hr = penum->Next(&pcomp);
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
|
||
|
// Set action to install and then install the component.
|
||
|
pcomp->SetInstallQueueState(SETACTION_INSTALL);
|
||
|
|
||
|
hr = pInsEng->InstallComponents(EXECUTEJOB_IGNORETRUST | EXECUTEJOB_IGNOREDOWNLOADERROR);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
TRACE_HR(hr, "InstallActiveSetupItem: inseng.InstallComponents failed");
|
||
|
throw hr;
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
pInsEng->GetEngineStatus(&dwEngineStatus);
|
||
|
|
||
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||
|
{
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
SleepEx(50, TRUE);
|
||
|
} while (dwEngineStatus != ENGINESTATUS_READY);
|
||
|
|
||
|
if (pcomp->IsComponentInstalled() != ICI_INSTALLED)
|
||
|
{
|
||
|
hr = pCallback->LastError();
|
||
|
|
||
|
//
|
||
|
// if we don't know the exact error from the callback, use E_FAIL
|
||
|
//
|
||
|
if (hr == NOERROR)
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
TRACE_HR(hr, "InstallActiveSetupItem: inseng failed to install");
|
||
|
throw hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// get the return status
|
||
|
//
|
||
|
if (pCallback->GetStatus() & STOPINSTALL_REBOOTNEEDED)
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_SUCCESS_REBOOT_REQUIRED;
|
||
|
else
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_SUCCESS;
|
||
|
pStatusInfo->hrError = NOERROR;
|
||
|
|
||
|
//
|
||
|
// release interfaces
|
||
|
//
|
||
|
if (penum)
|
||
|
penum->Release();
|
||
|
|
||
|
if (picif)
|
||
|
picif->Release();
|
||
|
|
||
|
if (pInsEng)
|
||
|
pInsEng->Release();
|
||
|
|
||
|
if (pCallback)
|
||
|
delete pCallback;
|
||
|
}
|
||
|
catch(HRESULT hr)
|
||
|
{
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_FAILED;
|
||
|
pStatusInfo->hrError = hr;
|
||
|
|
||
|
if (penum)
|
||
|
penum->Release();
|
||
|
|
||
|
if (picif)
|
||
|
picif->Release();
|
||
|
|
||
|
if (pInsEng)
|
||
|
pInsEng->Release();
|
||
|
|
||
|
if (pCallback)
|
||
|
delete pCallback;
|
||
|
|
||
|
throw hr;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//This function handles installation of a Device driver package.
|
||
|
void InstallDriverItem(
|
||
|
LPCTSTR szLocalDir, //Local directory where installation files are.
|
||
|
BOOL bWindowsNT, //TRUE if client machine is NT else FALSE.
|
||
|
LPCTSTR pszTitle, //Description of package, Device Manager displays this in its install dialog.
|
||
|
PINVENTORY_ITEM pItem, //Install Item Information
|
||
|
PSELECTITEMINFO pStatusInfo //Returned status information.
|
||
|
)
|
||
|
{
|
||
|
LOG_block("InstallDriverItem");
|
||
|
|
||
|
try
|
||
|
{
|
||
|
//Note: GetCatalog automatically prunes any drivers if the system is
|
||
|
//not either NT 5 or Windows 98 since we only support installation
|
||
|
//of drivers on these platforms.
|
||
|
|
||
|
//If we do not have a hardware id then we cannot install the device.
|
||
|
PWU_VARIABLE_FIELD pvTmp = pItem->pv->Find(WU_CDM_HARDWARE_ID);
|
||
|
if (!pvTmp)
|
||
|
{
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_FAILED;
|
||
|
pStatusInfo->hrError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BOOL reboot = FALSE;
|
||
|
CdmInstallDriver(bWindowsNT,
|
||
|
(WU_ITEM_STATE_CURRENT == pItem->ps->state) ? edsCurrent : edsNew,
|
||
|
(LPCTSTR)pvTmp->pData, szLocalDir, pszTitle, (PULONG)&reboot);
|
||
|
|
||
|
if (reboot)
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_SUCCESS_REBOOT_REQUIRED;
|
||
|
else
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_SUCCESS;
|
||
|
pStatusInfo->hrError = NOERROR;
|
||
|
}
|
||
|
catch(HRESULT hr)
|
||
|
{
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_FAILED;
|
||
|
pStatusInfo->hrError = hr;
|
||
|
|
||
|
throw hr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT UninstallDriverItem(PINVENTORY_ITEM pItem, PSELECTITEMINFO pStatusInfo)
|
||
|
{
|
||
|
|
||
|
PBYTE pTitle;
|
||
|
PWU_VARIABLE_FIELD pvTitle;
|
||
|
PWU_VARIABLE_FIELD pvTmp;
|
||
|
BOOL bWindowsNT;
|
||
|
TCHAR szLocalDir[MAX_PATH];
|
||
|
BOOL bReboot = FALSE;
|
||
|
|
||
|
|
||
|
bWindowsNT = IsWindowsNT();
|
||
|
|
||
|
if (!(pvTmp = pItem->pv->Find(WU_CDM_HARDWARE_ID)) )
|
||
|
{
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_FAILED;
|
||
|
pStatusInfo->hrError = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
if (pvTitle = pItem->pd->pv->Find(WU_DESCRIPTION_TITLE))
|
||
|
{
|
||
|
pTitle = (PBYTE)pvTitle->pData;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pTitle = (PBYTE)"";
|
||
|
}
|
||
|
|
||
|
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_SUCCESS;
|
||
|
|
||
|
//we will call UpdateCDMDriver with our cache directory but this directory should not
|
||
|
//really be used by UpdateCDMDriver in case of an uninstall since the uninstall case
|
||
|
//reads the correct directory from the registry
|
||
|
GetWindowsUpdateDirectory(szLocalDir);
|
||
|
|
||
|
try
|
||
|
{
|
||
|
CdmInstallDriver(bWindowsNT, edsBackup, (LPCTSTR)pvTmp->pData, szLocalDir, (LPCTSTR)pTitle, (PULONG)&bReboot);
|
||
|
if (bReboot)
|
||
|
{
|
||
|
g_v3state.m_bRebootNeeded = TRUE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
catch(HRESULT hr)
|
||
|
{
|
||
|
pStatusInfo->iStatus = ITEM_STATUS_FAILED;
|
||
|
pStatusInfo->hrError = hr;
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT GetUninstallCmdFromKey(LPCTSTR pszUninstallKey, LPTSTR pszCmdValue)
|
||
|
{
|
||
|
|
||
|
const TCHAR UNINSTALLKEY[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
|
||
|
const TCHAR UNINSTALLVALUE[] = _T("UninstallString");
|
||
|
const TCHAR QUIETUNINSTALLVALUE[] = _T("QuietUninstallString");
|
||
|
|
||
|
HKEY hRegKey = NULL;
|
||
|
DWORD dwRegType;
|
||
|
DWORD dwRegSize;
|
||
|
TCHAR szRegKey[256];
|
||
|
LONG lRet;
|
||
|
TCHAR szValue[256];
|
||
|
|
||
|
if (pszUninstallKey == NULL)
|
||
|
return E_FAIL;
|
||
|
|
||
|
if (pszUninstallKey[0] == _T('"'))
|
||
|
{
|
||
|
//strip quotes from the key
|
||
|
lstrcpy(szValue, (pszUninstallKey + 1));
|
||
|
int l = lstrlen(szValue);
|
||
|
if (l > 0)
|
||
|
szValue[l - 1] = _T('\0');
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lstrcpy(szValue, pszUninstallKey);
|
||
|
}
|
||
|
|
||
|
|
||
|
lstrcpy(szRegKey, UNINSTALLKEY);
|
||
|
lstrcat(szRegKey, szValue);
|
||
|
|
||
|
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_READ, &hRegKey);
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
return HRESULT_FROM_WIN32(lRet);
|
||
|
|
||
|
//check the uninstall value
|
||
|
dwRegSize = sizeof(szValue);
|
||
|
lRet = RegQueryValueEx(hRegKey, UNINSTALLVALUE, NULL, &dwRegType, (LPBYTE)szValue, &dwRegSize);
|
||
|
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
{
|
||
|
// try to find quiteuninstall value
|
||
|
dwRegSize = sizeof(szValue);
|
||
|
lRet = RegQueryValueEx(hRegKey, QUIETUNINSTALLVALUE, NULL, &dwRegType, (LPBYTE)szValue, &dwRegSize);
|
||
|
}
|
||
|
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
{
|
||
|
HRESULT hr = HRESULT_FROM_WIN32(lRet);
|
||
|
RegCloseKey(hRegKey);
|
||
|
return hr;
|
||
|
}
|
||
|
RegCloseKey(hRegKey);
|
||
|
|
||
|
//
|
||
|
// copy the key to the output parameter
|
||
|
//
|
||
|
lstrcpy(pszCmdValue, szValue);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
//Given an uninstall key, looks up in the registry to find the uninsall command and launches it
|
||
|
//If quotes are found around the uninstall key, they are striped. This is done to make it
|
||
|
//compatible with the value specified in the AS CIF file. This function also understands the
|
||
|
//special INF syntax of the uninstall key.
|
||
|
HRESULT UninstallActiveSetupItem(LPCTSTR pszUninstallKey)
|
||
|
{
|
||
|
const TCHAR INFUNINSTALLCOMMAND[] = _T("RunDll32 advpack.dll,LaunchINFSection ");
|
||
|
const TCHAR INFDIRECTORY[] = _T("INF\\");
|
||
|
|
||
|
|
||
|
TCHAR szCmd[256] = {_T('\0')};
|
||
|
TCHAR szActualKey[128] = {_T('\0')};
|
||
|
LONG lRet;
|
||
|
LPCTSTR pszParse;
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (pszUninstallKey == NULL)
|
||
|
return E_FAIL;
|
||
|
|
||
|
if (lstristr(pszUninstallKey, _T(".inf")) != NULL)
|
||
|
{
|
||
|
//
|
||
|
// we have .INF syntax: frontpad,fpxpress.inf,uninstall, start parsing
|
||
|
//
|
||
|
pszParse = lstrcpystr(pszUninstallKey, _T(","), szActualKey); // get actual uninstall key
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lstrcpy(szActualKey, pszUninstallKey);
|
||
|
pszParse = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the uninstall command from the registry
|
||
|
//
|
||
|
hr = GetUninstallCmdFromKey(szActualKey, szCmd);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// we have the uninstall command, try to launch it
|
||
|
lRet = LaunchProcess(szCmd, NULL, SW_NORMAL, TRUE);
|
||
|
|
||
|
TRACE("Uninstall: %s, %d", szCmd, lRet);
|
||
|
|
||
|
if (lRet != 0)
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(lRet);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// we did not get the uninstall command from registry, launch INF
|
||
|
if (pszParse != NULL)
|
||
|
{
|
||
|
|
||
|
TCHAR szTemp[MAX_PATH];
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
//get INF directory
|
||
|
if (! GetWindowsDirectory(szTemp, sizeof(szTemp) / sizeof(TCHAR)))
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||
|
TRACE("Uninstall: GetWindowsDirectory failed, hr=0x%x", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
AddBackSlash(szTemp);
|
||
|
lstrcat(szTemp, INFDIRECTORY);
|
||
|
|
||
|
//start building the command
|
||
|
lstrcpy(szCmd, INFUNINSTALLCOMMAND);
|
||
|
lstrcat(szCmd, szTemp);
|
||
|
|
||
|
pszParse = lstrcpystr(pszParse, _T(","), szTemp); // get INF file name
|
||
|
lstrcat(szCmd, szTemp);
|
||
|
|
||
|
lstrcat(szCmd, _T(","));
|
||
|
|
||
|
pszParse = lstrcpystr(pszParse, _T(","), szTemp); // get INF section
|
||
|
lstrcat(szCmd, szTemp);
|
||
|
|
||
|
lRet = LaunchProcess(szCmd, NULL, SW_NORMAL, TRUE);
|
||
|
if (lRet != 0)
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(lRet);
|
||
|
}
|
||
|
|
||
|
TRACE("Uninstall: %s, %d", szCmd, lRet);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
//
|
||
|
// reboot handling after uninstall only if uninstall was successful
|
||
|
//
|
||
|
pszParse = lstrcpystr(pszParse, _T(","), szTemp); // get the reboot key
|
||
|
if (lstrcmpi(szTemp, _T("reboot")) == 0)
|
||
|
{
|
||
|
g_v3state.m_bRebootNeeded = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
void InstallPrinterItem(LPCTSTR pszDriverName, LPCTSTR pszInstallFolder, LPCTSTR pszArchitecture)
|
||
|
{
|
||
|
DWORD dw = InstallPrinterDriver(pszDriverName, pszInstallFolder, pszArchitecture);
|
||
|
HRESULT hr = HRESULT_FROM_WIN32(dw);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
throw hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT AdvPackRunSetupCommand(HWND hwnd, LPCSTR pszInfFile, LPCSTR pszSection, LPCSTR pszDir, DWORD dwFlags)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
RUNSETUPCOMMAND pfRunSetupCommand;
|
||
|
|
||
|
HINSTANCE hAdvPack = LoadLibrary(_T("advpack.dll"));
|
||
|
|
||
|
if (hAdvPack != NULL)
|
||
|
{
|
||
|
pfRunSetupCommand = (RUNSETUPCOMMAND)GetProcAddress(hAdvPack, "RunSetupCommand");
|
||
|
if (pfRunSetupCommand)
|
||
|
{
|
||
|
dwFlags |= (RSC_FLAG_INF | RSC_FLAG_NGCONV | RSC_FLAG_QUIET);
|
||
|
hr = pfRunSetupCommand(hwnd, pszInfFile, pszSection, pszDir, NULL, NULL, dwFlags, NULL);
|
||
|
}
|
||
|
FreeLibrary(hAdvPack);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// checks to see if inseng is up to date
|
||
|
void CheckLocalDll(LPCTSTR pszServer, LPCTSTR pszDllName, LPCTSTR pszServDllName, LPCTSTR pszDllVersion)
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
const TCHAR TEMPINFFN[] = _T("temp.inf");
|
||
|
const TCHAR PERIOD[] = _T(".");
|
||
|
|
||
|
TCHAR szServDllName[32] = _T("\0");
|
||
|
TCHAR szValue[256] = _T("\0");
|
||
|
TCHAR szTempFN[MAX_PATH] = _T("\0");
|
||
|
TCHAR szDllFN[MAX_PATH] = _T("\0");
|
||
|
TCHAR szInfDir[MAX_PATH] = _T("\0");
|
||
|
TCHAR szDllName[MAX_PATH] = _T("\0");
|
||
|
TCHAR szDllVersion[64] = _T("\0");
|
||
|
TCHAR *pszToken = NULL;
|
||
|
DWORD dwIniMSVer = 0;
|
||
|
DWORD dwIniLSVer = 0;
|
||
|
DWORD dwFileMSVer = 0;
|
||
|
DWORD dwFileLSVer = 0;
|
||
|
LPTSTR p = NULL;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
//check input arguments
|
||
|
if (NULL == pszDllName || NULL == pszServDllName || NULL == pszDllVersion)
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
if (!GetSystemDirectory(szDllFN, sizeof(szDllFN) / sizeof(TCHAR)))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
AddBackSlash(szDllFN);
|
||
|
lstrcat(szDllFN, pszDllName);
|
||
|
|
||
|
lstrcpy(szDllVersion, pszDllVersion);
|
||
|
lstrcpy(szServDllName, pszServDllName);
|
||
|
|
||
|
if (FileExists(szDllFN))
|
||
|
{
|
||
|
// convert file version
|
||
|
ConvertVersionStrToDwords(szDllVersion, &dwIniMSVer, &dwIniLSVer);
|
||
|
|
||
|
// get file version of the DLL
|
||
|
if (!GetFileVersionDwords(szDllFN, &dwFileMSVer, &dwFileLSVer))
|
||
|
{
|
||
|
TRACE("Could not check file version: %s", szDllFN);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// compare the versions
|
||
|
if ((dwFileMSVer > dwIniMSVer) || ((dwFileMSVer == dwIniMSVer) && (dwFileLSVer >= dwIniLSVer)))
|
||
|
{
|
||
|
// install version is up to date
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// we need to download and install it!
|
||
|
//
|
||
|
BLOCK
|
||
|
{
|
||
|
CWUDownload dl(pszServer, 8192);
|
||
|
|
||
|
if (!dl.Copy(szServDllName, NULL, NULL, NULL, DOWNLOAD_NEWER | CACHE_FILE_LOCALLY, NULL))
|
||
|
{
|
||
|
throw HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
|
||
|
// filename with OS ext
|
||
|
GetWindowsUpdateDirectory(szTempFN);
|
||
|
lstrcat(szTempFN, szServDllName);
|
||
|
|
||
|
// filename with .dll
|
||
|
lstrcpy(szDllFN, szTempFN);
|
||
|
p = _tcschr(szDllFN, _T('.'));
|
||
|
if (p)
|
||
|
*p = _T('\0');
|
||
|
lstrcat(szDllFN, _T(".dll"));
|
||
|
|
||
|
CDiamond dm;
|
||
|
|
||
|
// decompress or copy to .dll name
|
||
|
if (dm.IsValidCAB(szTempFN))
|
||
|
{
|
||
|
hr = dm.Decompress(szTempFN, szDllFN);
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
throw hr;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!CopyFile(szTempFN, szDllFN, FALSE))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// write out an INF file
|
||
|
//
|
||
|
HANDLE hFile;
|
||
|
DWORD dwBytes;
|
||
|
char szInfText[1024];
|
||
|
|
||
|
|
||
|
sprintf (szInfText,
|
||
|
"[Version]\r\n\
|
||
|
Signature=\"$Chicago$\"\r\n\
|
||
|
AdvancedINF=2.5\r\n\
|
||
|
[DestinationDirs]\r\n\
|
||
|
WUSysDirCopy=11\r\n\
|
||
|
[InstallControl]\r\n\
|
||
|
CopyFiles=WUSysDirCopy\r\n\
|
||
|
RegisterOCXs=WURegisterOCXSection\r\n\
|
||
|
[WUSysDirCopy]\r\n\
|
||
|
%s,,,32\r\n\
|
||
|
[WURegisterOCXSection]\r\n\
|
||
|
%%11%%\\%s\r\n\
|
||
|
[SourceDisksNames]\r\n\
|
||
|
55=\"Disk\",,0\r\n\
|
||
|
[SourceDisksFiles]\r\n\
|
||
|
%s=55\r\n",
|
||
|
T2A(pszDllName), T2A(pszDllName), T2A(pszDllName));
|
||
|
|
||
|
GetWindowsUpdateDirectory(szTempFN);
|
||
|
lstrcat(szTempFN, TEMPINFFN);
|
||
|
|
||
|
hFile = CreateFile(szTempFN, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
WriteFile(hFile, (LPCVOID)szInfText, strlen(szInfText), &dwBytes, NULL);
|
||
|
|
||
|
CloseHandle(hFile);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// RunSetupCommand to install the .INF
|
||
|
//
|
||
|
GetWindowsUpdateDirectory(szInfDir);
|
||
|
|
||
|
hr = AdvPackRunSetupCommand(NULL, T2A(szTempFN), "InstallControl", T2A(szInfDir), 0);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
throw hr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CheckDllsToJit(LPCTSTR pszServer)
|
||
|
{
|
||
|
const TCHAR SEPS[] = _T("=");
|
||
|
TCHAR szValue[1024];
|
||
|
TCHAR szTempFN[MAX_PATH];
|
||
|
TCHAR szKey[256];
|
||
|
TCHAR szDllBaseName[64];
|
||
|
TCHAR szDllExt[32];
|
||
|
TCHAR szKeyLhs[64];
|
||
|
TCHAR szDllName[64];
|
||
|
TCHAR szDllTempName[64];
|
||
|
TCHAR szDllVersion[64];
|
||
|
TCHAR *pszValue;
|
||
|
long len;
|
||
|
|
||
|
if (g_v3state.m_bInsengChecked)
|
||
|
return;
|
||
|
|
||
|
g_v3state.m_bInsengChecked = TRUE;
|
||
|
|
||
|
GetWindowsUpdateDirectory(szTempFN);
|
||
|
lstrcat(szTempFN, FILEVERINI_FN);
|
||
|
|
||
|
if (0 == GetPrivateProfileSection(_T("version"), szValue, sizeof(szValue) / sizeof(TCHAR), szTempFN))
|
||
|
{
|
||
|
// version not available for this file
|
||
|
TRACE("Section: version is missing from FileVer.ini");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
pszValue = szValue;
|
||
|
while (0 != (len = lstrlen(pszValue)))
|
||
|
{
|
||
|
lstrcpyn(szKey, pszValue, len+1);
|
||
|
lstrcat(szKey, _T("\0"));
|
||
|
pszValue += len + 1;
|
||
|
|
||
|
_stscanf(szKey, _T("%[^=]=%s"), szKeyLhs, szDllVersion);
|
||
|
_stscanf(szKeyLhs, _T("%[^.].%s"), szDllBaseName, szDllExt);
|
||
|
wsprintf(szDllName, _T("%s.dll"), szDllBaseName);
|
||
|
|
||
|
wsprintf(szDllTempName, _T("%s."), szDllBaseName);
|
||
|
AppendExtForOS(szDllTempName);
|
||
|
if (0 == lstrcmpi(szDllTempName, szKeyLhs))
|
||
|
CheckLocalDll(pszServer, szDllName, szKeyLhs, szDllVersion);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
// Pings a URL for tracking purposes
|
||
|
//
|
||
|
// NOTE: pszStatus must not contain spaces and cannot be null
|
||
|
void URLPingReport(PINVENTORY_ITEM pItem, CCatalog* pCatalog, PSELECTITEMINFO pSelectItem, LPCTSTR pszStatus)
|
||
|
{
|
||
|
LOG_block("URLPingReport");
|
||
|
|
||
|
//check for input arguments
|
||
|
if (NULL == pItem || NULL == pCatalog)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// create a download object
|
||
|
try
|
||
|
{
|
||
|
CWUDownload dl(g_v3state.GetIdentServer(), 8192);
|
||
|
|
||
|
// build the URL with parameters
|
||
|
TCHAR szURL[INTERNET_MAX_PATH_LENGTH];
|
||
|
wsprintf(szURL, _T("wutrack.bin?VER=%s&PUID=%d&PLAT=%d&LOCALE=%s&STATUS=%s&ERR=0x%x&SESSID=%s"),
|
||
|
CCV3::s_szControlVer,
|
||
|
pItem->GetPuid(),
|
||
|
pCatalog->GetPlatform(),
|
||
|
pCatalog->GetMachineLocaleSZ(),
|
||
|
pszStatus,
|
||
|
pSelectItem->hrError,
|
||
|
CWUDownload::m_szWUSessionID);
|
||
|
|
||
|
LOG_out("Sending %s", szURL);
|
||
|
|
||
|
// ping the URL and receive the response in memory
|
||
|
PVOID pMemBuf;
|
||
|
ULONG ulMemSize;
|
||
|
if (dl.QCopy(szURL, &pMemBuf, &ulMemSize))
|
||
|
{
|
||
|
// we don't care about the response so we just free it
|
||
|
V3_free(pMemBuf);
|
||
|
}
|
||
|
}
|
||
|
catch(HRESULT hr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
}
|