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.
2487 lines
64 KiB
2487 lines
64 KiB
#include "inspch.h"
|
|
#include "inseng.h"
|
|
#include "resource.h"
|
|
#include "insobj.h"
|
|
#include "advpub.h"
|
|
#include "capi.h"
|
|
#include "util.h"
|
|
#include "util2.h"
|
|
#include <regstr.h>
|
|
|
|
TCHAR c_gszSetupAPI[] = "setupapi.dll";
|
|
TCHAR c_gszAdvpext[] = "advpext.dll";
|
|
|
|
// A reusable buffer for logging. Note there is a possible threading
|
|
// issue here as two threads may use this at the same time! I am choosing
|
|
// not to protect it for performance reasons but be careful!!
|
|
char szLogBuf[512];
|
|
|
|
|
|
|
|
// NT reboot
|
|
//
|
|
|
|
|
|
|
|
#define MSDOWNLOAD "msdownld.tmp"
|
|
#define DOWNLDSUB "download"
|
|
|
|
// functions
|
|
BOOL IfNotExistCreateDir( LPTSTR lpDir, BOOL bHidden, BOOL bRemoveFileIfExist );
|
|
BOOL CheckImageHlp_dll();
|
|
|
|
char g_szWindowsDir[MAX_PATH] = { 0 };
|
|
|
|
#define MAXRETRIES 100
|
|
BOOL GetUniqueFileName(LPCSTR pszRoot, LPCSTR pszPrefix, UINT uStartIndex, LPSTR pszBuffer)
|
|
{
|
|
char pszTemp[MAX_PATH];
|
|
char pszTempname[16];
|
|
// we now ignore the uStartIndex parameter, and create something random.
|
|
uStartIndex = GetTickCount() % 0xFFFF9A;
|
|
UINT uEndIndex = uStartIndex + MAXRETRIES;
|
|
LPSTR pszEnd;
|
|
|
|
pszBuffer[0] = 0;
|
|
lstrcpy(pszTemp, pszRoot);
|
|
pszEnd = pszTemp + lstrlen(pszTemp);
|
|
|
|
do
|
|
{
|
|
wsprintf(pszTempname, "%s%06X.tmp", pszPrefix, uStartIndex);
|
|
AddPath(pszTemp, pszTempname);
|
|
if(GetFileAttributes(pszTemp) == 0xFFFFFFFF)
|
|
break;
|
|
uStartIndex++;
|
|
*pszEnd = 0;
|
|
} while (uStartIndex < uEndIndex);
|
|
|
|
if(uStartIndex != uEndIndex)
|
|
lstrcpy(pszBuffer, pszTemp);
|
|
|
|
return ( pszBuffer[0] != 0 );
|
|
}
|
|
|
|
#define MIN_DISKSIZE_FOR_EXTRACT 1024 * 100
|
|
#define MAX_DRIVES 26
|
|
|
|
BOOL IsUsableDrive(LPSTR szRoot)
|
|
{
|
|
static BYTE bDrives[MAX_DRIVES] = { 0 };
|
|
static UINT uUseRemovable = 0xffffffff;
|
|
BOOL fUsable;
|
|
UINT uType;
|
|
DWORD dwOldErrorMode;
|
|
|
|
if(uUseRemovable == 0xffffffff)
|
|
{
|
|
char sztemp[] = "X:\\";
|
|
for(char ch = 'A'; ch <= 'Z'; ch++)
|
|
{
|
|
sztemp[0] = ch;
|
|
if(GetDriveType(sztemp) == DRIVE_FIXED)
|
|
{
|
|
uUseRemovable = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if(uUseRemovable == 0xffffffff)
|
|
uUseRemovable = TRUE;
|
|
}
|
|
|
|
dwOldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
uType = GetDriveType(szRoot);
|
|
|
|
// the drive type is OK, if
|
|
// it is fixed or removable AND
|
|
// it is bigger than MIN_DISKSIZE_FOR_EXTRACT AND
|
|
// GetFileAttributes succeeds
|
|
//
|
|
if ( (!bDrives[szRoot[0] - 'A']) &&
|
|
((uType == DRIVE_REMOVABLE && uUseRemovable) || (uType == DRIVE_FIXED)) &&
|
|
( GetFileAttributes( szRoot ) != 0xffffffff) &&
|
|
( GetDriveSize(szRoot) >= MIN_DISKSIZE_FOR_EXTRACT ) )
|
|
{
|
|
fUsable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bDrives[szRoot[0] - 'A'] = 1;
|
|
fUsable = FALSE;
|
|
}
|
|
SetErrorMode(dwOldErrorMode);
|
|
return fUsable;
|
|
}
|
|
|
|
BOOL IsDirWriteable(LPSTR lpDir)
|
|
{
|
|
char szFile[MAX_PATH];
|
|
HANDLE hFile;
|
|
BOOL bWriteAccess = FALSE;
|
|
|
|
lstrcpy(szFile, lpDir);
|
|
AddPath(szFile, "~!~ie6.~!~");
|
|
hFile = CreateFile(szFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
bWriteAccess = TRUE;
|
|
CloseHandle(hFile);
|
|
DeleteFile(szFile);
|
|
}
|
|
return bWriteAccess;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
// BUGBUG: Currently we have two problems :
|
|
// 1. Always assume cache drive == win drive
|
|
// 2. Compression isn't accounted for on stuff going to cache
|
|
|
|
HRESULT CreateTempDir( DWORD dwDownloadSize,
|
|
DWORD dwExtractSize,
|
|
char chInstallDrive, DWORD dwInstallSize,
|
|
DWORD dwWindowsDriveSize,
|
|
LPSTR pszBuf, DWORD dwBufSize, DWORD dwFlag )
|
|
{
|
|
char szRoot[MAX_PATH];
|
|
char szUnique[MAX_PATH];
|
|
DWORD dwReqSize;
|
|
DWORD dwReqSizeWin = 0;
|
|
DWORD dwReqSizeOther = 0;
|
|
DWORD dwVolFlags;
|
|
DWORD dwCompressFactor;
|
|
|
|
if ( !pszBuf || (dwBufSize==0) )
|
|
{
|
|
return ( E_INVALIDARG );
|
|
}
|
|
|
|
if(g_szWindowsDir[0] == 0)
|
|
{
|
|
GetWindowsDirectory(g_szWindowsDir, sizeof(g_szWindowsDir));
|
|
}
|
|
// Make sure there is enough install space on drive
|
|
dwReqSizeWin = dwWindowsDriveSize;
|
|
if(chInstallDrive == g_szWindowsDir[0])
|
|
dwReqSizeWin += dwInstallSize;
|
|
else
|
|
dwReqSizeOther = dwInstallSize;
|
|
|
|
if(dwReqSizeWin > 0)
|
|
{
|
|
lstrcpyn(szRoot, g_szWindowsDir, 4);
|
|
if(!IsEnoughSpace(szRoot, dwReqSizeWin))
|
|
return E_FAIL;
|
|
}
|
|
|
|
if(dwReqSizeOther > 0)
|
|
{
|
|
lstrcpyn(szRoot, g_szWindowsDir, 4);
|
|
szRoot[0] = chInstallDrive;
|
|
if(!IsEnoughSpace(szRoot, dwReqSizeOther))
|
|
return E_FAIL;
|
|
}
|
|
|
|
lstrcpy( szRoot, "A:\\" );
|
|
|
|
while ( szRoot[0] <= 'Z' )
|
|
{
|
|
UINT uType;
|
|
|
|
uType = GetDriveType(szRoot);
|
|
|
|
// even the drive type is OK, verify the drive has valid connection
|
|
//
|
|
if ( !IsUsableDrive(szRoot) )
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
|
|
if(!IsDirWriteable(szRoot))
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
|
|
if(!GetVolumeInformation(szRoot, NULL, 0, NULL, NULL, &dwVolFlags, NULL, 0))
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
if(dwVolFlags & FS_VOL_IS_COMPRESSED)
|
|
dwCompressFactor = 19;
|
|
else
|
|
dwCompressFactor = 10;
|
|
|
|
|
|
// suitable drive:
|
|
dwReqSize = (dwDownloadSize * dwCompressFactor)/10;
|
|
dwReqSize += dwExtractSize;
|
|
if(g_szWindowsDir[0] == szRoot[0])
|
|
dwReqSize += dwReqSizeWin;
|
|
else if(chInstallDrive == szRoot[0])
|
|
dwReqSize += dwReqSizeOther;
|
|
|
|
if ( !IsEnoughSpace( szRoot, dwReqSize ) )
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
|
|
// if our suitable drive happens also to be the windows drive,
|
|
// create msdownld.tmp of of it.
|
|
if(szRoot[0] == g_szWindowsDir[0])
|
|
lstrcpy(szRoot, g_szWindowsDir);
|
|
|
|
AddPath( szRoot, MSDOWNLOAD );
|
|
|
|
if ( !IfNotExistCreateDir( szRoot, TRUE, TRUE ) )
|
|
{
|
|
TryNextDrive:
|
|
szRoot[0]++;
|
|
szRoot[3] = '\0';
|
|
continue;
|
|
}
|
|
|
|
// BUGBUG: On NT, it always tries with sequential numbers ASE1.TMP, ASE2.TMP
|
|
// ASE3.TMP, etc. and if there is already a directory by this name
|
|
// it fails the call instead of trying again with next number!
|
|
//
|
|
if ( !GetUniqueFileName(szRoot,"AS", 0, szUnique) )
|
|
goto TryNextDrive ;
|
|
|
|
lstrcpy(szRoot, szUnique);
|
|
|
|
if ( !IfNotExistCreateDir( szRoot, FALSE, FALSE) )
|
|
{
|
|
goto TryNextDrive;
|
|
}
|
|
|
|
// you got the good dir
|
|
AddPath( szRoot, "" );
|
|
|
|
if ( (DWORD) lstrlen(szRoot)+1 > dwBufSize )
|
|
{
|
|
return ( E_INVALIDARG );
|
|
}
|
|
|
|
// success
|
|
lstrcpy( pszBuf, szRoot );
|
|
return S_OK;
|
|
}
|
|
|
|
// no drive has enough space
|
|
return( E_FAIL );
|
|
}
|
|
|
|
void CleanUpTempDir(LPCSTR szTemp)
|
|
{
|
|
char szBuf[MAX_PATH];
|
|
char szWinDir[MAX_PATH];
|
|
|
|
|
|
lstrcpy(szBuf, szTemp);
|
|
|
|
DelNode(szBuf, 0);
|
|
|
|
// clean up msdownld.tmp if its not the windows drive
|
|
GetWindowsDirectory(szWinDir, sizeof(szWinDir));
|
|
if(!ANSIStrStrI(szBuf, szWinDir))
|
|
{
|
|
GetParentDir(szBuf);
|
|
DelNode(szBuf, ADN_DEL_IF_EMPTY);
|
|
}
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
// Checks the install destination dir free disk space
|
|
//
|
|
BOOL IsEnoughSpace( LPCSTR szPath, DWORD dwInstNeedSize )
|
|
{
|
|
char szRoot[4];
|
|
|
|
lstrcpyn(szRoot, szPath, 4);
|
|
if( szRoot[0] == 0)
|
|
return FALSE;
|
|
|
|
if ( dwInstNeedSize + 1 > GetSpace(szRoot) )
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void SafeAddPath(LPSTR szPath, LPCSTR szName, DWORD dwPathSize)
|
|
{
|
|
LPSTR szTmp;
|
|
DWORD dwLen = lstrlen(szPath);
|
|
|
|
if(dwLen + 1 >= dwPathSize)
|
|
return;
|
|
|
|
// Find end of the string
|
|
szTmp = szPath + dwLen;
|
|
|
|
// If no trailing backslash then add one
|
|
if ( szTmp > szPath && *(AnsiPrev( szPath, szTmp )) != '\\' )
|
|
*(szTmp++) = '\\';
|
|
*szTmp = 0;
|
|
|
|
// Add new name to existing path string
|
|
while ( *szName == ' ' ) szName++;
|
|
lstrcpyn( szTmp, szName, dwPathSize - lstrlen(szPath) );
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
BOOL IfNotExistCreateDir( LPTSTR lpDir, BOOL bHidden, BOOL bRemoveFileIfExist)
|
|
{
|
|
DWORD attr;
|
|
|
|
attr = GetFileAttributes( lpDir );
|
|
if ((attr != -1) && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
|
{
|
|
// lpDir does not have a directory attribute
|
|
// If we are allowed to delete the file, try do that.
|
|
if (bRemoveFileIfExist)
|
|
{
|
|
SetFileAttributes(lpDir, FILE_ATTRIBUTE_NORMAL);
|
|
DeleteFile(lpDir);
|
|
attr = GetFileAttributes( lpDir );
|
|
}
|
|
}
|
|
if (attr == -1)
|
|
{
|
|
if ( CreateDirectory( lpDir, NULL ) )
|
|
{
|
|
if(bHidden)
|
|
return (SetFileAttributes( lpDir, FILE_ATTRIBUTE_HIDDEN ) );
|
|
else
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
return (attr & FILE_ATTRIBUTE_DIRECTORY);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT LaunchProcess(LPCSTR pszCmd, HANDLE *phProc, LPCSTR pszDir, UINT uShow)
|
|
{
|
|
STARTUPINFO startInfo;
|
|
PROCESS_INFORMATION processInfo;
|
|
HRESULT hr = S_OK;
|
|
BOOL fRet;
|
|
|
|
if(phProc)
|
|
*phProc = NULL;
|
|
|
|
// Create process on pszCmd
|
|
ZeroMemory(&startInfo, sizeof(startInfo));
|
|
startInfo.cb = sizeof(startInfo);
|
|
startInfo.dwFlags |= STARTF_USESHOWWINDOW;
|
|
startInfo.wShowWindow = (USHORT)uShow;
|
|
fRet = CreateProcess(NULL, (LPSTR) pszCmd, NULL, NULL, FALSE,
|
|
NORMAL_PRIORITY_CLASS, NULL, pszDir, &startInfo, &processInfo);
|
|
if(!fRet)
|
|
return E_FAIL;
|
|
|
|
if(phProc)
|
|
*phProc = processInfo.hProcess;
|
|
else
|
|
CloseHandle(processInfo.hProcess);
|
|
|
|
CloseHandle(processInfo.hThread);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
HRESULT LaunchAndWait(LPSTR pszCmd, HANDLE hAbort, HANDLE *phProc, LPSTR pszDir, UINT uShow)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = LaunchProcess(pszCmd, phProc, pszDir, uShow);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
HANDLE pHandles[2];
|
|
BOOL fQuit = FALSE;
|
|
pHandles[0] = *phProc;
|
|
|
|
if(hAbort)
|
|
pHandles[1] = hAbort;
|
|
|
|
DWORD dwRet;
|
|
|
|
while(!fQuit)
|
|
{
|
|
dwRet = MsgWaitForMultipleObjects(hAbort ? 2 : 1, pHandles, FALSE, INFINITE, QS_ALLINPUT);
|
|
// Give abort the highest priority
|
|
if(dwRet == WAIT_OBJECT_0)
|
|
{
|
|
fQuit = TRUE;
|
|
}
|
|
else if((dwRet == WAIT_OBJECT_0 + 1) && hAbort)
|
|
{
|
|
// Any abort work?
|
|
hr = E_ABORT;
|
|
fQuit = TRUE;
|
|
}
|
|
else
|
|
{
|
|
MSG msg;
|
|
// read all of the messages in this next loop
|
|
// removing each message as we read it
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
|
|
// if it's a quit message we're out of here
|
|
if (msg.message == WM_QUIT)
|
|
fQuit = TRUE;
|
|
else
|
|
{
|
|
// otherwise dispatch it
|
|
DispatchMessage(&msg);
|
|
} // end of PeekMessage while loop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
void ConvertVersionStrToDwords(LPSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
|
|
{
|
|
DWORD dwTemp1,dwTemp2;
|
|
|
|
dwTemp1 = GetIntField(pszVer, 0, 0);
|
|
dwTemp2 = GetIntField(pszVer, 1, 0);
|
|
|
|
*pdwVer = (dwTemp1 << 16) + dwTemp2;
|
|
|
|
dwTemp1 = GetIntField(pszVer, 2, 0);
|
|
dwTemp2 = GetIntField(pszVer, 3, 0);
|
|
|
|
*pdwBuild = (dwTemp1 << 16) + dwTemp2;
|
|
}
|
|
|
|
/*
|
|
void ConvertVersionStr(LPSTR pszVer, WORD rwVer[])
|
|
{
|
|
LPSTR pszMyVer = MakeAnsiStrFromAnsi(pszVer);
|
|
LPSTR pszEnd = pszMyVer + lstrlen(pszMyVer);
|
|
LPSTR pszTemp = pszMyVer;
|
|
LPSTR pszBegin;
|
|
|
|
for(int i = 0; i < NUM_VERSION_ENTRIES; i++)
|
|
rwVer[i] = 0;
|
|
|
|
for(i = 0; i < 4 && pszTemp < pszEnd; i++)
|
|
{
|
|
pszBegin = pszTemp;
|
|
while(pszTemp < pszEnd && *pszTemp != ',')
|
|
pszTemp++;
|
|
|
|
*pszTemp = 0;
|
|
rwVer[i] = (WORD) AtoL(pszBegin);
|
|
pszTemp++;
|
|
}
|
|
CoTaskMemFree(pszMyVer);
|
|
}
|
|
|
|
*/
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
// -1 Ver1 < Ver2
|
|
// 0 Ver1 == Ver2
|
|
// 1 Ver1 > Ver2
|
|
// Notes:
|
|
|
|
int VersionCmp(WORD rwVer1[], WORD rwVer2[])
|
|
{
|
|
/*
|
|
for(int i = 0; i < NUM_VERSION_ENTRIES; i++)
|
|
{
|
|
if(rwVer1[i] < rwVer2[i])
|
|
return -1;
|
|
if(rwVer1[i] > rwVer2[i])
|
|
return 1;
|
|
}
|
|
*/
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
int ErrMsgBox(LPSTR pszText, LPCSTR pszTitle, UINT mbFlags)
|
|
{
|
|
HWND hwndActive;
|
|
int id;
|
|
|
|
hwndActive = GetActiveWindow();
|
|
|
|
id = MessageBox(hwndActive, pszText, pszTitle, mbFlags | MB_ICONERROR | MB_TASKMODAL);
|
|
|
|
return id;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
int LoadSz(UINT id, LPSTR pszBuf, UINT cMaxSize)
|
|
{
|
|
|
|
if(cMaxSize == 0)
|
|
return 0;
|
|
|
|
pszBuf[0] = 0;
|
|
|
|
return LoadString(g_hInstance, id, pszBuf, cMaxSize);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPSTR FindChar(LPSTR pszStr, char ch)
|
|
{
|
|
while( *pszStr != 0 && *pszStr != ch )
|
|
{
|
|
if (*pszStr == '\"')
|
|
{
|
|
// Move past the first "
|
|
pszStr++;
|
|
|
|
// Now keep scanning till find the closing ". After that return to scanning
|
|
// for the user-given delimiter 'ch'.
|
|
while( *pszStr != 0 && *pszStr != '\"' )
|
|
pszStr++;
|
|
|
|
// Have reached end of string without finding closing ", return now.
|
|
if (*pszStr == 0)
|
|
break;
|
|
}
|
|
|
|
pszStr++;
|
|
}
|
|
|
|
return pszStr;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
// This is a very hacky function that will strip quotes.
|
|
// Note it chages the contents of the buffer passed to it!!
|
|
LPSTR StripQuotes(LPSTR pszStr)
|
|
{
|
|
if(!pszStr)
|
|
return NULL;
|
|
|
|
UINT uEnd = lstrlenA(pszStr);
|
|
if(uEnd > 0 && pszStr[uEnd-1] == '"' && *pszStr == '"')
|
|
{
|
|
pszStr[uEnd-1] = 0;
|
|
pszStr++;
|
|
}
|
|
|
|
return pszStr;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
|
|
DWORD WINAPI LaunchInfCommand(void *p)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
INF_ARGUEMENTS *pinfArgs = (INF_ARGUEMENTS *)p;
|
|
|
|
if(pinfArgs->dwType == InfExCommand)
|
|
{
|
|
CABINFO cabinfo;
|
|
cabinfo.pszCab = pinfArgs->szCab;
|
|
cabinfo.pszInf = pinfArgs->szInfname;
|
|
cabinfo.pszSection = pinfArgs->szSection;
|
|
|
|
lstrcpy(cabinfo.szSrcPath, pinfArgs->szDir);
|
|
cabinfo.dwFlags = pinfArgs->dwFlags;
|
|
|
|
hr = ExecuteCab(NULL, &cabinfo, 0);
|
|
}
|
|
else
|
|
{
|
|
hr = RunSetupCommand(NULL, pinfArgs->szInfname,
|
|
lstrlen(pinfArgs->szSection) ? pinfArgs->szSection : NULL,
|
|
pinfArgs->szDir, NULL, NULL, pinfArgs->dwFlags, NULL );
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
#define ABOUTTWODAYSTIME 0x000000C9
|
|
|
|
void CleanupDir(LPSTR lpDir)
|
|
{
|
|
char szFile[MAX_PATH];
|
|
WIN32_FIND_DATA fileData;
|
|
HANDLE hFindFile;
|
|
FILETIME currenttime;
|
|
|
|
if ( lpDir == NULL || *lpDir == '\0' )
|
|
return;
|
|
|
|
lstrcpy( szFile, lpDir );
|
|
if ( szFile[ lstrlen(szFile)-1 ] != '\\' )
|
|
lstrcat( szFile, "\\" );
|
|
lstrcat( szFile, "*.tmp" );
|
|
hFindFile = FindFirstFile( szFile, &fileData );
|
|
if ( hFindFile == INVALID_HANDLE_VALUE )
|
|
return;
|
|
|
|
do
|
|
{
|
|
|
|
if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
|
{
|
|
if ( lstrcmp( fileData.cFileName, "." ) == 0 ||
|
|
lstrcmp( fileData.cFileName, ".." ) == 0 )
|
|
continue;
|
|
|
|
GetSystemTimeAsFileTime(¤ttime);
|
|
if( ( currenttime.dwHighDateTime >
|
|
fileData.ftLastWriteTime.dwHighDateTime ) &&
|
|
( currenttime.dwHighDateTime -
|
|
fileData.ftLastWriteTime.dwHighDateTime > ABOUTTWODAYSTIME))
|
|
{
|
|
lstrcpy( szFile, lpDir );
|
|
if ( szFile[ lstrlen(szFile)-1 ] != '\\' )
|
|
lstrcat( szFile, "\\" );
|
|
// delete the sub-dir
|
|
lstrcat( szFile, fileData.cFileName );
|
|
SetFileAttributes(szFile, FILE_ATTRIBUTE_NORMAL );
|
|
DelNode( szFile, 0 );
|
|
}
|
|
}
|
|
else
|
|
continue;
|
|
|
|
} while ( FindNextFile( hFindFile, &fileData ) );
|
|
|
|
FindClose( hFindFile );
|
|
}
|
|
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD WINAPI CleanUpAllDirs(LPVOID pv)
|
|
{
|
|
char szDir[MAX_PATH];
|
|
UINT uType;
|
|
|
|
DllAddRef();
|
|
if(g_szWindowsDir[0] == 0)
|
|
{
|
|
GetWindowsDirectory(g_szWindowsDir, sizeof(g_szWindowsDir));
|
|
}
|
|
|
|
lstrcpy( szDir, "X:\\" );
|
|
for(char chDrive = 'A'; chDrive <= 'Z'; chDrive++)
|
|
{
|
|
szDir[0] = chDrive;
|
|
|
|
if (IsUsableDrive(szDir))
|
|
{
|
|
if(chDrive == g_szWindowsDir[0])
|
|
lstrcpy(szDir, g_szWindowsDir);
|
|
|
|
AddPath(szDir, MSDOWNLOAD);
|
|
CleanupDir(szDir);
|
|
szDir[3] = 0;
|
|
}
|
|
}
|
|
DllRelease();
|
|
return 0;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
BOOL IsCabFile(LPCSTR pszFile)
|
|
{
|
|
|
|
DWORD dwLen = lstrlenA(pszFile);
|
|
if(dwLen <= 3)
|
|
return FALSE;
|
|
|
|
LPCSTR pszExt = pszFile + (dwLen - 4);
|
|
|
|
if(lstrcmpiA(pszExt, ".cab") == 0)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
typedef HRESULT (WINAPI *WINVERIFYTRUST) (HWND hwnd, GUID *pgActionID, LPVOID pWintrustData);
|
|
|
|
// BUGBUG: get rid of this once moved to winbase.h!!!
|
|
// #define WIN_TRUST_SUBJTYPE_CABINET \
|
|
// { 0xd17c5374, \
|
|
// 0xa392, \
|
|
// 0x11cf, \
|
|
// { 0x9d, 0xf5, 0x0, 0xaa, 0x0, 0xc1, 0x84, 0xe0 } \
|
|
// }
|
|
|
|
// PublishedSoftwareNoBad {C6B2E8D0-E005-11cf-A134-00C04FD7BF43}
|
|
#define WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI \
|
|
{ 0xc6b2e8d0, \
|
|
0xe005, \
|
|
0x11cf, \
|
|
{ 0xa1, 0x34, 0x0, 0xc0, 0x4f, 0xd7, 0xbf, 0x43 } \
|
|
}
|
|
|
|
#define WINTRUST "wintrust.dll"
|
|
|
|
// Verion number 5.0
|
|
#define AUTHENTICODE2_MS_VERSION 0x00050000
|
|
// Build number 1542.32
|
|
#define AUTHENTICODE2_LS_VERSION 0x06050020
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CheckTrustIE3(LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt);
|
|
HRESULT CheckTrustIE4(LPCSTR szURL, LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt);
|
|
|
|
|
|
HRESULT WINAPI CheckTrustEx(LPCSTR szURL, LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, DWORD dwReserved)
|
|
{
|
|
WINVERIFYTRUST pwvt;
|
|
HINSTANCE hinst;
|
|
char szPath[MAX_PATH] = { 0 };
|
|
DWORD dwVerMS = 0;
|
|
DWORD dwVerLS = 0;
|
|
HRESULT hr = S_OK;
|
|
static BOOL st_CheckTrust = TRUE ;
|
|
static BOOL st_Auth2Checked = FALSE;
|
|
|
|
|
|
if (!st_CheckTrust)
|
|
return S_FALSE ;
|
|
|
|
if (!CheckImageHlp_dll())
|
|
{
|
|
st_CheckTrust = FALSE;
|
|
return S_FALSE ;
|
|
}
|
|
|
|
hinst = LoadLibrary(WINTRUST);
|
|
if(!hinst)
|
|
{
|
|
//
|
|
st_CheckTrust = FALSE ;
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
if (!st_Auth2Checked)
|
|
{
|
|
// If we get here, we know we can load Wintrust.dll
|
|
GetSystemDirectory(szPath, sizeof(szPath));
|
|
AddPath(szPath, "Softpub.dll");
|
|
GetVersionFromFile(szPath, &dwVerMS, &dwVerLS, TRUE);
|
|
|
|
// If softpubs version is less then the authenticode2 version don't call WinverifyTrust.
|
|
if ((dwVerMS < AUTHENTICODE2_MS_VERSION) ||
|
|
((dwVerMS == AUTHENTICODE2_MS_VERSION) && (dwVerLS < AUTHENTICODE2_LS_VERSION)) )
|
|
{
|
|
hr = S_FALSE;
|
|
st_CheckTrust = FALSE;
|
|
}
|
|
st_Auth2Checked = TRUE;
|
|
}
|
|
|
|
if (st_CheckTrust)
|
|
{
|
|
|
|
pwvt = (WINVERIFYTRUST) GetProcAddress(hinst, "WinVerifyTrust");
|
|
if(!pwvt)
|
|
{
|
|
FreeLibrary(hinst);
|
|
st_CheckTrust = FALSE ;
|
|
|
|
return S_FALSE;
|
|
}
|
|
// If we don't have a URL, use the IE3 methode of CheckTrust.
|
|
hr = TRUST_E_PROVIDER_UNKNOWN;
|
|
if (szURL)
|
|
{
|
|
// The new way of calling into WinVerifyTrust wll return TRUST_E_PROVIDER_UNKNOWN
|
|
// if the new methode is not implemented on the system.
|
|
__try
|
|
{
|
|
hr = CheckTrustIE4(szURL, szFilename, hwndForUI, bShowBadUI, pwvt);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
//Corrupted Java.
|
|
hr = TRUST_E_FAIL;
|
|
}
|
|
|
|
}
|
|
|
|
if (hr == TRUST_E_PROVIDER_UNKNOWN || hr == E_FAIL)
|
|
{
|
|
hr = CheckTrustIE3(szFilename, hwndForUI, bShowBadUI, pwvt);
|
|
if (hr == S_FALSE)
|
|
st_CheckTrust = FALSE;
|
|
}
|
|
}
|
|
|
|
FreeLibrary(hinst);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CheckTrustIE3(LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt)
|
|
{
|
|
HRESULT hr;
|
|
LPWSTR pwszFilename = NULL;
|
|
|
|
GUID PublishedSoftware = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
|
|
GUID PublishedSoftwareNoBadUI = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI;
|
|
|
|
GUID * ActionGUID;
|
|
|
|
if(bShowBadUI)
|
|
ActionGUID = &PublishedSoftware;
|
|
else
|
|
ActionGUID = &PublishedSoftwareNoBadUI;
|
|
|
|
GUID SubjectPeImage = WIN_TRUST_SUBJTYPE_PE_IMAGE;
|
|
GUID SubjectCAB = WIN_TRUST_SUBJTYPE_CABINET;
|
|
WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT ActionData;
|
|
WIN_TRUST_SUBJECT_FILE Subject;
|
|
|
|
Subject.hFile = INVALID_HANDLE_VALUE;
|
|
pwszFilename = OLESTRFROMANSI(szFilename);
|
|
Subject.lpPath = pwszFilename;
|
|
|
|
if (IsCabFile(szFilename))
|
|
{
|
|
ActionData.SubjectType = &SubjectCAB;
|
|
}
|
|
else
|
|
{
|
|
ActionData.SubjectType = &SubjectPeImage;
|
|
}
|
|
|
|
ActionData.Subject = &Subject;
|
|
ActionData.hClientToken = NULL;
|
|
|
|
hr = pwvt( hwndForUI, ActionGUID, &ActionData);
|
|
|
|
if(hr == E_FAIL)
|
|
{
|
|
// Hopefully, this is a general "trust is screwy" error. We will put
|
|
// up our own ui to see if we can continue
|
|
// Is this UI OK
|
|
|
|
char szTitle[128];
|
|
char szMess[256];
|
|
|
|
LoadSz(IDS_SECURITYTITLE, szTitle, 128);
|
|
LoadSz(IDS_SECURITY, szMess, 256);
|
|
if(MessageBox(hwndForUI, szMess, szTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
if(pwszFilename)
|
|
CoTaskMemFree(pwszFilename);
|
|
return hr;
|
|
}
|
|
|
|
|
|
// {D41E4F1D-A407-11d1-8BC9-00C04FA30A41}
|
|
#define COR_POLICY_PROVIDER_DOWNLOAD \
|
|
{ 0xd41e4f1d, 0xa407, 0x11d1, {0x8b, 0xc9, 0x0, 0xc0, 0x4f, 0xa3, 0xa, 0x41 } }
|
|
|
|
typedef HRESULT (WINAPI *COINTERNETCREATESECURITYMANAGER) ( IServiceProvider *pSP, IInternetSecurityManager **ppSM, DWORD dwReserved);
|
|
|
|
HRESULT CheckTrustIE4(LPCSTR szURL, LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt)
|
|
{
|
|
GUID guidCor = COR_POLICY_PROVIDER_DOWNLOAD;
|
|
GUID *pguidActionIDCor = &guidCor;
|
|
|
|
LPWSTR pwszURL = NULL;
|
|
GUID guidJava = JAVA_POLICY_PROVIDER_DOWNLOAD;
|
|
GUID *pguidActionIDJava = &guidJava;
|
|
|
|
WINTRUST_DATA wintrustData;
|
|
WINTRUST_FILE_INFO fileData;
|
|
JAVA_POLICY_PROVIDER javaPolicyData;
|
|
|
|
HRESULT hr = S_OK;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
|
|
HINSTANCE hUrlmon = NULL;
|
|
IInternetSecurityManager *pSecMgr = NULL;
|
|
DWORD dwZone;
|
|
|
|
hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
else
|
|
{
|
|
if (hwndForUI == INVALID_HANDLE_VALUE)
|
|
bShowBadUI = FALSE;
|
|
|
|
pwszURL = OLESTRFROMANSI(szURL);
|
|
|
|
memset(&wintrustData, 0, sizeof(wintrustData));
|
|
memset(&fileData, 0, sizeof(fileData));
|
|
memset(&javaPolicyData, 0, sizeof(javaPolicyData));
|
|
|
|
javaPolicyData.cbSize = sizeof(JAVA_POLICY_PROVIDER);
|
|
javaPolicyData.VMBased = FALSE;
|
|
|
|
// obsolete: noone pays attention to this
|
|
javaPolicyData.fNoBadUI = !bShowBadUI;
|
|
|
|
javaPolicyData.pwszZone = pwszURL;
|
|
javaPolicyData.pZoneManager = NULL;
|
|
|
|
// Use a file handle, so that in case trust has to put up UI the path
|
|
// to the local file does not show in hte UI if we actually downloaded the
|
|
// file from a URL.
|
|
fileData.cbStruct = sizeof(WINTRUST_FILE_INFO);
|
|
fileData.pcwszFilePath = pwszURL;
|
|
fileData.hFile = hFile;
|
|
|
|
wintrustData.cbStruct = sizeof(WINTRUST_DATA);
|
|
wintrustData.pPolicyCallbackData = &javaPolicyData;
|
|
if (hwndForUI == INVALID_HANDLE_VALUE)
|
|
wintrustData.dwUIChoice = WTD_UI_NONE;
|
|
else if(bShowBadUI)
|
|
wintrustData.dwUIChoice = WTD_UI_ALL;
|
|
else
|
|
wintrustData.dwUIChoice = WTD_UI_NOBAD;
|
|
|
|
wintrustData.dwUnionChoice = WTD_CHOICE_FILE;
|
|
wintrustData.pFile = &fileData;
|
|
|
|
|
|
hr = pwvt( hwndForUI, pguidActionIDCor, &wintrustData);
|
|
if (hr == TRUST_E_PROVIDER_UNKNOWN)
|
|
{
|
|
hr = pwvt( hwndForUI, pguidActionIDJava, &wintrustData);
|
|
}
|
|
|
|
// BUGBUG: Check with Vatsan about this bugbug.
|
|
// this works around a wvt bug that returns 0x57 (success) when
|
|
// you hit No to an unsigned control
|
|
if (SUCCEEDED(hr) && hr != S_OK)
|
|
{
|
|
hr = TRUST_E_FAIL;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hUrlmon = LoadLibrary("urlmon.dll");
|
|
if (hUrlmon)
|
|
{
|
|
COINTERNETCREATESECURITYMANAGER pcicsm;
|
|
|
|
pcicsm = (COINTERNETCREATESECURITYMANAGER) GetProcAddress(hUrlmon, "CoInternetCreateSecurityManager");
|
|
if (pcicsm)
|
|
pcicsm(NULL, &pSecMgr, NULL);
|
|
}
|
|
|
|
if ((javaPolicyData.pbJavaTrust == NULL) ||
|
|
(!javaPolicyData.pbJavaTrust->fAllActiveXPermissions) ||
|
|
(pSecMgr && SUCCEEDED(pSecMgr->MapUrlToZone(pwszURL, &dwZone, 0)) && dwZone == URLZONE_LOCAL_MACHINE && FAILED(javaPolicyData.pbJavaTrust->hVerify)))
|
|
hr = TRUST_E_FAIL;
|
|
|
|
if (hUrlmon)
|
|
FreeLibrary(hUrlmon);
|
|
}
|
|
|
|
if (javaPolicyData.pbJavaTrust)
|
|
CoTaskMemFree(javaPolicyData.pbJavaTrust);
|
|
|
|
if(pwszURL)
|
|
CoTaskMemFree(pwszURL);
|
|
|
|
CloseHandle(hFile);
|
|
|
|
if (pSecMgr)
|
|
pSecMgr->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT WINAPI CheckTrust(LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI)
|
|
{
|
|
return CheckTrustEx(NULL, szFilename, hwndForUI, bShowBadUI, NULL);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
DWORD GetStringField(LPSTR szStr, UINT uField, LPSTR szBuf, UINT cBufSize)
|
|
{
|
|
LPSTR pszBegin = szStr;
|
|
LPSTR pszEnd;
|
|
UINT i = 0;
|
|
DWORD dwToCopy;
|
|
|
|
if(cBufSize == 0)
|
|
return 0;
|
|
|
|
szBuf[0] = 0;
|
|
|
|
if(szStr == NULL)
|
|
return 0;
|
|
|
|
while(*pszBegin != 0 && i < uField)
|
|
{
|
|
pszBegin = FindChar(pszBegin, ',');
|
|
if(*pszBegin != 0)
|
|
pszBegin++;
|
|
i++;
|
|
}
|
|
|
|
// we reached end of string, no field
|
|
if(*pszBegin == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
pszEnd = FindChar(pszBegin, ',');
|
|
while(pszBegin <= pszEnd && *pszBegin == ' ')
|
|
pszBegin++;
|
|
|
|
while(pszEnd > pszBegin && *(pszEnd - 1) == ' ')
|
|
pszEnd--;
|
|
|
|
if(pszEnd > (pszBegin + 1) && *pszBegin == '"' && *(pszEnd-1) == '"')
|
|
{
|
|
pszBegin++;
|
|
pszEnd--;
|
|
}
|
|
|
|
dwToCopy = (DWORD)(pszEnd - pszBegin + 1);
|
|
|
|
if(dwToCopy > cBufSize)
|
|
dwToCopy = cBufSize;
|
|
|
|
lstrcpynA(szBuf, pszBegin, dwToCopy);
|
|
|
|
return dwToCopy - 1;
|
|
}
|
|
|
|
DWORD GetIntField(LPSTR szStr, UINT uField, DWORD dwDefault)
|
|
{
|
|
char szNumBuf[16];
|
|
|
|
if(GetStringField(szStr, uField, szNumBuf, sizeof(szNumBuf)) == 0)
|
|
return dwDefault;
|
|
else
|
|
return AtoL(szNumBuf);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPSTR BuildDependencyString(LPSTR pszName,LPSTR pszOwner)
|
|
{
|
|
LPSTR pszRet = NULL;
|
|
|
|
if(pszOwner)
|
|
{
|
|
char szBuf[128];
|
|
LoadSz(IDS_DEPENDNAME, szBuf, sizeof(szBuf));
|
|
pszRet = new char[lstrlenA(pszName) + lstrlenA(szBuf) + lstrlenA(pszOwner) + 25];
|
|
if(pszRet)
|
|
wsprintf(pszRet, szBuf, pszName, pszOwner);
|
|
}
|
|
else
|
|
{
|
|
pszRet = new char[lstrlenA(pszName) + 1];
|
|
if(pszRet)
|
|
lstrcpyA(pszRet, pszName);
|
|
}
|
|
|
|
return pszRet;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPWSTR ParseURLW(BSTR str)
|
|
{
|
|
LPWSTR pwszTemp;
|
|
|
|
if(str == NULL || *str == '\0')
|
|
return NULL;
|
|
|
|
pwszTemp = str + SysStringLen(str) - 1;
|
|
while(pwszTemp >= str && *pwszTemp != '\\' && *pwszTemp != '/')
|
|
pwszTemp--;
|
|
|
|
return pwszTemp + 1;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPSTR ParseURLA(LPCSTR str)
|
|
{
|
|
LPSTR pszTemp;
|
|
|
|
if(str == NULL || *str == '\0')
|
|
return NULL;
|
|
|
|
pszTemp = (LPSTR)str + lstrlen(str) - 1;
|
|
while(pszTemp >= str && *pszTemp != '\\' && *pszTemp != '/')
|
|
pszTemp--;
|
|
|
|
return pszTemp + 1;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPSTR MakeAnsiStrFromAnsi(LPSTR psz)
|
|
{
|
|
LPSTR pszTmp;
|
|
|
|
if(psz == NULL)
|
|
return NULL;
|
|
|
|
pszTmp = (LPSTR) CoTaskMemAlloc(lstrlenA(psz) + 1);
|
|
if(pszTmp)
|
|
lstrcpyA(pszTmp, psz);
|
|
|
|
return pszTmp;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPSTR CopyAnsiStr(LPCSTR psz)
|
|
{
|
|
LPSTR pszTmp;
|
|
|
|
if(psz == NULL)
|
|
return NULL;
|
|
|
|
pszTmp = (LPSTR) new char[lstrlenA(psz) + 1];
|
|
if(pszTmp)
|
|
lstrcpyA(pszTmp, psz);
|
|
|
|
return pszTmp;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
BOOL DeleteKeyAndSubKeys(HKEY hkIn, LPSTR pszSubKey)
|
|
{
|
|
HKEY hk;
|
|
TCHAR szTmp[MAX_PATH];
|
|
DWORD dwTmpSize;
|
|
long l;
|
|
BOOL f;
|
|
|
|
l = RegOpenKeyEx(hkIn, pszSubKey, 0, KEY_READ | KEY_WRITE, &hk);
|
|
if (l != ERROR_SUCCESS) return FALSE;
|
|
|
|
// loop through all subkeys, blowing them away.
|
|
//
|
|
f = TRUE;
|
|
while (f) {
|
|
dwTmpSize = MAX_PATH;
|
|
l = RegEnumKeyEx(hk, 0, szTmp, &dwTmpSize, 0, NULL, NULL, NULL);
|
|
if (l != ERROR_SUCCESS) break;
|
|
f = DeleteKeyAndSubKeys(hk, szTmp);
|
|
}
|
|
|
|
// there are no subkeys left, [or we'll just generate an error and return FALSE].
|
|
// let's go blow this dude away.
|
|
//
|
|
RegCloseKey(hk);
|
|
l = RegDeleteKey(hkIn, pszSubKey);
|
|
|
|
return (l == ERROR_SUCCESS) ? TRUE : FALSE;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
int StringFromGuid(const CLSID* piid, LPTSTR pszBuf)
|
|
{
|
|
return wsprintf(pszBuf, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
|
|
piid->Data1, piid->Data2, piid->Data3, piid->Data4[0], piid->Data4[1],
|
|
piid->Data4[2],piid->Data4[3], piid->Data4[4], piid->Data4[5],
|
|
piid->Data4[6], piid->Data4[7]);
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
// Function name here
|
|
//=--------------------------------------------------------------------------=
|
|
// Function description
|
|
//
|
|
// Parameters:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
|
|
LPWSTR MakeWideStrFromAnsi(LPSTR psz, BYTE bType)
|
|
{
|
|
LPWSTR pwsz;
|
|
int i;
|
|
|
|
// arg checking.
|
|
//
|
|
if (!psz)
|
|
return NULL;
|
|
|
|
// compute the length of the required BSTR
|
|
//
|
|
i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
|
|
if (i <= 0) return NULL;
|
|
|
|
// allocate the widestr
|
|
//
|
|
switch (bType) {
|
|
case STR_BSTR:
|
|
// -1 since it'll add it's own space for a NULL terminator
|
|
//
|
|
pwsz = (LPWSTR) SysAllocStringLen(NULL, i - 1);
|
|
break;
|
|
case STR_OLESTR:
|
|
pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!pwsz) return NULL;
|
|
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
|
|
pwsz[i - 1] = 0;
|
|
return pwsz;
|
|
}
|
|
|
|
#define UNINSTALL_BRANCH "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
|
|
|
|
|
|
BOOL UninstallKeyExists(LPCSTR pszUninstallKey)
|
|
{
|
|
HKEY hUninstallKey = NULL;
|
|
char szUninstallStr[512];
|
|
|
|
if (!pszUninstallKey) // If the pointer is NULL, assume installed
|
|
return TRUE;
|
|
|
|
lstrcpyA(szUninstallStr, UNINSTALL_BRANCH);
|
|
lstrcatA(szUninstallStr, "\\");
|
|
lstrcatA(szUninstallStr, pszUninstallKey);
|
|
|
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, szUninstallStr, 0, KEY_READ,
|
|
&hUninstallKey) == ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hUninstallKey);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
void AddTempToLikelyExtractDrive(DWORD dwTempDLSpace, DWORD dwTempExSpace,
|
|
char chInstallDrive, char chDownloadDrive,
|
|
DWORD *pdwWinDirReq, DWORD *pdwInsDirReq,
|
|
DWORD *pdwDownloadDirReq)
|
|
{
|
|
DWORD dwExNeeded, dwNeeded;
|
|
DWORD dwVolFlags, dwCompressFactor;
|
|
char szRoot[4];
|
|
DWORD dwInsDirNeeded = dwTempDLSpace + dwTempExSpace;
|
|
DWORD dwInstallDriveCompress = 10;
|
|
|
|
lstrcpy(szRoot, "A:\\");
|
|
while ( szRoot[0] <= 'Z' )
|
|
{
|
|
if (!IsUsableDrive( szRoot ) )
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
if(!GetVolumeInformation(szRoot, NULL, 0, NULL, NULL, &dwVolFlags, NULL, 0))
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
if(dwVolFlags & FS_VOL_IS_COMPRESSED)
|
|
{
|
|
dwCompressFactor = 19;
|
|
if(szRoot[0] == chInstallDrive)
|
|
dwInstallDriveCompress = 19;
|
|
}
|
|
else
|
|
dwCompressFactor = 10;
|
|
// Decide how much we need if we extract to this drive
|
|
dwExNeeded = (dwTempDLSpace * dwCompressFactor)/10 + dwTempExSpace;
|
|
|
|
dwNeeded = 0;
|
|
// if the install dir, add what is going to install dir
|
|
if(szRoot[0] == chInstallDrive)
|
|
dwNeeded += *pdwInsDirReq;
|
|
// if it is the windows dir, add what goes to win dir
|
|
if(szRoot[0] == g_szWindowsDir[0])
|
|
dwNeeded += *pdwWinDirReq;
|
|
|
|
// BUGBUG: compression on this guy?
|
|
if(szRoot[0] == chDownloadDrive)
|
|
dwNeeded += ((*pdwDownloadDirReq * dwCompressFactor)/10);
|
|
|
|
dwNeeded += dwExNeeded;
|
|
// if this drive has enough bump Req if appropiate
|
|
if(IsEnoughSpace(szRoot, dwNeeded ))
|
|
{
|
|
if(szRoot[0] == chInstallDrive)
|
|
{
|
|
*pdwInsDirReq += dwExNeeded;
|
|
}
|
|
else if(szRoot[0] == chDownloadDrive)
|
|
*pdwDownloadDirReq += dwExNeeded;
|
|
else if(szRoot[0] == g_szWindowsDir[0])
|
|
*pdwWinDirReq += dwExNeeded;
|
|
|
|
return;
|
|
}
|
|
szRoot[0]++;
|
|
}
|
|
// if we get here, NO drive has enough space.
|
|
// Add to install dir here
|
|
*pdwInsDirReq += (dwTempDLSpace * dwCompressFactor)/10 + dwTempExSpace;
|
|
}
|
|
|
|
|
|
#define INSTALLCHECK_VALUE 0
|
|
#define INSTALLCHECK_DATA 1
|
|
#define INSTALLCHECK_NOTSUPPORTED 2
|
|
// If you change the string below you also have to tell all clients which use this feature to change.
|
|
// The clients are writing there success values under this key.
|
|
#define REGSTR_SUCCESS_KEY "Software\\Microsoft\\Active Setup\\Install Check"
|
|
BOOL SuccessCheck(LPSTR pszSuccessKey)
|
|
{
|
|
HKEY hKey = NULL;
|
|
char szRegKey[512];
|
|
char szRegData[512];
|
|
DWORD dwSize;
|
|
BOOL bInstalledSuccessfull = FALSE;
|
|
|
|
if (!pszSuccessKey) // If the pointer is NULL, assume installed
|
|
return TRUE;
|
|
|
|
if (GetStringField(pszSuccessKey, INSTALLCHECK_NOTSUPPORTED, szRegKey, sizeof(szRegKey)))
|
|
return FALSE; // This format is not yet supported
|
|
|
|
if (GetStringField(pszSuccessKey, INSTALLCHECK_VALUE, szRegKey, sizeof(szRegKey)) == 0)
|
|
return TRUE; // There is not Registry value to check for. Assume OK
|
|
|
|
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_SUCCESS_KEY, 0, KEY_READ,
|
|
&hKey) == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(szRegData);
|
|
if (RegQueryValueEx(hKey, szRegKey, NULL, NULL, (LPBYTE)szRegData, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
bInstalledSuccessfull = TRUE;
|
|
// If a data filed is specified, check if the value data compare
|
|
if (GetStringField(pszSuccessKey, INSTALLCHECK_DATA, szRegKey, sizeof(szRegKey)))
|
|
{
|
|
bInstalledSuccessfull = (lstrcmpi(szRegKey, szRegData) == 0);
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
return bInstalledSuccessfull;
|
|
}
|
|
|
|
|
|
DWORD WaitForEvent(HANDLE hEvent, HWND hwnd)
|
|
{
|
|
BOOL fQuit = FALSE;
|
|
BOOL fDone = FALSE;
|
|
DWORD dwRet;
|
|
while(!fQuit && !fDone)
|
|
{
|
|
dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE,
|
|
INFINITE, QS_ALLINPUT);
|
|
// Give abort the highest priority
|
|
if(dwRet == WAIT_OBJECT_0)
|
|
{
|
|
fDone = TRUE;
|
|
}
|
|
else
|
|
{
|
|
MSG msg;
|
|
// read all of the messages in this next loop
|
|
// removing each message as we read it
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
if(!hwnd || !IsDialogMessage(hwnd, &msg))
|
|
{
|
|
// if it's a quit message we're out of here
|
|
if (msg.message == WM_QUIT)
|
|
fQuit = TRUE;
|
|
else
|
|
{
|
|
// otherwise dispatch it
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
} // end of PeekMessage while loop
|
|
}
|
|
}
|
|
}
|
|
return (fQuit ? EVENTWAIT_QUIT : EVENTWAIT_DONE);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If .CIF command switch has #W or #w, expand it to Windows directory. Otherwise, do nothing.
|
|
// Input: lpBuf : the original switches
|
|
// dwSize : buffer size
|
|
// Outout: lpBuf : expanded switches
|
|
//
|
|
void ExpandString( LPSTR lpBuf, DWORD dwSize )
|
|
{
|
|
LPSTR pTmp, pTmp1;
|
|
char ch;
|
|
|
|
if ( !lpBuf || !*lpBuf || !dwSize )
|
|
return;
|
|
|
|
pTmp = ANSIStrChr( lpBuf, '#' );
|
|
if ( pTmp )
|
|
{
|
|
pTmp1 = CharNext( pTmp );
|
|
ch = (char)CharUpper((LPSTR) *pTmp1);
|
|
if ( ch == 'W' )
|
|
{
|
|
PSTR pTmpBuf;
|
|
|
|
// #W... => <WindowsDir>...
|
|
if ( dwSize < (DWORD)( lstrlen(lpBuf) + lstrlen(g_szWindowsDir) - 1 ) )
|
|
return; // should never be here
|
|
|
|
pTmpBuf = (LPSTR)LocalAlloc( LPTR, dwSize );
|
|
if ( pTmpBuf )
|
|
{
|
|
*pTmp = '\0';
|
|
lstrcpy( pTmpBuf, lpBuf );
|
|
lstrcat( pTmpBuf, g_szWindowsDir );
|
|
lstrcat( pTmpBuf, CharNext(pTmp1) );
|
|
// re-set the output string
|
|
lstrcpy( lpBuf, pTmpBuf );
|
|
|
|
LocalFree( pTmpBuf );
|
|
}
|
|
}
|
|
else if ( ch == '#' )
|
|
{
|
|
// ##... => #...
|
|
MoveMemory( pTmp, pTmp1, lstrlen(pTmp1)+1 );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void DeleteFilelist(LPCSTR pszFilelist)
|
|
{
|
|
LPSTR pszSections, pszSectionsPreFail, pszTemp;
|
|
DWORD dwSize = ALLOC_CHUNK_SIZE;
|
|
DWORD dwRead;
|
|
// Get a list of all sections
|
|
//
|
|
// BUGBUG: Write this so only one call to GetPrivateProfile exists
|
|
pszSections = (LPSTR) malloc(dwSize);
|
|
|
|
// Bail out if no memory
|
|
if(!pszSections)
|
|
return;
|
|
|
|
dwRead = GetPrivateProfileStringA(NULL, NULL, "", pszSections, dwSize, pszFilelist);
|
|
while( dwRead >= (dwSize - 2) )
|
|
{
|
|
dwSize += ALLOC_CHUNK_SIZE;
|
|
pszSectionsPreFail = pszSections;
|
|
#pragma prefast(suppress: 308, "Noise - pointer was saved")
|
|
pszSections = (LPSTR) realloc(pszSections, dwSize);
|
|
if(!pszSections)
|
|
{
|
|
free(pszSectionsPreFail);
|
|
dwRead = 0;
|
|
break;
|
|
}
|
|
dwRead = GetPrivateProfileStringA(NULL, NULL, "", pszSections, dwSize, pszFilelist);
|
|
}
|
|
|
|
pszTemp = pszSections;
|
|
dwSize = lstrlenA(pszTemp);
|
|
while(dwSize != 0)
|
|
{
|
|
WritePrivateProfileSection(pszTemp, NULL, pszFilelist);
|
|
|
|
pszTemp += (dwSize + 1);
|
|
dwSize = lstrlenA(pszTemp);
|
|
}
|
|
|
|
free(pszSections);
|
|
}
|
|
|
|
|
|
BOOL WaitForMutex(HANDLE hMutex)
|
|
{
|
|
BOOL fQuit = FALSE;
|
|
|
|
while (MsgWaitForMultipleObjects(1, &hMutex, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
|
|
{
|
|
MSG msg;
|
|
|
|
while (!fQuit && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
if (msg.message == WM_QUIT)
|
|
fQuit = TRUE;
|
|
else
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
return fQuit;
|
|
}
|
|
|
|
BOOL IsNT()
|
|
{
|
|
static int st_IsNT = 0xffff;
|
|
|
|
if(st_IsNT == 0xffff)
|
|
{
|
|
OSVERSIONINFO verinfo; // Version Check
|
|
|
|
verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if ( GetVersionEx( &verinfo ) != FALSE )
|
|
{
|
|
if( verinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
|
|
st_IsNT = 0;
|
|
else if ( verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
|
|
st_IsNT = 1;
|
|
}
|
|
}
|
|
|
|
return (st_IsNT == 1) ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
HINSTANCE InitSetupLib(LPCSTR pszInfName, HINF *phinf)
|
|
{
|
|
HINSTANCE hInst = NULL;
|
|
*phinf = NULL;
|
|
|
|
if( IsNT() )
|
|
{
|
|
hInst = LoadLibrary("setupapi.dll");
|
|
OpenINFEngine( pszInfName, NULL, 0, phinf, NULL );
|
|
}
|
|
else
|
|
{
|
|
hInst = LoadLibrary("w95inf32.dll");
|
|
}
|
|
return hInst;
|
|
}
|
|
|
|
void FreeSetupLib(HINSTANCE hInst, HINF hInf)
|
|
{
|
|
if(hInf)
|
|
CloseINFEngine(hInf);
|
|
if(hInst)
|
|
FreeLibrary(hInst);
|
|
}
|
|
|
|
HRESULT MyTranslateInfString( PCSTR pszInfFilename, PCSTR pszInstallSection,
|
|
PCSTR pszTranslateSection, PCSTR pszTranslateKey,
|
|
PSTR pszBuffer, DWORD dwBufferSize,
|
|
PDWORD pdwRequiredSize, HINF hInf )
|
|
{
|
|
HRESULT hr;
|
|
if(IsNT() && hInf)
|
|
{
|
|
hr = TranslateInfStringEx( hInf, pszInfFilename, pszTranslateSection, pszTranslateKey,
|
|
pszBuffer, dwBufferSize,
|
|
pdwRequiredSize, NULL );
|
|
}
|
|
else
|
|
{
|
|
hr = TranslateInfString( pszInfFilename, pszInstallSection, pszTranslateSection, pszTranslateKey,
|
|
pszBuffer, dwBufferSize,
|
|
pdwRequiredSize, NULL);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
#define UNUSED_STRING "xxx"
|
|
|
|
HRESULT MyTranslateString( LPCSTR pszCif, LPCSTR pszID, LPCSTR pszTranslateKey,
|
|
LPSTR pszBuffer, DWORD dwBufferSize)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
char szTemp[512];
|
|
|
|
if(GetPrivateProfileString(pszID, pszTranslateKey, "", pszBuffer, dwBufferSize, pszCif))
|
|
{
|
|
//bad code
|
|
DWORD dwLen = lstrlen(pszBuffer);
|
|
if(dwLen > 2)
|
|
{
|
|
// Cut the last %, and then look up in string section
|
|
if(pszBuffer[0] == '%' && pszBuffer[dwLen - 1] == '%')
|
|
{
|
|
pszBuffer[dwLen - 1] = 0;
|
|
GetPrivateProfileString("Strings", pszBuffer + 1, UNUSED_STRING, szTemp, sizeof(szTemp), pszCif);
|
|
if(lstrcmp(UNUSED_STRING, szTemp) != 0)
|
|
lstrcpyn(pszBuffer, szTemp, dwBufferSize);
|
|
else
|
|
pszBuffer[dwLen - 1] = '%';
|
|
}
|
|
}
|
|
hr = NOERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// add the quotes around the string
|
|
DWORD MyWritePrivateProfileString( LPCSTR pszSec, LPCSTR pszKey, LPCSTR pszData, LPCSTR pszFile)
|
|
{
|
|
LPSTR pszBuf;
|
|
DWORD dwOut = 0;
|
|
|
|
pszBuf = (LPSTR)LocalAlloc( LPTR, lstrlen(pszData)+8 );
|
|
if ( !pszBuf )
|
|
return dwOut;
|
|
|
|
lstrcpy( pszBuf, "\"" );
|
|
lstrcat( pszBuf, pszData );
|
|
lstrcat( pszBuf, "\"" );
|
|
|
|
dwOut = WritePrivateProfileString(pszSec, pszKey, pszBuf, pszFile);
|
|
|
|
LocalFree(pszBuf);
|
|
return dwOut;
|
|
}
|
|
|
|
HRESULT WriteTokenizeString(LPCSTR pszCif, LPCSTR pszID, LPCSTR pszTranslateKey, LPCSTR pszBuffer)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
char szTemp[MAX_PATH];
|
|
LPCSTR pszKeyname, pszSecname;
|
|
|
|
pszKeyname = pszTranslateKey;
|
|
pszSecname = pszID;
|
|
if(GetPrivateProfileString(pszID, pszTranslateKey, "", szTemp, sizeof(szTemp), pszCif))
|
|
{
|
|
//bad code
|
|
DWORD dwLen = lstrlen(szTemp);
|
|
if(dwLen > 2)
|
|
{
|
|
// Cut the last %, and then look up in string section
|
|
if(szTemp[0] == '%' && szTemp[dwLen - 1] == '%')
|
|
{
|
|
szTemp[dwLen - 1] = 0;
|
|
pszKeyname = &szTemp[1];
|
|
pszSecname = "strings";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (MyWritePrivateProfileString(pszSecname, pszKeyname, pszBuffer, pszCif))
|
|
hr = NOERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HWND GetVersionConflictHWND()
|
|
{
|
|
char szBuf[256];
|
|
|
|
LoadSz(IDS_VERSIONCONFLICT, szBuf, sizeof(szBuf));
|
|
HWND hVersionConflict = FindWindowEx(NULL, NULL, (LPCSTR)
|
|
SEARCHFORCONFLICT_CLASS, szBuf );
|
|
if(!hVersionConflict)
|
|
{
|
|
LoadSz(IDS_VERSIONCONFLICTNT, szBuf, sizeof(szBuf));
|
|
hVersionConflict = FindWindowEx(NULL, NULL, (LPCSTR)
|
|
SEARCHFORCONFLICT_CLASS, szBuf );
|
|
}
|
|
return hVersionConflict;
|
|
}
|
|
|
|
HRESULT WINAPI CheckForVersionConflict()
|
|
{
|
|
HWND hVersionConflict = GetVersionConflictHWND();
|
|
|
|
if(hVersionConflict)
|
|
BOOL foo = SetForegroundWindow(hVersionConflict);
|
|
return S_OK;
|
|
}
|
|
|
|
int CompareLocales(LPCSTR pcszLoc1, LPCSTR pcszLoc2)
|
|
{
|
|
int ret;
|
|
|
|
if(pcszLoc1[0] == '*' || pcszLoc2[0] == '*')
|
|
ret = 0;
|
|
else
|
|
ret = lstrcmpi(pcszLoc1, pcszLoc2);
|
|
|
|
return ret;
|
|
}
|
|
|
|
HRESULT CreateTempDirOnMaxDrive(LPSTR pszDir, DWORD dwBufSize)
|
|
{
|
|
char szRoot[] = "A:\\";
|
|
char szDownloadDrive[] = "?:\\";
|
|
char szDir[MAX_PATH];
|
|
char szUnique[MAX_PATH];
|
|
DWORD dwMaxFree = 0;
|
|
DWORD dwDriveFree;
|
|
|
|
if(pszDir)
|
|
pszDir[0] = 0;
|
|
|
|
// Check all loacle drives for diskspace and take the one with the most.
|
|
while ( szRoot[0] <= 'Z' )
|
|
{
|
|
|
|
// even the drive type is OK, verify the drive has valid connection
|
|
//
|
|
if (!IsUsableDrive( szRoot ) )
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
|
|
|
|
if(!IsDirWriteable(szRoot))
|
|
{
|
|
szRoot[0]++;
|
|
continue;
|
|
}
|
|
|
|
dwDriveFree = GetSpace(szRoot);
|
|
|
|
if (dwDriveFree > dwMaxFree)
|
|
{
|
|
dwMaxFree = dwDriveFree;
|
|
szDownloadDrive[0] = szRoot[0];
|
|
}
|
|
szRoot[0]++;
|
|
|
|
}
|
|
if(szDownloadDrive[0] == '?')
|
|
return E_FAIL;
|
|
|
|
lstrcpy(szDir, szDownloadDrive);
|
|
|
|
// if our suitable drive happens also to be the windows drive,
|
|
// create msdownld.tmp of of it.
|
|
if(szDownloadDrive[0] == g_szWindowsDir[0])
|
|
lstrcpy(szDir, g_szWindowsDir);
|
|
|
|
AddPath( szDir, MSDOWNLOAD );
|
|
|
|
if ( !IfNotExistCreateDir( szDir, TRUE, TRUE) )
|
|
return E_FAIL;
|
|
|
|
//
|
|
if ( !GetUniqueFileName(szDir,"AS", 0, szUnique) )
|
|
return E_FAIL;
|
|
|
|
lstrcpy(szDir, szUnique);
|
|
|
|
if ( !IfNotExistCreateDir( szDir, FALSE, FALSE) )
|
|
return E_FAIL;
|
|
|
|
AddPath( szDir, "" );
|
|
|
|
if ( (DWORD) lstrlen(szDir)+1 > dwBufSize )
|
|
return ( E_INVALIDARG );
|
|
|
|
// success
|
|
lstrcpy( pszDir, szDir );
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
* enabled or restores Sage
|
|
* bRestore TRUE means restore, otherwise disable
|
|
*/
|
|
void EnableSage(BOOL bRestore)
|
|
{
|
|
//MBD 6-22: MUST USE stdcall convention when accessing sage.dll
|
|
typedef long (__stdcall *PFNDLL)(int);
|
|
|
|
HINSTANCE hSageAPI;
|
|
PFNDLL pfnSageEnable;
|
|
static int restore = ENABLE_AGENT; //initialize to valid value...
|
|
|
|
hSageAPI = LoadLibrary("SAGE.DLL");
|
|
if (hSageAPI != NULL)
|
|
{
|
|
pfnSageEnable = (PFNDLL) GetProcAddress(hSageAPI,"System_Agent_Enable");
|
|
if(pfnSageEnable)
|
|
{
|
|
if(bRestore)
|
|
{
|
|
(pfnSageEnable)(restore);
|
|
}
|
|
else
|
|
{
|
|
if(ENABLE_AGENT == (restore = (pfnSageEnable)(GET_AGENT_STATUS)))
|
|
{
|
|
(pfnSageEnable)(DISABLE_AGENT);
|
|
}
|
|
}
|
|
}
|
|
FreeLibrary(hSageAPI);
|
|
}
|
|
}
|
|
|
|
void EnableScreenSaver(BOOL bRestore)
|
|
{
|
|
static BOOL bScreenSaver = FALSE;
|
|
if (bRestore)
|
|
{
|
|
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, bScreenSaver, 0 , 0);
|
|
bScreenSaver = FALSE; // reset the static to be able to disable the screensaver again.
|
|
}
|
|
else
|
|
{
|
|
// Only if the static is false call this again,
|
|
// otherwise we did call this function already.
|
|
if (!bScreenSaver)
|
|
{
|
|
SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, FALSE, &bScreenSaver, 0);
|
|
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0 , 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnableDiskCleaner(BOOL bRestore)
|
|
{
|
|
static HANDLE hDiskCleaner = NULL;
|
|
if (bRestore)
|
|
{
|
|
if (hDiskCleaner)
|
|
{
|
|
CloseHandle(hDiskCleaner);
|
|
hDiskCleaner = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hDiskCleaner = CreateEvent(NULL, FALSE, FALSE, "DisableLowDiskWarning");
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
typedef HRESULT (WINAPI *COINTERNETCREATESECURITYMANAGER) ( IServiceProvider *pSP, IInternetSecurityManager **ppSM, DWORD dwReserved);
|
|
|
|
DWORD IsUrlSaveToDownloadFrom(LPSTR lpszURL)
|
|
{
|
|
HRESULT hr;
|
|
BOOL bOK = FALSE;
|
|
DWORD dwPolicy = URLPOLICY_QUERY; // In the default case we do checktrust
|
|
HINSTANCE hUrlmon;
|
|
COINTERNETCREATESECURITYMANAGER pcicsm;
|
|
|
|
hUrlmon = LoadLibrary("urlmon.dll");
|
|
if (hUrlmon)
|
|
{
|
|
pcicsm = (COINTERNETCREATESECURITYMANAGER) GetProcAddress(hUrlmon, "CoInternetCreateSecurityManager");
|
|
if (pcicsm)
|
|
{
|
|
IInternetSecurityManager *InternetSecurityManager;
|
|
LPWSTR lpwszURL = NULL;
|
|
DWORD dwSize;
|
|
hr = pcicsm(NULL, &InternetSecurityManager, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dwSize = sizeof(dwPolicy);
|
|
lpwszURL = MakeWideStrFromAnsi(lpszURL, STR_OLESTR);
|
|
hr = InternetSecurityManager->ProcessUrlAction(lpwszURL,
|
|
URLACTION_DOWNLOAD_SIGNED_ACTIVEX,
|
|
(BYTE*)&dwPolicy, dwSize, NULL, NULL, PUAF_NOUI, NULL);
|
|
wsprintf(szLogBuf, "InternetSecurityManager->ProcessUrlAction on :%s: Policy :%ld:", lpszURL, dwPolicy);
|
|
MessageBox(NULL, szLogBuf, "TEST", MB_OK| MB_SETFOREGROUND);
|
|
if (GetUrlPolicyPermissions(dwPolicy) != URLPOLICY_ALLOW)
|
|
{
|
|
hr = InternetSecurityManager->ProcessUrlAction(lpwszURL,
|
|
URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX,
|
|
(BYTE*)&dwPolicy, dwSize, NULL, NULL, PUAF_NOUI, NULL);
|
|
wsprintf(szLogBuf, "InternetSecurityManager->ProcessUrlAction on :%s: Policy :%ld:", lpszURL, dwPolicy);
|
|
MessageBox(NULL, szLogBuf, "TEST", MB_OK| MB_SETFOREGROUND);
|
|
}
|
|
if (lpwszURL)
|
|
CoTaskMemFree(lpwszURL);
|
|
InternetSecurityManager->Release();
|
|
}
|
|
}
|
|
FreeLibrary(hUrlmon);
|
|
}
|
|
return dwPolicy;
|
|
}
|
|
#endif
|
|
|
|
BOOL PathIsFileSpec(LPCSTR lpszPath)
|
|
{
|
|
for (; *lpszPath; lpszPath = CharNext(lpszPath)) {
|
|
if (*lpszPath == '\\' || *lpszPath == ':')
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
const char c_gszRegstrPathIExplore[] = REGSTR_PATH_APPPATHS "\\iexplore.exe";
|
|
|
|
HRESULT GetIEPath(LPSTR pszPath, DWORD dwSize)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
UINT i;
|
|
DWORD dwType;
|
|
HKEY hKey;
|
|
|
|
// findout where ie is, append on cif name
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_gszRegstrPathIExplore, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
if ((RegQueryValueEx(hKey, NULL, 0, &dwType, (LPBYTE)pszPath, &dwSize) == ERROR_SUCCESS) &&
|
|
(dwType == REG_SZ))
|
|
{
|
|
GetParentDir(pszPath);
|
|
}
|
|
else
|
|
hr = E_INVALIDARG;
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
DWORD MyGetFileSize(LPCSTR pszFilename)
|
|
{
|
|
DWORD dwSize;
|
|
WIN32_FIND_DATA fileData;
|
|
HANDLE hFindFile;
|
|
dwSize = 0;
|
|
hFindFile = FindFirstFile( pszFilename, &fileData );
|
|
|
|
if ( hFindFile != INVALID_HANDLE_VALUE )
|
|
{
|
|
if (fileData.nFileSizeHigh == 0)
|
|
dwSize = fileData.nFileSizeLow;
|
|
else
|
|
dwSize = (DWORD)-1;
|
|
FindClose( hFindFile );
|
|
}
|
|
return dwSize;
|
|
}
|
|
|
|
WORD GetNTProcessorArchitecture(void)
|
|
{
|
|
static WORD wNTProcArch = -1 ;
|
|
SYSTEM_INFO System_info;
|
|
|
|
// If we have calculated this before just pass that back.
|
|
// else find it now.
|
|
//
|
|
if (wNTProcArch == (WORD)-1)
|
|
{
|
|
GetSystemInfo(&System_info);
|
|
wNTProcArch = System_info.wProcessorArchitecture;
|
|
}
|
|
|
|
return wNTProcArch;
|
|
}
|
|
|
|
DWORD GetCurrentPlatform()
|
|
{
|
|
static DWORD dwPlatform = 0xffffffff;
|
|
|
|
if(dwPlatform != 0xffffffff)
|
|
return dwPlatform;
|
|
|
|
OSVERSIONINFO VerInfo;
|
|
|
|
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
GetVersionEx(&VerInfo);
|
|
|
|
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
// Running NT
|
|
if (GetNTProcessorArchitecture() == PROCESSOR_ARCHITECTURE_ALPHA)
|
|
{
|
|
dwPlatform = PLATFORM_NT5ALPHA;
|
|
if (VerInfo.dwMajorVersion == 4)
|
|
dwPlatform = PLATFORM_NT4ALPHA;
|
|
}
|
|
else
|
|
{
|
|
dwPlatform = PLATFORM_NT5;
|
|
if (VerInfo.dwMajorVersion == 4)
|
|
dwPlatform = PLATFORM_NT4;
|
|
}
|
|
}
|
|
else
|
|
{ // Running Windows 9x
|
|
dwPlatform = PLATFORM_WIN98;
|
|
if (VerInfo.dwMinorVersion == 0)
|
|
dwPlatform = PLATFORM_WIN95;
|
|
else if (VerInfo.dwMinorVersion == 90)
|
|
dwPlatform = PLATFORM_MILLEN;
|
|
}
|
|
return dwPlatform;
|
|
}
|
|
|
|
BOOL FNeedGrpConv()
|
|
{
|
|
char szSetupIni[MAX_PATH];
|
|
|
|
if(GetWindowsDirectory(szSetupIni, sizeof(szSetupIni)))
|
|
{
|
|
AddPath(szSetupIni, "setup.ini");
|
|
return(GetFileAttributes(szSetupIni) != 0xffffffff);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CopyCifString(LPCSTR pcszSect, LPCSTR pcszKey, LPCSTR pcszCifSrc, LPCSTR pcszCifDest)
|
|
{
|
|
char szField[MAX_PATH];
|
|
char szString[MAX_PATH];
|
|
LPSTR pszPercent;
|
|
|
|
if (GetPrivateProfileString(pcszSect, pcszKey, "", szField, sizeof(szField), pcszCifSrc)
|
|
&& (szField[0] == '%'))
|
|
{
|
|
pszPercent = ANSIStrChr(&szField[1], '%');
|
|
if (pszPercent)
|
|
{
|
|
*pszPercent = '\0';
|
|
GetPrivateProfileString("Strings", &szField[1], "", szString, sizeof(szString), pcszCifSrc);
|
|
WritePrivateProfileString("Strings", &szField[1], szString, pcszCifDest);
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Function to log the Date/Time stamp for each Component.
|
|
//---------------------------------------------------------
|
|
void GetTimeDateStamp(LPSTR lpLogBuf)
|
|
{
|
|
SYSTEMTIME SystemTime;
|
|
|
|
GetLocalTime(&SystemTime);
|
|
wsprintf(lpLogBuf, "Date:%d/%d/%d (M/D/Y) Time:%d:%d:%d",
|
|
SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,
|
|
SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
|
|
|
|
}
|
|
|
|
|
|
HRESULT WINAPI DownloadFile(LPCSTR szURL, LPCSTR szFilename, HWND hwnd, BOOL bCheckTrust, BOOL bShowBadUI)
|
|
{
|
|
HRESULT hr;
|
|
char szTempfile[MAX_PATH];
|
|
char szTemp[MAX_PATH];
|
|
|
|
CDownloader *pDL = new CDownloader();
|
|
|
|
if(!pDL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
hr = pDL->SetupDownload(szURL, NULL, 0, NULL);
|
|
szTempfile[0] = 0;
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = pDL->DoDownload(szTempfile, sizeof(szTempfile));
|
|
}
|
|
|
|
pDL->Release();
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if (bCheckTrust)
|
|
{
|
|
hr = ::CheckTrustEx(szURL, szTempfile, bShowBadUI?hwnd:(HWND)INVALID_HANDLE_VALUE, bShowBadUI, NULL);
|
|
}
|
|
|
|
if(!CopyFile(szTempfile, szFilename, FALSE))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
if(szTempfile[0] != 0)
|
|
{
|
|
GetParentDir(szTempfile);
|
|
CleanUpTempDir(szTempfile);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL IsPatchableINF(LPTSTR pszInf)
|
|
{
|
|
TCHAR szBuf[MAX_PATH];
|
|
|
|
if (GetPrivateProfileInt("DefaultInstall", "Patching", 0, pszInf) ||
|
|
GetPrivateProfileString("DownloadFileSection", NULL, "", szBuf, sizeof(szBuf), pszInf))
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
PFNGETFILELIST g_pfnGetFileList = NULL;
|
|
PFNDOWNLOADANDPATCHFILES g_pfnDownloadAndPatchFiles = NULL;
|
|
PFNPROCESSFILESECTION g_pfnProcessFileSection = NULL;
|
|
|
|
BOOL InitSRLiteLibs()
|
|
{
|
|
HINSTANCE hAdvpext = LoadLibrary(c_gszAdvpext);
|
|
|
|
if (hAdvpext == NULL)
|
|
return FALSE;
|
|
g_pfnGetFileList = (PFNGETFILELIST) GetProcAddress(hAdvpext, "GetFileList");
|
|
g_pfnDownloadAndPatchFiles = (PFNDOWNLOADANDPATCHFILES) GetProcAddress(hAdvpext, "DownloadAndPatchFiles");
|
|
g_pfnProcessFileSection = (PFNPROCESSFILESECTION) GetProcAddress(hAdvpext, "ProcessFileSection");
|
|
|
|
if (g_pfnGetFileList == NULL ||
|
|
g_pfnDownloadAndPatchFiles == NULL ||
|
|
g_pfnProcessFileSection == NULL
|
|
)
|
|
{
|
|
FreeLibrary(hAdvpext);
|
|
return FALSE;
|
|
}
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
void FreeSRLiteLibs()
|
|
{
|
|
HMODULE hMod;
|
|
|
|
hMod = GetModuleHandle(c_gszAdvpext);
|
|
if (hMod)
|
|
FreeLibrary(hMod);
|
|
}
|
|
|
|
// For now, we're patching on any IE5 version, so we might
|
|
// as well perform a check similar to ie5wzd
|
|
BOOL IsPatchableIEVersion()
|
|
{
|
|
char szIE[MAX_PATH] = { 0 };
|
|
DWORD dwMSVer, dwLSVer;
|
|
|
|
GetSystemDirectory(szIE, sizeof(szIE));
|
|
AddPath(szIE, "shdocvw.dll");
|
|
GetVersionFromFile(szIE, &dwMSVer, &dwLSVer, TRUE);
|
|
|
|
return (dwMSVer >= 0x00050000);
|
|
}
|
|
|
|
BOOL IsCorrectAdvpExt()
|
|
{
|
|
DWORD dwMSVer, dwLSVer;
|
|
|
|
GetVersionFromFile(c_gszAdvpext, &dwMSVer, &dwLSVer, TRUE);
|
|
|
|
return (dwMSVer >= 0x00050032);
|
|
}
|
|
|
|
BOOL CheckImageHlp_dll()
|
|
{
|
|
char szFile[MAX_PATH] = { 0 };
|
|
DWORD dwMSVer, dwLSVer;
|
|
|
|
GetSystemDirectory(szFile, sizeof(szFile));
|
|
AddPath(szFile, "imagehlp.dll");
|
|
GetVersionFromFile(szFile, &dwMSVer, &dwLSVer, TRUE);
|
|
|
|
return (!(dwMSVer == 0x00040000) || !(dwLSVer == 0x04C90001));
|
|
}
|