URLMON: FindMimeFromData rewrite

Jacek Caban jack at itma.pwr.wroc.pl
Mon Sep 12 08:52:01 CDT 2005


Changelog:
    Rewrote FindMimeFromData to pass tests
-------------- next part --------------
Index: dlls/urlmon/urlmon_main.c
===================================================================
RCS file: /home/wine/wine/dlls/urlmon/urlmon_main.c,v
retrieving revision 1.33
diff -u -p -r1.33 urlmon_main.c
--- dlls/urlmon/urlmon_main.c	8 Sep 2005 11:01:46 -0000	1.33
+++ dlls/urlmon/urlmon_main.c	12 Sep 2005 13:46:06 -0000
@@ -24,12 +24,13 @@
 
 #include "windef.h"
 #include "winbase.h"
-#include "winerror.h"
-#include "wtypes.h"
+#include "winreg.h"
+
 #define NO_SHLWAPI_REG
 #include "shlwapi.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 #include "winuser.h"
 #include "urlmon.h"
@@ -386,3 +387,94 @@ void WINAPI ReleaseBindInfo(BINDINFO* pb
     if(pbindinfo->pUnk)
         IUnknown_Release(pbindinfo->pUnk);
 }
+
+/***********************************************************************
+ *           FindMimeFromData (URLMON.@)
+ *
+ * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided.
+ */
+HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
+        DWORD cbSize, LPCWSTR pwzMimeProposed, DWORD dwMimeFlags,
+        LPWSTR* ppwzMimeOut, DWORD dwReserved)
+{
+    TRACE("(%p,%s,%p,%ld,%s,0x%lx,%p,0x%lx)\n", pBC, debugstr_w(pwzUrl), pBuffer, cbSize,
+            debugstr_w(pwzMimeProposed), dwMimeFlags, ppwzMimeOut, dwReserved);
+
+    if(dwMimeFlags)
+        WARN("dwMimeFlags=%08lx\n", dwMimeFlags);
+    if(dwReserved)
+        WARN("dwReserved=%ld\n", dwReserved);
+
+    /* pBC seams to not be used */
+
+    if(!ppwzMimeOut || (!pwzUrl && !pBuffer))
+        return E_INVALIDARG;
+
+    if(pwzMimeProposed && (!pwzUrl || !pBuffer || (pBuffer && !cbSize))) {
+        DWORD len;
+
+        if(!pwzMimeProposed)
+            return E_FAIL;
+
+        len = strlenW(pwzMimeProposed)+1;
+        *ppwzMimeOut = CoTaskMemAlloc(len*sizeof(WCHAR));
+        memcpy(*ppwzMimeOut, pwzMimeProposed, len*sizeof(WCHAR));
+        return S_OK;
+    }
+
+    if(pBuffer) {
+        UCHAR *ptr = pBuffer;
+        DWORD len;
+        LPCWSTR ret;
+
+        static const WCHAR wszAppOctetStream[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
+                'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
+        static const WCHAR wszTextPlain[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
+
+        if(!cbSize)
+            return E_FAIL;
+
+        ret = wszTextPlain;
+        for(ptr = pBuffer; ptr < (UCHAR*)pBuffer+cbSize-1; ptr++) {
+            if(*ptr < 0x20 && *ptr != '\n' && *ptr != '\r' && *ptr != '\t') {
+                ret = wszAppOctetStream;
+                break;
+            }
+        }
+
+        len = strlenW(ret)+1;
+        *ppwzMimeOut = CoTaskMemAlloc(len*sizeof(WCHAR));
+        memcpy(*ppwzMimeOut, ret, len*sizeof(WCHAR));
+        return S_OK;
+    }
+
+    if(pwzUrl) {
+        HKEY hkey;
+        DWORD res, size;
+        LPCWSTR ptr;
+        WCHAR mime[64];
+
+        static const WCHAR wszContentType[] =
+                {'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
+
+        ptr = strrchrW(pwzUrl, '.');
+        if(!ptr)
+            return E_FAIL;
+
+        res = RegOpenKeyW(HKEY_CLASSES_ROOT, ptr, &hkey);
+        if(res != ERROR_SUCCESS)
+            return E_FAIL;
+
+        size = sizeof(mime);
+        res = RegQueryValueExW(hkey, wszContentType, NULL, NULL, (LPBYTE)mime, &size);
+        RegCloseKey(hkey);
+        if(res != ERROR_SUCCESS)
+            return E_FAIL;
+
+        *ppwzMimeOut = CoTaskMemAlloc(size);
+        memcpy(*ppwzMimeOut, mime, size);
+        return S_OK;
+    }
+
+    return E_FAIL;
+}
Index: dlls/urlmon/umon.c
===================================================================
RCS file: /home/wine/wine/dlls/urlmon/umon.c,v
retrieving revision 1.63
diff -u -p -r1.63 umon.c
--- dlls/urlmon/umon.c	8 Sep 2005 11:01:46 -0000	1.63
+++ dlls/urlmon/umon.c	12 Sep 2005 13:46:07 -0000
@@ -1331,69 +1331,6 @@ HRESULT WINAPI CoInternetQueryInfo(LPCWS
   return S_OK;
 }
 
-static BOOL URLMON_IsBinary(LPVOID pBuffer, DWORD cbSize)
-{
-    unsigned int i, binarycount = 0;
-    unsigned char *buff = pBuffer;
-    for(i=0; i<cbSize; i++) {
-        if(buff[i] < 32)
-            binarycount++;
-    }
-    return binarycount > (cbSize-binarycount);
-}
-
-/***********************************************************************
- *           FindMimeFromData (URLMON.@)
- *
- * Determines the Multipurpose Internet Mail Extensions (MIME) type from the data provided.
- *
- * NOTE
- *  See http://msdn.microsoft.com/workshop/networking/moniker/overview/appendix_a.asp
- */
-HRESULT WINAPI FindMimeFromData(LPBC pBC, LPCWSTR pwzUrl, LPVOID pBuffer,
-   DWORD cbSize, LPCWSTR pwzMimeProposed, DWORD dwMimeFlags,
-   LPWSTR* ppwzMimeOut, DWORD dwReserved)
-{
-    static const WCHAR szBinaryMime[] = {'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m','\0'};
-    static const WCHAR szTextMime[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
-    static const WCHAR szContentType[] = {'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
-    WCHAR szTmpMime[256];
-    LPCWSTR mimeType = NULL;
-    HKEY hKey = NULL;
-
-    TRACE("(%p,%s,%p,%ld,%s,0x%lx,%p,0x%lx)\n", pBC, debugstr_w(pwzUrl), pBuffer, cbSize,
-          debugstr_w(pwzMimeProposed), dwMimeFlags, ppwzMimeOut, dwReserved);
-
-    if((!pwzUrl && (!pBuffer || cbSize <= 0)) || !ppwzMimeOut)
-        return E_INVALIDARG;
-
-    if(pwzMimeProposed)
-        mimeType = pwzMimeProposed;
-    else {
-        /* Try and find the mime type in the registry */
-        if(pwzUrl) {
-            LPWSTR ext = strrchrW(pwzUrl, '.');
-            if(ext) {
-                DWORD dwSize;
-                if(!RegOpenKeyExW(HKEY_CLASSES_ROOT, ext, 0, 0, &hKey)) {
-                    if(!RegQueryValueExW(hKey, szContentType, NULL, NULL, (LPBYTE)szTmpMime, &dwSize)) {
-                        mimeType = szTmpMime;
-                    }
-                    RegCloseKey(hKey);
-                }
-            }
-        }
-    }
-    if(!mimeType && pBuffer && cbSize > 0)
-        mimeType = URLMON_IsBinary(pBuffer, cbSize)?szBinaryMime:szTextMime;
-
-    TRACE("Using %s\n", debugstr_w(mimeType));
-    *ppwzMimeOut = CoTaskMemAlloc((lstrlenW(mimeType)+1)*sizeof(WCHAR));
-    if(!*ppwzMimeOut) return E_OUTOFMEMORY;
-    lstrcpyW(*ppwzMimeOut, mimeType);
-    return S_OK;
-}
-
 /***********************************************************************
  *           IsAsyncMoniker (URLMON.@)
  */
Index: dlls/urlmon/tests/misc.c
===================================================================
RCS file: /home/wine/wine/dlls/urlmon/tests/misc.c,v
retrieving revision 1.5
diff -u -p -r1.5 misc.c
--- dlls/urlmon/tests/misc.c	12 Sep 2005 10:10:52 -0000	1.5
+++ dlls/urlmon/tests/misc.c	12 Sep 2005 13:46:07 -0000
@@ -207,9 +207,12 @@ static const WCHAR url1[] = {'r','e','s'
 static const WCHAR url2[] = {'i','n','d','e','x','.','h','t','m',0};
 static const WCHAR url3[] = {'f','i','l','e',':','c',':','\\','I','n','d','e','x','.','h','t','m',0};
 static const WCHAR url4[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e',
-        '%','2','E','j','p','g',0};
+        '%','2','e','j','p','g',0};
 static const WCHAR url5[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
         '.','o','r','g',0};
+static const WCHAR url6[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
+static const WCHAR url7[] = {'f','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g','/',
+        'f','i','l','e','.','t','e','s','t',0};
 
 static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e',
         '.','j','p','g',0};
@@ -219,6 +222,8 @@ static const WCHAR path4[] = {'s','o','m
 
 static const WCHAR wszRes[] = {'r','e','s',0};
 static const WCHAR wszFile[] = {'f','i','l','e',0};
+static const WCHAR wszHttp[] = {'h','t','t','p',0};
+static const WCHAR wszAbout[] = {'a','b','o','u','t',0};
 static const WCHAR wszEmpty[] = {0};
 
 struct parse_test {
@@ -234,7 +239,9 @@ static const struct parse_test parse_tes
     {url1, S_OK,   url1,  E_INVALIDARG, NULL, wszRes},
     {url2, E_FAIL, url2,  E_INVALIDARG, NULL, wszEmpty},
     {url3, E_FAIL, url3,  S_OK, path3,        wszFile},
-    {url4, E_FAIL, url4e, S_OK, path4,        wszFile}
+    {url4, E_FAIL, url4e, S_OK, path4,        wszFile},
+    {url5, E_FAIL, url5,  E_INVALIDARG, NULL, wszHttp},
+    {url6, S_OK,   url6,  E_INVALIDARG, NULL, wszAbout}
 };
 
 static void test_CoInternetParseUrl(void)
@@ -267,7 +274,8 @@ static void test_CoInternetParseUrl(void
         memset(buf, 0xf0, sizeof(buf));
         hres = CoInternetParseUrl(parse_tests[i].url, PARSE_PATH_FROM_URL, 0, buf,
                 sizeof(buf)/sizeof(WCHAR), &size, 0);
-        ok(hres == parse_tests[i].path_hres, "[%d] path failed: %08lx\n", i, hres);
+        ok(hres == parse_tests[i].path_hres, "[%d] path failed: %08lx, expected %08lx\n",
+                i, hres, parse_tests[i].path_hres);
         if(parse_tests[i].path) {
             ok(size == lstrlenW(parse_tests[i].path), "[%d] wrong size\n", i);
             ok(!lstrcmpW(parse_tests[i].path, buf), "[%d] wrong path\n", i);
@@ -282,9 +290,129 @@ static void test_CoInternetParseUrl(void
     }
 }
 
+static const WCHAR mimeTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
+static const WCHAR mimeTextPlain[] = {'t','e','x','t','/','p','l','a','i','n',0};
+static const WCHAR mimeAppOctetStream[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
+    'o','c','t','e','t','-','s','t','r','e','a','m',0};
+
+static const struct {
+    LPCWSTR url;
+    LPCWSTR mime;
+} mime_tests[] = {
+    {url1, mimeTextHtml},
+    {url2, mimeTextHtml},
+    {url3, mimeTextHtml},
+    {url4, NULL},
+    {url5, NULL},
+    {url6, NULL},
+    {url7, NULL}
+};
+
+static BYTE data1[] = "test data\n";
+static BYTE data2[] = {31,'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0};
+static BYTE data3[] = {0,0,0};
+static BYTE data4[] = {'t','e','s',0xfa,'t',' ','d','a','t','a','\n',0,0};
+static BYTE data5[] = {0xa,0xa,0xa,'x',32,'x',0};
+static BYTE data6[] = {0xfa,0xfa,0xfa,0xfa,'\n','\r','\t','x','x','x',1};
+
+static const struct {
+    BYTE *data;
+    DWORD size;
+    LPCWSTR mime;
+} mime_tests2[] = {
+    {data1, sizeof(data1), mimeTextPlain},
+    {data2, sizeof(data2), mimeAppOctetStream},
+    {data3, sizeof(data3), mimeAppOctetStream},
+    {data4, sizeof(data4), mimeAppOctetStream},
+    {data5, sizeof(data5), mimeTextPlain},
+    {data6, sizeof(data6), mimeTextPlain}
+};
+
+static void test_FindMimeFromData(void)
+{
+    HRESULT hres;
+    LPWSTR mime;
+    int i;
+
+    for(i=0; i<sizeof(mime_tests)/sizeof(mime_tests[0]); i++) {
+        mime = (LPWSTR)0xf0f0f0f0;
+        hres = FindMimeFromData(NULL, mime_tests[i].url, NULL, 0, NULL, 0, &mime, 0);
+        if(mime_tests[i].mime) {
+            ok(hres == S_OK, "[%d] FindMimeFromData failed: %08lx\n", i, hres);
+            ok(!lstrcmpW(mime, mime_tests[i].mime), "[%d] wrong mime\n", i);
+            CoTaskMemFree(mime);
+        }else {
+            ok(hres == E_FAIL, "FindMimeFromData failed: %08lx, expected E_FAIL\n", hres);
+            ok(mime == (LPWSTR)0xf0f0f0f0, "[%d] mime != 0xf0f0f0f0\n", i);
+        }
+
+        mime = (LPWSTR)0xf0f0f0f0;
+        hres = FindMimeFromData(NULL, mime_tests[i].url, NULL, 0, mimeTextPlain, 0, &mime, 0);
+        ok(hres == S_OK, "[%d] FindMimeFromData failed: %08lx\n", i, hres);
+        ok(!lstrcmpW(mime, mimeTextPlain), "[%d] wrong mime\n", i);
+        CoTaskMemFree(mime);
+
+        mime = (LPWSTR)0xf0f0f0f0;
+        hres = FindMimeFromData(NULL, mime_tests[i].url, NULL, 0, mimeAppOctetStream, 0, &mime, 0);
+        ok(hres == S_OK, "[%d] FindMimeFromData failed: %08lx\n", i, hres);
+        ok(!lstrcmpW(mime, mimeAppOctetStream), "[%d] wrong mime\n", i);
+        CoTaskMemFree(mime);
+    }
+
+    for(i=0; i < sizeof(mime_tests2)/sizeof(mime_tests2[0]); i++) {
+        hres = FindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
+                NULL, 0, &mime, 0);
+        ok(hres == S_OK, "[%d] FindMimeFromData failed: %08lx\n", i, hres);
+        ok(!lstrcmpW(mime, mime_tests2[i].mime), "[%d] wrong mime\n", i);
+        CoTaskMemFree(mime);
+
+        hres = FindMimeFromData(NULL, NULL, mime_tests2[i].data, mime_tests2[i].size,
+                mimeTextHtml, 0, &mime, 0);
+        ok(hres == S_OK, "[%d] FindMimeFromData failed: %08lx\n", i, hres);
+        ok(!lstrcmpW(mime, mimeTextHtml), "[%d] wrong mime\n", i);
+        CoTaskMemFree(mime);
+    }
+
+    hres = FindMimeFromData(NULL, url1, data1, sizeof(data1), NULL, 0, &mime, 0);
+    ok(hres == S_OK, "FindMimeFromData failed: %08lx\n", hres);
+    ok(!lstrcmpW(mime, mimeTextPlain), "wrong mime\n");
+    CoTaskMemFree(mime);
+
+    hres = FindMimeFromData(NULL, url1, data1, sizeof(data1), mimeAppOctetStream, 0, &mime, 0);
+    ok(hres == S_OK, "FindMimeFromData failed: %08lx\n", hres);
+    ok(!lstrcmpW(mime, mimeTextPlain), "wrong mime\n");
+    CoTaskMemFree(mime);
+
+    hres = FindMimeFromData(NULL, url4, data1, sizeof(data1), mimeAppOctetStream, 0, &mime, 0);
+    ok(hres == S_OK, "FindMimeFromData failed: %08lx\n", hres);
+    ok(!lstrcmpW(mime, mimeTextPlain), "wrong mime\n");
+    CoTaskMemFree(mime);
+
+    hres = FindMimeFromData(NULL, NULL, NULL, 0, NULL, 0, &mime, 0);
+    ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08lx, excepted E_INVALIDARG\n", hres);
+
+    hres = FindMimeFromData(NULL, NULL, NULL, 0, mimeTextPlain, 0, &mime, 0);
+    ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08lx, expected E_INVALIDARG\n", hres);
+
+    hres = FindMimeFromData(NULL, NULL, data1, 0, NULL, 0, &mime, 0);
+    ok(hres == E_FAIL, "FindMimeFromData failed: %08lx, expected E_FAIL\n", hres);
+
+    hres = FindMimeFromData(NULL, url1, data1, 0, NULL, 0, &mime, 0);
+    ok(hres == E_FAIL, "FindMimeFromData failed: %08lx, expected E_FAIL\n", hres);
+
+    hres = FindMimeFromData(NULL, NULL, data1, 0, mimeTextPlain, 0, &mime, 0);
+    ok(hres == S_OK, "FindMimeFromData failed: %08lx\n", hres);
+    ok(!lstrcmpW(mime, mimeTextPlain), "wrong mime\n");
+    CoTaskMemFree(mime);
+
+    hres = FindMimeFromData(NULL, NULL, data1, 0, mimeTextPlain, 0, NULL, 0);
+    ok(hres == E_INVALIDARG, "FindMimeFromData failed: %08lx, expected E_INVALIDARG\n", hres);
+}
+
 START_TEST(misc)
 {
     test_CreateFormatEnum();
     test_RegisterFormatEnumerator();
     test_CoInternetParseUrl();
+    test_FindMimeFromData();
 }


More information about the wine-patches mailing list