Alexandre Julliard : msvcrt: Create the Ansi argv from the Unicode one.

Alexandre Julliard julliard at winehq.org
Mon Dec 9 16:57:35 CST 2019


Module: wine
Branch: master
Commit: 94a3d4adad43dad1086f8293d6ea293cc601c13b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=94a3d4adad43dad1086f8293d6ea293cc601c13b

Author: Alexandre Julliard <julliard at 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 at 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.@)
  */




More information about the wine-cvs mailing list