Sync to Wine-0_9_5:
Jacek Caban <jacek@codeweavers.com>
- urlmon: URL with two slashes is valid.
- urlmon: Added GetSecurityId implementation.
- urlmon: Removed not used code.
- urlmon: Use pluggable protocol for file protocol.
Rolf Kalbermatter <rolf.kalbermatter@citeng.com>
- urlmon: Implement BindAsyncMoniker function.
Modified: trunk/reactos/lib/urlmon/binding.c
Modified: trunk/reactos/lib/urlmon/file.c
Modified: trunk/reactos/lib/urlmon/sec_mgr.c
Modified: trunk/reactos/lib/urlmon/umon.c
Modified: trunk/reactos/lib/urlmon/urlmon.spec

Modified: trunk/reactos/lib/urlmon/binding.c
--- trunk/reactos/lib/urlmon/binding.c	2006-01-06 20:35:12 UTC (rev 20626)
+++ trunk/reactos/lib/urlmon/binding.c	2006-01-06 20:42:46 UTC (rev 20627)
@@ -225,6 +225,16 @@
         memcpy(This->mime, szStatusText, len*sizeof(WCHAR));
         break;
     }
+    case BINDSTATUS_SENDINGREQUEST:
+        IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_SENDINGREQUEST,
+                                       szStatusText);
+        break;
+    case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
+        IBindStatusCallback_OnProgress(This->callback, 0, 0,
+                                       BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
+        break;
+    case BINDSTATUS_CACHEFILENAMEAVAILABLE:
+        break;
     default:
         FIXME("Unhandled status code %ld\n", ulStatusCode);
         return E_NOTIMPL;
@@ -438,6 +448,8 @@
     int len;
     HRESULT hres;
 
+    static const WCHAR wszFile[] = {'f','i','l','e',':'};
+
     if(!IsEqualGUID(&IID_IStream, riid)) {
         FIXME("Unsupported riid %s\n", debugstr_guid(riid));
         return E_NOTIMPL;
@@ -483,9 +495,13 @@
         return hres;
     }
 
-    ret->bindf |= (BINDF_FROMURLMON|BINDF_NEEDFILE);
+    ret->bindf |= BINDF_FROMURLMON;
 
     len = strlenW(url)+1;
+
+    if(len < sizeof(wszFile)/sizeof(WCHAR) || memcmp(wszFile, url, sizeof(wszFile)))
+        ret->bindf |= BINDF_NEEDFILE;
+
     ret->url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
     memcpy(ret->url, url, len*sizeof(WCHAR));
 

Modified: trunk/reactos/lib/urlmon/file.c
--- trunk/reactos/lib/urlmon/file.c	2006-01-06 20:35:12 UTC (rev 20626)
+++ trunk/reactos/lib/urlmon/file.c	2006-01-06 20:42:46 UTC (rev 20627)
@@ -145,8 +145,10 @@
         IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
 
         file_name = url+sizeof(wszFile)/sizeof(WCHAR);
-        if(file_name[0] == '/' && file_name[1] == '/' && file_name[2] == '/')
-            file_name += 3;
+        if(file_name[0] == '/' && file_name[1] == '/')
+            file_name += 2;
+        if(*file_name == '/')
+            file_name++;
 
         This->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
                                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

Modified: trunk/reactos/lib/urlmon/sec_mgr.c
--- trunk/reactos/lib/urlmon/sec_mgr.c	2006-01-06 20:35:12 UTC (rev 20626)
+++ trunk/reactos/lib/urlmon/sec_mgr.c	2006-01-06 20:42:46 UTC (rev 20627)
@@ -109,7 +109,7 @@
     size = sizeof(DWORD);
     res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
     if(res == ERROR_SUCCESS)
-                            return S_OK;
+        return S_OK;
 
     *zone = 3;
     return S_OK;
@@ -268,16 +268,18 @@
 }
 
 static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface, 
-                                                   LPCWSTR pwszUrl,
-                                                   BYTE *pbSecurityId, DWORD *pcbSecurityId,
-                                                   DWORD_PTR dwReserved)
+        LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
 {
     SecManagerImpl *This = SECMGR_THIS(iface);
+    LPWSTR buf, ptr, ptr2;
+    DWORD size, zone, len;
     HRESULT hres;
 
-    TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId, pcbSecurityId,
-          dwReserved);
+    static const WCHAR wszFile[] = {'f','i','l','e',':'};
 
+    TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId,
+          pcbSecurityId, dwReserved);
+
     if(This->custom_manager) {
         hres = IInternetSecurityManager_GetSecurityId(This->custom_manager,
                 pwszUrl, pbSecurityId, pcbSecurityId, dwReserved);
@@ -285,8 +287,65 @@
             return hres;
     }
 
-    FIXME("Default action is not implemented\n");
-    return E_NOTIMPL;
+    if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
+        return E_INVALIDARG;
+
+    if(dwReserved)
+        FIXME("dwReserved is not supported\n");
+
+    len = strlenW(pwszUrl)+1;
+    buf = HeapAlloc(GetProcessHeap(), 0, (len+16)*sizeof(WCHAR));
+
+    hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0);
+    if(FAILED(hres))
+        memcpy(buf, pwszUrl, len*sizeof(WCHAR));
+
+    hres = map_url_to_zone(buf, &zone);
+    if(FAILED(hres)) {
+        HeapFree(GetProcessHeap(), 0, buf);
+        return hres == 0x80041001 ? E_INVALIDARG : hres;
+    }
+
+    /* file protocol is a special case */
+    if(strlenW(pwszUrl) >= sizeof(wszFile)/sizeof(WCHAR)
+            && !memcmp(buf, wszFile, sizeof(wszFile))) {
+
+        static const BYTE secidFile[] = {'f','i','l','e',':'};
+
+        if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
+            return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+
+        memcpy(pbSecurityId, secidFile, sizeof(secidFile));
+        *(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone;
+
+        *pcbSecurityId = sizeof(secidFile)+sizeof(zone);
+        return S_OK;
+    }
+
+    ptr = strchrW(buf, ':');
+    ptr2 = ++ptr;
+    while(*ptr2 == '/')
+        ptr2++;
+    if(ptr2 != ptr)
+        memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
+
+    ptr = strchrW(ptr, '/');
+    if(ptr)
+        *ptr = 0;
+
+    len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1;
+
+    if(len+sizeof(DWORD) > *pcbSecurityId)
+        return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+
+    WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL);
+    HeapFree(GetProcessHeap(), 0, buf);
+
+    *(DWORD*)(pbSecurityId+len) = zone;
+
+    *pcbSecurityId = len+sizeof(DWORD);
+
+    return S_OK;
 }
 
 

Modified: trunk/reactos/lib/urlmon/umon.c
--- trunk/reactos/lib/urlmon/umon.c	2006-01-06 20:35:12 UTC (rev 20626)
+++ trunk/reactos/lib/urlmon/umon.c	2006-01-06 20:42:46 UTC (rev 20627)
@@ -3,6 +3,7 @@
  *
  * Copyright 1999 Ulrich Czekalla for Corel Corporation
  * Copyright 2002 Huw D M Davies for CodeWeavers
+ * Copyright 2005 Jacek Caban for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -496,55 +497,6 @@
     return E_NOTIMPL;
 }
 
-typedef struct {
-    enum {OnProgress, OnDataAvailable} callback;
-} URLMON_CallbackData;
-
-
-#if 0
-static LRESULT CALLBACK URLMON_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
-{
-    return DefWindowProcA(hwnd, msg, wparam, lparam);
-}
-
-static void PostOnProgress(URLMonikerImpl *This, UINT progress, UINT maxprogress, DWORD status, LPCWSTR *str)
-{
-}
-
-static void CALLBACK URLMON_InternetCallback(HINTERNET hinet, /*DWORD_PTR*/ DWORD context, DWORD status,
-					     void *status_info, DWORD status_info_len)
-{
-    URLMonikerImpl *This = (URLMonikerImpl *)context;
-    TRACE("handle %p this %p status %08lx\n", hinet, This, status);
-
-    if(This->filesize == -1) {
-	switch(status) {
-	case INTERNET_STATUS_RESOLVING_NAME:
-	    PostOnProgess(This, 0, 0, BINDSTATUS_FINDINGRESOURCE, status_info);
-	    break;
-	case INTERNET_STATUS_CONNECTING_TO_SERVER:
-	    PostOnProgress(This, 0, 0, BINDSTATUS_CONNECTING, NULL);
-	    break;
-	case INTERNET_STATUS_SENDING_REQUEST:
-	    PostOnProgress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL);
-	    break;
-	case INTERNET_REQUEST_COMPLETE:
-	  {
-	      DWORD len, lensz = sizeof(len);
-
-	    HttpQueryInfoW(hrequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &len, &lensz, NULL);
-	    TRACE("res = %ld gle = %08lx url len = %ld\n", hres, GetLastError(), len);
-	    This->filesize = len;
-	    break;
-	  }
-	}
-    }
-
-    return;
-}
-#endif
-
-
 /******************************************************************************
  *        URLMoniker_BindToStorage
  ******************************************************************************/
@@ -601,7 +553,7 @@
             if(SUCCEEDED(hres)) {
                 WCHAR *urlcopy, *tmpwc;
                 URL_COMPONENTSW url;
-                WCHAR *host, *path, *partial_path, *user, *pass;
+                WCHAR *host, *path, *user, *pass;
                 DWORD lensz = sizeof(bind->expected_size);
                 DWORD dwService = 0;
                 BOOL bSuccess;
@@ -622,17 +574,6 @@
                     if (*tmpwc == '\\')
                             *tmpwc = '/';
 
-#if 0
-                if(!registered_wndclass) {
-                    WNDCLASSA urlmon_wndclass = {0, URLMON_WndProc,0, 0, URLMON_hInstance, 0, 0, 0, NULL, "URLMON_Callback_Window_Class"};
-                    RegisterClassA(&urlmon_wndclass);
-                    registered_wndclass = TRUE;
-                }
-
-                This->hwndCallback = CreateWindowA("URLMON_Callback_Window_Class", NULL, 0, 0, 0, 0, 0, 0, 0,
-                                                   URLMON_hInstance, NULL);
-
-#endif
                 bind->expected_size = 0;
                 bind->total_read = 0;
 
@@ -667,15 +608,9 @@
                     pass = 0;
                 }
 
-                switch ((DWORD) url.nScheme)
-                {
-                case INTERNET_SCHEME_FTP:
-                case INTERNET_SCHEME_GOPHER:
-                case INTERNET_SCHEME_HTTP:
-                case INTERNET_SCHEME_HTTPS:
 
-                    bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0 /*INTERNET_FLAG_ASYNC*/);
-/*                  InternetSetStatusCallback(bind->hinternet, URLMON_InternetCallback);*/
+                do {
+                    bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0);
                     if (!bind->hinternet)
                     {
                             hres = HRESULT_FROM_WIN32(GetLastError());
@@ -797,48 +732,8 @@
             
                     InternetCloseHandle(bind->hconnect);
                     InternetCloseHandle(bind->hinternet);
-                    break;
+                } while(0);
 
-                case INTERNET_SCHEME_FILE:
-                    partial_path = bind->URLName + 5; /* Skip the "file:" part */
-                    if ((partial_path[0] != '/' && partial_path[0] != '\\') ||
-                        (partial_path[1] != '/' && partial_path[1] != '\\'))
-                    {
-                        hres = E_FAIL;
-                    }
-                    else
-                    {
-                        HANDLE h;
-
-                        partial_path += 2;
-                        if (partial_path[0] == '/' || partial_path[0] == '\\')
-                            ++partial_path;
-                        h = CreateFileW(partial_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-                        if (h == (HANDLE) HFILE_ERROR)
-                        {
-                            hres = HRESULT_FROM_WIN32(GetLastError());
-                        }
-                        else
-                        {
-                            char buf[4096];
-                            DWORD bufread;
-
-                            IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName);
-
-                            while (ReadFile(h, buf, sizeof(buf), &bufread, NULL) && bufread > 0)
-                                hres = Binding_MoreCacheData(bind, buf, bufread);
-
-                            CloseHandle(h);
-                            hres = S_OK;
-                        }
-                    }
-                        
-                    break;
-
-                default:
-                    FIXME("Unsupported URI scheme");
-                    break;
-                }
                 Binding_CloseCacheDownload(bind);
                 Binding_FinishedDownload(bind, hres);
 
@@ -880,8 +775,7 @@
     if(url.nScheme == INTERNET_SCHEME_HTTP
        || url.nScheme== INTERNET_SCHEME_HTTPS
        || url.nScheme== INTERNET_SCHEME_FTP
-       || url.nScheme == INTERNET_SCHEME_GOPHER
-       || url.nScheme == INTERNET_SCHEME_FILE)
+       || url.nScheme == INTERNET_SCHEME_GOPHER)
         return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, pmkToLeft, riid, ppvObject);
 
     TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject);
@@ -1198,9 +1092,20 @@
             HeapFree(GetProcessHeap(), 0, This->URLName);
             return hres;
         }
+    }else {
+        /* FIXME:
+         * We probably should use CoInternetParseUrl or something similar here.
+         */
+
+        static const WCHAR wszFile[] = {'f','i','l','e',':','/','/',};
+
+        /* file protocol is a special case */
+        if(sizeStr > sizeof(wszFile)/sizeof(WCHAR)
+                && !memcmp(lpszURLName, wszFile, sizeof(wszFile)))
+            UrlCanonicalizeW(lpszURLName, This->URLName, &sizeStr, URL_FILE_USE_PATHURL);
+        else
+            strcpyW(This->URLName,lpszURLName);
     }
-    else
-        strcpyW(This->URLName,lpszURLName);
 
     URLMON_LockModule();
 
@@ -1350,6 +1255,42 @@
 }
 
 /***********************************************************************
+ *           BindAsyncMoniker (URLMON.@)
+ *
+ * Bind a bind status callback to an asynchronous URL Moniker.
+ *
+ * PARAMS
+ *  pmk           [I] Moniker object to bind status callback to
+ *  grfOpt        [I] Options, seems not used
+ *  pbsc          [I] Status callback to bind
+ *  iidResult     [I] Interface to return
+ *  ppvResult     [O] Resulting asynchronous moniker object
+ *
+ * RETURNS
+ *    Success: S_OK.
+ *    Failure: E_INVALIDARG, if any argument is invalid, or
+ *             E_OUTOFMEMORY if memory allocation fails.
+ */
+HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback *pbsc, REFIID iidResult, LPVOID *ppvResult)
+{
+    LPBC pbc = NULL;
+    HRESULT hr = E_INVALIDARG;
+
+    if (pmk && ppvResult)
+    {
+        *ppvResult = NULL;
+
+        hr = CreateAsyncBindCtx(0, pbsc, NULL, &pbc);
+        if (hr == NOERROR)
+        {
+            hr = IMoniker_BindToObject(pmk, pbc, NULL, iidResult, ppvResult);
+            IBindCtx_Release(pbc);
+        }
+    }
+    return hr;
+}
+
+/***********************************************************************
  *           RegisterBindStatusCallback (URLMON.@)
  *
  * Register a bind status callback.

Modified: trunk/reactos/lib/urlmon/urlmon.spec
--- trunk/reactos/lib/urlmon/urlmon.spec	2006-01-06 20:35:12 UTC (rev 20626)
+++ trunk/reactos/lib/urlmon/urlmon.spec	2006-01-06 20:42:46 UTC (rev 20627)
@@ -7,7 +7,7 @@
 
 @ stub AsyncGetClassBits
 @ stub AsyncInstallDistributionUnit
-@ stub BindAsyncMoniker
+@ stdcall BindAsyncMoniker(ptr long ptr ptr ptr)
 @ stdcall CoGetClassObjectFromURL(ptr wstr long long wstr ptr long ptr ptr ptr)
 @ stub CoInstall
 @ stdcall CoInternetCombineUrl(wstr wstr long wstr long ptr long)