Commit fa1a9860 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

Rewrote FindMimeFromData to pass tests.

parent 157f9741
......@@ -207,9 +207,12 @@ static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.'
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','e',' ','f','i','l','e','.','j','p','g
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_tests[] = {
{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();
}
......@@ -1331,69 +1331,6 @@ HRESULT WINAPI CoInternetQueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption,
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.@)
*/
......
......@@ -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* pbindinfo)
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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment