/* * %CopyrightBegin% * * Copyright Ericsson AB 1997-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * %CopyrightEnd% */ /* * Extra support for running the emulator on Windows. * Most of this only used when beam is run as a separate process. */ #pragma comment(linker,"/manifestdependency:\"type='win32' "\ "name='Microsoft.Windows.Common-Controls' "\ "version='6.0.0.0' processorArchitecture='*' "\ "publicKeyToken='6595b64144ccf1df' language='*'\"") #include #include #include #include #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sys.h" #include "erl_driver.h" extern int nohup; extern int keep_window; void error(char* format, ...); /* * Local functions. */ #define LOAD_BEAM_DYNAMICALLY 1 static int start(char* emu, char** argv); static void start_winsock(void); static char* last_error(void); static char* last_wsa_error(void); static char* win32_errorstr(int error); static int has_console(void); static char** fnuttify_argv(char **argv); static void free_fnuttified(char **v); static int windowed = 0; #ifdef LOAD_BEAM_DYNAMICALLY typedef int SysGetKeyFunction(int); typedef void ErlStartFunction(int, char **); typedef void SysPrimitiveInitFunction(HMODULE); static SysGetKeyFunction *sys_get_key_p; static ErlStartFunction *erl_start_p; static SysPrimitiveInitFunction *sys_primitive_init_p; /* * To enable debugging of argument processing etc * #define ARGS_HARDDEBUG 1 * #define HARDDEBUG 1 */ static HMODULE load_win_beam_dll(wchar_t *name) { HMODULE beam_module; beam_module=LoadLibraryW(name); if (beam_module == INVALID_HANDLE_VALUE || beam_module == NULL) { error("Unable to load emulator DLL\n(%S)",name); return NULL; } sys_get_key_p = (SysGetKeyFunction *) GetProcAddress(beam_module, "sys_get_key"); erl_start_p = (ErlStartFunction *) GetProcAddress(beam_module, "erl_start"); sys_primitive_init_p = (SysPrimitiveInitFunction *) GetProcAddress(beam_module, "sys_primitive_init"); return beam_module; } #endif #define DLL_ENV "ERL_EMULATOR_DLL" static void set_env(char *key, char *value) /* Both in UTF-8 encoding */ { wchar_t *wkey=NULL; wchar_t *wvalue=NULL; int keylen; int valuelen; keylen = MultiByteToWideChar(CP_UTF8, 0, key, -1, NULL, 0); valuelen = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0); wkey = malloc(keylen*sizeof(wchar_t)); wvalue = malloc(valuelen*sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, keylen); MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, valuelen); if (!SetEnvironmentVariableW( wkey, wvalue)) error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value); } static char * get_env(char *key) { DWORD size = 32; char *value = NULL; while (1) { DWORD nsz; if (value) free(value); value = malloc(size); if (!value) error("GetEnvironmentVariable(\"%s\") failed", key); SetLastError(0); nsz = GetEnvironmentVariable((LPCTSTR) key, (LPTSTR) value, size); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { free(value); return NULL; } if (nsz <= size) return value; size = nsz; } } free_env_val(char *value) { if (value) free(value); } int start_win_emulator(char* utf8emu, char *utf8start_prog, char** utf8argv, int start_detached) { int len; int argc = 0; windowed = 1; while (utf8argv[argc] != NULL) { ++argc; } if (start_detached) { wchar_t *start_prog=NULL; int result; int i; wchar_t **argv; close(0); close(1); close(2); set_env("ERL_CONSOLE_MODE", "detached"); set_env(DLL_ENV, utf8emu); utf8argv[0] = utf8start_prog; utf8argv = fnuttify_argv(utf8argv); len = MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, NULL, 0); start_prog = malloc(len*sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, start_prog, len); /* Convert utf8argv to multibyte argv */ argv = malloc((argc+1) * sizeof(wchar_t*)); for (i=0; i