2 * Copyright 2010 Jacek Caban for CodeWeavers
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.
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.
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
31 #include "mshtml_private.h"
32 #include "pluginhost.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 /* Parts of npapi.h */
42 #define NPERR_NO_ERROR (NPERR_BASE + 0)
43 #define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
44 #define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
45 #define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
46 #define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
47 #define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
48 #define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
49 #define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
50 #define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
51 #define NPERR_INVALID_PARAM (NPERR_BASE + 9)
52 #define NPERR_INVALID_URL (NPERR_BASE + 10)
53 #define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
54 #define NPERR_NO_DATA (NPERR_BASE + 12)
55 #define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
57 /* Parts of npfunctions.h */
59 typedef NPError (CDECL
*NPP_NewProcPtr
)(NPMIMEType
,NPP
,UINT16
,INT16
,char**,char**,NPSavedData
*);
60 typedef NPError (CDECL
*NPP_DestroyProcPtr
)(NPP
,NPSavedData
**);
61 typedef NPError (CDECL
*NPP_SetWindowProcPtr
)(NPP
,NPWindow
*);
62 typedef NPError (CDECL
*NPP_NewStreamProcPtr
)(NPP
,NPMIMEType
,NPStream
*,NPBool
,UINT16
*);
63 typedef NPError (CDECL
*NPP_DestroyStreamProcPtr
)(NPP
,NPStream
*,NPReason
);
64 typedef INT32 (CDECL
*NPP_WriteReadyProcPtr
)(NPP
,NPStream
*);
65 typedef INT32 (CDECL
*NPP_WriteProcPtr
)(NPP
,NPStream
*,INT32
,INT32
,void*);
66 typedef void (CDECL
*NPP_StreamAsFileProcPtr
)(NPP
,NPStream
*,const char*);
67 typedef void (CDECL
*NPP_PrintProcPtr
)(NPP
,NPPrint
*);
68 typedef INT16 (CDECL
*NPP_HandleEventProcPtr
)(NPP
,void*);
69 typedef void (CDECL
*NPP_URLNotifyProcPtr
)(NPP
,const char*,NPReason
,void*);
70 typedef NPError (CDECL
*NPP_GetValueProcPtr
)(NPP
,NPPVariable
,void*);
71 typedef NPError (CDECL
*NPP_SetValueProcPtr
)(NPP
,NPNVariable
,void*);
72 typedef NPBool (CDECL
*NPP_GotFocusPtr
)(NPP
,NPFocusDirection
);
73 typedef void (CDECL
*NPP_LostFocusPtr
)(NPP
);
75 typedef struct _NPPluginFuncs
{
79 NPP_DestroyProcPtr destroy
;
80 NPP_SetWindowProcPtr setwindow
;
81 NPP_NewStreamProcPtr newstream
;
82 NPP_DestroyStreamProcPtr destroystream
;
83 NPP_StreamAsFileProcPtr asfile
;
84 NPP_WriteReadyProcPtr writeready
;
85 NPP_WriteProcPtr write
;
86 NPP_PrintProcPtr print
;
87 NPP_HandleEventProcPtr event
;
88 NPP_URLNotifyProcPtr urlnotify
;
90 NPP_GetValueProcPtr getvalue
;
91 NPP_SetValueProcPtr setvalue
;
92 NPP_GotFocusPtr gotfocus
;
93 NPP_LostFocusPtr lostfocus
;
96 static nsIDOMElement
*get_dom_element(NPP instance
)
98 nsISupports
*instance_unk
= (nsISupports
*)instance
->ndata
;
99 nsIPluginInstance
*plugin_instance
;
100 nsIPluginInstanceOwner
*owner
;
101 nsIPluginTagInfo
*tag_info
;
105 nsres
= nsISupports_QueryInterface(instance_unk
, &IID_nsIPluginInstance
, (void**)&plugin_instance
);
109 nsres
= nsIPluginInstance_GetOwner(plugin_instance
, &owner
);
110 nsIPluginInstance_Release(instance_unk
);
111 if(NS_FAILED(nsres
) || !owner
)
114 nsres
= nsISupports_QueryInterface(owner
, &IID_nsIPluginTagInfo
, (void**)&tag_info
);
115 nsISupports_Release(owner
);
119 nsres
= nsIPluginTagInfo_GetDOMElement(tag_info
, &elem
);
120 nsIPluginTagInfo_Release(tag_info
);
127 static HTMLWindow
*get_elem_window(nsIDOMElement
*elem
)
129 nsIDOMWindow
*nswindow
;
130 nsIDOMDocument
*nsdoc
;
134 nsres
= nsIDOMElement_GetOwnerDocument(elem
, &nsdoc
);
138 nswindow
= get_nsdoc_window(nsdoc
);
139 nsIDOMDocument_Release(nsdoc
);
143 window
= nswindow_to_window(nswindow
);
144 nsIDOMWindow_Release(nswindow
);
149 static BOOL
parse_classid(const PRUnichar
*classid
, CLSID
*clsid
)
155 static const PRUnichar clsidW
[] = {'c','l','s','i','d',':'};
157 if(strncmpiW(classid
, clsidW
, sizeof(clsidW
)/sizeof(WCHAR
)))
160 ptr
= classid
+ sizeof(clsidW
)/sizeof(WCHAR
);
164 hres
= CLSIDFromString(ptr
, clsid
);
165 }else if(len
== 36) {
169 memcpy(buf
+1, ptr
, len
*sizeof(WCHAR
));
172 hres
= CLSIDFromString(buf
, clsid
);
177 return SUCCEEDED(hres
);
180 static BOOL
get_elem_clsid(nsIDOMElement
*elem
, CLSID
*clsid
)
182 nsAString attr_str
, val_str
;
186 static const PRUnichar classidW
[] = {'c','l','a','s','s','i','d',0};
188 nsAString_InitDepend(&attr_str
, classidW
);
189 nsAString_Init(&val_str
, NULL
);
190 nsres
= nsIDOMElement_GetAttribute(elem
, &attr_str
, &val_str
);
191 nsAString_Finish(&attr_str
);
192 if(NS_SUCCEEDED(nsres
)) {
193 const PRUnichar
*val
;
195 nsAString_GetData(&val_str
, &val
);
197 ret
= parse_classid(val
, clsid
);
199 ERR("GetAttribute failed: %08x\n", nsres
);
202 nsAString_Finish(&attr_str
);
206 static IUnknown
*create_activex_object(HTMLWindow
*window
, nsIDOMElement
*nselem
, CLSID
*clsid
)
208 IClassFactoryEx
*cfex
;
214 if(!get_elem_clsid(nselem
, clsid
)) {
215 WARN("Could not determine element CLSID\n");
219 TRACE("clsid %s\n", debugstr_guid(clsid
));
222 hres
= IInternetHostSecurityManager_ProcessUrlAction(&window
->doc
->IInternetHostSecurityManager_iface
,
223 URLACTION_ACTIVEX_RUN
, (BYTE
*)&policy
, sizeof(policy
), (BYTE
*)clsid
, sizeof(GUID
), 0, 0);
224 if(FAILED(hres
) || policy
!= URLPOLICY_ALLOW
) {
225 WARN("ProcessUrlAction returned %08x %x\n", hres
, policy
);
229 hres
= CoGetClassObject(clsid
, CLSCTX_INPROC_SERVER
|CLSCTX_LOCAL_SERVER
, NULL
, &IID_IClassFactory
, (void**)&cf
);
233 hres
= IClassFactory_QueryInterface(cf
, &IID_IClassFactoryEx
, (void**)&cfex
);
234 if(SUCCEEDED(hres
)) {
235 FIXME("Use IClassFactoryEx\n");
236 IClassFactoryEx_Release(cfex
);
239 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)&obj
);
246 static NPError CDECL
NPP_New(NPMIMEType pluginType
, NPP instance
, UINT16 mode
, INT16 argc
, char **argn
,
247 char **argv
, NPSavedData
*saved
)
249 nsIDOMElement
*nselem
;
253 NPError err
= NPERR_NO_ERROR
;
255 TRACE("(%s %p %x %d %p %p %p)\n", debugstr_a(pluginType
), instance
, mode
, argc
, argn
, argv
, saved
);
257 nselem
= get_dom_element(instance
);
259 ERR("Could not get DOM element\n");
260 return NPERR_GENERIC_ERROR
;
263 window
= get_elem_window(nselem
);
265 ERR("Could not get element's window object\n");
266 nsIDOMElement_Release(nselem
);
267 return NPERR_GENERIC_ERROR
;
270 obj
= create_activex_object(window
, nselem
, &clsid
);
275 hres
= create_plugin_host(window
->doc
, nselem
, obj
, &clsid
, &host
);
276 nsIDOMElement_Release(nselem
);
277 IUnknown_Release(obj
);
279 instance
->pdata
= host
;
281 err
= NPERR_GENERIC_ERROR
;
283 err
= NPERR_GENERIC_ERROR
;
286 nsIDOMElement_Release(nselem
);
290 static NPError CDECL
NPP_Destroy(NPP instance
, NPSavedData
**save
)
292 PluginHost
*host
= instance
->pdata
;
294 TRACE("(%p %p)\n", instance
, save
);
297 return NPERR_GENERIC_ERROR
;
299 detach_plugin_host(host
);
300 IOleClientSite_Release(&host
->IOleClientSite_iface
);
301 instance
->pdata
= NULL
;
302 return NPERR_NO_ERROR
;
305 static NPError CDECL
NPP_SetWindow(NPP instance
, NPWindow
*window
)
307 PluginHost
*host
= instance
->pdata
;
308 RECT pos_rect
= {0, 0, window
->width
, window
->height
};
310 TRACE("(%p %p)\n", instance
, window
);
313 return NPERR_GENERIC_ERROR
;
315 update_plugin_window(host
, window
->window
, &pos_rect
);
316 return NPERR_NO_ERROR
;
319 static NPError CDECL
NPP_NewStream(NPP instance
, NPMIMEType type
, NPStream
*stream
, NPBool seekable
, UINT16
*stype
)
322 return NPERR_GENERIC_ERROR
;
325 static NPError CDECL
NPP_DestroyStream(NPP instance
, NPStream
*stream
, NPReason reason
)
328 return NPERR_GENERIC_ERROR
;
331 static INT32 CDECL
NPP_WriteReady(NPP instance
, NPStream
*stream
)
334 return NPERR_GENERIC_ERROR
;
337 static INT32 CDECL
NPP_Write(NPP instance
, NPStream
*stream
, INT32 offset
, INT32 len
, void *buffer
)
340 return NPERR_GENERIC_ERROR
;
343 static void CDECL
NPP_StreamAsFile(NPP instance
, NPStream
*stream
, const char *fname
)
348 static void CDECL
NPP_Print(NPP instance
, NPPrint
*platformPrint
)
353 static INT16 CDECL
NPP_HandleEvent(NPP instance
, void *event
)
356 return NPERR_GENERIC_ERROR
;
359 static void CDECL
NPP_URLNotify(NPP instance
, const char *url
, NPReason reason
, void *notifyData
)
364 static NPError CDECL
NPP_GetValue(NPP instance
, NPPVariable variable
, void *ret_value
)
367 return NPERR_GENERIC_ERROR
;
370 static NPError CDECL
NPP_SetValue(NPP instance
, NPNVariable variable
, void *value
)
373 return NPERR_GENERIC_ERROR
;
376 static NPBool CDECL
NPP_GotFocus(NPP instance
, NPFocusDirection direction
)
379 return NPERR_GENERIC_ERROR
;
382 static void CDECL
NPP_LostFocus(NPP instance
)
387 /***********************************************************************
388 * NP_GetEntryPoints (mshtml.@)
390 NPError WINAPI
NP_GetEntryPoints(NPPluginFuncs
* funcs
)
392 TRACE("(%p)\n", funcs
);
394 funcs
->version
= (NP_VERSION_MAJOR
<< 8) | NP_VERSION_MINOR
;
395 funcs
->newp
= NPP_New
;
396 funcs
->destroy
= NPP_Destroy
;
397 funcs
->setwindow
= NPP_SetWindow
;
398 funcs
->newstream
= NPP_NewStream
;
399 funcs
->destroystream
= NPP_DestroyStream
;
400 funcs
->asfile
= NPP_StreamAsFile
;
401 funcs
->writeready
= NPP_WriteReady
;
402 funcs
->write
= NPP_Write
;
403 funcs
->print
= NPP_Print
;
404 funcs
->event
= NPP_HandleEvent
;
405 funcs
->urlnotify
= NPP_URLNotify
;
406 funcs
->javaClass
= NULL
;
407 funcs
->getvalue
= NPP_GetValue
;
408 funcs
->setvalue
= NPP_SetValue
;
409 funcs
->gotfocus
= NPP_GotFocus
;
410 funcs
->lostfocus
= NPP_LostFocus
;
412 return NPERR_NO_ERROR
;