msvcrt: Create the Ansi argv from the Unicode one.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5a9c88d62e
commit
94a3d4adad
|
@ -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.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue