mshtml: Added QueryCustomPolicy implementation.
diff --git a/dlls/mshtml/secmgr.c b/dlls/mshtml/secmgr.c
index c9b1e46..be56e5d 100644
--- a/dlls/mshtml/secmgr.c
+++ b/dlls/mshtml/secmgr.c
@@ -27,6 +27,8 @@
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
+#include "objsafe.h"
+#include "activscp.h"
#include "wine/debug.h"
@@ -36,6 +38,10 @@
static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
+/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
+const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
+ {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
+
#define HOSTSECMGR_THIS(iface) DEFINE_THIS(HTMLDocumentNode, IInternetHostSecurityManager, iface)
static HRESULT WINAPI InternetHostSecurityManager_QueryInterface(IInternetHostSecurityManager *iface, REFIID riid, void **ppv)
@@ -78,12 +84,84 @@
pContext, cbContext, dwFlags, dwReserved);
}
+static DWORD confirm_safety(HTMLDocumentNode *This, const WCHAR *url, IUnknown *obj)
+{
+ DWORD policy, enabled_opts, supported_opts;
+ IObjectSafety *obj_safety;
+ HRESULT hres;
+
+ /* FIXME: Check URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY */
+
+ hres = IInternetSecurityManager_ProcessUrlAction(This->secmgr, url, URLACTION_SCRIPT_SAFE_ACTIVEX,
+ (BYTE*)&policy, sizeof(policy), NULL, 0, 0, 0);
+ if(FAILED(hres) || policy != URLPOLICY_ALLOW)
+ return URLPOLICY_DISALLOW;
+
+ hres = IUnknown_QueryInterface(obj, &IID_IObjectSafety, (void**)&obj_safety);
+ if(FAILED(hres))
+ return URLPOLICY_DISALLOW;
+
+ hres = IObjectSafety_GetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, &supported_opts, &enabled_opts);
+ if(SUCCEEDED(hres)) {
+ enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
+ if(supported_opts & INTERFACE_USES_SECURITY_MANAGER)
+ enabled_opts |= INTERFACE_USES_SECURITY_MANAGER;
+ hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts);
+ }
+ IObjectSafety_Release(obj_safety);
+ if(FAILED(hres))
+ return URLPOLICY_DISALLOW;
+
+ return URLPOLICY_ALLOW;
+}
+
static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHostSecurityManager *iface, REFGUID guidKey,
BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved)
{
HTMLDocumentNode *This = HOSTSECMGR_THIS(iface);
- FIXME("(%p)->(%s %p %p %p %d %x)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
- return E_NOTIMPL;
+ const WCHAR *url;
+ HRESULT hres;
+
+ TRACE("(%p)->(%s %p %p %p %d %x)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);
+
+ url = This->basedoc.doc_obj->url ? This->basedoc.doc_obj->url : about_blankW;
+
+ hres = IInternetSecurityManager_QueryCustomPolicy(This->secmgr, url, guidKey, ppPolicy, pcbPolicy,
+ pContext, cbContext, dwReserved);
+ if(hres != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
+ return hres;
+
+ if(IsEqualGUID(&GUID_CUSTOM_CONFIRMOBJECTSAFETY, guidKey)) {
+ IActiveScript *active_script;
+ struct CONFIRMSAFETY *cs;
+ DWORD policy;
+
+ if(cbContext != sizeof(struct CONFIRMSAFETY)) {
+ FIXME("wrong context size\n");
+ return E_FAIL;
+ }
+
+ cs = (struct CONFIRMSAFETY*)pContext;
+ hres = IUnknown_QueryInterface(cs->pUnk, &IID_IActiveScript, (void**)&active_script);
+ if(SUCCEEDED(hres)) {
+ FIXME("Got IAciveScript iface\n");
+ IActiveScript_Release(active_script);
+ return E_FAIL;
+ }
+
+ policy = confirm_safety(This, url, cs->pUnk);
+
+ *ppPolicy = CoTaskMemAlloc(sizeof(policy));
+ if(!*ppPolicy)
+ return E_OUTOFMEMORY;
+
+ *(DWORD*)*ppPolicy = policy;
+ *pcbPolicy = sizeof(policy);
+ return S_OK;
+ }
+
+ FIXME("Unknown guidKey %s\n", debugstr_guid(guidKey));
+ return hres;
}
#undef HOSTSECMGR_THIS
diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c
index 89b076c..5f59ea4 100644
--- a/dlls/mshtml/tests/script.c
+++ b/dlls/mshtml/tests/script.c
@@ -37,6 +37,10 @@
DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
+const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
+ {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
+
#ifdef _WIN64
#define CTXARG_T DWORDLONG
@@ -110,6 +114,10 @@
DEFINE_EXPECT(funcDisp);
DEFINE_EXPECT(script_testprop_d);
DEFINE_EXPECT(script_testprop_i);
+DEFINE_EXPECT(AXQueryInterface_IActiveScript);
+DEFINE_EXPECT(AXQueryInterface_IObjectSafety);
+DEFINE_EXPECT(AXGetInterfaceSafetyOptions);
+DEFINE_EXPECT(AXSetInterfaceSafetyOptions);
#define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
@@ -519,7 +527,7 @@
static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
- ok(0, "unexpected call\n");
+ ok(0, "unexpected call %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
@@ -573,11 +581,72 @@
static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl };
+static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ if(IsEqualGUID(&IID_IActiveScript, riid)) {
+ CHECK_EXPECT(AXQueryInterface_IActiveScript);
+ return E_NOINTERFACE;
+ }
+
+ if(IsEqualGUID(&IID_IObjectSafety, riid)) {
+ CHECK_EXPECT(AXQueryInterface_IObjectSafety);
+ *ppv = iface;
+ return S_OK;
+ }
+
+ ok(0, "unexpected call %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
+ DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
+{
+ CHECK_EXPECT(AXGetInterfaceSafetyOptions);
+
+ ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid));
+ ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
+ ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
+
+ *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
+ *pdwEnabledOptions = INTERFACE_USES_DISPEX;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
+ DWORD dwOptionSetMask, DWORD dwEnabledOptions)
+{
+ CHECK_EXPECT(AXSetInterfaceSafetyOptions);
+
+ ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid));
+
+ ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER),
+ "dwOptionSetMask=%x\n", dwOptionSetMask);
+ ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER),
+ "dwEnabledOptions=%x\n", dwOptionSetMask);
+
+ return S_OK;
+}
+
+static const IObjectSafetyVtbl AXObjectSafetyVtbl = {
+ AXObjectSafety_QueryInterface,
+ ObjectSafety_AddRef,
+ ObjectSafety_Release,
+ AXObjectSafety_GetInterfaceSafetyOptions,
+ AXObjectSafety_SetInterfaceSafetyOptions
+};
+
+static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl };
+
static void test_security(void)
{
IInternetHostSecurityManager *sec_mgr;
IServiceProvider *sp;
- DWORD policy;
+ DWORD policy, policy_size;
+ struct CONFIRMSAFETY cs;
+ BYTE *ppolicy;
HRESULT hres;
hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp);
@@ -593,6 +662,26 @@
ok(hres == S_OK, "ProcessUrlAction failed: %08x\n", hres);
ok(policy == URLPOLICY_ALLOW, "policy = %x\n", policy);
+ cs.clsid = CLSID_TestActiveX;
+ cs.pUnk = (IUnknown*)&AXObjectSafety;
+ cs.dwFlags = 0;
+
+ SET_EXPECT(AXQueryInterface_IActiveScript);
+ SET_EXPECT(AXQueryInterface_IObjectSafety);
+ SET_EXPECT(AXGetInterfaceSafetyOptions);
+ SET_EXPECT(AXSetInterfaceSafetyOptions);
+ hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
+ &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
+ CHECK_CALLED(AXQueryInterface_IActiveScript);
+ CHECK_CALLED(AXQueryInterface_IObjectSafety);
+ CHECK_CALLED(AXGetInterfaceSafetyOptions);
+ CHECK_CALLED(AXSetInterfaceSafetyOptions);
+
+ ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
+ ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
+ ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
+ CoTaskMemFree(ppolicy);
+
IInternetHostSecurityManager_Release(sec_mgr);
}