📄 bindinstalldlg.cpp
字号:
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; } } if (m_accountExists == FALSE) { success = CreateServiceAccount(m_accountName.GetBuffer(30), m_accountPassword.GetBuffer(30)); if (success == FALSE) { MsgBox(IDS_CREATEACCOUNT_FAILED); return; } m_accountExists = TRUE; } ProgramGroup(FALSE); try { CreateDirs(); CopyFiles(); RegisterService(); RegisterMessages(); HKEY hKey; /* Create a new key for named */ SetCurrent(IDS_CREATE_KEY); if (RegCreateKey(HKEY_LOCAL_MACHINE, BIND_SUBKEY, &hKey) == ERROR_SUCCESS) { // Get the install directory 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); } ProgramGroup(FALSE); if (m_startOnInstall) 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);}/* * Methods to do the work */void CBINDInstallDlg::CreateDirs() { /* s'OK if the directories already exist */ 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); // Check for existence then remove if present 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 {/* * 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. */ 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);} /* * Get the service account name out of the registry, if any */voidCBINDInstallDlg::GetCurrentServiceAccountName() { HKEY hKey; BOOL keyFound = FALSE; char accountName[MAX_PATH]; DWORD nameLen = MAX_PATH; CString Tmp; m_accountUsed = FALSE; memset(accountName, 0, nameLen); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, BIND_SERVICE_SUBKEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { keyFound = TRUE; } else { m_serviceExists = FALSE; } if (keyFound == TRUE) { /* Get the named service account, if one was specified */ if (RegQueryValueEx(hKey, "ObjectName", NULL, NULL, (LPBYTE)accountName, &nameLen) != ERROR_SUCCESS) keyFound = FALSE; } RegCloseKey(hKey); if(keyFound == FALSE) 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 */ if (Tmp.Left(2) == ".\\") { m_accountName = Tmp.Mid(2); m_accountUsed = TRUE; } }}BOOLCBINDInstallDlg::ValidateServiceAccount() { wchar_t *PrivList[MAX_PRIVS]; unsigned int PrivCount = 0; char *Groups[MAX_GROUPS]; unsigned int totalGroups = 0; int status; char *name; name = m_accountName.GetBuffer(30); status = GetAccountPrivileges(name, PrivList, &PrivCount, Groups, &totalGroups, MAX_GROUPS); if (status == RTN_NOACCOUNT) { m_accountExists = FALSE; /* We need to do this in case an account was previously used */ m_accountUsed = FALSE; return (TRUE); } if (status != RTN_OK) { MsgBox(IDS_ERR_BADACCOUNT); return (FALSE); } m_accountExists = TRUE; if (PrivCount > 1) { if (MsgBox(IDS_ERR_TOOPRIVED, MB_YESNO) == IDYES) return (FALSE); else return (TRUE); } /* See if we have the correct privilege */ if (wcscmp(PrivList[0], SE_SERVICE_LOGON_PRIV) != 0) { MsgBox(IDS_ERR_WRONGPRIV, PrivList[0]); return (FALSE); } return (TRUE);}voidCBINDInstallDlg::RegisterService() { SC_HANDLE hSCManager; SC_HANDLE hService; CString StartName = ".\\" + m_accountName; /* * 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) { UpdateService(); SetItemStatus(IDC_REG_SERVICE); return; } else { SetItemStatus(IDC_REG_SERVICE); return; } } 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, StartName, m_accountPassword); if (!hService && GetLastError() != ERROR_SERVICE_EXISTS) throw(Exception(IDS_ERR_CREATE_SERVICE, GetErrMessage())); if (hService) CloseServiceHandle(hService); if (hSCManager) CloseServiceHandle(hSCManager); SetItemStatus(IDC_REG_SERVICE);}voidCBINDInstallDlg::UpdateService() { SC_HANDLE hSCManager; SC_HANDLE hService; CString StartName = ".\\" + m_accountName; SetCurrent(IDS_OPEN_SCM); hSCManager= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!hSCManager) { MsgBox(IDS_ERR_OPEN_SCM, GetErrMessage()); return; } 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_OPEN_SERVICE); hService = OpenService(hSCManager, BIND_SERVICE_NAME, SERVICE_CHANGE_CONFIG); if (!hService) { MsgBox(IDS_ERR_OPEN_SERVICE, GetErrMessage()); if (hSCManager) CloseServiceHandle(hSCManager); return; } else { if (ChangeServiceConfig(hService, dwServiceType, dwStart, SERVICE_ERROR_NORMAL, namedLoc, NULL, NULL, NULL, StartName, m_accountPassword,BIND_DISPLAY_NAME) != TRUE) { DWORD err = GetLastError(); MsgBox(IDS_ERR_UPDATE_SERVICE, GetErrMessage()); } } if (hService) CloseServiceHandle(hService); if (hSCManager) CloseServiceHandle(hSCManager); SetItemStatus(IDC_REG_SERVICE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -