Commit 74042733 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

shell32: Forward some functions to shcore.dll.

parent e4115e36
......@@ -271,7 +271,7 @@
@ stdcall CheckEscapesA(str long)
@ stdcall CheckEscapesW(wstr long)
@ stdcall CommandLineToArgvW(wstr ptr)
@ stdcall CommandLineToArgvW(wstr ptr) shcore.CommandLineToArgvW
@ stdcall Control_FillCache_RunDLL(long long long long) Control_FillCache_RunDLLA
@ stdcall Control_FillCache_RunDLLA(long long long long)
@ stdcall Control_FillCache_RunDLLW(long long long long)
......@@ -312,7 +312,7 @@
@ stdcall FindExecutableW(wstr wstr ptr)
@ stub FixupOptionalComponents
@ stdcall FreeIconList(long)
@ stdcall GetCurrentProcessExplicitAppUserModelID(ptr)
@ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) shcore.GetCurrentProcessExplicitAppUserModelID
@ stdcall InitNetworkAddressControl()
@ stub InternalExtractIconListA
@ stub InternalExtractIconListW
......@@ -328,7 +328,7 @@
@ stub RealShellExecuteExW
@ stub RealShellExecuteW
@ stdcall RegenerateUserEnvironment(ptr long)
@ stdcall SetCurrentProcessExplicitAppUserModelID(wstr)
@ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) shcore.SetCurrentProcessExplicitAppUserModelID
@ stdcall SHAddToRecentDocs (long ptr)
@ stdcall SHAppBarMessage(long ptr)
@ stdcall SHAssocEnumHandlers(wstr long ptr)
......
......@@ -55,266 +55,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/*************************************************************************
* CommandLineToArgvW [SHELL32.@]
*
* We must interpret the quotes in the command line to rebuild the argv
* array correctly:
* - arguments are separated by spaces or tabs
* - quotes serve as optional argument delimiters
* '"a b"' -> 'a b'
* - escaped quotes must be converted back to '"'
* '\"' -> '"'
* - consecutive backslashes preceding a quote see their number halved with
* the remainder escaping the quote:
* 2n backslashes + quote -> n backslashes + quote as an argument delimiter
* 2n+1 backslashes + quote -> n backslashes + literal quote
* - backslashes that are not followed by a quote are copied literally:
* 'a\b' -> 'a\b'
* 'a\\b' -> 'a\\b'
* - in quoted strings, consecutive quotes see their number divided by three
* with the remainder modulo 3 deciding whether to close the string or not.
* Note that the opening quote must be counted in the consecutive quotes,
* that's the (1+) below:
* (1+) 3n quotes -> n quotes
* (1+) 3n+1 quotes -> n quotes plus closes the quoted string
* (1+) 3n+2 quotes -> n+1 quotes plus closes the quoted string
* - in unquoted strings, the first quote opens the quoted string and the
* remaining consecutive quotes follow the above rule.
*/
LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
{
DWORD argc;
LPWSTR *argv;
LPCWSTR s;
LPWSTR d;
LPWSTR cmdline;
int qcount,bcount;
if(!numargs)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
if (*lpCmdline==0)
{
/* Return the path to the executable */
DWORD len, deslen=MAX_PATH, size;
size = sizeof(LPWSTR)*2 + deslen*sizeof(WCHAR);
for (;;)
{
if (!(argv = LocalAlloc(LMEM_FIXED, size))) return NULL;
len = GetModuleFileNameW(0, (LPWSTR)(argv+2), deslen);
if (!len)
{
LocalFree(argv);
return NULL;
}
if (len < deslen) break;
deslen*=2;
size = sizeof(LPWSTR)*2 + deslen*sizeof(WCHAR);
LocalFree( argv );
}
argv[0]=(LPWSTR)(argv+2);
argv[1]=NULL;
*numargs=1;
return argv;
}
/* --- First count the arguments */
argc=1;
s=lpCmdline;
/* The first argument, the executable path, follows special rules */
if (*s=='"')
{
/* The executable path ends at the next quote, no matter what */
s++;
while (*s)
if (*s++=='"')
break;
}
else
{
/* The executable path ends at the next space, no matter what */
while (*s && *s!=' ' && *s!='\t')
s++;
}
/* skip to the first argument, if any */
while (*s==' ' || *s=='\t')
s++;
if (*s)
argc++;
/* Analyze the remaining arguments */
qcount=bcount=0;
while (*s)
{
if ((*s==' ' || *s=='\t') && qcount==0)
{
/* skip to the next argument and count it if any */
while (*s==' ' || *s=='\t')
s++;
if (*s)
argc++;
bcount=0;
}
else if (*s=='\\')
{
/* '\', count them */
bcount++;
s++;
}
else if (*s=='"')
{
/* '"' */
if ((bcount & 1)==0)
qcount++; /* unescaped '"' */
s++;
bcount=0;
/* consecutive quotes, see comment in copying code below */
while (*s=='"')
{
qcount++;
s++;
}
qcount=qcount % 3;
if (qcount==2)
qcount=0;
}
else
{
/* a regular character */
bcount=0;
s++;
}
}
/* Allocate in a single lump, the string array, and the strings that go
* with it. This way the caller can make a single LocalFree() call to free
* both, as per MSDN.
*/
argv=LocalAlloc(LMEM_FIXED, (argc+1)*sizeof(LPWSTR)+(strlenW(lpCmdline)+1)*sizeof(WCHAR));
if (!argv)
return NULL;
cmdline=(LPWSTR)(argv+argc+1);
strcpyW(cmdline, lpCmdline);
/* --- Then split and copy the arguments */
argv[0]=d=cmdline;
argc=1;
/* The first argument, the executable path, follows special rules */
if (*d=='"')
{
/* The executable path ends at the next quote, no matter what */
s=d+1;
while (*s)
{
if (*s=='"')
{
s++;
break;
}
*d++=*s++;
}
}
else
{
/* The executable path ends at the next space, no matter what */
while (*d && *d!=' ' && *d!='\t')
d++;
s=d;
if (*s)
s++;
}
/* close the executable path */
*d++=0;
/* skip to the first argument and initialize it if any */
while (*s==' ' || *s=='\t')
s++;
if (!*s)
{
/* There are no parameters so we are all done */
argv[argc]=NULL;
*numargs=argc;
return argv;
}
/* Split and copy the remaining arguments */
argv[argc++]=d;
qcount=bcount=0;
while (*s)
{
if ((*s==' ' || *s=='\t') && qcount==0)
{
/* close the argument */
*d++=0;
bcount=0;
/* skip to the next one and initialize it if any */
do {
s++;
} while (*s==' ' || *s=='\t');
if (*s)
argv[argc++]=d;
}
else if (*s=='\\')
{
*d++=*s++;
bcount++;
}
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;
qcount++;
}
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;
/* Now count the number of consecutive quotes. Note that qcount
* already takes into account the opening quote if any, as well as
* the quote that lead us here.
*/
while (*s=='"')
{
if (++qcount==3)
{
*d++='"';
qcount=0;
}
s++;
}
if (qcount==2)
qcount=0;
}
else
{
/* a regular character */
*d++=*s++;
bcount=0;
}
}
*d='\0';
argv[argc]=NULL;
*numargs=argc;
return argv;
}
static DWORD shgfi_get_exe_type(LPCWSTR szFullPath)
{
BOOL status = FALSE;
......@@ -1377,25 +1117,6 @@ HRESULT WINAPI SHGetLocalizedName(LPCWSTR path, LPWSTR module, UINT size, INT *r
}
/***********************************************************************
* SetCurrentProcessExplicitAppUserModelID (SHELL32.@)
*/
HRESULT WINAPI SetCurrentProcessExplicitAppUserModelID(PCWSTR appid)
{
FIXME("%s: stub\n", debugstr_w(appid));
return E_NOTIMPL;
}
/***********************************************************************
* GetCurrentProcessExplicitAppUserModelID (SHELL32.@)
*/
HRESULT WINAPI GetCurrentProcessExplicitAppUserModelID(PWSTR *appid)
{
FIXME("%p: stub\n", appid);
*appid = NULL;
return E_NOTIMPL;
}
/***********************************************************************
* SHSetUnreadMailCountW (SHELL32.@)
*/
HRESULT WINAPI SHSetUnreadMailCountW(LPCWSTR mailaddress, DWORD count, LPCWSTR executecommand)
......
......@@ -339,6 +339,13 @@ my @dll_groups =
"sspicli",
],
[
"shcore",
"shell32",
"api-ms-win-shcore-obsolete-l1-1-0",
"api-ms-win-shcore-thread-l1-1-0",
"api-ms-win-shcore-stream-l1-1-0",
],
[
"shell32",
"api-ms-win-downlevel-shell32-l1-1-0",
"api-ms-win-shell-shellcom-l1-1-0",
......@@ -357,16 +364,9 @@ my @dll_groups =
[
"shell32",
"shlwapi",
"shcore",
"api-ms-win-shcore-scaling-l1-1-1",
],
[
"shcore",
"api-ms-win-shcore-obsolete-l1-1-0",
"api-ms-win-shcore-thread-l1-1-0",
"api-ms-win-shcore-stream-l1-1-0",
],
[
"user32",
"api-ms-win-core-stringansi-l1-1-0",
"api-ms-win-core-stringloader-l1-1-1",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment