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