atl80: Added AtlComModuleRegisterServer implementation (based on AtlModuleRegisterSer...
[wine] / dlls / mshtml / npplugin.c
1 /*
2  * Copyright 2010 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
29 #include "shlobj.h"
30
31 #include "mshtml_private.h"
32 #include "pluginhost.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 /* Parts of npapi.h */
39
40 #define NP_VERSION_MAJOR 0
41 #define NP_VERSION_MINOR 25
42
43 typedef unsigned char NPBool;
44 typedef INT16 NPError;
45 typedef INT16 NPReason;
46 typedef char *NPMIMEType;
47
48 typedef struct _NPP {
49     void *pdata;
50     void *ndata;
51 } NPP_t, *NPP;
52
53 typedef struct _NPStream {
54     void *pdata;
55     void *ndata;
56     const char *url;
57     UINT32 end;
58     UINT32 lastmodified;
59     void *notifyData;
60     const char *headers;
61 } NPStream;
62
63 typedef struct _NPSavedData {
64     INT32 len;
65     void *buf;
66 } NPSavedData;
67
68 typedef struct _NPRect {
69     UINT16 top;
70     UINT16 left;
71     UINT16 bottom;
72     UINT16 right;
73 } NPRect;
74
75 typedef enum {
76     NPFocusNext = 0,
77     NPFocusPrevious = 1
78 } NPFocusDirection;
79
80 #define NP_ABI_MASK 0
81
82 typedef enum {
83     NPPVpluginNameString = 1,
84     NPPVpluginDescriptionString,
85     NPPVpluginWindowBool,
86     NPPVpluginTransparentBool,
87     NPPVjavaClass,
88     NPPVpluginWindowSize,
89     NPPVpluginTimerInterval,
90     NPPVpluginScriptableInstance = (10 | NP_ABI_MASK),
91     NPPVpluginScriptableIID = 11,
92     NPPVjavascriptPushCallerBool = 12,
93     NPPVpluginKeepLibraryInMemory = 13,
94     NPPVpluginNeedsXEmbed = 14,
95     NPPVpluginScriptableNPObject = 15,
96     NPPVformValue = 16,
97     NPPVpluginUrlRequestsDisplayedBool = 17,
98     NPPVpluginWantsAllNetworkStreams = 18,
99     NPPVpluginNativeAccessibleAtkPlugId = 19,
100     NPPVpluginCancelSrcStream = 20,
101     NPPVSupportsAdvancedKeyHandling = 21
102 } NPPVariable;
103
104 typedef enum {
105     NPNVxDisplay = 1,
106     NPNVxtAppContext,
107     NPNVnetscapeWindow,
108     NPNVjavascriptEnabledBool,
109     NPNVasdEnabledBool,
110     NPNVisOfflineBool,
111     NPNVserviceManager = (10 | NP_ABI_MASK),
112     NPNVDOMElement     = (11 | NP_ABI_MASK),
113     NPNVDOMWindow      = (12 | NP_ABI_MASK),
114     NPNVToolkit        = (13 | NP_ABI_MASK),
115     NPNVSupportsXEmbedBool = 14,
116     NPNVWindowNPObject = 15,
117     NPNVPluginElementNPObject = 16,
118     NPNVSupportsWindowless = 17,
119     NPNVprivateModeBool = 18,
120     NPNVsupportsAdvancedKeyHandling = 21
121 } NPNVariable;
122
123 typedef enum {
124     NPWindowTypeWindow = 1,
125     NPWindowTypeDrawable
126 } NPWindowType;
127
128 typedef struct _NPWindow {
129     void *window;
130     INT32 x;
131     INT32 y;
132     UINT32 width;
133     UINT32 height;
134     NPRect clipRect;
135     NPWindowType type;
136 } NPWindow;
137
138 typedef struct _NPFullPrint {
139     NPBool pluginPrinted;
140     NPBool printOne;
141     void *platformPrint;
142 } NPFullPrint;
143
144 typedef struct _NPEmbedPrint {
145     NPWindow window;
146     void *platformPrint;
147 } NPEmbedPrint;
148
149 typedef struct _NPPrint {
150     UINT16 mode;
151     union {
152         NPFullPrint fullPrint;
153         NPEmbedPrint embedPrint;
154     } print;
155 } NPPrint;
156
157 typedef HRGN NPRegion;
158
159 #define NPERR_BASE                         0
160 #define NPERR_NO_ERROR                    (NPERR_BASE + 0)
161 #define NPERR_GENERIC_ERROR               (NPERR_BASE + 1)
162 #define NPERR_INVALID_INSTANCE_ERROR      (NPERR_BASE + 2)
163 #define NPERR_INVALID_FUNCTABLE_ERROR     (NPERR_BASE + 3)
164 #define NPERR_MODULE_LOAD_FAILED_ERROR    (NPERR_BASE + 4)
165 #define NPERR_OUT_OF_MEMORY_ERROR         (NPERR_BASE + 5)
166 #define NPERR_INVALID_PLUGIN_ERROR        (NPERR_BASE + 6)
167 #define NPERR_INVALID_PLUGIN_DIR_ERROR    (NPERR_BASE + 7)
168 #define NPERR_INCOMPATIBLE_VERSION_ERROR  (NPERR_BASE + 8)
169 #define NPERR_INVALID_PARAM               (NPERR_BASE + 9)
170 #define NPERR_INVALID_URL                 (NPERR_BASE + 10)
171 #define NPERR_FILE_NOT_FOUND              (NPERR_BASE + 11)
172 #define NPERR_NO_DATA                     (NPERR_BASE + 12)
173 #define NPERR_STREAM_NOT_SEEKABLE         (NPERR_BASE + 13)
174
175 /* Parts of npfunctions.h */
176
177 typedef NPError (CDECL *NPP_NewProcPtr)(NPMIMEType,NPP,UINT16,INT16,char**,char**,NPSavedData*);
178 typedef NPError (CDECL *NPP_DestroyProcPtr)(NPP,NPSavedData**);
179 typedef NPError (CDECL *NPP_SetWindowProcPtr)(NPP,NPWindow*);
180 typedef NPError (CDECL *NPP_NewStreamProcPtr)(NPP,NPMIMEType,NPStream*,NPBool,UINT16*);
181 typedef NPError (CDECL *NPP_DestroyStreamProcPtr)(NPP,NPStream*,NPReason);
182 typedef INT32 (CDECL *NPP_WriteReadyProcPtr)(NPP,NPStream*);
183 typedef INT32 (CDECL *NPP_WriteProcPtr)(NPP,NPStream*,INT32,INT32,void*);
184 typedef void (CDECL *NPP_StreamAsFileProcPtr)(NPP,NPStream*,const char*);
185 typedef void (CDECL *NPP_PrintProcPtr)(NPP,NPPrint*);
186 typedef INT16 (CDECL *NPP_HandleEventProcPtr)(NPP,void*);
187 typedef void (CDECL *NPP_URLNotifyProcPtr)(NPP,const char*,NPReason,void*);
188 typedef NPError (CDECL *NPP_GetValueProcPtr)(NPP,NPPVariable,void*);
189 typedef NPError (CDECL *NPP_SetValueProcPtr)(NPP,NPNVariable,void*);
190 typedef NPBool (CDECL *NPP_GotFocusPtr)(NPP,NPFocusDirection);
191 typedef void (CDECL *NPP_LostFocusPtr)(NPP);
192
193 typedef struct _NPPluginFuncs {
194     UINT16 size;
195     UINT16 version;
196     NPP_NewProcPtr newp;
197     NPP_DestroyProcPtr destroy;
198     NPP_SetWindowProcPtr setwindow;
199     NPP_NewStreamProcPtr newstream;
200     NPP_DestroyStreamProcPtr destroystream;
201     NPP_StreamAsFileProcPtr asfile;
202     NPP_WriteReadyProcPtr writeready;
203     NPP_WriteProcPtr write;
204     NPP_PrintProcPtr print;
205     NPP_HandleEventProcPtr event;
206     NPP_URLNotifyProcPtr urlnotify;
207     void *javaClass;
208     NPP_GetValueProcPtr getvalue;
209     NPP_SetValueProcPtr setvalue;
210     NPP_GotFocusPtr gotfocus;
211     NPP_LostFocusPtr lostfocus;
212 } NPPluginFuncs;
213
214 static nsIDOMElement *get_dom_element(NPP instance)
215 {
216     nsISupports *instance_unk = (nsISupports*)instance->ndata;
217     nsIPluginInstance *plugin_instance;
218     nsIDOMElement *elem;
219     nsresult nsres;
220
221     nsres = nsISupports_QueryInterface(instance_unk, &IID_nsIPluginInstance, (void**)&plugin_instance);
222     if(NS_FAILED(nsres)) {
223         ERR("Could not get nsIPluginInstance interface: %08x\n", nsres);
224         return NULL;
225     }
226
227     nsres = nsIPluginInstance_GetDOMElement(plugin_instance, &elem);
228     nsIPluginInstance_Release(plugin_instance);
229     if(NS_FAILED(nsres)) {
230         ERR("GetDOMElement failed: %08x\n", nsres);
231         return NULL;
232     }
233
234     return elem;
235 }
236
237 static HTMLInnerWindow *get_elem_window(nsIDOMElement *elem)
238 {
239     nsIDOMWindow *nswindow;
240     nsIDOMDocument *nsdoc;
241     HTMLOuterWindow *window;
242     nsresult nsres;
243
244     nsres = nsIDOMElement_GetOwnerDocument(elem, &nsdoc);
245     if(NS_FAILED(nsres))
246         return NULL;
247
248     nsres = nsIDOMDocument_GetDefaultView(nsdoc, &nswindow);
249     nsIDOMDocument_Release(nsdoc);
250     if(NS_FAILED(nsres) || !nswindow)
251         return NULL;
252
253     window = nswindow_to_window(nswindow);
254     nsIDOMWindow_Release(nswindow);
255
256     return window->base.inner_window;
257 }
258
259 static BOOL parse_classid(const PRUnichar *classid, CLSID *clsid)
260 {
261     const WCHAR *ptr;
262     unsigned len;
263     HRESULT hres;
264
265     static const PRUnichar clsidW[] = {'c','l','s','i','d',':'};
266
267     if(strncmpiW(classid, clsidW, sizeof(clsidW)/sizeof(WCHAR)))
268         return FALSE;
269
270     ptr = classid + sizeof(clsidW)/sizeof(WCHAR);
271     len = strlenW(ptr);
272
273     if(len == 38) {
274         hres = CLSIDFromString(ptr, clsid);
275     }else if(len == 36) {
276         WCHAR buf[39];
277
278         buf[0] = '{';
279         memcpy(buf+1, ptr, len*sizeof(WCHAR));
280         buf[37] = '}';
281         buf[38] = 0;
282         hres = CLSIDFromString(buf, clsid);
283     }else {
284         return FALSE;
285     }
286
287     return SUCCEEDED(hres);
288 }
289
290 static BOOL get_elem_clsid(nsIDOMElement *elem, CLSID *clsid)
291 {
292     nsAString attr_str, val_str;
293     nsresult nsres;
294     BOOL ret = FALSE;
295
296     static const PRUnichar classidW[] = {'c','l','a','s','s','i','d',0};
297
298     nsAString_InitDepend(&attr_str, classidW);
299     nsAString_Init(&val_str, NULL);
300     nsres = nsIDOMElement_GetAttribute(elem, &attr_str, &val_str);
301     nsAString_Finish(&attr_str);
302     if(NS_SUCCEEDED(nsres)) {
303         const PRUnichar *val;
304
305         nsAString_GetData(&val_str, &val);
306         if(*val)
307             ret = parse_classid(val, clsid);
308     }else {
309         ERR("GetAttribute failed: %08x\n", nsres);
310     }
311
312     nsAString_Finish(&attr_str);
313     return ret;
314 }
315
316 typedef struct {
317     IBindStatusCallback IBindStatusCallback_iface;
318     IWindowForBindingUI IWindowForBindingUI_iface;
319     LONG ref;
320 } InstallCallback;
321
322 static inline InstallCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
323 {
324     return CONTAINING_RECORD(iface, InstallCallback, IBindStatusCallback_iface);
325 }
326
327 static HRESULT WINAPI InstallCallback_QueryInterface(IBindStatusCallback *iface,
328         REFIID riid, void **ppv)
329 {
330     InstallCallback *This = impl_from_IBindStatusCallback(iface);
331
332     if(IsEqualGUID(&IID_IUnknown, riid)) {
333         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
334         *ppv = &This->IBindStatusCallback_iface;
335     }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
336         TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
337         *ppv = &This->IBindStatusCallback_iface;
338     }else if(IsEqualGUID(&IID_IWindowForBindingUI, riid)) {
339         TRACE("(%p)->(IID_IWindowForBindingUI %p)\n", This, ppv);
340         *ppv = &This->IWindowForBindingUI_iface;
341     }else {
342         TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
343         *ppv = NULL;
344         return E_NOINTERFACE;
345     }
346
347     IUnknown_AddRef((IUnknown*)*ppv);
348     return S_OK;
349 }
350
351 static ULONG WINAPI InstallCallback_AddRef(IBindStatusCallback *iface)
352 {
353     InstallCallback *This = impl_from_IBindStatusCallback(iface);
354     LONG ref = InterlockedIncrement(&This->ref);
355
356     TRACE("(%p) ref=%d\n", This, ref);
357
358     return ref;
359 }
360
361 static ULONG WINAPI InstallCallback_Release(IBindStatusCallback *iface)
362 {
363     InstallCallback *This = impl_from_IBindStatusCallback(iface);
364     LONG ref = InterlockedIncrement(&This->ref);
365
366     TRACE("(%p) ref=%d\n", This, ref);
367
368     if(!ref)
369         heap_free(This);
370
371     return ref;
372 }
373
374 static HRESULT WINAPI InstallCallback_OnStartBinding(IBindStatusCallback *iface,
375         DWORD dwReserved, IBinding *pib)
376 {
377     InstallCallback *This = impl_from_IBindStatusCallback(iface);
378     TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
379     return S_OK;
380 }
381
382 static HRESULT WINAPI InstallCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
383 {
384     InstallCallback *This = impl_from_IBindStatusCallback(iface);
385     TRACE("(%p)->(%p)\n", This, pnPriority);
386     return E_NOTIMPL;
387 }
388
389 static HRESULT WINAPI InstallCallback_OnLowResource(IBindStatusCallback *iface, DWORD dwReserved)
390 {
391     InstallCallback *This = impl_from_IBindStatusCallback(iface);
392     TRACE("(%p)->(%x)\n", This, dwReserved);
393     return S_OK;
394 }
395
396 static HRESULT WINAPI InstallCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
397         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
398 {
399     InstallCallback *This = impl_from_IBindStatusCallback(iface);
400     TRACE("(%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
401     return S_OK;
402 }
403
404 static HRESULT WINAPI InstallCallback_OnStopBinding(IBindStatusCallback *iface,
405         HRESULT hresult, LPCWSTR szError)
406 {
407     InstallCallback *This = impl_from_IBindStatusCallback(iface);
408     TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
409     return S_OK;
410 }
411
412 static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
413         DWORD* grfBINDF, BINDINFO* pbindinfo)
414 {
415     InstallCallback *This = impl_from_IBindStatusCallback(iface);
416
417     TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
418
419     *grfBINDF = BINDF_ASYNCHRONOUS;
420     return S_OK;
421 }
422
423 static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
424         DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
425 {
426     InstallCallback *This = impl_from_IBindStatusCallback(iface);
427     ERR("(%p)\n", This);
428     return E_NOTIMPL;
429 }
430
431 static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
432         REFIID riid, IUnknown* punk)
433 {
434     InstallCallback *This = impl_from_IBindStatusCallback(iface);
435     ERR("(%p)\n", This);
436     return E_NOTIMPL;
437 }
438
439 static IBindStatusCallbackVtbl InstallCallbackVtbl = {
440     InstallCallback_QueryInterface,
441     InstallCallback_AddRef,
442     InstallCallback_Release,
443     InstallCallback_OnStartBinding,
444     InstallCallback_GetPriority,
445     InstallCallback_OnLowResource,
446     InstallCallback_OnProgress,
447     InstallCallback_OnStopBinding,
448     InstallCallback_GetBindInfo,
449     InstallCallback_OnDataAvailable,
450     InstallCallback_OnObjectAvailable
451 };
452
453 static inline InstallCallback *impl_from_IWindowForBindingUI(IWindowForBindingUI *iface)
454 {
455     return CONTAINING_RECORD(iface, InstallCallback, IWindowForBindingUI_iface);
456 }
457
458 static HRESULT WINAPI WindowForBindingUI_QueryInterface(IWindowForBindingUI *iface, REFIID riid, void **ppv)
459 {
460     InstallCallback *This = impl_from_IWindowForBindingUI(iface);
461     return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
462 }
463
464 static ULONG WINAPI WindowForBindingUI_AddRef(IWindowForBindingUI *iface)
465 {
466     InstallCallback *This = impl_from_IWindowForBindingUI(iface);
467     return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
468 }
469
470 static ULONG WINAPI WindowForBindingUI_Release(IWindowForBindingUI *iface)
471 {
472     InstallCallback *This = impl_from_IWindowForBindingUI(iface);
473     return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
474 }
475
476 static HRESULT WINAPI WindowForBindingUI_GetWindow(IWindowForBindingUI *iface, REFGUID rguidReason, HWND *phwnd)
477 {
478     InstallCallback *This = impl_from_IWindowForBindingUI(iface);
479     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(rguidReason), phwnd);
480     *phwnd = NULL;
481     return S_OK;
482 }
483
484 static const IWindowForBindingUIVtbl WindowForBindingUIVtbl = {
485     WindowForBindingUI_QueryInterface,
486     WindowForBindingUI_AddRef,
487     WindowForBindingUI_Release,
488     WindowForBindingUI_GetWindow
489 };
490
491 typedef struct {
492     struct list entry;
493     IUri *uri;
494 } install_entry_t;
495
496 static struct list install_list = LIST_INIT(install_list);
497
498 static CRITICAL_SECTION cs_install_list;
499 static CRITICAL_SECTION_DEBUG cs_install_list_dbg =
500 {
501     0, 0, &cs_install_list,
502     { &cs_install_list_dbg.ProcessLocksList, &cs_install_list_dbg.ProcessLocksList },
503       0, 0, { (DWORD_PTR)(__FILE__ ": install_list") }
504 };
505 static CRITICAL_SECTION cs_install_list = { &cs_install_list_dbg, -1, 0, 0, 0, 0 };
506
507 static void install_codebase(const WCHAR *url)
508 {
509     InstallCallback *callback;
510     IBindCtx *bctx;
511     HRESULT hres;
512
513     callback = heap_alloc(sizeof(*callback));
514     if(!callback)
515         return;
516
517     callback->IBindStatusCallback_iface.lpVtbl = &InstallCallbackVtbl;
518     callback->IWindowForBindingUI_iface.lpVtbl = &WindowForBindingUIVtbl;
519     callback->ref = 1;
520
521     hres = CreateAsyncBindCtx(0, &callback->IBindStatusCallback_iface, NULL, &bctx);
522     IBindStatusCallback_Release(&callback->IBindStatusCallback_iface);
523     if(FAILED(hres))
524         return;
525
526     hres = AsyncInstallDistributionUnit(NULL, NULL, NULL, 0, 0, url, bctx, NULL, 0);
527     IBindCtx_Release(bctx);
528     if(FAILED(hres))
529         WARN("FAILED: %08x\n", hres);
530 }
531
532 static void check_codebase(HTMLInnerWindow *window, nsIDOMElement *nselem)
533 {
534     nsAString attr_str, val_str;
535     BOOL is_on_list = FALSE;
536     install_entry_t *iter;
537     IUri *uri = NULL;
538     nsresult nsres;
539     HRESULT hres;
540
541     static const PRUnichar codebaseW[] = {'c','o','d','e','b','a','s','e',0};
542
543     nsAString_InitDepend(&attr_str, codebaseW);
544     nsAString_Init(&val_str, NULL);
545     nsres = nsIDOMElement_GetAttribute(nselem, &attr_str, &val_str);
546     nsAString_Finish(&attr_str);
547     if(NS_SUCCEEDED(nsres)) {
548         const PRUnichar *val;
549
550         nsAString_GetData(&val_str, &val);
551         if(*val) {
552             hres = CoInternetCombineUrlEx(window->base.outer_window->uri, val, 0, &uri, 0);
553             if(FAILED(hres))
554                 uri = NULL;
555         }
556     }else {
557         ERR("GetAttribute failed: %08x\n", nsres);
558     }
559
560     nsAString_Finish(&attr_str);
561     if(!uri)
562         return;
563
564     EnterCriticalSection(&cs_install_list);
565
566     LIST_FOR_EACH_ENTRY(iter, &install_list, install_entry_t, entry) {
567         BOOL eq;
568
569         hres = IUri_IsEqual(uri, iter->uri, &eq);
570         if(SUCCEEDED(hres) && eq) {
571             TRACE("already proceeded\n");
572             is_on_list = TRUE;
573             break;
574         }
575     }
576
577     if(!is_on_list) {
578         iter = heap_alloc(sizeof(*iter));
579         if(iter) {
580             IUri_AddRef(uri);
581             iter->uri = uri;
582
583             list_add_tail(&install_list, &iter->entry);
584         }
585     }
586
587     LeaveCriticalSection(&cs_install_list);
588
589     if(!is_on_list) {
590         BSTR display_uri;
591
592         hres = IUri_GetDisplayUri(uri, &display_uri);
593         if(SUCCEEDED(hres)) {
594             install_codebase(display_uri);
595             SysFreeString(display_uri);
596         }
597     }
598
599     IUri_Release(uri);
600 }
601
602 static IUnknown *create_activex_object(HTMLInnerWindow *window, nsIDOMElement *nselem, CLSID *clsid)
603 {
604     IClassFactoryEx *cfex;
605     IClassFactory *cf;
606     IUnknown *obj;
607     DWORD policy;
608     HRESULT hres;
609
610     if(!get_elem_clsid(nselem, clsid)) {
611         WARN("Could not determine element CLSID\n");
612         return NULL;
613     }
614
615     TRACE("clsid %s\n", debugstr_guid(clsid));
616
617     policy = 0;
618     hres = IInternetHostSecurityManager_ProcessUrlAction(&window->doc->IInternetHostSecurityManager_iface,
619             URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy), (BYTE*)clsid, sizeof(GUID), 0, 0);
620     if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
621         WARN("ProcessUrlAction returned %08x %x\n", hres, policy);
622         return NULL;
623     }
624
625     hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
626     if(hres == REGDB_E_CLASSNOTREG)
627         check_codebase(window, nselem);
628     if(FAILED(hres))
629         return NULL;
630
631     hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
632     if(SUCCEEDED(hres)) {
633         FIXME("Use IClassFactoryEx\n");
634         IClassFactoryEx_Release(cfex);
635     }
636
637     hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
638     if(FAILED(hres))
639         return NULL;
640
641     return obj;
642 }
643
644 static NPError CDECL NPP_New(NPMIMEType pluginType, NPP instance, UINT16 mode, INT16 argc, char **argn,
645         char **argv, NPSavedData *saved)
646 {
647     nsIDOMElement *nselem;
648     HTMLInnerWindow *window;
649     IUnknown *obj;
650     CLSID clsid;
651     NPError err = NPERR_NO_ERROR;
652
653     TRACE("(%s %p %x %d %p %p %p)\n", debugstr_a(pluginType), instance, mode, argc, argn, argv, saved);
654
655     nselem = get_dom_element(instance);
656     if(!nselem) {
657         ERR("Could not get DOM element\n");
658         return NPERR_GENERIC_ERROR;
659     }
660
661     window = get_elem_window(nselem);
662     if(!window) {
663         ERR("Could not get element's window object\n");
664         nsIDOMElement_Release(nselem);
665         return NPERR_GENERIC_ERROR;
666     }
667
668     obj = create_activex_object(window, nselem, &clsid);
669     if(obj) {
670         PluginHost *host;
671         HRESULT hres;
672
673         hres = create_plugin_host(window->doc, nselem, obj, &clsid, &host);
674         nsIDOMElement_Release(nselem);
675         IUnknown_Release(obj);
676         if(SUCCEEDED(hres))
677             instance->pdata = host;
678         else
679             err = NPERR_GENERIC_ERROR;
680     }else {
681         err = NPERR_GENERIC_ERROR;
682     }
683
684     nsIDOMElement_Release(nselem);
685     return err;
686 }
687
688 static NPError CDECL NPP_Destroy(NPP instance, NPSavedData **save)
689 {
690     PluginHost *host = instance->pdata;
691
692     TRACE("(%p %p)\n", instance, save);
693
694     if(!host)
695         return NPERR_GENERIC_ERROR;
696
697     detach_plugin_host(host);
698     IOleClientSite_Release(&host->IOleClientSite_iface);
699     instance->pdata = NULL;
700     return NPERR_NO_ERROR;
701 }
702
703 static NPError CDECL NPP_SetWindow(NPP instance, NPWindow *window)
704 {
705     PluginHost *host = instance->pdata;
706     RECT pos_rect = {0, 0, window->width, window->height};
707
708     TRACE("(%p %p)\n", instance, window);
709
710     if(!host)
711         return NPERR_GENERIC_ERROR;
712
713     update_plugin_window(host, window->window, &pos_rect);
714     return NPERR_NO_ERROR;
715 }
716
717 static NPError CDECL NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, UINT16 *stype)
718 {
719     TRACE("\n");
720     return NPERR_GENERIC_ERROR;
721 }
722
723 static NPError CDECL NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
724 {
725     TRACE("\n");
726     return NPERR_GENERIC_ERROR;
727 }
728
729 static INT32 CDECL NPP_WriteReady(NPP instance, NPStream *stream)
730 {
731     TRACE("\n");
732     return NPERR_GENERIC_ERROR;
733 }
734
735 static INT32 CDECL NPP_Write(NPP instance, NPStream *stream, INT32 offset, INT32 len, void *buffer)
736 {
737     TRACE("\n");
738     return NPERR_GENERIC_ERROR;
739 }
740
741 static void CDECL NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
742 {
743     TRACE("\n");
744 }
745
746 static void CDECL NPP_Print(NPP instance, NPPrint *platformPrint)
747 {
748     FIXME("\n");
749 }
750
751 static INT16 CDECL NPP_HandleEvent(NPP instance, void *event)
752 {
753     TRACE("\n");
754     return NPERR_GENERIC_ERROR;
755 }
756
757 static void CDECL NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
758 {
759     TRACE("\n");
760 }
761
762 static NPError CDECL NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value)
763 {
764     TRACE("\n");
765     return NPERR_GENERIC_ERROR;
766 }
767
768 static NPError CDECL NPP_SetValue(NPP instance, NPNVariable variable, void *value)
769 {
770     TRACE("\n");
771     return NPERR_GENERIC_ERROR;
772 }
773
774 static NPBool CDECL NPP_GotFocus(NPP instance, NPFocusDirection direction)
775 {
776     FIXME("\n");
777     return NPERR_GENERIC_ERROR;
778 }
779
780 static void CDECL NPP_LostFocus(NPP instance)
781 {
782     FIXME("\n");
783 }
784
785 /***********************************************************************
786  *          NP_GetEntryPoints (mshtml.@)
787  */
788 NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* funcs)
789 {
790     TRACE("(%p)\n", funcs);
791
792     funcs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
793     funcs->newp = NPP_New;
794     funcs->destroy = NPP_Destroy;
795     funcs->setwindow = NPP_SetWindow;
796     funcs->newstream = NPP_NewStream;
797     funcs->destroystream = NPP_DestroyStream;
798     funcs->asfile = NPP_StreamAsFile;
799     funcs->writeready = NPP_WriteReady;
800     funcs->write = NPP_Write;
801     funcs->print = NPP_Print;
802     funcs->event = NPP_HandleEvent;
803     funcs->urlnotify = NPP_URLNotify;
804     funcs->javaClass = NULL;
805     funcs->getvalue = NPP_GetValue;
806     funcs->setvalue = NPP_SetValue;
807     funcs->gotfocus = NPP_GotFocus;
808     funcs->lostfocus = NPP_LostFocus;
809
810     return NPERR_NO_ERROR;
811 }