msvcrt: Rebuild the argv array instead of getting it from libwine.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
036f4dca3c
commit
e9d2b31c87
|
@ -23,12 +23,13 @@
|
|||
|
||||
#include <math.h>
|
||||
#include "msvcrt.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
|
||||
|
||||
static WCHAR **initial_wargv;
|
||||
static int initial_argc;
|
||||
int MSVCRT___argc = 0;
|
||||
static int wargc_expand;
|
||||
unsigned int MSVCRT__commode = 0;
|
||||
|
@ -159,6 +160,69 @@ static char **build_argv( WCHAR **wargv )
|
|||
return argv;
|
||||
}
|
||||
|
||||
static WCHAR **cmdline_to_argv( const WCHAR *src, int *ret_argc )
|
||||
{
|
||||
WCHAR **argv, *arg, *dst;
|
||||
int argc, in_quotes = 0, bcount = 0, len = lstrlenW(src) + 1;
|
||||
|
||||
argc = 2 + len / 2;
|
||||
argv = HeapAlloc( GetProcessHeap(), 0, argc * sizeof(*argv) + len * sizeof(WCHAR) );
|
||||
arg = dst = (WCHAR *)(argv + argc);
|
||||
argc = 0;
|
||||
while (*src)
|
||||
{
|
||||
if ((*src == ' ' || *src == '\t') && !in_quotes)
|
||||
{
|
||||
/* skip the remaining spaces */
|
||||
while (*src == ' ' || *src == '\t') src++;
|
||||
if (!*src) break;
|
||||
/* close the argument and copy it */
|
||||
*dst++ = 0;
|
||||
argv[argc++] = arg;
|
||||
/* start with a new argument */
|
||||
arg = dst;
|
||||
bcount = 0;
|
||||
}
|
||||
else if (*src == '\\')
|
||||
{
|
||||
*dst++ = *src++;
|
||||
bcount++;
|
||||
}
|
||||
else if (*src == '"')
|
||||
{
|
||||
if ((bcount & 1) == 0)
|
||||
{
|
||||
/* Preceded by an even number of '\', this is half that
|
||||
* number of '\', plus a '"' which we discard.
|
||||
*/
|
||||
dst -= bcount / 2;
|
||||
src++;
|
||||
if (in_quotes && *src == '"') *dst++ = *src++;
|
||||
else in_quotes = !in_quotes;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Preceded by an odd number of '\', this is half that
|
||||
* number of '\' followed by a '"'
|
||||
*/
|
||||
dst -= bcount / 2 + 1;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
bcount = 0;
|
||||
}
|
||||
else /* a regular character */
|
||||
{
|
||||
*dst++ = *src++;
|
||||
bcount = 0;
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
argv[argc++] = arg;
|
||||
argv[argc] = NULL;
|
||||
*ret_argc = argc;
|
||||
return argv;
|
||||
}
|
||||
|
||||
typedef void (CDECL *_INITTERMFUN)(void);
|
||||
typedef int (CDECL *_INITTERM_E_FN)(void);
|
||||
|
||||
|
@ -348,9 +412,10 @@ void msvcrt_init_args(void)
|
|||
|
||||
MSVCRT__acmdln = MSVCRT__strdup( GetCommandLineA() );
|
||||
MSVCRT__wcmdln = MSVCRT__wcsdup( GetCommandLineW() );
|
||||
MSVCRT___argc = __wine_main_argc;
|
||||
MSVCRT___wargv = __wine_main_wargv;
|
||||
MSVCRT___argv = build_argv( MSVCRT___wargv );
|
||||
initial_wargv = cmdline_to_argv( GetCommandLineW(), &initial_argc );
|
||||
MSVCRT___argc = initial_argc;
|
||||
MSVCRT___wargv = initial_wargv;
|
||||
MSVCRT___argv = build_argv( initial_wargv );
|
||||
|
||||
TRACE("got %s, wide = %s argc=%d\n", debugstr_a(MSVCRT__acmdln),
|
||||
debugstr_w(MSVCRT__wcmdln),MSVCRT___argc);
|
||||
|
@ -419,21 +484,21 @@ static int build_expanded_wargv(int *argc, MSVCRT_wchar_t **argv)
|
|||
HANDLE h;
|
||||
|
||||
args_no = 0;
|
||||
for(i=0; i<__wine_main_argc; i++) {
|
||||
for(i=0; i < initial_argc; i++) {
|
||||
WIN32_FIND_DATAW data;
|
||||
int len = 0;
|
||||
|
||||
is_expandable = FALSE;
|
||||
for(path_len = strlenW(__wine_main_wargv[i])-1; path_len>=0; path_len--) {
|
||||
if(__wine_main_wargv[i][path_len]=='*' || __wine_main_wargv[i][path_len]=='?')
|
||||
for(path_len = strlenW(initial_wargv[i])-1; path_len>=0; path_len--) {
|
||||
if(initial_wargv[i][path_len]=='*' || initial_wargv[i][path_len]=='?')
|
||||
is_expandable = TRUE;
|
||||
else if(__wine_main_wargv[i][path_len]=='\\' || __wine_main_wargv[i][path_len]=='/')
|
||||
else if(initial_wargv[i][path_len]=='\\' || initial_wargv[i][path_len]=='/')
|
||||
break;
|
||||
}
|
||||
path_len++;
|
||||
|
||||
if(is_expandable)
|
||||
h = FindFirstFileW(__wine_main_wargv[i], &data);
|
||||
h = FindFirstFileW(initial_wargv[i], &data);
|
||||
else
|
||||
h = INVALID_HANDLE_VALUE;
|
||||
|
||||
|
@ -446,7 +511,7 @@ static int build_expanded_wargv(int *argc, MSVCRT_wchar_t **argv)
|
|||
len = strlenW(data.cFileName)+1;
|
||||
if(argv) {
|
||||
argv[args_no] = (MSVCRT_wchar_t*)(argv+*argc+1)+size;
|
||||
memcpy(argv[args_no], __wine_main_wargv[i], path_len*sizeof(MSVCRT_wchar_t));
|
||||
memcpy(argv[args_no], initial_wargv[i], path_len*sizeof(MSVCRT_wchar_t));
|
||||
memcpy(argv[args_no]+path_len, data.cFileName, len*sizeof(MSVCRT_wchar_t));
|
||||
}
|
||||
args_no++;
|
||||
|
@ -456,10 +521,10 @@ static int build_expanded_wargv(int *argc, MSVCRT_wchar_t **argv)
|
|||
}
|
||||
|
||||
if(!len) {
|
||||
len = strlenW(__wine_main_wargv[i])+1;
|
||||
len = strlenW(initial_wargv[i])+1;
|
||||
if(argv) {
|
||||
argv[args_no] = (MSVCRT_wchar_t*)(argv+*argc+1)+size;
|
||||
memcpy(argv[args_no], __wine_main_wargv[i], len*sizeof(MSVCRT_wchar_t));
|
||||
memcpy(argv[args_no], initial_wargv[i], len*sizeof(MSVCRT_wchar_t));
|
||||
}
|
||||
args_no++;
|
||||
size += len;
|
||||
|
@ -496,8 +561,8 @@ int CDECL __wgetmainargs(int *argc, MSVCRT_wchar_t** *wargv, MSVCRT_wchar_t** *w
|
|||
}
|
||||
}
|
||||
if (!expand_wildcards) {
|
||||
MSVCRT___argc = __wine_main_argc;
|
||||
MSVCRT___wargv = __wine_main_wargv;
|
||||
MSVCRT___argc = initial_argc;
|
||||
MSVCRT___wargv = initial_wargv;
|
||||
}
|
||||
|
||||
/* Initialize the _wenviron array if it's not already created. */
|
||||
|
@ -533,8 +598,8 @@ int CDECL __getmainargs(int *argc, char** *argv, char** *envp,
|
|||
}
|
||||
}
|
||||
if (!expand_wildcards) {
|
||||
MSVCRT___argc = __wine_main_argc;
|
||||
MSVCRT___argv = build_argv( __wine_main_wargv );
|
||||
MSVCRT___argc = initial_argc;
|
||||
MSVCRT___argv = build_argv( initial_wargv );
|
||||
}
|
||||
|
||||
*argc = MSVCRT___argc;
|
||||
|
|
Loading…
Reference in New Issue