Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
726cf9c0
Commit
726cf9c0
authored
Mar 30, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Make sure the argv array matches the Unicode version, even when launching start.exe.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6ca1a926
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
140 additions
and
83 deletions
+140
-83
env.c
dlls/ntdll/unix/env.c
+122
-76
loader.c
dlls/ntdll/unix/loader.c
+18
-7
No files found.
dlls/ntdll/unix/env.c
View file @
726cf9c0
...
...
@@ -851,82 +851,146 @@ char **build_envp( const WCHAR *envW )
*
* Change the process name in the ps output.
*/
static
int
set_process_name
(
int
argc
,
char
*
argv
[]
)
static
void
set_process_name
(
const
char
*
name
)
{
BOOL
shift_strings
;
char
*
p
,
*
name
;
int
i
;
char
*
p
;
#ifdef HAVE_SETPROCTITLE
setproctitle
(
"-%s"
,
argv
[
1
]);
shift_strings
=
FALSE
;
#else
p
=
argv
[
0
];
shift_strings
=
(
argc
>=
2
);
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
p
+=
strlen
(
p
)
+
1
;
if
(
p
!=
argv
[
i
])
{
shift_strings
=
FALSE
;
break
;
}
}
setproctitle
(
"-%s"
,
name
);
#endif
if
((
p
=
strrchr
(
name
,
'\\'
)))
name
=
p
+
1
;
if
((
p
=
strrchr
(
name
,
'/'
)))
name
=
p
+
1
;
#ifdef HAVE_SETPROGNAME
setprogname
(
name
);
#endif
#ifdef HAVE_PRCTL
#ifndef PR_SET_NAME
# define PR_SET_NAME 15
#endif
prctl
(
PR_SET_NAME
,
name
);
#endif
}
/***********************************************************************
* rebuild_argv
*
* Build the main argv by removing argv[0].
*/
static
void
rebuild_argv
(
void
)
{
BOOL
shift_strings
=
FALSE
;
int
i
;
#ifndef HAVE_SETPROCTITLE
for
(
i
=
1
;
i
<
main_argc
;
i
++
)
if
(
main_argv
[
i
-
1
]
+
strlen
(
main_argv
[
i
-
1
]
)
+
1
!=
main_argv
[
i
])
break
;
shift_strings
=
(
i
==
main_argc
);
#endif
if
(
shift_strings
)
{
int
offset
=
argv
[
1
]
-
argv
[
0
];
char
*
end
=
argv
[
argc
-
1
]
+
strlen
(
argv
[
argc
-
1
])
+
1
;
memmove
(
argv
[
0
],
argv
[
1
],
end
-
argv
[
1
]
);
int
offset
=
main_argv
[
1
]
-
main_
argv
[
0
];
char
*
end
=
main_argv
[
main_argc
-
1
]
+
strlen
(
main_argv
[
main_argc
-
1
])
+
1
;
memmove
(
main_argv
[
0
],
main_argv
[
1
],
end
-
main_
argv
[
1
]
);
memset
(
end
-
offset
,
0
,
offset
);
for
(
i
=
1
;
i
<
argc
;
i
++
)
argv
[
i
-
1
]
=
argv
[
i
]
-
offset
;
argv
[
i
-
1
]
=
NULL
;
for
(
i
=
1
;
i
<
main_argc
;
i
++
)
main_argv
[
i
-
1
]
=
main_argv
[
i
]
-
offset
;
}
else
else
memmove
(
main_argv
,
main_argv
+
1
,
(
main_argc
-
1
)
*
sizeof
(
main_argv
[
0
])
);
main_argv
[
--
main_argc
]
=
NULL
;
set_process_name
(
main_argv
[
0
]
);
}
/***********************************************************************
* prepend_argv
*
* Prepend values to the main argv, removing the original argv[0].
*/
static
void
prepend_argv
(
const
char
**
args
,
int
count
)
{
char
**
new_argv
=
malloc
(
(
main_argc
+
count
)
*
sizeof
(
*
new_argv
)
);
char
*
p
,
*
end
;
BOOL
write_strings
=
FALSE
;
int
i
,
total
=
0
,
new_argc
=
main_argc
+
count
-
1
;
for
(
i
=
0
;
i
<
count
;
i
++
)
total
+=
strlen
(
args
[
i
])
+
1
;
for
(
i
=
1
;
i
<
main_argc
;
i
++
)
total
+=
strlen
(
main_argv
[
i
])
+
1
;
new_argv
=
malloc
(
(
new_argc
+
1
)
*
sizeof
(
*
new_argv
)
+
total
);
p
=
(
char
*
)(
new_argv
+
new_argc
+
1
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
/* remove argv[0] */
memmove
(
argv
,
argv
+
1
,
argc
*
sizeof
(
argv
[
0
])
);
new_argv
[
i
]
=
p
;
strcpy
(
p
,
args
[
i
]
);
p
+=
strlen
(
p
)
+
1
;
}
for
(
i
=
1
;
i
<
main_argc
;
i
++
)
{
new_argv
[
count
+
i
-
1
]
=
p
;
strcpy
(
p
,
main_argv
[
i
]
);
p
+=
strlen
(
p
)
+
1
;
}
new_argv
[
new_argc
]
=
NULL
;
name
=
argv
[
0
];
if
((
p
=
strrchr
(
name
,
'\\'
)))
name
=
p
+
1
;
if
((
p
=
strrchr
(
name
,
'/'
)))
name
=
p
+
1
;
/* copy what we can over the original argv */
#if defined(HAVE_SETPROGNAME)
setprogname
(
name
);
#ifndef HAVE_SETPROCTITLE
for
(
i
=
1
;
i
<
main_argc
;
i
++
)
if
(
main_argv
[
i
-
1
]
+
strlen
(
main_argv
[
i
-
1
])
+
1
!=
main_argv
[
i
])
break
;
write_strings
=
(
i
==
main_argc
);
#endif
if
(
write_strings
)
{
p
=
main_argv
[
0
];
end
=
main_argv
[
main_argc
-
1
]
+
strlen
(
main_argv
[
main_argc
-
1
])
+
1
;
#ifdef HAVE_PRCTL
#ifndef PR_SET_NAME
# define PR_SET_NAME 15
#endif
prctl
(
PR_SET_NAME
,
name
);
#endif
/* HAVE_PRCTL */
return
argc
-
1
;
for
(
i
=
0
;
i
<
min
(
new_argc
,
main_argc
)
&&
p
<
end
;
i
++
)
{
int
len
=
min
(
end
-
p
-
1
,
strlen
(
new_argv
[
i
])
);
memcpy
(
p
,
new_argv
[
i
],
len
);
main_argv
[
i
]
=
p
;
p
+=
len
;
*
p
++
=
0
;
}
memset
(
p
,
0
,
end
-
p
);
main_argv
[
i
]
=
NULL
;
}
else
{
memcpy
(
main_argv
,
new_argv
,
min
(
new_argc
,
main_argc
)
*
sizeof
(
*
new_argv
)
);
main_argv
[
min
(
new_argc
,
main_argc
)]
=
NULL
;
}
main_argc
=
new_argc
;
main_argv
=
new_argv
;
set_process_name
(
main_argv
[
0
]
);
}
/***********************************************************************
* build_wargv
*
* Build the Unicode argv array.
* Build the Unicode argv array
, replacing argv[0] by the image name
.
*/
static
WCHAR
**
build_wargv
(
c
har
**
argv
)
static
WCHAR
**
build_wargv
(
c
onst
WCHAR
*
image
)
{
int
argc
;
WCHAR
*
p
,
**
wargv
;
DWORD
total
=
0
;
DWORD
total
=
wcslen
(
image
)
+
1
;
for
(
argc
=
0
;
argv
[
argc
];
argc
++
)
total
+=
strlen
(
argv
[
argc
])
+
1
;
for
(
argc
=
1
;
main_argv
[
argc
];
argc
++
)
total
+=
strlen
(
main_
argv
[
argc
])
+
1
;
wargv
=
malloc
(
total
*
sizeof
(
WCHAR
)
+
(
argc
+
1
)
*
sizeof
(
*
wargv
)
);
p
=
(
WCHAR
*
)(
wargv
+
argc
+
1
);
for
(
argc
=
0
;
argv
[
argc
];
argc
++
)
wargv
[
0
]
=
p
;
wcscpy
(
p
,
image
);
total
-=
wcslen
(
p
)
+
1
;
p
+=
wcslen
(
p
)
+
1
;
for
(
argc
=
1
;
main_argv
[
argc
];
argc
++
)
{
DWORD
reslen
=
ntdll_umbstowcs
(
argv
[
argc
],
strlen
(
argv
[
argc
])
+
1
,
p
,
total
);
DWORD
reslen
=
ntdll_umbstowcs
(
main_argv
[
argc
],
strlen
(
main_
argv
[
argc
])
+
1
,
p
,
total
);
wargv
[
argc
]
=
p
;
p
+=
reslen
;
total
-=
reslen
;
...
...
@@ -936,22 +1000,6 @@ static WCHAR **build_wargv( char **argv )
}
/***********************************************************************
* prepend_main_wargv
*
* Rebuild the main_wargv array with some extra arguments in front.
*/
static
void
prepend_main_wargv
(
const
WCHAR
**
args
,
int
count
)
{
WCHAR
**
argv
=
malloc
(
(
main_argc
+
count
+
1
)
*
sizeof
(
*
argv
)
);
memcpy
(
argv
,
args
,
count
*
sizeof
(
*
argv
)
);
memcpy
(
argv
+
count
,
main_wargv
,
(
main_argc
+
1
)
*
sizeof
(
*
argv
)
);
main_wargv
=
argv
;
main_argc
+=
count
;
}
/* Unix format is: lang[_country][.charset][@modifier]
* Windows format is: lang[-script][-country][_modifier] */
static
BOOL
unix_to_win_locale
(
const
char
*
unix_name
,
char
*
win_name
)
...
...
@@ -1093,9 +1141,8 @@ void init_environment( int argc, char *argv[], char *envp[] )
lctable
=
case_table
+
case_table
[
1
]
+
2
;
}
main_argc
=
set_process_name
(
argc
,
argv
)
;
main_argc
=
argc
;
main_argv
=
argv
;
main_wargv
=
build_wargv
(
argv
);
main_envp
=
envp
;
}
...
...
@@ -1851,7 +1898,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
WCHAR
*
dst
,
*
image
,
*
cmdline
,
*
p
,
*
path
=
NULL
;
WCHAR
*
env
=
get_initial_environment
(
&
env_pos
,
&
env_size
);
WCHAR
*
curdir
=
get_initial_directory
();
void
*
module
;
void
*
module
=
NULL
;
NTSTATUS
status
;
/* store the initial PATH value */
...
...
@@ -1871,25 +1918,21 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
add_registry_environment
(
&
env
,
&
env_pos
,
&
env_size
);
env
[
env_pos
++
]
=
0
;
status
=
load_main_exe
(
main_wargv
[
0
],
main_argv
[
0
],
curdir
,
&
image
,
&
module
,
&
image_info
);
if
(
status
>=
0
&&
image_info
.
Machine
!=
current_machine
)
/* need to restart for Wow64 */
{
NtUnmapViewOfSection
(
GetCurrentProcess
(),
module
);
status
=
STATUS_INVALID_IMAGE_FORMAT
;
}
status
=
load_main_exe
(
NULL
,
main_argv
[
1
],
curdir
,
&
image
,
&
module
,
&
image_info
);
if
(
!
status
&&
image_info
.
Machine
!=
current_machine
)
status
=
STATUS_INVALID_IMAGE_FORMAT
;
if
(
status
)
/* try launching it through start.exe */
{
static
const
WCHAR
execW
[]
=
{
'/'
,
'e'
,
'x'
,
'e'
,
'c'
,
0
};
const
WCHAR
*
args
[]
=
{
NULL
,
execW
};
static
const
char
*
args
[]
=
{
"start.exe"
,
"/exec"
};
free
(
image
);
prepend_main_wargv
(
args
,
2
);
if
(
module
)
NtUnmapViewOfSection
(
GetCurrentProcess
(),
module
);
load_start_exe
(
&
image
,
&
module
,
&
image_info
);
prepend_argv
(
args
,
2
);
}
else
rebuild_argv
();
NtCurrentTeb
()
->
Peb
->
ImageBaseAddress
=
module
;
main_wargv
[
0
]
=
get_dos_path
(
image
);
main_wargv
=
build_wargv
(
get_dos_path
(
image
)
);
cmdline
=
build_command_line
(
main_wargv
);
TRACE
(
"image %s cmdline %s dir %s
\n
"
,
...
...
@@ -1918,6 +1961,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
put_unicode_string
(
main_wargv
[
0
],
&
dst
,
&
params
->
ImagePathName
);
put_unicode_string
(
cmdline
,
&
dst
,
&
params
->
CommandLine
);
free
(
image
);
free
(
cmdline
);
free
(
curdir
);
...
...
@@ -2043,6 +2087,8 @@ void init_startup_info(void)
NtTerminateProcess
(
GetCurrentProcess
(),
status
);
}
NtCurrentTeb
()
->
Peb
->
ImageBaseAddress
=
module
;
rebuild_argv
();
main_wargv
=
build_wargv
(
get_dos_path
(
image
));
free
(
image
);
}
...
...
dlls/ntdll/unix/loader.c
View file @
726cf9c0
...
...
@@ -1531,10 +1531,12 @@ static NTSTATUS open_main_image( WCHAR *image, void **module, SECTION_IMAGE_INFO
/***********************************************************************
* load_main_exe
*/
NTSTATUS
load_main_exe
(
const
WCHAR
*
name
,
const
char
*
unix_name
,
const
WCHAR
*
curdir
,
NTSTATUS
load_main_exe
(
const
WCHAR
*
dos_
name
,
const
char
*
unix_name
,
const
WCHAR
*
curdir
,
WCHAR
**
image
,
void
**
module
,
SECTION_IMAGE_INFORMATION
*
image_info
)
{
UNICODE_STRING
nt_name
;
WCHAR
*
tmp
=
NULL
;
BOOL
contains_path
;
NTSTATUS
status
;
SIZE_T
size
;
struct
stat
st
;
...
...
@@ -1549,7 +1551,18 @@ NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *c
free
(
*
image
);
}
if
((
status
=
get_full_path
(
name
,
curdir
,
image
)))
goto
failed
;
if
(
!
dos_name
)
{
dos_name
=
tmp
=
malloc
(
(
strlen
(
unix_name
)
+
1
)
*
sizeof
(
WCHAR
)
);
ntdll_umbstowcs
(
unix_name
,
strlen
(
unix_name
)
+
1
,
tmp
,
strlen
(
unix_name
)
+
1
);
}
contains_path
=
(
wcschr
(
dos_name
,
'/'
)
||
wcschr
(
dos_name
,
'\\'
)
||
(
dos_name
[
0
]
&&
dos_name
[
1
]
==
':'
));
if
((
status
=
get_full_path
(
dos_name
,
curdir
,
image
)))
goto
failed
;
free
(
tmp
);
status
=
open_main_image
(
*
image
,
module
,
image_info
);
if
(
status
!=
STATUS_DLL_NOT_FOUND
)
return
status
;
...
...
@@ -1560,13 +1573,11 @@ NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *c
status
=
find_builtin_dll
(
&
nt_name
,
module
,
&
size
,
image_info
,
machine
,
FALSE
);
if
(
status
!=
STATUS_DLL_NOT_FOUND
)
return
status
;
}
/* if name contains a path, bail out */
if
(
wcschr
(
name
,
'/'
)
||
wcschr
(
name
,
'\\'
)
||
(
name
[
0
]
&&
name
[
1
]
==
':'
))
goto
failed
;
return
STATUS_DLL_NOT_FOUND
;
if
(
!
contains_path
)
return
STATUS_DLL_NOT_FOUND
;
failed:
MESSAGE
(
"wine: failed to open %s: %x
\n
"
,
debugstr_w
(
name
),
status
);
MESSAGE
(
"wine: failed to open %s: %x
\n
"
,
unix_name
?
debugstr_a
(
unix_name
)
:
debugstr_w
(
dos_name
),
status
);
NtTerminateProcess
(
GetCurrentProcess
(),
status
);
return
status
;
/* unreached */
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment