boinc/lib/win_util.cpp

175 lines
5.2 KiB
C++

// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
#if defined(_WIN32) && !defined(__STDWX_H__)
#include "boinc_win.h"
#elif defined(_WIN32) && defined(__STDWX_H__)
#include "stdwx.h"
#endif
#if defined(_MSC_VER) || defined(__MINGW32__)
#define snprintf _snprintf
#endif
#include "diagnostics.h"
#include "util.h"
#include "filesys.h"
#include "win_util.h"
/**
* This function terminates a process by process id instead of a handle.
**/
BOOL TerminateProcessById( DWORD dwProcessID ) {
HANDLE hProcess;
BOOL bRetVal = FALSE;
hProcess = OpenProcess( PROCESS_TERMINATE, FALSE, dwProcessID );
if (hProcess) {
bRetVal = TerminateProcess(hProcess, 1);
}
CloseHandle( hProcess );
return bRetVal;
}
// change the current directory to the BOINC data directory
// in the registry, if it exists
//
void chdir_to_data_dir() {
LONG lReturnValue;
HKEY hkSetupHive;
char szPath[MAX_PATH];
LPSTR lpszValue = NULL;
LPSTR lpszExpandedValue = NULL;
DWORD dwValueType = REG_EXPAND_SZ;
DWORD dwSize = 0;
lReturnValue = RegOpenKeyExA(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Space Sciences Laboratory, U.C. Berkeley\\BOINC Setup",
0,
KEY_READ,
&hkSetupHive
);
if (lReturnValue == ERROR_SUCCESS) {
// How large does our buffer need to be?
lReturnValue = RegQueryValueExA(
hkSetupHive,
"DATADIR",
NULL,
&dwValueType,
NULL,
&dwSize
);
if (lReturnValue != ERROR_FILE_NOT_FOUND) {
// Allocate the buffer space.
lpszValue = (LPSTR) malloc(dwSize);
(*lpszValue) = NULL;
// Now get the data
lReturnValue = RegQueryValueExA(
hkSetupHive,
"DATADIR",
NULL,
&dwValueType,
(LPBYTE)lpszValue,
&dwSize
);
// Expand the Strings
// We need to get the size of the buffer needed
dwSize = 0;
lReturnValue = ExpandEnvironmentStringsA(lpszValue, NULL, dwSize);
if (lReturnValue) {
// Make the buffer big enough for the expanded string
lpszExpandedValue = (LPSTR) malloc(lReturnValue);
(*lpszExpandedValue) = NULL;
dwSize = lReturnValue;
ExpandEnvironmentStringsA(lpszValue, lpszExpandedValue, dwSize);
SetCurrentDirectoryA(lpszExpandedValue);
}
}
} else {
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, szPath))) {
strncat(szPath, "\\boinc", (sizeof(szPath) - strlen(szPath)));
if (boinc_file_exists(szPath)) {
SetCurrentDirectoryA(szPath);
}
}
}
if (hkSetupHive) RegCloseKey(hkSetupHive);
if (lpszValue) free(lpszValue);
if (lpszExpandedValue) free(lpszExpandedValue);
}
std::wstring boinc_ascii_to_wide(const std::string& str) {
int length_wide = MultiByteToWideChar(CP_ACP, 0, str.data(), -1, NULL, 0);
wchar_t *string_wide = static_cast<wchar_t*>(_alloca((length_wide * sizeof(wchar_t)) + sizeof(wchar_t)));
MultiByteToWideChar(CP_ACP, 0, str.data(), -1, string_wide, length_wide);
std::wstring result(string_wide, length_wide);
return result;
}
std::string boinc_wide_to_ascii(const std::wstring& str) {
int length_ansi = WideCharToMultiByte(CP_UTF8, 0, str.data(), -1, NULL, 0, NULL, NULL);
char* string_ansi = static_cast<char*>(_alloca(length_ansi + sizeof(char)));
WideCharToMultiByte(CP_UTF8, 0, str.data(), -1, string_ansi, length_ansi, NULL, NULL);
std::string result(string_ansi, length_ansi);
return result;
}
// get message for given error
//
char* windows_format_error_string(
unsigned long dwError, char* pszBuf, int iSize
) {
DWORD dwRet;
LPWSTR lpszTemp = NULL;
dwRet = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
dwError,
LANG_NEUTRAL,
(LPWSTR)&lpszTemp,
0,
NULL
);
if (dwRet != 0) {
// include the hex error code as well
snprintf(pszBuf, iSize, "%S (0x%x)", lpszTemp, dwError);
if (lpszTemp) {
LocalFree((HLOCAL)lpszTemp);
}
} else {
strcpy(pszBuf, "(unknown error)");
}
return pszBuf;
}