mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge remote branch 'public/win_unicode_fixes'
This commit is contained in:
commit
edc9256e95
11
changes/win32_unicode
Normal file
11
changes/win32_unicode
Normal file
@ -0,0 +1,11 @@
|
||||
o Minor bugfixes
|
||||
- On Windows, build correctly either with or without Unicode support.
|
||||
This is necessary so that Tor can support fringe platforms like
|
||||
Windows 98 (which has no Unicode), or Windows CE (which has no
|
||||
non-Unicode). Bugfix on 0.2.2.14-alpha. Fixes bug 1797.
|
||||
- Fix the Windows directory-listing code. A bug introduced in
|
||||
0.2.2.14-alpha could make Windows directory servers forget to
|
||||
load some of their cached v2 networkstatus files.
|
||||
|
||||
o Testing
|
||||
- Add a unit test for cross-platform directory-listing code.
|
@ -169,13 +169,17 @@ tor_munmap_file(tor_mmap_t *handle)
|
||||
tor_mmap_t *
|
||||
tor_mmap_file(const char *filename)
|
||||
{
|
||||
WCHAR wfilename[MAX_PATH]= {0};
|
||||
TCHAR tfilename[MAX_PATH]= {0};
|
||||
tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t));
|
||||
int empty = 0;
|
||||
res->file_handle = INVALID_HANDLE_VALUE;
|
||||
res->mmap_handle = NULL;
|
||||
mbstowcs(wfilename,filename,MAX_PATH);
|
||||
res->file_handle = CreateFileW(wfilename,
|
||||
#ifdef UNICODE
|
||||
mbstowcs(tfilename,filename,MAX_PATH);
|
||||
#else
|
||||
strlcpy(tfilename,filename,MAX_PATH);
|
||||
#endif
|
||||
res->file_handle = CreateFile(tfilename,
|
||||
GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
@ -1698,11 +1702,7 @@ get_uname(void)
|
||||
#endif
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
#if defined (WINCE)
|
||||
OSVERSIONINFO info;
|
||||
#else
|
||||
OSVERSIONINFOEXW info;
|
||||
#endif
|
||||
OSVERSIONINFOEX info;
|
||||
int i;
|
||||
const char *plat = NULL;
|
||||
const char *extra = NULL;
|
||||
@ -1724,13 +1724,17 @@ get_uname(void)
|
||||
};
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.dwOSVersionInfoSize = sizeof(info);
|
||||
if (! GetVersionExW((LPOSVERSIONINFOW)&info)) {
|
||||
if (! GetVersionEx((LPOSVERSIONINFO)&info)) {
|
||||
strlcpy(uname_result, "Bizarre version of Windows where GetVersionEx"
|
||||
" doesn't work.", sizeof(uname_result));
|
||||
uname_result_is_set = 1;
|
||||
return uname_result;
|
||||
}
|
||||
#ifdef UNICODE
|
||||
wcstombs(acsd, info.szCSDVersion, MAX_PATH);
|
||||
#else
|
||||
strlcpy(acsd, info.szCSDVersion, sizeof(acsd));
|
||||
#endif
|
||||
if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) {
|
||||
if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
||||
plat = "Windows NT 4.0";
|
||||
@ -2517,22 +2521,26 @@ network_init(void)
|
||||
char *
|
||||
format_win32_error(DWORD err)
|
||||
{
|
||||
LPVOID str = NULL;
|
||||
char abuf[1024] = {0};
|
||||
TCHAR *str = NULL;
|
||||
char *result;
|
||||
|
||||
/* Somebody once decided that this interface was better than strerror(). */
|
||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPWSTR) &str,
|
||||
(LPVOID)&str,
|
||||
0, NULL);
|
||||
|
||||
if (str) {
|
||||
#ifdef UNICODE
|
||||
char abuf[1024] = {0};
|
||||
wcstombs(abuf,str,1024);
|
||||
result = tor_strdup((char*)abuf);
|
||||
result = tor_strdup(abuf);
|
||||
#else
|
||||
result = tor_strdup(str);
|
||||
#endif
|
||||
LocalFree(str); /* LocalFree != free() */
|
||||
} else {
|
||||
result = tor_strdup("<unformattable error>");
|
||||
|
@ -2569,26 +2569,34 @@ tor_listdir(const char *dirname)
|
||||
smartlist_t *result;
|
||||
#ifdef MS_WINDOWS
|
||||
char *pattern;
|
||||
WCHAR wpattern[MAX_PATH] = {0};
|
||||
TCHAR tpattern[MAX_PATH] = {0};
|
||||
char name[MAX_PATH] = {0};
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW findData;
|
||||
WIN32_FIND_DATA findData;
|
||||
size_t pattern_len = strlen(dirname)+16;
|
||||
pattern = tor_malloc(pattern_len);
|
||||
tor_snprintf(pattern, pattern_len, "%s\\*", dirname);
|
||||
mbstowcs(wpattern,pattern,MAX_PATH);
|
||||
if (INVALID_HANDLE_VALUE == (handle = FindFirstFileW(wpattern, &findData))) {
|
||||
#ifdef UNICODE
|
||||
mbstowcs(tpattern,pattern,MAX_PATH);
|
||||
#else
|
||||
strlcpy(tpattern, pattern, MAX_PATH);
|
||||
#endif
|
||||
if (INVALID_HANDLE_VALUE == (handle = FindFirstFile(tpattern, &findData))) {
|
||||
tor_free(pattern);
|
||||
return NULL;
|
||||
}
|
||||
wcstombs(name,findData.cFileName,MAX_PATH);
|
||||
result = smartlist_create();
|
||||
while (1) {
|
||||
#ifdef UNICODE
|
||||
wcstombs(name,findData.cFileName,MAX_PATH);
|
||||
#else
|
||||
strlcpy(name,findData.cFileName,sizeof(name));
|
||||
#endif
|
||||
if (strcmp(name, ".") &&
|
||||
strcmp(name, "..")) {
|
||||
smartlist_add(result, tor_strdup(name));
|
||||
}
|
||||
if (!FindNextFileW(handle, &findData)) {
|
||||
if (!FindNextFile(handle, &findData)) {
|
||||
DWORD err;
|
||||
if ((err = GetLastError()) != ERROR_NO_MORE_FILES) {
|
||||
char *errstr = format_win32_error(err);
|
||||
|
@ -3832,7 +3832,7 @@ get_windows_conf_root(void)
|
||||
{
|
||||
static int is_set = 0;
|
||||
static char path[MAX_PATH+1];
|
||||
WCHAR wpath[MAX_PATH] = {0};
|
||||
TCHAR tpath[MAX_PATH] = {0};
|
||||
|
||||
LPITEMIDLIST idl;
|
||||
IMalloc *m;
|
||||
@ -3859,8 +3859,12 @@ get_windows_conf_root(void)
|
||||
return path;
|
||||
}
|
||||
/* Convert the path from an "ID List" (whatever that is!) to a path. */
|
||||
result = SHGetPathFromIDListW(idl, wpath);
|
||||
wcstombs(path,wpath,MAX_PATH);
|
||||
result = SHGetPathFromIDList(idl, tpath);
|
||||
#ifdef UNICODE
|
||||
wcstombs(path,tpath,MAX_PATH);
|
||||
#else
|
||||
strlcpy(path,tpath,sizeof(path));
|
||||
#endif
|
||||
|
||||
/* Now we need to free the memory that the path-idl was stored in. In
|
||||
* typical Windows fashion, we can't just call 'free()' on it. */
|
||||
|
@ -3132,7 +3132,7 @@ load_nameservers_with_getnetworkparams(void)
|
||||
GetNetworkParams_fn_t fn;
|
||||
|
||||
/* XXXX Possibly, we should hardcode the location of this DLL. */
|
||||
if (!(handle = LoadLibraryW(L"iphlpapi.dll"))) {
|
||||
if (!(handle = LoadLibrary(TEXT("iphlpapi.dll"))) {
|
||||
log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
|
||||
/* right now status = 0, doesn't that mean "good" - mikec */
|
||||
status = -1;
|
||||
@ -3201,46 +3201,44 @@ load_nameservers_with_getnetworkparams(void)
|
||||
}
|
||||
|
||||
static int
|
||||
config_nameserver_from_reg_key(HKEY key, const char *subkey)
|
||||
config_nameserver_from_reg_key(HKEY key, const TCHAR *subkey)
|
||||
{
|
||||
char *buf;
|
||||
DWORD bufsz = 0, type = 0;
|
||||
WCHAR wsubkey[MAX_PATH] = {0};
|
||||
char ansibuf[MAX_PATH] = {0};
|
||||
int status = 0;
|
||||
|
||||
mbstowcs(wsubkey,subkey,MAX_PATH);
|
||||
if (RegQueryValueExW(key, wsubkey, 0, &type, NULL, &bufsz)
|
||||
if (RegQueryValueEx(key, subkey, 0, &type, NULL, &bufsz)
|
||||
!= ERROR_MORE_DATA)
|
||||
return -1;
|
||||
if (!(buf = mm_malloc(bufsz)))
|
||||
return -1;
|
||||
|
||||
if (RegQueryValueExW(key, wsubkey, 0, &type, (LPBYTE)buf, &bufsz)
|
||||
if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
|
||||
== ERROR_SUCCESS && bufsz > 1) {
|
||||
wcstombs(ansibuf,(wchar_t*)buf,MAX_PATH);
|
||||
status = evdns_nameserver_ip_add_line(ansibuf);
|
||||
wcstombs(ansibuf,(wchar_t*)buf,MAX_PATH);/*XXXX UNICODE */
|
||||
status = evdns_nameserver_ip_add_line(buf);
|
||||
}
|
||||
|
||||
mm_free(buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
#define SERVICES_KEY L"System\\CurrentControlSet\\Services\\"
|
||||
#define WIN_NS_9X_KEY SERVICES_KEY L"VxD\\MSTCP"
|
||||
#define WIN_NS_NT_KEY SERVICES_KEY L"Tcpip\\Parameters"
|
||||
#define SERVICES_KEY TEXT("System\\CurrentControlSet\\Services\\")
|
||||
#define WIN_NS_9X_KEY SERVICES_KEY TEXT("VxD\\MSTCP")
|
||||
#define WIN_NS_NT_KEY SERVICES_KEY TEXT("Tcpip\\Parameters")
|
||||
|
||||
static int
|
||||
load_nameservers_from_registry(void)
|
||||
{
|
||||
int found = 0;
|
||||
int r;
|
||||
OSVERSIONINFO info = {0};
|
||||
OSVERSIONINFO info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.dwOSVersionInfoSize = sizeof (info);
|
||||
GetVersionExW((LPOSVERSIONINFO)&info);
|
||||
GetVersionEx(&info);
|
||||
|
||||
#define TRY(k, name) \
|
||||
if (!found && config_nameserver_from_reg_key(k,name) == 0) { \
|
||||
if (!found && config_nameserver_from_reg_key(k,TEXT(name)) == 0) { \
|
||||
log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
|
||||
found = 1; \
|
||||
} else if (!found) { \
|
||||
@ -3251,12 +3249,12 @@ load_nameservers_from_registry(void)
|
||||
if (info.dwMajorVersion >= 5) { /* NT */
|
||||
HKEY nt_key = 0, interfaces_key = 0;
|
||||
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
|
||||
KEY_READ, &nt_key) != ERROR_SUCCESS) {
|
||||
log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
r = RegOpenKeyExW(nt_key, L"Interfaces", 0,
|
||||
r = RegOpenKeyEx(nt_key, Text("Interfaces"), 0,
|
||||
KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
|
||||
&interfaces_key);
|
||||
if (r != ERROR_SUCCESS) {
|
||||
@ -3271,7 +3269,7 @@ load_nameservers_from_registry(void)
|
||||
RegCloseKey(nt_key);
|
||||
} else {
|
||||
HKEY win_key = 0;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
|
||||
KEY_READ, &win_key) != ERROR_SUCCESS) {
|
||||
log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
|
||||
return -1;
|
||||
|
113
src/or/ntmain.c
113
src/or/ntmain.c
@ -15,12 +15,12 @@
|
||||
#include <event.h>
|
||||
#endif
|
||||
|
||||
#include <tchar.h>
|
||||
#define GENSRV_SERVICENAME TEXT("tor")
|
||||
#define GENSRV_DISPLAYNAME TEXT("Tor Win32 Service")
|
||||
#include <windows.h>
|
||||
#define GENSRV_SERVICENAME "tor"
|
||||
#define GENSRV_DISPLAYNAME "Tor Win32 Service"
|
||||
#define GENSRV_DESCRIPTION \
|
||||
TEXT("Provides an anonymous Internet communication system")
|
||||
#define GENSRV_USERACCT TEXT("NT AUTHORITY\\LocalService")
|
||||
"Provides an anonymous Internet communication system"
|
||||
#define GENSRV_USERACCT "NT AUTHORITY\\LocalService"
|
||||
|
||||
// Cheating: using the pre-defined error codes, tricks Windows into displaying
|
||||
// a semi-related human-readable error message if startup fails as
|
||||
@ -36,7 +36,6 @@ static SERVICE_STATUS_HANDLE hStatus;
|
||||
* to the NT service functions. */
|
||||
static char **backup_argv;
|
||||
static int backup_argc;
|
||||
static char* nt_strerror(uint32_t errnum);
|
||||
|
||||
static void nt_service_control(DWORD request);
|
||||
static void nt_service_body(int argc, char **argv);
|
||||
@ -70,30 +69,30 @@ struct service_fns {
|
||||
|
||||
SC_HANDLE (WINAPI *CreateServiceA_fn)(
|
||||
SC_HANDLE hSCManager,
|
||||
LPCTSTR lpServiceName,
|
||||
LPCTSTR lpDisplayName,
|
||||
LPCSTR lpServiceName,
|
||||
LPCSTR lpDisplayName,
|
||||
DWORD dwDesiredAccess,
|
||||
DWORD dwServiceType,
|
||||
DWORD dwStartType,
|
||||
DWORD dwErrorControl,
|
||||
LPCTSTR lpBinaryPathName,
|
||||
LPCTSTR lpLoadOrderGroup,
|
||||
LPCSTR lpBinaryPathName,
|
||||
LPCSTR lpLoadOrderGroup,
|
||||
LPDWORD lpdwTagId,
|
||||
LPCTSTR lpDependencies,
|
||||
LPCTSTR lpServiceStartName,
|
||||
LPCTSTR lpPassword);
|
||||
LPCSTR lpDependencies,
|
||||
LPCSTR lpServiceStartName,
|
||||
LPCSTR lpPassword);
|
||||
|
||||
BOOL (WINAPI *DeleteService_fn)(
|
||||
SC_HANDLE hService);
|
||||
|
||||
SC_HANDLE (WINAPI *OpenSCManagerA_fn)(
|
||||
LPCTSTR lpMachineName,
|
||||
LPCTSTR lpDatabaseName,
|
||||
LPCSTR lpMachineName,
|
||||
LPCSTR lpDatabaseName,
|
||||
DWORD dwDesiredAccess);
|
||||
|
||||
SC_HANDLE (WINAPI *OpenServiceA_fn)(
|
||||
SC_HANDLE hSCManager,
|
||||
LPCTSTR lpServiceName,
|
||||
LPCSTR lpServiceName,
|
||||
DWORD dwDesiredAccess);
|
||||
|
||||
BOOL (WINAPI *QueryServiceStatus_fn)(
|
||||
@ -101,23 +100,23 @@ struct service_fns {
|
||||
LPSERVICE_STATUS lpServiceStatus);
|
||||
|
||||
SERVICE_STATUS_HANDLE (WINAPI *RegisterServiceCtrlHandlerA_fn)(
|
||||
LPCTSTR lpServiceName,
|
||||
LPCSTR lpServiceName,
|
||||
LPHANDLER_FUNCTION lpHandlerProc);
|
||||
|
||||
BOOL (WINAPI *SetServiceStatus_fn)(SERVICE_STATUS_HANDLE,
|
||||
LPSERVICE_STATUS);
|
||||
|
||||
BOOL (WINAPI *StartServiceCtrlDispatcherA_fn)(
|
||||
const SERVICE_TABLE_ENTRY* lpServiceTable);
|
||||
const SERVICE_TABLE_ENTRYA* lpServiceTable);
|
||||
|
||||
BOOL (WINAPI *StartServiceA_fn)(
|
||||
SC_HANDLE hService,
|
||||
DWORD dwNumServiceArgs,
|
||||
LPCTSTR* lpServiceArgVectors);
|
||||
LPCSTR* lpServiceArgVectors);
|
||||
|
||||
BOOL (WINAPI *LookupAccountNameA_fn)(
|
||||
LPCTSTR lpSystemName,
|
||||
LPCTSTR lpAccountName,
|
||||
LPCSTR lpSystemName,
|
||||
LPCSTR lpAccountName,
|
||||
PSID Sid,
|
||||
LPDWORD cbSid,
|
||||
LPTSTR ReferencedDomainName,
|
||||
@ -140,7 +139,7 @@ nt_service_loadlibrary(void)
|
||||
return;
|
||||
|
||||
/* XXXX Possibly, we should hardcode the location of this DLL. */
|
||||
if (!(library = LoadLibrary("advapi32.dll"))) {
|
||||
if (!(library = LoadLibrary(TEXT("advapi32.dll")))) {
|
||||
log_err(LD_GENERAL, "Couldn't open advapi32.dll. Are you trying to use "
|
||||
"NT services on Windows 98? That doesn't work.");
|
||||
goto err;
|
||||
@ -284,20 +283,20 @@ nt_service_body(int argc, char **argv)
|
||||
static void
|
||||
nt_service_main(void)
|
||||
{
|
||||
SERVICE_TABLE_ENTRY table[2];
|
||||
SERVICE_TABLE_ENTRYA table[2];
|
||||
DWORD result = 0;
|
||||
char *errmsg;
|
||||
nt_service_loadlibrary();
|
||||
table[0].lpServiceName = (char*)GENSRV_SERVICENAME;
|
||||
table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)nt_service_body;
|
||||
table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)nt_service_body;
|
||||
table[1].lpServiceName = NULL;
|
||||
table[1].lpServiceProc = NULL;
|
||||
|
||||
if (!service_fns.StartServiceCtrlDispatcherA_fn(table)) {
|
||||
result = GetLastError();
|
||||
errmsg = nt_strerror(result);
|
||||
errmsg = format_win32_error(result);
|
||||
printf("Service error %d : %s\n", (int) result, errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
if (result == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
|
||||
if (tor_init(backup_argc, backup_argv) < 0)
|
||||
return;
|
||||
@ -332,9 +331,9 @@ nt_service_open_scm(void)
|
||||
nt_service_loadlibrary();
|
||||
if ((hSCManager = service_fns.OpenSCManagerA_fn(
|
||||
NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("OpenSCManager() failed : %s\n", errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
}
|
||||
return hSCManager;
|
||||
}
|
||||
@ -349,9 +348,9 @@ nt_service_open(SC_HANDLE hSCManager)
|
||||
nt_service_loadlibrary();
|
||||
if ((hService = service_fns.OpenServiceA_fn(hSCManager, GENSRV_SERVICENAME,
|
||||
SERVICE_ALL_ACCESS)) == NULL) {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("OpenService() failed : %s\n", errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
}
|
||||
return hService;
|
||||
}
|
||||
@ -383,14 +382,14 @@ nt_service_start(SC_HANDLE hService)
|
||||
printf("Service started successfully\n");
|
||||
return 0;
|
||||
} else {
|
||||
errmsg = nt_strerror(service_status.dwWin32ExitCode);
|
||||
errmsg = format_win32_error(service_status.dwWin32ExitCode);
|
||||
printf("Service failed to start : %s\n", errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
}
|
||||
} else {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("StartService() failed : %s\n", errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -427,14 +426,14 @@ nt_service_stop(SC_HANDLE hService)
|
||||
} else if (wait_time == MAX_SERVICE_WAIT_TIME) {
|
||||
printf("Service did not stop within %d seconds.\n", wait_time);
|
||||
} else {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("QueryServiceStatus() failed : %s\n",errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
}
|
||||
} else {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("ControlService() failed : %s\n", errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -448,6 +447,7 @@ static char *
|
||||
nt_service_command_line(int *using_default_torrc)
|
||||
{
|
||||
TCHAR tor_exe[MAX_PATH+1];
|
||||
char tor_exe_ascii[MAX_PATH+1];
|
||||
char *command, *options=NULL;
|
||||
smartlist_t *sl;
|
||||
int i, cmdlen;
|
||||
@ -473,18 +473,25 @@ nt_service_command_line(int *using_default_torrc)
|
||||
options = smartlist_join_strings(sl,"\" \"",0,NULL);
|
||||
smartlist_free(sl);
|
||||
|
||||
#ifdef UNICODE
|
||||
wcstombs(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii));
|
||||
#else
|
||||
strlcpy(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii));
|
||||
#endif
|
||||
|
||||
/* Allocate a string for the NT service command line */
|
||||
cmdlen = strlen(tor_exe) + (options?strlen(options):0) + 32;
|
||||
cmdlen = strlen(tor_exe_ascii) + (options?strlen(options):0) + 32;
|
||||
command = tor_malloc(cmdlen);
|
||||
|
||||
/* Format the service command */
|
||||
if (options) {
|
||||
if (tor_snprintf(command, cmdlen, "\"%s\" --nt-service \"%s\"",
|
||||
tor_exe, options)<0) {
|
||||
tor_exe_ascii, options)<0) {
|
||||
tor_free(command); /* sets command to NULL. */
|
||||
}
|
||||
} else { /* ! options */
|
||||
if (tor_snprintf(command, cmdlen, "\"%s\" --nt-service", tor_exe)<0) {
|
||||
if (tor_snprintf(command, cmdlen, "\"%s\" --nt-service",
|
||||
tor_exe_ascii)<0) {
|
||||
tor_free(command); /* sets command to NULL. */
|
||||
}
|
||||
}
|
||||
@ -509,7 +516,7 @@ nt_service_install(int argc, char **argv)
|
||||
|
||||
SC_HANDLE hSCManager = NULL;
|
||||
SC_HANDLE hService = NULL;
|
||||
SERVICE_DESCRIPTION sdBuff;
|
||||
SERVICE_DESCRIPTIONA sdBuff;
|
||||
char *command;
|
||||
char *errmsg;
|
||||
const char *user_acct = GENSRV_USERACCT;
|
||||
@ -599,10 +606,10 @@ nt_service_install(int argc, char **argv)
|
||||
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
|
||||
command, NULL, NULL, NULL,
|
||||
user_acct, password)) == NULL) {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("CreateService() failed : %s\n", errmsg);
|
||||
service_fns.CloseServiceHandle_fn(hSCManager);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
tor_free(command);
|
||||
return -1;
|
||||
}
|
||||
@ -643,9 +650,9 @@ nt_service_remove(void)
|
||||
|
||||
nt_service_stop(hService);
|
||||
if (service_fns.DeleteService_fn(hService) == FALSE) {
|
||||
errmsg = nt_strerror(GetLastError());
|
||||
errmsg = format_win32_error(GetLastError());
|
||||
printf("DeleteService() failed : %s\n", errmsg);
|
||||
LocalFree(errmsg);
|
||||
tor_free(errmsg);
|
||||
service_fns.CloseServiceHandle_fn(hService);
|
||||
service_fns.CloseServiceHandle_fn(hSCManager);
|
||||
return -1;
|
||||
@ -702,20 +709,6 @@ nt_service_cmd_stop(void)
|
||||
return stop;
|
||||
}
|
||||
|
||||
/** Given a Win32 error code, this attempts to make Windows
|
||||
* return a human-readable error message. The char* returned
|
||||
* is allocated by Windows, but should be freed with LocalFree()
|
||||
* when finished with it. */
|
||||
static char*
|
||||
nt_strerror(uint32_t errnum)
|
||||
{
|
||||
char *msgbuf;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&msgbuf, 0, NULL);
|
||||
return msgbuf;
|
||||
}
|
||||
|
||||
int
|
||||
nt_service_parse_options(int argc, char **argv, int *should_exit)
|
||||
{
|
||||
|
@ -111,7 +111,7 @@ _testcase_run_forked(const struct testgroup_t *group,
|
||||
*/
|
||||
int ok;
|
||||
char buffer[LONGEST_TEST_NAME+256];
|
||||
STARTUPINFO si;
|
||||
STARTUPINFOA si;
|
||||
PROCESS_INFORMATION info;
|
||||
DWORD exitcode;
|
||||
|
||||
@ -130,7 +130,7 @@ _testcase_run_forked(const struct testgroup_t *group,
|
||||
memset(&info, 0, sizeof(info));
|
||||
si.cb = sizeof(si);
|
||||
|
||||
ok = CreateProcess(commandname, buffer, NULL, NULL, 0,
|
||||
ok = CreateProcessA(commandname, buffer, NULL, NULL, 0,
|
||||
0, NULL, NULL, &si, &info);
|
||||
if (!ok) {
|
||||
printf("CreateProcess failed!\n");
|
||||
|
Loading…
Reference in New Issue
Block a user