mshtml: Added ActiveX control creation implementation.

This commit is contained in:
Jacek Caban 2010-12-02 13:50:02 +01:00 committed by Alexandre Julliard
parent b00b8631a6
commit 0b046c94ac
3 changed files with 264 additions and 6 deletions

View File

@ -92,11 +92,190 @@ typedef struct _NPPluginFuncs {
NPP_LostFocusPtr lostfocus;
} NPPluginFuncs;
static nsIDOMElement *get_dom_element(NPP instance)
{
nsISupports *instance_unk = (nsISupports*)instance->ndata;
nsIPluginInstance *plugin_instance;
nsIPluginInstanceOwner *owner;
nsIPluginTagInfo *tag_info;
nsIDOMElement *elem;
nsresult nsres;
nsres = nsISupports_QueryInterface(instance_unk, &IID_nsIPluginInstance, (void**)&plugin_instance);
if(NS_FAILED(nsres))
return NULL;
nsres = nsIPluginInstance_GetOwner(plugin_instance, &owner);
nsIPluginInstance_Release(instance_unk);
if(NS_FAILED(nsres) || !owner)
return NULL;
nsres = nsISupports_QueryInterface(owner, &IID_nsIPluginTagInfo, (void**)&tag_info);
nsISupports_Release(owner);
if(NS_FAILED(nsres))
return NULL;
nsres = nsIPluginTagInfo_GetDOMElement(tag_info, &elem);
nsIPluginTagInfo_Release(tag_info);
if(NS_FAILED(nsres))
return NULL;
return elem;
}
static HTMLWindow *get_elem_window(nsIDOMElement *elem)
{
nsIDOMWindow *nswindow;
nsIDOMDocument *nsdoc;
HTMLWindow *window;
nsresult nsres;
nsres = nsIDOMElement_GetOwnerDocument(elem, &nsdoc);
if(NS_FAILED(nsres))
return NULL;
nswindow = get_nsdoc_window(nsdoc);
nsIDOMDocument_Release(nsdoc);
if(!nswindow)
return NULL;
window = nswindow_to_window(nswindow);
nsIDOMWindow_Release(nswindow);
return window;
}
static BOOL parse_classid(const PRUnichar *classid, CLSID *clsid)
{
const WCHAR *ptr;
unsigned len;
HRESULT hres;
static const PRUnichar clsidW[] = {'c','l','s','i','d',':'};
if(strncmpW(classid, clsidW, sizeof(clsidW)/sizeof(WCHAR)))
return FALSE;
ptr = classid + sizeof(clsidW)/sizeof(WCHAR);
len = strlenW(ptr);
if(len == 38) {
hres = CLSIDFromString(ptr, clsid);
}else if(len == 36) {
WCHAR buf[39];
buf[0] = '{';
memcpy(buf+1, ptr, len*sizeof(WCHAR));
buf[37] = '}';
buf[38] = 0;
hres = CLSIDFromString(buf, clsid);
}else {
return FALSE;
}
return SUCCEEDED(hres);
}
static BOOL get_elem_clsid(nsIDOMElement *elem, CLSID *clsid)
{
nsAString attr_str, val_str;
nsresult nsres;
BOOL ret = FALSE;
static const PRUnichar classidW[] = {'c','l','a','s','s','i','d',0};
nsAString_InitDepend(&attr_str, classidW);
nsAString_Init(&val_str, NULL);
nsres = nsIDOMElement_GetAttribute(elem, &attr_str, &val_str);
nsAString_Finish(&attr_str);
if(NS_SUCCEEDED(nsres)) {
const PRUnichar *val;
nsAString_GetData(&val_str, &val);
if(*val)
ret = parse_classid(val, clsid);
}else {
ERR("GetAttribute failed: %08x\n", nsres);
}
nsAString_Finish(&attr_str);
return ret;
}
static IUnknown *create_activex_object(HTMLWindow *window, nsIDOMElement *nselem)
{
IClassFactoryEx *cfex;
IClassFactory *cf;
IUnknown *obj;
DWORD policy;
CLSID guid;
HRESULT hres;
if(!get_elem_clsid(nselem, &guid)) {
WARN("Could not determine element CLSID\n");
return NULL;
}
TRACE("clsid %s\n", debugstr_guid(&guid));
policy = 0;
hres = IInternetHostSecurityManager_ProcessUrlAction(HOSTSECMGR(window->doc), URLACTION_ACTIVEX_RUN,
(BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0);
if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
WARN("ProcessUrlAction returned %08x %x\n", hres, policy);
return NULL;
}
hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
if(FAILED(hres))
return NULL;
hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
if(SUCCEEDED(hres)) {
FIXME("Use IClassFactoryEx\n");
IClassFactoryEx_Release(cfex);
}
hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
if(FAILED(hres))
return NULL;
return obj;
}
static NPError CDECL NPP_New(NPMIMEType pluginType, NPP instance, UINT16 mode, INT16 argc, char **argn,
char **argv, NPSavedData *saved)
{
FIXME("(%s %p %x %d %p %p %p)\n", debugstr_a(pluginType), instance, mode, argc, argn, argv, saved);
return NPERR_GENERIC_ERROR;
nsIDOMElement *nselem;
HTMLWindow *window;
IUnknown *obj;
NPError err = NPERR_NO_ERROR;
TRACE("(%s %p %x %d %p %p %p)\n", debugstr_a(pluginType), instance, mode, argc, argn, argv, saved);
nselem = get_dom_element(instance);
if(!nselem) {
ERR("Could not get DOM element\n");
return NPERR_GENERIC_ERROR;
}
window = get_elem_window(nselem);
if(!window) {
ERR("Could not get element's window object\n");
nsIDOMElement_Release(nselem);
return NPERR_GENERIC_ERROR;
}
obj = create_activex_object(window, nselem);
if(obj) {
FIXME("Embed objet %p\n", obj);
IUnknown_Release(obj);
}else {
err = NPERR_GENERIC_ERROR;
}
nsIDOMElement_Release(nselem);
return err;
}
static NPError CDECL NPP_Destroy(NPP instance, NPSavedData **save)

