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