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