View File

@ -148,6 +148,8 @@ typedef nsISupports nsITransferable;
typedef nsISupports nsIDOMHTMLHeadElement;
typedef nsISupports nsIDOMFileList;
typedef nsISupports nsIControllers;
typedef nsISupports nsIPluginInstanceOwner;
typedef nsISupports nsIPluginStreamListener;
[
object,
@ -3018,3 +3020,76 @@ typedef struct _NPPrint {
NPEmbedPrint embedPrint;
} print;
} NPPrint;
typedef HRGN NPRegion;
[
object,
uuid(84994340-e120-4051-824f-d4ee8aef1a3e),
local
]
interface nsIPluginInstance : nsISupports
{
typedef void *JSContext;
typedef void *JSObject;
nsresult Initialize(nsIPluginInstanceOwner *aOwner, const char *aMIMEType);
nsresult Start();
nsresult Stop();
nsresult SetWindow(NPWindow *aWindow);
nsresult NewStreamToPlugin(nsIPluginStreamListener **aListener);
nsresult NewStreamFromPlugin(const char *aType, const char *aTarget, nsIOutputStream **aResult);
nsresult Print(NPPrint *aPlatformPrint);
nsresult HandleEvent(void *aEvent, PRInt16 *aHandled);
nsresult InvalidateRect(NPRect *aRect);
nsresult InvalidateRegion(NPRegion aRegion);
nsresult ForceRedraw();
nsresult GetMIMEType(const char **aValue);
nsresult GetJSContext(JSContext **aJSContext);
nsresult GetOwner(nsIPluginInstanceOwner **aOwner);
nsresult SetOwner(nsIPluginInstanceOwner *aOwner);
nsresult ShowStatus(const char *aMessage);
nsresult InvalidateOwner();
nsresult GetJSObject(JSContext *cx, JSObject **_retval);
nsresult GetFormValue(nsAString *aFormValue);
nsresult PushPopupsEnabledState(PRBool aEnabled);
nsresult PopPopupsEnabledState();
nsresult GetPluginAPIVersion(PRUint16 *aPluginAPIVersion);
nsresult DefineJavaProperties();
nsresult ShouldCache(PRBool *_retval);
nsresult IsWindowless(PRBool *_retval);
nsresult IsTransparent(PRBool *_retval);
nsresult GetValueFromPlugin(NPPVariable variable, void *aValue);
nsresult GetDrawingModel(PRInt32 *_retval);
}
[
object,
uuid(6d827df5-b5cd-416c-85cb-3cdd05c7aed1),
local
]
interface nsIPluginTagInfo : nsISupports
{
typedef enum {
nsPluginTagType_Unknown,
nsPluginTagType_Embed,
nsPluginTagType_Object,
nsPluginTagType_Applet
} nsPluginTagType;
nsresult GetAttributes(PRUint16 *aCount, const char ***aNames, const char ***aValues);
nsresult GetAttribute(const char *aName, const char **aResult);
nsresult GetTagType(nsPluginTagType *aTagType);
nsresult GetTagText(const char **aTagText);
nsresult GetParameters(PRUint16 *aCount, const char ***aNames, const char ***aValues);
nsresult GetParameter(const char *aName, const char **aResult);
nsresult GetDocumentBase(const char **aDocumentBase);
nsresult GetDocumentEncoding(const char **aDocumentEncoding);
nsresult GetAlignment(const char **aElignment);
nsresult GetWidth(PRUint32 *aWidth);
nsresult GetHeight(PRUint32 *aHeight);
nsresult GetBorderVertSpace(PRUint32 *aBorderVertSpace);
nsresult GetBorderHorizSpace(PRUint32 *aBorderHorizSpace);
nsresult GetUniqueID(PRUint32 *aUniqueID);
nsresult GetDOMElement(nsIDOMElement **aDOMElement);
}

View File

@ -659,7 +659,7 @@ static IHTMLDocument2 *create_document(void)
return doc;
}
static IHTMLDocument2 *create_doc(const char *str)
static IHTMLDocument2 *create_doc(const char *str, BOOL *b)
{
IHTMLDocument2 *doc;
MSG msg;
@ -669,7 +669,7 @@ static IHTMLDocument2 *create_doc(const char *str)
doc_load_string(doc, str);
do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
while((!doc_complete || (b && !*b)) && GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@ -690,9 +690,13 @@ static void test_object_ax(void)
{
IHTMLDocument2 *doc;
/*
* We pump messages until both document is loaded and plugin instance is created.
* Pumping until document is loaded should be enough, but Gecko loads plugins
* asynchronously and until we'll work around it, we need this hack.
*/
SET_EXPECT(CreateInstance);
doc = create_doc(object_ax_str);
todo_wine
doc = create_doc(object_ax_str, &called_CreateInstance);
CHECK_CALLED(CreateInstance);
release_doc(doc);