BINDInstallDlg.cpp [plain text]
#ifdef BINARIES_INSTALL
#endif
#include "stdafx.h"
#include "BINDInstall.h"
#include "BINDInstallDlg.h"
#include "DirBrowse.h"
#include <winsvc.h>
#include <named/ntservice.h>
#include <isc/bind_registry.h>
#include <direct.h>
#include "versioninfo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
typedef struct _exception
{
_exception(UINT string, ...);
CString resString;
} Exception;
_exception::_exception(UINT string, ...)
{
CString format;
va_list va;
format.LoadString(string);
va_start(va, string);
resString.FormatV(format, va);
va_end(va);
}
typedef struct _filedata
{
enum FileDestinations {TargetDir, BinDir, EtcDir, WinSystem};
enum FileImportance {Trivial, Normal, Critical};
char *filename;
int destination;
int importance;
BOOL checkVer;
} FileData;
const FileData installFiles[] =
{
#ifdef BINARIES_INSTALL
# ifdef DEBUG_BINARIES
{"msvcrtd.dll", FileData::WinSystem, FileData::Critical, TRUE},
# endif
# ifdef RELEASE_BINARIES
{"msvcrt.dll", FileData::WinSystem, FileData::Critical, TRUE},
# endif
#endif
{"bindevt.dll", FileData::WinSystem, FileData::Normal, FALSE},
{"libisc.dll", FileData::WinSystem, FileData::Critical, FALSE},
{"libisccfg.dll", FileData::WinSystem, FileData::Critical, FALSE},
{"libisccc.dll", FileData::WinSystem, FileData::Critical, FALSE},
{"libdns.dll", FileData::WinSystem, FileData::Critical, FALSE},
{"liblwres.dll", FileData::WinSystem, FileData::Critical, FALSE},
{"libeay32.dll", FileData::WinSystem, FileData::Critical, FALSE},
{"named.exe", FileData::BinDir, FileData::Critical, FALSE},
{"nsupdate.exe", FileData::BinDir, FileData::Normal, FALSE},
{"BINDInstall.exe", FileData::BinDir, FileData::Normal, FALSE},
{"rndc.exe", FileData::BinDir, FileData::Normal, FALSE},
{"dig.exe", FileData::BinDir, FileData::Normal, FALSE},
{"host.exe", FileData::BinDir, FileData::Normal, FALSE},
{"nslookup.exe", FileData::BinDir, FileData::Normal, FALSE},
{"rndc-confgen.exe", FileData::BinDir, FileData::Normal, FALSE},
{"dnssec-keygen.exe", FileData::BinDir, FileData::Normal, FALSE},
{"dnssec-makekeyset.exe", FileData::BinDir, FileData::Normal, FALSE},
{"dnssec-signkey.exe", FileData::BinDir, FileData::Normal, FALSE},
{"dnssec-signzone.exe", FileData::BinDir, FileData::Normal, FALSE},
{"named-checkconf.exe", FileData::BinDir, FileData::Normal, FALSE},
{"named-checkzone.exe", FileData::BinDir, FileData::Normal, FALSE},
{"readme1st.txt", FileData::BinDir, FileData::Trivial, FALSE},
{NULL, -1, -1}
};
CBINDInstallDlg::CBINDInstallDlg(CWnd* pParent )
: CDialog(CBINDInstallDlg::IDD, pParent)
{
char buf[MAX_PATH];
m_targetDir = _T("");
m_version = _T("");
m_autoStart = FALSE;
m_keepFiles = FALSE;
m_current = _T("");
m_startOnInstall = FALSE;
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_reboot = FALSE;
GetSystemDirectory(buf, MAX_PATH);
m_winSysDir = buf;
m_defaultDir = buf;
m_defaultDir += "\\dns";
}
void CBINDInstallDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_TARGETDIR, m_targetDir);
DDX_Text(pDX, IDC_VERSION, m_version);
DDX_Check(pDX, IDC_AUTO_START, m_autoStart);
DDX_Check(pDX, IDC_KEEP_FILES, m_keepFiles);
DDX_Text(pDX, IDC_CURRENT, m_current);
DDX_Check(pDX, IDC_START, m_startOnInstall);
}
BEGIN_MESSAGE_MAP(CBINDInstallDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(IDC_INSTALL, OnInstall)
ON_BN_CLICKED(IDC_EXIT, OnExit)
ON_BN_CLICKED(IDC_UNINSTALL, OnUninstall)
END_MESSAGE_MAP()
BOOL CBINDInstallDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);
char filename[MAX_PATH];
char dirname[MAX_PATH];
char *fptr = &filename[0];
GetModuleFileName(NULL, filename, MAX_PATH);
char *dptr = strrchr(filename,'\\');
int index = dptr - fptr;
strncpy(dirname, filename, index);
dirname[index] = '\0';
CString Dirname(dirname);
m_currentDir = Dirname;
CVersionInfo bindInst(filename);
if(bindInst.IsValid())
m_version.Format(IDS_VERSION, bindInst.GetFileVersionString());
else
m_version.LoadString(IDS_NO_VERSION);
DWORD dwBufLen = MAX_PATH;
char buf[MAX_PATH];
HKEY hKey;
m_startOnInstall = CheckBINDService();
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, BIND_SUBKEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
memset(buf, 0, MAX_PATH);
if(RegQueryValueEx(hKey, "InstallDir", NULL, NULL, (LPBYTE)buf, &dwBufLen) == ERROR_SUCCESS)
if(strcmp(buf, ""))
m_defaultDir = buf;
RegCloseKey(hKey);
}
m_targetDir = m_defaultDir;
m_autoStart = TRUE;
m_keepFiles = TRUE;
UpdateData(FALSE);
return(TRUE); }
void CBINDInstallDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CBINDInstallDlg::OnQueryDragIcon()
{
return((HCURSOR)m_hIcon);
}
void CBINDInstallDlg::OnBrowse()
{
CDirBrowse browse;
if(browse.DoModal() == IDOK)
{
UpdateData(FALSE);
}
}
void CBINDInstallDlg::OnExit()
{
EndDialog(0);
}
void CBINDInstallDlg::OnUninstall()
{
UpdateData();
if(MsgBox(IDS_UNINSTALL, MB_YESNO) == IDYES)
{
if(CheckBINDService())
StopBINDService();
HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hSCManager)
{
MsgBox(IDS_ERR_OPEN_SCM, GetErrMessage());
return;
}
HANDLE hService = OpenService(hSCManager, BIND_SERVICE_NAME, SERVICE_ALL_ACCESS);
if(!hService && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
{
MsgBox(IDS_ERR_OPEN_SERVICE, GetErrMessage());
return;
}
SERVICE_STATUS ss;
QueryServiceStatus(hService, &ss);
if(ss.dwCurrentState == SERVICE_RUNNING)
{
BOOL rc = ControlService(hService, SERVICE_CONTROL_STOP, &ss);
if(rc == FALSE || ss.dwCurrentState != SERVICE_STOPPED)
{
MsgBox(IDS_ERR_STOP_SERVICE, GetErrMessage());
return;
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
m_etcDir = m_targetDir + "\\etc";
m_binDir = m_targetDir + "\\bin";
UninstallTags();
UnregisterMessages(TRUE);
UnregisterService(TRUE);
DeleteFiles(TRUE);
if(m_keepFiles == FALSE)
RemoveDirs(TRUE);
else
GetDlgItem(IDC_CREATE_DIR)->SetWindowText("Not Removed");
RegDeleteKey(HKEY_LOCAL_MACHINE, BIND_SESSION_SUBKEY);
RegDeleteKey(HKEY_LOCAL_MACHINE, BIND_SUBKEY);
RegDeleteKey(HKEY_LOCAL_MACHINE, BIND_UNINSTALL_SUBKEY);
ProgramGroup(FALSE);
SetCurrent(IDS_UNINSTALL_DONE);
MsgBox(IDS_UNINSTALL_DONE);
}
}
void CBINDInstallDlg::OnInstall()
{
BOOL success = FALSE;
if(CheckBINDService())
StopBINDService();
InstallTags();
UpdateData();
m_etcDir = m_targetDir + "\\etc";
m_binDir = m_targetDir + "\\bin";
if(m_defaultDir != m_targetDir)
{
if(GetFileAttributes(m_targetDir) != 0xFFFFFFFF)
{
int install = MsgBox(IDS_DIREXIST, MB_YESNO | MB_ICONQUESTION, m_targetDir);
if(install == IDNO)
return;
}
else
{
int createDir = MsgBox(IDS_CREATEDIR, MB_YESNO | MB_ICONQUESTION, m_targetDir);
if(createDir == IDNO)
return;
}
}
try
{
CreateDirs();
CopyFiles();
RegisterService();
RegisterMessages();
HKEY hKey;
SetCurrent(IDS_CREATE_KEY);
if(RegCreateKey(HKEY_LOCAL_MACHINE, BIND_SUBKEY, &hKey) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, "InstallDir", 0, REG_SZ, (LPBYTE)(LPCTSTR)m_targetDir, m_targetDir.GetLength());
RegCloseKey(hKey);
}
SetCurrent(IDS_ADD_REMOVE);
if(RegCreateKey(HKEY_LOCAL_MACHINE, BIND_UNINSTALL_SUBKEY, &hKey) == ERROR_SUCCESS)
{
char winDir[MAX_PATH];
CString buf(BIND_DISPLAY_NAME);
GetWindowsDirectory(winDir, MAX_PATH);
RegSetValueEx(hKey, "DisplayName", 0, REG_SZ, (LPBYTE)(LPCTSTR)buf, buf.GetLength());
buf.Format("%s\\BINDInstall.exe", winDir);
RegSetValueEx(hKey, "UninstallString", 0, REG_SZ, (LPBYTE)(LPCTSTR)buf, buf.GetLength());
RegCloseKey(hKey);
}
if(m_startOnInstall && !m_reboot)
StartBINDService();
}
catch(Exception e)
{
MessageBox(e.resString);
SetCurrent(IDS_CLEANUP);
FailedInstall();
MsgBox(IDS_FAIL);
return;
}
catch(DWORD dw)
{
CString msg;
msg.Format("A fatal error occured\n(%s)", GetErrMessage(dw));
MessageBox(msg);
SetCurrent(IDS_CLEANUP);
FailedInstall();
MsgBox(IDS_FAIL);
return;
}
SetCurrent(IDS_INSTALL_DONE);
MsgBox(IDS_SUCCESS);
if(m_reboot)
{
if(MsgBox(IDS_REBOOT, MB_YESNO) == IDYES)
{
InitiateSystemShutdown(NULL, NULL, 0, TRUE, TRUE);
}
}
}
void CBINDInstallDlg::CreateDirs()
{
SetCurrent(IDS_CREATE_DIR, m_targetDir);
if(!CreateDirectory(m_targetDir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
throw(Exception(IDS_ERR_CREATE_DIR, m_targetDir, GetErrMessage()));
SetCurrent(IDS_CREATE_DIR, m_etcDir);
if(!CreateDirectory(m_etcDir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
throw(Exception(IDS_ERR_CREATE_DIR, m_etcDir, GetErrMessage()));
SetCurrent(IDS_CREATE_DIR, m_binDir);
if(!CreateDirectory(m_binDir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
throw(Exception(IDS_ERR_CREATE_DIR, m_binDir, GetErrMessage()));
SetItemStatus(IDC_CREATE_DIR);
}
void CBINDInstallDlg::RemoveDirs(BOOL uninstall)
{
if(!m_keepFiles)
{
SetCurrent(IDS_REMOVE_DIR, m_binDir);
if(GetFileAttributes(m_binDir) != 0xFFFFFFFF)
RemoveDirectory(m_binDir);
SetCurrent(IDS_REMOVE_DIR, m_etcDir);
if(GetFileAttributes(m_etcDir) != 0xFFFFFFFF)
RemoveDirectory(m_etcDir);
SetCurrent(IDS_REMOVE_DIR, m_targetDir);
if(GetFileAttributes(m_targetDir) != 0xFFFFFFFF)
RemoveDirectory(m_targetDir);
}
if(uninstall)
SetItemStatus(IDC_CREATE_DIR, TRUE);
}
void CBINDInstallDlg::CopyFiles()
{
CString destFile;
for(int i = 0; installFiles[i].filename; i++)
{
SetCurrent(IDS_COPY_FILE, installFiles[i].filename);
destFile = DestDir(installFiles[i].destination) + "\\" + installFiles[i].filename;
CString filespec = m_currentDir + "\\" + installFiles[i].filename;
CVersionInfo bindFile(destFile);
CVersionInfo origFile(filespec);
if(!origFile.IsValid() && installFiles[i].checkVer)
{
if(MsgBox(IDS_FILE_BAD, MB_YESNO, installFiles[i].filename) == IDNO)
throw(Exception(IDS_ERR_COPY_FILE, installFiles[i].filename, GetErrMessage()));
}
try
{
bindFile.CopyFileNoVersion(origFile);
}
catch(...)
{
if(installFiles[i].importance != FileData::Trivial)
{
if(installFiles[i].importance == FileData::Critical ||
MsgBox(IDS_ERR_NONCRIT_FILE, MB_YESNO, installFiles[i].filename, GetErrMessage()) == IDNO)
{
SetItemStatus(IDC_COPY_FILE, FALSE);
throw(Exception(IDS_ERR_COPY_FILE, installFiles[i].filename, GetErrMessage()));
}
}
}
}
SetItemStatus(IDC_COPY_FILE);
}
void CBINDInstallDlg::DeleteFiles(BOOL uninstall)
{
CString destFile;
for(int i = 0; installFiles[i].filename; i++)
{
if(installFiles[i].checkVer)
continue;
destFile = DestDir(installFiles[i].destination) + "\\" + installFiles[i].filename;
if(uninstall)
SetCurrent(IDS_DELETE_FILE, installFiles[i].filename);
DeleteFile(destFile);
}
if(!m_keepFiles)
{
WIN32_FIND_DATA findData;
CString file = m_etcDir + "\\*.*";
BOOL rc;
HANDLE hFile;
hFile = FindFirstFile(file, &findData);
rc = hFile != INVALID_HANDLE_VALUE;
while(rc == TRUE)
{
if(strcmp(findData.cFileName, ".") && strcmp(findData.cFileName, ".."))
{
file = m_etcDir + "\\" + findData.cFileName;
SetCurrent(IDS_DELETE_FILE, file);
DeleteFile(file);
}
rc = FindNextFile(hFile, &findData);
}
FindClose(hFile);
}
if(uninstall)
SetItemStatus(IDC_COPY_FILE, TRUE);
}
void CBINDInstallDlg::RegisterService()
{
HANDLE hSCManager;
HANDLE hService;
SetCurrent(IDS_OPEN_SCM);
hSCManager= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hSCManager)
throw(Exception(IDS_ERR_OPEN_SCM, GetErrMessage()));
DWORD dwStart = SERVICE_DEMAND_START;
if(m_autoStart)
dwStart = SERVICE_AUTO_START;
DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
CString namedLoc;
namedLoc.Format("%s\\bin\\named.exe", m_targetDir);
SetCurrent(IDS_CREATE_SERVICE);
hService = CreateService(hSCManager, BIND_SERVICE_NAME, BIND_DISPLAY_NAME, SERVICE_ALL_ACCESS, dwServiceType, dwStart,
SERVICE_ERROR_NORMAL, namedLoc, NULL, NULL, NULL, NULL, NULL);
if(!hService && GetLastError() != ERROR_SERVICE_EXISTS)
throw(Exception(IDS_ERR_CREATE_SERVICE, GetErrMessage()));
if(hSCManager)
CloseServiceHandle(hSCManager);
if(hService)
CloseServiceHandle(hService);
SetItemStatus(IDC_REG_SERVICE);
}
void CBINDInstallDlg::UnregisterService(BOOL uninstall)
{
BOOL rc = FALSE;
HANDLE hSCManager;
HANDLE hService;
while(1)
{
SetCurrent(IDS_OPEN_SCM);
hSCManager= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hSCManager && uninstall == TRUE)
{
MsgBox(IDS_ERR_OPEN_SCM, GetErrMessage());
break;
}
SetCurrent(IDS_OPEN_SERVICE);
hService = OpenService(hSCManager, BIND_SERVICE_NAME, STANDARD_RIGHTS_REQUIRED);
if(!hService && uninstall == TRUE)
{
if(GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
{
MsgBox(IDS_ERR_OPEN_SERVICE, GetErrMessage());
break;
}
}
else
{
SetCurrent(IDS_REMOVE_SERVICE);
if(!DeleteService(hService) && uninstall == TRUE)
{
DWORD err = GetLastError();
if(err != ERROR_SERVICE_MARKED_FOR_DELETE && err != ERROR_SERVICE_DOES_NOT_EXIST)
{
MsgBox(IDS_ERR_REMOVE_SERVICE, GetErrMessage());
break;
}
}
}
rc = TRUE;
break;
}
if(hSCManager)
CloseServiceHandle(hSCManager);
if(hService)
CloseServiceHandle(hService);
if(uninstall)
SetItemStatus(IDC_REG_SERVICE, rc);
}
void CBINDInstallDlg::RegisterMessages()
{
HKEY hKey;
DWORD dwData;
char pszMsgDLL[MAX_PATH], buf[MAX_PATH];
GetSystemDirectory(buf, MAX_PATH);
sprintf(pszMsgDLL, "%s\\%s", buf, "bindevt.dll");
SetCurrent(IDS_REGISTER_MESSAGES);
if(RegCreateKey(HKEY_LOCAL_MACHINE, BIND_MESSAGE_SUBKEY, &hKey) != ERROR_SUCCESS)
throw(Exception(IDS_ERR_CREATE_KEY, GetErrMessage()));
if(RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, (LPBYTE)pszMsgDLL, strlen(pszMsgDLL) + 1) != ERROR_SUCCESS)
throw(Exception(IDS_ERR_SET_VALUE, GetErrMessage()));
dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
if(RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD)) != ERROR_SUCCESS)
throw(Exception(IDS_ERR_SET_VALUE, GetErrMessage()));
RegCloseKey(hKey);
SetItemStatus(IDC_REG_MESSAGE);
}
void CBINDInstallDlg::UnregisterMessages(BOOL uninstall)
{
BOOL rc = FALSE;
HKEY hKey = NULL;
while(1)
{
SetCurrent(IDS_UNREGISTER_MESSAGES);
if(RegOpenKey(HKEY_LOCAL_MACHINE, EVENTLOG_APP_SUBKEY, &hKey) != ERROR_SUCCESS)
break;
if(RegDeleteKey(hKey, BIND_MESSAGE_NAME) != ERROR_SUCCESS)
break;
rc = TRUE;
break;
}
if(hKey)
RegCloseKey(hKey);
if(uninstall)
SetItemStatus(IDC_REG_MESSAGE, rc);
}
void CBINDInstallDlg::FailedInstall()
{
UnregisterMessages(FALSE);
UnregisterService(FALSE);
DeleteFiles(FALSE);
RemoveDirs(FALSE);
}
void CBINDInstallDlg::InstallTags()
{
CString tag;
tag.LoadString(IDS_INSTALL_FILE);
GetDlgItem(IDC_COPY_TAG)->SetWindowText(tag);
GetDlgItem(IDC_COPY_FILE)->SetWindowText("");
tag.LoadString(IDS_INSTALL_DIR);
GetDlgItem(IDC_DIR_TAG)->SetWindowText(tag);
GetDlgItem(IDC_CREATE_DIR)->SetWindowText("");
GetDlgItem(IDC_REG_SERVICE)->SetWindowText("");
tag.LoadString(IDS_INSTALL_SERVICE);
GetDlgItem(IDC_SERVICE_TAG)->SetWindowText(tag);
tag.LoadString(IDS_INSTALL_MESSAGE);
GetDlgItem(IDC_MESSAGE_TAG)->SetWindowText(tag);
GetDlgItem(IDC_REG_MESSAGE)->SetWindowText("");
}
void CBINDInstallDlg::UninstallTags()
{
CString tag;
tag.LoadString(IDS_UNINSTALL_FILES);
GetDlgItem(IDC_COPY_TAG)->SetWindowText(tag);
GetDlgItem(IDC_COPY_FILE)->SetWindowText("");
tag.LoadString(IDS_UNINSTALL_DIR);
GetDlgItem(IDC_DIR_TAG)->SetWindowText(tag);
GetDlgItem(IDC_CREATE_DIR)->SetWindowText("");
tag.LoadString(IDS_UNINSTALL_SERVICE);
GetDlgItem(IDC_SERVICE_TAG)->SetWindowText(tag);
GetDlgItem(IDC_REG_SERVICE)->SetWindowText("");
tag.LoadString(IDS_UNINSTALL_MESSAGE);
GetDlgItem(IDC_MESSAGE_TAG)->SetWindowText(tag);
GetDlgItem(IDC_REG_MESSAGE)->SetWindowText("");
}
void CBINDInstallDlg::SetItemStatus(UINT nID, BOOL bSuccess)
{
GetDlgItem(nID)->SetWindowText(bSuccess == TRUE ? "Done" : "Failed");
}
void CBINDInstallDlg::SetCurrent(int id, ...)
{
CString format;
va_list va;
char buf[128];
format.LoadString(id);
memset(buf, 0, 128);
va_start(va, id);
vsprintf(buf, format, va);
va_end(va);
m_current.Format("%s", buf);
UpdateData(FALSE);
}
void CBINDInstallDlg::StopBINDService()
{
SERVICE_STATUS svcStatus;
SetCurrent(IDS_STOP_SERVICE);
HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hSCManager)
{
MsgBox(IDS_ERR_OPEN_SCM, GetErrMessage());
}
HANDLE hBINDSvc = OpenService(hSCManager, BIND_SERVICE_NAME, SERVICE_ALL_ACCESS);
if(!hBINDSvc)
{
MsgBox(IDS_ERR_OPEN_SERVICE, GetErrMessage());
}
BOOL rc = ControlService(hBINDSvc, SERVICE_CONTROL_STOP, &svcStatus);
}
void CBINDInstallDlg::StartBINDService()
{
SetCurrent(IDS_START_SERVICE);
HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hSCManager)
{
MsgBox(IDS_ERR_OPEN_SCM, GetErrMessage());
}
HANDLE hBINDSvc = OpenService(hSCManager, BIND_SERVICE_NAME, SERVICE_ALL_ACCESS);
if(!hBINDSvc)
{
MsgBox(IDS_ERR_OPEN_SERVICE, GetErrMessage());
}
BOOL rc = StartService(hBINDSvc, 0, NULL);
}
BOOL CBINDInstallDlg::CheckBINDService()
{
SERVICE_STATUS svcStatus;
HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(hSCManager)
{
HANDLE hBINDSvc = OpenService(hSCManager, BIND_SERVICE_NAME, SERVICE_ALL_ACCESS);
if(hBINDSvc)
{
BOOL rc = ControlService(hBINDSvc, SERVICE_CONTROL_INTERROGATE, &svcStatus);
if(!rc)
DWORD err = GetLastError();
return(svcStatus.dwCurrentState == SERVICE_RUNNING);
}
}
return(FALSE);
}
int CBINDInstallDlg::MsgBox(int id, ...)
{
CString format;
va_list va;
char buf[BUFSIZ];
format.LoadString(id);
memset(buf, 0, BUFSIZ);
va_start(va, id);
vsprintf(buf, format, va);
va_end(va);
return(MessageBox(buf));
}
int CBINDInstallDlg::MsgBox(int id, UINT type, ...)
{
CString format;
va_list va;
char buf[BUFSIZ];
format.LoadString(id);
memset(buf, 0, BUFSIZ);
va_start(va, type);
vsprintf(buf, format, va);
va_end(va);
return(MessageBox(buf, NULL, type));
}
CString CBINDInstallDlg::GetErrMessage(DWORD err)
{
LPVOID msgBuf;
static char buf[BUFSIZ];
DWORD len = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, err == -1 ? GetLastError() : err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msgBuf, 0, NULL );
strcpy(buf, (LPTSTR)msgBuf);
LocalFree(msgBuf);
buf[len - 3] = 0;
return(buf);
}
void CBINDInstallDlg::ProgramGroup(BOOL create)
{
TCHAR path[MAX_PATH], commonPath[MAX_PATH], fileloc[MAX_PATH], linkpath[MAX_PATH];
HRESULT hres;
IShellLink *psl = NULL;
LPMALLOC pMalloc = NULL;
ITEMIDLIST *itemList = NULL;
HRESULT hr = SHGetMalloc(&pMalloc);
if(hr != NOERROR)
{
MessageBox("Could not get a handle to Shell memory object");
return;
}
hr = SHGetSpecialFolderLocation(m_hWnd, CSIDL_COMMON_PROGRAMS, &itemList);
if(hr != NOERROR)
{
MessageBox("Could not get a handle to the Common Programs folder");
if(itemList)
{
pMalloc->Free(itemList);
}
return;
}
hr = SHGetPathFromIDList(itemList, commonPath);
pMalloc->Free(itemList);
if(create)
{
sprintf(path, "%s\\ISC", commonPath);
CreateDirectory(path, NULL);
sprintf(path, "%s\\ISC\\BIND", commonPath);
CreateDirectory(path, NULL);
hres = CoInitialize(NULL);
if (SUCCEEDED(hres))
{
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
sprintf(linkpath, "%s\\BINDCtrl.lnk", path);
sprintf(fileloc, "%s\\BINDCtrl.exe", m_binDir);
psl->SetPath(fileloc);
psl->SetDescription("BIND Control Panel");
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, linkpath, -1, wsz, MAX_PATH);
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
if(GetFileAttributes("readme.txt") != -1)
{
sprintf(fileloc, "%s\\Readme.txt", m_targetDir);
sprintf(linkpath, "%s\\Readme.lnk", path);
psl->SetPath(fileloc);
psl->SetDescription("BIND Readme");
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, linkpath, -1, wsz, MAX_PATH);
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
}
CoUninitialize();
}
}
else
{
TCHAR filename[MAX_PATH];
WIN32_FIND_DATA fd;
sprintf(path, "%s\\ISC\\BIND", commonPath);
sprintf(filename, "%s\\*.*", path);
HANDLE hFind = FindFirstFile(filename, &fd);
if(hFind != INVALID_HANDLE_VALUE)
{
do
{
if(strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, ".."))
{
sprintf(filename, "%s\\%s", path, fd.cFileName);
DeleteFile(filename);
}
} while(FindNextFile(hFind, &fd));
FindClose(hFind);
}
RemoveDirectory(path);
sprintf(path, "%s\\ISC", commonPath);
RemoveDirectory(path);
}
}
CString CBINDInstallDlg::DestDir(int destination)
{
switch(destination)
{
case FileData::TargetDir:
return m_targetDir;
case FileData::BinDir:
return m_binDir;
case FileData::EtcDir:
return m_etcDir;
case FileData::WinSystem:
return m_winSysDir;
}
return("");
}