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 : size_t len = MY_LENGTH(L"\"") + (exeEnd - exe) + MY_LENGTH(L"\" ") +
278 : wcslen(s_read_fd) + MY_LENGTH(L" ") + wcslen(s_write_fd) +
279 : MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") +
280 : (iniEnd - ini) + MY_LENGTH(L"\"") + 1; //TODO: overflow
281 : boost::scoped_array< WCHAR > args(new WCHAR[len]);
282 : _snwprintf(
283 : args.get(), len,
284 : L"\"%s\" %s %s \"-env:INIFILENAME=vnd.sun.star.pathname:%s\"", exe,
285 : s_read_fd, s_write_fd, ini);
286 : STARTUPINFOW NSP_StarInfo;
287 : memset((void*) &NSP_StarInfo, 0, sizeof(STARTUPINFOW));
288 : NSP_StarInfo.cb = sizeof(STARTUPINFOW);
289 : PROCESS_INFORMATION NSP_ProcessInfo;
290 : memset((void*)&NSP_ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
291 : if(!CreateProcessW(
292 : exe, args.get(), NULL, NULL, TRUE,
293 : CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, env.get(), path,
294 : &NSP_StarInfo, &NSP_ProcessInfo))
295 : {
296 : DWORD Err = GetLastError();
297 : (void)Err;
298 : }
299 : #endif //end of WNT
300 : }
301 0 : NSP_Close_Pipe(fd[0]);
302 0 : return NPERR_NO_ERROR;
303 : }
304 :
305 0 : bool sendMsg( PLUGIN_MSG* pMsg, size_t len, int iEnsure)
306 : {
307 0 : NSP_Lock_Mute_Obj(send_lock);
308 0 : size_t len_w = 0;
309 :
310 0 : debug_fprintf(NSP_LOG_APPEND, "try to send message type:%d; len: %d\n", pMsg->msg_id, len);
311 : /*
312 : debug_fprintf(NSP_LOG_APPEND, "NSPlugin Message: msg_id:%d; instance_id:%d;
313 : wnd_id:%d;wnd_x:%d;wnd_y:%d;wnd_w:%d;wnd_h:%d; url:%s\n",
314 : pMsg->msg_id, pMsg->instance_id, pMsg->wnd_id,
315 : pMsg->wnd_x, pMsg->wnd_y, pMsg->wnd_w, pMsg->wnd_h, pMsg->url);*/
316 0 : len_w = NSP_WriteToPipe(write_fd, (void*) pMsg, len);
317 0 : if (len_w != len){
318 0 : if(errno == EPIPE) // If pipe breaks, then init pipe again and resend the msg
319 : {
320 0 : if(iEnsure){
321 0 : debug_fprintf(NSP_LOG_APPEND, "send message error, plugin exec need to be restart\n");
322 0 : NSP_Close_Pipe(write_fd);
323 0 : do_init_pipe();
324 0 : len_w = NSP_WriteToPipe(write_fd, (void*) pMsg, len);
325 : }
326 : }
327 0 : else if(errno == EINTR) // If interrupted by signal, then continue to send
328 : {
329 : long new_len;
330 0 : debug_fprintf(NSP_LOG_APPEND, "send message error, send intrrupted by singal, resend again\n");
331 0 : new_len = NSP_WriteToPipe(write_fd, (char*)pMsg+len_w, len-len_w);
332 0 : len_w = len_w + new_len;
333 : }
334 : else // else return error
335 : {
336 0 : debug_fprintf(NSP_LOG_APPEND, "send message error :%s.\n", strerror(errno));
337 0 : len_w = 0;
338 : }
339 : }
340 0 : NSP_Unlock_Mute_Obj(send_lock);
341 0 : debug_fprintf(NSP_LOG_APPEND, "send message success!\n");
342 0 : return len_w == len;
343 : }
344 :
345 : extern "C"
346 : {
347 : char* pMimeTypes = const_cast< char* >( "application/msword:doc:MS Word 97-2003 document;"
348 : "application/msword:dot:MS Word 97-2003 document template;"
349 : "application/vnd.openxmlformats-officedocument.wordprocessingml.document:docx:MS Word document;"
350 : "application/vnd.ms-word.document.macroenabled.12:docm:MS Word document with macros;"
351 : "application/vnd.openxmlformats-officedocument.wordprocessingml.template:dotx:MS Word document template;"
352 : "application/vnd.ms-word.template.macroenabled.12:dotm:MS Word document template with macros;"
353 : "application/rtf:rtf:Rich Text Format;"
354 : "application/vnd.ms-excel:xls:MS Excel 97-2003 spreadsheet;"
355 : "application/vnd.ms-excel:xlt:MS Excel 97-2003 spreadsheet template;"
356 : "application/vnd.ms-excel:xla:MS Excel 97-2003 spreadsheet;"
357 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:xlsx:MS Excel spreadsheet;"
358 : "application/vnd.ms-excel.sheet.macroenabled.12:xlsm:MS Excel spreadsheet with macros;"
359 : "application/vnd.openxmlformats-officedocument.spreadsheetml.template:xltx:MS Excel spreadsheet template;"
360 : "application/vnd.ms-excel.template.macroenabled.12:xltm:MS Excel spreadsheet template with macros;"
361 : "application/vnd.ms-powerpoint:ppt:MS PowerPoint 97-2003 presentation;"
362 : "application/vnd.openxmlformats-officedocument.presentationml.presentation:pptx:MS PowerPoint presentation;"
363 : "application/vnd.ms-powerpoint.presentation.macroenabled.12:pptm:MS PowerPoint presentation with macros;"
364 : "application/vnd.openxmlformats-officedocument.presentationml.template:potx:MS PowerPoint presentation template;"
365 : "application/vnd.ms-powerpoint.template.macroenabled.12:potm:MS PowerPoint presentation template with macros;"
366 : MIMETYPE_VND_SUN_XML_CALC_ASCII ":sxc:StarOffice 6.0/7 Spreadsheet;"
367 : MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII":stc:StarOffice 6.0/7 Spreadsheet Template;"
368 : MIMETYPE_VND_SUN_XML_DRAW_ASCII ":sxd:StarOffice 6.0/7 Drawing;"
369 : MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII ":std:StarOffice 6.0/7 Drawing Template;"
370 : MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ":sxi:StarOffice 6.0/7 Presentation;"
371 : MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII ":sti:StarOffice 6.0/7 Presentation Template;"
372 : MIMETYPE_VND_SUN_XML_MATH_ASCII ":sxm:StarOffice 6.0/7 Formula;"
373 : MIMETYPE_VND_SUN_XML_WRITER_ASCII ":sxw:StarOffice 6.0/7 Text Document;"
374 : MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII ":sxg:StarOffice 6.0/7 Master Document;"
375 : MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII ":stw:StarOffice 6.0/7 Text Document Template;"
376 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ":odt:OpenDocument Text;"
377 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII "-flat-xml:fodt:OpenDocument Text Flat XML;"
378 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ":ott:OpenDocument Text Template;"
379 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ":odm:OpenDocument Master Document;"
380 : MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ":oth:HTML Document Template;"
381 : MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ":ods:OpenDocument Spreadsheet;"
382 : MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII "-flat-xml:fods:OpenDocument Spreadsheet Flat XML;"
383 : MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ":ots:OpenDocument Spreadsheet Template;"
384 : MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ":odg:OpenDocument Drawing;"
385 : MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII "-flat-xml:fodg:OpenDocument Drawing Flat XML;"
386 : MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ":otg:OpenDocument Drawing Template;"
387 : MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII ":odp:OpenDocument Presentation;"
388 : MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII "-flat-xml:fodp:OpenDocument Presentation Flat XML;"
389 : MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII ":otp:OpenDocument Presentation Template;"
390 : MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ":odf:OpenDocument Formula;" );
391 :
392 : NP_DLLPUBLIC
393 : #ifndef HAVE_NON_CONST_NPP_GETMIMEDESCRIPTION
394 : const
395 : #endif
396 : char*
397 0 : NPP_GetMIMEDescription(void)
398 : {
399 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, NPP_GetMIMEDescription:%s.\n", pMimeTypes);
400 0 : return(pMimeTypes);
401 : }
402 :
403 : #ifdef UNIX
404 : NP_DLLPUBLIC NPError
405 0 : NPP_GetValue(NPP /*instance*/, NPPVariable variable, void *value)
406 : {
407 0 : NPError err = NPERR_NO_ERROR;
408 :
409 0 : switch (variable) {
410 : case NPPVpluginNameString:
411 : // add here, for dynamic productname
412 0 : *((char **)value) = NSP_getPluginName();
413 0 : break;
414 : case NPPVpluginDescriptionString:
415 : // add here, for dynamic product description
416 0 : *((char **)value) = NSP_getPluginDesc();
417 0 : break;
418 : default:
419 0 : err = NPERR_GENERIC_ERROR;
420 : }
421 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, NPP_GetValue return %d.\n", err);
422 0 : return err;
423 : }
424 :
425 :
426 : NPMIMEType
427 0 : dupMimeType(NPMIMEType type)
428 : {
429 0 : NPMIMEType mimetype = (NPMIMEType) NPN_MemAlloc(strlen(type)+1);
430 0 : strcpy(mimetype, type);
431 0 : return(mimetype);
432 : }
433 : #endif // end of UNIX
434 :
435 : NPError
436 0 : NPP_Initialize(void)
437 : {
438 0 : debug_fprintf(NSP_LOG_NEW, "NS Plugin begin initialize.\n");
439 0 : return (NPError)do_init_pipe();
440 : }
441 :
442 : #ifdef OJI
443 : NP_DLLPUBLIC jref
444 : NPP_GetJavaClass()
445 : {
446 : return NULL;
447 : }
448 : #endif
449 :
450 : void
451 0 : NPP_Shutdown(void)
452 : {
453 : PLUGIN_MSG msg;
454 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
455 0 : msg.msg_id = SO_SHUTDOWN;
456 0 : sendMsg(&msg, sizeof(PLUGIN_MSG), 0);
457 0 : NSP_Close_Pipe(write_fd);
458 :
459 : #ifdef UNIX
460 : // on Unix we should wait till the child process is dead
461 : int nStatus;
462 0 : waitpid( nChildPID, &nStatus, 0 );
463 : #endif
464 0 : }
465 :
466 : NP_DLLPUBLIC NPError NP_LOADDS
467 0 : NPP_New(NPMIMEType pluginType,
468 : NPP instance,
469 : uint16_t mode,
470 : int16_t /*argc*/,
471 : char* /*argn*/[],
472 : char* /*argv*/[],
473 : NPSavedData* /*saved*/)
474 : {
475 : PluginInstance* This;
476 :
477 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, enter NPP_New.\n");
478 0 : if (instance == NULL)
479 0 : return NPERR_INVALID_INSTANCE_ERROR;
480 :
481 0 : instance->pdata = (PluginInstance*)NPN_MemAlloc(sizeof(PluginInstance));
482 :
483 0 : memset(instance->pdata, 0 , sizeof(PluginInstance));
484 0 : This = (PluginInstance*) instance->pdata;
485 :
486 0 : if (This == NULL)
487 : {
488 0 : return NPERR_OUT_OF_MEMORY_ERROR;
489 : }
490 :
491 0 : memset(This, 0, sizeof(PluginInstance));
492 :
493 : /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
494 : #ifdef UNIX
495 0 : This->mode = mode;
496 0 : This->type = dupMimeType(pluginType);
497 0 : This->instance = instance;
498 0 : This->pluginsPageUrl = NULL;
499 0 : This->exists = FALSE;
500 : #endif //end of UNIX
501 : #ifdef WNT
502 : (void)pluginType;
503 : This->fWindow = (NPWindow*)NPN_MemAlloc(sizeof(NPWindow));
504 : memset(This->fWindow, 0, sizeof (NPWindow));
505 : This->fMode = mode;
506 : #endif //end of WNT
507 : PLUGIN_MSG msg;
508 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
509 0 : msg.msg_id = SO_NEW_INSTANCE;
510 0 : msg.instance_id = (plugin_Int32)instance;
511 0 : if (!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
512 0 : return NPERR_GENERIC_ERROR;
513 :
514 0 : NPN_Status(instance, "......");
515 0 : return NPERR_NO_ERROR;
516 : }
517 :
518 : NP_DLLPUBLIC NPError NP_LOADDS
519 0 : NPP_Destroy(NPP instance, NPSavedData** /*save*/)
520 : {
521 0 : debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, enter NPP_Destroy.\n");
522 : PluginInstance* This;
523 :
524 0 : if (instance == NULL)
525 0 : return NPERR_INVALID_INSTANCE_ERROR;
526 :
527 : // Send destroy message
528 : PLUGIN_MSG msg;
529 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
530 0 : msg.msg_id = SO_DESTROY;
531 0 : msg.instance_id = (plugin_Int32)instance;
532 : #ifdef UNIX
533 0 : msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->window;
534 : #endif //end of UNIX
535 : #ifdef WNT
536 : msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->fhWnd;
537 : #endif //end of WNT
538 0 : sendMsg(&msg, sizeof(PLUGIN_MSG), 0);
539 :
540 : // Free the instance space
541 0 : This = (PluginInstance*) instance->pdata;
542 0 : if (This != NULL) {
543 : #ifdef UNIX
544 0 : if (This->type)
545 0 : NPN_MemFree(This->type);
546 0 : if (This->pluginsPageUrl)
547 0 : NPN_MemFree(This->pluginsPageUrl);
548 0 : if (This->pluginsFileUrl)
549 0 : NPN_MemFree(This->pluginsFileUrl);
550 : #endif //end of UNIX
551 : #ifdef WNT
552 : if(This->fWindow)
553 : NPN_MemFree(This->fWindow);
554 : #endif //end of WNT
555 0 : NPN_MemFree(instance->pdata);
556 0 : instance->pdata = NULL;
557 : }
558 :
559 0 : return NPERR_NO_ERROR;
560 : }
561 :
562 :
563 : NP_DLLPUBLIC NPError NP_LOADDS
564 0 : NPP_SetWindow(NPP instance, NPWindow* window)
565 : {
566 : PluginInstance* This;
567 : #ifdef UNIX
568 : NPSetWindowCallbackStruct *ws_info;
569 : #endif //end of UNIX
570 :
571 0 : debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, received window resize.\n");
572 0 : if (instance == NULL)
573 0 : return NPERR_INVALID_INSTANCE_ERROR;
574 :
575 0 : This = (PluginInstance*) instance->pdata;
576 0 : if (This == NULL)
577 0 : return NPERR_INVALID_INSTANCE_ERROR;
578 :
579 : // Prepare the general part of the SET_WINDOW message
580 : PLUGIN_MSG msg;
581 0 : memset((char*)&msg, 0, sizeof(msg));
582 0 : msg.msg_id = SO_SET_WINDOW;
583 0 : msg.instance_id = (plugin_Int32)instance;
584 :
585 0 : if ( window )
586 : {
587 : // Set window info for instance
588 : #ifdef UNIX
589 0 : ws_info = (NPSetWindowCallbackStruct *)window->ws_info;
590 0 : This->window = (Window) window->window;
591 0 : This->x = window->x;
592 0 : This->y = window->y;
593 0 : This->width = window->width;
594 0 : This->height = window->height;
595 0 : This->display = ws_info->display;
596 0 : This->visual = ws_info->visual;
597 0 : This->depth = ws_info->depth;
598 0 : This->colormap = ws_info->colormap;
599 : #endif //end of UNIX
600 : #ifdef WNT
601 : This->fhWnd = (HWND) window->window;
602 : This->fWindow->x = window->x;
603 : This->fWindow->y = window->y;
604 : This->fWindow->width = window->width;
605 : This->fWindow->height = window->height;
606 : #endif //end of WNT
607 0 : debug_fprintf(NSP_LOG_APPEND, "begin Set window of Office\n");
608 0 : debug_fprintf(NSP_LOG_APPEND, "W=(%d) H=(%d)\n", window->width, window->height);
609 :
610 : // fill the window dependent part of the message
611 0 : msg.wnd_id = (plugin_Int32) window->window;
612 0 : msg.wnd_x = window->x;
613 0 : msg.wnd_y = window->y;
614 0 : msg.wnd_w = window->width;
615 0 : msg.wnd_h = window->height;
616 : }
617 : else
618 : {
619 : // empty window pointer usually means closing of the parent window
620 : #ifdef UNIX
621 0 : ws_info = NULL;
622 0 : This->window = (Window) NULL;
623 0 : This->x = 0;
624 0 : This->y = 0;
625 0 : This->width = 0;
626 0 : This->height = 0;
627 0 : This->display = NULL;
628 0 : This->visual = NULL;
629 : #endif //end of UNIX
630 : #ifdef WNT
631 : This->fhWnd = (HWND) NULL;
632 : This->fWindow->x = 0;
633 : This->fWindow->y = 0;
634 : This->fWindow->width = 0;
635 : This->fWindow->height = 0;
636 : #endif //end of WNT
637 0 : debug_fprintf(NSP_LOG_APPEND, "Empty window pointer is provided\n");
638 :
639 : // fill the window dependent part of the message
640 0 : msg.wnd_id = (plugin_Int32) NULL;
641 0 : msg.wnd_x = 0;
642 0 : msg.wnd_y = 0;
643 0 : msg.wnd_w = 0;
644 0 : msg.wnd_h = 0;
645 : }
646 :
647 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
648 : {
649 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_SetWindow return failure \n");
650 0 : return NPERR_GENERIC_ERROR;
651 : }
652 :
653 0 : return NPERR_NO_ERROR;
654 : }
655 :
656 :
657 : NP_DLLPUBLIC NPError NP_LOADDS
658 0 : NPP_NewStream(NPP instance,
659 : NPMIMEType /*type*/,
660 : NPStream* /*stream*/,
661 : NPBool /*seekable*/,
662 : uint16_t *stype)
663 : {
664 0 : if (instance == NULL)
665 0 : return NPERR_INVALID_INSTANCE_ERROR;
666 :
667 : // Notify Mozilla to fetch the remote file into local cache directory
668 0 : *stype=NP_ASFILEONLY;
669 :
670 0 : return NPERR_NO_ERROR;
671 : }
672 :
673 :
674 : int32_t STREAMBUFSIZE = 0X0FFFFFFF;
675 : /* If we are reading from a file in NPAsFile
676 : * mode so we can take any size stream in our
677 : * write call (since we ignore it) */
678 :
679 : NP_DLLPUBLIC int32_t NP_LOADDS
680 0 : NPP_WriteReady(NPP /*instance*/, NPStream* /*stream*/)
681 : {
682 0 : return STREAMBUFSIZE;
683 : }
684 :
685 :
686 : NP_DLLPUBLIC int32_t NP_LOADDS
687 0 : NPP_Write(NPP /*instance*/, NPStream* /*stream*/, int32_t /*offset*/, int32_t len, void* /*buffer*/)
688 : {
689 0 : return len; /* The number of bytes accepted */
690 : }
691 :
692 :
693 : NP_DLLPUBLIC NPError NP_LOADDS
694 0 : NPP_DestroyStream(NPP instance, NPStream* /*stream*/, NPError /*reason*/)
695 : {
696 0 : if (instance == NULL)
697 0 : return NPERR_INVALID_INSTANCE_ERROR;
698 0 : return NPERR_NO_ERROR;
699 : }
700 :
701 : // save fname to another file with the original file name
702 : NP_DLLPUBLIC void NP_LOADDS
703 0 : NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
704 : {
705 0 : debug_fprintf(NSP_LOG_APPEND, "Into Stream\n");
706 0 : char* url = (char*)stream->url;
707 0 : char filename[1024] = {0};
708 0 : char* pfilename = NULL;
709 0 : if (NULL != (pfilename = strrchr(url, '/')))
710 : {
711 0 : strcpy(filename, pfilename+1);
712 : } else {
713 0 : return;
714 : }
715 :
716 0 : int length = strlen(url);
717 0 : debug_fprintf(NSP_LOG_APPEND, "url: %s; length: %d\n", url, length);
718 : PluginInstance* This;
719 0 : This = (PluginInstance*) instance->pdata;
720 :
721 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile\n");
722 :
723 : // copy cached file to another file with original name
724 0 : char localPathNew[NPP_PATH_MAX] = {0};
725 0 : char localFileNew[NPP_PATH_MAX] = {0};
726 : // if the file is from local
727 0 : if (0 == STRNICMP(url, "file:///", strlen("file:///")))
728 : {
729 0 : sprintf(localPathNew, "%s", fname);
730 0 : char* pAskSymbol = NULL;
731 0 : if(NULL != (pAskSymbol = strrchr(localPathNew, '?')))
732 0 : *pAskSymbol = 0;
733 : }
734 : else // from network, on windows, fname is c:\abc123
735 : {
736 0 : strncpy(localPathNew, fname, NPP_PATH_MAX - 1);
737 0 : char* pRandomFilename = NULL;
738 :
739 : #ifdef UNIX
740 0 : if(NULL != (pRandomFilename = strrchr(localPathNew, '/')))
741 : #endif //end of UNIX
742 : #ifdef WNT
743 : if(NULL != (pRandomFilename = strrchr(localPathNew, '\\')))
744 : #endif //end of WNT
745 : {
746 0 : pRandomFilename[1] = 0;
747 : } else {
748 0 : return;
749 : }
750 0 : strcat(localPathNew, filename);
751 0 : char* pAskSymbol = NULL;
752 0 : if(NULL != (pAskSymbol = strrchr(localPathNew, '?')))
753 0 : *pAskSymbol = 0;
754 :
755 0 : sprintf(localFileNew, "file://%s", localPathNew);
756 0 : UnixToDosPath(localFileNew);
757 : debug_fprintf(NSP_LOG_APPEND, "fname: %s\n localPathNew: %s\nlocalFileNew: %s\n",
758 0 : fname, localPathNew, localFileNew);
759 :
760 0 : restoreUTF8(localPathNew);
761 0 : restoreUTF8(localFileNew);
762 0 : if(0 != strcmp(fname, localPathNew)) {
763 :
764 : #ifdef WNT
765 : if(FALSE == CopyFile(fname, localPathNew, FALSE))
766 : return;
767 : #endif //end of WNT
768 :
769 : #ifdef UNIX
770 : int fdSrc, fdDst;
771 0 : if((0 > (fdSrc = open(fname, O_RDONLY)))){
772 0 : return;
773 : }
774 0 : remove(localPathNew);
775 0 : umask(0);
776 0 : if (0 > (fdDst = open(localPathNew, O_WRONLY|O_CREAT,
777 : S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))){
778 0 : close( fdSrc);
779 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:can not create cache file %s. error: %s \n",
780 0 : localPathNew, strerror(errno));
781 0 : return;
782 : }
783 0 : char buffer[NPP_BUFFER_SIZE] = {0};
784 : ssize_t ret;
785 0 : while(0 <= (ret = read(fdSrc, buffer, NPP_BUFFER_SIZE)))
786 : {
787 0 : if (0 == ret)
788 : {
789 0 : if(EINTR == errno)
790 0 : continue;
791 : else
792 :
793 0 : break;
794 : }
795 0 : ssize_t written_bytes = write(fdDst, buffer, ret);
796 0 : if (written_bytes != ret)
797 : {
798 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:short write to %s. error: %s \n",
799 0 : localPathNew, strerror(errno));
800 0 : close(fdSrc);
801 0 : close(fdDst);
802 0 : return;
803 : }
804 : }
805 0 : close(fdSrc);
806 0 : close(fdDst);
807 : #endif //end of UNIX
808 :
809 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:before SetURL\n");
810 : }
811 : }
812 :
813 : // send SO_SET_URl message to inform the new URL
814 : PLUGIN_MSG msg;
815 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
816 0 : msg.msg_id = SO_SET_URL;
817 0 : msg.instance_id = (plugin_Int32)instance;
818 : #ifdef UNIX
819 0 : msg.wnd_id =(plugin_Int32)(This->window);
820 0 : sprintf(msg.url, "file://%s", localPathNew);
821 : #endif //end of UNIX
822 : #ifdef WNT
823 : msg.wnd_id =(plugin_Int32)(This->fhWnd);
824 : sprintf(msg.url, "file:///%s", localPathNew);
825 : DosToUnixPath(msg.url);
826 : #endif //endof WNT
827 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
828 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_URL return failure \n");
829 :
830 : // send SO_SET_WINDOW message
831 : // memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
832 0 : msg.msg_id = SO_SET_WINDOW;
833 0 : msg.instance_id = (plugin_Int32)instance;
834 : // msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->window;
835 : #ifdef UNIX
836 0 : msg.wnd_x = This->x;
837 0 : msg.wnd_y = This->y;
838 0 : msg.wnd_w = This->width;
839 0 : msg.wnd_h = This->height;
840 : #endif //end of UNIX
841 : #ifdef WNT
842 : msg.wnd_x = This->fWindow->x;
843 : msg.wnd_y = This->fWindow->y;
844 : msg.wnd_w = This->fWindow->width;
845 : msg.wnd_h = This->fWindow->height;
846 : #endif //endof WNT
847 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
848 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_WINDOW return failure \n");
849 : }
850 :
851 : NP_DLLPUBLIC void NP_LOADDS
852 0 : NPP_URLNotify(NPP /*instance*/, const char* /*url*/,
853 : NPReason /*reason*/, void* /*notifyData*/)
854 : {
855 0 : }
856 :
857 :
858 : NP_DLLPUBLIC void NP_LOADDS
859 0 : NPP_Print(NPP instance, NPPrint* printInfo)
860 : {
861 0 : if(printInfo == NULL)
862 0 : return;
863 :
864 0 : if (instance != NULL) {
865 : /***** Insert NPP_Print code here *****/
866 0 : PluginInstance* This = (PluginInstance*) instance->pdata;
867 : (void)This;
868 : PLUGIN_MSG msg;
869 0 : memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
870 0 : msg.msg_id = SO_PRINT;
871 0 : msg.instance_id = (plugin_Int32)instance;
872 0 : if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
873 0 : debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_WINDOW return failure \n");
874 : /**************************************/
875 :
876 0 : if (printInfo->mode == NP_FULL) {
877 : /*
878 : * PLUGIN DEVELOPERS:
879 : * If your plugin would like to take over
880 : * printing completely when it is in full-screen mode,
881 : * set printInfo->pluginPrinted to TRUE and print your
882 : * plugin as you see fit. If your plugin wants Netscape
883 : * to handle printing in this case, set
884 : * printInfo->pluginPrinted to FALSE (the default) and
885 : * do nothing. If you do want to handle printing
886 : * yourself, printOne is true if the print button
887 : * (as opposed to the print menu) was clicked.
888 : * On the Macintosh, platformPrint is a THPrint; on
889 : * Windows, platformPrint is a structure
890 : * (defined in npapi.h) containing the printer name, port,
891 : * etc.
892 : */
893 :
894 : /***** Insert NPP_Print code here *****\
895 : void* platformPrint =
896 : printInfo->print.fullPrint.platformPrint;
897 : NPBool printOne =
898 : printInfo->print.fullPrint.printOne;
899 : \**************************************/
900 :
901 : /* Do the default*/
902 0 : printInfo->print.fullPrint.pluginPrinted = FALSE;
903 : }
904 : else { /* If not fullscreen, we must be embedded */
905 : /*
906 : * PLUGIN DEVELOPERS:
907 : * If your plugin is embedded, or is full-screen
908 : * but you returned false in pluginPrinted above, NPP_Print
909 : * will be called with mode == NP_EMBED. The NPWindow
910 : * in the printInfo gives the location and dimensions of
911 : * the embedded plugin on the printed page. On the
912 : * Macintosh, platformPrint is the printer port; on
913 : * Windows, platformPrint is the handle to the printing
914 : * device context.
915 : */
916 :
917 : /***** Insert NPP_Print code here *****\
918 : NPWindow* printWindow =
919 : &(printInfo->print.embedPrint.window);
920 : void* platformPrint =
921 : printInfo->print.embedPrint.platformPrint;
922 : \**************************************/
923 : }
924 : }
925 : }
926 :
927 : }// end of extern "C"
928 :
929 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|