Преглед на файлове

Merge branch 'port_to_wince'

Nick Mathewson преди 15 години
родител
ревизия
2dce01982a
променени са 12 файла, в които са добавени 165 реда и са изтрити 42 реда
  1. 4 0
      changes/port_to_wince
  2. 31 13
      src/common/compat.c
  3. 18 2
      src/common/compat.h
  4. 4 0
      src/common/tortls.c
  5. 13 8
      src/common/util.c
  6. 3 3
      src/or/circuitbuild.c
  7. 9 2
      src/or/config.c
  8. 1 1
      src/or/dns.c
  9. 20 12
      src/or/eventdns.c
  10. 52 0
      src/or/main.c
  11. 2 0
      src/or/or.h
  12. 8 1
      src/win32/orconfig.h

+ 4 - 0
changes/port_to_wince

@@ -0,0 +1,4 @@
+  o Major features:
+    - Tor has now been ported to build and run correctly on Windows CE
+      systems, using the wcecompat library.  (Valerio Lupi)
+

+ 31 - 13
src/common/compat.c

@@ -169,12 +169,13 @@ tor_munmap_file(tor_mmap_t *handle)
 tor_mmap_t *
 tor_mmap_file(const char *filename)
 {
+  WCHAR wfilename[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;
-
-  res->file_handle = CreateFile(filename,
+  mbstowcs(wfilename,filename,MAX_PATH);
+  res->file_handle = CreateFileW(wfilename,
                                 GENERIC_READ, FILE_SHARE_READ,
                                 NULL,
                                 OPEN_EXISTING,
@@ -1697,10 +1698,15 @@ get_uname(void)
 #endif
       {
 #ifdef MS_WINDOWS
-        OSVERSIONINFOEX info;
+#if defined (WINCE)
+        OSVERSIONINFO info;
+#else
+        OSVERSIONINFOEXW info;
+#endif
         int i;
         const char *plat = NULL;
         const char *extra = NULL;
+        char acsd[MAX_PATH] = {0};
         static struct {
           unsigned major; unsigned minor; const char *version;
         } win_version_table[] = {
@@ -1718,20 +1724,21 @@ get_uname(void)
         };
         memset(&info, 0, sizeof(info));
         info.dwOSVersionInfoSize = sizeof(info);
-        if (! GetVersionEx((LPOSVERSIONINFO)&info)) {
+        if (! GetVersionExW((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;
         }
+        wcstombs(acsd, info.szCSDVersion, MAX_PATH);
         if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) {
           if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
             plat = "Windows NT 4.0";
           else
             plat = "Windows 95";
-          if (info.szCSDVersion[1] == 'B')
+          if (acsd[1] == 'B')
             extra = "OSR2 (B)";
-          else if (info.szCSDVersion[1] == 'C')
+          else if (acsd[1] == 'C')
             extra = "OSR2 (C)";
         } else {
           for (i=0; win_version_table[i].major>0; ++i) {
@@ -1743,14 +1750,14 @@ get_uname(void)
           }
         }
         if (plat && !strcmp(plat, "Windows 98")) {
-          if (info.szCSDVersion[1] == 'A')
+          if (acsd[1] == 'A')
             extra = "SE (A)";
-          else if (info.szCSDVersion[1] == 'B')
+          else if (acsd[1] == 'B')
             extra = "SE (B)";
         }
         if (plat) {
           if (!extra)
-            extra = info.szCSDVersion;
+            extra = acsd;
           tor_snprintf(uname_result, sizeof(uname_result), "%s %s",
                        plat, extra);
         } else {
@@ -1759,13 +1766,14 @@ get_uname(void)
             tor_snprintf(uname_result, sizeof(uname_result),
                       "Very recent version of Windows [major=%d,minor=%d] %s",
                       (int)info.dwMajorVersion,(int)info.dwMinorVersion,
-                      info.szCSDVersion);
+                      acsd);
           else
             tor_snprintf(uname_result, sizeof(uname_result),
                       "Unrecognized version of Windows [major=%d,minor=%d] %s",
                       (int)info.dwMajorVersion,(int)info.dwMinorVersion,
-                      info.szCSDVersion);
+                      acsd);
         }
+#if !defined (WINCE)
 #ifdef VER_SUITE_BACKOFFICE
         if (info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
           strlcat(uname_result, " [domain controller]", sizeof(uname_result));
@@ -1775,6 +1783,7 @@ get_uname(void)
           strlcat(uname_result, " [workstation]", sizeof(uname_result));
         }
 #endif
+#endif
 #else
         strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
 #endif
@@ -1902,8 +1911,15 @@ tor_gettimeofday(struct timeval *timeval)
     uint64_t ft_64;
     FILETIME ft_ft;
   } ft;
+#if defined (WINCE)
+  /* wince do not have GetSystemTimeAsFileTime */
+  SYSTEMTIME stime;
+  GetSystemTime(&stime);
+  SystemTimeToFileTime(&stime,&ft.ft_ft);
+#else
   /* number of 100-nsec units since Jan 1, 1601 */
   GetSystemTimeAsFileTime(&ft.ft_ft);
+#endif
   if (ft.ft_64 < EPOCH_BIAS) {
     log_err(LD_GENERAL,"System time is before 1970; failing.");
     exit(1);
@@ -2515,10 +2531,11 @@ char *
 format_win32_error(DWORD err)
 {
   LPVOID str = NULL;
+  char abuf[1024] = {0};
   char *result;
 
   /* Somebody once decided that this interface was better than strerror(). */
-  FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+  FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM |
                  FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL, err,
@@ -2527,7 +2544,8 @@ format_win32_error(DWORD err)
                  0, NULL);
 
   if (str) {
-    result = tor_strdup((char*)str);
+    wcstombs(abuf,str,1024);
+    result = tor_strdup((char*)abuf);
     LocalFree(str); /* LocalFree != free() */
   } else {
     result = tor_strdup("<unformattable error>");

+ 18 - 2
src/common/compat.h

@@ -51,6 +51,22 @@
 #include <netinet6/in6.h>
 #endif
 
+#if defined (WINCE)
+#include <fcntl.h>
+#include <io.h>
+#include <math.h>
+#include <projects.h>
+#define snprintf _snprintf
+/* this is not exported as W .... */
+#define SHGetPathFromIDListW SHGetPathFromIDList
+/* wcecompat has vasprintf */
+#define HAVE_VASPRINTF
+/* no service here */
+#ifdef NT_SERVICE
+#undef NT_SERVICE
+#endif
+#endif // WINCE
+
 #ifndef NULL_REP_IS_ZERO_BYTES
 #error "It seems your platform does not represent NULL as zero. We can't cope."
 #endif
@@ -177,8 +193,8 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
 /* ===== String compatibility */
 #ifdef MS_WINDOWS
 /* Windows names string functions differently from most other platforms. */
-#define strncasecmp strnicmp
-#define strcasecmp stricmp
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
 #endif
 #ifndef HAVE_STRLCAT
 size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));

+ 4 - 0
src/common/tortls.c

@@ -16,6 +16,10 @@
 
 #include "orconfig.h"
 
+#if defined (WINCE)
+#include <WinSock2.h>
+#endif
+
 #include <assert.h>
 #include <openssl/ssl.h>
 #include <openssl/ssl3.h>

+ 13 - 8
src/common/util.c

@@ -1707,7 +1707,7 @@ check_private_dir(const char *dirname, cpd_check_t check)
       return -1;
     } else if (check == CPD_CREATE) {
       log_info(LD_GENERAL, "Creating directory %s", dirname);
-#ifdef MS_WINDOWS
+#if defined (MS_WINDOWS) && !defined (WINCE)
       r = mkdir(dirname);
 #else
       r = mkdir(dirname, 0700);
@@ -1843,7 +1843,8 @@ start_writing_to_file(const char *fname, int open_flags, int mode,
   if (open_flags & O_BINARY)
     new_file->binary = 1;
 
-  if ((new_file->fd = open(open_name, open_flags, mode)) < 0) {
+  new_file->fd = open(open_name, open_flags, mode);
+  if (new_file->fd < 0) {
     log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
         open_name, fname, strerror(errno));
     goto err;
@@ -2526,22 +2527,26 @@ tor_listdir(const char *dirname)
   smartlist_t *result;
 #ifdef MS_WINDOWS
   char *pattern;
+  WCHAR wpattern[MAX_PATH] = {0};
+  char name[MAX_PATH] = {0};
   HANDLE handle;
-  WIN32_FIND_DATA findData;
+  WIN32_FIND_DATAW findData;
   size_t pattern_len = strlen(dirname)+16;
   pattern = tor_malloc(pattern_len);
   tor_snprintf(pattern, pattern_len, "%s\\*", dirname);
-  if (INVALID_HANDLE_VALUE == (handle = FindFirstFile(pattern, &findData))) {
+  mbstowcs(wpattern,pattern,MAX_PATH);
+  if (INVALID_HANDLE_VALUE == (handle = FindFirstFileW(wpattern, &findData))) {
     tor_free(pattern);
     return NULL;
   }
+  wcstombs(name,findData.cFileName,MAX_PATH);
   result = smartlist_create();
   while (1) {
-    if (strcmp(findData.cFileName, ".") &&
-        strcmp(findData.cFileName, "..")) {
-      smartlist_add(result, tor_strdup(findData.cFileName));
+    if (strcmp(name, ".") &&
+        strcmp(name, "..")) {
+      smartlist_add(result, tor_strdup(name));
     }
-    if (!FindNextFile(handle, &findData)) {
+    if (!FindNextFileW(handle, &findData)) {
       DWORD err;
       if ((err = GetLastError()) != ERROR_NO_MORE_FILES) {
         char *errstr = format_win32_error(err);

+ 3 - 3
src/or/circuitbuild.c

@@ -2327,7 +2327,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
      * possibly support any of them.  Choose a router at random that satisfies
      * at least one predicted exit port. */
 
-    int try;
+    int attempt;
     smartlist_t *needed_ports, *supporting, *use;
 
     if (best_support == -1) {
@@ -2347,13 +2347,13 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
     supporting = smartlist_create();
     use = smartlist_create();
     needed_ports = circuit_get_unhandled_ports(time(NULL));
-    for (try = 0; try < 2; try++) {
+    for (attempt = 0; attempt < 2; attempt++) {
       /* try once to pick only from routers that satisfy a needed port,
        * then if there are none, pick from any that support exiting. */
       for (i = 0; i < smartlist_len(dir->routers); i++) {
         router = smartlist_get(dir->routers, i);
         if (n_supported[i] != -1 &&
-            (try || router_handles_some_port(router, needed_ports))) {
+            (attempt || router_handles_some_port(router, needed_ports))) {
 //          log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.",
 //                 try, router->nickname);
           smartlist_add(supporting, router);

+ 9 - 2
src/or/config.c

@@ -217,8 +217,12 @@ static config_var_t _option_vars[] = {
   V(ExitPortStatistics,          BOOL,     "0"),
   V(ExtraInfoStatistics,         BOOL,     "0"),
 
+#if defined (WINCE)
+  V(FallbackNetworkstatusFile,   FILENAME, "fallback-consensus"),
+#else
   V(FallbackNetworkstatusFile,   FILENAME,
     SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
+#endif
   V(FascistFirewall,             BOOL,     "0"),
   V(FirewallPorts,               CSV,      ""),
   V(FastFirstHopPK,              BOOL,     "1"),
@@ -3697,6 +3701,7 @@ get_windows_conf_root(void)
 {
   static int is_set = 0;
   static char path[MAX_PATH+1];
+  WCHAR wpath[MAX_PATH] = {0};
 
   LPITEMIDLIST idl;
   IMalloc *m;
@@ -3714,7 +3719,7 @@ get_windows_conf_root(void)
 #define APPDATA_PATH CSIDL_APPDATA
 #endif
   if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL, APPDATA_PATH, &idl))) {
-    GetCurrentDirectory(MAX_PATH, path);
+    getcwd(path,MAX_PATH);
     is_set = 1;
     log_warn(LD_CONFIG,
              "I couldn't find your application data folder: are you "
@@ -3723,7 +3728,9 @@ get_windows_conf_root(void)
     return path;
   }
   /* Convert the path from an "ID List" (whatever that is!) to a path. */
-  result = SHGetPathFromIDList(idl, path);
+  result = SHGetPathFromIDListW(idl, wpath);
+  wcstombs(path,wpath,MAX_PATH);
+
   /* Now we need to free the */
   SHGetMalloc(&m);
   if (m) {

+ 1 - 1
src/or/dns.c

@@ -453,7 +453,7 @@ purge_expired_resolves(time_t now)
         log_err(LD_BUG, "The expired resolve we purged didn't match any in"
                 " the cache. Tried to purge %s (%p); instead got %s (%p).",
                 resolve->address, (void*)resolve,
-                removed ? removed->address : "NULL", (void*)remove);
+                removed ? removed->address : "NULL", (void*)removed);
       }
       tor_assert(removed == resolve);
     } else {

+ 20 - 12
src/or/eventdns.c

@@ -3132,13 +3132,13 @@ load_nameservers_with_getnetworkparams(void)
 	GetNetworkParams_fn_t fn;
 
 	/* XXXX Possibly, we should hardcode the location of this DLL. */
-	if (!(handle = LoadLibrary("iphlpapi.dll"))) {
+	if (!(handle = LoadLibraryW(L"iphlpapi.dll"))) {
 		log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
 		/* right now status = 0, doesn't that mean "good" - mikec */
 		status = -1;
 		goto done;
 	}
-	if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, "GetNetworkParams"))) {
+	if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, TEXT("GetNetworkParams")))) {
 		log(EVDNS_LOG_WARN, "Could not get address of function.");
 		/* same as above */
 		status = -1;
@@ -3205,32 +3205,40 @@ config_nameserver_from_reg_key(HKEY key, const char *subkey)
 {
 	char *buf;
 	DWORD bufsz = 0, type = 0;
+	WCHAR wsubkey[MAX_PATH] = {0};
+	char ansibuf[MAX_PATH] = {0};
 	int status = 0;
 
-	if (RegQueryValueEx(key, subkey, 0, &type, NULL, &bufsz)
+	mbstowcs(wsubkey,subkey,MAX_PATH);
+	if (RegQueryValueExW(key, wsubkey, 0, &type, NULL, &bufsz)
 		!= ERROR_MORE_DATA)
 		return -1;
 	if (!(buf = mm_malloc(bufsz)))
 		return -1;
 
-	if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
+	if (RegQueryValueExW(key, wsubkey, 0, &type, (LPBYTE)buf, &bufsz)
 		== ERROR_SUCCESS && bufsz > 1) {
-		status = evdns_nameserver_ip_add_line(buf);
+		wcstombs(ansibuf,(wchar_t*)buf,MAX_PATH);
+		status = evdns_nameserver_ip_add_line(ansibuf);
 	}
 
 	mm_free(buf);
 	return status;
 }
 
-#define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
-#define WIN_NS_9X_KEY  SERVICES_KEY "VxD\\MSTCP"
-#define WIN_NS_NT_KEY  SERVICES_KEY "Tcpip\\Parameters"
+#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"
 
 static int
 load_nameservers_from_registry(void)
 {
 	int found = 0;
 	int r;
+	OSVERSIONINFO info = {0};
+	info.dwOSVersionInfoSize = sizeof (info);
+	GetVersionExW((LPOSVERSIONINFO)&info);
+
 #define TRY(k, name)													\
 	if (!found && config_nameserver_from_reg_key(k,name) == 0) {		\
 		log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name);		\
@@ -3240,15 +3248,15 @@ load_nameservers_from_registry(void)
 			#k,#name);													\
 	}
 
-	if (((int)GetVersion()) > 0) { /* NT */
+	if (info.dwMajorVersion >= 5) { /* NT */
 		HKEY nt_key = 0, interfaces_key = 0;
 
-		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
+		if (RegOpenKeyExW(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 = RegOpenKeyEx(nt_key, "Interfaces", 0,
+		r = RegOpenKeyExW(nt_key, L"Interfaces", 0,
 						 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
 						 &interfaces_key);
 		if (r != ERROR_SUCCESS) {
@@ -3263,7 +3271,7 @@ load_nameservers_from_registry(void)
 		RegCloseKey(nt_key);
 	} else {
 		HKEY win_key = 0;
-		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
+		if (RegOpenKeyExW(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;

+ 52 - 0
src/or/main.c

@@ -2104,6 +2104,31 @@ do_hash_password(void)
   printf("16:%s\n",output);
 }
 
+#if defined (WINCE)
+int
+find_flashcard_path(PWCHAR path, size_t size)
+{
+  WIN32_FIND_DATA d = {0};
+  HANDLE h = NULL;
+
+  if (!path)
+    return -1;
+
+  h = FindFirstFlashCard(&d);
+  if (h == INVALID_HANDLE_VALUE)
+    return -1;
+
+  if (wcslen(d.cFileName) == 0) {
+    FindClose(h);
+    return -1;
+  }
+
+  wcsncpy(path,d.cFileName,size);
+  FindClose(h);
+  return 0;
+}
+#endif
+
 /** Main entry point for the Tor process.  Called from main(). */
 /* This function is distinct from main() only so we can link main.c into
  * the unittest binary without conflicting with the unittests' main. */
@@ -2111,6 +2136,33 @@ int
 tor_main(int argc, char *argv[])
 {
   int result = 0;
+#if defined (WINCE)
+  WCHAR path [MAX_PATH] = {0};
+  WCHAR fullpath [MAX_PATH] = {0};
+  PWCHAR p = NULL;
+  FILE* redir = NULL;
+  FILE* redirdbg = NULL;
+
+  // this is to facilitate debugging by opening
+  // a file on a folder shared by the wm emulator.
+  // if no flashcard (real or emulated) is present,
+  // log files will be written in the root folder
+  if (find_flashcard_path(path,MAX_PATH) == -1)
+  {
+    redir = _wfreopen( L"\\stdout.log", L"w", stdout );
+    redirdbg = _wfreopen( L"\\stderr.log", L"w", stderr );
+  } else {
+    swprintf(fullpath,L"\\%s\\tor",path);
+    CreateDirectory(fullpath,NULL);
+
+    swprintf(fullpath,L"\\%s\\tor\\stdout.log",path);
+    redir = _wfreopen( fullpath, L"w", stdout );
+
+    swprintf(fullpath,L"\\%s\\tor\\stderr.log",path);
+    redirdbg = _wfreopen( fullpath, L"w", stderr );
+  }
+#endif
+
   update_approx_time(time(NULL));
   tor_threads_init();
   init_logging();

+ 2 - 0
src/or/or.h

@@ -4377,8 +4377,10 @@ void networkstatus_free_all(void);
 
 /********************************* ntmain.c ***************************/
 #ifdef MS_WINDOWS
+#if !defined (WINCE)
 #define NT_SERVICE
 #endif
+#endif
 
 #ifdef NT_SERVICE
 int nt_service_parse_options(int argc, char **argv, int *should_exit);

+ 8 - 1
src/win32/orconfig.h

@@ -88,11 +88,18 @@
 #define HAVE_STRING_H
 
 /* Define to 1 if you have the `strlcat' function. */
+#if defined (WINCE)
+#define HAVE_STRLCAT
+#else
 #undef HAVE_STRLCAT
+#endif
 
 /* Define to 1 if you have the `strlcpy' function. */
+#if defined (WINCE)
+#define HAVE_STRLCPY
+#else
 #undef HAVE_STRLCPY
-
+#endif
 /* Define to 1 if you have the `strptime' function. */
 #undef HAVE_STRPTIME