LCOV - code coverage report
Current view: top level - libreoffice/extensions/source/nsplugin/source - npshell.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 256 0.0 %
Date: 2012-12-27 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10