? extensions/source/nsplugin/source/¸´¼þ so_instance.cxx ? extensions/source/nsplugin/source/¸´¼þ so_instance.hxx ? extensions/source/nsplugin/source/¸´¼þ so_main.cxx Index: extensions/source/nsplugin/source/so_instance.cxx =================================================================== RCS file: /cvs/util/extensions/source/nsplugin/source/so_instance.cxx,v retrieving revision 1.11 diff -u -p -r1.11 so_instance.cxx --- extensions/source/nsplugin/source/so_instance.cxx 9 Jun 2008 12:32:34 -0000 1.11 +++ extensions/source/nsplugin/source/so_instance.cxx 9 Sep 2008 02:21:27 -0000 @@ -69,15 +69,9 @@ using namespace com::sun::star; char SoPluginInstance::sSO_Dir[] = {0}; Reference< XMultiServiceFactory > SoPluginInstance::mxRemoteMSF = Reference< XMultiServiceFactory >(NULL); -Reference< XMultiServiceFactory > SoPluginInstance::mxLocalMSF = Reference< XMultiServiceFactory >(NULL); -extern "C"{ - sal_Bool restart_office(void); -} - - -SoPluginInstance::SoPluginInstance(long pParent): +SoPluginInstance::SoPluginInstance(long pParent, Reference< XMultiServiceFactory > xMSF): m_xUnoWin(NULL), m_xComponent(NULL), m_xFrame(NULL), @@ -95,135 +89,14 @@ SoPluginInstance::SoPluginInstance(long m_sURL = rtl::OUString::createFromAscii(""); m_hParent = 0; m_pParent = pParent; - m_dParentStyl = 0; + m_dParentStyl = 0; + mxRemoteMSF = xMSF; } SoPluginInstance::~SoPluginInstance() { } -// Start listening staroffice and connect to it -sal_Bool SoPluginInstance::Connect() -{ - Reference< XComponentContext > xComponentContext; - sal_Bool bRetval(sal_False); - - if(mxRemoteMSF.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, remote ServiceManager has been created. no need to create it again.\n"); - return sal_True; - } - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, try to create defaultBootstrap_InitialComponentContext.\n"); -/* -#ifdef UNIX - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, HOME:%s; LANG:%s; LC_ALL:%s; LC_COLLATE:%s; PATH:%s; current dir:%s \n", - getenv("HOME"), getenv("LANG"), getenv("LC_ALL"), getenv("LC_COLLATE"), getenv("PATH"), get_current_dir_name()); -#endif // end of UNIX -*/ - //create local service manager - if(!mxLocalMSF.is()) - { - xComponentContext = defaultBootstrap_InitialComponentContext(); - if (xComponentContext.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, try to create mxLocalMSF.\n"); - mxLocalMSF = Reference< XMultiServiceFactory >::query(xComponentContext->getServiceManager()); - bRetval = sal_True; - if(!mxLocalMSF.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, create mxLocalMSF failure.\n"); - return sal_False; - } - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, create mxLocalMSF success.\n"); - } - else - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, try to create mxLocalMSF false.\n"); - return bRetval; - } - } - - //then try to connect to the remote StarOffice process - bRetval = sal_True; - try - { - const OUString sUnoUrlResolver(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver")); - char para[128] = {0}; - sprintf(para, "uno:socket,host=localhost,port=%d;urp;StarOffice.ServiceManager", SO_SERVER_PORT); - const OUString sResolverArguments(OUString::createFromAscii(para)); - - // Create UnoUrlResolver - Reference < XInterface > rInterface = mxLocalMSF->createInstance(sUnoUrlResolver); - if (!rInterface.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, create sUnoUrlResolver, failure.\n"); - return sal_False; - } - - // Create XUnoUrlResolver by querying Interface of UnoUrlResolver - Reference < com::sun::star::bridge::XUnoUrlResolver > rResolver(rInterface, UNO_QUERY); - if(!rResolver.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, create XUnoUrlResolver, failure.\n"); - return sal_False; - } - - // Resolve the arguments - rInterface = rResolver->resolve(sResolverArguments); - if(!rInterface.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, rResolver->resolve(sResolverArguments), failure\n"); - return sal_False; - } - - // Create XPropertySet - Reference< ::com::sun::star::beans::XPropertySet > xPropSet( rInterface, UNO_QUERY ); - if(!xPropSet.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, xPropSet( rInterface, UNO_QUERY ), failure\n"); - return sal_False; - } - - // Get remote xComponentContext - xPropSet->getPropertyValue( OUString::createFromAscii("DefaultContext") ) >>= xComponentContext; - - // Get the service manager from the remote context - mxRemoteMSF = Reference< XMultiServiceFactory >( xComponentContext->getServiceManager(), UNO_QUERY); - if(!mxRemoteMSF.is()) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, create mcRemoteMSF, failure.\n"); - bRetval = sal_False; - } - } - catch (ConnectionSetupException& ) - { - debug_fprintf(NSP_LOG_APPEND, "couldn't access local resource (possible security resons)\n"); - bRetval = sal_False; - } - catch (NoConnectException& ) - { - debug_fprintf(NSP_LOG_APPEND, "no server listening on the resource\n"); - bRetval = sal_False; - } - catch (IllegalArgumentException& ) - { - debug_fprintf(NSP_LOG_APPEND, "uno url invalid\n"); - bRetval = sal_False; - } - catch (RuntimeException& ) - { - debug_fprintf(NSP_LOG_APPEND, "a remote call was aborted\n"); - bRetval = sal_False; - } - catch (uno::Exception&) - { - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, unknown error while connect to remote Office.\n"); - bRetval = sal_False; - } - debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, connect over.\n"); - return bRetval; -} - sal_Bool SoPluginInstance::SetURL(char* aURL) { debug_fprintf(NSP_LOG_APPEND, "SoPluginInstance::SetURL %s\n", aURL); @@ -240,7 +113,7 @@ sal_Bool SoPluginInstance::SetURL(char* } // plugin window UI part: create window, load document -bool SoPluginInstance::LoadDocument(NSP_HWND hParent) +sal_Bool SoPluginInstance::LoadDocument(NSP_HWND hParent) { // If doc has been loaded, we just resize the window and return if(m_bInit) @@ -249,24 +122,14 @@ bool SoPluginInstance::LoadDocument(NSP_ m_xUnoWin->setPosSize( m_nX, m_nY, m_nWidth, m_nHeight, m_nFlag ); debug_fprintf(NSP_LOG_APPEND, "set windows to x:%d y:%d w:%d h%d falg:%d\n", m_nX, m_nY, m_nWidth, m_nHeight, m_nFlag); - return true; + return sal_True; } // If mxRemoteMSF is not initialized, we assert and return sal_False if(!mxRemoteMSF.is()) { debug_fprintf(NSP_LOG_APPEND, "Remote StarOfiice ServiceManager is not initilzed correctly!\n"); - - // first, try restar office and reconnect - if(!restart_office()){ - debug_fprintf(NSP_LOG_APPEND, "restar office error!\n"); - return false; - } - if(!Connect()){ - debug_fprintf(NSP_LOG_APPEND, "reconnect office error!\n"); - return false; - } - debug_fprintf(NSP_LOG_APPEND, "Restore StarOfiice ServiceManager is not initilzed correctly!\n"); + return sal_False; } try @@ -278,7 +141,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if( !xToolkit.is() ) { debug_fprintf(NSP_LOG_APPEND, "Can not create Toolkit!\n"); - return false; + return sal_False; } // prepare parameters for plugin window @@ -294,7 +157,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if (!xToolkitSystemChildFactory.is()) { debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, get xToolkitSystemChildFactory failure.\n"); - return false; + return sal_False; } debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, try to create plugin container window HWIN:%ld.\n", hParent); @@ -306,7 +169,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if ( !xNewWinPeer.is() ) { debug_fprintf(NSP_LOG_APPEND, "can not create first window\n", hParent); - return false; + return sal_False; } // get interface of first window @@ -314,7 +177,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if( !m_xUnoWin.is() ) { debug_fprintf(NSP_LOG_APPEND, "can not get interface of first window\n", hParent); - return false; + return sal_False; } // initialize window @@ -331,7 +194,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if (!m_xFrame.is()) { debug_fprintf(NSP_LOG_APPEND, "can not create frame\n"); - return false; + return sal_False; } // initialize frame @@ -356,7 +219,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if ( !m_xFramesSupplier.is() ) { debug_fprintf(NSP_LOG_APPEND, "can not get desktop\n"); - return false; + return sal_False; } // get frames @@ -364,7 +227,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if ( !m_xFrames.is() ) { debug_fprintf(NSP_LOG_APPEND, "can not get frames from FramesSupplier\n"); - return false; + return sal_False; } // append m_xFrame to m_xFrames @@ -375,7 +238,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if ( !xLoader.is() ) { debug_fprintf(NSP_LOG_APPEND, "can not get ComponentLoader to load URL\n"); - return false; + return sal_False; } //create stream for the document @@ -385,14 +248,14 @@ bool SoPluginInstance::LoadDocument(NSP_ if(!xSimpleFileAccess.is()) { debug_fprintf(NSP_LOG_APPEND, "can not create SimpleFileAccess to load URL\n"); - return false; + return sal_False; } Reference xInputStream = xSimpleFileAccess->openFileRead( m_sURL ); if(!xInputStream.is()) { debug_fprintf(NSP_LOG_APPEND, "can not create XInputStream for URL\n"); - return false; + return sal_False; } // prepare to load document @@ -434,7 +297,7 @@ bool SoPluginInstance::LoadDocument(NSP_ if ( !m_xComponent.is() ) { debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, Load Componment error\n"); - return false; + return sal_False; } // register the closelistener that will prevent closing of the component @@ -458,13 +321,13 @@ bool SoPluginInstance::LoadDocument(NSP_ if(!m_xDispatcher.is()) { debug_fprintf(NSP_LOG_APPEND, "m_xDispatcher can not be getten\n"); - return false; + return sal_False; } m_xDispatchProvider = Reference< frame::XDispatchProvider >(m_xFrame, uno::UNO_QUERY); if(!m_xDispatchProvider.is()) { debug_fprintf(NSP_LOG_APPEND, "m_xDispatchProvider can not be getten\n"); - return false; + return sal_False; } //try to enable toolbar and tool windows @@ -487,9 +350,9 @@ bool SoPluginInstance::LoadDocument(NSP_ debug_fprintf(NSP_LOG_APPEND, "Unknown exception while loading document in netscape plugin windows\n"); OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); debug_fprintf(NSP_LOG_APPEND, "error: %s \n", o.pData->buffer ); - return false; + return sal_False; } - return true; + return sal_True; } sal_Bool SoPluginInstance::SetSODir(char * sDir) @@ -528,12 +391,8 @@ sal_Bool SoPluginInstance::SetWindow(NSP if(!mxRemoteMSF.is()) { - bRetval = Connect(); // Connect to listening so and get mxRemoteMSF - if(!bRetval) - { - debug_fprintf(NSP_LOG_APPEND, "can not connect to remote service manager\n"); - return sal_False; - } + debug_fprintf(NSP_LOG_APPEND, "Remote StarOfiice ServiceManager is not initilzed correctly!\n"); + return sal_False; } debug_fprintf(NSP_LOG_APPEND, "in SoPluginInstance::SetWindow, begin LoadDocument(hParent)\n"); bRetval = LoadDocument(hParent); // Load document into current window Index: extensions/source/nsplugin/source/so_instance.hxx =================================================================== RCS file: /cvs/util/extensions/source/nsplugin/source/so_instance.hxx,v retrieving revision 1.7 diff -u -p -r1.7 so_instance.hxx --- extensions/source/nsplugin/source/so_instance.hxx 20 May 2008 19:08:52 -0000 1.7 +++ extensions/source/nsplugin/source/so_instance.hxx 9 Sep 2008 02:21:51 -0000 @@ -63,8 +63,6 @@ class SoPluginInstance private: // Service manager of remote Soffice static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxRemoteMSF; - // Service manager of local Soffice - static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxLocalMSF; // Dir where Soffice is in, ie. /Soffice7/program static char sSO_Dir[NPP_PATH_MAX]; int m_nWidth; @@ -93,14 +91,13 @@ private: PluginDocumentClosePreventer* m_pCloseListener; ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseListener > m_xCloseListener; - bool LoadDocument(NSP_HWND hParent); - sal_Bool Connect(void); + sal_Bool LoadDocument(NSP_HWND hParent); long m_dParentStyl; // Old Windows style of parent window public: - SoPluginInstance(long iInstance); + SoPluginInstance(long iInstance, ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF); virtual ~SoPluginInstance(void); virtual sal_Bool SetURL(char* aURL); virtual sal_Bool IsInit(void){return m_bInit;}; Index: extensions/source/nsplugin/source/so_main.cxx =================================================================== RCS file: /cvs/util/extensions/source/nsplugin/source/so_main.cxx,v retrieving revision 1.9 diff -u -p -r1.9 so_main.cxx --- extensions/source/nsplugin/source/so_main.cxx 9 Jun 2008 12:32:46 -0000 1.9 +++ extensions/source/nsplugin/source/so_main.cxx 9 Sep 2008 02:21:51 -0000 @@ -69,6 +69,33 @@ #include "sal/main.h" +#include "rtl/process.h" +#include "rtl/bootstrap.hxx" +#include "rtl/string.hxx" +#include "rtl/ustrbuf.hxx" + +#include "osl/security.hxx" +#include "osl/thread.hxx" + +#include "cppuhelper/bootstrap.hxx" + + + +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/bridge/UnoUrlResolver.hpp" +#include "com/sun/star/bridge/XUnoUrlResolver.hpp" + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +#define ARLEN(x) sizeof (x) / sizeof *(x) + +using namespace ::rtl; +using namespace ::osl; +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + + #define MAX_NODE_NUM 1024 SoPluginInstance* lpInstance[MAX_NODE_NUM]; @@ -159,13 +186,13 @@ int Set_URL(PLUGIN_MSG* pMsg) return -1; } -int New_Instance(PLUGIN_MSG* pMsg) +int New_Instance(PLUGIN_MSG* pMsg, Reference< lang::XMultiServiceFactory > xMSF) { dump_plugin_message(pMsg); int free_no; if( -1 == (free_no = find_free_node())) return -1; - lpInstance[free_no] = new SoPluginInstance(pMsg->instance_id); + lpInstance[free_no] = new SoPluginInstance(pMsg->instance_id, xMSF); return 0; } @@ -212,14 +239,15 @@ int Shutdown() return -1; } -int dispatchMsg(PLUGIN_MSG* pMsg) +int dispatchMsg(PLUGIN_MSG* pMsg, Reference< lang::XMultiServiceFactory > xMSF) { switch(pMsg->msg_id) { case SO_SET_WINDOW: return Set_Window(pMsg); case SO_NEW_INSTANCE: - return New_Instance(pMsg); + if(xMSF.is()) + return New_Instance(pMsg, xMSF); case SO_SET_URL: return Set_URL(pMsg); case SO_DESTROY: @@ -235,109 +263,167 @@ int dispatchMsg(PLUGIN_MSG* pMsg) } } -sal_Bool start_office(NSP_PIPE_FD read_fd) +Reference< lang::XMultiServiceFactory > SAL_CALL start_office(NSP_PIPE_FD read_fd) { - int my_sock; - struct sockaddr_in dst_addr; - char sCommand[NPP_PATH_MAX]; - sCommand[0] = 0; -#ifdef WNT - { - WSADATA wsaData; - WORD wVersionRequested; - - wVersionRequested = MAKEWORD(2,0); - if(WSAStartup(wVersionRequested, &wsaData)) - { - NSP_Close_Pipe(read_fd); - debug_fprintf(NSP_LOG_APPEND, "Can not init socket in Windows.\n"); - return sal_False; - } - } -#endif //end of WNT - memset(&dst_addr, 0, sizeof(dst_addr)); - dst_addr.sin_family = AF_INET; - dst_addr.sin_port = htons(SO_SERVER_PORT); - dst_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - - int count = 0; - int ret = 0; - - my_sock=socket(PF_INET, SOCK_STREAM, 0); - - // if Star Office has been stared, we need not to start it again - ret = connect(my_sock, (struct sockaddr *)&dst_addr, sizeof(dst_addr)); - if(ret == 0) - { - NSP_CloseSocket(my_sock); - debug_fprintf(NSP_LOG_APPEND, "Staroffice already start\n"); - return sal_True; - } - { - debug_fprintf(NSP_LOG_APPEND, "try to star Staroffice\n"); - char para[128] = {0}; - sprintf(para, "-accept=socket,host=0,port=%d;urp", SO_SERVER_PORT); -#ifdef UNIX + Reference< XComponentContext > xRemoteContext; + try + { + OUString path; +#ifdef UNIX boost::scoped_array< char > exepath( new char[( progdir ? strlen( progdir ) : 0 ) + RTL_CONSTASCII_LENGTH( "/soffice" ) + 1] ); if ( progdir ) sprintf( exepath.get(), "%s/soffice", progdir ); else sprintf( exepath.get(), "soffice" ); - - int nChildPID = fork(); - if( ! nChildPID ) // child process - { - NSP_CloseSocket(my_sock); - NSP_Close_Pipe(read_fd); - sprintf(sCommand, "/bin/sh %s -nologo -nodefault %s", exepath.get(), para); - debug_fprintf(NSP_LOG_APPEND,"StarOffice will be started by command: %s\n",sCommand); - execl("/bin/sh", "/bin/sh", exepath.get(), "-nologo", "-nodefault", para, NULL); - _exit(255); + if (!rtl_convertStringToUString( + &path.pData, exepath, strlen(exepath), osl_getThreadTextEncoding(), + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) + { + debug_fprintf(NSP_LOG_APPEND,"bad characters in soffice installation path!\n"); + return Reference< lang::XMultiServiceFactory >(NULL); } #endif //end of UNIX #ifdef WNT - STARTUPINFO NSP_StarInfo; - memset((void*) &NSP_StarInfo, 0, sizeof(STARTUPINFO)); - NSP_StarInfo.cb = sizeof(STARTUPINFO); - PROCESS_INFORMATION NSP_ProcessInfo; - memset((void*)&NSP_ProcessInfo, 0, sizeof(PROCESS_INFORMATION)); - sprintf(para, " -nologo -nodefault -accept=socket,host=0,port=%d;urp", SO_SERVER_PORT); - //sprintf(para, " -accept=socket,host=0,port=%d;urp\n", SO_SERVER_PORT); - SECURITY_ATTRIBUTES NSP_access = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE}; (void)NSP_access; - sprintf(sCommand, "\"%s\" %s", findSofficeExecutable(), para); - debug_fprintf(NSP_LOG_APPEND,"StarOffice will be started by command: %s",sCommand); - BOOL ret = false; - ret = CreateProcess(findSofficeExecutable(), sCommand, NULL, NULL, FALSE, - 0 , NULL, NULL, &NSP_StarInfo, &NSP_ProcessInfo); - if(ret==false){ - debug_fprintf(NSP_LOG_APPEND,"run staroffice error: %u \n", - GetLastError()); - } - else debug_fprintf(NSP_LOG_APPEND,"run staroffice success\n"); -#endif //end of WNT - } - - NSP_Sleep(5); - // try to connect to background SO, thus judge if it is ready - while(0 > connect(my_sock, (struct sockaddr *)&dst_addr, sizeof(dst_addr))) - { - NSP_Sleep(1); - if (count++ >= 120) + char sPath[NPP_PATH_MAX]; + sPath[0] = 0; + sprintf(sPath, "\"%s\"", findSofficeExecutable() ); + if (!rtl_convertStringToUString( + &path.pData, sPath, strlen(sPath), osl_getThreadTextEncoding(), + (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | + RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) { - NSP_CloseSocket(my_sock); - debug_fprintf(NSP_LOG_APPEND, "print by nsplugin, con star remote StarOffice\n"); - return sal_False; + debug_fprintf(NSP_LOG_APPEND,"bad characters in soffice installation path!\n"); + return Reference< lang::XMultiServiceFactory >(NULL); } - debug_fprintf(NSP_LOG_APPEND, "print by nsplugin, Current count: %d\n", count); - } - NSP_CloseSocket(my_sock); - NSP_Sleep(5); - - prepareEnviron(); +#endif //end of WNT - return sal_True; + // create default local component context + Reference< XComponentContext > xLocalContext( + defaultBootstrap_InitialComponentContext() ); + if ( !xLocalContext.is() ) + { + debug_fprintf(NSP_LOG_APPEND,"no local component context!\n"); + return Reference< lang::XMultiServiceFactory >(NULL); + } + + // env string + ::rtl::OUStringBuffer buf; + OUString aIniPath, aOfficeInstPath, aPluginInstPath; + + if(!Bootstrap::get(OUSTR("BRAND_BASE_DIR"), aIniPath)) + { + debug_fprintf(NSP_LOG_APPEND,"failed to get BRAND_BASE_DIR!\n"); + return Reference< lang::XMultiServiceFactory >(NULL); + } + aIniPath += OUSTR("/program/"); + aIniPath += OUSTR(SAL_CONFIGFILE("boostrap")); + Bootstrap aVersionFile(aIniPath); + aVersionFile.getFrom(OUSTR("UserInstallation"), aOfficeInstPath, OUString()); + aVersionFile.getFrom(OUSTR("BaseInstallation"), aPluginInstPath, OUString()); + + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " -env:UserInstallation=" ) ); + buf.append( aOfficeInstPath ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/nsplugin" ) ); + OUString sEnvString( buf.makeStringAndClear() ); + + // accept string + OSL_ASSERT( buf.getLength() == 0 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "-accept=pipe,name=" ) ); + buf.append( aPluginInstPath ); //user installation path as pipe name + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) ); + OUString sConnectStartString( buf.makeStringAndClear() ); + + // arguments + OUString args [] = { + OUSTR( "-nologo" ), + OUSTR( "-nodefault" ), + OUSTR( "-nolockcheck" ), + sConnectStartString, + sEnvString + }; + rtl_uString * ar_args [] = { + args[ 0 ].pData, + args[ 1 ].pData, + args[ 2 ].pData, + args[ 3 ].pData, + args[ 4 ].pData + }; + + // create a URL resolver + Reference< bridge::XUnoUrlResolver > xUrlResolver( + bridge::UnoUrlResolver::create( xLocalContext ) ); + + // connection string + OSL_ASSERT( buf.getLength() == 0 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) ); + buf.append( aPluginInstPath ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( + ";urp;StarOffice.ComponentContext" ) ); + OUString sConnectString( buf.makeStringAndClear() ); + + try + { + // try to connect to office, no need to start instance again if office already started + xRemoteContext.set( + xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW ); + debug_fprintf(NSP_LOG_APPEND, "Staroffice already start\n"); + return Reference< lang::XMultiServiceFactory >(xRemoteContext->getServiceManager(), UNO_QUERY); + } + catch ( connection::NoConnectException & ) + { + } + + // start office process + Security sec; + oslProcess hProcess = 0; + oslProcessError rc = osl_executeProcess( + path.pData, ar_args, ARLEN( ar_args ), + osl_Process_DETACHED, + sec.getHandle(), + 0, // => current working dir + 0, 0, // => no env vars + &hProcess ); + switch ( rc ) + { + case osl_Process_E_None: + osl_freeProcessHandle( hProcess ); + break; + default: + debug_fprintf(NSP_LOG_APPEND, "unmapped error!\n"); + } + + // wait until office is started + for ( int i = 0; i < 240 /* stop the connection after 240 * 500ms */; ++i ) + { + try + { + // try to connect to office + xRemoteContext.set( + xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW ); + return Reference< lang::XMultiServiceFactory >(xRemoteContext->getServiceManager(), UNO_QUERY); + } + catch ( connection::NoConnectException & ) + { + // wait 500 ms, then try to connect again + TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ }; + ::osl::Thread::wait( tv ); + } + } + debug_fprintf(NSP_LOG_APPEND, "Failed to connect to Staroffice in 2 minutes\n"); + return Reference< lang::XMultiServiceFactory >(NULL); + } + catch ( Exception & e) + { + debug_fprintf(NSP_LOG_APPEND, "unexpected UNO exception caught: "); + debug_fprintf(NSP_LOG_APPEND, (sal_Char *)e.Message.getStr()); + return Reference< lang::XMultiServiceFactory >(NULL); + } + } @@ -372,12 +458,13 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) // the program path is provided only on unix, on windows the registry entry is used if ( argc > 4 ) progdir = argv[4]; - if(!start_office(la_read_fd)) + + Reference< lang::XMultiServiceFactory > xFactory = start_office(la_read_fd); + if(!xFactory.is()) { - NSP_Close_Pipe(la_read_fd); + NSP_Close_Pipe(la_read_fd); return -1; } - PLUGIN_MSG nMsg; int len; while(1) @@ -387,7 +474,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) if(len != sizeof(PLUGIN_MSG)) break; debug_fprintf(NSP_LOG_APPEND, "Read message from pipe type %d \n", nMsg.msg_id); - if(-1 == dispatchMsg(&nMsg)) + if(-1 == dispatchMsg(&nMsg, xFactory)) { debug_fprintf(NSP_LOG_APPEND, "plugin will shutdown\n"); break; @@ -397,9 +484,3 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) _exit(0); return EXIT_SUCCESS; // avoid warnings } - -extern "C"{ - sal_Bool restart_office(void){ - return start_office(la_read_fd); - } -}