[URLMON]
authorChristoph von Wittich <christoph_vw@reactos.org>
Sun, 30 May 2010 10:20:31 +0000 (10:20 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sun, 30 May 2010 10:20:31 +0000 (10:20 +0000)
sync to wine 1.2 RC2

svn path=/trunk/; revision=47438

reactos/dll/win32/urlmon/binding.c
reactos/dll/win32/urlmon/file.c
reactos/dll/win32/urlmon/umon.c
reactos/dll/win32/urlmon/uri.c
reactos/include/psdk/urlmon.idl

index dcf0207..e0f3624 100644 (file)
@@ -47,6 +47,7 @@ typedef struct {
     BYTE buf[1024*8];
     DWORD size;
     BOOL init;
+    HANDLE file;
     HRESULT hres;
 
     LPWSTR cache_file;
@@ -57,7 +58,7 @@ typedef struct _stgmed_obj_t stgmed_obj_t;
 typedef struct {
     void (*release)(stgmed_obj_t*);
     HRESULT (*fill_stgmed)(stgmed_obj_t*,STGMEDIUM*);
-    void *(*get_result)(stgmed_obj_t*);
+    HRESULT (*get_result)(stgmed_obj_t*,DWORD,void**);
 } stgmed_obj_vtbl;
 
 struct _stgmed_obj_t {
@@ -101,6 +102,7 @@ struct Binding {
     LPWSTR redirect_url;
     IID iid;
     BOOL report_mime;
+    BOOL use_cache_file;
     DWORD state;
     HRESULT hres;
     download_state_t download_state;
@@ -134,6 +136,20 @@ static void fill_stgmed_buffer(stgmed_buf_t *buf)
         buf->init = TRUE;
 }
 
+static void read_protocol_data(stgmed_buf_t *stgmed_buf)
+{
+    BYTE buf[8192];
+    DWORD read;
+    HRESULT hres;
+
+    fill_stgmed_buffer(stgmed_buf);
+    if(stgmed_buf->size < sizeof(stgmed_buf->buf))
+        return;
+
+    do hres = IInternetProtocol_Read(stgmed_buf->protocol, buf, sizeof(buf), &read);
+    while(hres == S_OK);
+}
+
 static void dump_BINDINFO(BINDINFO *bi)
 {
     static const char * const BINDINFOF_str[] = {
@@ -339,6 +355,19 @@ static void create_object(Binding *binding)
         IInternetProtocol_Terminate(binding->protocol, 0);
 }
 
+static void cache_file_available(Binding *This, const WCHAR *file_name)
+{
+    heap_free(This->stgmed_buf->cache_file);
+    This->stgmed_buf->cache_file = heap_strdupW(file_name);
+
+    if(This->use_cache_file) {
+        This->stgmed_buf->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if(This->stgmed_buf->file == INVALID_HANDLE_VALUE)
+            WARN("CreateFile failed: %u\n", GetLastError());
+    }
+}
+
 #define STGMEDUNK_THIS(iface) DEFINE_THIS(stgmed_buf_t, Unknown, iface)
 
 static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
@@ -377,6 +406,8 @@ static ULONG WINAPI StgMedUnk_Release(IUnknown *iface)
     TRACE("(%p) ref=%d\n", This, ref);
 
     if(!ref) {
+        if(This->file != INVALID_HANDLE_VALUE)
+            CloseHandle(This->file);
         IInternetProtocol_Release(This->protocol);
         heap_free(This->cache_file);
         heap_free(This);
@@ -403,6 +434,7 @@ static stgmed_buf_t *create_stgmed_buf(IInternetProtocol *protocol)
     ret->ref = 1;
     ret->size = 0;
     ret->init = FALSE;
+    ret->file = INVALID_HANDLE_VALUE;
     ret->hres = S_OK;
     ret->cache_file = NULL;
 
@@ -488,6 +520,15 @@ static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv,
 
     TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead);
 
+    if(This->buf->file != INVALID_HANDLE_VALUE) {
+        if (!ReadFile(This->buf->file, pv, cb, &read, NULL))
+            return INET_E_DOWNLOAD_FAILURE;
+
+        if(pcbRead)
+            *pcbRead = read;
+        return read ? S_OK : S_FALSE;
+    }
+
     if(This->buf->size) {
         read = cb;
 
@@ -637,12 +678,13 @@ static HRESULT stgmed_stream_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
     return S_OK;
 }
 
-static void *stgmed_stream_get_result(stgmed_obj_t *obj)
+static HRESULT stgmed_stream_get_result(stgmed_obj_t *obj, DWORD bindf, void **result)
 {
     ProtocolStream *stream = (ProtocolStream*)obj;
 
     IStream_AddRef(STREAM(stream));
-    return STREAM(stream);
+    *result = STREAM(stream);
+    return S_OK;
 }
 
 static const stgmed_obj_vtbl stgmed_stream_vtbl = {
@@ -689,16 +731,7 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
         return INET_E_DATA_NOT_AVAILABLE;
     }
 
-    fill_stgmed_buffer(file_obj->buf);
-    if(file_obj->buf->size == sizeof(file_obj->buf->buf)) {
-        BYTE buf[1024];
-        DWORD read;
-        HRESULT hres;
-
-        do {
-            hres = IInternetProtocol_Read(file_obj->buf->protocol, buf, sizeof(buf), &read);
-        }while(hres == S_OK);
-    }
+    read_protocol_data(file_obj->buf);
 
     stgmed->tymed = TYMED_FILE;
     stgmed->u.lpszFileName = file_obj->buf->cache_file;
@@ -707,9 +740,9 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
     return S_OK;
 }
 
-static void *stgmed_file_get_result(stgmed_obj_t *obj)
+static HRESULT stgmed_file_get_result(stgmed_obj_t *obj, DWORD bindf, void **result)
 {
-    return NULL;
+    return bindf & BINDF_ASYNCHRONOUS ? MK_S_ASYNCHRONOUS : S_OK;
 }
 
 static const stgmed_obj_vtbl stgmed_file_vtbl = {
@@ -987,8 +1020,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
         mime_available(This, szStatusText);
         break;
     case BINDSTATUS_CACHEFILENAMEAVAILABLE:
-        heap_free(This->stgmed_buf->cache_file);
-        This->stgmed_buf->cache_file = heap_strdupW(szStatusText);
+        cache_file_available(This, szStatusText);
         break;
     case BINDSTATUS_DECODING:
         IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText);
@@ -1019,9 +1051,12 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
     if(This->download_state == END_DOWNLOAD || (This->state & BINDING_STOPPED))
         return;
 
-    if(This->download_state == BEFORE_DOWNLOAD) {
+    if(This->stgmed_buf->file != INVALID_HANDLE_VALUE)
+        read_protocol_data(This->stgmed_buf);
+    else if(This->download_state == BEFORE_DOWNLOAD)
         fill_stgmed_buffer(This->stgmed_buf);
 
+    if(This->download_state == BEFORE_DOWNLOAD) {
         This->download_state = DOWNLOADING;
         sent_begindownloaddata = TRUE;
         IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
@@ -1430,8 +1465,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url,
     if(to_obj)
         ret->bindinfo.dwOptions |= 0x100000;
 
-    if(!is_urlmon_protocol(url))
+    if(!(ret->bindf & BINDF_ASYNCHRONOUS)) {
+        ret->bindf |= BINDF_NEEDFILE;
+        ret->use_cache_file = TRUE;
+    }else if(!is_urlmon_protocol(url)) {
         ret->bindf |= BINDF_NEEDFILE;
+    }
 
     ret->url = heap_strdupW(url);
 
@@ -1530,12 +1569,14 @@ HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
         if((binding->state & BINDING_STOPPED) && (binding->state & BINDING_LOCKED))
             IInternetProtocol_UnlockRequest(binding->protocol);
 
-        *ppv = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj);
+        hres = binding->stgmed_obj->vtbl->get_result(binding->stgmed_obj, binding->bindf, ppv);
+    }else {
+        hres = MK_S_ASYNCHRONOUS;
     }
 
     IBinding_Release(BINDING(binding));
 
-    return *ppv ? S_OK : MK_S_ASYNCHRONOUS;
+    return hres;
 }
 
 HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv)
index ed4802b..a517d94 100644 (file)
@@ -141,7 +141,10 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
         IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
 
         file_name = url+sizeof(wszFile)/sizeof(WCHAR);
-        if(file_name[0] == '/' && file_name[1] == '/')
+
+        /* Strip both forward and back slashes */
+        if( (file_name[0] == '/' && file_name[1] == '/') ||
+            (file_name[0] == '\\' && file_name[1] == '\\'))
             file_name += 2;
         if(*file_name == '/')
             file_name++;
index 5e6a8f6..7ce22cc 100644 (file)
@@ -513,6 +513,12 @@ HRESULT WINAPI CreateURLMonikerEx(IMoniker *pmkContext, LPCWSTR szURL, IMoniker
 
     TRACE("(%p, %s, %p, %08x)\n", pmkContext, debugstr_w(szURL), ppmk, dwFlags);
 
+    if (ppmk)
+        *ppmk = NULL;
+
+    if (!szURL || !ppmk)
+        return E_INVALIDARG;
+
     if (dwFlags & URL_MK_UNIFORM) FIXME("ignoring flag URL_MK_UNIFORM\n");
 
     if(!(obj = alloc_moniker()))
@@ -619,6 +625,9 @@ HRESULT WINAPI MkParseDisplayNameEx(IBindCtx *pbc, LPCWSTR szDisplayName, ULONG
 {
     TRACE("(%p %s %p %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk);
 
+    if (!pbc || !szDisplayName || !*szDisplayName || !pchEaten || !ppmk)
+        return E_INVALIDARG;
+
     if(is_registered_protocol(szDisplayName)) {
         HRESULT hres;
 
index 668aa9b..27b0863 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2010 Jacek Caban for CodeWeavers
+ * Copyright 2010 Thomas Mullaly
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -97,6 +98,20 @@ static HRESULT WINAPI Uri_GetPropertyDWORD(IUri *iface, Uri_PROPERTY uriProp, DW
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%d %p %x)\n", This, uriProp, pcchProperty, dwFlags);
+
+    if(!pcchProperty)
+        return E_INVALIDARG;
+
+    /* Microsoft's implementation for the ZONE property of a URI seems to be lacking...
+     * From what I can tell, instead of checking which URLZONE the URI belongs to it
+     * simply assigns URLZONE_INVALID and returns E_NOTIMPL. This also applies to the GetZone
+     * function.
+     */
+    if(uriProp == Uri_PROPERTY_ZONE) {
+        *pcchProperty = URLZONE_INVALID;
+        return E_NOTIMPL;
+    }
+
     return E_NOTIMPL;
 }
 
@@ -111,6 +126,10 @@ static HRESULT WINAPI Uri_GetAbsoluteUri(IUri *iface, BSTR *pstrAbsoluteUri)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrAbsoluteUri);
+
+    if(!pstrAbsoluteUri)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -118,6 +137,10 @@ static HRESULT WINAPI Uri_GetAuthority(IUri *iface, BSTR *pstrAuthority)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrAuthority);
+
+    if(!pstrAuthority)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -125,6 +148,10 @@ static HRESULT WINAPI Uri_GetDisplayUri(IUri *iface, BSTR *pstrDisplayUri)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrDisplayUri);
+
+    if(!pstrDisplayUri)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -132,6 +159,10 @@ static HRESULT WINAPI Uri_GetDomain(IUri *iface, BSTR *pstrDomain)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrDomain);
+
+    if(!pstrDomain)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -139,6 +170,10 @@ static HRESULT WINAPI Uri_GetExtension(IUri *iface, BSTR *pstrExtension)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrExtension);
+
+    if(!pstrExtension)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -146,6 +181,10 @@ static HRESULT WINAPI Uri_GetFragment(IUri *iface, BSTR *pstrFragment)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrFragment);
+
+    if(!pstrFragment)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -160,6 +199,10 @@ static HRESULT WINAPI Uri_GetPassword(IUri *iface, BSTR *pstrPassword)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrPassword);
+
+    if(!pstrPassword)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -167,6 +210,10 @@ static HRESULT WINAPI Uri_GetPath(IUri *iface, BSTR *pstrPath)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrPath);
+
+    if(!pstrPath)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -174,6 +221,10 @@ static HRESULT WINAPI Uri_GetPathAndQuery(IUri *iface, BSTR *pstrPathAndQuery)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrPathAndQuery);
+
+    if(!pstrPathAndQuery)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -181,6 +232,10 @@ static HRESULT WINAPI Uri_GetQuery(IUri *iface, BSTR *pstrQuery)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrQuery);
+
+    if(!pstrQuery)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -188,6 +243,10 @@ static HRESULT WINAPI Uri_GetRawUri(IUri *iface, BSTR *pstrRawUri)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrRawUri);
+
+    if(!pstrRawUri)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -195,6 +254,10 @@ static HRESULT WINAPI Uri_GetSchemeName(IUri *iface, BSTR *pstrSchemeName)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrSchemeName);
+
+    if(!pstrSchemeName)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -202,6 +265,10 @@ static HRESULT WINAPI Uri_GetUserInfo(IUri *iface, BSTR *pstrUserInfo)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrUserInfo);
+
+    if(!pstrUserInfo)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -209,6 +276,10 @@ static HRESULT WINAPI Uri_GetUserName(IUri *iface, BSTR *pstrUserName)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pstrUserName);
+
+    if(!pstrUserName)
+        return E_POINTER;
+
     return E_NOTIMPL;
 }
 
@@ -216,6 +287,10 @@ static HRESULT WINAPI Uri_GetHostType(IUri *iface, DWORD *pdwHostType)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pdwHostType);
+
+    if(!pdwHostType)
+        return E_INVALIDARG;
+
     return E_NOTIMPL;
 }
 
@@ -223,6 +298,10 @@ static HRESULT WINAPI Uri_GetPort(IUri *iface, DWORD *pdwPort)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pdwPort);
+
+    if(!pdwPort)
+        return E_INVALIDARG;
+
     return E_NOTIMPL;
 }
 
@@ -230,6 +309,10 @@ static HRESULT WINAPI Uri_GetScheme(IUri *iface, DWORD *pdwScheme)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pdwScheme);
+
+    if(!pdwScheme)
+        return E_INVALIDARG;
+
     return E_NOTIMPL;
 }
 
@@ -237,6 +320,14 @@ static HRESULT WINAPI Uri_GetZone(IUri *iface, DWORD *pdwZone)
 {
     Uri *This = URI_THIS(iface);
     FIXME("(%p)->(%p)\n", This, pdwZone);
+
+    if(!pdwZone)
+        return E_INVALIDARG;
+
+    /* Microsoft doesn't seem to have this implemented yet... See
+     * the comment in Uri_GetPropertyDWORD for more about this.
+     */
+    *pdwZone = URLZONE_INVALID;
     return E_NOTIMPL;
 }
 
