[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [tor/master] Make the windows build succeed with or without -DUNICODE enabled.



Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Fri, 20 Aug 2010 12:30:25 -0400
Subject: Make the windows build succeed with or without -DUNICODE enabled.
Commit: c0c78682508c72940c8c7eee99aaea0da16ce34a

This should keep WinCE working (unicode always-on) and get Win98
working again (unicode never-on).

There are two places where we explicitly use ASCII-only APIs, still:
in ntmain.c and in the unit tests.

This patch also fixes a bug in windoes tor_listdir that would cause
the first file to be listed an arbitrary number of times that was
also introduced with WinCE support.

Should fix bug 1797.
---
 changes/win32_unicode |   11 +++++
 src/common/compat.c   |   36 ++++++++++------
 src/common/util.c     |   20 ++++++---
 src/or/config.c       |   10 +++-
 src/or/eventdns.c     |   34 +++++++--------
 src/or/ntmain.c       |  113 +++++++++++++++++++++++--------------------------
 src/test/tinytest.c   |    4 +-
 7 files changed, 125 insertions(+), 103 deletions(-)
 create mode 100644 changes/win32_unicode

diff --git a/changes/win32_unicode b/changes/win32_unicode
new file mode 100644
index 0000000..f64a22f
--- /dev/null
+++ b/changes/win32_unicode
@@ -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.
diff --git a/src/common/compat.c b/src/common/compat.c
index e9101a8..20394b4 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -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>");
diff --git a/src/common/util.c b/src/common/util.c
index 6830ef3..0f50dfe 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2526,26 +2526,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);
diff --git a/src/or/config.c b/src/or/config.c
index 7ad272f..6b3bcf6 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -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. */
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index 4e44d15..14c5d88 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -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;
diff --git a/src/or/ntmain.c b/src/or/ntmain.c
index 7163f5c..0b611f0 100644
--- a/src/or/ntmain.c
+++ b/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)
 {
diff --git a/src/test/tinytest.c b/src/test/tinytest.c
index b358bb3..b453308 100644
--- a/src/test/tinytest.c
+++ b/src/test/tinytest.c
@@ -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");
-- 
1.7.1