Merge branch 'port_to_wince'

This commit is contained in:
Nick Mathewson 2010-05-24 12:17:43 -04:00
commit 2dce01982a
12 changed files with 165 additions and 42 deletions

4
changes/port_to_wince Normal file
View file

@ -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)

View file

@ -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>");

View file

@ -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));

View file

@ -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>

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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 {

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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