From ee23d4b549618044d4a4f800db839483b359cb9f Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Thu, 18 Apr 2013 14:55:47 +0200 Subject: erts: Windows, convert erlsrv to use widestring --- erts/etc/win32/erlsrv/erlsrv_global.h | 10 +- erts/etc/win32/erlsrv/erlsrv_interactive.c | 669 +++++++++++++++-------------- erts/etc/win32/erlsrv/erlsrv_interactive.h | 2 +- erts/etc/win32/erlsrv/erlsrv_main.c | 2 +- erts/etc/win32/erlsrv/erlsrv_registry.c | 249 ++++++----- erts/etc/win32/erlsrv/erlsrv_registry.h | 16 +- erts/etc/win32/erlsrv/erlsrv_service.c | 403 ++++++++--------- erts/etc/win32/erlsrv/erlsrv_service.h | 2 +- erts/etc/win32/erlsrv/erlsrv_util.c | 100 ++--- erts/etc/win32/erlsrv/erlsrv_util.h | 18 +- 10 files changed, 753 insertions(+), 718 deletions(-) (limited to 'erts/etc/win32/erlsrv') diff --git a/erts/etc/win32/erlsrv/erlsrv_global.h b/erts/etc/win32/erlsrv/erlsrv_global.h index d3922dc1e3..f25e09ea45 100644 --- a/erts/etc/win32/erlsrv/erlsrv_global.h +++ b/erts/etc/win32/erlsrv/erlsrv_global.h @@ -19,13 +19,13 @@ #ifndef _ERLSRV_GLOBAL_H #define _ERLSRV_GLOBAL_H -#define APP_NAME "ErlSrv" +#define APP_NAME L"ErlSrv" -#define ERLANG_MACHINE "erl.exe" +#define ERLANG_MACHINE L"erl.exe" -#define SERVICE_ENV "ERLSRV_SERVICE_NAME" -#define EXECUTABLE_ENV "ERLSRV_EXECUTABLE" -#define DEBUG_ENV "ERLSRV_DEBUG" +#define SERVICE_ENV L"ERLSRV_SERVICE_NAME" +#define EXECUTABLE_ENV L"ERLSRV_EXECUTABLE" +#define DEBUG_ENV L"ERLSRV_DEBUG" #ifdef _DEBUG #define HARDDEBUG 1 diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.c b/erts/etc/win32/erlsrv/erlsrv_interactive.c index 3f7e20b923..c370485ac1 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.c +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.c @@ -27,54 +27,60 @@ #include "erlsrv_interactive.h" #include "erlsrv_util.h" /* service_name */ -#define DBG fprintf(stderr,"argv[0]:%s line %d\n",argv[0],__LINE__) +#define DBG fwprintf(stderr,L"argv[0]:%s line %d\n",argv[0],__LINE__) +/* #define HARDDEBUG 1 */ + +#include /* Really HAS to correcpond to the enum in erlsrv_registry.h */ -static char *arg_tab[] = { - "stopaction", "st", - "onfail", "on", - "machine", "m", - "env", "e", - "workdir", "w", - "priority", "p", - "sname", "sn", - "name", "n", - "args", "ar", - "debugtype", "d", - "internalservicename","i", - "comment","c", +static wchar_t *arg_tab[] = { + L"stopaction", L"st", + L"onfail", L"on", + L"machine", L"m", + L"env", L"e", + L"workdir", L"w", + L"priority", L"p", + L"sname", L"sn", + L"name", L"n", + L"args", L"ar", + L"debugtype", L"d", + L"internalservicename",L"i", + L"comment",L"c", NULL, NULL }; -static char *generate_real_service_name(char *display_name){ +static wchar_t *generate_real_service_name(wchar_t *display_name){ SYSTEMTIME systime; FILETIME ftime; - char *buff = malloc(strlen(display_name)+ - (8*2)+1); - char *tmp = _strdup(display_name); + int len=(wcslen(display_name)+(8*2)+1); + wchar_t *buff; + wchar_t *tmp = _wcsdup(display_name); int i; + buff = (wchar_t*) malloc(len*sizeof(wchar_t)); + /* 2 Hex chars for each byte in a DWORD */ GetSystemTime(&systime); SystemTimeToFileTime(&systime,&ftime); /* Remove trailing version info to avoid user confusion */ - for(i = (strlen(tmp)-1);i > 0; --i) - if(tmp[i] == '_'){ - tmp[i] = '\0'; + for(i = (wcslen(tmp)-1);i > 0; --i) + if(tmp[i] == L'_'){ + tmp[i] = L'\0'; break; } - sprintf(buff,"%s%08x%08x",tmp,ftime.dwHighDateTime, - ftime.dwLowDateTime); + swprintf(buff,len,L"%s%08x%08x",tmp, + ftime.dwHighDateTime, + ftime.dwLowDateTime); free(tmp); return buff; } -static int lookup_arg(char *arg){ +static int lookup_arg(wchar_t *arg){ int i; - if(*arg != '-' && *arg != '/') + if(*arg != L'-' && *arg != L'/') return -1; for(i=0; arg_tab[i] != NULL; i += 2){ - if(!_strnicmp(arg_tab[i],arg+1,strlen(arg+1)) && - !_strnicmp(arg_tab[i+1],arg+1,strlen(arg_tab[i+1]))) + if(!_wcsnicmp(arg_tab[i],arg+1,wcslen(arg+1)) && + !_wcsnicmp(arg_tab[i+1],arg+1,wcslen(arg_tab[i+1]))) return (i / 2); } return -1; @@ -82,29 +88,29 @@ static int lookup_arg(char *arg){ -char *edit_env(char *edit, char *oldenv){ - char **arg; - char *value; - char *name = strdup(edit); +wchar_t *edit_env(wchar_t *edit, wchar_t *oldenv){ + wchar_t **arg; + wchar_t *value; + wchar_t *name = wcsdup(edit); int i; - char *tmp; + wchar_t *tmp; arg = env_to_arg(oldenv); - value = strchr(name,'='); + value = wcschr(name,L'='); if(value){ - *(value++) = '\0'; - if(*value == '\0') + *(value++) = L'\0'; + if(*value == L'\0') value = NULL; } for(i=0;arg[i] != NULL; ++i){ - tmp = strchr(arg[i],'='); - if(((int) strlen(name)) == (tmp - arg[i]) && - !_strnicmp(name,arg[i], tmp - arg[i])) + tmp = wcschr(arg[i],L'='); + if(((int) wcslen(name)) == (tmp - arg[i]) && + !_wcsnicmp(name,arg[i], tmp - arg[i])) break; } if(arg[i] != NULL){ free(arg[i]); if(value){ - arg[i] = strdup(edit); + arg[i] = wcsdup(edit); } else { do { arg[i] = arg[i+1]; @@ -113,7 +119,7 @@ char *edit_env(char *edit, char *oldenv){ } } else if(value){ /* add to arg, which is always allocated to hold one extra environment variable*/ - arg[i] = strdup(edit); + arg[i] = wcsdup(edit); arg[i+1] = NULL; } free(name); @@ -132,8 +138,8 @@ void print_last_error(void){ (LPTSTR) &mes, 0, NULL ); - fprintf(stderr,"Error: %s",mes); - LocalFree(mes); + fwprintf(stderr,L"Error: %S",mes); + LocalFree(mes); } static int get_last_error(void) @@ -144,19 +150,19 @@ static int get_last_error(void) static BOOL install_service(void){ SC_HANDLE scm; SC_HANDLE service; - char filename[MAX_PATH + 3]; + wchar_t filename[MAX_PATH + 3]; DWORD fnsiz=MAX_PATH; - char dependant[] = { 'L','a','n','m','a','n', - 'W','o','r','k','s','t', - 'a','t','i','o','n','\0','\0'}; + wchar_t dependant[] = { L'L',L'a',L'n',L'm',L'a',L'n', + L'W',L'o',L'r',L'k',L's',L't', + L'a',L't',L'i',L'o',L'n',L'\0',L'\0'}; - if(!(fnsiz = GetModuleFileName(NULL, filename, fnsiz))) + if(!(fnsiz = GetModuleFileNameW(NULL, filename, fnsiz))) return FALSE; - if(strchr(filename,' ')){ - memmove(filename+1,filename,fnsiz); - filename[0] ='\"'; /* " */ - filename[fnsiz+1] = '\"'; /* " */ - filename[fnsiz+2] = '\0'; + if(wcschr(filename,L' ')){ + memmove(filename+1,filename,fnsiz*sizeof(wchar_t)); + filename[0] = L'\"'; /* " */ + filename[fnsiz+1] = L'\"'; /* " */ + filename[fnsiz+2] = L'\0'; } if((scm = OpenSCManager(NULL, NULL, @@ -166,20 +172,20 @@ static BOOL install_service(void){ last_error = GetLastError(); return FALSE; } - service = CreateService(scm, - real_service_name, - service_name, - SERVICE_ALL_ACCESS & - ~(SERVICE_PAUSE_CONTINUE), - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - filename, - NULL, - NULL, - dependant, - NULL, - NULL); + service = CreateServiceW(scm, + real_service_name, + service_name, + SERVICE_ALL_ACCESS & + ~(SERVICE_PAUSE_CONTINUE), + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + filename, + NULL, + NULL, + dependant, + NULL, + NULL); if(service == NULL){ CloseServiceHandle(scm); last_error = GetLastError(); @@ -198,9 +204,9 @@ static BOOL remove_service(void){ GENERIC_WRITE)) == NULL) return FALSE; - service = OpenService(scm, - real_service_name, - SERVICE_ALL_ACCESS); + service = OpenServiceW(scm, + real_service_name, + SERVICE_ALL_ACCESS); if(service == NULL){ CloseServiceHandle(scm); return FALSE; @@ -220,9 +226,9 @@ static BOOL open_service_control(SC_HANDLE *scm, SC_HANDLE *service){ SC_MANAGER_ALL_ACCESS)) == NULL) return FALSE; - *service = OpenService(*scm, - real_service_name, - SERVICE_ALL_ACCESS); + *service = OpenServiceW(*scm, + real_service_name, + SERVICE_ALL_ACCESS); if(service == NULL){ CloseServiceHandle(*scm); return FALSE; @@ -239,10 +245,10 @@ static BOOL open_service_config(SC_HANDLE *scm, SC_HANDLE *service){ last_error = GetLastError(); return FALSE; } - *service = OpenService(*scm, - real_service_name, - /*GENERIC_WRITE*/ - SERVICE_ALL_ACCESS); + *service = OpenServiceW(*scm, + real_service_name, + /*GENERIC_WRITE*/ + SERVICE_ALL_ACCESS); if(service == NULL){ last_error = GetLastError(); CloseServiceHandle(*scm); @@ -251,16 +257,16 @@ static BOOL open_service_config(SC_HANDLE *scm, SC_HANDLE *service){ return TRUE; } -static BOOL set_service_comment(char *comment) { +static BOOL set_service_comment(wchar_t *comment) { SC_HANDLE scm; SC_HANDLE service; - SERVICE_DESCRIPTION sd; + SERVICE_DESCRIPTIONW sd; BOOL ret = TRUE; sd.lpDescription = comment; if (!open_service_config(&scm,&service)) { return FALSE; } - if (!ChangeServiceConfig2(service,SERVICE_CONFIG_DESCRIPTION,&sd)) { + if (!ChangeServiceConfig2W(service,SERVICE_CONFIG_DESCRIPTION,&sd)) { last_error = GetLastError(); ret = FALSE; } @@ -325,7 +331,7 @@ static BOOL stop_service(void){ if(!open_service_control(&scm,&service)){ #ifdef HARDDEBUG - fprintf(stderr,"Failed to open service.\n"); + fwprintf(stderr,L"Failed to open service.\n"); #endif return FALSE; } @@ -338,7 +344,7 @@ static BOOL stop_service(void){ #ifdef HARDDEBUG if(!ret) { - fprintf(stderr,"Failed to control service.\n"); + fwprintf(stderr,L"Failed to control service.\n"); print_last_error(); } #endif @@ -466,115 +472,114 @@ void cleanup_old(){ } BOOL fill_in_defaults(RegEntry *new){ - char filename[MAX_PATH]; - char *ptr; + wchar_t filename[MAX_PATH]; + wchar_t *ptr; - if(!GetModuleFileName(NULL, filename, MAX_PATH)) + if(!GetModuleFileNameW(NULL, filename, MAX_PATH)) return FALSE; - for(ptr = filename + strlen(filename) - 1; - ptr > filename && *ptr != '\\'; + for(ptr = filename + wcslen(filename) - 1; + ptr > filename && *ptr != L'\\'; --ptr) ; - if(*ptr == '\\') + if(*ptr == L'\\') ++ptr; - *ptr = '\0'; + *ptr = L'\0'; - ptr = malloc(strlen(filename)+strlen(ERLANG_MACHINE)+1); - strcpy(ptr,filename); - strcat(ptr,ERLANG_MACHINE); + ptr = (wchar_t*) malloc((wcslen(filename)+wcslen(ERLANG_MACHINE)+1)*sizeof(wchar_t)); + wcscpy(ptr,filename); + wcscat(ptr,ERLANG_MACHINE); - new[StopAction].data.bytes = ""; + new[StopAction].data.string = L""; new[OnFail].data.value = ON_FAIL_IGNORE; - new[Machine].data.bytes = ptr; - new[Machine].data.expand.unexpanded = ptr; - new[Env].data.bytes = "\0"; - new[WorkDir].data.bytes = new[WorkDir].data.expand.unexpanded = - ""; + new[Machine].data.string = ptr; + new[Machine].data.expand.unexpanded = ptr; + new[Env].data.string = L"\0"; + new[WorkDir].data.string = new[WorkDir].data.expand.unexpanded = L""; new[Priority].data.value = NORMAL_PRIORITY_CLASS; - new[SName].data.bytes = service_name; - new[Name].data.bytes = ""; - new[Args].data.bytes = new[Args].data.expand.unexpanded = ""; + new[SName].data.string = service_name; + new[Name].data.string = L""; + new[Args].data.string = new[Args].data.expand.unexpanded = L""; new[DebugType].data.value = DEBUG_TYPE_NO_DEBUG; - new[InternalServiceName].data.bytes = real_service_name; - new[Comment].data.bytes = ""; + new[InternalServiceName].data.string = real_service_name; + new[Comment].data.string = L""; return TRUE; } -int do_usage(char *arg0){ - printf("Usage:\n"); - printf("%s {set | add} \n" - "\t[-st[opaction] []]\n" - "\t[-on[fail] [{reboot | restart | restart_always}]]\n" - "\t[-m[achine] []]\n" - "\t[-e[nv] [[=]]]\n" - "\t[-w[orkdir] []]\n" - "\t[-p[riority] [{low|high|realtime}]]\n" - "\t[{-sn[ame] | -n[ame]} []]\n" - "\t[-d[ebugtype] [{new|reuse|console}]]\n" - "\t[-ar[gs] []]\n\n" - "%s {start | start_disabled | stop | disable | enable} \n\n" - "%s remove \n\n" - "%s rename \n\n" - "%s list []\n\n" - "%s help\n\n", +int do_usage(wchar_t *arg0){ + wprintf(L"Usage:\n"); + wprintf(L"%s {set | add} \n" + L"\t[-st[opaction] []]\n" + L"\t[-on[fail] [{reboot | restart | restart_always}]]\n" + L"\t[-m[achine] []]\n" + L"\t[-e[nv] [[=]]]\n" + L"\t[-w[orkdir] []]\n" + L"\t[-p[riority] [{low|high|realtime}]]\n" + L"\t[{-sn[ame] | -n[ame]} []]\n" + L"\t[-d[ebugtype] [{new|reuse|console}]]\n" + L"\t[-ar[gs] []]\n\n" + L"%s {start | start_disabled | stop | disable | enable} \n\n" + L"%s remove \n\n" + L"%s rename \n\n" + L"%s list []\n\n" + L"%s help\n\n", arg0,arg0,arg0,arg0,arg0,arg0); - printf("Manipulates Erlang system services on Windows NT.\n\n"); - printf("When no parameter to an option is specified, the option\n" - "is reset to it's default value. To set an empty argument\n" - "list, give option -args as last option on command line " - "with\n" - "no arguments.\n\n"); - printf("See Erlang documentation for full description.\n"); + wprintf(L"Manipulates Erlang system services on Windows NT.\n\n"); + wprintf(L"When no parameter to an option is specified, the option\n" + L"is reset to it's default value. To set an empty argument\n" + L"list, give option -args as last option on command line " + L"with\n" + L"no arguments.\n\n"); + wprintf(L"See Erlang documentation for full description.\n"); return 0; } -int do_manage(int argc,char **argv){ - char *action = argv[1]; +int do_manage(int argc, wchar_t **argv){ + wchar_t *action = argv[1]; RegEntry *current = empty_reg_tab(); if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; if(!fetch_current(current)){ - fprintf(stderr,"%s: The service %s is not an erlsrv controlled service.\n", + fwprintf(stderr,L"%s: The service %s is not an erlsrv controlled service.\n", argv[0],service_name); return 1; } - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); free_keys(current); - if(!_stricmp(action,"start")){ + if(!_wcsicmp(action,L"start")){ if(!start_service()){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_RUNNING, 60)){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s started.\n", + wprintf(L"%s: Service %s started.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"start_disabled")){ + if(!_wcsicmp(action,L"start_disabled")){ if(!enable_service()){ - fprintf(stderr,"%s: Failed to enable service %s.\n", + fwprintf(stderr,L"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!start_service() && get_last_error() != ERROR_SERVICE_ALREADY_RUNNING){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); goto failure_starting; @@ -582,84 +587,84 @@ int do_manage(int argc,char **argv){ if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_RUNNING, 60)){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); goto failure_starting; } if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s started.\n", + wprintf(L"%s: Service %s started.\n", argv[0],service_name); return 0; failure_starting: if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); } return 1; } - if(!_stricmp(action,"stop")){ + if(!_wcsicmp(action,L"stop")){ if(!stop_service()){ - fprintf(stderr,"%s: Failed to stop service %s.\n", + fwprintf(stderr,L"%s: Failed to stop service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { if(!wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ - fprintf(stderr,"%s: Failed to stop service %s.\n", + fwprintf(stderr,L"%s: Failed to stop service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s stopped.\n", + wprintf(L"%s: Service %s stopped.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"disable")){ + if(!_wcsicmp(action,L"disable")){ #if 0 if(stop_service()){ - printf("%s: Service %s stopped.\n", + wprintf(L"%s: Service %s stopped.\n", argv[0],service_name); } #endif if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { - printf("%s: Service %s disabled.\n", + wprintf(L"%s: Service %s disabled.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"enable")){ + if(!_wcsicmp(action,L"enable")){ if(!enable_service()){ - fprintf(stderr,"%s: Failed to enable service %s.\n", + fwprintf(stderr,L"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { - printf("%s: Service %s enabled.\n", + wprintf(L"%s: Service %s enabled.\n", argv[0],service_name); return 0; } } - fprintf(stderr,"%s: Unrecignized argument %s.\n", + fwprintf(stderr,L"%s: Unrecignized argument %s.\n", argv[0],action); return 1; } -int do_add_or_set(int argc, char **argv){ +int do_add_or_set(int argc, wchar_t **argv){ RegEntry *new_entries; RegEntry *default_entries; int add = 0; @@ -669,40 +674,40 @@ int do_add_or_set(int argc, char **argv){ new_entries = empty_reg_tab(); default_entries = empty_reg_tab(); if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; - if(!_stricmp(argv[1],"add")){ + if(!_wcsicmp(argv[1],L"add")){ if(fetch_current(default_entries)){ - fprintf(stderr,"%s: A service with the name %s already " - "exists.\n", + fwprintf(stderr,L"%s: A service with the name %s already " + L"exists.\n", argv[0],service_name); return 1; } real_service_name = generate_real_service_name(service_name); if(!fill_in_defaults(new_entries)){ - fprintf(stderr,"%s: Internal error.\n", argv[0]); + fwprintf(stderr,L"%s: Internal error.\n", argv[0]); return 1; } add = 1; } else { if(!fetch_current(new_entries)){ - fprintf(stderr,"%s: No service with the name %s exists.\n", + fwprintf(stderr,L"%s: No service with the name %s exists.\n", argv[0], service_name); return 1; } - real_service_name = new_entries[InternalServiceName].data.bytes; + real_service_name = new_entries[InternalServiceName].data.string; } if(!fill_in_defaults(default_entries)){ - fprintf(stderr,"%s: Internal error.\n", argv[0]); + fwprintf(stderr,L"%s: Internal error.\n", argv[0]); return 1; } /* make sure env is malloced... */ - new_entries[Env].data.bytes = envdup(new_entries[Env].data.bytes); + new_entries[Env].data.string = envdup(new_entries[Env].data.string); for(i = 3; i < argc; ++i){ switch((current = lookup_arg(argv[i]))){ @@ -712,43 +717,43 @@ int do_add_or_set(int argc, char **argv){ case WorkDir: case Args: if(i+1 >= argc){ - new_entries[current].data.bytes = - default_entries[current].data.bytes; + new_entries[current].data.string = + default_entries[current].data.string; new_entries[current].data.expand.unexpanded = default_entries[current].data.expand.unexpanded; } else { new_entries[current].data.expand.unexpanded = - new_entries[current].data.bytes = argv[i+1]; + new_entries[current].data.string = argv[i+1]; ++i; } break; case SName: - new_entries[Name].data.bytes = ""; + new_entries[Name].data.string = L""; case StopAction: case Name: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ - new_entries[current].data.bytes = - default_entries[current].data.bytes; + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ + new_entries[current].data.string = + default_entries[current].data.string; } else { - new_entries[current].data.bytes = argv[i+1]; + new_entries[current].data.string = argv[i+1]; ++i; } break; case OnFail: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"reboot")) + if(!_wcsicmp(argv[i+1],L"reboot")) new_entries[current].data.value = ON_FAIL_REBOOT; - else if(!_stricmp(argv[i+1],"restart")) + else if(!_wcsicmp(argv[i+1],L"restart")) new_entries[current].data.value = ON_FAIL_RESTART; - else if(!_stricmp(argv[i+1],"restart_always")) + else if(!_wcsicmp(argv[i+1],L"restart_always")) new_entries[current].data.value = ON_FAIL_RESTART_ALWAYS; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -757,18 +762,18 @@ int do_add_or_set(int argc, char **argv){ break; case DebugType: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"new")) + if(!_wcsicmp(argv[i+1],L"new")) new_entries[current].data.value = DEBUG_TYPE_NEW; - else if(!_stricmp(argv[i+1],"reuse")) + else if(!_wcsicmp(argv[i+1],L"reuse")) new_entries[current].data.value = DEBUG_TYPE_REUSE; - else if(!_stricmp(argv[i+1],"console")) + else if(!_wcsicmp(argv[i+1],L"console")) new_entries[current].data.value = DEBUG_TYPE_CONSOLE; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -777,18 +782,18 @@ int do_add_or_set(int argc, char **argv){ break; case Priority: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"high")) + if(!_wcsicmp(argv[i+1],L"high")) new_entries[current].data.value = HIGH_PRIORITY_CLASS; - else if(!_stricmp(argv[i+1],"low")) + else if(!_wcsicmp(argv[i+1],L"low")) new_entries[current].data.value = IDLE_PRIORITY_CLASS; - else if(!_stricmp(argv[i+1],"realtime")) + else if(!_wcsicmp(argv[i+1],L"realtime")) new_entries[current].data.value = REALTIME_PRIORITY_CLASS; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -798,64 +803,64 @@ int do_add_or_set(int argc, char **argv){ case Env: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ - fprintf(stderr,"%s: %s requires a parameter.\n", + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ + fwprintf(stderr,L"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } - new_entries[current].data.bytes = - edit_env(argv[i+1], - new_entries[current].data.bytes); + new_entries[current].data.string = + edit_env(argv[i+1], new_entries[current].data.string); ++i; break; case InternalServiceName: if (!add) { - fprintf(stderr,"%s: %s only allowed when adding a new service.\n", + fwprintf(stderr,L"%s: %s only allowed when adding a new service.\n", argv[0],argv[i]); return 1; } if(i+1 >= argc){ - fprintf(stderr,"%s: %s requires a parameter.\n", + fwprintf(stderr,L"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } new_entries[InternalServiceName].data.expand.unexpanded = - new_entries[InternalServiceName].data.bytes = argv[i+1]; + new_entries[InternalServiceName].data.string = argv[i+1]; ++i; /* Discard old, should maybe be fred' but we'll exit anyway */ - real_service_name = new_entries[InternalServiceName].data.bytes; + real_service_name = new_entries[InternalServiceName].data.string; break; default: - fprintf(stderr,"%s: Unrecognized option %s.\n", argv[0], + fwprintf(stderr,L"%s: Unrecognized option %s.\n", argv[0], argv[i]); return 1; } } - if(*new_entries[SName].data.bytes && - *new_entries[Name].data.bytes){ + if(*new_entries[SName].data.string && + *new_entries[Name].data.string){ #if 0 - fprintf(stderr,"%s: Both -sname and -name specified.\n", + fwprintf(stderr,L"%s: Both -sname and -name specified.\n", argv[0]); return 1; #else - new_entries[SName].data.bytes = ""; + new_entries[SName].data.string = L""; #endif } - if(add && !(*new_entries[SName].data.bytes) && - !(*new_entries[Name].data.bytes)){ - fprintf(stderr,"%s: Neither -sname nor -name specified.\n", + if(add && !(*new_entries[SName].data.string) && + !(*new_entries[Name].data.string)){ + fwprintf(stderr,L"%s: Neither -sname nor -name specified.\n", argv[0]); return 1; } + if(add && !install_service()){ - fprintf(stderr,"%s: Unable to register service with service manager.\n", + fwprintf(stderr,L"%s: Unable to register %s service with service manager.\n", argv[0], service_name); print_last_error(); return 1; } if(!set_interactive(new_entries[DebugType].data.value == DEBUG_TYPE_CONSOLE)){ - fprintf(stderr,"%s: Warning, could not set correct interactive mode.\n", + fwprintf(stderr,L"%s: Warning, could not set correct interactive mode. %s\n", argv[0], service_name); print_last_error(); /* Not severe or??? */ @@ -865,9 +870,9 @@ int do_add_or_set(int argc, char **argv){ set_keys(service_name, new_entries); /* Update service comment if needed */ if(set_comment) { - if (!set_service_comment(new_entries[Comment].data.bytes)) { - fprintf(stderr,"%s: Warning, could not set correct " - "service description (comment)", + if (!set_service_comment(new_entries[Comment].data.string)) { + fwprintf(stderr,L"%s: Warning, could not set correct " + L"service description (comment) %s", argv[0], service_name); print_last_error(); } @@ -878,64 +883,64 @@ int do_add_or_set(int argc, char **argv){ malloced, but we'll exit anyway, so... */ cleanup_old(); if(add) - printf("%s: Service %s added to system.\n", + wprintf(L"%s: Service %s added to system.\n", argv[0], service_name); else - printf("%s: Service %s updated.\n", + wprintf(L"%s: Service %s updated.\n", argv[0], service_name); return 0; } -int do_rename(int argc, char **argv){ +int do_rename(int argc, wchar_t **argv){ RegEntry *current = empty_reg_tab(); RegEntry *dummy = empty_reg_tab(); SC_HANDLE scm; SC_HANDLE service; if(argc < 3){ - fprintf(stderr,"%s: No old servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No old servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } if(argc < 4){ - fprintf(stderr,"%s: No new servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No new servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[3]; if(fetch_current(dummy)){ - fprintf(stderr,"%s: A service with the name %s already " - "exists.\n", + fwprintf(stderr,L"%s: A service with the name %s already " + L"exists.\n", argv[0],service_name); return 1; } service_name = argv[2]; if(!fetch_current(current)){ - fprintf(stderr,"%s: Error, old service name %s does not exist.\n", + fwprintf(stderr,L"%s: Error, old service name %s does not exist.\n", argv[0],service_name); return 1; } - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); if(!open_service_config(&scm,&service)){ - fprintf(stderr,"%s: Error, unable to communicate with service control" - " manager.\n", + fwprintf(stderr,L"%s: Error, unable to communicate with service control" + L" manager.\n", argv[0]); print_last_error(); return 1; } - if(!ChangeServiceConfig(service, - SERVICE_NO_CHANGE, - SERVICE_NO_CHANGE, - SERVICE_NO_CHANGE, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - argv[3])){ - fprintf(stderr,"%s: Error, unable to communicate with service control" - " manager.\n", + if(!ChangeServiceConfigW(service, + SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + argv[3])){ + fwprintf(stderr,L"%s: Error, unable to communicate with service control" + L" manager.\n", argv[0]); print_last_error(); CloseServiceHandle(scm); @@ -946,154 +951,154 @@ int do_rename(int argc, char **argv){ CloseServiceHandle(service); if(remove_keys(service_name) != 0) - fprintf(stderr,"%s: Warning, old service parameter keys could not " - "be removed, continuing.\n", argv[0]); + fwprintf(stderr,L"%s: Warning, old service parameter keys could not " + L"be removed, continuing.\n", argv[0]); /* Update registry */ register_logkeys(); set_keys(argv[3], current); - printf("%s: Service %s renamed to %s.\n", + wprintf(L"%s: Service %s renamed to %s.\n", argv[0], service_name, argv[3]); return 0; } -int do_remove(int argc, char **argv){ +int do_remove(int argc, wchar_t **argv){ RegEntry *current = empty_reg_tab(); int rem_res; BOOL found; if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; found = fetch_current(current); if(found){ - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); } else { - real_service_name = _strdup(service_name); + real_service_name = _wcsdup(service_name); } if(found) free_keys(current); if(stop_service() && !wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ - fprintf(stderr,"%s: Failed to stop running service %s.\n", + fwprintf(stderr,L"%s: Failed to stop running service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!remove_service()){ - fprintf(stderr,"%s: Unable to remove service (not enough " - "privileges?)\n",argv[0]); + fwprintf(stderr,L"%s: Unable to remove service (not enough " + L"privileges?)\n",argv[0]); print_last_error(); return 1; } if((rem_res = remove_keys(service_name)) > 0){ - fprintf(stderr,"%s: Warning, service parameter keys belonged to old " - "erlsrv version.\n", argv[0]); + fwprintf(stderr,L"%s: Warning, service parameter keys belonged to old " + L"erlsrv version.\n", argv[0]); /* Backward compatibility... */ } else if(rem_res < 0) { - fprintf(stderr,"%s: Error, service parameter keys nonexistent.\n", + fwprintf(stderr,L"%s: Error, service parameter keys nonexistent.\n", argv[0]); return 1; } - printf("%s: Service %s removed from system.\n", + wprintf(L"%s: Service %s removed from system.\n", argv[0], service_name); return 0; } -BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ - char *onfail; - char *prio; - char *debugtype; +BOOL list_one(wchar_t *servicename, RegEntry *keys, BOOL longlist){ + wchar_t *onfail; + wchar_t *prio; + wchar_t *debugtype; switch(keys[OnFail].data.value){ case ON_FAIL_RESTART: - onfail = "restart"; + onfail = L"restart"; break; case ON_FAIL_RESTART_ALWAYS: - onfail = "restart_always"; + onfail = L"restart_always"; break; case ON_FAIL_REBOOT: - onfail = "reboot"; + onfail = L"reboot"; break; default: - onfail = "ignore"; + onfail = L"ignore"; } switch(keys[DebugType].data.value){ case DEBUG_TYPE_NEW: - debugtype = "new"; + debugtype = L"new"; break; case DEBUG_TYPE_REUSE: - debugtype = "reuse"; + debugtype = L"reuse"; break; case DEBUG_TYPE_CONSOLE: - debugtype = "console"; + debugtype = L"console"; break; default: - debugtype = "none"; + debugtype = L"none"; } switch(keys[Priority].data.value){ case HIGH_PRIORITY_CLASS: - prio = "high"; + prio = L"high"; break; case IDLE_PRIORITY_CLASS: - prio = "low"; + prio = L"low"; break; case REALTIME_PRIORITY_CLASS: - prio = "realtime"; + prio = L"realtime"; break; case NORMAL_PRIORITY_CLASS: - prio = "default"; + prio = L"default"; break; default: - prio = "unknown/faulty"; + prio = L"unknown/faulty"; } if(longlist){ - char *env = envdup(keys[Env].data.bytes); - char **arg = env_to_arg(env); - char **pek = arg; - printf("Service name: %s\n", + wchar_t *env = envdup(keys[Env].data.string); + wchar_t **arg = env_to_arg(env); + wchar_t **pek = arg; + wprintf(L"Service name: %s\n", servicename); - printf("StopAction: %s\n", - keys[StopAction].data.bytes); - printf("OnFail: %s\n",onfail); - printf("Machine: %s\n", + wprintf(L"StopAction: %s\n", + keys[StopAction].data.string); + wprintf(L"OnFail: %s\n",onfail); + wprintf(L"Machine: %s\n", keys[Machine].data.expand.unexpanded); - printf("WorkDir: %s\n", + wprintf(L"WorkDir: %s\n", keys[WorkDir].data.expand.unexpanded); - if(*keys[SName].data.bytes) - printf("SName: %s\n", - keys[SName].data.bytes); + if(*keys[SName].data.string) + wprintf(L"SName: %s\n", + keys[SName].data.string); else - printf("Name: %s\n", - keys[Name].data.bytes); - printf("Priority: %s\n",prio); - printf("DebugType: %s\n",debugtype); - printf("Args: %s\n", + wprintf(L"Name: %s\n", + keys[Name].data.string); + wprintf(L"Priority: %s\n",prio); + wprintf(L"DebugType: %s\n",debugtype); + wprintf(L"Args: %s\n", keys[Args].data.expand.unexpanded); - printf("InternalServiceName: %s\n", - keys[InternalServiceName].data.bytes); - printf("Comment: %s\n", - keys[Comment].data.bytes); - printf("Env:\n"); + wprintf(L"InternalServiceName: %s\n", + keys[InternalServiceName].data.string); + wprintf(L"Comment: %s\n", + keys[Comment].data.string); + wprintf(L"Env:\n"); while(*pek){ - printf("\t%s\n",*pek); + wprintf(L"\t%s\n",*pek); ++pek; } /* env is easier to free...*/ env = arg_to_env(arg); free(env); } else { - printf("%s\t%s\t%s\t%s\t%s\n", + wprintf(L"%s\t%s\t%s\t%s\t%s\n", servicename, - (*keys[Name].data.bytes) ? - keys[Name].data.bytes : - keys[SName].data.bytes, + (*keys[Name].data.string) ? + keys[Name].data.string : + keys[SName].data.string, prio, onfail, keys[Args].data.expand.unexpanded); @@ -1102,15 +1107,15 @@ BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ } -int do_list(int argc, char **argv){ +int do_list(int argc, wchar_t **argv){ if(argc < 3){ RegEntryDesc *all_keys = get_all_keys(); if(!all_keys){ - fprintf(stderr,"%s: No services found in registry.\n", + fwprintf(stderr,L"%s: No services found in registry.\n", argv[0]); return 0; } - printf("Service\t(S)Name\tPrio\tOnFail\tArgs\n"); + wprintf(L"Service\t(S)Name\tPrio\tOnFail\tArgs\n"); while(all_keys->servicename){ list_one(all_keys->servicename,all_keys->entries,FALSE); ++all_keys; @@ -1121,8 +1126,8 @@ int do_list(int argc, char **argv){ service_name = argv[2]; keys = get_keys(service_name); if(!keys){ - fprintf(stderr,"%s: Could not retrieve any " - "registered data for %s.\n",argv[0],service_name); + fwprintf(stderr,L"%s: Could not retrieve any " + L"registered data for %s.\n",argv[0],service_name); return 1; } list_one(service_name, keys, TRUE); @@ -1133,15 +1138,15 @@ int do_list(int argc, char **argv){ #define READ_CHUNK 100 #define ARGV_CHUNK 20 -char *safe_get_line(void){ +wchar_t *safe_get_line(void){ int lsize = READ_CHUNK; - char *line = malloc(READ_CHUNK); + wchar_t *line = malloc(READ_CHUNK*sizeof(wchar_t)); int pos = 0; int ch; - while((ch = getchar()) != EOF && ch != '\n'){ + while((ch = getwchar()) != EOF && ch != L'\n'){ if(pos + 1 >= lsize){ - line = realloc(line,(lsize += READ_CHUNK)); + line = realloc(line,(lsize += READ_CHUNK)*sizeof(wchar_t)); assert(line); } line[pos++] = ch; @@ -1150,22 +1155,22 @@ char *safe_get_line(void){ free(line); return NULL; } - line[pos] = '\0'; + line[pos] = L'\0'; return line; } -void read_arguments(int *pargc, char ***pargv){ +void read_arguments(int *pargc, wchar_t ***pargv){ int argc = 0; int asize = ARGV_CHUNK; - char **argv = malloc(ARGV_CHUNK*sizeof(char *)); - char *tmp; + wchar_t **argv = malloc(ARGV_CHUNK*sizeof(wchar_t *)); + wchar_t *tmp; argv[0] = (*pargv)[0]; argc = 1; while((tmp = safe_get_line()) != NULL){ if(argc + 1 >= asize){ - argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(char *)); + argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(wchar_t *)); assert(argv); } argv[argc++] = tmp; @@ -1258,40 +1263,54 @@ void release_lock(void) { -int interactive_main(int argc, char **argv){ - char *action = argv[1]; +int interactive_main(int argc, wchar_t **argv){ + wchar_t *action = argv[1]; int res; - + + _setmode(_fileno(stdin), _O_U8TEXT); /* set stdin to UTF8 */ + _setmode(_fileno(stdout), _O_U8TEXT); /* set stdout to UTF8 */ + _setmode(_fileno(stderr), _O_U8TEXT); /* set stderr to UTF8 */ + if (take_lock() != 0) { - fprintf(stderr,"%s: unable to acquire global lock (%s).\n",argv[0], + fwprintf(stderr,L"%s: unable to acquire global lock (%s).\n",argv[0], ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE); return 1; } - if(!_stricmp(action,"readargs")){ + if(!_wcsicmp(action,L"readargs")){ read_arguments(&argc,&argv); action = argv[1]; } - if(!_stricmp(action,"set") || !_stricmp(action,"add")) + +#ifdef HARDDEBUG + {int i; + for(i=0; i < argc; i++) { + fwprintf(stderr, L"%s ", argv[i]); + } + fwprintf(stderr, L"\n"); + } +#endif + + if(!_wcsicmp(action,L"set") || !_wcsicmp(action,L"add")) res = do_add_or_set(argc,argv); - else if(!_stricmp(action,"rename")) + else if(!_wcsicmp(action,L"rename")) res = do_rename(argc,argv); - else if(!_stricmp(action,"remove")) + else if(!_wcsicmp(action,L"remove")) res = do_remove(argc,argv); - else if(!_stricmp(action,"list")) + else if(!_wcsicmp(action,L"list")) res = do_list(argc,argv); - else if(!_stricmp(action,"start") || - !_stricmp(action,"start_disabled") || - !_stricmp(action,"stop") || - !_stricmp(action,"enable") || - !_stricmp(action,"disable")) + else if(!_wcsicmp(action,L"start") || + !_wcsicmp(action,L"start_disabled") || + !_wcsicmp(action,L"stop") || + !_wcsicmp(action,L"enable") || + !_wcsicmp(action,L"disable")) res = do_manage(argc,argv); - else if(_stricmp(action,"?") && - _stricmp(action,"/?") && - _stricmp(action,"-?") && - *action != 'h' && - *action != 'H') { - fprintf(stderr,"%s: action %s not implemented.\n",argv[0],action); + else if(_wcsicmp(action,L"?") && + _wcsicmp(action,L"/?") && + _wcsicmp(action,L"-?") && + *action != L'h' && + *action != L'H') { + fwprintf(stderr,L"%s: action %s not implemented.\n",argv[0],action); do_usage(argv[0]); res = 1; } else { diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.h b/erts/etc/win32/erlsrv/erlsrv_interactive.h index 23e69e508d..bc6e55fdef 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.h +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.h @@ -21,6 +21,6 @@ #define ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE "{468d6954-e355-415f-968f-d257cb0feef4}" -int interactive_main(int argc, char **argv); +int interactive_main(int argc, wchar_t **argv); #endif /* _ERLSRV_INTERACTIVE_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_main.c b/erts/etc/win32/erlsrv/erlsrv_main.c index 920a4a1827..6d8e208fc8 100644 --- a/erts/etc/win32/erlsrv/erlsrv_main.c +++ b/erts/etc/win32/erlsrv/erlsrv_main.c @@ -25,7 +25,7 @@ #include "erlsrv_interactive.h" #include "erlsrv_service.h" -int main(int argc, char **argv){ +int wmain(int argc, wchar_t **argv){ if(argc > 1) return interactive_main(argc,argv); else diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.c b/erts/etc/win32/erlsrv/erlsrv_registry.c index c1aa9f2b67..ad50da89a4 100644 --- a/erts/etc/win32/erlsrv/erlsrv_registry.c +++ b/erts/etc/win32/erlsrv/erlsrv_registry.c @@ -24,38 +24,37 @@ #include "erlsrv_global.h" #include "erlsrv_registry.h" -#define LOG_TYPE "System" -#define LOG_ROOT \ -"SYSTEM\\CurrentControlSet\\Services\\EventLog\\" LOG_TYPE "\\" +#define LOG_TYPE L"System" +#define LOG_ROOT L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\" LOG_TYPE L"\\" #define LOG_APP_KEY APP_NAME #define BASE_KEY HKEY_LOCAL_MACHINE #define PRODUCT_NAME APP_NAME -#define OLD_PRODUCT_VERSION "1.0" -#define PRODUCT_VERSION "1.1" -#define PROG_KEY "SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME "\\" PRODUCT_VERSION -#define OLD_PROG_KEY "SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME "\\" OLD_PRODUCT_VERSION +#define OLD_PRODUCT_VERSION L"1.0" +#define PRODUCT_VERSION L"1.1" +#define PROG_KEY L"SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME L"\\" PRODUCT_VERSION +#define OLD_PROG_KEY L"SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME L"\\" OLD_PRODUCT_VERSION #define MAX_KEY_LEN MAX_PATH -static const char * const noString = "\0"; +static const wchar_t * const noString = L"\0"; #define MAX_MANDATORY_REG_ENTRY 10 /* InternalServiceName == reg_entries[10] */ static RegEntry reg_entries[] = { - {"StopAction",REG_SZ,NULL}, - {"OnFail",REG_DWORD,NULL}, - {"Machine",REG_EXPAND_SZ,NULL}, - {"Env", REG_MULTI_SZ,NULL}, - {"WorkDir", REG_EXPAND_SZ,NULL}, - {"Priority",REG_DWORD,NULL}, - {"SName",REG_SZ,NULL}, - {"Name",REG_SZ,NULL}, - {"Args",REG_EXPAND_SZ,NULL}, - {"DebugType",REG_DWORD,NULL}, - {"InternalServiceName",REG_SZ,NULL}, + {L"StopAction",REG_SZ,NULL}, + {L"OnFail",REG_DWORD,NULL}, + {L"Machine",REG_EXPAND_SZ,NULL}, + {L"Env", REG_MULTI_SZ,NULL}, + {L"WorkDir", REG_EXPAND_SZ,NULL}, + {L"Priority",REG_DWORD,NULL}, + {L"SName",REG_SZ,NULL}, + {L"Name",REG_SZ,NULL}, + {L"Args",REG_EXPAND_SZ,NULL}, + {L"DebugType",REG_DWORD,NULL}, + {L"InternalServiceName",REG_SZ,NULL}, /* Non mandatory follows */ - {"Comment",REG_SZ,NULL} + {L"Comment",REG_SZ,NULL} }; @@ -73,8 +72,8 @@ void free_keys(RegEntry *keys){ for(i=0;i MAX_KEY_LEN) + if(wcslen(PROG_KEY) + wcslen(servicename) + 2 > MAX_KEY_LEN) goto error; - sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); + swprintf(key_to_open,MAX_KEY_LEN,L"%s\\%s",PROG_KEY,servicename); - if(RegOpenKeyEx(BASE_KEY, - key_to_open, - 0, - KEY_QUERY_VALUE, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, + key_to_open, + 0, + KEY_QUERY_VALUE, + &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; @@ -128,12 +127,12 @@ RegEntry *get_keys(char *servicename){ for(i=0;i tmpbuflen){ - tmpbuf=realloc(tmpbuf,tmpbuflen=ret); + tmpbuf=realloc(tmpbuf,(tmpbuflen=ret)*sizeof(wchar_t)); } else { - copy = strdup(tmpbuf); + copy = wcsdup(tmpbuf); free(tmpbuf); break; } } - res[i].data.expand.unexpanded = strdup(val_data); + res[i].data.expand.unexpanded = wcsdup(val_data); } case REG_MULTI_SZ: case REG_SZ: if(!copy){ if(!val_datalen || - ((val_datalen == 1 && val_data[0] == '\0') || - (val_datalen == 2 && val_data[0] == '\0' && - val_data[1] == '\0'))){ - copy = (char *) noString; + ((val_datalen == 2 && val_data[0] == L'\0') || + (val_datalen == 4 && val_data[0] == L'\0' && + val_data[1] == L'\0'))){ + copy = (wchar_t *) noString; } else { - copy = malloc(val_datalen); - memcpy(copy,val_data,val_datalen); + copy = malloc(val_datalen); /* val_datalen in bytes */ + memcpy(copy,val_data,val_datalen); } } - res[i].data.bytes = copy; + res[i].data.string = copy; break; case REG_DWORD: memcpy(&res[i].data.value,val_data,sizeof(DWORD)); @@ -222,32 +221,32 @@ error: return NULL; } -int set_keys(char *servicename, RegEntry *keys){ +int set_keys(wchar_t *servicename, RegEntry *keys){ HKEY prog_key; int key_opened = 0; int i; - char key_to_open[MAX_KEY_LEN]; + wchar_t key_to_open[MAX_KEY_LEN]; DWORD disposition; - if(strlen(PROG_KEY) + strlen(servicename) + 2 > MAX_KEY_LEN) + if(wcslen(PROG_KEY) + wcslen(servicename) + 2 > MAX_KEY_LEN) goto error; - sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); + swprintf(key_to_open,MAX_KEY_LEN,L"%s\\%s",PROG_KEY,servicename); - if(RegOpenKeyEx(BASE_KEY, - key_to_open, - 0, - KEY_SET_VALUE, - &prog_key) != ERROR_SUCCESS){ - if(RegCreateKeyEx(BASE_KEY, - key_to_open, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, - NULL, - &prog_key, - &disposition) != ERROR_SUCCESS) - goto error; + if(RegOpenKeyExW(BASE_KEY, + key_to_open, + 0, + KEY_SET_VALUE, + &prog_key) != ERROR_SUCCESS){ + if(RegCreateKeyExW(BASE_KEY, + key_to_open, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, + NULL, + &prog_key, + &disposition) != ERROR_SUCCESS) + goto error; } key_opened = 1; @@ -258,19 +257,19 @@ int set_keys(char *servicename, RegEntry *keys){ int j; switch(keys[i].type){ case REG_SZ: - ptr = keys[i].data.bytes; - siz = strlen(ptr)+1; + ptr = keys[i].data.string; + siz = (wcslen(ptr)+1)*sizeof(wchar_t); break; case REG_EXPAND_SZ: ptr = keys[i].data.expand.unexpanded; - siz = strlen(ptr)+1; + siz = (wcslen(ptr)+1)*sizeof(wchar_t); break; case REG_MULTI_SZ: - ptr = keys[i].data.bytes; - for(j=0;!(((char *)ptr)[j] == '\0' && - ((char *)ptr)[j+1] == '\0');++j) + ptr = keys[i].data.string; + for(j=0;!(((wchar_t *)ptr)[j] == L'\0' && + ((wchar_t *)ptr)[j+1] == L'\0');++j) ; - siz=(DWORD)j+2; + siz=(j+2)*sizeof(wchar_t); break; case REG_DWORD: ptr = &keys[i].data.value; @@ -280,15 +279,15 @@ int set_keys(char *servicename, RegEntry *keys){ goto error; } #ifdef HARDDEBUG - fprintf(stderr,"%s %s:%d\n",keys[i].name, - (keys[i].type == REG_DWORD) ? "(dword)" : ptr,siz); + fprintf(stderr,"%S %S:%d\n",keys[i].name, + (keys[i].type == REG_DWORD) ? L"(dword)" : ptr,siz); #endif - if(RegSetValueEx(prog_key, - keys[i].name, - 0, - keys[i].type, - ptr, - siz) != ERROR_SUCCESS) + if(RegSetValueExW(prog_key, + keys[i].name, + 0, + keys[i].type, + ptr, + siz) != ERROR_SUCCESS) goto error; } RegCloseKey(prog_key); @@ -299,15 +298,15 @@ error: return 1; } -static int do_remove_keys(char *servicename, const char *prog_key_name){ +static int do_remove_keys(wchar_t *servicename, const wchar_t *prog_key_name){ HKEY prog_key; - if(RegOpenKeyEx(BASE_KEY, - prog_key_name, - 0, - KEY_ALL_ACCESS, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, + prog_key_name, + 0, + KEY_ALL_ACCESS, + &prog_key) != ERROR_SUCCESS) return -1; - if(RegDeleteKey(prog_key,servicename) != ERROR_SUCCESS){ + if(RegDeleteKeyW(prog_key,servicename) != ERROR_SUCCESS){ RegCloseKey(prog_key); return -1; } @@ -315,7 +314,7 @@ static int do_remove_keys(char *servicename, const char *prog_key_name){ return 0; } -int remove_keys(char *servicename){ +int remove_keys(wchar_t *servicename){ int ret; if((ret = do_remove_keys(servicename, PROG_KEY)) < 0){ @@ -335,33 +334,33 @@ RegEntryDesc *get_all_keys(void){ HKEY prog_key; int key_opened = 0; DWORD enum_index; - char name[MAX_KEY_LEN]; + wchar_t name[MAX_KEY_LEN]; DWORD namelen; - char class[MAX_KEY_LEN]; + wchar_t class[MAX_KEY_LEN]; DWORD classlen; FILETIME ft; res[ndx].servicename = NULL; - if(RegOpenKeyEx(BASE_KEY, PROG_KEY, 0, - KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, PROG_KEY, 0, + KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, + &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; for(enum_index = 0, namelen = MAX_KEY_LEN, classlen = MAX_KEY_LEN; - ERROR_SUCCESS == RegEnumKeyEx(prog_key, - enum_index, - name, - &namelen, - NULL, - class, - &classlen, - &ft); + ERROR_SUCCESS == RegEnumKeyExW(prog_key, + enum_index, + name, + &namelen, + NULL, + class, + &classlen, + &ft); ++enum_index, namelen = MAX_KEY_LEN, classlen = MAX_KEY_LEN){ if(ndx >= res_siz - 1) res = realloc(res, (res_siz += 10)*sizeof(RegEntryDesc)); if(!(res[ndx].entries = get_keys(name))) - goto error; - res[ndx].servicename = strdup(name); + goto error; + res[ndx].servicename = wcsdup(name); res[++ndx].servicename = NULL; } RegCloseKey(prog_key); @@ -380,24 +379,24 @@ int register_logkeys(void){ EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; DWORD catcount=1; - char filename[2048]; + wchar_t filename[2048]; DWORD fnsiz=2048; - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - LOG_ROOT LOG_APP_KEY, 0, - NULL, REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, NULL, - &key, &disposition) != ERROR_SUCCESS) + if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, + LOG_ROOT LOG_APP_KEY, 0, + NULL, REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, NULL, + &key, &disposition) != ERROR_SUCCESS) return -1; - if(!GetModuleFileName(NULL, filename, fnsiz)) + if(!GetModuleFileNameW(NULL, filename, fnsiz)) return -1; - if(RegSetValueEx(key, "EventMessageFile", - 0, REG_EXPAND_SZ, (LPBYTE) filename, - strlen(filename)+1) != ERROR_SUCCESS) + if(RegSetValueExW(key, L"EventMessageFile", + 0, REG_EXPAND_SZ, (LPBYTE) filename, + (wcslen(filename)+1)*sizeof(wchar_t)) != ERROR_SUCCESS) return -1; - if(RegSetValueEx(key, "TypesSupported", - 0, REG_DWORD, (LPBYTE) &types, - sizeof(DWORD)) != ERROR_SUCCESS) + if(RegSetValueExW(key, L"TypesSupported", + 0, REG_DWORD, (LPBYTE) &types, + sizeof(DWORD)) != ERROR_SUCCESS) return -1; return 0; } diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.h b/erts/etc/win32/erlsrv/erlsrv_registry.h index fbccc5416a..4be10e9ff2 100644 --- a/erts/etc/win32/erlsrv/erlsrv_registry.h +++ b/erts/etc/win32/erlsrv/erlsrv_registry.h @@ -20,20 +20,20 @@ #define _ERLSRV_REGISTRY_H typedef struct _reg_entry { - char *name; + wchar_t *name; DWORD type; union { - char *bytes; + wchar_t *string; DWORD value; struct { - char *bytes; - char *unexpanded; + wchar_t *string; + wchar_t *unexpanded; } expand; } data; } RegEntry; typedef struct _reg_entry_desc { - char *servicename; + wchar_t *servicename; RegEntry *entries; } RegEntryDesc; @@ -67,10 +67,10 @@ extern int num_reg_entries; RegEntry *empty_reg_tab(void); void free_keys(RegEntry *keys); void free_all_keys(RegEntryDesc *descs); -RegEntry *get_keys(char *servicename); -int set_keys(char *servicename, RegEntry *keys); +RegEntry *get_keys(wchar_t *servicename); +int set_keys(wchar_t *servicename, RegEntry *keys); RegEntryDesc *get_all_keys(void); -int remove_keys(char *servicename); +int remove_keys(wchar_t *servicename); int register_logkeys(void); #endif /* _ERLSRV_REGISTRY_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_service.c b/erts/etc/win32/erlsrv/erlsrv_service.c index 58738ee445..2e56c579a2 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.c +++ b/erts/etc/win32/erlsrv/erlsrv_service.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2012. All Rights Reserved. + * Copyright Ericsson AB 1998-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -99,8 +99,8 @@ static BOOL reset_current(){ } static VOID WINAPI handler(DWORD control){ - char buffer[1024]; - sprintf(buffer,"handler called with control = %d.",(int) control); + wchar_t buffer[1024]; + swprintf(buffer,1024,L"handler called with control = %d.",(int) control); log_debug(buffer); switch(control){ case SERVICE_CONTROL_STOP: @@ -119,7 +119,7 @@ typedef struct _server_info { RegEntry *keys; PROCESS_INFORMATION info; HANDLE erl_stdin; - char *event_name; + wchar_t *event_name; } ServerInfo; @@ -138,7 +138,7 @@ static BOOL reset_acl(SaveAclStruct *save_acl){ return FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ - log_warning("Failed to open access token."); + log_warning(L"Failed to open access token."); return FALSE; } save_acl->initialized = FALSE; @@ -146,7 +146,7 @@ static BOOL reset_acl(SaveAclStruct *save_acl){ TokenDefaultDacl, save_acl->defdacl, sizeof(TOKEN_DEFAULT_DACL))){ - log_warning("Failed to get default ACL from token."); + log_warning(L"Failed to get default ACL from token."); CloseHandle(tokenh); LocalFree(save_acl->defdacl); LocalFree(save_acl->newacl); @@ -177,7 +177,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ save_acl->initialized = FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ - log_warning("Failed to open access token."); + log_warning(L"Failed to open access token."); return FALSE; } save_acl->defdacl = &dummy; @@ -188,7 +188,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ sizeof(TOKEN_DEFAULT_DACL), &required); if(required == 0){ - log_warning("Failed to get any ACL info from token."); + log_warning(L"Failed to get any ACL info from token."); CloseHandle(tokenh); return FALSE; } @@ -200,7 +200,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ &required)){ #ifdef HARDDEBUG { - char *mes; + wchar_t *mes; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, @@ -213,7 +213,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ LocalFree(mes); } #endif - log_warning("Failed to get default ACL from token."); + log_warning(L"Failed to get default ACL from token."); CloseHandle(tokenh); return FALSE; } @@ -221,7 +221,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ oldacl = save_acl->defdacl->DefaultDacl; if(!GetAclInformation(oldacl, &si, sizeof(si), AclSizeInformation)){ - log_warning("Failed to get size information for ACL"); + log_warning(L"Failed to get size information for ACL"); CloseHandle(tokenh); return FALSE; } @@ -237,7 +237,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ 0, 0, &extra_sid)){ - log_warning("Failed to initialize administrator SID."); + log_warning(L"Failed to initialize administrator SID."); CloseHandle(tokenh); return FALSE; } @@ -248,7 +248,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ newacl = LocalAlloc(LPTR,newsize); if(!InitializeAcl(newacl, newsize, ACL_REVISION)){ - log_warning("Failed to initialize new ACL."); + log_warning(L"Failed to initialize new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -258,7 +258,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ for(i=0;i<((int)si.AceCount);++i){ ACE_HEADER *ace_header; if (!GetAce (oldacl, i, &ace_header)){ - log_warning("Failed to get ACE from old ACL."); + log_warning(L"Failed to get ACE from old ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -266,7 +266,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ } if(!AddAce(newacl,ACL_REVISION,0xffffffff,ace_header, ace_header->AceSize)){ - log_warning("Failed to set ACE in new ACL."); + log_warning(L"Failed to set ACE in new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -277,7 +277,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ ACL_REVISION2, PROCESS_ALL_ACCESS, extra_sid)){ - log_warning("Failed to add system ACE to new ACL."); + log_warning(L"Failed to add system ACE to new ACL."); LocalFree(newacl); FreeSid(extra_sid); return FALSE; @@ -288,7 +288,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ TokenDefaultDacl, &newdacl, sizeof(newdacl))){ - log_warning("Failed to set token information"); + log_warning(L"Failed to set token information"); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -302,18 +302,18 @@ static BOOL new_acl(SaveAclStruct *save_acl){ return TRUE; } -static char **find_arg(char **arg, char *str){ - char *tmp; +static wchar_t **find_arg(wchar_t **arg, wchar_t *str){ + wchar_t *tmp; int len; - str = strdup(str); - if((tmp = strchr(str,'=')) == NULL) + str = wcsdup(str); + if((tmp = wcschr(str,L'=')) == NULL) goto fail; tmp++; - *tmp = '\0'; + *tmp = L'\0'; len = tmp - str; while(*arg != NULL){ - if(!_strnicmp(*arg,str,len)){ + if(!_wcsnicmp(*arg,str,len)){ free(str); return arg; } @@ -324,11 +324,11 @@ fail: return NULL; } -static char **merge_environment(char *current, char *add){ - char **c_arg = env_to_arg(envdup(current)); - char **a_arg = env_to_arg(envdup(add)); - char **new; - char **tmp; +static wchar_t **merge_environment(wchar_t *current, wchar_t *add){ + wchar_t **c_arg = env_to_arg(envdup(current)); + wchar_t **a_arg = env_to_arg(envdup(add)); + wchar_t **new; + wchar_t **tmp; int i,j; for(i=0;c_arg[i] != NULL;++i) @@ -336,19 +336,19 @@ static char **merge_environment(char *current, char *add){ for(j=0;a_arg[j] != NULL;++j) ; - new = malloc(sizeof(char *)*(i + j + 3)); + new = malloc(sizeof(wchar_t *)*(i + j + 3)); for(i = 0; c_arg[i] != NULL; ++i) - new[i] = strdup(c_arg[i]); + new[i] = wcsdup(c_arg[i]); new[i] = NULL; for(j = 0; a_arg[j] != NULL; ++j){ if((tmp = find_arg(new,a_arg[j])) != NULL){ free(*tmp); - *tmp = strdup(a_arg[j]); + *tmp = wcsdup(a_arg[j]); } else { - new[i++] = strdup(a_arg[j]); + new[i++] = wcsdup(a_arg[j]); new[i] = NULL; } } @@ -358,12 +358,12 @@ static char **merge_environment(char *current, char *add){ } -static char *get_next_debug_file(char *prefix){ - char *buffer = malloc(strlen(prefix)+12); +static wchar_t *get_next_debug_file(wchar_t *prefix){ + wchar_t *buffer = malloc((wcslen(prefix)+12)*sizeof(wchar_t)); int i; for(i=1;i<100;++i){ - sprintf(buffer,"%s.%d",prefix,i); - if(GetFileAttributes(buffer) == 0xFFFFFFFF) + swprintf(buffer,wcslen(prefix)+12,L"%s.%d",prefix,i); + if(GetFileAttributesW(buffer) == 0xFFFFFFFF) return buffer; } return NULL; @@ -372,56 +372,66 @@ static char *get_next_debug_file(char *prefix){ static BOOL start_a_service(ServerInfo *srvi){ - STARTUPINFO start; - char execbuff[MAX_PATH*4]; /* FIXME: Can get overflow! */ - char namebuff[MAX_PATH]; - char errbuff[MAX_PATH*4]; /* hmmm.... */ + STARTUPINFOW start; + wchar_t namebuff[MAX_PATH]; + wchar_t *execbuff; + wchar_t *errbuff; HANDLE write_pipe = NULL, read_pipe = NULL; SECURITY_ATTRIBUTES pipe_security; SECURITY_ATTRIBUTES attr; HANDLE nul; SaveAclStruct save_acl; - char *my_environ; + wchar_t *my_environ; BOOL console_allocated = FALSE; + int bufflen=0; - if(!(*(srvi->keys[Env].data.bytes))){ + if(!(*(srvi->keys[Env].data.string))){ my_environ = NULL; } else { - char *tmp; - char **merged = merge_environment((tmp = GetEnvironmentStrings()), - srvi->keys[Env].data.bytes); - FreeEnvironmentStrings(tmp); + wchar_t *tmp; + wchar_t **merged = merge_environment((tmp = GetEnvironmentStringsW()), + srvi->keys[Env].data.string); + FreeEnvironmentStringsW(tmp); my_environ = arg_to_env(merged); } - if(!*(srvi->keys[Machine].data.bytes) || - (!*(srvi->keys[SName].data.bytes) && - !*(srvi->keys[Name].data.bytes))){ - log_error("Not enough parameters for erlang service."); + if(!*(srvi->keys[Machine].data.string) || + (!*(srvi->keys[SName].data.string) && + !*(srvi->keys[Name].data.string))){ + log_error(L"Not enough parameters for erlang service."); if(my_environ) free(my_environ); return FALSE; } - if(*(srvi->keys[SName].data.bytes)) - sprintf(namebuff,"-nohup -sname %s",srvi->keys[SName].data.bytes); + if(*(srvi->keys[SName].data.string)) + swprintf(namebuff,MAX_PATH,L"-nohup -sname %s",srvi->keys[SName].data.string); else - sprintf(namebuff,"-nohup -name %s",srvi->keys[Name].data.bytes); + swprintf(namebuff,MAX_PATH,L"-nohup -name %s",srvi->keys[Name].data.string); if(srvi->keys[DebugType].data.value == DEBUG_TYPE_CONSOLE) - strcat(namebuff," -keep_window"); + wcscat(namebuff,L" -keep_window"); + + bufflen = MAX_PATH + + wcslen(srvi->keys[Machine].data.string) + + wcslen(srvi->event_name) + + wcslen(namebuff) + + wcslen(srvi->keys[Args].data.string); + + execbuff = malloc(bufflen * sizeof(wchar_t)); + errbuff = malloc((MAX_PATH + bufflen) * sizeof(wchar_t)); if (srvi->event_name != NULL) { - sprintf(execbuff,"\"%s\" -service_event %s %s %s", - srvi->keys[Machine].data.bytes, - srvi->event_name, - namebuff, - srvi->keys[Args].data.bytes); + swprintf(execbuff,bufflen,L"\"%s\" -service_event %s %s %s", + srvi->keys[Machine].data.string, + srvi->event_name, + namebuff, + srvi->keys[Args].data.string); } else { - sprintf(execbuff,"\"%s\" %s %s", - srvi->keys[Machine].data.bytes, - namebuff, - srvi->keys[Args].data.bytes); + swprintf(execbuff,bufflen,L"\"%s\" %s %s", + srvi->keys[Machine].data.string, + namebuff, + srvi->keys[Args].data.string); } memset (&start, 0, sizeof (start)); @@ -435,45 +445,49 @@ static BOOL start_a_service(ServerInfo *srvi){ if(console_allocated = AllocConsole()) SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),coord); else - log_warning("Unable to allocate debugging console!"); - } else if(*(srvi->keys[StopAction].data.bytes) || + log_warning(L"Unable to allocate debugging console!"); + } else if(*(srvi->keys[StopAction].data.string) || srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG){ pipe_security.nLength = sizeof(pipe_security); pipe_security.lpSecurityDescriptor = NULL; pipe_security.bInheritHandle = TRUE; if(!CreatePipe(&read_pipe,&write_pipe,&pipe_security,0)){ - log_error("Could not create pipe for erlang service."); + log_error(L"Could not create pipe for erlang service."); if(my_environ) - free(my_environ); + free(my_environ); + free(execbuff); + free(errbuff); return FALSE; } if(srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG){ - char *filename; - if(*(srvi->keys[WorkDir].data.bytes)){ - filename = malloc(strlen(srvi->keys[WorkDir].data.bytes) + 1 + - strlen(service_name)+strlen(".debug")+1); - sprintf(filename,"%s\\%s.debug", - srvi->keys[WorkDir].data.bytes, - service_name); + wchar_t *filename; + if(*(srvi->keys[WorkDir].data.string)){ + int filenamelen = (wcslen(srvi->keys[WorkDir].data.string) + 1 + + wcslen(service_name)+wcslen(L".debug")+1); + filename = malloc(filenamelen*sizeof(wchar_t)); + swprintf(filename,filenamelen,L"%s\\%s.debug", + srvi->keys[WorkDir].data.string, + service_name); } else { - filename = malloc(strlen(service_name)+strlen(".debug")+1); - sprintf(filename,"%s.debug",service_name); + int filenamelen = wcslen(service_name)+wcslen(L".debug")+1; + filename = malloc(filenamelen*sizeof(wchar_t)); + swprintf(filename,filenamelen,L"%s.debug",service_name); } log_debug(filename); if(srvi->keys[DebugType].data.value == DEBUG_TYPE_NEW){ - char *tmpfn = get_next_debug_file(filename); + wchar_t *tmpfn = get_next_debug_file(filename); if(tmpfn){ free(filename); filename = tmpfn; } else { - log_warning("Number of debug files exceeds system defined " - "limit, reverting to DebugType: reuse. "); + log_warning(L"Number of debug files exceeds system defined " + L"limit, reverting to DebugType: reuse. "); } } - nul = CreateFile(filename, + nul = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &pipe_security, @@ -492,9 +506,9 @@ static BOOL start_a_service(ServerInfo *srvi){ } if(nul == NULL){ log_error((srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG) - ? "Could not create debug file. " - "(Working directory not valid?)" - : "Cold not open NUL!"); + ? L"Could not create debug file. " + L"(Working directory not valid?)" + : L"Cold not open NUL!"); start.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); start.hStdError = GetStdHandle(STD_ERROR_HANDLE); } @@ -510,23 +524,24 @@ static BOOL start_a_service(ServerInfo *srvi){ new_acl(&save_acl); - if(!CreateProcess(NULL, - execbuff, - &attr, - NULL, - (read_pipe != NULL), - CREATE_DEFAULT_ERROR_MODE | - (srvi->keys[Priority].data.value), - my_environ, - (*(srvi->keys[WorkDir].data.bytes)) ? - srvi->keys[WorkDir].data.bytes : NULL, - &start, - &(srvi->info))){ - sprintf(errbuff,"Could not start erlang service " - "with commandline \"%s\".", - service_name, - execbuff - ); + if(!CreateProcessW(NULL, + execbuff, + &attr, + NULL, + (read_pipe != NULL), + CREATE_UNICODE_ENVIRONMENT | + CREATE_DEFAULT_ERROR_MODE | + (srvi->keys[Priority].data.value), + my_environ, + (*(srvi->keys[WorkDir].data.string)) ? + srvi->keys[WorkDir].data.string : NULL, + &start, + &(srvi->info))){ + swprintf(errbuff,bufflen+MAX_PATH,L"Could not start erlang service \"%s\"" + L"with commandline [%s].", + service_name, + execbuff + ); log_error(errbuff); if(read_pipe != NULL){ CloseHandle(read_pipe); @@ -539,14 +554,16 @@ static BOOL start_a_service(ServerInfo *srvi){ reset_acl(&save_acl); if(my_environ) free(my_environ); + free(execbuff); + free(errbuff); return FALSE; } if(console_allocated) FreeConsole(); #ifdef HARDDEBUG - sprintf(errbuff, - "Started %s with the following commandline: " - "%s",service_name,execbuff); + swprintf(errbuff,bufflen+MAX_PATH, + L"Started %s with the following commandline: %s", + service_name,execbuff); log_debug(errbuff); #endif if(read_pipe != NULL){ @@ -559,19 +576,21 @@ static BOOL start_a_service(ServerInfo *srvi){ reset_acl(&save_acl); if(my_environ) free(my_environ); + free(execbuff); + free(errbuff); return TRUE; } -static HANDLE create_erlang_event(char *event_name) +static HANDLE create_erlang_event(wchar_t *event_name) { HANDLE e; - if ((e = OpenEvent(EVENT_ALL_ACCESS,FALSE,event_name)) == NULL) { - if ((e = CreateEvent(NULL, TRUE, FALSE, event_name)) == NULL) { - log_warning("Could not create or access erlang termination event"); + if ((e = OpenEventW(EVENT_ALL_ACCESS,FALSE,event_name)) == NULL) { + if ((e = CreateEventW(NULL, TRUE, FALSE, event_name)) == NULL) { + log_warning(L"Could not create or access erlang termination event"); } } else { if (!ResetEvent(e)) { - log_warning("Could not reset erlang termination event."); + log_warning(L"Could not reset erlang termination event."); } } return e; @@ -580,17 +599,18 @@ static HANDLE create_erlang_event(char *event_name) static BOOL stop_erlang(ServerInfo *srvi, int waithint, int *checkpoint){ DWORD written = 0; - char *action = srvi->keys[StopAction].data.bytes; - DWORD towrite = strlen(action)+1; - char *toerl; + wchar_t *wc_action = srvi->keys[StopAction].data.string; + DWORD towrite = wcslen(wc_action); + char *toerl; DWORD exitcode; int i; int kill; if(towrite > 2 && srvi->erl_stdin != NULL){ - toerl = malloc(towrite+1); - strcpy(toerl,action); - strcat(toerl,"\n"); + towrite = WideCharToMultiByte(CP_UTF8, 0, wc_action, -1, NULL, 0, NULL, NULL); + toerl = malloc((1+towrite)*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wc_action, -1, toerl, towrite, NULL, NULL); + strcat(toerl, "\n"); WriteFile(srvi->erl_stdin, toerl, towrite, &written,0); free(toerl); /* Give it 45 seconds to terminate */ @@ -605,9 +625,9 @@ static BOOL stop_erlang(ServerInfo *srvi, int waithint, ++(*checkpoint); set_stop_pending(waithint,*checkpoint); } - log_warning("StopAction did not terminate erlang. Trying forced kill."); + log_warning(L"StopAction did not terminate erlang. Trying forced kill."); } - log_debug("Terminating erlang..."); + log_debug(L"Terminating erlang..."); kill = 1; if(eventKillErlang != NULL && SetEvent(eventKillErlang) != 0){ for(i=0;i<10;++i){ @@ -621,25 +641,25 @@ static BOOL stop_erlang(ServerInfo *srvi, int waithint, } else { #ifdef HARDDEBUG { - char *mes; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &mes, - 0, - NULL ); + wchar_t *mes; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &mes, + 0, + NULL ); log_info(mes); LocalFree(mes); } #endif - log_debug("Could not send control event to Erlang process"); + log_debug(L"Could not send control event to Erlang process"); } if(kill){ - log_warning("Using TerminateProcess to kill erlang."); + log_warning(L"Using TerminateProcess to kill erlang."); if(!TerminateProcess(srvi->info.hProcess,NO_ERROR)) - log_error("TerminateProcess failed"); + log_error(L"TerminateProcess failed"); } GetExitCodeProcess(srvi->info.hProcess,&exitcode); CloseHandle(srvi->info.hProcess); @@ -668,14 +688,14 @@ static BOOL enable_privilege(void) { static BOOL pull_service_name(void){ SC_HANDLE scm; DWORD sz = 1024; - static char service_name_buff[1024]; + static wchar_t service_name_buff[1024]; if((scm = OpenSCManager(NULL, NULL, GENERIC_READ)) == NULL){ return FALSE; } - if(!GetServiceDisplayName(scm,real_service_name,service_name_buff,&sz)) + if(!GetServiceDisplayNameW(scm,real_service_name,service_name_buff,&sz)) return FALSE; CloseServiceHandle(scm); service_name = service_name_buff; @@ -683,7 +703,7 @@ static BOOL pull_service_name(void){ } -static VOID WINAPI service_main_loop(DWORD argc, char **argv){ +static VOID WINAPI service_main_loop(DWORD argc, wchar_t **argv){ int waithint = 30000; int checkpoint = 1; RegEntry *keys; @@ -692,36 +712,35 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ HANDLE harr[2]; FILETIME creationt,exitt,kernelt,usert; LONGLONG creationl,exitl,diffl; - char event_name[MAX_PATH] = "ErlSrv_"; - char executable_name[MAX_PATH]; + wchar_t event_name[MAX_PATH] = L"ErlSrv_"; + wchar_t executable_name[MAX_PATH]; #ifdef DEBUG - char errorbuff[2048]; /* FIXME... */ + wchar_t errorbuff[2048]; /* FIXME... */ #endif int success_wait = NO_SUCCESS_WAIT; real_service_name = argv[0]; if(!pull_service_name()){ - log_error("Could not get Display name of erlang service."); + log_error(L"Could not get Display name of erlang service."); set_stopped(ERROR_CANTREAD); return; } - SetEnvironmentVariable((LPCTSTR) SERVICE_ENV, (LPCTSTR) service_name); + SetEnvironmentVariableW(SERVICE_ENV, service_name); - strncat(event_name, service_name, MAX_PATH - strlen(event_name)); - event_name[MAX_PATH - 1] = '\0'; + wcsncat(event_name, service_name, MAX_PATH - wcslen(event_name)); + event_name[MAX_PATH - 1] = L'\0'; - if(!GetModuleFileName(NULL, executable_name, MAX_PATH)){ - log_error("Unable to retrieve module file name, " EXECUTABLE_ENV - " will not be set."); + if(!GetModuleFileNameW(NULL, executable_name, MAX_PATH)){ + log_error(L"Unable to retrieve module file name, " EXECUTABLE_ENV + L" will not be set."); } else { - char quoted_exe_name[MAX_PATH+4]; - sprintf(quoted_exe_name, "\"%s\"", executable_name); - SetEnvironmentVariable((LPCTSTR) EXECUTABLE_ENV, - (LPCTSTR) quoted_exe_name); + wchar_t quoted_exe_name[MAX_PATH+4]; + swprintf(quoted_exe_name, MAX_PATH+4, L"\"%s\"", executable_name); + SetEnvironmentVariableW(EXECUTABLE_ENV, quoted_exe_name); } - log_debug("Here we go, service_main_loop..."); + log_debug(L"Here we go, service_main_loop..."); currentState = SERVICE_START_PENDING; InitializeCriticalSection(&crit); eventStop = CreateEvent(NULL,FALSE,FALSE,NULL); @@ -730,13 +749,13 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } else { srvi.event_name = NULL; } - statusHandle = RegisterServiceCtrlHandler(real_service_name, &handler); + statusHandle = RegisterServiceCtrlHandlerW(real_service_name, &handler); if(!statusHandle) return; set_start_pending(waithint,checkpoint); keys = get_keys(service_name); if(!keys){ - log_error("Could not get registry keys for erlang service."); + log_error(L"Could not get registry keys for erlang service."); set_stopped(ERROR_CANTREAD); return; } @@ -745,7 +764,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ ++checkpoint; if(!start_a_service(&srvi)){ - log_error("Could not start erlang machine"); + log_error(L"Could not start erlang machine"); set_stopped(ERROR_PROCESS_ABORTED); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); @@ -769,16 +788,16 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ if(ret == WAIT_TIMEOUT){ /* Just do the "success reporting" and continue */ if(success_wait == INITIAL_SUCCESS_WAIT){ - log_info("Erlang service started successfully."); + log_info(L"Erlang service started successfully."); } else { - log_warning("Erlang service restarted"); + log_warning(L"Erlang service restarted"); } success_wait = NO_SUCCESS_WAIT; continue; } if(ret == WAIT_FAILED || (int)(ret-WAIT_OBJECT_0) >= 2){ set_stopped(WAIT_FAILED); - log_error("Internal error, could not wait for objects."); + log_error(L"Internal error, could not wait for objects."); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); } @@ -791,7 +810,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ checkpoint = 2; /* 1 is taken by the handler */ set_stop_pending(waithint,checkpoint); if(stop_erlang(&srvi,waithint,&checkpoint)){ - log_debug("Erlang machine is stopped"); + log_debug(L"Erlang machine is stopped"); CloseHandle(eventStop); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); @@ -802,7 +821,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ free_keys(keys); return; } else { - log_warning("Unable to stop erlang service."); + log_warning(L"Unable to stop erlang service."); set_running(); continue; } @@ -811,12 +830,12 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ save_keys = keys; keys = get_keys(service_name); if(!keys){ - log_error("Could not reload registry keys."); + log_error(L"Could not reload registry keys."); keys = srvi.keys = save_keys; } else { #ifdef HARDDEBUG - sprintf(errorbuff,"Reloaded the registry keys because %s stopped.", - service_name); + swprintf(errorbuff,2048,L"Reloaded the registry keys because %s stopped.", + service_name); log_debug(errorbuff); #endif /* HARDDEBUG */ free_keys(save_keys); @@ -827,7 +846,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ if(!GetProcessTimes(srvi.info.hProcess,&creationt, &exitt,&kernelt,&usert)){ DWORD rcode = GetLastError(); - log_error("Could not get process time of terminated process."); + log_error(L"Could not get process time of terminated process."); CloseHandle(srvi.info.hProcess); CloseHandle(srvi.info.hThread); CloseHandle(eventStop); @@ -850,15 +869,14 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ diffl = exitl - creationl; diffl /= 10000000; #ifdef DEBUG - sprintf(errorbuff,"Process lived for %d seconds", (int) diffl); + swprintf(errorbuff,2048,L"Process lived for %d seconds", (int) diffl); log_debug(errorbuff); #endif if(diffl > CYCLIC_RESTART_LIMIT || srvi.keys[OnFail].data.value == ON_FAIL_RESTART_ALWAYS){ if(!start_a_service(&srvi)){ - log_error("Unable to restart failed erlang service, " - "aborting."); + log_error(L"Unable to restart failed erlang service, aborting."); CloseHandle(eventStop); set_stopped(ERROR_PROCESS_ABORTED); if (eventKillErlang != NULL) { @@ -867,19 +885,19 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ free_keys(keys); return; } - log_warning("Restarted erlang machine."); + log_warning(L"Restarted erlang machine."); if(diffl <= CYCLIC_RESTART_LIMIT) - log_warning("Possible cyclic restarting of erlang machine."); + log_warning(L"Possible cyclic restarting of erlang machine."); success_wait = RESTART_SUCCESS_WAIT; harr[0] = srvi.info.hProcess; } else { if(success_wait == INITIAL_SUCCESS_WAIT){ - log_error("Erlang machine stopped instantly " - "(distribution name conflict?). " - "The service is not restarted, ignoring OnFail option."); + log_error(L"Erlang machine stopped instantly " + L"(distribution name conflict?). " + L"The service is not restarted, ignoring OnFail option."); } else { - log_error("Erlang machine seems to die " - "continously, not restarted."); + log_error(L"Erlang machine seems to die " + L"continously, not restarted."); } CloseHandle(eventStop); set_stopped(ERROR_PROCESS_ABORTED); @@ -890,21 +908,21 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ return; } } else if(srvi.keys[OnFail].data.value == ON_FAIL_REBOOT){ - log_error("Rebooting because erlang machine stopped."); + log_error(L"Rebooting because erlang machine stopped."); enable_privilege(); if(!InitiateSystemShutdown("",NULL,0,TRUE,TRUE)){ - log_error("Failed to reboot!"); + log_error(L"Failed to reboot!"); #ifdef HARDDEBUG { - char *mes; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &mes, - 0, - NULL ); + wchar_t *mes; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &mes, + 0, + NULL ); log_debug(mes); LocalFree(mes); } @@ -923,13 +941,13 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } else { DWORD ecode = NO_ERROR; if(success_wait == NO_SUCCESS_WAIT){ - log_warning("Erlang machine voluntarily stopped. " - "The service is not restarted as OnFail " - "is set to ignore."); + log_warning(L"Erlang machine voluntarily stopped. " + L"The service is not restarted as OnFail " + L"is set to ignore."); } else { - log_error("Erlang machine stopped instantly " - "(distribution name conflict?). " - "The service is not restarted as OnFail is set to ignore."); + log_error(L"Erlang machine stopped instantly " + L"(distribution name conflict?). " + L"The service is not restarted as OnFail is set to ignore."); ecode = ERROR_PROCESS_ABORTED; } CloseHandle(srvi.info.hProcess); @@ -946,20 +964,19 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } } -int service_main(int argc, char **argv){ - char dummy_name[] = ""; - SERVICE_TABLE_ENTRY serviceTable[] = +int service_main(int argc, wchar_t **argv){ + wchar_t dummy_name[] = L""; + SERVICE_TABLE_ENTRYW serviceTable[] = { { dummy_name, - (LPSERVICE_MAIN_FUNCTION) service_main_loop}, + (LPSERVICE_MAIN_FUNCTIONW) service_main_loop}, { NULL, NULL } }; BOOL success; - success = - StartServiceCtrlDispatcher(serviceTable); + success = StartServiceCtrlDispatcherW(serviceTable); if (!success) - log_error("Could not initiate service"); - log_debug("service_main done its job"); + log_error(L"Could not initiate service"); + log_debug(L"service_main done its job"); return 0; } diff --git a/erts/etc/win32/erlsrv/erlsrv_service.h b/erts/etc/win32/erlsrv/erlsrv_service.h index 3eab275836..c46689d83e 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.h +++ b/erts/etc/win32/erlsrv/erlsrv_service.h @@ -27,6 +27,6 @@ #define RESTART_SUCCESS_WAIT 2 -int service_main(int argc, char **argv); +int service_main(int argc, wchar_t **argv); #endif /* _ERLSRV_SERVICE_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_util.c b/erts/etc/win32/erlsrv/erlsrv_util.c index da3c6f5ef7..4b1ba071e8 100644 --- a/erts/etc/win32/erlsrv/erlsrv_util.c +++ b/erts/etc/win32/erlsrv/erlsrv_util.c @@ -25,76 +25,76 @@ #include "erlsrv_util.h" #include "erlsrv_logmess.h" -char *service_name = ""; -char *real_service_name = ""; +wchar_t *service_name = L""; +wchar_t *real_service_name = L""; -void log_warning(char *mess){ +void log_warning(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_WARNING_TYPE, 0, MSG_WARNING, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_WARNING_TYPE, 0, MSG_WARNING, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } -void log_error(char *mess){ +void log_error(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_ERROR_TYPE, 0, MSG_ERROR, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_ERROR_TYPE, 0, MSG_ERROR, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } -void log_info(char *mess){ +void log_info(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_INFORMATION_TYPE, 0, MSG_INFO, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_INFORMATION_TYPE, 0, MSG_INFO, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } #ifndef NDEBUG -void log_debug(char *mess){ - char *buff=malloc(strlen(mess)+100); - sprintf(buff,"DEBUG! %s",mess); +void log_debug(wchar_t *mess){ + wchar_t *buff=malloc((wcslen(mess)+100)*sizeof(wchar_t)); + swprintf(buff,wcslen(mess)+100,L"DEBUG! %s",mess); log_info(buff); free(buff); } #endif -char *envdup(char *env){ - char *tmp; +wchar_t *envdup(wchar_t *env){ + wchar_t *tmp; int len; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1) + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1) ; len = (tmp - env) + 1; if(len == 1) ++len; - tmp = malloc(len); - memcpy(tmp,env,len); + tmp = malloc(len*sizeof(wchar_t)); + memcpy(tmp,env,len*sizeof(wchar_t)); return tmp; } -char **env_to_arg(char *env){ - char **ret; - char *tmp; +wchar_t **env_to_arg(wchar_t *env){ + wchar_t **ret; + wchar_t *tmp; int i; int num_strings = 0; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1) + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1) ++num_strings; /* malloc enough to insert ONE string */ - ret = malloc(sizeof(char *) * (num_strings + 2)); + ret = malloc(sizeof(wchar_t *) * (num_strings + 2)); i = 0; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1){ - ret[i++] = strdup(tmp); + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1){ + ret[i++] = wcsdup(tmp); } ret[i] = NULL; free(env); @@ -102,52 +102,52 @@ char **env_to_arg(char *env){ } static int compare(const void *a, const void *b){ - char *s1 = *((char **) a); - char *s2 = *((char **) b); - char *e1 = strchr(s1,'='); - char *e2 = strchr(s2,'='); + wchar_t *s1 = *((wchar_t **) a); + wchar_t *s2 = *((wchar_t **) b); + wchar_t *e1 = wcschr(s1,L'='); + wchar_t *e2 = wcschr(s2,L'='); int ret; int len; if(!e1) - e1 = s1 + strlen(s1); + e1 = s1 + wcslen(s1); if(!e2) - e2 = s2 + strlen(s2); + e2 = s2 + wcslen(s2); if((e1 - s1) > (e2 - s2)) len = (e2 - s2); else len = (e1 - s1); - ret = _strnicmp(s1,s2,len); + ret = _wcsnicmp(s1,s2,len); if(ret == 0) return ((e1 - s1) - (e2 - s2)); else return ret; } -char *arg_to_env(char **arg){ - char *block; - char *pek; +wchar_t *arg_to_env(wchar_t **arg){ + wchar_t *block; + wchar_t *pek; int i; int totlen = 1; /* extra '\0' */ for(i=0;arg[i] != NULL;++i) - totlen += strlen(arg[i])+1; + totlen += wcslen(arg[i])+1; /* sort the environment vector */ - qsort(arg,i,sizeof(char *),&compare); + qsort(arg,i,sizeof(wchar_t *),&compare); if(totlen == 1){ - block = malloc(2); - block[0] = block[1] = '\0'; + block = malloc(2*sizeof(wchar_t)); + block[0] = block[1] = L'\0'; } else { - block = malloc(totlen); + block = malloc(totlen*sizeof(wchar_t)); pek = block; for(i=0; arg[i] != NULL; ++i){ - strcpy(pek, arg[i]); + wcscpy(pek, arg[i]); free(arg[i]); - pek += strlen(pek)+1; + pek += wcslen(pek)+1; } - *pek = '\0'; + *pek = L'\0'; } free(arg); return block; diff --git a/erts/etc/win32/erlsrv/erlsrv_util.h b/erts/etc/win32/erlsrv/erlsrv_util.h index b98a6cd3ef..6881906a52 100644 --- a/erts/etc/win32/erlsrv/erlsrv_util.h +++ b/erts/etc/win32/erlsrv/erlsrv_util.h @@ -19,30 +19,30 @@ #ifndef _ERLSRV_UTIL_H #define _ERLSRV_UTIL_H -extern char *service_name; -extern char *real_service_name; -void log_warning(char *mess); -void log_error(char *mess); -void log_info(char *mess); +extern wchar_t *service_name; +extern wchar_t *real_service_name; +void log_warning(wchar_t *mess); +void log_error(wchar_t *mess); +void log_info(wchar_t *mess); -char *envdup(char *env); +wchar_t *envdup(wchar_t *env); /* ** Call before env_to_arg to get a 'freeable' environment block. */ -char *arg_to_env(char **arg); +wchar_t *arg_to_env(wchar_t **arg); /* ** Frees the argument list before returning! */ -char **env_to_arg(char *env); +wchar_t **env_to_arg(wchar_t *env); /* ** Frees the environment block before returning! */ #ifndef NDEBUG -void log_debug(char *mess); +void log_debug(wchar_t *mess); #else #define log_debug(mess) /* Debug removed */ #endif -- cgit v1.2.3