mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-21 17:09:06 -07:00
rundll32: Rewrite command line parsing.
Windows doesn't do any fancy unescaping.
This commit is contained in:
parent
c20bf25556
commit
5c597119a0
1 changed files with 28 additions and 90 deletions
|
@ -191,90 +191,33 @@ static void *get_entry_point32( HMODULE module, LPCWSTR entry, BOOL *unicode )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPWSTR get_next_arg(LPWSTR *cmdline)
|
static WCHAR *parse_arguments( WCHAR *cmdline, WCHAR **dll, WCHAR **entrypoint )
|
||||||
{
|
{
|
||||||
LPWSTR s;
|
WCHAR *p;
|
||||||
LPWSTR arg,d;
|
|
||||||
BOOL in_quotes;
|
|
||||||
int bcount,len=0;
|
|
||||||
|
|
||||||
/* count the chars */
|
if (cmdline[0] == '"')
|
||||||
bcount=0;
|
p = wcschr( ++cmdline, '"' );
|
||||||
in_quotes=FALSE;
|
else
|
||||||
s=*cmdline;
|
p = wcspbrk( cmdline, L" ,\t" );
|
||||||
while (1) {
|
|
||||||
if (*s==0 || ((*s=='\t' || *s==' ') && !in_quotes)) {
|
|
||||||
/* end of this command line argument */
|
|
||||||
break;
|
|
||||||
} else if (*s=='\\') {
|
|
||||||
/* '\', count them */
|
|
||||||
bcount++;
|
|
||||||
} else if ((*s=='"') && ((bcount & 1)==0)) {
|
|
||||||
/* unescaped '"' */
|
|
||||||
in_quotes=!in_quotes;
|
|
||||||
bcount=0;
|
|
||||||
} else {
|
|
||||||
/* a regular character */
|
|
||||||
bcount=0;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
arg=malloc( (len+1)*sizeof(WCHAR) );
|
|
||||||
if (!arg)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
bcount=0;
|
if (!p) return NULL;
|
||||||
in_quotes=FALSE;
|
*p++ = 0;
|
||||||
d=arg;
|
*dll = cmdline;
|
||||||
s=*cmdline;
|
/* skip spaces and commas */
|
||||||
while (*s) {
|
p += wcsspn( p, L" ,\t" );
|
||||||
if ((*s=='\t' || *s==' ') && !in_quotes) {
|
if (!*p) return NULL;
|
||||||
/* end of this command line argument */
|
*entrypoint = p;
|
||||||
break;
|
/* find end of entry point string */
|
||||||
} else if (*s=='\\') {
|
p += wcscspn( p, L" \t" );
|
||||||
/* '\\' */
|
if (*p) *p++ = 0;
|
||||||
*d++=*s++;
|
p += wcsspn( p, L" \t" );
|
||||||
bcount++;
|
return p;
|
||||||
} else if (*s=='"') {
|
|
||||||
/* '"' */
|
|
||||||
if ((bcount & 1)==0) {
|
|
||||||
/* Preceded by an even number of '\', this is half that
|
|
||||||
* number of '\', plus a quote which we erase.
|
|
||||||
*/
|
|
||||||
d-=bcount/2;
|
|
||||||
in_quotes=!in_quotes;
|
|
||||||
s++;
|
|
||||||
} else {
|
|
||||||
/* Preceded by an odd number of '\', this is half that
|
|
||||||
* number of '\' followed by a '"'
|
|
||||||
*/
|
|
||||||
d=d-bcount/2-1;
|
|
||||||
*d++='"';
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
bcount=0;
|
|
||||||
} else {
|
|
||||||
/* a regular character */
|
|
||||||
*d++=*s++;
|
|
||||||
bcount=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*d=0;
|
|
||||||
*cmdline=s;
|
|
||||||
|
|
||||||
/* skip the remaining spaces */
|
|
||||||
while (**cmdline=='\t' || **cmdline==' ') {
|
|
||||||
(*cmdline)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return arg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI wWinMain(HINSTANCE instance, HINSTANCE hOldInstance, LPWSTR szCmdLine, int nCmdShow)
|
int WINAPI wWinMain(HINSTANCE instance, HINSTANCE hOldInstance, LPWSTR szCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
LPWSTR szDllName,szEntryPoint;
|
LPWSTR szDllName, szEntryPoint, args;
|
||||||
void *entry_point = NULL;
|
void *entry_point = NULL;
|
||||||
BOOL unicode = FALSE, win16 = FALSE;
|
BOOL unicode = FALSE, win16 = FALSE;
|
||||||
HMODULE hDll, hCtx;
|
HMODULE hDll, hCtx;
|
||||||
|
@ -289,16 +232,11 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE hOldInstance, LPWSTR szCmdLine
|
||||||
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);
|
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* Get the dll name and API EntryPoint */
|
/* Get the dll name and API EntryPoint */
|
||||||
WINE_TRACE("CmdLine=%s\n",wine_dbgstr_w(szCmdLine));
|
args = parse_arguments( wcsdup(szCmdLine), &szDllName, &szEntryPoint );
|
||||||
szDllName = get_next_arg(&szCmdLine);
|
if (!args) return 0;
|
||||||
if (!szDllName || *szDllName==0)
|
|
||||||
return 0;
|
TRACE( "dll %s entry %s cmdline %s\n", wine_dbgstr_w(szDllName),
|
||||||
WINE_TRACE("DllName=%s\n",wine_dbgstr_w(szDllName));
|
wine_dbgstr_w(szEntryPoint), wine_dbgstr_w(args) );
|
||||||
if ((szEntryPoint = wcschr(szDllName, ',' )))
|
|
||||||
*szEntryPoint++=0;
|
|
||||||
else
|
|
||||||
szEntryPoint = get_next_arg(&szCmdLine);
|
|
||||||
WINE_TRACE("EntryPoint=%s\n",wine_dbgstr_w(szEntryPoint));
|
|
||||||
|
|
||||||
/* Activate context before DllMain() is called */
|
/* Activate context before DllMain() is called */
|
||||||
if (SearchPathW(NULL, szDllName, NULL, ARRAY_SIZE(path), path, NULL))
|
if (SearchPathW(NULL, szDllName, NULL, ARRAY_SIZE(path), path, NULL))
|
||||||
|
@ -347,19 +285,19 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE hOldInstance, LPWSTR szCmdLine
|
||||||
if (unicode)
|
if (unicode)
|
||||||
{
|
{
|
||||||
WINE_TRACE( "Calling %s (%p,%p,%s,%d)\n", wine_dbgstr_w(szEntryPoint),
|
WINE_TRACE( "Calling %s (%p,%p,%s,%d)\n", wine_dbgstr_w(szEntryPoint),
|
||||||
hWnd, instance, wine_dbgstr_w(szCmdLine), info.wShowWindow );
|
hWnd, instance, wine_dbgstr_w(args), info.wShowWindow );
|
||||||
|
|
||||||
call_entry_point( entry_point, hWnd, instance, szCmdLine, info.wShowWindow );
|
call_entry_point( entry_point, hWnd, instance, args, info.wShowWindow );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD len = WideCharToMultiByte( CP_ACP, 0, szCmdLine, -1, NULL, 0, NULL, NULL );
|
DWORD len = WideCharToMultiByte( CP_ACP, 0, args, -1, NULL, 0, NULL, NULL );
|
||||||
char *cmdline = malloc( len );
|
char *cmdline = malloc( len );
|
||||||
|
|
||||||
if (!cmdline)
|
if (!cmdline)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
WideCharToMultiByte( CP_ACP, 0, szCmdLine, -1, cmdline, len, NULL, NULL );
|
WideCharToMultiByte( CP_ACP, 0, args, -1, cmdline, len, NULL, NULL );
|
||||||
|
|
||||||
WINE_TRACE( "Calling %s (%p,%p,%s,%d)\n", wine_dbgstr_w(szEntryPoint),
|
WINE_TRACE( "Calling %s (%p,%p,%s,%d)\n", wine_dbgstr_w(szEntryPoint),
|
||||||
hWnd, instance, wine_dbgstr_a(cmdline), info.wShowWindow );
|
hWnd, instance, wine_dbgstr_a(cmdline), info.wShowWindow );
|
||||||
|
|
Loading…
Reference in a new issue