@@ -296,6 +387,14 @@ HRESULT WINAPI CreateUri(LPCWSTR pwzURI, DWORD dwFlags, DWORD_PTR dwReserved, IU
 
     TRACE("(%s %x %x %p)\n", debugstr_w(pwzURI), dwFlags, (DWORD)dwReserved, ppURI);
 
+    if(!ppURI)
+        return E_INVALIDARG;
+
+    if(!pwzURI) {
+        *ppURI = NULL;
+        return E_INVALIDARG;
+    }
+
     ret = heap_alloc(sizeof(Uri));
     if(!ret)
         return E_OUTOFMEMORY;
index 2ab3b2b..c1d3bec 100644 (file)
@@ -1231,6 +1231,7 @@ interface IInternetZoneManager : IUnknown
 
     typedef enum tagURLZONE
     {
+        URLZONE_INVALID         = -1,
         URLZONE_PREDEFINED_MIN  = 0,
         URLZONE_LOCAL_MACHINE   = 0,
         URLZONE_INTRANET        = 1,
@@ -1563,6 +1564,15 @@ interface IUri : IUnknown
         Uri_PROPERTY_DWORD_LAST = Uri_PROPERTY_ZONE
     } Uri_PROPERTY;
 
+    typedef enum
+    {
+        Uri_HOST_UNKNOWN = 0,
+        Uri_HOST_DNS = 1,
+        Uri_HOST_IPV4 = 2,
+        Uri_HOST_IPV6 = 3,
+        Uri_HOST_IDN = 4
+    } Uri_HOST_TYPE;
+
     HRESULT GetPropertyBSTR(
         [in]  Uri_PROPERTY uriProp,
         [out] BSTR *pbstrProperty,