From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 24 ++++++++++- dlls/mshtml/main.c | 66 +++++++++++++++++++++++++++++++ dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/documentmode.js | 1 + dlls/mshtml/tests/htmldoc.c | 19 +++++++++ 5 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index e3ef57ecfee..35d8a6ac0e7 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -1245,8 +1245,28 @@ static HRESULT WINAPI HTMLDocument_get_defaultCharset(IHTMLDocument2 *iface, BST static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p) { HTMLDocumentNode *This = impl_from_IHTMLDocument2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + const char *content_type; + WCHAR *content_typeW; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + *p = NULL; + + if(!This->window) { + FIXME("No window\n"); + return E_NOTIMPL; + } + + if(!This->window->bscallback || !(content_type = This->window->bscallback->nschannel->content_type)) + return E_FAIL; + + if(!(content_typeW = heap_strdupAtoW(content_type))) + return E_OUTOFMEMORY; + + hres = get_mime_type_display_name(content_typeW, p); + heap_free(content_typeW); + return hres; }
static HRESULT WINAPI HTMLDocument_get_fileSize(IHTMLDocument2 *iface, BSTR *p) diff --git a/dlls/mshtml/main.c b/dlls/mshtml/main.c index ae14137bc54..03cf0713ef4 100644 --- a/dlls/mshtml/main.c +++ b/dlls/mshtml/main.c @@ -48,6 +48,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+#define CHARS_IN_GUID 39 + HINSTANCE hInst; DWORD mshtml_tls = TLS_OUT_OF_INDEXES;
@@ -126,6 +128,70 @@ BSTR charset_string_from_cp(UINT cp) return SysAllocString(info.wszWebCharset); }
+HRESULT get_mime_type_display_name(const WCHAR *content_type, BSTR *ret) +{ + WCHAR buffer[128], *str; + WCHAR *const clsid_str = buffer + sizeof("CLSID\")-1; + DWORD type, size, len; + HKEY key, type_key; + LSTATUS status; + + status = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"MIME\Database\Content Type", 0, 0, &key); + if(status != ERROR_SUCCESS) + goto fail; + + RegOpenKeyExW(key, content_type, 0, KEY_QUERY_VALUE, &type_key); + RegCloseKey(key); + if(status != ERROR_SUCCESS) + goto fail; + + size = CHARS_IN_GUID * sizeof(WCHAR); + status = RegQueryValueExW(type_key, L"CLSID", NULL, &type, (BYTE*)clsid_str, &size); + RegCloseKey(type_key); + if(status != ERROR_SUCCESS || type != REG_SZ || size != CHARS_IN_GUID * sizeof(WCHAR) || + clsid_str[0] != '{' || clsid_str[CHARS_IN_GUID-2] != '}' || clsid_str[CHARS_IN_GUID-1]) + goto fail; + + memcpy(buffer, L"CLSID\", sizeof(L"CLSID\")-sizeof(WCHAR)); + status = RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_QUERY_VALUE, &key); + if(status != ERROR_SUCCESS) + goto fail; + + size = sizeof(buffer); + str = buffer; + for(;;) { + status = RegQueryValueExW(key, NULL, NULL, &type, (BYTE*)str, &size); + if(status == ERROR_SUCCESS && type == REG_SZ && size >= sizeof(WCHAR)) + break; + if(str != buffer) + heap_free(str); + if(status != ERROR_MORE_DATA) { + RegCloseKey(key); + goto fail; + } + if(!(str = heap_alloc(size))) { + RegCloseKey(key); + return E_OUTOFMEMORY; + } + } + RegCloseKey(key); + + len = size / sizeof(WCHAR); + len -= !str[len - 1]; + *ret = SysAllocStringLen(str, len); + if(str != buffer) + heap_free(str); + + return *ret ? S_OK : E_OUTOFMEMORY; + +fail: + WARN("Did not find MIME in database for %s\n", debugstr_w(content_type)); + + /* native seems to return "File" when it doesn't know the content type */ + *ret = SysAllocString(L"File"); + return *ret ? S_OK : E_OUTOFMEMORY; +} + IInternetSecurityManager *get_security_manager(void) { if(!security_manager) { diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 49393c977cc..c403b4efc54 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -1455,6 +1455,7 @@ extern void *call_thiscall_func; compat_mode_t get_max_compat_mode(IUri*) DECLSPEC_HIDDEN; UINT cp_from_charset_string(BSTR) DECLSPEC_HIDDEN; BSTR charset_string_from_cp(UINT) DECLSPEC_HIDDEN; +HRESULT get_mime_type_display_name(const WCHAR*,BSTR*) DECLSPEC_HIDDEN; HINSTANCE get_shdoclc(void) DECLSPEC_HIDDEN; void set_statustext(HTMLDocumentObj*,INT,LPCWSTR) DECLSPEC_HIDDEN; IInternetSecurityManager *get_security_manager(void) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index a9ff38d5781..3054ed920ab 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -311,6 +311,7 @@ sync_test("doc_props", function() { }
var v = document.documentMode; + ok(document.mimeType === "HTML Document", "mimeType = " + document.mimeType);
test_exposed("onstorage", v < 9); test_exposed("textContent", v >= 9); diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index 7764f256ab0..0758b23995d 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -7680,6 +7680,23 @@ static void test_QueryInterface(IHTMLDocument2 *htmldoc) IUnknown_Release(qi); }
+static void test_mimeType(IHTMLDocument2 *doc, const WCHAR *expected) +{ + BSTR mime_type = (BSTR)0xdeadbeef; + HRESULT hres; + + hres = IHTMLDocument2_get_mimeType(doc, &mime_type); + if(expected) { + ok(hres == S_OK, "get_mimeType returned %08lx\n", hres); + ok(!lstrcmpW(mime_type, expected), "mime type = %s, expected %s\n", + debugstr_w(mime_type), debugstr_w(expected)); + }else { + ok(hres == E_FAIL, "get_mimeType returned %08lx\n", hres); + ok(!mime_type, "mime type = %s, expected (null)\n", debugstr_w(mime_type)); + } + SysFreeString(mime_type); +} + static void init_test(enum load_state_t ls) { doc_unk = NULL; doc_hwnd = last_hwnd = NULL; @@ -7733,6 +7750,7 @@ static void test_HTMLDocument(BOOL do_load, BOOL mime) test_GetCurMoniker((IUnknown*)doc, &Moniker, NULL, FALSE); test_elem_from_point(doc); } + test_mimeType(doc, do_load ? L"HTML Document" : NULL);
test_MSHTML_QueryStatus(doc, OLECMDF_SUPPORTED); test_OleCommandTarget_fail(doc); @@ -7844,6 +7862,7 @@ static void test_MHTMLDocument(void) set_custom_uihandler(doc, &CustomDocHostUIHandler); test_GetCurMoniker((IUnknown*)doc, NULL, L"mhtml:winetest:doc", FALSE); test_download(0); + test_mimeType(doc, L"HTML Document");
test_exec_onunload(doc); test_UIDeactivate();