diff --git a/dlls/msvcrt/data.c b/dlls/msvcrt/data.c index fa53b85bd7d..578130b719f 100644 --- a/dlls/msvcrt/data.c +++ b/dlls/msvcrt/data.c @@ -229,7 +229,7 @@ char*** CDECL __p___initenv(void) { return &MSVCRT___initenv; } MSVCRT_wchar_t*** CDECL __p___winitenv(void) { return &MSVCRT___winitenv; } /* INTERNAL: Create a wide string from an ascii string */ -static MSVCRT_wchar_t *wstrdupa(const char *str) +MSVCRT_wchar_t *msvcrt_wstrdupa(const char *str) { const size_t len = strlen(str) + 1 ; MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t)); @@ -249,7 +249,7 @@ void msvcrt_init_args(void) DWORD version; MSVCRT__acmdln = _strdup( GetCommandLineA() ); - MSVCRT__wcmdln = wstrdupa(MSVCRT__acmdln); + MSVCRT__wcmdln = msvcrt_wstrdupa(MSVCRT__acmdln); MSVCRT___argc = __wine_main_argc; MSVCRT___argv = __wine_main_argv; MSVCRT___wargv = __wine_main_wargv; diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 5d4540f9116..59c42cbe301 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -125,6 +125,8 @@ extern MSVCRT_wchar_t **_wenviron; extern char ** msvcrt_SnapshotOfEnvironmentA(char **); extern MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **); +MSVCRT_wchar_t *msvcrt_wstrdupa(const char *); + /* FIXME: This should be declared in new.h but it's not an extern "C" so * it would not be much use anyway. Even for Winelib applications. */ diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index fffe8832e96..b0fa5e9668f 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -570,7 +570,7 @@ @ cdecl _wstat64(wstr ptr) MSVCRT__wstat64 @ cdecl _wstrdate(ptr) @ cdecl _wstrtime(ptr) -@ stub _wsystem #(wstr) +@ cdecl _wsystem(wstr) @ cdecl _wtempnam(wstr wstr) @ stub _wtmpnam #(ptr) @ cdecl _wtoi(wstr) ntdll._wtoi diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c index 14f8e9a28bd..46481efa9c3 100644 --- a/dlls/msvcrt/process.c +++ b/dlls/msvcrt/process.c @@ -269,6 +269,22 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim) return ret; } +/* INTERNAL: retrieve COMSPEC environment variable */ +static MSVCRT_wchar_t *msvcrt_get_comspec(void) +{ + static const MSVCRT_wchar_t cmd[] = {'c','m','d',0}; + static const MSVCRT_wchar_t comspec[] = {'C','O','M','S','P','E','C',0}; + MSVCRT_wchar_t *ret; + unsigned int len; + + if (!(len = GetEnvironmentVariableW(comspec, NULL, 0))) len = sizeof(cmd)/sizeof(MSVCRT_wchar_t); + if ((ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t)))) + { + if (!GetEnvironmentVariableW(comspec, ret, len)) strcpyW(ret, cmd); + } + return ret; +} + /********************************************************************* * _cwait (MSVCRT.@) */ @@ -821,20 +837,51 @@ int CDECL MSVCRT__pclose(MSVCRT_FILE* file) return MSVCRT_fclose(file); } +/********************************************************************* + * _wsystem (MSVCRT.@) + * + * Unicode version of system + */ +int CDECL _wsystem(const MSVCRT_wchar_t* cmd) +{ + int res; + MSVCRT_wchar_t *comspec, *fullcmd; + unsigned int len; + static const MSVCRT_wchar_t flag[] = {' ','/','c',' ',0}; + + if (!(comspec = msvcrt_get_comspec())) return -1; + len = strlenW(comspec) + strlenW(flag) + strlenW(cmd) + 1; + + if (!(fullcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t)))) + { + HeapFree(GetProcessHeap(), 0, comspec); + return -1; + } + strcpyW(fullcmd, comspec); + strcatW(fullcmd, flag); + strcatW(fullcmd, cmd); + + res = msvcrt_spawn_wide(MSVCRT__P_WAIT, comspec, fullcmd, NULL); + + HeapFree(GetProcessHeap(), 0, comspec); + HeapFree(GetProcessHeap(), 0, fullcmd); + return res; +} + /********************************************************************* * system (MSVCRT.@) */ int CDECL MSVCRT_system(const char* cmd) { - char* cmdcopy; - int res; + int res = -1; + MSVCRT_wchar_t *cmdW; - /* Make a writable copy for CreateProcess */ - cmdcopy=_strdup(cmd); - /* FIXME: should probably launch cmd interpreter in COMSPEC */ - res=msvcrt_spawn(MSVCRT__P_WAIT, NULL, cmdcopy, NULL); - MSVCRT_free(cmdcopy); - return res; + if ((cmdW = msvcrt_wstrdupa(cmd))) + { + res = _wsystem(cmdW); + HeapFree(GetProcessHeap(), 0, cmdW); + } + return res; } /*********************************************************************