Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1711 lines
50 KiB

#include "pch.h"
#include "fixie.h"
HANDLE g_hHeap = NULL;
HWND g_hWnd = NULL;
HWND g_hProgress = NULL;
int g_nNumGuids = 0;
HRESULT g_hr = E_FAIL;
char g_szLogFileName[MAX_PATH];
LPSTORAGE g_pIStorage = NULL;
LPSTREAM g_pIStream = NULL;
DWORD g_dwPlatform = NULL;
LCIFCOMPONENT g_pLinkCif = NULL;
// #40352 - always repair the Icons. g_bRestoreIcons does not get changed anywhere else.
BOOL g_bRestoreIcons = TRUE;
BOOL g_bQuiet = FALSE;
BOOL g_bRunningWin95;
BOOL g_bNeedReboot = FALSE;
LPSTR g_pszError = NULL;
// Used for the progress bar
// start and end for each section (out of 100)
int g_nVerifyAllFilesStart = 0;
int g_nVerifyAllFilesEnd = 10;
int g_nRunSetupCommandPreROEXStart = 10;
int g_nRunSetupCommandPreROEXEnd = 11;
int g_nRunSetupCommandAllROEXStart = 11;
int g_nRunSetupCommandAllROEXEnd = 21;
int g_nDoRunOnceExProcessStart = 21;
int g_nDoRunOnceExProcessEnd = 80;
int g_nRunSetupCommandAllPostROEXStart = 80;
int g_nRunSetupCommandAllPostROEXEnd = 90;
int g_nRestoreIconsStart = 90;
int g_nRestoreIconsEnd = 100;
int g_nProgressStart = 0;
int g_nProgressEnd = 100;
const char c_gszRegstrPathIExplore[] = REGSTR_PATH_APPPATHS "\\iexplore.exe";
const char c_gszLogFileName[] = "Fix IE Log.txt";
char g_szFixIEInf[MAX_STRING];
const char c_gszFixIEInfName[] = "fixie.inf";
const char c_gszIERnOnceDLL[] = "iernonce.dll";
const char c_gszMainSectionName[] = "FixIE";
const char c_gszPreSectionName[] = "PreROEX";
const char c_gszRegRestoreIcons[] = "Software\\Microsoft\\Active Setup\\Installed Components";
char g_szModifiedMainSectionName[MAX_STRING];
char g_szCryptoSectionName[MAX_STRING];
const char c_gszWin95[] = "";
const char c_gszMillen[] = ".Millen";
const char c_gszNTx86[] = ".NT";
const char c_gszW2K[] = ".W2K";
const char c_gszNTalpha[] = ".Alpha";
const char c_gszCrypto[] = ".Crypto";
LPSTR MakeAnsiStrFromWide(LPWSTR pwsz);
LPWSTR MakeWideStrFromAnsi(LPSTR psz);
void ConvertIStreamToFile(LPSTORAGE *pIStorage, LPSTREAM *pIStream);
void MakePath(LPSTR lpPath);
void LogTimeDate();
HRESULT MyRunSetupCommand(HWND hwnd, LPCSTR lpszInfFile, LPCSTR lpszSection, DWORD dwFlags);
DWORD GetStringField(LPSTR szStr, UINT uField, LPSTR szBuf, UINT cBufSize);
LPSTR FindChar(LPSTR pszStr, char ch);
// Reboot stuff
BOOL MyNTReboot();
HRESULT LaunchProcess(LPCSTR pszCmd, HANDLE *phProc, LPCSTR pszDir, UINT uShow);
BOOL MyRestartDialog(HWND hParent, BOOL bShowPrompt, UINT nIdMessage);
VOID MyConvertVersionString(LPSTR lpszVersion, LPDWORD pdwMSVer, LPDWORD pdwLSVer);
VOID MyGetVersionFromFile(LPSTR lpszFilename, LPDWORD pdwMSVer, LPDWORD pdwLSVer);
int DisplayMessage(char* pszMessage, UINT uStyle);
int LoadSz(UINT id, LPSTR pszBuf, UINT cMaxSize);
VOID GetPlatform();
BOOL CheckForNT4_SP4();
VOID GetInfFile();
VOID AddComponent(ICifComponent *pCifComp);
VOID WriteToLog(char *pszFormatString, ...);
HRESULT InitComponentList();
HRESULT VerifyAllFiles();
HRESULT RunSetupCommandPreROEX();
HRESULT RunSetupCommandAllROEX();
HRESULT RunSetupCommandAllPostROEX();
HRESULT DoRunOnceExProcess();
HRESULT RestoreIcons();
HRESULT Process();
void AddRegMunger();
DWORD RunProcess(LPVOID lp);
INT_PTR CALLBACK DlgProcFixIE(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK DlgProcConfirm(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK DlgProcReinstall(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void uiCenterDialog( HWND hwndDlg );
void RunOnceExProcessCallback(int nCurrent, int nMax, LPSTR pszError);
void LogError(char *pszFormatString, ...);
void VersionToString(DWORD dwMSVer, DWORD dwLSVer, LPSTR pszVersion);
HRESULT FixIE(BOOL bConfirm, DWORD dwFlags)
{
HRESULT hr = S_OK;
HANDLE hMutex ;
OSVERSIONINFO VerInfo;
// allow only one instance running at a time
// ALSO : mutex wrt to IESetup.EXE. Hence use specific named mutex only
hMutex = CreateMutex(NULL, TRUE, "Ie4Setup.Mutext");
if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))
{
CloseHandle(hMutex);
return S_FALSE;
}
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&VerInfo);
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// If the user does not have Admin rights, bail out.
if ( !IsNTAdmin(0, NULL))
{
char szMsg[MAX_STRING];
LoadSz(IDS_NEED_ADMIN, szMsg, sizeof(szMsg));
DisplayMessage(szMsg, MB_OK|MB_ICONEXCLAMATION);
if (hMutex)
CloseHandle(hMutex);
return S_OK;
}
}
if (bConfirm)
{
if (DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_CONFIRM), NULL, DlgProcConfirm) == IDNO)
{
WriteToLog("\r\nUser selected not to repair.\r\n");
if (g_pIStream)
ConvertIStreamToFile(&g_pIStorage, &g_pIStream);
if (hMutex)
CloseHandle(hMutex);
return S_OK;
}
}
// #40352 - always repair Icons. No need to check if flag is set for it.
////////////////////////////////////////////////////////////////
// else
// {
// g_bRestoreIcons = dwFlags & FIXIE_ICONS;
// }
////////////////////////////////////////////////////////////////
if (g_bRestoreIcons)
{
WriteToLog("Restore icon set to true.\r\n");
}
else
{
WriteToLog("Restore icon set to false.\r\n");
}
if (dwFlags & FIXIE_QUIET)
{
g_bQuiet = TRUE;
WriteToLog("Quiet mode on.\r\n");
}
else
{
WriteToLog("Quiet mode off.\r\n");
}
// Get the heap - used for HeapAlloc and HeapReAlloc
g_hHeap = GetProcessHeap();
InitCommonControls();
GetPlatform();
WriteToLog("Main section name: %1\r\n",g_szModifiedMainSectionName);
// if running on NT5 or Millennium or
// If NT4-SP4, don't process the Crypto files else process them too.
if ( (g_dwPlatform == PLATFORM_MILLEN) || (g_dwPlatform == PLATFORM_NT5) ||
((g_dwPlatform == PLATFORM_NT4 || g_dwPlatform == PLATFORM_NT4ALPHA) && CheckForNT4_SP4()))
{
// Null string the Crypto section name
*g_szCryptoSectionName = '\0';
WriteToLog("No Crypto section to be processed!\r\n");
}
else
{
lstrcpy(g_szCryptoSectionName, c_gszMainSectionName);
lstrcat(g_szCryptoSectionName, c_gszCrypto);
WriteToLog("Crypto section name: %1\r\n",g_szCryptoSectionName);
}
GetInfFile();
WriteToLog("Inf file used: %1\r\n",g_szFixIEInf);
WriteToLog("\r\nFixIE started.\r\n\r\n");
if (!g_bQuiet)
{
if (DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_FIXIE), NULL, DlgProcFixIE) == -1)
{
WriteToLog("\r\nERROR - Display dialog failed!\r\n\r\n");
hr = E_FAIL;
}
else
{
hr = g_hr;
}
}
else
{
hr = Process();
}
if (SUCCEEDED(hr))
{
WriteToLog("\r\nFixIE successful!\r\n");
// Success, so ask user to reboot
MyRestartDialog(g_hWnd, !g_bQuiet, IDS_REBOOT);
}
else
{
WriteToLog("\r\nERROR - FixIE failed!\r\n\r\n");
if (g_bNeedReboot)
{
MyRestartDialog(g_hWnd, !g_bQuiet, IDS_REBOOTFILE);
}
else
{
DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_REINSTALL), NULL, DlgProcReinstall);
}
}
if (g_pszError)
HeapFree(g_hHeap,0,g_pszError);
if (g_pIStream)
ConvertIStreamToFile(&g_pIStorage, &g_pIStream);
if (hMutex)
CloseHandle(hMutex);
return hr;
}
HRESULT Process()
{
HRESULT hr = S_OK;
WriteToLog("\r\nInside Process.\r\n");
// Get all the components that are successfully installed for the current platform
if (SUCCEEDED(hr))
{
hr = InitComponentList();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nInitComponentList succeeded!\r\n\r\n");
WriteToLog("There are a total of %1!ld! installed components.\r\n\r\n",g_nNumGuids);
}
else
{
WriteToLog("\r\nERROR - InitComponentList failed!\r\n\r\n");
}
}
// Verify all the files in the VFS sections exists and have valid version #s
if (SUCCEEDED(hr))
{
hr = VerifyAllFiles();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nVerifyAllFiles succeeded!\r\n\r\n");
}
else
{
WriteToLog("\r\nERROR - VerifyAllFiles failed!\r\n\r\n");
}
}
// Run RunSetupCommand on the PreROEX section
if (SUCCEEDED(hr))
{
hr = RunSetupCommandPreROEX();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nRunSetupCommandPreROEX succeeded!\r\n\r\n");
}
else
{
WriteToLog("\r\nERROR - RunSetupCommandPreROEX failed!\r\n\r\n");
}
}
// Run RunSetupCommand on all the ROEX sections
if (SUCCEEDED(hr))
{
hr = RunSetupCommandAllROEX();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nRunSetupCommandAllROEX succeeded!\r\n\r\n");
}
else
{
WriteToLog("\r\nERROR - RunSetupCommandAllROEX failed!\r\n\r\n");
}
}
// Call runonceexprocess
if (SUCCEEDED(hr))
{
hr = DoRunOnceExProcess();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nDoRunOnceExProcess succeeded!\r\n\r\n");
}
else
{
WriteToLog("\r\nERROR - DoRunOnceExProcess failed!\r\n\r\n");
}
}
// If there are any errors, then set hr to E_FAIL
if (g_pszError)
hr = E_FAIL;
// Run RunSetupCommand on all the PostROEX sections
if (SUCCEEDED(hr))
{
hr = RunSetupCommandAllPostROEX();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nRunSetupCommandAllPostROEX succeeded!\r\n\r\n");
}
else
{
WriteToLog("\r\nERROR - RunSetupCommandAllPostROEX failed!\r\n\r\n");
}
}
// Restore icons
if (SUCCEEDED(hr) && g_bRestoreIcons)
{
hr = RestoreIcons();
if (SUCCEEDED(hr))
{
WriteToLog("\r\nRestoreIcons succeeded!\r\n\r\n");
}
else
{
WriteToLog("\r\nERROR - RestoreIcons failed!\r\n\r\n");
}
}
return hr;
}
DWORD RunProcess(LPVOID lp)
{
WriteToLog("\r\nInside RunProcess.\r\n");
SendMessage(g_hProgress, PBM_SETRANGE, 0, MAKELPARAM(g_nProgressStart, g_nProgressEnd));
SendMessage(g_hProgress, PBM_SETPOS, g_nProgressStart, 0);
g_hr = Process();
SendMessage(g_hProgress, PBM_SETPOS, g_nProgressEnd, 0);
// terminate the dialog box
PostMessage((HWND) lp, WM_FINISHED, 0, 0L);
return 0;
}
INT_PTR CALLBACK DlgProcConfirm(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
uiCenterDialog(hWnd);
g_hWnd = hWnd;
break;
case WM_COMMAND:
switch( wParam )
{
case IDYES:
case IDNO:
// #40352 - Icon check box no longer exists. Always repair icons.
// g_bRestoreIcons = (IsDlgButtonChecked(hWnd, IDC_REPAIR_ICONS) == BST_CHECKED);
g_hWnd = NULL;
EndDialog(hWnd, wParam);
break;
case IDCANCEL:
g_hWnd = NULL;
EndDialog(hWnd, IDNO);
break;
default:
return FALSE;
}
break;
default:
return(FALSE);
}
return(TRUE);
}
INT_PTR CALLBACK DlgProcReinstall(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static LPSTR pszMessage;
switch (uMsg)
{
case WM_INITDIALOG:
uiCenterDialog(hWnd);
if (!g_pszError)
{
EnableWindow(GetDlgItem(hWnd, IDC_DETAILS), FALSE);
}
else
{
char szString[MAX_STRING];
LoadSz(IDS_FOLLOWINGERROR, szString, sizeof(szString));
pszMessage = (LPSTR)HeapAlloc(g_hHeap, 0, lstrlen(g_pszError) + sizeof(szString) + 1);
lstrcpy(pszMessage, szString);
lstrcat(pszMessage, g_pszError);
}
g_hWnd = hWnd;
break;
case WM_COMMAND:
switch( wParam )
{
case IDOK:
case IDCANCEL:
g_hWnd = NULL;
HeapFree(g_hHeap, 0, pszMessage);
EndDialog(hWnd, wParam);
break;
case IDC_DETAILS:
// Display failure messages.
char szTitle[MAX_STRING];
GetWindowText(hWnd, szTitle, sizeof(szTitle));
MessageBox(hWnd, pszMessage, szTitle, MB_OK);
break;
default:
return FALSE;
}
break;
default:
return(FALSE);
}
return(TRUE);
}
INT_PTR CALLBACK DlgProcFixIE(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HANDLE s_hThread = NULL;
DWORD dwThread;
switch (uMsg)
{
case WM_INITDIALOG:
uiCenterDialog(hWnd);
g_hWnd = hWnd;
g_hProgress = GetDlgItem(hWnd, IDC_PROGRESS);
if ((s_hThread = CreateThread(NULL, 0, RunProcess, (LPVOID) hWnd, 0, &dwThread)) == NULL)
PostMessage(hWnd, WM_FINISHED, 0, 0L);
break;
case WM_FINISHED:
if (s_hThread != NULL)
{
while (MsgWaitForMultipleObjects(1, &s_hThread, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CloseHandle(s_hThread);
s_hThread = NULL;
}
g_hWnd = NULL;
EndDialog(hWnd, 0);
break;
default:
return(FALSE);
}
return(TRUE);
}
void RunOnceExProcessCallback(int nCurrent, int nMax, LPSTR pszError)
{
int nStart = g_nDoRunOnceExProcessStart;
int nEnd = g_nDoRunOnceExProcessEnd;
WriteToLog("Current=%1!ld! ; Max=%2!ld! ; Error=%3\r\n", nCurrent, nMax, pszError);
if (g_hProgress && nMax)
{
SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurrent/nMax, 0);
}
if (pszError)
{
LogError(pszError);
}
}
void LogError(char *pszFormatString, ...)
{
va_list args;
char *pszFullErrMsg = NULL;
LPSTR pszErrorPreFail = NULL;
// If error string does not exist, then malloc it
if (!g_pszError)
{
g_pszError = (LPSTR)HeapAlloc(g_hHeap, 0, BUFFERSIZE);
if ( ! g_pszError )
return; // Is it OK to fail quietly here ?
*g_pszError = '\0';
}
va_start(args, pszFormatString);
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
(LPCVOID) pszFormatString, 0, 0, (LPTSTR) &pszFullErrMsg, 0, &args);
if (pszFullErrMsg)
{
// Make room for new string and newline
while (lstrlen(g_pszError)+lstrlen(pszFullErrMsg)+2>(int)HeapSize(g_hHeap, 0, g_pszError))
{
WriteToLog("Error string size is %1!ld!", HeapSize(g_hHeap, 0, g_pszError));
pszErrorPreFail = g_pszError;
#pragma prefast(suppress: 308, "PREfast noise - pointer was saved")
g_pszError = (LPSTR)HeapReAlloc(g_hHeap, 0, g_pszError, HeapSize(g_hHeap, 0, g_pszError)+BUFFERSIZE);
if(!g_pszError)
{
if (pszErrorPreFail)
HeapFree(g_hHeap, 0, pszErrorPreFail);
break;
}
WriteToLog(", increasing it to %1!ld!\r\n", HeapSize(g_hHeap, 0, g_pszError));
}
if ( g_pszError )
{
// Add string and then add newline
lstrcat(g_pszError, pszFullErrMsg);
lstrcat(g_pszError, "\n");
}
LocalFree(pszFullErrMsg);
}
}
HRESULT RestoreIcons()
{
HRESULT hr = S_OK;
const char szIEAccess[] = "Software\\Microsoft\\Active Setup\\Installed Components\\>{26923b43-4d38-484f-9b9e-de460746276c}";
int nStart = g_nRestoreIconsStart;
int nEnd = g_nRestoreIconsEnd;
int nCurGuid = 0;
LCIFCOMPONENT pComp = g_pLinkCif;
char szKey[MAX_PATH];
lstrcpy(szKey, c_gszRegRestoreIcons);
char* pszEnd = szKey + lstrlen(szKey);
while (pComp && SUCCEEDED(hr))
{
// Add guid to end
AddPath(szKey, pComp->szGuid);
// Delete key
if (RegDeleteKey(HKEY_CURRENT_USER, szKey) == ERROR_SUCCESS)
{
WriteToLog("Reg key HKCU\\%1 deleted\r\n", szKey);
}
else
{
WriteToLog("Reg key HKCU\\%1 cannot be deleted\r\n", szKey);
}
// Remove the guid
*pszEnd = '\0';
nCurGuid++;
if (g_hProgress)
SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
pComp = pComp->next;
}
RegDeleteKey(HKEY_CURRENT_USER, szIEAccess);
return hr;
}
HRESULT DoRunOnceExProcess()
{
HRESULT hr = E_FAIL;
int nStart = g_nDoRunOnceExProcessStart;
int nEnd = g_nDoRunOnceExProcessEnd;
// Load iernonce.dll
HINSTANCE hIERnOnceDLL;
char szDLLPath[MAX_PATH];
GetSystemDirectory(szDLLPath, sizeof(szDLLPath));
AddPath(szDLLPath, c_gszIERnOnceDLL);
hIERnOnceDLL = LoadLibrary(szDLLPath);
if (hIERnOnceDLL)
{
RUNONCEEXPROCESS fpRunOnceExProcess;
INITCALLBACK fpInitCallback;
// Add callback and set to quiet
if (fpInitCallback = (INITCALLBACK)GetProcAddress(hIERnOnceDLL, achInitCallback))
{
fpInitCallback(&RunOnceExProcessCallback, TRUE);
}
else
{
WriteToLog("\r\nERROR - GetProcAddress on %1 failed!\r\n\r\n", achInitCallback);
}
// Run RunOnceExProcess
if (fpRunOnceExProcess = (RUNONCEEXPROCESS)GetProcAddress(hIERnOnceDLL, achRunOnceExProcess))
{
hr = fpRunOnceExProcess(g_hWnd, NULL, NULL, 1);
}
else
{
WriteToLog("\r\nERROR - GetProcAddress on %1 failed!\r\n\r\n", achRunOnceExProcess);
}
FreeLibrary(hIERnOnceDLL);
}
else
{
WriteToLog("\r\nERROR - %1 cannot be loaded!\r\n\r\n", szDLLPath);
}
if (g_hProgress)
SendMessage(g_hProgress, PBM_SETPOS, nEnd, 0);
return hr;
}
HRESULT RunSetupCommandPreROEX()
{
HRESULT hr = S_OK;
int nStart = g_nRunSetupCommandPreROEXStart;
int nEnd = g_nRunSetupCommandPreROEXEnd;
hr = MyRunSetupCommand(g_hWnd, g_szFixIEInf, c_gszPreSectionName, 0);
if (g_hProgress)
SendMessage(g_hProgress, PBM_SETPOS, nEnd, 0);
return hr;
}
HRESULT RunSetupCommandAllPostROEX()
{
HRESULT hr = S_OK;
int nStart = g_nRunSetupCommandAllPostROEXStart;
int nEnd = g_nRunSetupCommandAllPostROEXEnd;
int nCurGuid = 0;
LCIFCOMPONENT pComp = g_pLinkCif;
while (pComp && SUCCEEDED(hr))
{
if ( *(pComp->szPostROEX) != '\0')
hr = MyRunSetupCommand(g_hWnd, g_szFixIEInf, pComp->szPostROEX, 0);
nCurGuid++;
if (g_hProgress)
SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
pComp = pComp->next;
}
return hr;
}
HRESULT RunSetupCommandAllROEX()
{
HRESULT hr = S_OK;
int nStart = g_nRunSetupCommandAllROEXStart;
int nEnd = g_nRunSetupCommandAllROEXEnd;
int nCurGuid = 0;
LCIFCOMPONENT pComp = g_pLinkCif;
while (pComp && SUCCEEDED(hr))
{
if ( *(pComp->szROEX) != '\0')
hr = MyRunSetupCommand(g_hWnd, g_szFixIEInf, pComp->szROEX, 0);
nCurGuid++;
if (g_hProgress)
SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
pComp = pComp->next;
}
return hr;
}
HRESULT VerifyAllFiles()
{
HRESULT hr = S_OK;
char szError[MAX_STRING];
int nStart = g_nVerifyAllFilesStart;
int nEnd = g_nVerifyAllFilesEnd;
int nCurGuid = 0;
LCIFCOMPONENT pComp = g_pLinkCif;
char szMessage[MAX_STRING];
char szLocation[MAX_PATH];
GetSystemDirectory(szLocation, sizeof(szLocation));
char *pTmp = szLocation + lstrlen(szLocation);
LPSTR lpVFSSection = NULL;
while (pComp)
{
lpVFSSection = (LPSTR)LocalAlloc(LPTR, MAX_CONTENT);
if(!lpVFSSection) {
return E_FAIL;
}
WriteToLog("Looking up %1...\r\n", pComp->szVFS);
if (GetPrivateProfileSection(pComp->szVFS, lpVFSSection, MAX_CONTENT, g_szFixIEInf))
{
LPSTR lpVFSLine = lpVFSSection;
while (*lpVFSLine)
{
int nLength = lstrlen(lpVFSLine);
// Need to allow new-line comments.
if ( *lpVFSLine == ';' )
{
lpVFSLine += nLength + 1;
continue; // Go on with next iteration of the WHILE loop
}
WriteToLog(" Verifying %1\r\n", lpVFSLine);
char szFile[MAX_STRING];
// Find '=' so that file and versions can be seperated
char* pChar;
pChar = ANSIStrChr(lpVFSLine, '=');
// if can't find '=' or '=' is last character then make sure file exists
if (!pChar || (*(pChar+1)=='\0'))
{
// Kill the '=' if it exists
if (pChar)
*pChar = '\0';
// Get the filename
lstrcpy(szFile, lpVFSLine);
// Add the filename to the path
AddPath(szLocation, szFile);
// If can't find file, then set error
if (GetFileAttributes(szLocation) == 0xFFFFFFFF)
{
hr = E_FAIL;
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
WriteToLog(" ERROR - File %1 does not exist.\r\n", szFile);
LoadSz(IDS_FILEMISSING, szError, sizeof(szError));
LogError(szError, szFile);
}
else
{
WriteToLog(" ERROR - File %1 exists but cannot be accessed.\r\n", szFile);
LoadSz(IDS_FILELOCKED, szError, sizeof(szError));
LogError(szError, szFile);
g_bNeedReboot = TRUE;
}
}
else
{
WriteToLog(" File %1 exists.\r\n", szFile);
}
// Reset the location to just the path again
*pTmp = '\0';
}
else // Make sure version in the given limits
{
*pChar = '\0';
pChar++;
// Get the filename
lstrcpy(szFile, lpVFSLine);
DWORD dwMSVer;
DWORD dwLSVer;
// Add the filename to the path
AddPath(szLocation, szFile);
// Get the version of that file
MyGetVersionFromFile(szLocation, &dwMSVer, &dwLSVer);
// If file cannot be read then report error
if (dwMSVer==0 && dwLSVer==0 && GetFileAttributes(szLocation) == 0xFFFFFFFF)
{
hr = E_FAIL;
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
WriteToLog(" ERROR - File %1 does not exist.\r\n", szFile);
LoadSz(IDS_FILEMISSING, szError, sizeof(szError));
LogError(szError, szFile);
}
else
{
WriteToLog(" ERROR - File %1 exists but cannot be accessed.\r\n", szFile);
LoadSz(IDS_FILELOCKED, szError, sizeof(szError));
LogError(szError, szFile);
g_bNeedReboot = TRUE;
}
}
else
{
// Find '-' so that if there are more than one versions then they are seperated
char* pChar2;
pChar2 = ANSIStrChr(pChar, '-');
if (pChar2)
{
BOOL bVerifyError = FALSE;
char szVersionFound[MAX_VER];
char szVersionLow[MAX_VER];
char szVersionHigh[MAX_VER];
VersionToString(dwMSVer, dwLSVer, szVersionFound);
*pChar2 = '\0';
pChar2++;
// pChar points to first version
// pChar2 points to second version
// '-' found
// so it's one of: xxxx- ; -xxxx ; xxxx-xxxx
if (lstrlen(pChar)) // Low version exists
{
DWORD dwMSVerLow = 0;
DWORD dwLSVerLow = 0;
MyConvertVersionString(pChar, &dwMSVerLow, &dwLSVerLow);
VersionToString(dwMSVerLow, dwLSVerLow, szVersionLow);
// Make sure this version is greater than low version
if ((dwMSVerLow<dwMSVer) || ((dwMSVerLow==dwMSVer) && (dwLSVerLow<=dwLSVer)))
{
}
else
{
bVerifyError = TRUE;
}
}
if (lstrlen(pChar2)) // High version exists
{
DWORD dwMSVerHigh = 0;
DWORD dwLSVerHigh = 0;
MyConvertVersionString(pChar2, &dwMSVerHigh, &dwLSVerHigh);
VersionToString(dwMSVerHigh, dwLSVerHigh, szVersionHigh);
// Make sure this version is lesser than high version
if ((dwMSVerHigh>dwMSVer) || ((dwMSVerHigh==dwMSVer) && (dwLSVerHigh>=dwLSVer)))
{
}
else
{
bVerifyError = TRUE;
}
}
if (bVerifyError)
{
WriteToLog(" ERROR - File %1 (version %2) version check failed.\r\n", szFile, szVersionFound);
hr = E_FAIL;
if (lstrlen(pChar)&&lstrlen(pChar2))
{
LoadSz(IDS_VERSIONINBETWEEN, szError, sizeof(szError));
LogError(szError, szVersionFound, szFile, szVersionLow, szVersionHigh);
}
else if (lstrlen(pChar))
{
LoadSz(IDS_VERSIONGREATER, szError, sizeof(szError));
LogError(szError, szVersionFound, szFile, szVersionLow);
}
else if (lstrlen(pChar2))
{
LoadSz(IDS_VERSIONLESS, szError, sizeof(szError));
LogError(szError, szVersionFound, szFile, szVersionHigh);
}
}
else
{
WriteToLog(" File %1 version checked.\r\n", szFile);
}
}
else // no '-' is found
{
// so it's a unique version
// the current version must be exact
DWORD dwMSVerExact = 0;
DWORD dwLSVerExact = 0;
MyConvertVersionString(pChar, &dwMSVerExact, &dwLSVerExact);
char szVersionFound[MAX_VER];
char szVersionRequired[MAX_VER];
VersionToString(dwMSVer, dwLSVer, szVersionFound);
VersionToString(dwMSVerExact, dwLSVerExact, szVersionRequired);
// If it is not an exact match then signal error occured
if ((dwMSVerExact==dwMSVer) && (dwLSVerExact==dwLSVer))
{
WriteToLog(" File %1 version checked.\r\n", szFile);
}
else
{
WriteToLog(" ERROR - File %1 (version %2) version check failed.\r\n", szFile, szVersionFound);
LoadSz(IDS_VERSIONEXACT, szError, sizeof(szError));
LogError(szError, szVersionFound, szFile, szVersionRequired);
hr = E_FAIL;
}
}
}
// Reset the location to just the path again
*pTmp = '\0';
}
lpVFSLine += nLength + 1;
}
}
nCurGuid++;
if (g_hProgress)
SendMessage(g_hProgress, PBM_SETPOS, nStart+(nEnd-nStart)*nCurGuid/g_nNumGuids, 0);
pComp = pComp->next;
}
if (lpVFSSection)
LocalFree(lpVFSSection);
return hr;
}
void VersionToString(DWORD dwMSVer, DWORD dwLSVer, LPSTR pszVersion)
{
wsprintf(pszVersion, "%d.%d.%d.%d", HIWORD(dwMSVer), LOWORD(dwMSVer), HIWORD(dwLSVer), LOWORD(dwLSVer));
}
VOID GetInfFile()
{
DWORD dwType;
DWORD dwSize = sizeof(g_szFixIEInf);
HKEY hKey;
*g_szFixIEInf = '\0';
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_gszRegstrPathIExplore, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
if ((RegQueryValueEx(hKey, NULL, 0, &dwType, (LPBYTE)g_szFixIEInf, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
{
GetParentDir(g_szFixIEInf);
}
RegCloseKey(hKey);
}
AddPath(g_szFixIEInf, c_gszFixIEInfName);
}
VOID GetPlatform()
{
LPCSTR pTemp = NULL;
OSVERSIONINFO VerInfo;
VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&VerInfo);
lstrcpy(g_szModifiedMainSectionName, c_gszMainSectionName);
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// Running NT
g_bRunningWin95 = FALSE;
SYSTEM_INFO System_info;
GetSystemInfo(&System_info);
if (System_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA)
{
g_dwPlatform = PLATFORM_NT5ALPHA;
if (VerInfo.dwMajorVersion == 4)
g_dwPlatform = PLATFORM_NT4ALPHA;
pTemp = c_gszNTalpha;
}
else
{
g_dwPlatform = PLATFORM_NT5;
pTemp = c_gszW2K;
if (VerInfo.dwMajorVersion == 4)
{
g_dwPlatform = PLATFORM_NT4;
pTemp = c_gszNTx86;
}
}
}
else
{
// Running Windows 9x
// Assume Win98
g_bRunningWin95 = TRUE;
g_dwPlatform = PLATFORM_WIN98;
pTemp = c_gszWin95;
if (VerInfo.dwMinorVersion == 0)
{
g_dwPlatform = PLATFORM_WIN95;
}
else if (VerInfo.dwMinorVersion == 90)
{
pTemp = c_gszMillen;
g_dwPlatform = PLATFORM_MILLEN;
}
}
if (pTemp)
lstrcat(g_szModifiedMainSectionName, pTemp);
}
#define REGSTR_CCS_CONTROL_WINDOWS REGSTR_PATH_CURRENT_CONTROL_SET "\\WINDOWS"
#define CSDVERSION "CSDVersion"
#define NTSP4_VERSION 0x0600
// version updated to SP6!
BOOL CheckForNT4_SP4()
{
HKEY hKey;
DWORD dwCSDVersion;
DWORD dwSize;
BOOL bNTSP4 = -1;
if ( bNTSP4 == -1)
{
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_CCS_CONTROL_WINDOWS, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
// assign the default
bNTSP4 = FALSE;
dwSize = sizeof(dwCSDVersion);
if (RegQueryValueEx(hKey, CSDVERSION, NULL, NULL, (unsigned char*)&dwCSDVersion, &dwSize) == ERROR_SUCCESS)
{
bNTSP4 = (LOWORD(dwCSDVersion) >= NTSP4_VERSION);
}
RegCloseKey(hKey);
}
}
return bNTSP4;
}
HRESULT InitComponentList()
{
HRESULT hr = E_FAIL;
ICifFile *pCifFile = NULL;
IEnumCifComponents *pEnumCifComponents = NULL;
ICifComponent *pCifComponent = NULL;
hr = GetICifFileFromFile(&pCifFile, "iesetup.cif");
if (SUCCEEDED(hr))
{
hr = pCifFile->EnumComponents(&pEnumCifComponents, g_dwPlatform , NULL);
if (SUCCEEDED(hr))
{
while (pEnumCifComponents->Next(&pCifComponent) == S_OK)
{
if (pCifComponent->IsComponentInstalled() == ICI_INSTALLED)
AddComponent(pCifComponent);
}
pEnumCifComponents->Release();
}
else
{
WriteToLog("\r\nERROR - Cannot pCifFile->EnumComponents!\r\n\r\n");
}
pCifFile->Release();
}
else
{
WriteToLog("\r\nERROR - Cannot GetICifFileFromFile!\r\n\r\n");
}
return hr;
}
VOID AddLink(LPSTR szGuid, ICifComponent *pCifComp, LPSTR szGuidProfileString)
{
char szID[MAX_STRING];
LCIFCOMPONENT pComp;
char *pStart = szGuidProfileString;
char *pChar;
LCIFCOMPONENT pTemp = g_pLinkCif;
LCIFCOMPONENT pLast = NULL;
pCifComp->GetID(szID, sizeof(szID));
WriteToLog("Add component %1 with GUID %2\r\n", szID, szGuid);
// Initialize all the members of the new LCIFCOMPONENT link.
pComp = (LCIFCOMPONENT)LocalAlloc(LPTR, sizeof(LINKEDCIFCOMPONENT));
pComp->pCifComponent = pCifComp;
lstrcpy(pComp->szGuid, szGuid);
*(pComp->szVFS) = '\0';
*(pComp->szROEX) = '\0';
*(pComp->szPostROEX) = '\0';
pComp->next = NULL;
GetStringField(szGuidProfileString, 0, pComp->szVFS, sizeof(pComp->szVFS));
GetStringField(szGuidProfileString, 1, pComp->szROEX, sizeof(pComp->szROEX));
GetStringField(szGuidProfileString, 2, pComp->szPostROEX, sizeof(pComp->szPostROEX));
WriteToLog(" VFS = %1\r\n",pComp->szVFS);
WriteToLog(" ROEX = %1\r\n", pComp->szROEX);
WriteToLog(" PostROEX = %1\r\n", pComp->szPostROEX);
// Add the new link to the linklist pointed to be g_pLinkCif
while (pTemp)
{
pLast = pTemp;
pTemp = pTemp->next;
}
if (pLast)
pLast->next = pComp;
else
g_pLinkCif = pComp;
// Increment global count of number of guids
g_nNumGuids++;
if (pTemp)
{
pComp->next = pTemp;
}
}
VOID AddComponent(ICifComponent *pCifComp)
{
char szGuid[MAX_STRING];
if (SUCCEEDED(pCifComp->GetGUID(szGuid, sizeof(szGuid))))
{
char szGuidProfileString[MAX_STRING];
if (GetPrivateProfileString(g_szModifiedMainSectionName, szGuid, "", szGuidProfileString, sizeof(szGuidProfileString), g_szFixIEInf))
{
AddLink(szGuid, pCifComp, szGuidProfileString);
}
// If a valid Crypto section exists, process this GUID entry under it too.
if ( *g_szCryptoSectionName )
{
if (GetPrivateProfileString(g_szCryptoSectionName, szGuid, "", szGuidProfileString, sizeof(szGuidProfileString), g_szFixIEInf))
{
AddLink(szGuid, pCifComp, szGuidProfileString);
}
}
}
}
VOID MyConvertVersionString(LPSTR lpszVersion, LPDWORD pdwMSVer, LPDWORD pdwLSVer)
{
WORD wVer[4];
ConvertVersionString(lpszVersion, wVer, '.' );
*pdwMSVer = (DWORD)wVer[0] << 16; // Make hi word of MS version
*pdwMSVer += (DWORD)wVer[1]; // Make lo word of MS version
*pdwLSVer = (DWORD)wVer[2] << 16; // Make hi word of LS version
*pdwLSVer += (DWORD)wVer[3]; // Make lo word of LS version
}
VOID MyGetVersionFromFile(LPSTR lpszFilename, LPDWORD pdwMSVer, LPDWORD pdwLSVer)
{
unsigned uiSize;
DWORD dwVerInfoSize;
DWORD dwHandle;
VS_FIXEDFILEINFO * lpVSFixedFileInfo;
void FAR *lpBuffer;
LPVOID lpVerBuffer;
*pdwMSVer = *pdwLSVer = 0L;
dwVerInfoSize = GetFileVersionInfoSize(lpszFilename, &dwHandle);
if (dwVerInfoSize)
{
// Alloc the memory for the version stamping
lpBuffer = LocalAlloc(LPTR, dwVerInfoSize);
if (lpBuffer)
{
// Read version stamping info
if (GetFileVersionInfo(lpszFilename, dwHandle, dwVerInfoSize, lpBuffer))
{
// Get the value for Translation
if (VerQueryValue(lpBuffer, "\\", (LPVOID*)&lpVSFixedFileInfo, &uiSize) &&
(uiSize))
{
*pdwMSVer = lpVSFixedFileInfo->dwFileVersionMS;
*pdwLSVer = lpVSFixedFileInfo->dwFileVersionLS;
}
}
LocalFree(lpBuffer);
}
}
return ;
}
VOID WriteToLog(char *pszFormatString, ...)
{
va_list args;
char *pszFullErrMsg = NULL;
DWORD dwBytesWritten;
if (!g_pIStream)
{
char szTmp[MAX_PATH];
LPWSTR pwsz = NULL;
if (GetWindowsDirectory(g_szLogFileName, sizeof(g_szLogFileName)))
{
AddPath(g_szLogFileName, c_gszLogFileName);
if (GetFileAttributes(g_szLogFileName) != 0xFFFFFFFF)
{
// Make a backup of the current log file
lstrcpyn(szTmp, g_szLogFileName, lstrlen(g_szLogFileName) - 2 ); // don't copy extension
lstrcat(szTmp, "BAK");
SetFileAttributes(szTmp, FILE_ATTRIBUTE_NORMAL);
DeleteFile(szTmp);
MoveFile(g_szLogFileName, szTmp);
}
pwsz = MakeWideStrFromAnsi(g_szLogFileName);
if ((pwsz) &&
(!FAILED(StgCreateDocfile(pwsz,
STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
0, &g_pIStorage))) )
{
g_pIStorage->CreateStream( L"CONTENTS",
STGM_READWRITE| STGM_SHARE_EXCLUSIVE,
0, 0, &g_pIStream );
if (g_pIStream == NULL)
{
// Could not open the stream, close the storage and delete the file
g_pIStorage->Release();
g_pIStorage = NULL;
DeleteFile(g_szLogFileName);
}
}
if (pwsz)
CoTaskMemFree(pwsz);
WriteToLog("Logging information for FixIE ...\r\n");
LogTimeDate();
WriteToLog("\r\n");
}
}
if (g_pIStream)
{
va_start(args, pszFormatString);
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
(LPCVOID) pszFormatString, 0, 0, (LPTSTR) &pszFullErrMsg, 0, &args);
if (pszFullErrMsg)
{
g_pIStream->Write(pszFullErrMsg, lstrlen(pszFullErrMsg), &dwBytesWritten);
LocalFree(pszFullErrMsg);
}
}
}
void ConvertIStreamToFile(LPSTORAGE *pIStorage, LPSTREAM *pIStream)
{
HANDLE fh;
char szTempFile[MAX_PATH]; // Should use the logfilename
LPVOID lpv = NULL;
LARGE_INTEGER li;
DWORD dwl;
ULONG ul;
HRESULT hr;
lstrcpy (szTempFile, g_szLogFileName);
MakePath(szTempFile);
if (GetTempFileName(szTempFile, "~VS", 0, szTempFile) != 0)
{
fh = CreateFile(szTempFile, GENERIC_READ|GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh != INVALID_HANDLE_VALUE)
{
lpv = (LPSTR)LocalAlloc(LPTR, BUFFERSIZE);
if (lpv)
{
LISet32(li, 0);
(*pIStream)->Seek(li, STREAM_SEEK_SET, NULL); // Set the seek pointer to the beginning
do
{
hr = (*pIStream)->Read(lpv, BUFFERSIZE, &ul);
if(SUCCEEDED(hr))
{
if (!WriteFile(fh, lpv, ul, &dwl, NULL))
hr = E_FAIL;
}
}
while ((SUCCEEDED(hr)) && (ul == BUFFERSIZE));
LocalFree(lpv);
}
CloseHandle(fh);
// Need to release stream and storage to close the storage file.
(*pIStream)->Release();
(*pIStorage)->Release();
*pIStream = NULL;
*pIStorage = NULL;
if (SUCCEEDED(hr))
{
DeleteFile(g_szLogFileName);
MoveFile(szTempFile, g_szLogFileName);
}
}
}
if (*pIStream)
{
// If we did not manage to convert the file to a text file
(*pIStream)->Release();
(*pIStorage)->Release();
*pIStream = NULL;
*pIStorage = NULL;
}
return ;
}
LPWSTR MakeWideStrFromAnsi(LPSTR psz)
{
LPWSTR pwsz;
int i;
// arg checking.
//
if (!psz)
return NULL;
// compute the length
//
i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
if (i <= 0) return NULL;
pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
if (!pwsz) return NULL;
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
pwsz[i - 1] = 0;
return pwsz;
}
LPSTR MakeAnsiStrFromWide(LPWSTR pwsz)
{
LPSTR psz;
int i;
// arg checking.
//
if (!pwsz)
return NULL;
// compute the length
//
i = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);
if (i <= 0) return NULL;
psz = (LPSTR) CoTaskMemAlloc(i * sizeof(CHAR));
if (!psz) return NULL;
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, i, NULL, NULL);
psz[i - 1] = 0;
return psz;
}
void MakePath(LPSTR lpPath)
{
LPSTR lpTmp;
lpTmp = CharPrev( lpPath, lpPath+lstrlen(lpPath));
// chop filename off
//
while ( (lpTmp > lpPath) && *lpTmp && (*lpTmp != '\\') )
lpTmp = CharPrev( lpPath, lpTmp );
if ( *CharPrev( lpPath, lpTmp ) != ':' )
*lpTmp = '\0';
else
*CharNext( lpTmp ) = '\0';
return;
}
void LogTimeDate()
{
SYSTEMTIME SystemTime;
GetLocalTime(&SystemTime);
WriteToLog("Date:%1!d!/%2!d!/%3!d! (M/D/Y) Time:%4!d!:%5!d!:%6!d!\r\n",
SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,
SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
}
HRESULT MyRunSetupCommand(HWND hwnd, LPCSTR lpszInfFile, LPCSTR lpszSection, DWORD dwFlags)
{
HRESULT hr = E_FAIL;
char szSourceDir[MAX_PATH];
lstrcpy(szSourceDir, lpszInfFile);
GetParentDir(szSourceDir);
WriteToLog("Run setup command. File:%1: Section:%2:\r\n",lpszInfFile, lpszSection);
dwFlags |= (RSC_FLAG_INF | RSC_FLAG_NGCONV | RSC_FLAG_QUIET);
hr = RunSetupCommand(hwnd, lpszInfFile, lpszSection, szSourceDir, NULL, NULL, dwFlags, NULL);
WriteToLog("RunSetupCommand returned :%1!lx!:\r\n", hr);
if (!SUCCEEDED(hr))
WriteToLog("\r\nERROR - RunSetupCommand failed\r\n\r\n");
return hr;
}
void uiCenterDialog( HWND hwndDlg )
{
RECT rc;
RECT rcScreen;
int x, y;
int cxDlg, cyDlg;
int cxScreen;
int cyScreen;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, 0);
cxScreen = rcScreen.right - rcScreen.left;
cyScreen = rcScreen.bottom - rcScreen.top;
GetWindowRect(hwndDlg,&rc);
x = rc.left; // Default is to leave the dialog where the template
y = rc.top; // was going to place it.
cxDlg = rc.right - rc.left;
cyDlg = rc.bottom - rc.top;
y = rcScreen.top + ((cyScreen - cyDlg) / 2);
x = rcScreen.left + ((cxScreen - cxDlg) / 2);
// Position the dialog.
//
SetWindowPos(hwndDlg, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
}
BOOL MyNTReboot()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
// get a token from this process
if ( !OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
return FALSE;
}
// get the LUID for the shutdown privilege
LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid );
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//get the shutdown privilege for this proces
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
{
return FALSE;
}
// shutdown the system and force all applications to close
if (!ExitWindowsEx( EWX_REBOOT, 0 ) )
{
return FALSE;
}
return TRUE;
}
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;
}
#define SOFTBOOT_CMDLINE "softboot.exe /s:,60"
// Display a dialog asking the user to restart Windows, with a button that
// will do it for them if possible.
//
BOOL MyRestartDialog(HWND hParent, BOOL bShowPrompt, UINT nIdMessage)
{
char szBuf[MAX_STRING];
char szTitle[MAX_STRING];
UINT id = IDYES;
if(bShowPrompt)
{
LoadSz(IDS_TITLE, szTitle, sizeof(szTitle));
LoadSz(nIdMessage, szBuf, sizeof(szBuf));
id = MessageBox(hParent, szBuf, szTitle, MB_ICONQUESTION | MB_YESNO | MB_TASKMODAL | MB_SETFOREGROUND);
}
if ( id == IDYES )
{
// path to softboot plus a little slop for the command line
char szBuf[MAX_PATH + 10];
szBuf[0] = 0;
GetSystemDirectory(szBuf, sizeof(szBuf));
AddPath(szBuf, SOFTBOOT_CMDLINE);
if(FAILED(LaunchProcess(szBuf, NULL, NULL, SW_SHOWNORMAL)))
{
if(g_bRunningWin95)
{
ExitWindowsEx( EWX_REBOOT , 0 );
}
else
{
MyNTReboot();
}
}
}
return (id == IDYES);
}
int LoadSz(UINT id, LPSTR pszBuf, UINT cMaxSize)
{
if(cMaxSize == 0)
return 0;
pszBuf[0] = 0;
return LoadString(g_hInstance, id, pszBuf, cMaxSize);
}
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;
}
LPSTR FindChar(LPSTR pszStr, char ch)
{
while( *pszStr != 0 && *pszStr != ch )
pszStr++;
return pszStr;
}
int DisplayMessage(char* pszMessage, UINT uStyle)
{
int iReturn = 0;
if (!g_bQuiet)
{
char szTitle[MAX_STRING];
LoadSz(IDS_TITLE, szTitle, sizeof(szTitle));
iReturn = MessageBox(g_hWnd, pszMessage, szTitle, uStyle);
}
return iReturn;
}