Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
Shcore.dll does not take over shell32.dll registration, or objects it implements.
dlls/shcore/shcore.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec index 0b20781635..dac4274e49 100644 --- a/dlls/shcore/shcore.spec +++ b/dlls/shcore/shcore.spec @@ -3,9 +3,9 @@ @ stub CreateRandomAccessStreamOnFile @ stub CreateRandomAccessStreamOverStream @ stub CreateStreamOverRandomAccessStream -@ stdcall -private DllCanUnloadNow() shell32.DllCanUnloadNow +@ stub DllCanUnloadNow @ stub DllGetActivationFactory -@ stdcall -private DllGetClassObject(ptr ptr ptr) shell32.DllGetClassObject +@ stub DllGetClassObject @ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) shell32.GetCurrentProcessExplicitAppUserModelID @ stdcall GetDpiForMonitor(long long ptr ptr) @ stub GetDpiForShellUIComponent
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shcore/main.c | 13 +++++++++++++ dlls/shcore/shcore.spec | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c index aa513ee09d..ccea518f88 100644 --- a/dlls/shcore/main.c +++ b/dlls/shcore/main.c @@ -221,3 +221,16 @@ HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
return hr; } + +HRESULT WINAPI SetCurrentProcessExplicitAppUserModelID(const WCHAR *appid) +{ + FIXME("%s: stub\n", debugstr_w(appid)); + return E_NOTIMPL; +} + +HRESULT WINAPI GetCurrentProcessExplicitAppUserModelID(const WCHAR **appid) +{ + FIXME("%p: stub\n", appid); + *appid = NULL; + return E_NOTIMPL; +} diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec index dac4274e49..2f3ca9925b 100644 --- a/dlls/shcore/shcore.spec +++ b/dlls/shcore/shcore.spec @@ -6,7 +6,7 @@ @ stub DllCanUnloadNow @ stub DllGetActivationFactory @ stub DllGetClassObject -@ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) shell32.GetCurrentProcessExplicitAppUserModelID +@ stdcall GetCurrentProcessExplicitAppUserModelID(ptr) @ stdcall GetDpiForMonitor(long long ptr ptr) @ stub GetDpiForShellUIComponent @ stdcall GetProcessDpiAwareness(long ptr) @@ -77,7 +77,7 @@ @ stdcall SHStrDupW(wstr ptr) shlwapi.SHStrDupW @ stdcall SHUnicodeToAnsi(wstr ptr ptr) shlwapi.SHUnicodeToAnsi @ stdcall SHUnicodeToUnicode(wstr ptr long) shlwapi.SHUnicodeToUnicode -@ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) shell32.SetCurrentProcessExplicitAppUserModelID +@ stdcall SetCurrentProcessExplicitAppUserModelID(wstr) @ stdcall SetProcessDpiAwareness(long) @ stub SetProcessReference @ stub UnregisterScaleChangeEvent
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shcore/main.c | 258 ++++++++++++++++++++++++++++++++++++++++ dlls/shcore/shcore.spec | 2 +- 2 files changed, 259 insertions(+), 1 deletion(-)
diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c index ccea518f88..8f674a2edc 100644 --- a/dlls/shcore/main.c +++ b/dlls/shcore/main.c @@ -29,6 +29,7 @@ #include "ocidl.h" #include "shellscalingapi.h" #include "wine/debug.h" +#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(shcore);
@@ -234,3 +235,260 @@ HRESULT WINAPI GetCurrentProcessExplicitAppUserModelID(const WCHAR **appid) *appid = NULL; return E_NOTIMPL; } + +/************************************************************************* + * CommandLineToArgvW [SHCORE.@] + * + * 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. + */ +WCHAR** WINAPI CommandLineToArgvW(const WCHAR *cmdline, int *numargs) +{ + int qcount, bcount; + const WCHAR *s; + WCHAR **argv; + DWORD argc; + WCHAR *d; + + if (!numargs) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (*cmdline == 0) + { + /* Return the path to the executable */ + DWORD len, deslen = MAX_PATH, size; + + size = sizeof(WCHAR *) * 2 + deslen * sizeof(WCHAR); + for (;;) + { + if (!(argv = LocalAlloc(LMEM_FIXED, size))) return NULL; + len = GetModuleFileNameW(0, (WCHAR *)(argv + 2), deslen); + if (!len) + { + LocalFree(argv); + return NULL; + } + if (len < deslen) break; + deslen *= 2; + size = sizeof(WCHAR *) * 2 + deslen * sizeof(WCHAR); + LocalFree(argv); + } + argv[0] = (WCHAR *)(argv + 2); + argv[1] = NULL; + *numargs = 1; + + return argv; + } + + /* --- First count the arguments */ + argc = 1; + s = cmdline; + /* 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(WCHAR *) + (strlenW(cmdline) + 1) * sizeof(WCHAR)); + if (!argv) + return NULL; + + /* --- Then split and copy the arguments */ + argv[0] = d = strcpyW((WCHAR *)(argv + argc + 1), 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; +} diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec index 2f3ca9925b..1266a02f69 100644 --- a/dlls/shcore/shcore.spec +++ b/dlls/shcore/shcore.spec @@ -1,5 +1,5 @@ 1 stub @ -@ stdcall CommandLineToArgvW(wstr ptr) shell32.CommandLineToArgvW +@ stdcall CommandLineToArgvW(wstr ptr) @ stub CreateRandomAccessStreamOnFile @ stub CreateRandomAccessStreamOverStream @ stub CreateStreamOverRandomAccessStream
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/shell32/shell32.spec | 6 +- dlls/shell32/shell32_main.c | 279 ------------------------------------ tools/make_specfiles | 14 +- 3 files changed, 10 insertions(+), 289 deletions(-)
diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index 837abd3fec..23243e1f22 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -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) diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c index e78e8f8c56..a791966031 100644 --- a/dlls/shell32/shell32_main.c +++ b/dlls/shell32/shell32_main.c @@ -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; @@ -1376,25 +1116,6 @@ HRESULT WINAPI SHGetLocalizedName(LPCWSTR path, LPWSTR module, UINT size, INT *r return E_NOTIMPL; }
-/*********************************************************************** - * 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.@) */ diff --git a/tools/make_specfiles b/tools/make_specfiles index ffb3bae15f..2b38aed74e 100755 --- a/tools/make_specfiles +++ b/tools/make_specfiles @@ -338,6 +338,13 @@ my @dll_groups = "secur32", "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", @@ -357,15 +364,8 @@ 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",