summaryrefslogtreecommitdiff
path: root/extensions/source/nsplugin/source/npshell.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/nsplugin/source/npshell.cxx')
-rw-r--r--extensions/source/nsplugin/source/npshell.cxx930
1 files changed, 930 insertions, 0 deletions
diff --git a/extensions/source/nsplugin/source/npshell.cxx b/extensions/source/nsplugin/source/npshell.cxx
new file mode 100644
index 000000000000..94edb1b0e48c
--- /dev/null
+++ b/extensions/source/nsplugin/source/npshell.cxx
@@ -0,0 +1,930 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#ifdef OS2
+#define UNIX
+#endif
+
+#ifdef UNIX
+
+#define XP_UNIX 1
+
+#include <strings.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#endif //end of UNIX
+
+#ifdef WNT
+
+#define _WINDOWS
+
+#pragma warning (push,1)
+#pragma warning (disable:4668)
+
+#include <windows.h>
+#include <direct.h>
+#include <stdlib.h>
+#include <io.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#pragma warning (pop)
+
+#endif //end of WNT
+
+
+#include <stdio.h>
+
+#include <string.h>
+#include <errno.h>
+#include "boost/scoped_array.hpp"
+#include "tools/pathutils.hxx"
+
+//http://qa.openoffice.org/issues/show_bug.cgi?id=82545
+//https://bugzilla.mozilla.org/show_bug.cgi?id=241262
+#ifdef UNIX
+# ifndef _UINT32
+# if defined(__alpha) || defined(__LP64__)
+ typedef unsigned int uint32;
+# else /* __alpha */
+ typedef unsigned long uint32;
+# endif
+# define _UINT32
+# endif
+# ifndef _INT32
+# if defined(__alpha) || defined(__LP64__)
+ typedef int int32;
+# else /* __alpha */
+ typedef long int32;
+# endif
+# define _INT32
+# endif
+#endif
+
+#include "npapi.h"
+#include "npshell.hxx"
+#include "so_env.hxx"
+#include "so_msg.hxx"
+#include "ns_debug.hxx"
+
+
+#include "nsp_func.hxx"
+
+#include <comphelper/documentconstants.hxx>
+
+/***********************************************************************
+ *
+ * Implementations of plugin API functions
+ *
+ ***********************************************************************/
+
+static NSP_Mute_Obj send_lock = NSP_New_Mute_Obj();
+static NSP_PIPE_FD write_fd = 0;
+
+
+long int NSP_WriteToPipe(NSP_PIPE_FD fp, void* buf, unsigned long int len)
+{
+ unsigned long int len_unix = 0, len_wnt = 0;
+
+ len_unix = NSP_Write_Pipe(fp, buf, len, &len_wnt);
+#ifdef UNIX
+ (void)len_wnt;
+ return len_unix;
+#endif //end of UNIX
+#ifdef WNT
+ return len_wnt;
+#endif //end of WNT
+
+}
+
+#ifdef UNIX
+static pid_t nChildPID = 0;
+#endif
+
+#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1)
+#define MY_STRING(s) (s), MY_LENGTH(s)
+
+#if defined WNT
+namespace {
+
+bool extendEnvironment(
+ boost::scoped_array< WCHAR > * environment, WCHAR const * pathBegin,
+ WCHAR const * pathEnd)
+{
+ WCHAR ure[MAX_PATH];
+ if (tools::buildPath(ure, pathBegin, pathEnd, MY_STRING(L"\\ure-link")) ==
+ NULL)
+ {
+ return false;
+ }
+ WCHAR * ureEnd = tools::resolveLink(ure);
+ if (ureEnd == NULL) {
+ return false;
+ }
+ ureEnd = tools::buildPath(ure, ure, ureEnd, MY_STRING(L"\\bin"));
+ if (ureEnd == NULL) {
+ return false;
+ }
+ WCHAR const * env = GetEnvironmentStringsW();
+ if (env == NULL) {
+ return false;
+ }
+ WCHAR const * p = env;
+ WCHAR const * p1 = NULL;
+ while (*p != L'\0') {
+ size_t n = wcslen(p);
+ if (p1 == NULL && n >= MY_LENGTH(L"PATH=") &&
+ (p[0] == L'P' || p[0] == L'p') &&
+ (p[1] == L'A' || p[1] == L'a') &&
+ (p[2] == L'T' || p[2] == L't') &&
+ (p[3] == L'H' || p[3] == L'h') && p[4] == L'=')
+ {
+ p1 = p + MY_LENGTH(L"PATH=");
+ //TODO: check whether the ure path is already present in PATH (at
+ // the beginning of PATH?)
+ }
+ p += n + 1;
+ }
+ ++p;
+ if (p1 == NULL) {
+ environment->reset(
+ new WCHAR[MY_LENGTH(L"PATH=") + (ureEnd - ure) + 1 + (p - env)]);
+ //TODO: overflow
+ memcpy(environment->get(), MY_STRING(L"PATH=") * sizeof (WCHAR));
+ memcpy(
+ environment->get() + MY_LENGTH(L"PATH="), ure,
+ ((ureEnd - ure) + 1) * sizeof (WCHAR));
+ memcpy(
+ environment->get() + MY_LENGTH(L"PATH=") + (ureEnd - ure) + 1, env,
+ (p - env) * sizeof (WCHAR));
+ } else {
+ environment->reset(
+ new WCHAR[(p - env) + (ureEnd - ure) + MY_LENGTH(L";")]);
+ //TODO: overflow
+ memcpy(environment->get(), env, (p1 - env) * sizeof (WCHAR));
+ memcpy(
+ environment->get() + (p1 - env), ure,
+ (ureEnd - ure) * sizeof (WCHAR));
+ environment->get()[(p1 - env) + (ureEnd - ure)] = L';';
+ memcpy(
+ environment->get() + (p1 - env) + (ureEnd - ure) + 1, p1,
+ (p - p1) * sizeof (WCHAR));
+ }
+ return true;
+}
+
+}
+#endif
+
+// start nspluin executable in child process, and use pipe to talk with it
+int do_init_pipe()
+{
+ debug_fprintf(NSP_LOG_APPEND, "enter do_init_pipe 1\n");
+ NSP_PIPE_FD fd[2];
+
+ if( 0 != NSP_Inherited_Pipe(fd) )
+ return NPERR_GENERIC_ERROR;
+
+ write_fd = fd[1]; // write fd
+#ifdef UNIX
+ // the parent process will wait for the child process in NPP_Shutdown code
+ nChildPID = fork();
+
+ if( ! nChildPID ) // child process
+#endif //end of UNIX
+ {
+#ifdef UNIX
+ char s_read_fd[16] = {0};
+ char s_write_fd[16] = {0};
+ sprintf(s_read_fd, "%d", fd[0]);
+ sprintf(s_write_fd, "%d", fd[1]);
+ char const * instdir = findInstallDir();
+ boost::scoped_array< char > exepath(
+ new char[strlen(instdir) +
+ RTL_CONSTASCII_LENGTH("/basis-link/program/nsplugin") +
+ 1]);
+ sprintf(exepath.get(), "%s/basis-link/program/nsplugin", instdir);
+ char const * progdir = findProgramDir();
+ boost::scoped_array< char > inifilepath(
+ new char[
+ RTL_CONSTASCII_LENGTH(
+ "-env:INIFILENAME=vnd.sun.star.pathname:") +
+ strlen(progdir) + RTL_CONSTASCII_LENGTH("/redirectrc") + 1]);
+ //TODO: overflow
+ sprintf(
+ inifilepath.get(),
+ "-env:INIFILENAME=vnd.sun.star.pathname:%s/redirectrc", progdir);
+ execl(
+ exepath.get(), exepath.get(), s_read_fd, s_write_fd,
+ inifilepath.get(), progdir, NULL);
+ _exit(255);
+#endif //end of UNIX
+#ifdef WNT
+ WCHAR s_read_fd[16] = {0};
+ WCHAR s_write_fd[16] = {0};
+ wsprintfW(s_read_fd, L"%d", fd[0]);
+ wsprintfW(s_write_fd, L"%d", fd[1]);
+ WCHAR brand[MAX_PATH];
+ int brandLen = MultiByteToWideChar(
+ CP_ACP, MB_PRECOMPOSED, findInstallDir(), -1, brand, MAX_PATH);
+ //TODO: conversion errors
+ if (brandLen == 0) {
+ return NPERR_GENERIC_ERROR;
+ }
+ WCHAR path[MAX_PATH];
+ if (tools::buildPath(
+ path, brand, brand + brandLen - 1, MY_STRING(L"\\basis-link"))
+ == NULL)
+ {
+ return NPERR_GENERIC_ERROR;
+ }
+ WCHAR * pathEnd = tools::resolveLink(path);
+ if (pathEnd == NULL) {
+ return NPERR_GENERIC_ERROR;
+ }
+ boost::scoped_array< WCHAR > env;
+ if (!extendEnvironment(&env, path, pathEnd)) {
+ return NPERR_GENERIC_ERROR;
+ }
+ pathEnd = tools::buildPath(
+ path, path, pathEnd, MY_STRING(L"\\program"));
+ if (pathEnd == NULL) {
+ return NPERR_GENERIC_ERROR;
+ }
+ WCHAR exe[MAX_PATH];
+ WCHAR * exeEnd = tools::buildPath(
+ exe, path, pathEnd, MY_STRING(L"\\nsplugin.exe"));
+ if (exeEnd == NULL) {
+ return NPERR_GENERIC_ERROR;
+ }
+ WCHAR * brandEnd = tools::buildPath(
+ brand, brand, brand + brandLen - 1,
+ MY_STRING(L"\\program\\redirect.ini"));
+ if (brandEnd == NULL) {
+ return NPERR_GENERIC_ERROR;
+ }
+ boost::scoped_array< WCHAR > args(
+ new WCHAR[
+ MY_LENGTH(L"\"") + (exeEnd - exe) + MY_LENGTH(L"\" ") +
+ wcslen(s_read_fd) + MY_LENGTH(L" ") + wcslen(s_write_fd) +
+ MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") +
+ (brandEnd - brand) + MY_LENGTH(L"\"") + 1]); //TODO: overflow
+ wsprintfW(
+ args.get(),
+ L"\"%s\" %s %s \"-env:INIFILENAME=vnd.sun.star.pathname:%s\"", exe,
+ s_read_fd, s_write_fd, brand);
+ STARTUPINFOW NSP_StarInfo;
+ memset((void*) &NSP_StarInfo, 0, sizeof(STARTUPINFOW));
+ NSP_StarInfo.cb = sizeof(STARTUPINFOW);
+ PROCESS_INFORMATION NSP_ProcessInfo;
+ memset((void*)&NSP_ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
+ if(!CreateProcessW(
+ exe, args.get(), NULL, NULL, TRUE,
+ CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, env.get(), path,
+ &NSP_StarInfo, &NSP_ProcessInfo))
+ {
+ DWORD Err = GetLastError();
+ (void)Err;
+ }
+#endif //end of WNT
+ }
+ NSP_Close_Pipe(fd[0]);
+ return NPERR_NO_ERROR;
+}
+
+bool sendMsg( PLUGIN_MSG* pMsg, size_t len, int iEnsure)
+{
+ NSP_Lock_Mute_Obj(send_lock);
+ size_t len_w = 0;
+
+ debug_fprintf(NSP_LOG_APPEND, "try to send message type:%d; len: %d\n", pMsg->msg_id, len);
+ /*
+ debug_fprintf(NSP_LOG_APPEND, "NSPlugin Message: msg_id:%d; instance_id:%d;
+ wnd_id:%d;wnd_x:%d;wnd_y:%d;wnd_w:%d;wnd_h:%d; url:%s\n",
+ pMsg->msg_id, pMsg->instance_id, pMsg->wnd_id,
+ pMsg->wnd_x, pMsg->wnd_y, pMsg->wnd_w, pMsg->wnd_h, pMsg->url);*/
+ len_w = NSP_WriteToPipe(write_fd, (void*) pMsg, len);
+ if (len_w != len){
+ if(errno == EPIPE) // If pipe breaks, then init pipe again and resend the msg
+ {
+ if(iEnsure){
+ debug_fprintf(NSP_LOG_APPEND, "send message error, plugin exec need to be restart\n");
+ NSP_Close_Pipe(write_fd);
+ do_init_pipe();
+ len_w = NSP_WriteToPipe(write_fd, (void*) pMsg, len);
+ }
+ }
+ else if(errno == EINTR) // If interrupted by signal, then continue to send
+ {
+ long new_len;
+ debug_fprintf(NSP_LOG_APPEND, "send message error, send intrrupted by singal, resend again\n");
+ new_len = NSP_WriteToPipe(write_fd, (char*)pMsg+len_w, len-len_w);
+ len_w = len_w + new_len;
+ }
+ else // else return error
+ {
+ debug_fprintf(NSP_LOG_APPEND, "send message error :%s.\n", strerror(errno));
+ len_w = 0;
+ }
+ }
+ NSP_Unlock_Mute_Obj(send_lock);
+ debug_fprintf(NSP_LOG_APPEND, "send message success!\n");
+ return len_w == len;
+}
+
+extern "C"
+{
+char* pMimeTypes = const_cast< char* >( "application/vnd.stardivision.calc:sdc:StarCalc 3.0 - 5.0;"
+"application/vnd.stardivision.chart:sds:StarChart 3.0 - 5.0;"
+"application/vnd.stardivision.draw:sda:StarDraw 3.0 - 5.0;"
+"application/vnd.stardivision.impress:sdd:StarImpress 3.0 - 5.0;"
+"application/vnd.stardivision.impress-packed:sdp:StarImpress-packed 3.0 - 5.0;"
+"application/vnd.stardivision.math:smf:StarMath 3.0 - 5.0;"
+"application/vnd.stardivision.writer:vor:StarWriter Template 3.0 - 5.0;"
+"application/vnd.stardivision.writer-global:sgl:StarWriter Global 3.0 - 5.0;"
+"application/vnd.staroffice.writer:sdw:StarWriter 3.0 - 5.0;"
+MIMETYPE_VND_SUN_XML_CALC_ASCII ":sxc:StarOffice 6.0/7 Spreadsheet;"
+MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII":stc:StarOffice 6.0/7 Spreadsheet Template;"
+MIMETYPE_VND_SUN_XML_DRAW_ASCII ":sxd:StarOffice 6.0/7 Drawing;"
+MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII ":std:StarOffice 6.0/7 Drawing Template;"
+MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ":sxi:StarOffice 6.0/7 Presentation;"
+MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII ":sti:StarOffice 6.0/7 Presentation Template;"
+MIMETYPE_VND_SUN_XML_MATH_ASCII ":sxm:StarOffice 6.0/7 Formula;"
+MIMETYPE_VND_SUN_XML_WRITER_ASCII ":sxw:StarOffice 6.0/7 Text Document;"
+MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII ":sxg:StarOffice 6.0/7 Master Document;"
+MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII ":stw:StarOffice 6.0/7 Text Document Template;"
+MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ":odt:OpenDocument Text;"
+MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ":ott:OpenDocument Text Template;"
+MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ":odm:OpenDocument Master Document;"
+MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ":oth:HTML Document Template;"
+MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ":ods:OpenDocument Spreadsheet;"
+MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ":ots:OpenDocument Spreadsheet Template;"
+MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ":odg:OpenDocument Drawing;"
+MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ":otg:OpenDocument Drawing Template;"
+MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII ":odp:OpenDocument Presentation;"
+MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII ":otp:OpenDocument Presentation Template;"
+MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ":odf:OpenDocument Formula;" );
+
+char*
+NPP_GetMIMEDescription(void)
+{
+ debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, NPP_GetMIMEDescription:%s.\n", pMimeTypes);
+ return(pMimeTypes);
+}
+
+#ifdef UNIX
+NPError
+// I am not actually sure wrt this, it ast least compiles with external
+// npapi.h now...
+NPP_GetValue(NPP /*instance*/, NPPVariable variable, void *value)
+{
+ NPError err = NPERR_NO_ERROR;
+
+ switch (variable) {
+ case NPPVpluginNameString:
+ // add here, for dynamic productname
+ *((char **)value) = NSP_getPluginName();
+ break;
+ case NPPVpluginDescriptionString:
+ // add here, for dynamic product description
+ *((char **)value) = NSP_getPluginDesc();
+ break;
+ default:
+ err = NPERR_GENERIC_ERROR;
+ }
+ debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, NPP_GetValue return %d.\n", err);
+ return err;
+}
+
+
+NPMIMEType
+dupMimeType(NPMIMEType type)
+{
+ NPMIMEType mimetype = (NPMIMEType) NPN_MemAlloc(strlen(type)+1);
+ mimetype[strlen(type)] = 0;
+ if (mimetype)
+ strcpy(mimetype, type);
+ return(mimetype);
+}
+#endif // end of UNIX
+
+NPError
+NPP_Initialize(void)
+{
+ debug_fprintf(NSP_LOG_NEW, "NS Plugin begin initialize.\n");
+ return (NPError)do_init_pipe();
+}
+
+#ifdef OJI
+jref
+NPP_GetJavaClass()
+{
+ return NULL;
+}
+#endif
+
+void
+NPP_Shutdown(void)
+{
+ PLUGIN_MSG msg;
+ memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
+ msg.msg_id = SO_SHUTDOWN;
+ sendMsg(&msg, sizeof(PLUGIN_MSG), 0);
+ NSP_Close_Pipe(write_fd);
+
+#ifdef UNIX
+ // on Unix we should wait till the child process is dead
+ int nStatus;
+ waitpid( nChildPID, &nStatus, 0 );
+#endif
+}
+
+NPError
+NPP_New(NPMIMEType pluginType,
+ NPP instance,
+ uint16 mode,
+ int16 /*argc*/,
+ char* /*argn*/[],
+ char* /*argv*/[],
+ NPSavedData* /*saved*/)
+{
+ PluginInstance* This;
+
+ debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, enter NPP_New.\n");
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ instance->pdata = (PluginInstance*)NPN_MemAlloc(sizeof(PluginInstance));
+
+ memset(instance->pdata, 0 , sizeof(PluginInstance));
+ This = (PluginInstance*) instance->pdata;
+
+ if (This == NULL)
+ {
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ }
+
+ memset(This, 0, sizeof(PluginInstance));
+
+ /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
+#ifdef UNIX
+ This->mode = mode;
+ This->type = dupMimeType(pluginType);
+ This->instance = instance;
+ This->pluginsPageUrl = NULL;
+ This->exists = FALSE;
+#endif //end of UNIX
+#ifdef WNT
+ (void)pluginType;
+ This->fWindow = (NPWindow*)NPN_MemAlloc(sizeof(NPWindow));
+ memset(This->fWindow, 0, sizeof (NPWindow));
+ This->fMode = mode;
+ #endif //end of WNT
+ PLUGIN_MSG msg;
+ memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
+ msg.msg_id = SO_NEW_INSTANCE;
+ msg.instance_id = (plugin_Int32)instance;
+ if (!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
+ return NPERR_GENERIC_ERROR;
+
+ NPN_Status(instance, "......");
+ return NPERR_NO_ERROR;
+}
+
+NPError
+NPP_Destroy(NPP instance, NPSavedData** /*save*/)
+{
+ debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, enter NPP_Destroy.\n");
+ PluginInstance* This;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ // Send destroy message
+ PLUGIN_MSG msg;
+ memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
+ msg.msg_id = SO_DESTROY;
+ msg.instance_id = (plugin_Int32)instance;
+#ifdef UNIX
+ msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->window;
+#endif //end of UNIX
+#ifdef WNT
+ msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->fhWnd;
+#endif //end of WNT
+ sendMsg(&msg, sizeof(PLUGIN_MSG), 0);
+
+ // Free the instance space
+ This = (PluginInstance*) instance->pdata;
+ if (This != NULL) {
+#ifdef UNIX
+ if (This->type)
+ NPN_MemFree(This->type);
+ if (This->pluginsPageUrl)
+ NPN_MemFree(This->pluginsPageUrl);
+ if (This->pluginsFileUrl)
+ NPN_MemFree(This->pluginsFileUrl);
+#endif //end of UNIX
+#ifdef WNT
+ if(This->fWindow)
+ NPN_MemFree(This->fWindow);
+#endif //end of WNT
+ NPN_MemFree(instance->pdata);
+ instance->pdata = NULL;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+
+NPError
+NPP_SetWindow(NPP instance, NPWindow* window)
+{
+ PluginInstance* This;
+#ifdef UNIX
+ NPSetWindowCallbackStruct *ws_info;
+#endif //end of UNIX
+
+ debug_fprintf(NSP_LOG_APPEND, "print by Netscape Plugin, received window resize.\n");
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ This = (PluginInstance*) instance->pdata;
+ if (This == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ // Prepare the general part of the SET_WINDOW message
+ PLUGIN_MSG msg;
+ memset((char*)&msg, 0, sizeof(msg));
+ msg.msg_id = SO_SET_WINDOW;
+ msg.instance_id = (plugin_Int32)instance;
+
+ if ( window )
+ {
+ // Set window info for instance
+#ifdef UNIX
+ ws_info = (NPSetWindowCallbackStruct *)window->ws_info;
+ This->window = (Window) window->window;
+ This->x = window->x;
+ This->y = window->y;
+ This->width = window->width;
+ This->height = window->height;
+ This->display = ws_info->display;
+ This->visual = ws_info->visual;
+ This->depth = ws_info->depth;
+ This->colormap = ws_info->colormap;
+#endif //end of UNIX
+#ifdef WNT
+ This->fhWnd = (HWND) window->window;
+ This->fWindow->x = window->x;
+ This->fWindow->y = window->y;
+ This->fWindow->width = window->width;
+ This->fWindow->height = window->height;
+#endif //end of WNT
+ debug_fprintf(NSP_LOG_APPEND, "begin Set window of Office\n");
+ debug_fprintf(NSP_LOG_APPEND, "W=(%d) H=(%d)\n", window->width, window->height);
+
+ // fill the window dependent part of the message
+ msg.wnd_id = (plugin_Int32) window->window;
+ msg.wnd_x = window->x;
+ msg.wnd_y = window->y;
+ msg.wnd_w = window->width;
+ msg.wnd_h = window->height;
+ }
+ else
+ {
+ // empty window pointer usually means closing of the parent window
+#ifdef UNIX
+ ws_info = NULL;
+ This->window = (Window) NULL;
+ This->x = 0;
+ This->y = 0;
+ This->width = 0;
+ This->height = 0;
+ This->display = NULL;
+ This->visual = NULL;
+#endif //end of UNIX
+#ifdef WNT
+ This->fhWnd = (HWND) NULL;
+ This->fWindow->x = 0;
+ This->fWindow->y = 0;
+ This->fWindow->width = 0;
+ This->fWindow->height = 0;
+#endif //end of WNT
+ debug_fprintf(NSP_LOG_APPEND, "Empty window pointer is provided\n");
+
+ // fill the window dependent part of the message
+ msg.wnd_id = (plugin_Int32) NULL;
+ msg.wnd_x = 0;
+ msg.wnd_y = 0;
+ msg.wnd_w = 0;
+ msg.wnd_h = 0;
+ }
+
+ if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
+ {
+ debug_fprintf(NSP_LOG_APPEND, "NPP_SetWindow return failure \n");
+ return NPERR_GENERIC_ERROR;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+
+NPError
+NPP_NewStream(NPP instance,
+ NPMIMEType /*type*/,
+ NPStream* /*stream*/,
+ NPBool /*seekable*/,
+ uint16 *stype)
+{
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ // Notify Mozilla to fetch the remote file into local cache directory
+ *stype=NP_ASFILEONLY;
+
+ return NPERR_NO_ERROR;
+}
+
+
+int32 STREAMBUFSIZE = 0X0FFFFFFF;
+/* If we are reading from a file in NPAsFile
+ * mode so we can take any size stream in our
+ * write call (since we ignore it) */
+
+int32
+NPP_WriteReady(NPP /*instance*/, NPStream* /*stream*/)
+{
+ return STREAMBUFSIZE;
+}
+
+
+int32
+NPP_Write(NPP /*instance*/, NPStream* /*stream*/, int32 /*offset*/, int32 len, void* /*buffer*/)
+{
+ return len; /* The number of bytes accepted */
+}
+
+
+NPError
+NPP_DestroyStream(NPP instance, NPStream* /*stream*/, NPError /*reason*/)
+{
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+ return NPERR_NO_ERROR;
+}
+
+// save fname to another file with the original file name
+void
+NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
+{
+ debug_fprintf(NSP_LOG_APPEND, "Into Stream\n");
+ char* url = (char*)stream->url;
+ char filename[1024] = {0};
+ char* pfilename = NULL;
+ if (NULL != (pfilename = strrchr(url, '/')))
+ {
+ strcpy(filename, pfilename+1);
+ } else {
+ return;
+ }
+
+ int length = strlen(url);
+ debug_fprintf(NSP_LOG_APPEND, "url: %s; length: %d\n", url, length);
+ PluginInstance* This;
+ This = (PluginInstance*) instance->pdata;
+
+ debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile\n");
+
+ // copy cached file to another file with original name
+ char localPathNew[NPP_PATH_MAX] = {0};
+ char localFileNew[NPP_PATH_MAX] = {0};
+ // if the file is from local
+ if (0 == STRNICMP(url, "file:///", strlen("file:///")))
+ {
+ sprintf(localPathNew, "%s", fname);
+ char* pAskSymbol = NULL;
+ if(NULL != (pAskSymbol = strrchr(localPathNew, '?')))
+ *pAskSymbol = 0;
+ }
+ else // from network, on windows, fname is c:\abc123
+ {
+ strncpy(localPathNew, fname, sizeof(localPathNew));
+ char* pRandomFilename = NULL;
+
+#ifdef UNIX
+ if(NULL != (pRandomFilename = strrchr(localPathNew, '/')))
+#endif //end of UNIX
+#ifdef WNT
+ if(NULL != (pRandomFilename = strrchr(localPathNew, '\\')))
+#endif //end of WNT
+ {
+ pRandomFilename[1] = 0;
+ } else {
+ return;
+ }
+ strcat(localPathNew, filename);
+ char* pAskSymbol = NULL;
+ if(NULL != (pAskSymbol = strrchr(localPathNew, '?')))
+ *pAskSymbol = 0;
+
+ sprintf(localFileNew, "file://%s", localPathNew);
+ UnixToDosPath(localFileNew);
+ debug_fprintf(NSP_LOG_APPEND, "fname: %s\n localPathNew: %s\nlocalFileNew: %s\n",
+ fname, localPathNew, localFileNew);
+
+ restoreUTF8(localPathNew);
+ restoreUTF8(localFileNew);
+ if(0 != strcmp(fname, localPathNew)) {
+
+#ifdef WNT
+ if(NULL == CopyFile(fname, localPathNew, FALSE))
+ return;
+#endif //end of WNT
+
+#ifdef UNIX
+ int fdSrc, fdDst;
+ if((0 > (fdSrc = open(fname, O_RDONLY)))){
+ return;
+ }
+ remove(localPathNew);
+ umask(0);
+ if (0 > (fdDst = open(localPathNew, O_WRONLY|O_CREAT,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))){
+ close( fdSrc);
+ debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:can not create cache file %s. error: %s \n",
+ localPathNew, strerror(errno));
+ return;
+ }
+ char buffer[NPP_BUFFER_SIZE] = {0};
+ int ret;
+ while(0 <= (ret = read(fdSrc, buffer, NPP_BUFFER_SIZE)))
+ {
+ if (0 == ret)
+ {
+ if(EINTR == errno)
+ continue;
+ else
+
+ break;
+ }
+ write(fdDst, buffer, ret);
+ }
+ close(fdSrc);
+ close(fdDst);
+#endif //end of UNIX
+
+ debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile:before SetURL\n");
+ }
+ }
+
+ // send SO_SET_URl message to inform the new URL
+ PLUGIN_MSG msg;
+ memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
+ msg.msg_id = SO_SET_URL;
+ msg.instance_id = (plugin_Int32)instance;
+#ifdef UNIX
+ msg.wnd_id =(plugin_Int32)(This->window);
+ sprintf(msg.url, "file://%s", localPathNew);
+#endif //end of UNIX
+#ifdef WNT
+ msg.wnd_id =(int)(This->fhWnd);
+ sprintf(msg.url, "file:///%s", localPathNew);
+ DosToUnixPath(msg.url);
+#endif //endof WNT
+ if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
+ debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_URL return failure \n");
+
+ // send SO_SET_WINDOW message
+// memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
+ msg.msg_id = SO_SET_WINDOW;
+ msg.instance_id = (plugin_Int32)instance;
+// msg.wnd_id =(plugin_Int32)((PluginInstance*) instance->pdata)->window;
+#ifdef UNIX
+ msg.wnd_x = This->x;
+ msg.wnd_y = This->y;
+ msg.wnd_w = This->width;
+ msg.wnd_h = This->height;
+#endif //end of UNIX
+#ifdef WNT
+ msg.wnd_x = This->fWindow->x;
+ msg.wnd_y = This->fWindow->y;
+ msg.wnd_w = This->fWindow->width;
+ msg.wnd_h = This->fWindow->height;
+#endif //endof WNT
+ if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
+ debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_WINDOW return failure \n");
+}
+
+void
+NPP_URLNotify(NPP /*instance*/, const char* /*url*/,
+ NPReason /*reason*/, void* /*notifyData*/)
+{
+}
+
+
+void
+NPP_Print(NPP instance, NPPrint* printInfo)
+{
+ if(printInfo == NULL)
+ return;
+
+ if (instance != NULL) {
+ /***** Insert NPP_Print code here *****/
+ PluginInstance* This = (PluginInstance*) instance->pdata;
+ (void)This;
+ PLUGIN_MSG msg;
+ memset((char*)&msg, 0, sizeof(PLUGIN_MSG));
+ msg.msg_id = SO_PRINT;
+ msg.instance_id = (plugin_Int32)instance;
+ if(!sendMsg(&msg, sizeof(PLUGIN_MSG), 1))
+ debug_fprintf(NSP_LOG_APPEND, "NPP_StreamAsFile send SO_SET_WINDOW return failure \n");
+ printInfo->mode = TRUE;
+ /**************************************/
+
+ if (printInfo->mode == NP_FULL) {
+ /*
+ * PLUGIN DEVELOPERS:
+ * If your plugin would like to take over
+ * printing completely when it is in full-screen mode,
+ * set printInfo->pluginPrinted to TRUE and print your
+ * plugin as you see fit. If your plugin wants Netscape
+ * to handle printing in this case, set
+ * printInfo->pluginPrinted to FALSE (the default) and
+ * do nothing. If you do want to handle printing
+ * yourself, printOne is true if the print button
+ * (as opposed to the print menu) was clicked.
+ * On the Macintosh, platformPrint is a THPrint; on
+ * Windows, platformPrint is a structure
+ * (defined in npapi.h) containing the printer name, port,
+ * etc.
+ */
+
+ /***** Insert NPP_Print code here *****\
+ void* platformPrint =
+ printInfo->print.fullPrint.platformPrint;
+ NPBool printOne =
+ printInfo->print.fullPrint.printOne;
+ \**************************************/
+
+ /* Do the default*/
+ printInfo->print.fullPrint.pluginPrinted = FALSE;
+ }
+ else { /* If not fullscreen, we must be embedded */
+ /*
+ * PLUGIN DEVELOPERS:
+ * If your plugin is embedded, or is full-screen
+ * but you returned false in pluginPrinted above, NPP_Print
+ * will be called with mode == NP_EMBED. The NPWindow
+ * in the printInfo gives the location and dimensions of
+ * the embedded plugin on the printed page. On the
+ * Macintosh, platformPrint is the printer port; on
+ * Windows, platformPrint is the handle to the printing
+ * device context.
+ */
+
+ /***** Insert NPP_Print code here *****\
+ NPWindow* printWindow =
+ &(printInfo->print.embedPrint.window);
+ void* platformPrint =
+ printInfo->print.embedPrint.platformPrint;
+ \**************************************/
+ }
+ }
+}
+
+}// end of extern "C"