|
|
#include "precomp.h"
#include "dbsupport.h"
#include "viewlog.h"
using namespace ShimLib;
//#define AV_OPTIONS_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\AppVerifier"
#define AV_OPTION_CLEAR_LOG L"ClearLogsBeforeRun"
#define AV_OPTION_BREAK_ON_LOG L"BreakOnLog"
#define AV_OPTION_FULL_PAGEHEAP L"FullPageHeap"
#define AV_OPTION_AV_DEBUGGER L"UseAVDebugger"
#define AV_OPTION_DEBUGGER L"Debugger"
#define AV_OPTION_PROPAGATE L"PropagateTests"
//
// Forward declarations
//
CWinApp theApp;
HINSTANCE g_hInstance = NULL;
BOOL g_bSettingsDirty = FALSE;
BOOL g_bRefreshingSettings = FALSE;
BOOL g_bConsoleMode = FALSE;
BOOL g_bWin2KMode = FALSE;
BOOL g_bInternalMode = FALSE;
//
// dialog handles
//
HWND g_hDlgMain = NULL; HWND g_hDlgOptions = NULL;
// forward function declarations
INT_PTR CALLBACK DlgMain( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
INT_PTR CALLBACK DlgRunAlone( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
INT_PTR CALLBACK DlgConflict( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
void RefreshSettingsList( HWND hDlg, BOOL bForceRefresh = FALSE );
void ReadOptions( void );
BOOL GetAppTitleString( wstring &strTitle ) { wstring strVersion;
if (!AVLoadString(IDS_APP_NAME, strTitle)) { return FALSE; }
#if defined(_WIN64)
if (!AVLoadString(IDS_VERSION_STRING_64, strVersion)) { return FALSE; } #else
if (!AVLoadString(IDS_VERSION_STRING, strVersion)) { return FALSE; } #endif
strTitle += L" "; strTitle += strVersion;
return TRUE; }
void ShowHTMLHelp( void ) { SHELLEXECUTEINFOW sei; WCHAR szPath[MAX_PATH]; WCHAR* pszBackSlash;
DWORD dwLen = GetModuleFileName(NULL, szPath, ARRAY_LENGTH(szPath));
if (!dwLen) { return; }
pszBackSlash = wcsrchr(szPath, L'\\'); if (pszBackSlash) { pszBackSlash++; *pszBackSlash = 0; } else { //
// punt and just try to find it on the path
//
szPath[0] = 0; }
StringCchCatW(szPath, ARRAY_LENGTH(szPath), L"appverif.chm");
ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei); sei.lpVerb = L"open"; sei.lpFile = szPath; sei.nShow = SW_SHOWNORMAL;
ShellExecuteExW(&sei); }
BOOL SearchGroupForSID( DWORD dwGroup, BOOL* pfIsMember ) { PSID pSID = NULL; SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; BOOL fRes = TRUE;
if (!AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, dwGroup, 0, 0, 0, 0, 0, 0, &pSID)) { return FALSE; }
if (!pSID) { return FALSE; }
if (!CheckTokenMembership(NULL, pSID, pfIsMember)) { fRes = FALSE; }
FreeSid(pSID);
return fRes; }
BOOL CanRun( void ) { BOOL fIsAdmin;
if (!SearchGroupForSID(DOMAIN_ALIAS_RID_ADMINS, &fIsAdmin)) { return FALSE; }
return fIsAdmin; }
void DumpResourceStringsToConsole(ULONG ulBegin, ULONG ulEnd) { ULONG ulRes; wstring strText;
for (ulRes = ulBegin; ulRes != ulEnd + 1; ++ulRes) { if (AVLoadString(ulRes, strText)) { printf("%ls\n", strText.c_str()); } } }
void DumpCurrentSettingsToConsole(void) { CAVAppInfo *pApp;
DumpResourceStringsToConsole(IDS_CURRENT_SETTINGS, IDS_CURRENT_SETTINGS);
for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) { printf("%ls:\n", pApp->wstrExeName.c_str());
CTestInfo *pTest;
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pApp->IsTestActive(*pTest)) { printf(" %ls\n", pTest->strTestName.c_str()); } }
printf("\n"); }
DumpResourceStringsToConsole(IDS_DONE, IDS_DONE); }
void DumpHelpToConsole(void) {
DumpResourceStringsToConsole(IDS_HELP_INTRO_00, IDS_HELP_INTRO_10);
CTestInfo *pTest;
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pTest->eTestType == TEST_KERNEL && ((pTest->bInternal && g_bInternalMode) || (pTest->bExternal && !g_bInternalMode)) && (pTest->bWin2KCompatible || !g_bWin2KMode)) {
printf(" %ls\n", pTest->strTestName.c_str()); } }
DumpResourceStringsToConsole(IDS_HELP_SHIM_TESTS, IDS_HELP_SHIM_TESTS);
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pTest->eTestType == TEST_SHIM && ((pTest->bInternal && g_bInternalMode) || (pTest->bExternal && !g_bInternalMode)) && (pTest->bWin2KCompatible || !g_bWin2KMode)) {
printf(" %ls\n", pTest->strTestName.c_str()); } }
DumpResourceStringsToConsole(IDS_HELP_EXAMPLE_00, IDS_HELP_EXAMPLE_11); }
void HandleCommandLine(int argc, LPWSTR *argv) { WCHAR szApp[MAX_PATH]; wstring strTemp; CWStringArray astrApps;
szApp[0] = 0;
g_bConsoleMode = TRUE;
//
// print the title
//
if (GetAppTitleString(strTemp)) { printf("\n%ls\n", strTemp.c_str()); } if (AVLoadString(IDS_COPYRIGHT, strTemp)) { printf("%ls\n\n", strTemp.c_str()); }
//
// check for global operations
//
if (_wcsnicmp(argv[0], L"/q", 2) == 0) { // querysettings
DumpCurrentSettingsToConsole(); return; } if (_wcsicmp(argv[0], L"/?") == 0) { // help
DumpHelpToConsole(); return; } if (_wcsnicmp(argv[0], L"/r", 2) == 0) { // reset
g_aAppInfo.clear(); goto out; }
//
// first get a list of the app names
//
for (int nArg = 0 ; nArg != argc; nArg++) { WCHAR wc = argv[nArg][0];
if (wc != L'/' && wc != L'-' && wc != L'+') { astrApps.push_back(argv[nArg]); } }
if (astrApps.size() == 0) { AVErrorResourceFormat(IDS_NO_APP); DumpHelpToConsole(); return; }
//
// now for each app name, parse the list and adjust its settings
//
for (wstring *pStr = astrApps.begin(); pStr != astrApps.end(); pStr++) { CAVAppInfo *pApp; BOOL bFound = FALSE;
//
// check to see if they submitted a full path
//
const WCHAR * pExe = NULL; const WCHAR * pPath = NULL;
pExe = wcsrchr(pStr->c_str(), L'\\'); if (!pExe) { if ((*pStr)[1] == L':') { pExe = pStr->c_str() + 2; } } else { pExe++; }
if (pExe) { pPath = pStr->c_str(); } else { pExe = pStr->c_str(); }
//
// first, find or add the app to the list, and get a pointer to it
//
for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) { if (_wcsicmp(pApp->wstrExeName.c_str(), pExe) == 0) { bFound = TRUE; break; } } if (!bFound) { CAVAppInfo App;
App.wstrExeName = pExe; g_aAppInfo.push_back(App); pApp = g_aAppInfo.end() - 1; }
//
// if they submitted a full path, update the records
//
if (pPath) { pApp->wstrExePath = pPath; }
//
// now walk the command line again and make the adjustments
//
for (int nArg = 0 ; nArg != argc; nArg++) { if (argv[nArg][0] == L'/') { if (_wcsnicmp(argv[nArg], L"/a", 2) == 0) { // all
for (CTestInfo *pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { pApp->AddTest(*pTest); } } else if (_wcsnicmp(argv[nArg], L"/n", 2) == 0) { // none
for (CTestInfo *pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { pApp->RemoveTest(*pTest); } } else if (_wcsnicmp(argv[nArg], L"/d", 2) == 0) { // default
for (CTestInfo *pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pTest->bDefault) { pApp->AddTest(*pTest); } else { pApp->RemoveTest(*pTest); } } } else {
//
// unknown parameter
//
AVErrorResourceFormat(IDS_INVALID_PARAMETER, argv[nArg]); DumpHelpToConsole(); return; }
} else if (argv[nArg][0] == L'+' || argv[nArg][0] == L'-') {
BOOL bAdd = (argv[nArg][0] == L'+'); LPWSTR szParam = argv[nArg] + 1;
//
// see if it's a shim name
//
CTestInfo *pTest; bFound = FALSE;
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (_wcsicmp(szParam, pTest->strTestName.c_str()) == 0) { if (bAdd) { pApp->AddTest(*pTest); } else { pApp->RemoveTest(*pTest); } bFound = TRUE; break; } }
if (!bFound) { //
// unknown test
//
AVErrorResourceFormat(IDS_INVALID_TEST, szParam); DumpHelpToConsole(); return; } } //
// anything that doesn't begin with a slash, plus, or minus
// is an app name, so we'll ignore it
//
} }
out: //
// save them to disk/registry
//
SetCurrentAppSettings();
//
// show them the current settings, for verification
//
DumpCurrentSettingsToConsole(); }
BOOL CheckWindowsVersion(void) { OSVERSIONINFOEXW VersionInfo;
ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFOEXW)); VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
GetVersionEx((LPOSVERSIONINFOW)&VersionInfo);
if (VersionInfo.dwMajorVersion < 5 || (VersionInfo.dwMajorVersion == 5 && VersionInfo.dwMinorVersion == 0 && VersionInfo.wServicePackMajor < 3)) { //
// too early - can't run
//
AVErrorResourceFormat(IDS_INVALID_VERSION);
return FALSE;
} else if (VersionInfo.dwMajorVersion == 5 && VersionInfo.dwMinorVersion == 0) { //
// Win2K
//
g_bWin2KMode = TRUE; } else { //
// WinXP or above -- all is well
//
g_bWin2KMode = FALSE; }
return TRUE; }
extern "C" int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) { LPWSTR* argv = NULL; int argc = 0;
g_hInstance = hInstance;
//
// check for appropriate version
//
if (!CheckWindowsVersion()) { return 0; }
//
// check for administrator access
//
if (!CanRun()) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); return 0; }
//
// check for internal mode
//
g_bInternalMode = IsInternalModeEnabled();
InitTestInfo();
GetCurrentAppSettings();
ReadOptions();
if (lpCmdLine && lpCmdLine[0]) { argv = CommandLineToArgvW(lpCmdLine, &argc); }
if (argc > 0) { //
// we're in console mode, so handle everything as a console
//
HandleCommandLine(argc, argv); return 1; }
FreeConsole();
InitCommonControls();
LinkWindow_RegisterClass();
HACCEL hAccelMain = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCEL_MAIN));
HWND hMainDlg = CreateDialog(g_hInstance, (LPCTSTR)IDD_DLG_MAIN, NULL, DlgMain);
MSG msg;
//
// Main message loop:
//
while (GetMessage(&msg, NULL, 0, 0)) { if (!hAccelMain || !TranslateAccelerator(hMainDlg, hAccelMain, &msg)) { if (!IsDialogMessage(hMainDlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } }
return 0; }
void RefreshAppList( HWND hDlg ) { CAVAppInfoArray::iterator it;
HWND hList = GetDlgItem(hDlg, IDC_LIST_APPS);
ListView_DeleteAllItems(hList);
for (it = g_aAppInfo.begin(); it != g_aAppInfo.end(); it++) { LVITEM lvi;
lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.pszText = (LPWSTR)it->wstrExeName.c_str(); lvi.lParam = (LPARAM)it; lvi.iItem = 9999; lvi.iSubItem = 0;
ListView_InsertItem(hList, &lvi); }
RefreshSettingsList(hDlg); }
void DirtySettings( HWND hDlg, BOOL bDirty ) { g_bSettingsDirty = bDirty; }
void SaveSettings( HWND hDlg ) { DirtySettings(hDlg, FALSE);
SetCurrentAppSettings(); }
void SaveSettingsIfDirty(HWND hDlg) { if (g_bSettingsDirty) { SaveSettings(hDlg); } }
void DisplayLog( HWND hDlg ) { g_szSingleLogFile[0] = 0;
DialogBox(g_hInstance, (LPCTSTR)IDD_VIEWLOG_PAGE, hDlg, DlgViewLog); }
void DisplaySingleLog(HWND hDlg) { WCHAR wszFilter[] = L"Log files (*.log)\0*.log\0"; OPENFILENAME ofn; WCHAR wszAppFullPath[MAX_PATH]; WCHAR wszAppShortName[MAX_PATH]; HRESULT hr;
wstring wstrLogTitle;
if (!AVLoadString(IDS_VIEW_EXPORTED_LOG_TITLE, wstrLogTitle)) { wstrLogTitle = _T("View Exported Log"); }
wszAppFullPath[0] = 0;
ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.hInstance = NULL; ofn.lpstrFilter = wszFilter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = wszAppFullPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = wszAppShortName; ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = wstrLogTitle.c_str(); ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | // hide the "open read-only" checkbox
OFN_NONETWORKBUTTON | // no network button
OFN_NOTESTFILECREATE | // don't test for write protection, a full disk, etc.
OFN_SHAREAWARE; // don't check the existance of file with OpenFile
ofn.lpstrDefExt = _T("log");
if ( !GetOpenFileName(&ofn) ) { goto out; }
hr = StringCchCopyW(g_szSingleLogFile, ARRAY_LENGTH(g_szSingleLogFile), wszAppFullPath); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, wszAppFullPath); goto out; }
DialogBox(g_hInstance, (LPCTSTR)IDD_VIEWLOG_PAGE, hDlg, DlgViewLog);
out: g_szSingleLogFile[0] = 0; }
void SelectApp( HWND hDlg, int nWhich ) { HWND hList = GetDlgItem(hDlg, IDC_LIST_APPS);
int nItems = ListView_GetItemCount(hList);
if (nItems == 0) { return; }
if (nWhich > nItems - 1) { nWhich = nItems - 1; }
ListView_SetItemState(hList, nWhich, LVIS_SELECTED, LVIS_SELECTED); }
void RunSelectedApp( HWND hDlg ) { WCHAR wszCommandLine[MAX_PATH]; HRESULT hr;
SaveSettings(hDlg);
HWND hAppList = GetDlgItem(hDlg, IDC_LIST_APPS);
int nApp = ListView_GetNextItem(hAppList, -1, LVNI_SELECTED);
if (nApp == -1) { return; }
LVITEM lvi;
lvi.mask = LVIF_PARAM; lvi.iItem = nApp; lvi.iSubItem = 0;
ListView_GetItem(hAppList, &lvi);
CAVAppInfo *pApp = (CAVAppInfo*)lvi.lParam;
if (pApp->wstrExePath.size()) {
//
// first set the current directory properly, if possible
//
LPWSTR pwsz;
hr = StringCchCopyW(wszCommandLine, ARRAY_LENGTH(wszCommandLine), pApp->wstrExePath.c_str()); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, pApp->wstrExePath.c_str()); goto out; }
pwsz = wcsrchr(wszCommandLine, L'\\');
if (pwsz) { *pwsz = 0; SetCurrentDirectory(wszCommandLine); *pwsz = L'\\'; }
//
// then prepare the command line
//
hr = StringCchPrintfW(wszCommandLine, ARRAY_LENGTH(wszCommandLine), L"\"%s\"", pApp->wstrExePath.c_str()); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, pApp->wstrExePath.c_str()); goto out; }
} else { hr = StringCchPrintfW(wszCommandLine, ARRAY_LENGTH(wszCommandLine), L"\"%s\"", pApp->wstrExeName.c_str()); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, pApp->wstrExeName.c_str()); goto out; }
}
PROCESS_INFORMATION ProcessInfo; BOOL bRet; STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo);
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
bRet = CreateProcess(NULL, wszCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo);
if (!bRet) { WCHAR wszFilter[] = L"Executable files (*.exe)\0*.exe\0"; OPENFILENAME ofn; WCHAR wszAppFullPath[MAX_PATH]; WCHAR wszAppShortName[MAX_PATH];
wstring strCaption;
if (!AVLoadString(IDS_LOCATE_APP, strCaption)) { strCaption = _T("Please locate application"); }
if (pApp->wstrExePath.size()) { hr = StringCchCopyW(wszAppFullPath, ARRAY_LENGTH(wszAppFullPath), pApp->wstrExePath.c_str()); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, pApp->wstrExePath.c_str()); goto out; } } else { hr = StringCchCopyW(wszAppFullPath, ARRAY_LENGTH(wszAppFullPath), pApp->wstrExeName.c_str()); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, pApp->wstrExeName.c_str()); goto out; } }
ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.hInstance = NULL; ofn.lpstrFilter = wszFilter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = wszAppFullPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = wszAppShortName; ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = strCaption.c_str(); ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | // hide the "open read-only" checkbox
OFN_NONETWORKBUTTON | // no network button
OFN_NOTESTFILECREATE | // don't test for write protection, a full disk, etc.
OFN_SHAREAWARE; // don't check the existance of file with OpenFile
ofn.lpstrDefExt = NULL;
if (!GetOpenFileName(&ofn)) { return; }
pApp->wstrExePath = wszAppFullPath; pApp->wstrExeName = wszAppShortName; hr = StringCchPrintfW(wszCommandLine, ARRAY_LENGTH(wszCommandLine), L"\"%s\"", pApp->wstrExePath.c_str()); if (FAILED(hr)) { AVErrorResourceFormat(IDS_PATH_TOO_LONG, pApp->wstrExePath.c_str()); goto out; }
RefreshAppList(hDlg);
ZeroMemory(&StartupInfo, sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo);
ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
bRet = CreateProcess(NULL, wszCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo); if (!bRet) { AVErrorResourceFormat(IDS_CANT_LAUNCH_EXE); }
} out: return; }
void AddAppToList( HWND hDlg ) {
WCHAR wszFilter[] = L"Executable files (*.exe)\0*.exe\0"; OPENFILENAME ofn; WCHAR wszAppFullPath[MAX_PATH]; WCHAR wszAppShortName[MAX_PATH];
wstring wstrTitle;
if (!AVLoadString(IDS_ADD_APPLICATION_TITLE, wstrTitle)) { wstrTitle = _T("Add Application"); }
wszAppFullPath[0] = 0;
ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.hInstance = NULL; ofn.lpstrFilter = wszFilter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = wszAppFullPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrFileTitle = wszAppShortName; ofn.nMaxFileTitle = MAX_PATH; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = wstrTitle.c_str(); ofn.Flags = OFN_HIDEREADONLY | // hide the "open read-only" checkbox
OFN_NONETWORKBUTTON | // no network button
OFN_NOTESTFILECREATE | // don't test for write protection, a full disk, etc.
OFN_SHAREAWARE; // don't check the existance of file with OpenFile
ofn.lpstrDefExt = _T("EXE");
if (!GetOpenFileName(&ofn)) { return; }
//
// check to see if the app is already in the list
//
CAVAppInfo *pApp; BOOL bFound = FALSE;
for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) { if (_wcsicmp(pApp->wstrExeName.c_str(), wszAppShortName) == 0) { //
// the app is already in the list, so just update the full
// path, if it's good
//
if (GetFileAttributes(wszAppFullPath) != -1) { pApp->wstrExePath = wszAppFullPath; } bFound = TRUE; } }
//
// if the app wasn't already in the list, add it to the list
//
if (!bFound) { CAVAppInfo AppInfo;
AppInfo.wstrExeName = wszAppShortName;
//
// check to see if the file actually exists
//
if (GetFileAttributes(wszAppFullPath) != -1) { AppInfo.wstrExePath = wszAppFullPath; }
//
// init the default tests
//
CAVAppInfo *pDefaultApp = &g_aAppInfo[0]; CTestInfo *pTest; for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pDefaultApp->IsTestActive(*pTest)) { AppInfo.AddTest(*pTest); } }
g_aAppInfo.push_back(AppInfo);
RefreshAppList(hDlg);
SelectApp(hDlg, 9999);
DirtySettings(hDlg, TRUE); } }
void RemoveSelectedApp( HWND hDlg ) { HWND hAppList = GetDlgItem(hDlg, IDC_LIST_APPS);
int nApp = ListView_GetNextItem(hAppList, -1, LVNI_SELECTED);
if (nApp == -1) { return; }
LVITEM lvi;
lvi.mask = LVIF_PARAM; lvi.iItem = nApp; lvi.iSubItem = 0;
ListView_GetItem(hAppList, &lvi);
CAVAppInfo *pApp = (CAVAppInfo*)lvi.lParam;
//
// if there is a debugger set for this app, for various reasons we want to
// kill the debugger before removing the app, or the debugger may linger forever
//
if (pApp->bBreakOnLog || pApp->bUseAVDebugger) { pApp->bBreakOnLog = FALSE; pApp->bUseAVDebugger = FALSE;
SetCurrentAppSettings(); }
g_aAppInfo.erase(pApp);
RefreshAppList(hDlg);
SelectApp(hDlg, nApp);
DirtySettings(hDlg, TRUE); }
typedef struct _CONFLICT_DLG_INFO { CTestInfo *pTest1; CTestInfo *pTest2; } CONFLICT_DLG_INFO, *PCONFLICT_DLG_INFO;
void CheckForRunAlone( CAVAppInfo *pApp ) { if (!pApp) { return; }
DWORD dwTests = 0;
//
// count the number of tests active
//
for (CTestInfo *pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pApp->IsTestActive(*pTest)) { dwTests++; } }
//
// look for conflicts
//
for (CTestInfo *pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { //
// if there are less than two, no chance for conflict
//
if (dwTests < 2) { return; }
if (pTest->bRunAlone && pApp->IsTestActive(*pTest)) { CONFLICT_DLG_INFO DlgInfo;
ZeroMemory(&DlgInfo, sizeof(DlgInfo));
DlgInfo.pTest1 = pTest; // pTest2 is unused in this case
INT_PTR nResult = DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_MUST_RUN_ALONE), g_hDlgMain, DlgRunAlone, (LPARAM)&DlgInfo);
switch (nResult) { case IDC_BTN_DISABLE1: pApp->RemoveTest(*pTest); DirtySettings(g_hDlgMain, TRUE); RefreshSettingsList(g_hDlgMain, TRUE); dwTests--; break;
case IDC_BTN_DISABLE2: //
// disable all the tests except the one passed in
//
for (CTestInfo *pTestTemp = g_aTestInfo.begin(); pTestTemp != g_aTestInfo.end(); pTestTemp++) { if (pTest != pTestTemp) { pApp->RemoveTest(*pTestTemp); } } DirtySettings(g_hDlgMain, TRUE); RefreshSettingsList(g_hDlgMain, TRUE); dwTests = 1; break;
} } } }
void CheckForConflictingTests( CAVAppInfo *pApp, LPCWSTR wszTest1, LPCWSTR wszTest2 ) { CONFLICT_DLG_INFO DlgInfo;
ZeroMemory(&DlgInfo, sizeof(DlgInfo));
//
// get the test pointers from the names
//
for (CTestInfo *pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pTest->strTestName == wszTest1) { DlgInfo.pTest1 = pTest; } if (pTest->strTestName == wszTest2) { DlgInfo.pTest2 = pTest; } }
//
// if we didn't find one or the other tests, get out
//
if (!DlgInfo.pTest1 || !DlgInfo.pTest2) { return; }
if (pApp->IsTestActive(*DlgInfo.pTest1) && pApp->IsTestActive(*DlgInfo.pTest2)) { INT_PTR nResult = DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_CONFLICT), g_hDlgMain, DlgConflict, (LPARAM)&DlgInfo);
switch (nResult) { case IDC_BTN_DISABLE1: pApp->RemoveTest(*DlgInfo.pTest1); DirtySettings(g_hDlgMain, TRUE); RefreshSettingsList(g_hDlgMain, TRUE); break;
case IDC_BTN_DISABLE2: pApp->RemoveTest(*DlgInfo.pTest2); DirtySettings(g_hDlgMain, TRUE); RefreshSettingsList(g_hDlgMain, TRUE); break;
} } }
void ScanSettingsList( HWND hDlg, int nItem ) {
HWND hSettingList = GetDlgItem(hDlg, IDC_LIST_SETTINGS); HWND hAppList = GetDlgItem(hDlg, IDC_LIST_APPS); int nBegin, nEnd;
int nApp = ListView_GetNextItem(hAppList, -1, LVNI_SELECTED);
if (nApp == -1) { return; }
LVITEM lvi;
lvi.mask = LVIF_PARAM; lvi.iItem = nApp; lvi.iSubItem = 0;
ListView_GetItem(hAppList, &lvi);
CAVAppInfo *pApp = (CAVAppInfo*)lvi.lParam;
if (!pApp) { return; }
int nItems = ListView_GetItemCount(hSettingList);
if (!nItems) { //
// nothing in list
//
return; }
if (nItem == -1 || nItem >= nItems) { nBegin = 0; nEnd = nItems; } else { nBegin = nItem; nEnd = nItem + 1; }
for (int i = nBegin; i < nEnd; ++i) { BOOL bTestEnabled = FALSE; BOOL bChecked = FALSE;
lvi.iItem = i;
ListView_GetItem(hSettingList, &lvi);
CTestInfo *pTest = (CTestInfo*)lvi.lParam;
bChecked = ListView_GetCheckState(hSettingList, i);
bTestEnabled = pApp->IsTestActive(*pTest);
if (bTestEnabled != bChecked) { DirtySettings(hDlg, TRUE);
if (bChecked) { pApp->AddTest(*pTest); } else { pApp->RemoveTest(*pTest); } }
CheckForRunAlone(pApp); }
CheckForConflictingTests(pApp, L"LogFileChanges", L"WindowsFileProtection"); }
void DisplaySettingsDescription( HWND hDlg ) { HWND hList = GetDlgItem(hDlg, IDC_LIST_SETTINGS);
int nItem = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
if (nItem == -1) { WCHAR szTestDesc[256];
LoadString(g_hInstance, IDS_VIEW_TEST_DESC, szTestDesc, ARRAY_LENGTH(szTestDesc)); SetWindowText(GetDlgItem(hDlg, IDC_STATIC_DESC), szTestDesc); } else { LVITEM lvi;
lvi.mask = LVIF_PARAM; lvi.iItem = nItem; lvi.iSubItem = 0;
ListView_GetItem(hList, &lvi);
CTestInfo *pTest = (CTestInfo*)lvi.lParam;
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_DESC), pTest->strTestDescription.c_str()); }
}
CAVAppInfo * GetCurrentAppSelection( void ) { if (!g_hDlgMain) { return NULL; }
HWND hAppList = GetDlgItem(g_hDlgMain, IDC_LIST_APPS);
int nItem = ListView_GetNextItem(hAppList, -1, LVNI_SELECTED);
if (nItem == -1) { return NULL; }
LVITEM lvi;
lvi.mask = LVIF_PARAM; lvi.iItem = nItem; lvi.iSubItem = 0;
ListView_GetItem(hAppList, &lvi);
CAVAppInfo *pApp = (CAVAppInfo*)lvi.lParam;
return pApp;
}
void RefreshSettingsList( HWND hDlg, BOOL bForceRefresh ) { g_bRefreshingSettings = TRUE;
HWND hSettingList = GetDlgItem(hDlg, IDC_LIST_SETTINGS); HWND hAppList = GetDlgItem(hDlg, IDC_LIST_APPS);
static nLastItem = -1;
int nItem = ListView_GetNextItem(hAppList, -1, LVNI_SELECTED);
if (nItem == -1) {
EnableWindow(GetDlgItem(hDlg, IDC_BTN_RUN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_REMOVE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_OPTIONS), FALSE);
} else if (nItem == 0) { EnableWindow(GetDlgItem(hDlg, IDC_BTN_RUN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_REMOVE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_OPTIONS), TRUE);
} else { EnableWindow(GetDlgItem(hDlg, IDC_BTN_RUN), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_REMOVE), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_OPTIONS), TRUE); }
if (nItem == nLastItem && !bForceRefresh) { goto out;
}
ListView_DeleteAllItems(hSettingList);
DisplaySettingsDescription(hDlg);
nLastItem = nItem;
if (nItem != -1) { LVITEM lvi;
lvi.mask = LVIF_PARAM; lvi.iItem = nItem; lvi.iSubItem = 0;
ListView_GetItem(hAppList, &lvi);
CAVAppInfo *pApp = (CAVAppInfo*)lvi.lParam;
if (!pApp) { return; }
CTestInfo* pTest;
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { //
// continue if this test isn't win2K compatible, and we're running on win2k
//
if (g_bWin2KMode && !pTest->bWin2KCompatible) { continue; }
//
// continue if this test is invalid for the current internal/external mode
//
if ((g_bInternalMode && !pTest->bInternal) || (!g_bInternalMode && !pTest->bExternal)) { continue; }
WCHAR szText[256];
//
// don't check the return, because if it's truncated, that's acceptable
//
StringCchPrintfW(szText, ARRAY_LENGTH(szText), L"%s - %s", pTest->strTestName.c_str(), pTest->strTestFriendlyName.c_str());
lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.pszText = (LPWSTR)szText; lvi.lParam = (LPARAM)pTest; lvi.iItem = 9999; lvi.iSubItem = 0;
nItem = ListView_InsertItem(hSettingList, &lvi);
BOOL bCheck = pApp->IsTestActive(*pTest);
ListView_SetCheckState(hSettingList, nItem, bCheck); } } out:
g_bRefreshingSettings = FALSE;
return; }
static const DWORD MAX_DEBUGGER_LEN = 1024;
void ReadOptions( void ) { for (CAVAppInfo *pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); ++pApp) { LPCWSTR szExe = pApp->wstrExeName.c_str();
WCHAR szDebugger[MAX_DEBUGGER_LEN];
pApp->bBreakOnLog = GetShimSettingDWORD(L"General", szExe, AV_OPTION_BREAK_ON_LOG, FALSE); pApp->bFullPageHeap = GetShimSettingDWORD(L"General", szExe, AV_OPTION_FULL_PAGEHEAP, FALSE); pApp->bUseAVDebugger = GetShimSettingDWORD(L"General", szExe, AV_OPTION_AV_DEBUGGER, FALSE); pApp->bPropagateTests = GetShimSettingDWORD(L"General", szExe, AV_OPTION_PROPAGATE, FALSE);
szDebugger[0] = 0; GetShimSettingString(L"General", szExe, AV_OPTION_DEBUGGER, szDebugger, MAX_DEBUGGER_LEN); pApp->wstrDebugger = szDebugger; } }
void SaveOptions( void ) {
for (CAVAppInfo *pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); ++pApp) { LPCWSTR szExe = pApp->wstrExeName.c_str();
SaveShimSettingDWORD(L"General", szExe, AV_OPTION_BREAK_ON_LOG, (DWORD)pApp->bBreakOnLog); SaveShimSettingDWORD(L"General", szExe, AV_OPTION_FULL_PAGEHEAP, (DWORD)pApp->bFullPageHeap); SaveShimSettingDWORD(L"General", szExe, AV_OPTION_AV_DEBUGGER, (DWORD)pApp->bUseAVDebugger); SaveShimSettingDWORD(L"General", szExe, AV_OPTION_PROPAGATE, (DWORD)pApp->bPropagateTests); SaveShimSettingString(L"General", szExe, AV_OPTION_DEBUGGER, pApp->wstrDebugger.c_str()); }
SetCurrentAppSettings(); }
INT_PTR CALLBACK DlgRunAlone( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_INITDIALOG: { WCHAR wszTemp[256]; WCHAR wszExpandedTemp[512]; PCONFLICT_DLG_INFO pDlgInfo;
pDlgInfo = (PCONFLICT_DLG_INFO)lParam;
wszTemp[0] = 0; AVLoadString(IDS_RUN_ALONE_MESSAGE, wszTemp, ARRAY_LENGTH(wszTemp));
StringCchPrintfW( wszExpandedTemp, ARRAY_LENGTH(wszExpandedTemp), wszTemp, pDlgInfo->pTest1->strTestFriendlyName.c_str() );
SetDlgItemTextW(hDlg, IDC_CONFLICT_STATIC, wszExpandedTemp);
return TRUE; }
case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_DISABLE1: case IDC_BTN_DISABLE2: case IDCANCEL: //
// return the button that was pressed
//
EndDialog(hDlg, (INT_PTR)LOWORD(wParam)); break; } break;
}
return FALSE; }
INT_PTR CALLBACK DlgConflict( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_INITDIALOG: { WCHAR wszTemp[256]; WCHAR wszExpandedTemp[512]; PCONFLICT_DLG_INFO pDlgInfo;
pDlgInfo = (PCONFLICT_DLG_INFO)lParam;
wszTemp[0] = 0; AVLoadString(IDS_CONFLICT_MESSAGE, wszTemp, ARRAY_LENGTH(wszTemp));
StringCchPrintf( wszExpandedTemp, ARRAY_LENGTH(wszExpandedTemp), wszTemp, pDlgInfo->pTest1->strTestFriendlyName.c_str(), pDlgInfo->pTest2->strTestFriendlyName.c_str() );
SetDlgItemTextW(hDlg, IDC_CONFLICT_STATIC, wszExpandedTemp);
return TRUE; }
case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_DISABLE1: case IDC_BTN_DISABLE2: case IDCANCEL: //
// return the button that was pressed
//
EndDialog(hDlg, (INT_PTR)LOWORD(wParam)); break; } break;
}
return FALSE; }
INT_PTR CALLBACK DlgViewOptions( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { static CAVAppInfo *pApp;
switch (message) { case WM_INITDIALOG:
g_hDlgOptions = hDlg; pApp = GetCurrentAppSelection();
if (!pApp) { return FALSE; }
ReadOptions();
//
// initialize the combo box options
//
SendDlgItemMessage(hDlg, IDC_COMBO_DEBUGGER, CB_ADDSTRING, 0, (LPARAM)L"ntsd"); SendDlgItemMessage(hDlg, IDC_COMBO_DEBUGGER, CB_ADDSTRING, 0, (LPARAM)L"windbg");
if (pApp->bBreakOnLog) { pApp->bUseAVDebugger = FALSE; EnableWindow(GetDlgItem(hDlg, IDC_USE_AV_DEBUGGER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_DEBUGGER), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DEBUGGER), TRUE);
if (!pApp->wstrDebugger.size()) { SetDlgItemText(hDlg, IDC_COMBO_DEBUGGER, L"ntsd"); } else { SetDlgItemText(hDlg, IDC_COMBO_DEBUGGER, pApp->wstrDebugger.c_str()); } } else { EnableWindow(GetDlgItem(hDlg, IDC_USE_AV_DEBUGGER), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_DEBUGGER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DEBUGGER), FALSE); }
/*SendDlgItemMessage(hDlg,
IDC_CLEAR_LOG_ON_CHANGES, BM_SETCHECK, (pApp->bClearSessionLogBeforeRun ? BST_CHECKED : BST_UNCHECKED), 0);*/
SendDlgItemMessage(hDlg, IDC_BREAK_ON_LOG, BM_SETCHECK, (pApp->bBreakOnLog ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hDlg, IDC_FULL_PAGEHEAP, BM_SETCHECK, (pApp->bFullPageHeap ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hDlg, IDC_USE_AV_DEBUGGER, BM_SETCHECK, (pApp->bUseAVDebugger ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hDlg, IDC_PROPAGATE_TESTS, BM_SETCHECK, (pApp->bPropagateTests ? BST_CHECKED : BST_UNCHECKED), 0);
return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BREAK_ON_LOG: { BOOL bChecked = IsDlgButtonChecked(hDlg, IDC_BREAK_ON_LOG); if (bChecked) { WCHAR szTemp[256];
CheckDlgButton(hDlg, IDC_USE_AV_DEBUGGER, BST_UNCHECKED); EnableWindow(GetDlgItem(hDlg, IDC_USE_AV_DEBUGGER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_DEBUGGER), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DEBUGGER), TRUE);
GetDlgItemText(hDlg, IDC_COMBO_DEBUGGER, szTemp, ARRAY_LENGTH(szTemp));
if (!szTemp[0]) { if (!pApp->wstrDebugger.size()) { SetDlgItemText(hDlg, IDC_COMBO_DEBUGGER, L"ntsd"); } else { SetDlgItemText(hDlg, IDC_COMBO_DEBUGGER, pApp->wstrDebugger.c_str()); } } } else { EnableWindow(GetDlgItem(hDlg, IDC_USE_AV_DEBUGGER), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_DEBUGGER), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_COMBO_DEBUGGER), FALSE); } } break; } break;
case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) {
case PSN_APPLY: /* pApp->bClearSessionLogBeforeRun = (SendDlgItemMessage(hDlg,
IDC_CLEAR_LOG_ON_CHANGES, BM_GETCHECK, 0, 0) == BST_CHECKED);*/
pApp->bBreakOnLog = (SendDlgItemMessage(hDlg, IDC_BREAK_ON_LOG, BM_GETCHECK, 0, 0) == BST_CHECKED);
pApp->bFullPageHeap = (SendDlgItemMessage(hDlg, IDC_FULL_PAGEHEAP, BM_GETCHECK, 0, 0) == BST_CHECKED);
pApp->bUseAVDebugger = (SendDlgItemMessage(hDlg, IDC_USE_AV_DEBUGGER, BM_GETCHECK, 0, 0) == BST_CHECKED);
pApp->bPropagateTests = (SendDlgItemMessage(hDlg, IDC_PROPAGATE_TESTS, BM_GETCHECK, 0, 0) == BST_CHECKED);
WCHAR szDebugger[MAX_DEBUGGER_LEN];
szDebugger[0] = 0; GetDlgItemText(hDlg, IDC_COMBO_DEBUGGER, szDebugger, ARRAY_LENGTH(szDebugger));
pApp->wstrDebugger = szDebugger;
SaveOptions();
g_hDlgOptions = NULL;
break; } }
return FALSE; }
void ViewOptions( HWND hDlg ) { HPROPSHEETPAGE *phPages = NULL; PROPSHEETPAGE PageGlobal; PROPSHEETHEADER psh;
CTestInfo* pTest; DWORD dwPages = 1; DWORD dwPage = 0;
CAVAppInfo *pApp = GetCurrentAppSelection();
if (!pApp) { return; }
LPCWSTR szExe = pApp->wstrExeName.c_str();
//
// count the number of pages
//
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pTest->PropSheetPage.pfnDlgProc) { dwPages++; } }
phPages = new HPROPSHEETPAGE[dwPages]; if (!phPages) { return; }
//
// init the global page
//
PageGlobal.dwSize = sizeof(PROPSHEETPAGE); PageGlobal.dwFlags = PSP_USETITLE; PageGlobal.hInstance = g_hInstance; PageGlobal.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS); PageGlobal.pfnDlgProc = DlgViewOptions; PageGlobal.pszTitle = MAKEINTRESOURCE(IDS_GLOBAL_OPTIONS); PageGlobal.lParam = 0; PageGlobal.pfnCallback = NULL; phPages[0] = CreatePropertySheetPage(&PageGlobal);
if (!phPages[0]) { //
// we need the global page minimum
//
return; }
//
// add the pages for the various tests
//
dwPage = 1; for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) { if (pTest->PropSheetPage.pfnDlgProc) {
//
// we use the lParam to identify the exe involved
//
pTest->PropSheetPage.lParam = (LPARAM)szExe;
phPages[dwPage] = CreatePropertySheetPage(&(pTest->PropSheetPage)); if (!phPages[dwPage]) { dwPages--; } else { dwPage++; } } }
wstring wstrOptions; AVLoadString(IDS_OPTIONS_TITLE, wstrOptions);
wstrOptions += L" - "; wstrOptions += szExe;
psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP; psh.hwndParent = hDlg; psh.hInstance = g_hInstance; psh.pszCaption = wstrOptions.c_str(); psh.nPages = dwPages; psh.nStartPage = 0; psh.phpage = phPages; psh.pfnCallback = NULL;
PropertySheet(&psh); }
// Message handler for main dialog.
INT_PTR CALLBACK DlgMain( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_INITDIALOG: { wstring strTemp;
g_hDlgMain = hDlg;
//
// set the caption to the appropriate version, etc.
//
if (GetAppTitleString(strTemp)) { SetWindowText(hDlg, strTemp.c_str()); } EnableWindow(GetDlgItem(hDlg, IDC_BTN_RUN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_REMOVE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_SAVE_SETTINGS), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_BTN_OPTIONS), FALSE);
HWND hList = GetDlgItem(hDlg, IDC_LIST_SETTINGS);
if (hList) { LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; lvc.fmt = LVCFMT_LEFT; lvc.cx = 700; lvc.iSubItem = 0; lvc.pszText = L"xxx";
ListView_InsertColumn(hList, 0, &lvc); ListView_SetExtendedListViewStyleEx(hList, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
}
hList = GetDlgItem(hDlg, IDC_LIST_APPS); if (hList) { LVITEM lvi; LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; lvc.fmt = LVCFMT_LEFT; lvc.cx = 250; lvc.iSubItem = 0; lvc.pszText = L"xxx";
ListView_InsertColumn(hList, 0, &lvc);
RefreshAppList(hDlg);
SelectApp(hDlg, 0); }
WCHAR szTestDesc[256];
LoadString(g_hInstance, IDS_VIEW_TEST_DESC, szTestDesc, ARRAY_LENGTH(szTestDesc)); SetWindowText(GetDlgItem(hDlg, IDC_STATIC_DESC), szTestDesc);
//
// Show the app icon.
//
HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON));
SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hIcon);
return TRUE; } break;
case WM_ACTIVATE: if (LOWORD(wParam) == WA_INACTIVE) { SaveSettingsIfDirty(hDlg); } break;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_ADD: AddAppToList(hDlg); break;
case IDC_BTN_REMOVE: RemoveSelectedApp(hDlg); break;
case IDC_BTN_VIEW_LOG: DisplayLog(hDlg); break;
case IDC_BTN_VIEW_EXTERNAL_LOG: DisplaySingleLog(hDlg); break;
case IDC_BTN_OPTIONS: ViewOptions(hDlg); break;
case IDC_BTN_RUN: RunSelectedApp(hDlg); break;
case IDC_BTN_HELP: ShowHTMLHelp(); break;
case IDOK: case IDCANCEL: SaveSettings(hDlg); EndDialog(hDlg, LOWORD(wParam)); g_hDlgMain = NULL; PostQuitMessage(0); return TRUE; break; } break;
case WM_NOTIFY: LPNMHDR pnmh = (LPNMHDR)lParam;
HWND hItem = pnmh->hwndFrom;
if (hItem == GetDlgItem(hDlg, IDC_LIST_APPS)) { switch (pnmh->code) { case LVN_KEYDOWN: { LPNMLVKEYDOWN pnmkd = (LPNMLVKEYDOWN)lParam;
if (pnmkd->wVKey == VK_DELETE) { if (IsWindowEnabled(GetDlgItem(hDlg, IDC_BTN_RUN))) { RemoveSelectedApp(hDlg); } } } break;
case LVN_ITEMCHANGED: LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
if (!g_bRefreshingSettings && (pnmv->uChanged & LVIF_STATE) && ((pnmv->uNewState ^ pnmv->uOldState) & LVIS_SELECTED)) { RefreshSettingsList(hDlg); }
} } else if (hItem == GetDlgItem(hDlg, IDC_LIST_SETTINGS)) { switch (pnmh->code) { case LVN_ITEMCHANGED: LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
if (!g_bRefreshingSettings) { //
// check for change in selection
//
if ((pnmv->uChanged & LVIF_STATE) && ((pnmv->uNewState ^ pnmv->uOldState) & LVIS_SELECTED)) { DisplaySettingsDescription(hDlg); }
//
// check for change in checkbox
//
if ((pnmv->uChanged & LVIF_STATE) && ((pnmv->uNewState ^ pnmv->uOldState) >> 12) != 0) { ScanSettingsList(hDlg, pnmv->iItem); } } break; } } break; } return FALSE; }
|