* Copyright (c) 2012-2014 Google, Inc. All rights reserved.
* Copyright (c) 2007-2008 VMware, Inc. All rights reserved.
* **********************************************************/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of VMware, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#include "stdafx.h"
#include "DynamoRIO.h"
#include "MainFrm.h"
#include "DynamoRIODoc.h"
#include "DynamoRIOView.h"
#include "OptionsDlg.h"
#include "IgnoreDlg.h"
#include "SyswideDlg.h"
#include <assert.h>
#include <process.h>
#ifdef _DEBUG
# define new DEBUG_NEW
# undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define HELP_PATH _T("\\docs\\html\\index.html")
#define INITIAL_OPTIONS _T("-stats -loglevel 1")
#define INITIAL_SYSTEMWIDE _T("\\lib\\debug\\dynamorio.dll")
#define INITIAL_IGNORE _T("drinject.exe;DynamoRIO.exe")
BEGIN_MESSAGE_MAP(CDynamoRIOApp, CWinApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_APP_EXIT, OnAppExit)
#ifndef DRSTATS_DEMO
ON_COMMAND(ID_EDIT_OPTIONS, OnEditOptions)
ON_COMMAND(ID_LIBRARY_RELEASE, OnLibraryRelease)
ON_COMMAND(ID_LIBRARY_PROFILE, OnLibraryProfile)
ON_COMMAND(ID_LIBRARY_DEBUG, OnLibraryDebug)
ON_COMMAND(ID_FILE_RUN, OnFileRun)
ON_COMMAND(ID_FILE_SYSTEMWIDE, OnFileSystemwide)
ON_COMMAND(ID_HELP_HELP, OnHelpHelp)
ON_COMMAND(ID_EDIT_IGNORELIST, OnEditIgnorelist)
#endif
#ifndef DRSTATS_DEMO
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
#endif
END_MESSAGE_MAP()
CDynamoRIOApp::CDynamoRIOApp()
{
}
CDynamoRIOApp theApp;
CDynamoRIOView *
CDynamoRIOApp::GetActiveView()
{
return (CDynamoRIOView *)theApp.m_pMainFrame->GetActiveView();
}
#ifndef DRSTATS_DEMO
BOOL
CDynamoRIOApp::SystemwideSet()
{
return theApp.m_bInjectAll;
}
TCHAR *
CDynamoRIOApp::GetDllPath()
{
return theApp.m_dll_path;
}
DLL_TYPE
CDynamoRIOApp::GetDllType()
{
return theApp.m_dll_type;
}
void
CDynamoRIOApp::SetSystemwideSetting(int val)
{
theApp.WriteProfileInt(_T("Settings"), _T("Confirm Systemwide"), val);
}
void
CDynamoRIOApp::AboutToExit()
{
theApp.PreExit();
}
#endif
void
CDynamoRIOApp::SetStatusbarText(TCHAR *txt)
{
theApp.m_pMainFrame->SetStatusBarText(0, txt);
}
BOOL
CDynamoRIOApp::InitInstance()
{
#ifndef DRSTATS_DEMO
TCHAR msg[MAX_PATH * 2];
#endif
BOOL windows_NT;
if (!CheckWindowsVersion(windows_NT)) {
return FALSE;
}
#if 0
# ifdef _AFXDLL
Enable3dControls();
# else
Enable3dControlsStatic();
# endif
#endif
#ifndef DRSTATS_DEMO
SetRegistryKey(L_DYNAMORIO_REGISTRY_KEY);
LoadStdProfileSettings(12);
#endif
CSingleDocTemplate *pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
#ifdef DRSTATS_DEMO
IDR_MAINFRAME_DEMO,
#else
IDR_MAINFRAME,
#endif
RUNTIME_CLASS(CDynamoRIODoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CDynamoRIOView));
AddDocTemplate(pDocTemplate);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
return FALSE;
m_pMainWnd->DragAcceptFiles();
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
m_pMainFrame = (CMainFrame *)m_pMainWnd;
m_pMainFrame->m_bAutoMenuEnable = FALSE;
#ifndef DRSTATS_DEMO
m_bSystemwideAllowed = TRUE;
TCHAR data[1024];
int len = GetEnvironmentVariable(_T("DYNAMORIO_HOME"), m_dynamorio_home, _MAX_DIR);
if (len == 0) {
int res = MessageBox(
NULL,
_T("DYNAMORIO_HOME environment variable not found.\n")
_T("Set all the DynamoRIO environment variables to their default values?\n")
_T("(Otherwise this GUI cannot operate and must exit.)"),
_T("DynamoRIO Not Configured for Current User"), MB_YESNO | MYMBFLAGS);
if (res == IDYES) {
if (!ConfigureForNewUser())
return FALSE;
} else {
return FALSE;
}
}
if (windows_NT) {
if (GetProfileInt(_T("Settings"), _T("Confirm Systemwide"), 1) == 1) {
MessageBox(NULL,
_T("Run All is not supported on Windows NT, it will be disabled"),
_T("Notice"), MB_OK | MYMBFLAGS);
SetSystemwideSetting(0);
}
m_bSystemwideAllowed = FALSE;
DisableSystemwideInject();
} else {
assert(len > 0 && len < _MAX_DIR &&
len + _tcslen(L_INJECT_ALL_DLL_SUBPATH) < MAX_PATH);
_stprintf(data, _T("%s%s"), m_dynamorio_home, L_INJECT_ALL_DLL_SUBPATH);
CFile check;
if (!check.Open(data, CFile::modeRead | CFile::shareDenyNone)) {
# if 0
_stprintf(msg, _T("Library %s does not exist"), data);
MessageBox(NULL, msg, _T("Error"), MB_OK | MYMBFLAGS);
# endif
m_bSystemwideAllowed = FALSE;
DisableSystemwideInject();
} else {
if (_tcschr(data, _T(' ')) != NULL) {
len = GetShortPathName(data, m_inject_all_value, MAX_PATH);
if (len == 0) {
_stprintf(msg,
_T("Cannot find 8.3 alias for space-containing path ")
_T("\"%s\"!\nDisabling Run All"),
data);
MessageBox(NULL, msg, _T("Error"), MB_OK | MYMBFLAGS);
m_bSystemwideAllowed = FALSE;
DisableSystemwideInject();
}
} else {
_tcscpy(m_inject_all_value, data);
}
check.Close();
}
}
if (m_bSystemwideAllowed) {
HKEY hk;
unsigned long size = 1024;
int res = RegOpenKeyEx(INJECT_ALL_HIVE, INJECT_ALL_KEY_L, 0, KEY_READ, &hk);
assert(res == ERROR_SUCCESS);
res = RegQueryValueEx(hk, INJECT_ALL_SUBKEY_L, 0, NULL, (LPBYTE)data, &size);
assert(res == ERROR_SUCCESS);
RegCloseKey(hk);
if (size > sizeof(TCHAR)) {
if (_tcscmp(m_inject_all_value, data) != 0) {
int res = MessageBox(
NULL,
_T("DynamoRIO's RunAll system-wide injection method is ")
_T("being used by some other program.\n")
_T("DynamoRIO can attempt to override the other program.\n")
_T("Otherwise, system-wide injection will be disabled.\n")
_T("Override?"),
_T("DynamoRIO Conflict"), MB_YESNO | MYMBFLAGS);
if (res == IDYES) {
SetSystemwideInject(_T(""));
} else {
m_bSystemwideAllowed = FALSE;
DisableSystemwideInject();
}
} else {
m_bInjectAll = TRUE;
}
} else {
m_bInjectAll = FALSE;
}
}
if (m_bSystemwideAllowed) {
m_pMainWnd->GetMenu()->CheckMenuItem(
ID_FILE_SYSTEMWIDE,
MF_BYCOMMAND | ((m_bInjectAll) ? MF_CHECKED : MF_UNCHECKED));
}
if (m_bSystemwideAllowed) {
CFile check;
if (!check.Open(m_inject_all_value, CFile::modeRead | CFile::shareDenyNone)) {
# if 0
_stprintf(msg, _T("Library %s does not exist!\nDisabling Run All"), m_inject_all_value);
MessageBox(NULL, msg, _T("DynamoRIO Configuration Error"), MB_OK | MYMBFLAGS);
# endif
DisableSystemwideInject();
} else
check.Close();
}
m_dll_path[0] = _T('\0');
DisableMissingLibraries(TRUE);
int lib = GetProfileInt(_T("Settings"), _T("Library"), 1);
int tried = 0;
while (tried < 3) {
if (lib == 0 && SwitchLibraries(L_DLLPATH_RELEASE, FALSE)) {
OnLibraryRelease();
break;
} else if (lib == 1 && SwitchLibraries(L_DLLPATH_DEBUG, FALSE)) {
OnLibraryDebug();
break;
} else if (lib == 2 && SwitchLibraries(L_DLLPATH_PROFILE, FALSE)) {
OnLibraryProfile();
break;
}
lib = (lib + 1) % 3;
tried++;
}
if (tried == 3) {
# if 0
MessageBox(NULL, _T("Cannot find any DynamoRIO libraries!\n")
_T("Running of applications will be disabled."), _T("Error"), MB_OK | MYMBFLAGS);
# endif
m_pMainWnd->GetMenu()->EnableMenuItem(ID_FILE_RUN, MF_BYCOMMAND | MF_GRAYED);
DisableSystemwideInject();
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_RELEASE,
MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_PROFILE,
MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_RELEASE,
MF_BYCOMMAND | MF_UNCHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_DEBUG,
MF_BYCOMMAND | MF_UNCHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_PROFILE,
MF_BYCOMMAND | MF_UNCHECKED);
}
if (m_bInjectAll) {
MessageBox(NULL, _T("Run All is already set!"), _T("Warning"), MB_OK | MYMBFLAGS);
SetEnvVarPermanently(_T("DYNAMORIO_SYSTEMWIDE"), m_dll_path);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_RELEASE,
MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_PROFILE,
MF_BYCOMMAND | MF_GRAYED);
}
#endif
return TRUE;
}
BOOL
CDynamoRIOApp::GetWindowsVersion(OSVERSIONINFOW *version)
{
typedef DWORD NTSTATUS;
typedef NTSTATUS(NTAPI * RtlGetVersion_t)(OSVERSIONINFOW * info);
#define NT_SUCCESS(res) ((res) >= 0)
RtlGetVersion_t RtlGetVersion;
NTSTATUS res;
HANDLE ntdll_handle = GetModuleHandle(_T("ntdll.dll"));
if (ntdll_handle == NULL)
return FALSE;
RtlGetVersion =
(RtlGetVersion_t)GetProcAddress((HMODULE)ntdll_handle, "RtlGetVersion");
if (RtlGetVersion == NULL)
return FALSE;
version->dwOSVersionInfoSize = sizeof(*version);
res = RtlGetVersion(version);
return NT_SUCCESS(res);
}
BOOL
CDynamoRIOApp::CheckWindowsVersion(BOOL &windows_NT)
{
windows_NT = FALSE;
TCHAR bad_os[64];
OSVERSIONINFOW version;
BOOL res = GetWindowsVersion(&version);
assert(res);
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
if (version.dwMajorVersion == 4) {
windows_NT = TRUE;
} else {
}
return TRUE;
} else if (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
unsigned ver_high = (version.dwBuildNumber >> 24) & 0xff;
unsigned ver_low = (version.dwBuildNumber >> 16) & 0xff;
if (ver_low >= 90 || ver_high >= 5)
_stprintf(bad_os, _T("Windows ME"));
else if (ver_low >= 10 && ver_low < 90)
_stprintf(bad_os, _T("Windows 98"));
else if (ver_low < 5)
_stprintf(bad_os, _T("Windows 31 / WfWg"));
else if (ver_low < 10)
_stprintf(bad_os, _T("Windows 98"));
else
assert(false);
} else {
_stprintf(bad_os, _T("Win32s"));
}
TCHAR msg[128];
_stprintf(msg, _T("DynamoRIO does not support %s"), bad_os);
MessageBox(m_pMainFrame->m_hWnd, msg, _T("Fatal Error"), MB_OK | MYMBFLAGS);
return FALSE;
}
class CAboutDlg : public CDialog {
public:
CAboutDlg();
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void
DoDataExchange(CDataExchange *pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg()
: CDialog(CAboutDlg::IDD)
{
}
void
CAboutDlg::DoDataExchange(CDataExchange *pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
void
CDynamoRIOApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
CDocument *
CDynamoRIOApp::OpenDocumentFile(LPCTSTR
#ifndef DRSTATS_DEMO
lpszFileName
#endif
)
{
#ifndef DRSTATS_DEMO
RunNewApp(lpszFileName);
#endif
return m_pMainFrame->GetActiveView()->GetDocument();
}
#ifndef DRSTATS_DEMO
static TCHAR szFilter[] = _T("Executable Files (*.exe)|*.exe|All Files (*.*)|*.*||");
void
CDynamoRIOApp::OnFileRun()
{
CFileDialog fileDlg(TRUE, _T(".exe"), NULL,
OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
szFilter);
int res = fileDlg.DoModal();
if (res == IDCANCEL)
return;
CString file = fileDlg.GetPathName();
RunNewApp(file);
}
BOOL
CDynamoRIOApp::RunNewApp(LPCTSTR lpszFileName)
{
m_pMainFrame->SetStatusBarText(0, lpszFileName);
AddToRecentFileList(lpszFileName);
CDynamoRIODoc *doc = (CDynamoRIODoc *)m_pMainFrame->GetActiveView()->GetDocument();
doc->RunApplication(lpszFileName);
return TRUE;
}
void
CDynamoRIOApp::OnFileSystemwide()
{
assert(m_bSystemwideAllowed);
if (!m_bInjectAll &&
GetProfileInt(_T("Settings"), _T("Confirm Systemwide"), 1) == 1) {
CSyswideDlg dlg;
int res = dlg.DoModal();
if (res == IDCANCEL)
return;
}
TCHAR *val;
if (m_bInjectAll) {
m_bInjectAll = FALSE;
val = _T("");
DisableMissingLibraries(FALSE);
} else {
m_bInjectAll = TRUE;
val = m_inject_all_value;
SetEnvVarPermanently(_T("DYNAMORIO_SYSTEMWIDE"), m_dll_path);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_RELEASE,
MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_GRAYED);
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_PROFILE,
MF_BYCOMMAND | MF_GRAYED);
}
if (!SetSystemwideInject(val))
return;
m_pMainWnd->GetMenu()->CheckMenuItem(
ID_FILE_SYSTEMWIDE, MF_BYCOMMAND | ((m_bInjectAll) ? MF_CHECKED : MF_UNCHECKED));
}
BOOL
CDynamoRIOApp::SetSystemwideInject(TCHAR *val)
{
assert(m_bSystemwideAllowed);
HKEY hk;
int res = RegOpenKeyEx(INJECT_ALL_HIVE, INJECT_ALL_KEY_L, 0, KEY_WRITE, &hk);
if (res != ERROR_SUCCESS) {
MessageBox(
NULL,
_T("DynamoRIO's system-wide injection method requires administrative ")
_T("privileges.\n")
_T("You must restart this program with such privileges to use this feature."),
_T("Lack of Privileges"), MB_OK | MYMBFLAGS);
m_bSystemwideAllowed = FALSE;
DisableSystemwideInject();
return FALSE;
}
res =
RegSetValueEx(hk, INJECT_ALL_SUBKEY_L, 0, REG_SZ, (LPBYTE)val, _tcslen(val) + 1);
assert(res == ERROR_SUCCESS);
RegCloseKey(hk);
return TRUE;
}
void
CDynamoRIOApp::DisableSystemwideInject()
{
if (m_bSystemwideAllowed) {
SetSystemwideInject(_T(""));
}
m_bSystemwideAllowed = FALSE;
m_bInjectAll = FALSE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_FILE_SYSTEMWIDE, MF_BYCOMMAND | MF_GRAYED);
m_pMainFrame->SetStatusBarText(0, _T("Disabled system-wide injection"));
}
void
CDynamoRIOApp::OnEditOptions()
{
COptionsDlg ops;
ops.DoModal();
}
void
CDynamoRIOApp::OnEditIgnorelist()
{
CIgnoreDlg dlg;
dlg.DoModal();
}
void
CDynamoRIOApp::DisableMissingLibraries(BOOL notify)
{
BOOL release_ok, debug_ok, profile_ok;
if (SwitchLibraries(L_DLLPATH_RELEASE, notify)) {
release_ok = TRUE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_RELEASE, MF_BYCOMMAND);
} else {
release_ok = FALSE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_RELEASE,
MF_BYCOMMAND | MF_GRAYED);
}
if (SwitchLibraries(L_DLLPATH_DEBUG, notify)) {
debug_ok = TRUE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND);
} else {
debug_ok = FALSE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_GRAYED);
}
if (SwitchLibraries(L_DLLPATH_PROFILE, notify)) {
profile_ok = TRUE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_PROFILE, MF_BYCOMMAND);
} else {
profile_ok = FALSE;
m_pMainWnd->GetMenu()->EnableMenuItem(ID_LIBRARY_PROFILE,
MF_BYCOMMAND | MF_GRAYED);
}
}
BOOL
CDynamoRIOApp::SwitchLibraries(TCHAR *newdllpath, BOOL notify)
{
CFile check;
TCHAR msg[MAX_PATH * 2];
TCHAR file[MAX_PATH];
assert(_tcslen(m_dynamorio_home) + _tcslen(newdllpath) < MAX_PATH);
_stprintf(file, _T("%s%s"), m_dynamorio_home, newdllpath);
if (!check.Open(file, CFile::modeRead | CFile::shareDenyNone)) {
if (notify) {
_stprintf(msg, _T("Library %s does not exist"), file);
# if 0
MessageBox(NULL, msg, _T("DynamoRIO Configuration Error"), MB_OK | MYMBFLAGS);
# endif
}
return FALSE;
}
check.Close();
_tcscpy(m_dll_path, file);
return TRUE;
}
void
CDynamoRIOApp::OnLibraryRelease()
{
if (!SwitchLibraries(L_DLLPATH_RELEASE, TRUE))
return;
m_dll_type = DLL_RELEASE;
COptionsDlg::CheckOptionsVersusDllType(m_dll_type);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_RELEASE, MF_BYCOMMAND | MF_CHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_UNCHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_PROFILE, MF_BYCOMMAND | MF_UNCHECKED);
}
void
CDynamoRIOApp::OnLibraryDebug()
{
if (!SwitchLibraries(L_DLLPATH_DEBUG, TRUE))
return;
m_dll_type = DLL_DEBUG;
COptionsDlg::CheckOptionsVersusDllType(m_dll_type);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_RELEASE, MF_BYCOMMAND | MF_UNCHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_CHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_PROFILE, MF_BYCOMMAND | MF_UNCHECKED);
}
void
CDynamoRIOApp::OnLibraryProfile()
{
if (!SwitchLibraries(L_DLLPATH_PROFILE, TRUE))
return;
m_dll_type = DLL_PROFILE;
COptionsDlg::CheckOptionsVersusDllType(m_dll_type);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_RELEASE, MF_BYCOMMAND | MF_UNCHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_DEBUG, MF_BYCOMMAND | MF_UNCHECKED);
m_pMainWnd->GetMenu()->CheckMenuItem(ID_LIBRARY_PROFILE, MF_BYCOMMAND | MF_CHECKED);
}
void
CDynamoRIOApp::OnHelpHelp()
{
TCHAR helppath[MAX_PATH];
_stprintf(helppath, _T("%s%s"), m_dynamorio_home, HELP_PATH);
TCHAR cwd[MAX_PATH];
int cwd_res = GetCurrentDirectory(MAX_PATH, cwd);
assert(cwd_res > 0);
HINSTANCE res =
ShellExecute(m_pMainWnd->m_hWnd, _T("open"), helppath, NULL, cwd, SW_SHOWNORMAL);
if ((int)res <= 32) {
TCHAR msg[MAX_PATH * 2];
_stprintf(msg, _T("Error browsing help document %s"), helppath);
MessageBox(m_pMainWnd->m_hWnd, msg, _T("Error"), MB_OK | MYMBFLAGS);
}
}
void
CDynamoRIOApp::PreExit()
{
BOOL ok = TRUE;
if (_tcsstr(m_dll_path, L_DLLPATH_RELEASE) != NULL)
ok = WriteProfileInt(_T("Settings"), _T("Library"), 0);
else if (_tcsstr(m_dll_path, L_DLLPATH_DEBUG) != NULL)
ok = WriteProfileInt(_T("Settings"), _T("Library"), 1);
else if (_tcsstr(m_dll_path, L_DLLPATH_PROFILE) != NULL)
ok = WriteProfileInt(_T("Settings"), _T("Library"), 2);
assert(ok);
if (m_bSystemwideAllowed && m_bInjectAll) {
int res = MessageBox(NULL,
_T("Run All is currently set. Turn it off?"),
_T("Confirmation"), MB_YESNO | MYMBFLAGS);
if (res == IDYES) {
SetSystemwideInject(_T(""));
}
}
}
void
CDynamoRIOApp::SetEnvVarPermanently(TCHAR *var, TCHAR *val)
{
HCURSOR prev_cursor = SetCursor(LoadCursor(IDC_WAIT));
TCHAR msg[MAX_PATH];
HKEY hk;
int res;
res = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Environment"), 0, KEY_WRITE, &hk);
if (res != ERROR_SUCCESS) {
_stprintf(msg, _T("Error writing to HKEY_CURRENT_USER\\Environment"));
MessageBox(NULL, msg, _T("Error"), MB_OK | MYMBFLAGS);
}
res = RegSetValueEx(hk, var, 0, REG_SZ, (LPBYTE)val, _tcslen(val) + 1);
assert(res == ERROR_SUCCESS);
RegCloseKey(hk);
DWORD dwReturnValue;
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment",
SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
BOOL ok = SetEnvironmentVariable(var, val);
assert(ok);
SetCursor(prev_cursor);
}
BOOL
CDynamoRIOApp::ConfigureForNewUser()
{
BOOL ok = FALSE;
TCHAR msg[MAX_PATH * 2];
int res;
GetModuleFileName(NULL, m_dynamorio_home, MAX_PATH);
TCHAR *sub = _tcsstr(m_dynamorio_home, _T("\\bin\\DynamoRIO.exe"));
if (sub != NULL) {
*sub = _T('\0');
_stprintf(msg, _T("Is this the location of the DynamoRIO installation?\n%s\n"),
m_dynamorio_home);
res = MessageBox(NULL, msg, _T("Confirmation"), MB_YESNO | MYMBFLAGS);
if (res == IDNO)
ok = FALSE;
else
ok = TRUE;
}
if (!ok) {
BROWSEINFO bi;
bi.hwndOwner = m_pMainFrame->m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = m_dynamorio_home;
bi.lpszTitle = _T("Locate Root of DynamoRIO Installation");
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = NULL;
bi.iImage = 0;
ITEMIDLIST *id = SHBrowseForFolder(&bi);
if (id == NULL)
return FALSE;
SHGetPathFromIDList(id, m_dynamorio_home);
}
HCURSOR prev_cursor = SetCursor(LoadCursor(IDC_WAIT));
HKEY hk;
res = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Environment"), 0, KEY_WRITE, &hk);
if (res != ERROR_SUCCESS) {
_stprintf(msg, _T("Error writing to HKEY_CURRENT_USER\\Environment"));
MessageBox(NULL, msg, _T("Error"), MB_OK | MYMBFLAGS);
}
TCHAR *val = m_dynamorio_home;
res =
RegSetValueEx(hk, _T("DYNAMORIO_HOME"), 0, REG_SZ, (LPBYTE)val, _tcslen(val) + 1);
assert(res == ERROR_SUCCESS);
ok = SetEnvironmentVariable(_T("DYNAMORIO_HOME"), val);
assert(ok);
val = INITIAL_OPTIONS;
res = RegSetValueEx(hk, _T("DYNAMORIO_OPTIONS"), 0, REG_SZ, (LPBYTE)val,
_tcslen(val) + 1);
assert(res == ERROR_SUCCESS);
ok = SetEnvironmentVariable(_T("DYNAMORIO_OPTIONS"), val);
assert(ok);
TCHAR buf[MAX_PATH];
_stprintf(buf, _T("%s%s"), m_dynamorio_home, INITIAL_SYSTEMWIDE);
val = buf;
res = RegSetValueEx(hk, _T("DYNAMORIO_SYSTEMWIDE"), 0, REG_SZ, (LPBYTE)val,
_tcslen(val) + 1);
assert(res == ERROR_SUCCESS);
ok = SetEnvironmentVariable(_T("DYNAMORIO_SYSTEMWIDE"), val);
assert(ok);
val = INITIAL_IGNORE;
res = RegSetValueEx(hk, _T("DYNAMORIO_IGNORE"), 0, REG_SZ, (LPBYTE)val,
_tcslen(val) + 1);
assert(res == ERROR_SUCCESS);
ok = SetEnvironmentVariable(_T("DYNAMORIO_IGNORE"), val);
assert(ok);
RegCloseKey(hk);
DWORD dwReturnValue;
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment",
SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
CDynamoRIODoc *doc = (CDynamoRIODoc *)m_pMainFrame->GetActiveView()->GetDocument();
doc->InitPaths();
SetCursor(prev_cursor);
return TRUE;
}
#endif
void
CDynamoRIOApp::OnAppExit()
{
ASSERT(AfxGetMainWnd() != NULL);
AfxGetMainWnd()->SendMessage(WM_CLOSE);
}
int
CDynamoRIOApp::ExitInstance()
{
return CWinApp::ExitInstance();
}