Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 : #ifdef UNIX
30 :
31 : #define XP_UNIX 1
32 :
33 : #include <strings.h>
34 : #include <arpa/inet.h>
35 : #include <netinet/in.h>
36 : #include <sys/types.h>
37 : #include <sys/socket.h>
38 : #include <sys/stat.h>
39 : #include <sys/wait.h>
40 : #include <unistd.h>
41 : #include <fcntl.h>
42 :
43 : #endif //end of UNIX
44 :
45 : #ifdef WNT
46 :
47 : #ifdef _MSC_VER
48 : #pragma warning (push,1)
49 : #pragma warning (disable:4668)
50 : #endif
51 :
52 : #include <windows.h>
53 : #include <direct.h>
54 : #include <stdlib.h>
55 : #include <io.h>
56 : #include <sys/types.h>
57 : #include <fcntl.h>
58 :
59 : #ifdef _MSC_VER
60 : #pragma warning (pop)
61 : #endif
62 :
63 : #include "tools/pathutils.hxx"
64 :
65 : #endif //end of WNT
66 :
67 :
68 : #include <stdio.h>
69 :
70 : #include <string.h>
71 : #include <errno.h>
72 : #include "boost/scoped_array.hpp"
73 :
74 : #include "npapi.h"
75 : #include "npshell.hxx"
76 : #include "so_env.hxx"
77 : #include "so_msg.hxx"
78 : #include "ns_debug.hxx"
79 :
80 :
81 : #include "nsp_func.hxx"
82 :
83 : #include "npsdk/plugin.h"
84 :
85 : #include <comphelper/documentconstants.hxx>
86 :
87 : #ifdef _MSC_VER
88 : #define NP_DLLPUBLIC
89 : #else
90 : #define NP_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
91 : #endif
92 :
93 : #if defined WNT
94 : static SECURITY_ATTRIBUTES NSP_pipe_access = {
95 : sizeof (SECURITY_ATTRIBUTES), NULL, TRUE };
96 : #define NSP_Inherited_Pipe(fd) \
97 : (!CreatePipe(&fd[0], &fd[1], &NSP_pipe_access, 1024 * 10))
98 : #else
99 : #define NSP_Inherited_Pipe(fp) pipe(fd)
100 : #endif
101 :
102 : /***********************************************************************
103 : *
104 : * Implementations of plugin API functions
105 : *
106 : ***********************************************************************/
107 :
108 : static NSP_Mute_Obj send_lock = NSP_New_Mute_Obj();
109 : static NSP_PIPE_FD write_fd = (NSP_PIPE_FD)-1;
110 :
111 :
112 0 : long int NSP_WriteToPipe(NSP_PIPE_FD fp, void* buf, unsigned long int len)
113 : {
114 0 : unsigned long int len_unix = 0, len_wnt = 0;
115 :
116 0 : len_unix = NSP_Write_Pipe(fp, buf, len, &len_wnt);
117 : #ifdef UNIX
118 : (void)len_wnt;
119 0 : return len_unix;
120 : #endif //end of UNIX
121 : #ifdef WNT
122 : (void)len_unix;
123 : return len_wnt;
124 : #endif //end of WNT
125 :
126 : }
127 :
128 : #ifdef UNIX
129 : static pid_t nChildPID = 0;
130 : #endif
131 :
132 : #if defined WNT
133 :
134 : #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
135 : #define MY_STRING(s) (s), MY_LENGTH(s)
136 :
137 : namespace {
138 :
139 : bool extendEnvironment(boost::scoped_array< WCHAR > * environment) {
140 : WCHAR path[MAX_PATH];
141 : int len = MultiByteToWideChar(
142 : CP_ACP, MB_PRECOMPOSED, findInstallDir(), -1, path, MAX_PATH);
143 : //TODO: conversion errors
144 : if (len == 0 ||
145 : (tools::buildPath(path, path, path + len - 1, MY_STRING(L"\\ure-link"))
146 : == NULL))
147 : {
148 : return false;
149 : }
150 : WCHAR * pathEnd = tools::resolveLink(path);
151 : if (pathEnd == NULL) {
152 : return false;
153 : }
154 : pathEnd = tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin"));
155 : if (pathEnd == NULL) {
156 : return false;
157 : }
158 : WCHAR const * env = GetEnvironmentStringsW();
159 : if (env == NULL) {
160 : return false;
161 : }
162 : WCHAR const * p = env;
163 : WCHAR const * p1 = NULL;
164 : while (*p != L'\0') {
165 : size_t n = wcslen(p);
166 : if (p1 == NULL && n >= MY_LENGTH(L"PATH=") &&
167 : (p[0] == L'P' || p[0] == L'p') &&
168 : (p[1] == L'A' || p[1] == L'a') &&
169 : (p[2] == L'T' || p[2] == L't') &&
170 : (p[3] == L'H' || p[3] == L'h') && p[4] == L'=')
171 : {
172 : p1 = p + MY_LENGTH(L"PATH=");
173 : //TODO: check whether the path is already present in PATH (at the
174 : // beginning of PATH?)
175 : }
176 : p += n + 1;
177 : }
178 : ++p;
179 : if (p1 == NULL) {
180 : environment->reset(
181 : new WCHAR[MY_LENGTH(L"PATH=") + (pathEnd - path) + 1 + (p - env)]);
182 : //TODO: overflow
183 : memcpy(environment->get(), MY_STRING(L"PATH=") * sizeof (WCHAR));
184 : memcpy(
185 : environment->get() + MY_LENGTH(L"PATH="), path,
186 : ((pathEnd - path) + 1) * sizeof (WCHAR));
187 : memcpy(
188 : environment->get() + MY_LENGTH(L"PATH=") + (pathEnd - path) + 1,
189 : env, (p - env) * sizeof (WCHAR));
190 : } else {
191 : environment->reset(
192 : new WCHAR[(p - env) + (pathEnd - path) + MY_LENGTH(L";")]);
193 : //TODO: overflow
194 : memcpy(environment->get(), env, (p1 - env) * sizeof (WCHAR));
195 : memcpy(
196 : environment->get() + (p1 - env), path,
197 : (pathEnd - path) * sizeof (WCHAR));
198 : environment->get()[(p1 - env) + (pathEnd - path)] = L';';
199 : memcpy(
200 : environment->get() + (p1 - env) + (pathEnd - path) + 1, p1,
201 : (p - p1) * sizeof (WCHAR));
202 : }
203 : return true;
204 : }
205 :
206 : }
207 : #endif
208 :
209 : // start nspluin executable in child process, and use pipe to talk with it
210 0 : int do_init_pipe()
211 : {
212 0 : debug_fprintf(NSP_LOG_APPEND, "enter do_init_pipe 1\n");
213 : NSP_PIPE_FD fd[2];
214 :
215 0 : if( 0 != NSP_Inherited_Pipe(fd) )
216 0 : return NPERR_GENERIC_ERROR;
217 :
218 0 : write_fd = fd[1]; // write fd
219 : #ifdef UNIX
220 : // the parent process will wait for the child process in NPP_Shutdown code
221 0 : nChildPID = fork();
222 :
223 0 : if( ! nChildPID ) // child process
224 : #endif //end of UNIX
225 : {
226 : #ifdef UNIX
227 0 : char s_read_fd[16] = {0};
228 0 : char s_write_fd[16] = {0};
229 0 : sprintf(s_read_fd, "%d", fd[0]);
230 0 : sprintf(s_write_fd, "%d", fd[1]);
231 0 : char const * progdir = findProgramDir();
232 : boost::scoped_array< char > exepath(
233 0 : new char[strlen(progdir) + RTL_CONSTASCII_LENGTH("/nsplugin") + 1]);
234 0 : sprintf(exepath.get(), "%s/nsplugin", progdir);
235 : boost::scoped_array< char > inifilepath(
236 : new char[
237 : RTL_CONSTASCII_LENGTH(
238 : "-env:INIFILENAME=vnd.sun.star.pathname:") +
239 0 : strlen(progdir) + RTL_CONSTASCII_LENGTH("/redirectrc") + 1]);
240 : //TODO: overflow
241 : sprintf(
242 : inifilepath.get(),
243 0 : "-env:INIFILENAME=vnd.sun.star.pathname:%s/redirectrc", progdir);
244 : execl(
245 0 : exepath.get(), exepath.get(), s_read_fd, s_write_fd,
246 0 : inifilepath.get(), progdir, NULL);
247 0 : _exit(255);
248 : #endif //end of UNIX
249 : #ifdef WNT
250 : WCHAR s_read_fd[16] = {0};
251 : WCHAR s_write_fd[16] = {0};
252 : wsprintfW(s_read_fd, L"%d", fd[0]);
253 : wsprintfW(s_write_fd, L"%d", fd[1]);
254 : boost::scoped_array< WCHAR > env;
255 : if (!extendEnvironment(&env)) {
256 : return NPERR_GENERIC_ERROR;
257 : }
258 : WCHAR path[MAX_PATH];
259 : int pathLen = MultiByteToWideChar(
260 : CP_ACP, MB_PRECOMPOSED, findProgramDir(), -1, path, MAX_PATH);
261 : //TODO: conversion errors
262 : if (pathLen == 0) {
263 : return NPERR_GENERIC_ERROR;
264 : }
265 : WCHAR exe[MAX_PATH];
266 : WCHAR * exeEnd = tools::buildPath(
267 : exe, path, path + pathLen - 1, MY_STRING(L"\\nsplugin.exe"));
268 : if (exeEnd == NULL) {
269 : return NPERR_GENERIC_ERROR;
270 : }
271 : WCHAR ini[MAX_PATH];
272 : WCHAR * iniEnd = tools::buildPath(
273 : ini, path, path + pathLen - 1, MY_STRING(L"\\redirect.ini"));
274 : if (iniEnd == NULL) {
275 : return NPERR_GENERIC_ERROR;
276 : }
277 : boost::scoped_array< WCHAR > args(
278 : new WCHAR[
279 : MY_LENGTH(L"\"") + (exeEnd - exe) + MY_LENGTH(L"\" ") +
280 : wcslen(s_read_fd) + MY_LENGTH(L" ") + wcslen(s_write_fd) +
281 : MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") +
282 : (iniEnd - ini) + MY_LENGTH(L"\"") + 1]); //TODO: overflow
283 : wsprintfW(
284 : args.get(),
285 : L"\"%s\" %s %s \"-env:INIFILENAME=vnd.sun.star.pathname:%s\"", exe,
286 : s_read_fd, s_write_fd, ini);
287 : STARTUPINFOW NSP_StarInfo;
288 : memset((void*) &NSP_StarInfo, 0, sizeof(STARTUPINFOW));
289 : NSP_StarInfo.cb = sizeof(STARTUPINFOW);
290 : PROCESS_INFORMATION NSP_ProcessInfo;
291 : memset((void*)&NSP_ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
292 : if(!CreateProcessW(
293 : exe, args.get(), NULL, NULL, TRUE,
294 : CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, env.get(), path,
295 : &NSP_StarInfo, &NSP_ProcessInfo))
296 : {
297 : DWORD Err = GetLastError();
298 : (void)Err;
299 : }
300 : #endif //end of WNT
301 : }
302 0 : NSP_Close_Pipe(fd[0]);
303 0 : return NPERR_NO_ERROR;
304 : }
305 :
306 0 : bool sendMsg( PLUGIN_MSG* pMsg, size_t len, int iEnsure)
307 : {
308 0 : NSP_Lock_Mute_Obj(send_lock);
309 0 : size_t len_w = 0;
310 :
311 0 : debug_fprintf(NSP_LOG_APPEND, "try to send message type:%d; len: %d\n", pMsg->msg_id, len);
312 : /*
313 : debug_fprintf(NSP_LOG_APPEND, "NSPlugin Message: msg_id:%d; instance_id:%d;
314 : wnd_id:%d;wnd_x:%d;wnd_y:%d;wnd_w:%d;wnd_h:%d; url:%s\n",
315 : pMsg->msg_id, pMsg->instance_id, pMsg->wnd_id,
316 : pMsg->wnd_x, pMsg->wnd_y, pMsg->wnd_w, pMsg->wnd_h, pMsg->url);*/
317 0 : len_w = NSP_WriteToPipe(write_fd, (void*) pMsg, len);
318 0 : if (len_w != len){
319 0 : if(errno == EPIPE) // If pipe breaks, then init pipe again and resend the msg
320 : {
321 0 : if(iEnsure){
322 0 : debug_fprintf(NSP_LOG_APPEND, "send message error, plugin exec need to be restart\n");
323 0 : NSP_Close_Pipe(write_fd);
324 0 : do_init_pipe();
325 0 : len_w = NSP_WriteToPipe(write_fd, (void*) pMsg, len);
326 : }
327 : }
328 0 : else if(errno == EINTR) // If interrupted by signal, then continue to send
329 : {
330 : long new_len;
331 0 : debug_fprintf(NSP_LOG_APPEND, "send message error, send intrrupted by singal, resend again\n");
332 0 : new_len = NSP_WriteToPipe(write_fd, (char*)pMsg+len_w, len-len_w);
333 0 : len_w = len_w + new_len;
334 : }
335 : else // else return error
336 : {
337 0 : debug_fprintf(NSP_LOG_APPEND, "send message error :%s.\n", strerror(errno));
338 0 : len_w = 0;
339 : }
340 : }
341 0 : NSP_Unlock_Mute_Obj(send_lock);
342 0 : debug_fprintf(NSP_LOG_APPEND, "send message success!\n");
343 0 : return len_w == len;
344 : }
345 :
346 : extern "C"
347 : {
348 : char* pMimeTypes = const_cast< char* >( "application/msword:doc:MS Word 97-2003 document;"
349 : "application/msword:dot:MS Word 97-2003 document template;"
350 : "application/vnd.openxmlformats-officedocument.wordprocessingml.document:docx:MS Word document;"
351 : "application/vnd.ms-word.document.macroenabled.12:docm:MS Word document with macros;"
352 : "application/vnd.openxmlformats-officedocument.wordprocessingml.template:dotx:MS Word document template;"
353 : "application/vnd.ms-word.template.macroenabled.12:dotm:MS Word document template with macros;"
354 : "application/rtf:rtf:Rich Text Format;"
355 : "application/vnd.ms-excel:xls:MS Excel 97-2003 spreadsheet;"
356 : "application/vnd.ms-excel:xlt:MS Excel 97-2003 spreadsheet template;"
357 : "application/vnd.ms-excel:xla:MS Excel 97-2003 spreadsheet;"
358 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:xlsx:MS Excel spreadsheet;"
359 : "application/vnd.ms-excel.sheet.macroenabled.12:xlsm:MS Excel spreadsheet with macros;"
360 : "application/vnd.openxmlformats-officedocument.spreadsheetml.template:xltx:MS Excel spreadsheet template;"
361 : "application/vnd.ms-excel.template.macroenabled.12:xltm:MS Excel spreadsheet template with macros;"
362 : "application/vnd.ms-powerpoint:ppt:MS PowerPoint 97-2003 presentation;"
363 : "application/vnd.openxmlformats-officedocument.presentationml.presentation:pptx:MS PowerPoint presentation;"
364 : "application/vnd.ms-powerpoint.presentation.macroenabled.12:pptm:MS PowerPoint presentation with macros;"
365 : "application/vnd.openxmlformats-officedocument.presentationml.template:potx:MS PowerPoint presentation template;"
366 : "application/vnd.ms-powerpoint.template.macroenabled.12:potm:MS PowerPoint presentation template with macros;"
367 : MIMETYPE_VND_SUN_XML_CALC_ASCII ":sxc:StarOffice 6.0/7 Spreadsheet;"
368 : MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII":stc:StarOffice 6.0/7 Spreadsheet Template;"
369 : MIMETYPE_VND_SUN_XML_DRAW_ASCII ":sxd:StarOffice 6.0/7 Drawing;"
370 : MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII ":std:StarOffice 6.0/7 Drawing Template;"
371 : MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ":sxi:StarOffice 6.0/7 Presentation;"
372 : MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII ":sti:StarOffice 6.0/7 Presentation Template;"
373 : MIMETYPE_VND_SUN_XML_MATH_ASCII ":sxm:StarOffice 6.0/7 Formula;"
374 : MIMETYPE_VND_SUN_XML_WRITER_ASCII ":sxw:StarOffice 6.0/7 Text Document;"
375 : MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII ":sxg:StarOffice 6.0/7 Master Document;"
376 : MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII ":stw:StarOffice 6.0/7 Text Document Template;"
377 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ":odt:OpenDocument Text;"
378 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII "-flat-xml:fodt:OpenDocument Text Flat XML;"
379 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ":ott:OpenDocument Text Template;"
380 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ":odm:OpenDocument Master Document;"
381 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ":oth:HTML Document Template;"
382 : MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ":ods:OpenDocument Spreadsheet;"
383 : MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII "-flat-xml:fods:OpenDocument Spreadsheet Flat XML;"
384 : MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ":ots:OpenDocument Spreadsheet Template;"
385 : MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ":odg:OpenDocument Drawing;"
386 : MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII "-flat-xml:fodg:OpenDocument Drawing Flat XML;"
387 : MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ":otg:OpenDocument Drawing Template;"
388 : MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII ":odp:OpenDocument Presentation;"
389 : MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII "-flat-xml:fodp:OpenDocument Presentation Flat XML;"
390 : MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII ":otp:OpenDocument Presentation Template;"
391 : MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ":odf:OpenDocument Formula;" );
392 :
393 : NP_DLLPUBLIC
394 : #ifndef HAVE_NON_CONST_NPP_GETMIMEDESCRIPTION
395 : const
396 : #endif
397 : char*
398 0 : NPP_GetMIMEDescription(void)
399 : {
400 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, NPP_GetMIMEDescription:%s.\n", pMimeTypes);
401 0 : return(pMimeTypes);
402 : }
403 :
404 : #ifdef UNIX
405 : NP_DLLPUBLIC NPError
406 0 : NPP_GetValue(NPP /*instance*/, NPPVariable variable, void *value)
407 : {
408 0 : NPError err = NPERR_NO_ERROR;
409 :
410 0 : switch (variable) {
411 : case NPPVpluginNameString:
412 : // add here, for dynamic productname
413 0 : *((char **)value) = NSP_getPluginName();
414 0 : break;
415 : case NPPVpluginDescriptionString:
416 : // add here, for dynamic product description
417 0 : *((char **)value) = NSP_getPluginDesc();
418 0 : break;
419 : default:
420 0 : err = NPERR_GENERIC_ERROR;
421 : }
422 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, NPP_GetValue return %d.\n", err);
423 0 : return err;
424 : }
425 :
426 :
427 : NPMIMEType
428 0 : dupMimeType(NPMIMEType type)
429 : {
430 0 : NPMIMEType mimetype = (NPMIMEType) NPN_MemAlloc(strlen(type)+1);
431 0 : mimetype[strlen(type)] = 0;
432 0 : if (mimetype)
433 0 : strcpy(mimetype, type);
434 0 : return(mimetype);
435 : }
436 : #endif // end of UNIX
437 :
438 : NPError
439 0 : NPP_Initialize(void)
440 : {
441 0 : debug_fprintf(NSP_LOG_NEW, "NS Plugin begin initialize.\n");
442 0 : return (NPError)do_init_pipe();
443 : }
444 :
445 : #ifdef OJI
446 : NP_DLLPUBLIC jref
447 : NPP_GetJavaClass()
448 : {
449 : return NULL;
450 : }
451 : #endif
452 :
453 : void
454 0 : NPP_Shutdown(void)
455 : {
456 : PLUGIN_MSG msg;
457 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
458 0 : msg.msg_id = SO_SHUTDOWN;
459 0 : sendMsg(&msg, sizeof(PLUGIN_MSG), 0);
460 0 : NSP_Close_Pipe(write_fd);
461 :
462 : #ifdef UNIX
463 : // on Unix we should wait till the child process is dead
464 : int nStatus;
465 0 : waitpid( nChildPID, &nStatus, 0 );
466 : #endif
467 0 : }
468 :
469 : NP_DLLPUBLIC NPError NP_LOADDS
470 0 : NPP_New(NPMIMEType pluginType,
471 : NPP instance,
472 : uint16_t mode,
473 : int16_t /*argc*/,
474 : char* /*argn*/[],
475 : char* /*argv*/[],
476 : NPSavedData* /*saved*/)
477 : {
478 : PluginInstance* This;
479 :
480 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, enter NPP_New.\n");
481 0 : if (instance == NULL)
482 0 : return NPERR_INVALID_INSTANCE_ERROR;
483 :
484 0 : instance->pdata = (PluginInstance*)NPN_MemAlloc(sizeof(PluginInstance));
485 :
486 0 : memset(instance->pdata, 0 , sizeof(PluginInstance));
487 0 : This = (PluginInstance*) instance->pdata;
488 :
489 0 : if (This == NULL)
490 : {
491 0 : return NPERR_OUT_OF_MEMORY_ERROR;
492 : }
493 :
494 0 : memset(This, 0, sizeof(PluginInstance));
495 :
496 : /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
497 : #ifdef UNIX
498 0 : This->mode = mode;
499 0 : This->type = dupMimeType(pluginType);
500 0 : This->instance = instance;
501 0 : This->pluginsPageUrl = NULL;
502 0 : This->exists = FALSE;
503 : #endif //end of UNIX
504 : #ifdef WNT
505 : (void)pluginType;
506 : This->fWindow = (NPWindow*)NPN_MemAlloc(sizeof(NPWindow));
507 : memset(This->fWindow, 0, sizeof (NPWindow));
508 : This->fMode = mode;
509 : #endif //end of WNT
510 : PLUGIN_MSG msg;
511 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
512 0 : msg.msg_id = SO_NEW_INSTANCE;
513 0 : msg.instance_id = (plugin_Int32)instance;
514 0 : if (!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
515 0 : return NPERR_GENERIC_ERROR;
516 :
517 0 : NPN_Status(instance, "......");
518 0 : return NPERR_NO_ERROR;
519 : }
520 :
521 : NP_DLLPUBLIC NPError NP_LOADDS
522 0 : NPP_Destroy(NPP instance, NPSavedData** /*save*/)
523 : {
524 0 : debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, enter NPP_Destroy.\n");
525 : PluginInstance* This;
526 :
527 0 : if (instance == NULL)
528 0 : return NPERR_INVALID_INSTANCE_ERROR;
529 :
530 : // Send destroy message
531 : PLUGIN_MSG msg;
532 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
533 0 : msg.msg_id = SO_DESTROY;
534 0 : msg.instance_id = (plugin_Int32)instance;
535 : #ifdef UNIX
536 0 : msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->window;
537 : #endif //end of UNIX
538 : #ifdef WNT
539 : msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->fhWnd;
540 : #endif //end of WNT
541 0 : sendMsg(&msg, sizeof(PLUGIN_MSG), 0);
542 :
543 : // Free the instance space
544 0 : This = (PluginInstance*) instance->pdata;
545 0 : if (This != NULL) {
546 : #ifdef UNIX
547 0 : if (This->type)
548 0 : NPN_MemFree(This->type);
549 0 : if (This->pluginsPageUrl)
550 0 : NPN_MemFree(This->pluginsPageUrl);
551 0 : if (This->pluginsFileUrl)
552 0 : NPN_MemFree(This->pluginsFileUrl);
553 : #endif //end of UNIX
554 : #ifdef WNT
555 : if(This->fWindow)
556 : NPN_MemFree(This->fWindow);
557 : #endif //end of WNT
558 0 : NPN_MemFree(instance->pdata);
559 0 : instance->pdata = NULL;
560 : }
561 :
562 0 : return NPERR_NO_ERROR;
563 : }
564 :
565 :
566 : NP_DLLPUBLIC NPError NP_LOADDS
567 0 : NPP_SetWindow(NPP instance, NPWindow* window)
568 : {
569 : PluginInstance* This;
570 : #ifdef UNIX
571 : NPSetWindowCallbackStruct *ws_info;
572 : #endif //end of UNIX
573 :
574 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, received window resize.\n");
575 0 : if (instance == NULL)
576 0 : return NPERR_INVALID_INSTANCE_ERROR;
577 :
578 0 : This = (PluginInstance*) instance->pdata;
579 0 : if (This == NULL)
580 0 : return NPERR_INVALID_INSTANCE_ERROR;
581 :
582 : // Prepare the general part of the SET_WINDOW message
583 : PLUGIN_MSG msg;
584 0 : memset((char*)&msg, 0, sizeof(msg));
585 0 : msg.msg_id = SO_SET_WINDOW;
586 0 : msg.instance_id = (plugin_Int32)instance;
587 :
588 0 : if ( window )
589 : {
590 : // Set window info for instance
591 : #ifdef UNIX
592 0 : ws_info = (NPSetWindowCallbackStruct *)window->ws_info;
593 0 : This->window = (Window) window->window;
594 0 : This->x = window->x;
595 0 : This->y = window->y;
596 0 : This->width = window->width;
597 0 : This->height = window->height;
598 0 : This->display = ws_info->display;
599 0 : This->visual = ws_info->visual;
600 0 : This->depth = ws_info->depth;
601 0 : This->colormap = ws_info->colormap;
602 : #endif //end of UNIX
603 : #ifdef WNT
604 : This->fhWnd = (HWND) window->window;
605 : This->fWindow->x = window->x;
606 : This->fWindow->y = window->y;
607 : This->fWindow->width = window->width;
608 : This->fWindow->height = window->height;
609 : #endif //end of WNT
610 0 : debug_fprintf(NSP_LOG_APPEND, "begin Set window of Office\n");
611 0 : debug_fprintf(NSP_LOG_APPEND, "W=(%d) H=(%d)\n", window->width, window->height);
612 :
613 : // fill the window dependent part of the message
614 0 : msg.wnd_id = (plugin_Int32) window->window;
615 0 : msg.wnd_x = window->x;
616 0 : msg.wnd_y = window->y;
617 0 : msg.wnd_w = window->width;
618 0 : msg.wnd_h = window->height;
619 : }
620 : else
621 : {
622 : // empty window pointer usually means closing of the parent window
623 : #ifdef UNIX
624 0 : ws_info = NULL;
625 0 : This->window = (Window) NULL;
626 0 : This->x = 0;
627 0 : This->y = 0;
628 0 : This->width = 0;
629 0 : This->height = 0;
630 0 : This->display = NULL;
631 0 : This->visual = NULL;
632 : #endif //end of UNIX
633 : #ifdef WNT
634 : This->fhWnd = (HWND) NULL;
635 : This->fWindow->x = 0;
636 : This->fWindow->y = 0;
637 : This->fWindow->width = 0;
638 : This->fWindow->height = 0;
639 : #endif //end of WNT
640 0 : debug_fprintf(NSP_LOG_APPEND, "Empty window pointer is provided\n");
641 :
642 : // fill the window dependent part of the message
643 0 : msg.wnd_id = (plugin_Int32) NULL;
644 0 : msg.wnd_x = 0;
645 0 : msg.wnd_y = 0;
646 0 : msg.wnd_w = 0;
647 0 : msg.wnd_h = 0;
648 : }
649 :
650 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
651 : {
652 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_SetWindow return failure \n");
653 0 : return NPERR_GENERIC_ERROR;
654 : }
655 :
656 0 : return NPERR_NO_ERROR;
657 : }
658 :
659 :
660 : NP_DLLPUBLIC NPError NP_LOADDS
661 0 : NPP_NewStream(NPP instance,
662 : NPMIMEType /*type*/,
663 : NPStream* /*stream*/,
664 : NPBool /*seekable*/,
665 : uint16_t *stype)
666 : {
667 0 : if (instance == NULL)
668 0 : return NPERR_INVALID_INSTANCE_ERROR;
669 :
670 : // Notify Mozilla to fetch the remote file into local cache directory
671 0 : *stype=NP_ASFILEONLY;
672 :
673 0 : return NPERR_NO_ERROR;
674 : }
675 :
676 :
677 : int32_t STREAMBUFSIZE = 0X0FFFFFFF;
678 : /* If we are reading from a file in NPAsFile
679 : * mode so we can take any size stream in our
680 : * write call (since we ignore it) */
681 :
682 : NP_DLLPUBLIC int32_t NP_LOADDS
683 0 : NPP_WriteReady(NPP /*instance*/, NPStream* /*stream*/)
684 : {
685 0 : return STREAMBUFSIZE;
686 : }
687 :
688 :
689 : NP_DLLPUBLIC int32_t NP_LOADDS
690 0 : NPP_Write(NPP /*instance*/, NPStream* /*stream*/, int32_t /*offset*/, int32_t len, void* /*buffer*/)
691 : {
692 0 : return len; /* The number of bytes accepted */
693 : }
694 :
695 :
696 : NP_DLLPUBLIC NPError NP_LOADDS
697 0 : NPP_DestroyStream(NPP instance, NPStream* /*stream*/, NPError /*reason*/)
698 : {
699 0 : if (instance == NULL)
700 0 : return NPERR_INVALID_INSTANCE_ERROR;
701 0 : return NPERR_NO_ERROR;
702 : }
703 :
704 : // save fname to another file with the original file name
705 : NP_DLLPUBLIC void NP_LOADDS
706 0 : NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
707 : {
708 0 : debug_fprintf(NSP_LOG_APPEND, "Into Stream\n");
709 0 : char* url = (char*)stream->url;
710 0 : char filename[1024] = {0};
711 0 : char* pfilename = NULL;
712 0 : if (NULL != (pfilename = strrchr(url, '/')))
713 : {
714 0 : strcpy(filename, pfilename+1);
715 : } else {
716 0 : return;
717 : }
718 :
719 0 : int length = strlen(url);
720 0 : debug_fprintf(NSP_LOG_APPEND, "url: %s; length: %d\n", url, length);
721 : PluginInstance* This;
722 0 : This = (PluginInstance*) instance->pdata;
723 :
724 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile\n");
725 :
726 : // copy cached file to another file with original name
727 0 : char localPathNew[NPP_PATH_MAX] = {0};
728 0 : char localFileNew[NPP_PATH_MAX] = {0};
729 : // if the file is from local
730 0 : if (0 == STRNICMP(url, "file:///", strlen("file:///")))
731 : {
732 0 : sprintf(localPathNew, "%s", fname);
733 0 : char* pAskSymbol = NULL;
734 0 : if(NULL != (pAskSymbol = strrchr(localPathNew, '?')))
735 0 : *pAskSymbol = 0;
736 : }
737 : else // from network, on windows, fname is c:\abc123
738 : {
739 0 : strncpy(localPathNew, fname, NPP_PATH_MAX - 1);
740 0 : char* pRandomFilename = NULL;
741 :
742 : #ifdef UNIX
743 0 : if(NULL != (pRandomFilename = strrchr(localPathNew, '/')))
744 : #endif //end of UNIX
745 : #ifdef WNT
746 : if(NULL != (pRandomFilename = strrchr(localPathNew, '\\')))
747 : #endif //end of WNT
748 : {
749 0 : pRandomFilename[1] = 0;
750 : } else {
751 0 : return;
752 : }
753 0 : strcat(localPathNew, filename);
754 0 : char* pAskSymbol = NULL;
755 0 : if(NULL != (pAskSymbol = strrchr(localPathNew, '?')))
756 0 : *pAskSymbol = 0;
757 :
758 0 : sprintf(localFileNew, "file://%s", localPathNew);
759 0 : UnixToDosPath(localFileNew);
760 : debug_fprintf(NSP_LOG_APPEND, "fname: %s\n localPathNew: %s\nlocalFileNew: %s\n",
761 0 : fname, localPathNew, localFileNew);
762 :
763 0 : restoreUTF8(localPathNew);
764 0 : restoreUTF8(localFileNew);
765 0 : if(0 != strcmp(fname, localPathNew)) {
766 :
767 : #ifdef WNT
768 : if(FALSE == CopyFile(fname, localPathNew, FALSE))
769 : return;
770 : #endif //end of WNT
771 :
772 : #ifdef UNIX
773 : int fdSrc, fdDst;
774 0 : if((0 > (fdSrc = open(fname, O_RDONLY)))){
775 0 : return;
776 : }
777 0 : remove(localPathNew);
778 0 : umask(0);
779 0 : if (0 > (fdDst = open(localPathNew, O_WRONLY|O_CREAT,
780 : S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))){
781 0 : close( fdSrc);
782 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:can not create cache file %s. error: %s \n",
783 0 : localPathNew, strerror(errno));
784 0 : return;
785 : }
786 0 : char buffer[NPP_BUFFER_SIZE] = {0};
787 : ssize_t ret;
788 0 : while(0 <= (ret = read(fdSrc, buffer, NPP_BUFFER_SIZE)))
789 : {
790 0 : if (0 == ret)
791 : {
792 0 : if(EINTR == errno)
793 0 : continue;
794 : else
795 :
796 0 : break;
797 : }
798 0 : ssize_t written_bytes = write(fdDst, buffer, ret);
799 0 : if (written_bytes != ret)
800 : {
801 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:short write to %s. error: %s \n",
802 0 : localPathNew, strerror(errno));
803 0 : close(fdSrc);
804 0 : close(fdDst);
805 0 : return;
806 : }
807 : }
808 0 : close(fdSrc);
809 0 : close(fdDst);
810 : #endif //end of UNIX
811 :
812 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:before SetURL\n");
813 : }
814 : }
815 :
816 : // send SO_SET_URl message to inform the new URL
817 : PLUGIN_MSG msg;
818 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
819 0 : msg.msg_id = SO_SET_URL;
820 0 : msg.instance_id = (plugin_Int32)instance;
821 : #ifdef UNIX
822 0 : msg.wnd_id =(plugin_Int32)(This->window);
823 0 : sprintf(msg.url, "file://%s", localPathNew);
824 : #endif //end of UNIX
825 : #ifdef WNT
826 : msg.wnd_id =(plugin_Int32)(This->fhWnd);
827 : sprintf(msg.url, "file:///%s", localPathNew);
828 : DosToUnixPath(msg.url);
829 : #endif //endof WNT
830 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
831 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_URL return failure \n");
832 :
833 : // send SO_SET_WINDOW message
834 : // memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
835 0 : msg.msg_id = SO_SET_WINDOW;
836 0 : msg.instance_id = (plugin_Int32)instance;
837 : // msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->window;
838 : #ifdef UNIX
839 0 : msg.wnd_x = This->x;
840 0 : msg.wnd_y = This->y;
841 0 : msg.wnd_w = This->width;
842 0 : msg.wnd_h = This->height;
843 : #endif //end of UNIX
844 : #ifdef WNT
845 : msg.wnd_x = This->fWindow->x;
846 : msg.wnd_y = This->fWindow->y;
847 : msg.wnd_w = This->fWindow->width;
848 : msg.wnd_h = This->fWindow->height;
849 : #endif //endof WNT
850 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
851 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_WINDOW return failure \n");
852 : }
853 :
854 : NP_DLLPUBLIC void NP_LOADDS
855 0 : NPP_URLNotify(NPP /*instance*/, const char* /*url*/,
856 : NPReason /*reason*/, void* /*notifyData*/)
857 : {
858 0 : }
859 :
860 :
861 : NP_DLLPUBLIC void NP_LOADDS
862 0 : NPP_Print(NPP instance, NPPrint* printInfo)
863 : {
864 0 : if(printInfo == NULL)
865 0 : return;
866 :
867 0 : if (instance != NULL) {
868 : /***** Insert NPP_Print code here *****/
869 0 : PluginInstance* This = (PluginInstance*) instance->pdata;
870 : (void)This;
871 : PLUGIN_MSG msg;
872 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
873 0 : msg.msg_id = SO_PRINT;
874 0 : msg.instance_id = (plugin_Int32)instance;
875 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
876 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_WINDOW return failure \n");
877 0 : printInfo->mode = TRUE;
878 : /**************************************/
879 :
880 0 : if (printInfo->mode == NP_FULL) {
881 : /*
882 : * PLUGIN DEVELOPERS:
883 : * If your plugin would like to take over
884 : * printing completely when it is in full-screen mode,
885 : * set printInfo->pluginPrinted to TRUE and print your
886 : * plugin as you see fit. If your plugin wants Netscape
887 : * to handle printing in this case, set
888 : * printInfo->pluginPrinted to FALSE (the default) and
889 : * do nothing. If you do want to handle printing
890 : * yourself, printOne is true if the print button
891 : * (as opposed to the print menu) was clicked.
892 : * On the Macintosh, platformPrint is a THPrint; on
893 : * Windows, platformPrint is a structure
894 : * (defined in npapi.h) containing the printer name, port,
895 : * etc.
896 : */
897 :
898 : /***** Insert NPP_Print code here *****\
899 : void* platformPrint =
900 : printInfo->print.fullPrint.platformPrint;
901 : NPBool printOne =
902 : printInfo->print.fullPrint.printOne;
903 : \**************************************/
904 :
905 : /* Do the default*/
906 0 : printInfo->print.fullPrint.pluginPrinted = FALSE;
907 : }
908 : else { /* If not fullscreen, we must be embedded */
909 : /*
910 : * PLUGIN DEVELOPERS:
911 : * If your plugin is embedded, or is full-screen
912 : * but you returned false in pluginPrinted above, NPP_Print
913 : * will be called with mode == NP_EMBED. The NPWindow
914 : * in the printInfo gives the location and dimensions of
915 : * the embedded plugin on the printed page. On the
916 : * Macintosh, platformPrint is the printer port; on
917 : * Windows, platformPrint is the handle to the printing
918 : * device context.
919 : */
920 :
921 : /***** Insert NPP_Print code here *****\
922 : NPWindow* printWindow =
923 : &(printInfo->print.embedPrint.window);
924 : void* platformPrint =
925 : printInfo->print.embedPrint.platformPrint;
926 : \**************************************/
927 : }
928 : }
929 : }
930 :
931 : }// end of extern "C"
932 :
933 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|