Module: wine Branch: master Commit: 94a3d4adad43dad1086f8293d6ea293cc601c13b URL: https://source.winehq.org/git/wine.git/?a=commit;h=94a3d4adad43dad1086f8293d...
Author: Alexandre Julliard julliard@winehq.org Date: Sat Dec 7 14:45:43 2019 +0100
msvcrt: Create the Ansi argv from the Unicode one.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/data.c | 187 ++++++++++++++++++++--------------------------------- 1 file changed, 71 insertions(+), 116 deletions(-)
diff --git a/dlls/msvcrt/data.c b/dlls/msvcrt/data.c index c3a1255a60..af7a13528f 100644 --- a/dlls/msvcrt/data.c +++ b/dlls/msvcrt/data.c @@ -30,7 +30,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
int MSVCRT___argc = 0; -static int argc_expand; static int wargc_expand; unsigned int MSVCRT__commode = 0; int MSVCRT__fmode = 0; @@ -50,7 +49,6 @@ unsigned int MSVCRT___setlc_active = 0; unsigned int MSVCRT___unguarded_readlc_active = 0; double MSVCRT__HUGE = 0; char **MSVCRT___argv = NULL; -static char **argv_expand; MSVCRT_wchar_t **MSVCRT___wargv = NULL; static MSVCRT_wchar_t **wargv_expand; char *MSVCRT__acmdln = NULL; @@ -139,6 +137,28 @@ MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **wblk) return wblk; }
+static char **build_argv( WCHAR **wargv ) +{ + int argc; + char *p, **argv; + DWORD total = 0; + + for (argc = 0; wargv[argc]; argc++) + total += WideCharToMultiByte( CP_ACP, 0, wargv[argc], -1, NULL, 0, NULL, NULL ); + + argv = HeapAlloc( GetProcessHeap(), 0, total + (argc + 1) * sizeof(*argv) ); + p = (char *)(argv + argc + 1); + for (argc = 0; wargv[argc]; argc++) + { + DWORD reslen = WideCharToMultiByte( CP_ACP, 0, wargv[argc], -1, p, total, NULL, NULL ); + argv[argc] = p; + p += reslen; + total -= reslen; + } + argv[argc] = NULL; + return argv; +} + typedef void (CDECL *_INITTERMFUN)(void); typedef int (CDECL *_INITTERM_E_FN)(void);
@@ -327,10 +347,10 @@ void msvcrt_init_args(void) OSVERSIONINFOW osvi;
MSVCRT__acmdln = MSVCRT__strdup( GetCommandLineA() ); - MSVCRT__wcmdln = msvcrt_wstrdupa(MSVCRT__acmdln); + MSVCRT__wcmdln = MSVCRT__wcsdup( GetCommandLineW() ); MSVCRT___argc = __wine_main_argc; - MSVCRT___argv = __wine_main_argv; MSVCRT___wargv = __wine_main_wargv; + MSVCRT___argv = build_argv( MSVCRT___wargv );
TRACE("got %s, wide = %s argc=%d\n", debugstr_a(MSVCRT__acmdln), debugstr_w(MSVCRT__wcmdln),MSVCRT___argc); @@ -382,125 +402,16 @@ void msvcrt_init_args(void) void msvcrt_free_args(void) { /* FIXME: more things to free */ + HeapFree(GetProcessHeap(), 0, MSVCRT___argv); HeapFree(GetProcessHeap(), 0, MSVCRT___initenv); HeapFree(GetProcessHeap(), 0, MSVCRT___winitenv); HeapFree(GetProcessHeap(), 0, MSVCRT__environ); HeapFree(GetProcessHeap(), 0, MSVCRT__wenviron); HeapFree(GetProcessHeap(), 0, MSVCRT__pgmptr); HeapFree(GetProcessHeap(), 0, MSVCRT__wpgmptr); - HeapFree(GetProcessHeap(), 0, argv_expand); HeapFree(GetProcessHeap(), 0, wargv_expand); }
-static int build_expanded_argv(int *argc, char **argv) -{ - int i, size=0, args_no=0, path_len; - BOOL is_expandable; - HANDLE h; - - args_no = 0; - for(i=0; i<__wine_main_argc; i++) { - WIN32_FIND_DATAA data; - int len = 0; - - is_expandable = FALSE; - for(path_len = strlen(__wine_main_argv[i])-1; path_len>=0; path_len--) { - if(__wine_main_argv[i][path_len]=='*' || __wine_main_argv[i][path_len]=='?') - is_expandable = TRUE; - else if(__wine_main_argv[i][path_len]=='\' || __wine_main_argv[i][path_len]=='/') - break; - } - path_len++; - - if(is_expandable) - h = FindFirstFileA(__wine_main_argv[i], &data); - else - h = INVALID_HANDLE_VALUE; - - if(h != INVALID_HANDLE_VALUE) { - do { - if(data.cFileName[0]=='.' && (data.cFileName[1]=='\0' || - (data.cFileName[1]=='.' && data.cFileName[2]=='\0'))) - continue; - - len = strlen(data.cFileName)+1; - if(argv) { - argv[args_no] = (char*)(argv+*argc+1)+size; - memcpy(argv[args_no], __wine_main_argv[i], path_len*sizeof(char)); - memcpy(argv[args_no]+path_len, data.cFileName, len*sizeof(char)); - } - args_no++; - size += len+path_len; - }while(FindNextFileA(h, &data)); - FindClose(h); - } - - if(!len) { - len = strlen(__wine_main_argv[i])+1; - if(argv) { - argv[args_no] = (char*)(argv+*argc+1)+size; - memcpy(argv[args_no], __wine_main_argv[i], len*sizeof(char)); - } - args_no++; - size += len; - } - } - - if(argv) - argv[args_no] = NULL; - size += (args_no+1)*sizeof(char*); - *argc = args_no; - return size; -} - -/********************************************************************* - * __getmainargs (MSVCRT.@) - */ -int CDECL __getmainargs(int *argc, char** *argv, char** *envp, - int expand_wildcards, int *new_mode) -{ - TRACE("(%p,%p,%p,%d,%p).\n", argc, argv, envp, expand_wildcards, new_mode); - - if (expand_wildcards) { - HeapFree(GetProcessHeap(), 0, argv_expand); - argv_expand = NULL; - - argv_expand = HeapAlloc(GetProcessHeap(), 0, - build_expanded_argv(&argc_expand, NULL)); - if (argv_expand) { - build_expanded_argv(&argc_expand, argv_expand); - - MSVCRT___argc = argc_expand; - MSVCRT___argv = argv_expand; - }else { - expand_wildcards = 0; - } - } - if (!expand_wildcards) { - MSVCRT___argc = __wine_main_argc; - MSVCRT___argv = __wine_main_argv; - } - - *argc = MSVCRT___argc; - *argv = MSVCRT___argv; - *envp = MSVCRT___initenv; - - if (new_mode) - MSVCRT__set_new_mode( *new_mode ); - return 0; -} - -#ifdef _CRTDLL -/********************************************************************* - * __GetMainArgs (CRTDLL.@) - */ -void CDECL __GetMainArgs( int *argc, char ***argv, char ***envp, int expand_wildcards ) -{ - int new_mode = 0; - __getmainargs( argc, argv, envp, expand_wildcards, &new_mode ); -} -#endif - static int build_expanded_wargv(int *argc, MSVCRT_wchar_t **argv) { int i, size=0, args_no=0, path_len; @@ -573,8 +484,6 @@ int CDECL __wgetmainargs(int *argc, MSVCRT_wchar_t** *wargv, MSVCRT_wchar_t** *w
if (expand_wildcards) { HeapFree(GetProcessHeap(), 0, wargv_expand); - wargv_expand = NULL; - wargv_expand = HeapAlloc(GetProcessHeap(), 0, build_expanded_wargv(&wargc_expand, NULL)); if (wargv_expand) { @@ -602,6 +511,52 @@ int CDECL __wgetmainargs(int *argc, MSVCRT_wchar_t** *wargv, MSVCRT_wchar_t** *w return 0; }
+/********************************************************************* + * __getmainargs (MSVCRT.@) + */ +int CDECL __getmainargs(int *argc, char** *argv, char** *envp, + int expand_wildcards, int *new_mode) +{ + TRACE("(%p,%p,%p,%d,%p).\n", argc, argv, envp, expand_wildcards, new_mode); + + if (expand_wildcards) { + HeapFree(GetProcessHeap(), 0, wargv_expand); + wargv_expand = HeapAlloc(GetProcessHeap(), 0, + build_expanded_wargv(&wargc_expand, NULL)); + if (wargv_expand) { + build_expanded_wargv(&wargc_expand, wargv_expand); + + MSVCRT___argc = wargc_expand; + MSVCRT___argv = build_argv( wargv_expand ); + }else { + expand_wildcards = 0; + } + } + if (!expand_wildcards) { + MSVCRT___argc = __wine_main_argc; + MSVCRT___argv = build_argv( __wine_main_wargv ); + } + + *argc = MSVCRT___argc; + *argv = MSVCRT___argv; + *envp = MSVCRT___initenv; + + if (new_mode) + MSVCRT__set_new_mode( *new_mode ); + return 0; +} + +#ifdef _CRTDLL +/********************************************************************* + * __GetMainArgs (CRTDLL.@) + */ +void CDECL __GetMainArgs( int *argc, char ***argv, char ***envp, int expand_wildcards ) +{ + int new_mode = 0; + __getmainargs( argc, argv, envp, expand_wildcards, &new_mode ); +} +#endif + /********************************************************************* * _initterm (MSVCRT.@) */