BINDInstallDlg.cpp revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Portions Copyright (C) 2001, 2003-2010, 2013-2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* $Id: BINDInstallDlg.cpp,v 1.48 2010/01/07 23:48:54 tbox Exp $ */
/*
* Copyright (c) 1999-2000 by Nortel Networks Corporation
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND NORTEL NETWORKS DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NORTEL NETWORKS
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Define this to make a standalone installer that will copy msvcrt.dll
*/
// #define BINARIES_INSTALL
/*
* msvcrt.dll is the release c-runtime library for MSVC. msvcrtd.dll
* is the debug c-runtime library for MSVC. If you have debug
* binaries you want to have DEBUG_BINARIES defined. If you have
* release binaries you want to have RELEASE_BINARIES defined.
* If you have both, then define them both.
* Of course, you need msvcrt[d].dll present to install it!
*/
#ifdef BINARIES_INSTALL
// # define DEBUG_BINARIES
// # define RELEASE_BINARIES
#endif
#include "stdafx.h"
#include "BINDInstall.h"
#include "BINDInstallDlg.h"
#include "DirBrowse.h"
#include <winsvc.h>
#include <shlobj.h>
#include <named/ntservice.h>
#include <isc/bind_registry.h>
#include <isc/ntgroups.h>
#include <direct.h>
#include "AccountInfo.h"
#include "versioninfo.h"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <config.h>
#define MAX_GROUPS 100
#define MAX_PRIVS 50
#define LOCAL_SERVICE "NT AUTHORITY\\LocalService"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
typedef struct _xexception
{
} Exception;
{
}
typedef struct _filedata {
char filename[128];
int destination;
int importance;
} FileData;
#if no_longer_used
const FileData installFiles[] =
{
#ifdef BINARIES_INSTALL
# ifdef DEBUG_BINARIES
# endif
# ifdef RELEASE_BINARIES
# endif
#endif
#if _MSC_VER < 1400
#if _MSC_VER >= 1310
#endif
#endif
#ifdef OPENSSL
#endif
#ifdef HAVE_LIBXML2
#endif
#ifdef USE_GSSAPI
#ifndef _WIN64
#else
#endif
#endif
#ifdef HAVE_GEOIP
#endif
#ifdef WITH_IDN
#endif
#ifdef USE_PKCS11
#endif
#ifdef USE_PYTHON
#endif
};
#else
#endif
/////////////////////////////////////////////////////////////////////////////
// CBINDInstallDlg dialog
//{{AFX_DATA_INIT(CBINDInstallDlg)
m_toolsOnly = FALSE;
m_autoStart = FALSE;
m_keepFiles = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent
// DestroyIcon in Win32
m_defaultDir = "notyetknown";
m_installed = FALSE;
if (m_accountName == "") {
m_accountName = "named";
}
}
//{{AFX_DATA_MAP(CBINDInstallDlg)
//}}AFX_DATA_MAP
}
//{{AFX_MSG_MAP(CBINDInstallDlg)
//}}AFX_MSG_MAP
/////////////////////////////////////////////////////////////////////////////
// CBINDInstallDlg message handlers
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
int id_program_files;
if (forwin64)
else
m_defaultDir += "\\ISC BIND 9";
else
/* See if we are installed already */
== ERROR_SUCCESS) {
m_installed = TRUE;
// Get the install directory
&dwBufLen) == ERROR_SUCCESS)
m_defaultDir = buf;
}
// Set checkbox defaults
m_autoStart = TRUE;
m_keepFiles = TRUE;
return (TRUE); /* return(TRUE) unless you set the focus to a control */
}
/*
* If you add a minimize button to your dialog, you will need the code below
* this is automatically done for you by the framework.
*/
void CBINDInstallDlg::OnPaint() {
if (IsIconic()) {
// Center icon in client rectangle
// Draw the icon
}
else {
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
}
void CBINDInstallDlg::OnBrowse() {
//m_targetDir = browse.m_selectedDir;
}
}
/*
* User pressed the exit button
*/
void CBINDInstallDlg::OnExit() {
EndDialog(0);
}
/*
* User pressed the uninstall button. Make it go.
*/
void CBINDInstallDlg::OnUninstall() {
UpdateData();
if (CheckBINDService())
if (!hSCManager) {
return;
}
return;
}
return;
}
}
// Directories
if (m_keepFiles == FALSE)
else
// Delete registry keys for named
}
}
/*
* User pressed the install button. Make it go.
*/
void CBINDInstallDlg::OnInstall() {
int oldlen;
if (CheckBINDService())
InstallTags();
UpdateData();
/*
* Check that the Passwords entered match.
*/
if (m_accountPassword != m_accountPasswordConfirm) {
return;
}
/*
* Check that there is not leading / trailing whitespace.
* This is for compatibility with the standard password dialog.
* Passwords really should be treated as opaque blobs.
*/
return;
}
/*
* Check the entered account name.
*/
if (ValidateServiceAccount() == FALSE)
return;
/*
* For Registration we need to know if account was changed.
*/
if (m_accountName != m_currentAccount)
{
/*
* Check that the Password is not null.
*/
if (m_accountPassword.GetLength() == 0) {
return;
}
}
} else if (m_accountName == LOCAL_SERVICE) {
/* The LocalService always exists. */
if (m_accountName != m_currentAccount)
}
/* Directories */
if (m_defaultDir != m_targetDir) {
{
return;
}
else {
return;
}
}
if (!m_toolsOnly) {
if (m_accountExists == FALSE) {
return;
}
}
}
/*
* Install Visual Studio libraries. As per:
*
* Vcredist_x86.exe /q:a /c:"msiexec /i vcredist.msi /qn /l*v %temp%\vcredist_x86.log"
*/
/*system(".\\Vcredist_x86.exe /q:a /c:\"msiexec /i vcredist.msi /qn /l*v %temp%\vcredist_x86.log\"");*/
/*
* Enclose full path to Vcredist_x86.exe in quotes as
* m_currentDir may contain spaces.
*/
if (runvcredist) {
char Vcredist_x86[MAX_PATH];
if (forwin64)
(LPCTSTR) m_currentDir);
else
(LPCTSTR) m_currentDir);
}
try {
CreateDirs();
CopyFiles();
if (!m_toolsOnly)
/* Create a new key for named */
&hKey) == ERROR_SUCCESS) {
// Get the install directory
m_targetDir.GetLength());
}
&hKey) == ERROR_SUCCESS) {
}
if (m_startOnInstall)
}
catch(Exception e) {
MessageBox(e.resString);
return;
}
return;
}
}
/*
* Methods to do the work
*/
void CBINDInstallDlg::CreateDirs() {
/* s'OK if the directories already exist */
}
if (!m_keepFiles) {
// Check for existence then remove if present
}
if (uninstall)
}
// InstallFlags: runvcredist and forwin64 options
void CBINDInstallDlg::ReadInstallFlags() {
if (!ff) {
}
runvcredist = TRUE;
}
}
// InstallFiles: {filename-divt}*
// destination: TBEW
// importance: TNC
// checkVer and withTools: TF (boolean)
void CBINDInstallDlg::ReadInstallFileList() {
if (!fl) {
}
continue;
if (line[0] == '#')
continue;
// zip -l adds spurious \r: remove trailing space chars
}
goto bad;
goto bad;
case 'T':
break;
case 'B':
break;
case 'E':
break;
case 'W':
break;
default:
goto bad;
}
case 'T':
break;
case 'N':
break;
case 'C':
break;
default:
goto bad;
}
case 'T':
break;
case 'F':
break;
default:
goto bad;
}
case 'T':
break;
case 'F':
break;
default:
goto bad;
}
}
return;
bad:
}
void CBINDInstallDlg::CopyFiles() {
continue;
throw(Exception(IDS_ERR_COPY_FILE,
GetErrMessage()));
}
try {
/*
* Ignore Version checking. We need to make sure that all files get
* copied regardless of whether or not they are earlier or later
* versions since we cannot guarantee that we have either backward or
* forward compatibility between versions.
*/
}
catch(...) {
GetErrMessage()) == IDNO)
{
throw(Exception(IDS_ERR_COPY_FILE,
GetErrMessage()));
}
}
}
}
}
continue;
if (uninstall)
}
if (!m_keepFiles) {
}
}
}
if (uninstall)
}
/*
* Get the service account name out of the registry, if any
*/
void
char accountName[MAX_PATH];
&hKey) == ERROR_SUCCESS) {
}
else {
}
/* Get the named service account, if one was specified */
}
m_accountName = "";
} else {
/*
* LocalSystem is not a regular account and is equivalent
* to no account but with lots of privileges
*/
Tmp = accountName;
if (Tmp == ".\\LocalSystem")
m_accountName = "";
/* Found account strip any ".\" from it */
}
}
}
unsigned int PrivCount = 0;
char *Groups[MAX_GROUPS];
unsigned int totalGroups = 0;
int status;
char *name;
if (status == RTN_NOACCOUNT) {
/* We need to do this in case an account was previously used */
return (TRUE);
}
return (FALSE);
}
if (PrivCount > 1) {
return (FALSE);
else
return (TRUE);
}
/* See if we have the correct privilege */
return (FALSE);
}
return (TRUE);
}
void
if (m_accountName == LOCAL_SERVICE)
else
/*
* We need to change the service rather than create it
* if the service already exists. Do nothing if we are already
* using that account
*/
if (m_serviceExists == TRUE) {
if (m_accountUsed == FALSE) {
return;
} else {
return;
}
}
if (!hSCManager)
if (m_autoStart)
if (hService)
if (hSCManager)
}
void
if(m_toolsOnly)
return;
if (!hSCManager) {
return;
}
if (m_autoStart)
if (!hService)
{
if (hSCManager)
return;
} else {
!= TRUE) {
}
}
if (hService)
if (hSCManager)
}
while(1) {
break;
}
{
if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST) {
break;
}
}
else {
if (err != ERROR_SERVICE_MARKED_FOR_DELETE &&
GetErrMessage());
break;
}
}
}
break;
}
if (hService)
if (hSCManager)
if (uninstall)
}
void CBINDInstallDlg::RegisterMessages() {
/* Create a new key for named */
!= ERROR_SUCCESS)
/* Add the Event-ID message-file name to the subkey. */
/* Set the supported types flags and addit to the subkey. */
}
while(1) {
/* Open key for Application Event Log */
!= ERROR_SUCCESS)
break;
/* Remove named from the list of messages sources */
break;
break;
}
if (hKey)
if (uninstall)
}
/*
* Install failed - clean up quietly
*/
void CBINDInstallDlg::FailedInstall() {
}
/*
* Set the checklist tags for install
*/
void CBINDInstallDlg::InstallTags() {
}
/*
* Set the checklist tags for uninstall
*/
void CBINDInstallDlg::UninstallTags() {
}
}
/*
* Set the text in the current operation field - use a string table string
*/
char buf[128];
}
/*
* Stop the BIND service
*/
void CBINDInstallDlg::StopBINDService() {
if (!hSCManager) {
}
if (!hBINDSvc) {
}
}
/*
* Start the BIND service
*/
void CBINDInstallDlg::StartBINDService() {
if (!hSCManager) {
}
if (!hBINDSvc) {
}
}
/*
* Check to see if the BIND service is running or not
*/
if (hSCManager) {
if (hBINDSvc) {
if (!rc)
}
}
return (FALSE);
}
/*
* Display message boxes with variable args, using string table strings
* for the format specifiers
*/
return (MessageBox(buf));
}
}
/*
* Call GetLastError(), retrieve the message associated with the error
*/
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 );
/* Strip off the period and the \n */
return(buf);
}
MessageBox("Could not get a handle to Shell memory object");
return;
}
MessageBox("Could not get a handle to the Common Programs folder");
if (itemList) {
}
return;
}
if (create) {
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl);
{
}
}
}
}
}
}
else {
if (hFind != INVALID_HANDLE_VALUE) {
do {
}
}
}
}
switch(destination) {
return m_targetDir;
return m_binDir;
return m_etcDir;
return m_winSysDir;
}
return("");
}