c2man: Fix .spec file flag recognition.
[wine/testsucceed.git] / dlls / mshtml / npplugin.c
blob042478b0d29d140cd850c08ba8db156faddcb6c5
1 /*
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
19 #include "config.h"
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
29 #include "shlobj.h"
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 */
41 #define NPERR_BASE 0
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 {
76 UINT16 size;
77 UINT16 version;
78 NPP_NewProcPtr newp;
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;
89 void *javaClass;
90 NPP_GetValueProcPtr getvalue;
91 NPP_SetValueProcPtr setvalue;
92 NPP_GotFocusPtr gotfocus;
93 NPP_LostFocusPtr lostfocus;
94 } NPPluginFuncs;
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;
102 nsIDOMElement *elem;
103 nsresult nsres;
105 nsres = nsISupports_QueryInterface(instance_unk, &IID_nsIPluginInstance, (void**)&plugin_instance);
106 if(NS_FAILED(nsres))
107 return NULL;
109 nsres = nsIPluginInstance_GetOwner(plugin_instance, &owner);
110 nsIPluginInstance_Release(instance_unk);
111 if(NS_FAILED(nsres) || !owner)
112 return NULL;
114 nsres = nsISupports_QueryInterface(owner, &IID_nsIPluginTagInfo, (void**)&tag_info);
115 nsISupports_Release(owner);
116 if(NS_FAILED(nsres))
117 return NULL;
119 nsres = nsIPluginTagInfo_GetDOMElement(tag_info, &elem);
120 nsIPluginTagInfo_Release(tag_info);
121 if(NS_FAILED(nsres))
122 return NULL;
124 return elem;
127 static HTMLWindow *get_elem_window(nsIDOMElement *elem)
129 nsIDOMWindow *nswindow;
130 nsIDOMDocument *nsdoc;
131 HTMLWindow *window;
132 nsresult nsres;
134 nsres = nsIDOMElement_GetOwnerDocument(elem, &nsdoc);
135 if(NS_FAILED(nsres))
136 return NULL;
138 nswindow = get_nsdoc_window(nsdoc);
139 nsIDOMDocument_Release(nsdoc);
140 if(!nswindow)
141 return NULL;
143 window = nswindow_to_window(nswindow);
144 nsIDOMWindow_Release(nswindow);
146 return window;
149 static BOOL parse_classid(const PRUnichar *classid, CLSID *clsid)
151 const WCHAR *ptr;
152 unsigned len;
153 HRESULT hres;
155 static const PRUnichar clsidW[] = {'c','l','s','i','d',':'};
157 if(strncmpiW(classid, clsidW, sizeof(clsidW)/sizeof(WCHAR)))
158 return FALSE;
160 ptr = classid + sizeof(clsidW)/sizeof(WCHAR);
161 len = strlenW(ptr);
163 if(len == 38) {
164 hres = CLSIDFromString(ptr, clsid);
165 }else if(len == 36) {
166 WCHAR buf[39];
168 buf[0] = '{';
169 memcpy(buf+1, ptr, len*sizeof(WCHAR));
170 buf[37] = '}';
171 buf[38] = 0;
172 hres = CLSIDFromString(buf, clsid);
173 }else {
174 return FALSE;
177 return SUCCEEDED(hres);
180 static BOOL get_elem_clsid(nsIDOMElement *elem, CLSID *clsid)
182 nsAString attr_str, val_str;
183 nsresult nsres;
184 BOOL ret = FALSE;
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);
196 if(*val)
197 ret = parse_classid(val, clsid);
198 }else {
199 ERR("GetAttribute failed: %08x\n", nsres);
202 nsAString_Finish(&attr_str);
203 return ret;
206 static IUnknown *create_activex_object(HTMLWindow *window, nsIDOMElement *nselem, CLSID *clsid)
208 IClassFactoryEx *cfex;
209 IClassFactory *cf;
210 IUnknown *obj;
211 DWORD policy;
212 HRESULT hres;
214 if(!get_elem_clsid(nselem, clsid)) {
215 WARN("Could not determine element CLSID\n");
216 return NULL;
219 TRACE("clsid %s\n", debugstr_guid(clsid));
221 policy = 0;
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);
226 return NULL;
229 hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
230 if(FAILED(hres))
231 return NULL;
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);
240 if(FAILED(hres))
241 return NULL;
243 return 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;
250 HTMLWindow *window;
251 IUnknown *obj;
252 CLSID clsid;
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);
258 if(!nselem) {
259 ERR("Could not get DOM element\n");
260 return NPERR_GENERIC_ERROR;
263 window = get_elem_window(nselem);
264 if(!window) {
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);
271 if(obj) {
272 PluginHost *host;
273 HRESULT hres;
275 hres = create_plugin_host(window->doc, nselem, obj, &clsid, &host);
276 nsIDOMElement_Release(nselem);
277 IUnknown_Release(obj);
278 if(SUCCEEDED(hres))
279 instance->pdata = host;
280 else
281 err = NPERR_GENERIC_ERROR;
282 }else {
283 err = NPERR_GENERIC_ERROR;
286 nsIDOMElement_Release(nselem);
287 return err;
290 static NPError CDECL NPP_Destroy(NPP instance, NPSavedData **save)
292 PluginHost *host = instance->pdata;
294 TRACE("(%p %p)\n", instance, save);
296 if(!host)
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);
312 if(!host)
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)
321 TRACE("\n");
322 return NPERR_GENERIC_ERROR;
325 static NPError CDECL NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
327 TRACE("\n");
328 return NPERR_GENERIC_ERROR;
331 static INT32 CDECL NPP_WriteReady(NPP instance, NPStream *stream)
333 TRACE("\n");
334 return NPERR_GENERIC_ERROR;
337 static INT32 CDECL NPP_Write(NPP instance, NPStream *stream, INT32 offset, INT32 len, void *buffer)
339 TRACE("\n");
340 return NPERR_GENERIC_ERROR;
343 static void CDECL NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
345 TRACE("\n");
348 static void CDECL NPP_Print(NPP instance, NPPrint *platformPrint)
350 FIXME("\n");
353 static INT16 CDECL NPP_HandleEvent(NPP instance, void *event)
355 TRACE("\n");
356 return NPERR_GENERIC_ERROR;
359 static void CDECL NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
361 TRACE("\n");
364 static NPError CDECL NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value)
366 TRACE("\n");
367 return NPERR_GENERIC_ERROR;
370 static NPError CDECL NPP_SetValue(NPP instance, NPNVariable variable, void *value)
372 TRACE("\n");
373 return NPERR_GENERIC_ERROR;
376 static NPBool CDECL NPP_GotFocus(NPP instance, NPFocusDirection direction)
378 FIXME("\n");
379 return NPERR_GENERIC_ERROR;
382 static void CDECL NPP_LostFocus(NPP instance)
384 FIXME("\n");
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;