aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2010-09-06 10:06:07 -0400
committerNick Mathewson <nickm@torproject.org>2010-09-06 10:06:07 -0400
commitedc9256e95e307092d57cf273ac699f33cb0192b (patch)
treecaca10af727a849131c1d23716cd7d6e3a97487e /src
parent20817403173dcd2f8128c9c8b14491117cdc40b6 (diff)
parentc0c78682508c72940c8c7eee99aaea0da16ce34a (diff)
downloadtor-edc9256e95e307092d57cf273ac699f33cb0192b.tar
tor-edc9256e95e307092d57cf273ac699f33cb0192b.tar.gz
Merge remote branch 'public/win_unicode_fixes'
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.c36
-rw-r--r--src/common/util.c20
-rw-r--r--src/or/config.c10
-rw-r--r--src/or/eventdns.c34
-rw-r--r--src/or/ntmain.c113
-rw-r--r--src/test/tinytest.c4
6 files changed, 114 insertions, 103 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index e9101a8d7..20394b4c5 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 2781fa35d..1d770458f 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -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);
diff --git a/src/or/config.c b/src/or/config.c
index 7ad272f74..6b3bcf6da 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 4e44d1516..14c5d88df 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 7163f5c9a..0b611f0bf 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 b358bb3a4..b45330812 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");