mshtml: Added ActiveX control creation implementation.
This commit is contained in:
parent
b00b8631a6
commit
0b046c94ac
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue