[SHLWAPI]
authorChristoph von Wittich <christoph_vw@reactos.org>
Sun, 21 Mar 2010 15:14:34 +0000 (15:14 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sun, 21 Mar 2010 15:14:34 +0000 (15:14 +0000)
sync shlwapi with wine 1.1.41

svn path=/trunk/; revision=46304

reactos/dll/win32/shlwapi/ordinal.c
reactos/dll/win32/shlwapi/shlwapi.spec
reactos/dll/win32/shlwapi/string.c
reactos/dll/win32/shlwapi/url.c

index 375ddaf..364bbfe 100644 (file)
@@ -402,7 +402,9 @@ HRESULT WINAPI RegisterDefaultAcceptHeaders(LPBC lpBC, IUnknown *lpUnknown)
     V_VT(&var) = VT_UNKNOWN;
     V_UNKNOWN(&var) = (IUnknown*)pIEnumFormatEtc;
 
-    hRet = IWebBrowserApp_PutProperty(pBrowser, (BSTR)szProperty, var);
+    property = SysAllocString(szProperty);
+    hRet = IWebBrowserApp_PutProperty(pBrowser, property, var);
+    SysFreeString(property);
     if (FAILED(hRet))
     {
        IEnumFORMATETC_Release(pIEnumFormatEtc);
@@ -4854,3 +4856,127 @@ BOOL WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LPLON
     }
     return hr;
 }
+
+/* return flags for SHGetObjectCompatFlags, names derived from registry value names */
+#define OBJCOMPAT_OTNEEDSSFCACHE           0x00000001
+#define OBJCOMPAT_NO_WEBVIEW               0x00000002
+#define OBJCOMPAT_UNBINDABLE               0x00000004
+#define OBJCOMPAT_PINDLL                   0x00000008
+#define OBJCOMPAT_NEEDSFILESYSANCESTOR     0x00000010
+#define OBJCOMPAT_NOTAFILESYSTEM           0x00000020
+#define OBJCOMPAT_CTXMENU_NOVERBS          0x00000040
+#define OBJCOMPAT_CTXMENU_LIMITEDQI        0x00000080
+#define OBJCOMPAT_COCREATESHELLFOLDERONLY  0x00000100
+#define OBJCOMPAT_NEEDSSTORAGEANCESTOR     0x00000200
+#define OBJCOMPAT_NOLEGACYWEBVIEW          0x00000400
+#define OBJCOMPAT_CTXMENU_XPQCMFLAGS       0x00001000
+#define OBJCOMPAT_NOIPROPERTYSTORE         0x00002000
+
+/* a search table for compatibility flags */
+struct objcompat_entry {
+    const WCHAR name[30];
+    DWORD value;
+};
+
+/* expected to be sorted by name */
+static const struct objcompat_entry objcompat_table[] = {
+    { {'C','O','C','R','E','A','T','E','S','H','E','L','L','F','O','L','D','E','R','O','N','L','Y',0},
+      OBJCOMPAT_COCREATESHELLFOLDERONLY },
+    { {'C','T','X','M','E','N','U','_','L','I','M','I','T','E','D','Q','I',0},
+      OBJCOMPAT_CTXMENU_LIMITEDQI },
+    { {'C','T','X','M','E','N','U','_','N','O','V','E','R','B','S',0},
+      OBJCOMPAT_CTXMENU_LIMITEDQI },
+    { {'C','T','X','M','E','N','U','_','X','P','Q','C','M','F','L','A','G','S',0},
+      OBJCOMPAT_CTXMENU_XPQCMFLAGS },
+    { {'N','E','E','D','S','F','I','L','E','S','Y','S','A','N','C','E','S','T','O','R',0},
+      OBJCOMPAT_NEEDSFILESYSANCESTOR },
+    { {'N','E','E','D','S','S','T','O','R','A','G','E','A','N','C','E','S','T','O','R',0},
+      OBJCOMPAT_NEEDSSTORAGEANCESTOR },
+    { {'N','O','I','P','R','O','P','E','R','T','Y','S','T','O','R','E',0},
+      OBJCOMPAT_NOIPROPERTYSTORE },
+    { {'N','O','L','E','G','A','C','Y','W','E','B','V','I','E','W',0},
+      OBJCOMPAT_NOLEGACYWEBVIEW },
+    { {'N','O','T','A','F','I','L','E','S','Y','S','T','E','M',0},
+      OBJCOMPAT_NOTAFILESYSTEM },
+    { {'N','O','_','W','E','B','V','I','E','W',0},
+      OBJCOMPAT_NO_WEBVIEW },
+    { {'O','T','N','E','E','D','S','S','F','C','A','C','H','E',0},
+      OBJCOMPAT_OTNEEDSSFCACHE },
+    { {'P','I','N','D','L','L',0},
+      OBJCOMPAT_PINDLL },
+    { {'U','N','B','I','N','D','A','B','L','E',0},
+      OBJCOMPAT_UNBINDABLE }
+};
+
+/**************************************************************************
+ *  SHGetObjectCompatFlags (SHLWAPI.476)
+ *
+ * Function returns an integer representation of compatibility flags stored
+ * in registry for CLSID under ShellCompatibility subkey.
+ *
+ * PARAMS
+ *  pUnk:  pointer to object IUnknown interface, idetifies CLSID
+ *  clsid: pointer to CLSID to retrieve data for
+ *
+ * RETURNS
+ *  0 on failure, flags set on success
+ */
+DWORD WINAPI SHGetObjectCompatFlags(IUnknown *pUnk, const CLSID *clsid)
+{
+    static const WCHAR compatpathW[] =
+        {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+         'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+         'S','h','e','l','l','C','o','m','p','a','t','i','b','i','l','i','t','y','\\',
+         'O','b','j','e','c','t','s','\\','%','s',0};
+    WCHAR strW[sizeof(compatpathW)/sizeof(WCHAR) + 38 /* { CLSID } */];
+    DWORD ret, length = sizeof(strW)/sizeof(WCHAR);
+    OLECHAR *clsid_str;
+    HKEY key;
+    INT i;
+
+    TRACE("%p %s\n", pUnk, debugstr_guid(clsid));
+
+    if (!pUnk && !clsid) return 0;
+
+    if (pUnk && !clsid)
+    {
+        FIXME("iface not handled\n");
+        return 0;
+    }
+
+    StringFromCLSID(clsid, &clsid_str);
+    sprintfW(strW, compatpathW, clsid_str);
+    CoTaskMemFree(clsid_str);
+
+    ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, strW, &key);
+    if (ret != ERROR_SUCCESS) return 0;
+
+    /* now collect flag values */
+    ret = 0;
+    for (i = 0; RegEnumValueW(key, i, strW, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; i++)
+    {
+        INT left, right, res, x;
+
+        /* search in table */
+        left  = 0;
+        right = sizeof(objcompat_table) / sizeof(struct objcompat_entry) - 1;
+
+        while (right >= left) {
+            x = (left + right) / 2;
+            res = strcmpW(strW, objcompat_table[x].name);
+            if (res == 0)
+            {
+                ret |= objcompat_table[x].value;
+                break;
+            }
+            else if (res < 0)
+                right = x - 1;
+            else
+                left = x + 1;
+        }
+
+        length = sizeof(strW)/sizeof(WCHAR);
+    }
+
+    return ret;
+}
index 3091783..d899232 100644 (file)
 473 stub -noname SHGetIniStringUTF7W
 474 stub -noname SHSetIniStringUTF7W
 475 stdcall -noname GetShellSecurityDescriptor(ptr long)
-476 stub -noname SHGetObjectCompatFlags
+476 stdcall -noname SHGetObjectCompatFlags(ptr ptr)
 477 stub -noname SHCreatePropertyBagOnMemory
 478 stdcall -noname IUnknown_TranslateAcceleratorIO(ptr ptr)
 479 stdcall -noname IUnknown_UIActivateIO(ptr long ptr)
 @ stdcall ColorAdjustLuma(long long long)
 @ stdcall ColorHLSToRGB(long long long)
 @ stdcall ColorRGBToHLS(long ptr ptr ptr)
+@ stdcall DelayLoadFailureHook(str str) kernel32.DelayLoadFailureHook
 @ stdcall -private DllGetVersion(ptr)
 @ stdcall GetMenuPosFromID(ptr long)
 @ stdcall HashData (ptr long ptr long)
index cfb59ea..e00a925 100644 (file)
@@ -507,22 +507,32 @@ LPWSTR WINAPI StrCpyW(LPWSTR lpszStr, LPCWSTR lpszSrc)
  * Copy a string to another string, up to a maximum number of characters.
  *
  * PARAMS
- *  lpszStr  [O] Destination string
- *  lpszSrc  [I] Source string
- *  iLen     [I] Maximum number of chars to copy
+ *  dst    [O] Destination string
+ *  src    [I] Source string
+ *  count  [I] Maximum number of chars to copy
  *
  * RETURNS
- *  lpszStr.
+ *  dst.
  */
-LPWSTR WINAPI StrCpyNW(LPWSTR lpszStr, LPCWSTR lpszSrc, int iLen)
+LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
 {
-  TRACE("(%p,%s,%i)\n", lpszStr, debugstr_w(lpszSrc), iLen);
+  LPWSTR d = dst;
+  LPCWSTR s = src;
 
-  lstrcpynW(lpszStr, lpszSrc, iLen);
-  return lpszStr;
-}
+  TRACE("(%p,%s,%i)\n", dst, debugstr_w(src), count);
 
+  if (s)
+  {
+    while ((count > 1) && *s)
+    {
+      count--;
+      *d++ = *s++;
+    }
+  }
+  if (count) *d = 0;
 
+  return dst;
+}
 
 /*************************************************************************
  * SHLWAPI_StrStrHelperA
index 2fdae3d..958a842 100644 (file)
@@ -359,6 +359,7 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized,
             if (*wk1 != '/') {state = 6; break;}
             *wk2++ = *wk1++;
             if((dwFlags & URL_FILE_USE_PATHURL) && nByteLen >= sizeof(wszLocalhost)
+                        && !strncmpW(wszFile, pszUrl, sizeof(wszFile)/sizeof(WCHAR))
                         && !memcmp(wszLocalhost, wk1, sizeof(wszLocalhost))){
                 wk1 += sizeof(wszLocalhost)/sizeof(WCHAR);
                 while(*wk1 == '\\' && (dwFlags & URL_FILE_USE_PATHURL))
@@ -2051,6 +2052,9 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
     LPWSTR in, out;
     DWORD ret, len, len2;
 
+    if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
+        return E_INVALIDARG;
+
     in = HeapAlloc(GetProcessHeap(), 0,
                              (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
     out = in + INTERNET_MAX_URL_LENGTH;
@@ -2067,7 +2071,7 @@ HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
 
     len2 = WideCharToMultiByte(0, 0, out, len, 0, 0, 0, 0);
     if (len2 > *pcchOut) {
-       *pcchOut = len2;
+       *pcchOut = len2+1;
        HeapFree(GetProcessHeap(), 0, in);
        return E_POINTER;
     }
@@ -2093,20 +2097,25 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
     TRACE("(%s %p %p(%d) %08x %08x)\n",
          debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwPart, dwFlags);
 
+    if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
+        return E_INVALIDARG;
+
+    *pszOut = '\0';
+
     addr = strchrW(pszIn, ':');
     if(!addr)
-        return E_FAIL;
-
-    scheme = get_scheme_code(pszIn, addr-pszIn);
+        scheme = URL_SCHEME_UNKNOWN;
+    else
+        scheme = get_scheme_code(pszIn, addr-pszIn);
 
     ret = URL_ParseUrl(pszIn, &pl);
-    if (ret == S_OK) {
-       schaddr = pl.pScheme;
-       schsize = pl.szScheme;
 
        switch (dwPart) {
        case URL_PART_SCHEME:
-           if (!pl.szScheme) return E_INVALIDARG;
+           if (!pl.szScheme || scheme == URL_SCHEME_UNKNOWN) {
+               *pcchOut = 0;
+               return S_FALSE;
+           }
            addr = pl.pScheme;
            size = pl.szScheme;
            break;
@@ -2121,55 +2130,76 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
             case URL_SCHEME_HTTPS:
                 break;
             default:
+                *pcchOut = 0;
                 return E_FAIL;
             }
 
             if(scheme==URL_SCHEME_FILE && (!pl.szHostName ||
                         (pl.szHostName==1 && *(pl.pHostName+1)==':'))) {
-                if(pcchOut)
-                    *pszOut = '\0';
                 *pcchOut = 0;
                 return S_FALSE;
             }
 
-           if (!pl.szHostName) return E_INVALIDARG;
+           if (!pl.szHostName) {
+               *pcchOut = 0;
+               return S_FALSE;
+           }
            addr = pl.pHostName;
            size = pl.szHostName;
            break;
 
        case URL_PART_USERNAME:
-           if (!pl.szUserName) return E_INVALIDARG;
+           if (!pl.szUserName) {
+               *pcchOut = 0;
+               return S_FALSE;
+           }
            addr = pl.pUserName;
            size = pl.szUserName;
            break;
 
        case URL_PART_PASSWORD:
-           if (!pl.szPassword) return E_INVALIDARG;
+           if (!pl.szPassword) {
+               *pcchOut = 0;
+               return S_FALSE;
+           }
            addr = pl.pPassword;
            size = pl.szPassword;
            break;
 
        case URL_PART_PORT:
-           if (!pl.szPort) return E_INVALIDARG;
+           if (!pl.szPort) {
+               *pcchOut = 0;
+               return S_FALSE;
+           }
            addr = pl.pPort;
            size = pl.szPort;
            break;
 
        case URL_PART_QUERY:
-           if (!pl.szQuery) return E_INVALIDARG;
+           if (!pl.szQuery) {
+               *pcchOut = 0;
+               return S_FALSE;
+           }
            addr = pl.pQuery;
            size = pl.szQuery;
            break;
 
        default:
+           *pcchOut = 0;
            return E_INVALIDARG;
        }
 
        if (dwFlags == URL_PARTFLAG_KEEPSCHEME) {
+            if(!pl.pScheme || !pl.szScheme) {
+                *pcchOut = 0;
+                return E_FAIL;
+            }
+            schaddr = pl.pScheme;
+            schsize = pl.szScheme;
             if (*pcchOut < schsize + size + 2) {
                 *pcchOut = schsize + size + 2;
-               return E_POINTER;
-           }
+                return E_POINTER;
+            }
             memcpy(pszOut, schaddr, schsize*sizeof(WCHAR));
             pszOut[schsize] = ':';
             memcpy(pszOut+schsize+1, addr, size*sizeof(WCHAR));
@@ -2183,12 +2213,6 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
            *pcchOut = size;
        }
        TRACE("len=%d %s\n", *pcchOut, debugstr_w(pszOut));
-    }else if(dwPart==URL_PART_HOSTNAME && scheme==URL_SCHEME_FILE) {
-        if(*pcchOut)
-            *pszOut = '\0';
-        *pcchOut = 0;
-        return S_FALSE;
-    }
 
     return ret;
 }