/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_desktop.hxx"

#include "app.hxx"
#include "officeipcthread.hxx"
#include "cmdlineargs.hxx"
#include "dispatchwatcher.hxx"
#include <memory>
#include <stdio.h>
#include <vos/process.hxx>
#include <unotools/bootstrap.hxx>
#include <vcl/svapp.hxx>
#include <vcl/help.hxx>
#include <unotools/configmgr.hxx>
#include <osl/thread.hxx>
#include <rtl/digest.h>
#include <rtl/ustrbuf.hxx>
#include <rtl/instance.hxx>
#include <osl/conditn.hxx>
#include <unotools/moduleoptions.hxx>
#include <rtl/bootstrap.hxx>
#include <rtl/strbuf.hxx>
#include <comphelper/processfactory.hxx>
#include "osl/file.hxx"
#include "rtl/process.h"
#include "tools/getprocessworkingdir.hxx"
#include <string.h>

using namespace vos;
using namespace rtl;
using namespace desktop;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;

const char  *OfficeIPCThread::sc_aTerminationSequence = "InternalIPC::TerminateThread";
const int OfficeIPCThread::sc_nTSeqLength = 28;
const char  *OfficeIPCThread::sc_aShowSequence = "-tofront";
const int OfficeIPCThread::sc_nShSeqLength = 5;
const char  *OfficeIPCThread::sc_aConfirmationSequence = "InternalIPC::ProcessingDone";
const int OfficeIPCThread::sc_nCSeqLength = 27;

namespace { static char const ARGUMENT_PREFIX[] = "InternalIPC::Arguments"; }

// Type of pipe we use
enum PipeMode
{
	PIPEMODE_DONTKNOW,
	PIPEMODE_CREATED,
	PIPEMODE_CONNECTED
};

namespace desktop
{

namespace {

class Parser: public CommandLineArgs::Supplier {
public:
    explicit Parser(rtl::OString const & input): m_input(input) {
        if (!m_input.match(ARGUMENT_PREFIX) ||
            m_input.getLength() == RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX))
        {
            throw CommandLineArgs::Supplier::Exception();
        }
        m_index = RTL_CONSTASCII_LENGTH(ARGUMENT_PREFIX);
        switch (m_input[m_index++]) {
        case '0':
            break;
        case '1':
            {
                rtl::OUString url;
                if (!next(&url, false)) {
                    throw CommandLineArgs::Supplier::Exception();
                }
                m_cwdUrl.reset(url);
                break;
            }
        case '2':
            {
                rtl::OUString path;
                if (!next(&path, false)) {
                    throw CommandLineArgs::Supplier::Exception();
                }
                rtl::OUString url;
                if (osl::FileBase::getFileURLFromSystemPath(path, url) ==
                    osl::FileBase::E_None)
                {
                    m_cwdUrl.reset(url);
                }
                break;
            }
        default:
            throw CommandLineArgs::Supplier::Exception();
        }
    }

    virtual ~Parser() {}

    virtual boost::optional< rtl::OUString > getCwdUrl() { return m_cwdUrl; }

    virtual bool next(rtl::OUString * argument) { return next(argument, true); }

private:
    virtual bool next(rtl::OUString * argument, bool prefix) {
        OSL_ASSERT(argument != NULL);
        if (m_index < m_input.getLength()) {
            if (prefix) {
                if (m_input[m_index] != ',') {
                    throw CommandLineArgs::Supplier::Exception();
                }
                ++m_index;
            }
            rtl::OStringBuffer b;
            while (m_index < m_input.getLength()) {
                char c = m_input[m_index];
                if (c == ',') {
                    break;
                }
                ++m_index;
                if (c == '\\') {
                    if (m_index < m_input.getLength()) {
                        c = m_input[m_index++];
                        switch (c) {
                        case '0':
                            c = '\0';
                            break;
                        case ',':
                        case '\\':
                            break;
                        default:
                            throw CommandLineArgs::Supplier::Exception();
                        }
                    } else {
                        throw CommandLineArgs::Supplier::Exception();
                    }
                }
                b.append(c);
            }
            rtl::OString b2(b.makeStringAndClear());
            if (!rtl_convertStringToUString(
                    &argument->pData, b2.getStr(), b2.getLength(),
                    RTL_TEXTENCODING_UTF8,
                    (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
                     RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
                     RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
            {
                throw CommandLineArgs::Supplier::Exception();
            }
            return true;
        } else {
            return false;
        }
    }

    boost::optional< rtl::OUString > m_cwdUrl;
    rtl::OString m_input;
    sal_Int32 m_index;
};

bool addArgument(
    ByteString * arguments, char prefix, rtl::OUString const & argument)
{
    rtl::OString utf8;
    if (!argument.convertToString(
            &utf8, RTL_TEXTENCODING_UTF8,
            (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
             RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
    {
        return false;
    }
    *arguments += prefix;
    for (sal_Int32 i = 0; i < utf8.getLength(); ++i) {
        char c = utf8[i];
        switch (c) {
        case '\0':
            *arguments += "\\0";
            break;
        case ',':
            *arguments += "\\,";
            break;
        case '\\':
            *arguments += "\\\\";
            break;
        default:
            *arguments += c;
            break;
        }
    }
    return true;
}

}

OfficeIPCThread*	OfficeIPCThread::pGlobalOfficeIPCThread = 0;
namespace { struct Security : public rtl::Static<OSecurity, Security> {}; }
::osl::Mutex*		OfficeIPCThread::pOfficeIPCThreadMutex = 0;


String CreateMD5FromString( const OUString& aMsg )
{
	// PRE: aStr "file"
	// BACK: Str "ababab....0f" Hexcode String

	rtlDigest handle = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
	if ( handle > 0 )
	{
		const sal_uInt8* pData = (const sal_uInt8*)aMsg.getStr();
		sal_uInt32		 nSize = ( aMsg.getLength() * sizeof( sal_Unicode ));
		sal_uInt32		 nMD5KeyLen = rtl_digest_queryLength( handle );
		sal_uInt8*		 pMD5KeyBuffer = new sal_uInt8[ nMD5KeyLen ];

		rtl_digest_init( handle, pData, nSize );
		rtl_digest_update( handle, pData, nSize );
		rtl_digest_get( handle, pMD5KeyBuffer, nMD5KeyLen );
		rtl_digest_destroy( handle );

		// Create hex-value string from the MD5 value to keep the string size minimal
		OUStringBuffer aBuffer( nMD5KeyLen * 2 + 1 );
		for ( sal_uInt32 i = 0; i < nMD5KeyLen; i++ )
			aBuffer.append( (sal_Int32)pMD5KeyBuffer[i], 16 );

		delete [] pMD5KeyBuffer;
		return aBuffer.makeStringAndClear();
	}

	return String();
}

class ProcessEventsClass_Impl
{
public:
	DECL_STATIC_LINK( ProcessEventsClass_Impl, CallEvent, void* pEvent );
	DECL_STATIC_LINK( ProcessEventsClass_Impl, ProcessDocumentsEvent, void* pEvent );
};

IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, CallEvent, void*, pEvent )
{
	// Application events are processed by the Desktop::HandleAppEvent implementation.
	Desktop::HandleAppEvent( *((ApplicationEvent*)pEvent) );
	delete (ApplicationEvent*)pEvent;
	return 0;
}

IMPL_STATIC_LINK_NOINSTANCE( ProcessEventsClass_Impl, ProcessDocumentsEvent, void*, pEvent )
{
	// Documents requests are processed by the OfficeIPCThread implementation
	ProcessDocumentsRequest* pDocsRequest = (ProcessDocumentsRequest*)pEvent;

	if ( pDocsRequest )
	{
		OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
		delete pDocsRequest;
	}
	return 0;
}

void ImplPostForeignAppEvent( ApplicationEvent* pEvent )
{
	Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, CallEvent ), pEvent );
}

void ImplPostProcessDocumentsEvent( ProcessDocumentsRequest* pEvent )
{
	Application::PostUserEvent( STATIC_LINK( NULL, ProcessEventsClass_Impl, ProcessDocumentsEvent ), pEvent );
}

OSignalHandler::TSignalAction SAL_CALL SalMainPipeExchangeSignalHandler::signal(TSignalInfo *pInfo)
{
    if( pInfo->Signal == osl_Signal_Terminate )
		OfficeIPCThread::DisableOfficeIPCThread();
	return (TAction_CallNextHandler);
}

// ----------------------------------------------------------------------------

// The OfficeIPCThreadController implementation is a bookkeeper for all pending requests
// that were created by the OfficeIPCThread. The requests are waiting to be processed by
// our framework loadComponentFromURL function (e.g. open/print request).
// During shutdown the framework is asking OfficeIPCThreadController about pending requests.
// If there are pending requests framework has to stop the shutdown process. It is waiting
// for these requests because framework is not able to handle shutdown and open a document
// concurrently.


// XServiceInfo
OUString SAL_CALL OfficeIPCThreadController::getImplementationName()
throw ( RuntimeException )
{
	return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.OfficeIPCThreadController" ));
}

sal_Bool SAL_CALL OfficeIPCThreadController::supportsService( const OUString& )
throw ( RuntimeException )
{
	return sal_False;
}

Sequence< OUString > SAL_CALL OfficeIPCThreadController::getSupportedServiceNames()
throw ( RuntimeException )
{
	Sequence< OUString > aSeq( 0 );
	return aSeq;
}

// XEventListener
void SAL_CALL OfficeIPCThreadController::disposing( const EventObject& )
throw( RuntimeException )
{
}

// XTerminateListener
void SAL_CALL OfficeIPCThreadController::queryTermination( const EventObject& )
throw( TerminationVetoException, RuntimeException )
{
	// Desktop ask about pending request through our office ipc pipe. We have to
	// be sure that no pending request is waiting because framework is not able to
	// handle shutdown and open a document concurrently.

	if ( OfficeIPCThread::AreRequestsPending() )
		throw TerminationVetoException();
	else
		OfficeIPCThread::SetDowning();
}

void SAL_CALL OfficeIPCThreadController::notifyTermination( const EventObject& )
throw( RuntimeException )
{
}

// ----------------------------------------------------------------------------

::osl::Mutex&	OfficeIPCThread::GetMutex()
{
	// Get or create our mutex for thread-saftey
	if ( !pOfficeIPCThreadMutex )
	{
		::osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() );
		if ( !pOfficeIPCThreadMutex )
			pOfficeIPCThreadMutex = new osl::Mutex;
	}

	return *pOfficeIPCThreadMutex;
}

void OfficeIPCThread::SetDowning()
{
	// We have the order to block all incoming requests. Framework
	// wants to shutdown and we have to make sure that no loading/printing
	// requests are executed anymore.
	::osl::MutexGuard	aGuard( GetMutex() );

	if ( pGlobalOfficeIPCThread )
		pGlobalOfficeIPCThread->mbDowning = true;
}

static bool s_bInEnableRequests = false;

void OfficeIPCThread::EnableRequests( bool i_bEnable )
{
    // switch between just queueing the requests and executing them
	::osl::MutexGuard	aGuard( GetMutex() );

	if ( pGlobalOfficeIPCThread )
    {
        s_bInEnableRequests = true;
		pGlobalOfficeIPCThread->mbRequestsEnabled = i_bEnable;
        if( i_bEnable )
        {
            // hit the compiler over the head
            ProcessDocumentsRequest aEmptyReq = ProcessDocumentsRequest( boost::optional< rtl::OUString >() );
            // trigger already queued requests
            OfficeIPCThread::ExecuteCmdLineRequests( aEmptyReq );
        }
        s_bInEnableRequests = false;
    }
}

sal_Bool OfficeIPCThread::AreRequestsPending()
{
	// Give info about pending requests
	::osl::MutexGuard	aGuard( GetMutex() );
	if ( pGlobalOfficeIPCThread )
		return ( pGlobalOfficeIPCThread->mnPendingRequests > 0 );
	else
		return sal_False;
}

void OfficeIPCThread::RequestsCompleted( int nCount )
{
	// Remove nCount pending requests from our internal counter
	::osl::MutexGuard	aGuard( GetMutex() );
	if ( pGlobalOfficeIPCThread )
	{
		if ( pGlobalOfficeIPCThread->mnPendingRequests > 0 )
			pGlobalOfficeIPCThread->mnPendingRequests -= nCount;
	}
}

OfficeIPCThread::Status OfficeIPCThread::EnableOfficeIPCThread()
{
	::osl::MutexGuard	aGuard( GetMutex() );

	if( pGlobalOfficeIPCThread )
		return IPC_STATUS_OK;

	::rtl::OUString aUserInstallPath;
    ::rtl::OUString aDummy;

	::vos::OStartupInfo aInfo;
	OfficeIPCThread* pThread = new OfficeIPCThread;

	pThread->maPipeIdent = OUString( RTL_CONSTASCII_USTRINGPARAM( "SingleOfficeIPC_" ) );

	// The name of the named pipe is created with the hashcode of the user installation directory (without /user). We have to retrieve
	// this information from a unotools implementation.
	::utl::Bootstrap::PathStatus aLocateResult = ::utl::Bootstrap::locateUserInstallation( aUserInstallPath );
	if ( aLocateResult == ::utl::Bootstrap::PATH_EXISTS || aLocateResult == ::utl::Bootstrap::PATH_VALID)
		aDummy = aUserInstallPath;
	else
	{
		delete pThread;
		return IPC_STATUS_BOOTSTRAP_ERROR;
	}

	// Try to  determine if we are the first office or not! This should prevent multiple
	// access to the user directory !
	// First we try to create our pipe if this fails we try to connect. We have to do this
	// in a loop because the the other office can crash or shutdown between createPipe
	// and connectPipe!!

    OUString            aIniName;
    
    aInfo.getExecutableFile( aIniName );
    sal_uInt32     lastIndex = aIniName.lastIndexOf('/');
    if ( lastIndex > 0 )
    {
        aIniName    = aIniName.copy( 0, lastIndex+1 );
        aIniName    += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
#if defined(WNT) || defined(OS2)
        aIniName    += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
#else
        aIniName    += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
#endif
    }
   
	::rtl::Bootstrap aPerfTuneIniFile( aIniName );
    
    OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
    OUString aPreloadData;
    
    aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "FastPipeCommunication" )), aPreloadData, aDefault );


	OUString aUserInstallPathHashCode;

    if ( aPreloadData.equalsAscii( "1" ))
    {
		sal_Char	szBuffer[32];
		sprintf( szBuffer, "%d", SUPD );
		aUserInstallPathHashCode = OUString( szBuffer, strlen(szBuffer), osl_getThreadTextEncoding() );
    }
	else
		aUserInstallPathHashCode = CreateMD5FromString( aDummy );
	

	// Check result to create a hash code from the user install path
	if ( aUserInstallPathHashCode.getLength() == 0 )
		return IPC_STATUS_BOOTSTRAP_ERROR; // Something completely broken, we cannot create a valid hash code!

	pThread->maPipeIdent = pThread->maPipeIdent + aUserInstallPathHashCode;

	PipeMode nPipeMode = PIPEMODE_DONTKNOW;
	do
	{
		OSecurity &rSecurity = Security::get();
		// #119950# Try to connect pipe first. If connected, means another instance already launched.
		if( pThread->maPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Open, rSecurity )) 
		{
			// #119950# Test if launched in a new terminal session for same user. On Windows platform, normally a user is restricted
			// to have only one terminal session. But if mutiple terminal session for one user is allowed, crash will happen if launched
			// OpenOffice from more than one terminal session. So need to detect and prevent this happen.

			// Will try to create a same name pipe. If creation is successfully, means current instance is launched in a new session.
			vos::OPipe	maSessionPipe;
			if ( maSessionPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Create, rSecurity )) {
				// Can create a pipe with same name. This can only happen in multiple terminal session environment on Windows platform.
				// Will display a warning dialog and exit.
				return IPC_STATUS_MULTI_TS_ERROR;
			} else {
				// Pipe connected to first office
				nPipeMode = PIPEMODE_CONNECTED;
			}

		}
		else if ( pThread->maPipe.create( pThread->maPipeIdent.getStr(), OPipe::TOption_Create, rSecurity )) // Connection not successful, now we try to create
		{
			// Pipe created
			nPipeMode = PIPEMODE_CREATED;
		}
		else
		{
			OPipe::TPipeError eReason = pThread->maPipe.getError();
			if ((eReason == OPipe::E_ConnectionRefused) || (eReason == OPipe::E_invalidError))
				return IPC_STATUS_BOOTSTRAP_ERROR;

			// Wait for second office to be ready
			TimeValue aTimeValue;
			aTimeValue.Seconds = 0;
			aTimeValue.Nanosec = 10000000; // 10ms
			osl::Thread::wait( aTimeValue );
		}

	} while ( nPipeMode == PIPEMODE_DONTKNOW );

	if ( nPipeMode == PIPEMODE_CREATED )
	{
		// Seems we are the one and only, so start listening thread
		pGlobalOfficeIPCThread = pThread;
		pThread->create(); // starts thread
	}
	else
	{
		// Seems another office is running. Pipe arguments to it and self terminate
		pThread->maStreamPipe = pThread->maPipe;

		sal_Bool bWaitBeforeClose = sal_False;
		ByteString aArguments(RTL_CONSTASCII_STRINGPARAM(ARGUMENT_PREFIX));
        rtl::OUString cwdUrl;
        if (!(tools::getProcessWorkingDir(&cwdUrl) &&
              addArgument(&aArguments, '1', cwdUrl)))
        {
            aArguments += '0';
        }
        sal_uInt32 nCount = rtl_getAppCommandArgCount();
        for( sal_uInt32 i=0; i < nCount; i++ )
		{
			rtl_getAppCommandArg( i, &aDummy.pData );
			if( aDummy.indexOf('-',0) != 0 )
			{
                bWaitBeforeClose = sal_True;
			}
            if (!addArgument(&aArguments, ',', aDummy)) {
                return IPC_STATUS_BOOTSTRAP_ERROR;
            }
		}
		// finally, write the string onto the pipe
		pThread->maStreamPipe.write( aArguments.GetBuffer(), aArguments.Len() );
		pThread->maStreamPipe.write( "\0", 1 );

		// wait for confirmation #95361# #95425#
		ByteString aToken(sc_aConfirmationSequence);
		char *aReceiveBuffer = new char[aToken.Len()+1];
		int n = pThread->maStreamPipe.read( aReceiveBuffer, aToken.Len() );
		aReceiveBuffer[n]='\0';

		delete pThread;
		if (aToken.CompareTo(aReceiveBuffer)!= COMPARE_EQUAL) {
			// something went wrong
			delete[] aReceiveBuffer;
			return IPC_STATUS_BOOTSTRAP_ERROR;
		} else {
			delete[] aReceiveBuffer;
			return IPC_STATUS_2ND_OFFICE;
		}
	}

	return IPC_STATUS_OK;
}

void OfficeIPCThread::DisableOfficeIPCThread()
{
	osl::ClearableMutexGuard aMutex( GetMutex() );

	if( pGlobalOfficeIPCThread )
	{
        OfficeIPCThread *pOfficeIPCThread = pGlobalOfficeIPCThread;
		pGlobalOfficeIPCThread = 0;

		// send thread a termination message
		// this is done so the subsequent join will not hang
		// because the thread hangs in accept of pipe
        OPipe Pipe( pOfficeIPCThread->maPipeIdent, OPipe::TOption_Open, Security::get() );
		//Pipe.send( TERMINATION_SEQUENCE, TERMINATION_LENGTH );
        if (Pipe.isValid())
        {
    		Pipe.send( sc_aTerminationSequence, sc_nTSeqLength+1 ); // also send 0-byte

	    	// close the pipe so that the streampipe on the other
    		// side produces EOF
	    	Pipe.close();
        }

		// release mutex to avoid deadlocks
		aMutex.clear();

        OfficeIPCThread::SetReady(pOfficeIPCThread);

		// exit gracefully and join
		pOfficeIPCThread->join();
		delete pOfficeIPCThread;


	}
}

OfficeIPCThread::OfficeIPCThread() :
	mbDowning( false ),
    mbRequestsEnabled( false ),
	mnPendingRequests( 0 ),
	mpDispatchWatcher( 0 )
{
}

OfficeIPCThread::~OfficeIPCThread()
{
	::osl::ClearableMutexGuard	aGuard( GetMutex() );

	if ( mpDispatchWatcher )
		mpDispatchWatcher->release();
	maPipe.close();
	maStreamPipe.close();
	pGlobalOfficeIPCThread = 0;
}

static void AddURLToStringList( const rtl::OUString& aURL, rtl::OUString& aStringList )
{
	if ( aStringList.getLength() )
		aStringList += ::rtl::OUString::valueOf( (sal_Unicode)APPEVENT_PARAM_DELIMITER );
	aStringList += aURL;
}

void OfficeIPCThread::SetReady(OfficeIPCThread* pThread)
{
    if (pThread == NULL) pThread = pGlobalOfficeIPCThread;
    if (pThread != NULL)
    {
        pThread->cReady.set();
    }
}

void SAL_CALL OfficeIPCThread::run()
{
    do
	{
        OPipe::TPipeError
			nError = maPipe.accept( maStreamPipe );


		if( nError == OStreamPipe::E_None )
		{

            // #111143# and others:
            // if we receive a request while the office is displaying some dialog or error during
            // bootstrap, that dialogs event loop might get events that are dispatched by this thread
            // we have to wait for cReady to be set by the real main loop.
            // only reqests that dont dispatch events may be processed before cReady is set.
            cReady.wait();

            // we might have decided to shutdown while we were sleeping
            if (!pGlobalOfficeIPCThread) return;

            // only lock the mutex when processing starts, othewise we deadlock when the office goes
            // down during wait
            osl::ClearableMutexGuard aGuard( GetMutex() );

            ByteString aArguments;
            // test byte by byte
            const int nBufSz = 2048;
            char pBuf[nBufSz];
            int nBytes = 0;
            int nResult = 0;
            // read into pBuf until '\0' is read or read-error
            while ((nResult=maStreamPipe.recv( pBuf+nBytes, nBufSz-nBytes))>0) {
				nBytes += nResult;
				if (pBuf[nBytes-1]=='\0') {
					aArguments += pBuf;
			        break;
		        }
	        }
			// don't close pipe ...

			// #90717# Is this a lookup message from another application? if so, ignore
			if ( aArguments.Len() == 0 )
				continue;

            // is this a termination message ? if so, terminate
            if(( aArguments.CompareTo( sc_aTerminationSequence, sc_nTSeqLength ) == COMPARE_EQUAL ) ||
                    mbDowning ) return;
            String           aEmpty;
            std::auto_ptr< CommandLineArgs > aCmdLineArgs;
            try
            {
                Parser p( aArguments );
                aCmdLineArgs.reset( new CommandLineArgs( p ) );
            }
            catch ( CommandLineArgs::Supplier::Exception & )
            {
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
                fprintf( stderr, "Error in received command line arguments\n" );
#endif
                continue;
            }
            CommandLineArgs	*pCurrentCmdLineArgs = Desktop::GetCommandLineArgs();

			if ( aCmdLineArgs->IsQuickstart() )
			{
				// we have to use application event, because we have to start quickstart service in main thread!!
				ApplicationEvent* pAppEvent =
					new ApplicationEvent( aEmpty, aEmpty,
											"QUICKSTART", aEmpty );
				ImplPostForeignAppEvent( pAppEvent );
			}

			// handle request for acceptor
			sal_Bool bAcceptorRequest = sal_False;
			OUString aAcceptString;
            if ( aCmdLineArgs->GetAcceptString(aAcceptString) && Desktop::CheckOEM()) {
				ApplicationEvent* pAppEvent =
					new ApplicationEvent( aEmpty, aEmpty,
										  "ACCEPT", aAcceptString );
				ImplPostForeignAppEvent( pAppEvent );
				bAcceptorRequest = sal_True;
			}
			// handle acceptor removal
			OUString aUnAcceptString;
			if ( aCmdLineArgs->GetUnAcceptString(aUnAcceptString) ) {
				ApplicationEvent* pAppEvent =
					new ApplicationEvent( aEmpty, aEmpty,
										 "UNACCEPT", aUnAcceptString );
				ImplPostForeignAppEvent( pAppEvent );
				bAcceptorRequest = sal_True;
			}

#ifndef UNX
			// only in non-unix version, we need to handle a -help request
			// in a running instance in order to display  the command line help
			if ( aCmdLineArgs->IsHelp() ) {
				ApplicationEvent* pAppEvent =
					new ApplicationEvent( aEmpty, aEmpty, "HELP", aEmpty );
				ImplPostForeignAppEvent( pAppEvent );
			}
#endif

			sal_Bool bDocRequestSent = sal_False;
			ProcessDocumentsRequest* pRequest = new ProcessDocumentsRequest(
                aCmdLineArgs->getCwdUrl());
            cProcessed.reset();
            pRequest->pcProcessed = &cProcessed;

			// Print requests are not dependent on the -invisible cmdline argument as they are
			// loaded with the "hidden" flag! So they are always checked.
			bDocRequestSent |= aCmdLineArgs->GetPrintList( pRequest->aPrintList );
			bDocRequestSent |= ( aCmdLineArgs->GetPrintToList( pRequest->aPrintToList ) &&
									aCmdLineArgs->GetPrinterName( pRequest->aPrinterName )		);

			if ( !pCurrentCmdLineArgs->IsInvisible() )
			{
				// Read cmdline args that can open/create documents. As they would open a window
				// they are only allowed if the "-invisible" is currently not used!
				bDocRequestSent |= aCmdLineArgs->GetOpenList( pRequest->aOpenList );
				bDocRequestSent |= aCmdLineArgs->GetViewList( pRequest->aViewList );
                bDocRequestSent |= aCmdLineArgs->GetStartList( pRequest->aStartList );
				bDocRequestSent |= aCmdLineArgs->GetForceOpenList( pRequest->aForceOpenList );
				bDocRequestSent |= aCmdLineArgs->GetForceNewList( pRequest->aForceNewList );

				// Special command line args to create an empty document for a given module

                // #i18338# (lo)
                // we only do this if no document was specified on the command line,
                // since this would be inconsistent with the the behaviour of
                // the first process, see OpenClients() (call to OpenDefault()) in app.cxx
                if ( aCmdLineArgs->HasModuleParam() && Desktop::CheckOEM() && (!bDocRequestSent))
				{
					SvtModuleOptions aOpt;
					SvtModuleOptions::EFactory eFactory = SvtModuleOptions::E_WRITER;
					if ( aCmdLineArgs->IsWriter() )
						eFactory = SvtModuleOptions::E_WRITER;
					else if ( aCmdLineArgs->IsCalc() )
						eFactory = SvtModuleOptions::E_CALC;
					else if ( aCmdLineArgs->IsDraw() )
						eFactory = SvtModuleOptions::E_DRAW;
					else if ( aCmdLineArgs->IsImpress() )
						eFactory = SvtModuleOptions::E_IMPRESS;
					else if ( aCmdLineArgs->IsBase() )
						eFactory = SvtModuleOptions::E_DATABASE;
					else if ( aCmdLineArgs->IsMath() )
						eFactory = SvtModuleOptions::E_MATH;
					else if ( aCmdLineArgs->IsGlobal() )
						eFactory = SvtModuleOptions::E_WRITERGLOBAL;
					else if ( aCmdLineArgs->IsWeb() )
						eFactory = SvtModuleOptions::E_WRITERWEB;

                    if ( pRequest->aOpenList.getLength() )
                        pRequest->aModule = aOpt.GetFactoryName( eFactory );
                    else
                        AddURLToStringList( aOpt.GetFactoryEmptyDocumentURL( eFactory ), pRequest->aOpenList );
					bDocRequestSent = sal_True;
				}
            }

            if (!aCmdLineArgs->IsQuickstart() && Desktop::CheckOEM()) {
                sal_Bool bShowHelp = sal_False;
                rtl::OUStringBuffer aHelpURLBuffer;
                if (aCmdLineArgs->IsHelpWriter()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
                } else if (aCmdLineArgs->IsHelpCalc()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
                } else if (aCmdLineArgs->IsHelpDraw()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
                } else if (aCmdLineArgs->IsHelpImpress()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
				} else if (aCmdLineArgs->IsHelpBase()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
                } else if (aCmdLineArgs->IsHelpBasic()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
                } else if (aCmdLineArgs->IsHelpMath()) {
                    bShowHelp = sal_True;
                    aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
                }
                if (bShowHelp) {
                    Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
                    rtl::OUString aTmp;
                    aRet >>= aTmp;
                    aHelpURLBuffer.appendAscii("?Language=");
                    aHelpURLBuffer.append(aTmp);
#if defined UNX
                    aHelpURLBuffer.appendAscii("&System=UNX");
#elif defined WNT
                    aHelpURLBuffer.appendAscii("&System=WIN");
#elif defined OS2
                    aHelpURLBuffer.appendAscii("&System=OS2");
#endif
                    ApplicationEvent* pAppEvent =
                        new ApplicationEvent( aEmpty, aEmpty,
                                              "OPENHELPURL", aHelpURLBuffer.makeStringAndClear());
                    ImplPostForeignAppEvent( pAppEvent );
                }
            }

            if ( bDocRequestSent && Desktop::CheckOEM())
 			{
				// Send requests to dispatch watcher if we have at least one. The receiver
				// is responsible to delete the request after processing it.
                if ( aCmdLineArgs->HasModuleParam() )
                {
                    SvtModuleOptions    aOpt;

                    // Support command line parameters to start a module (as preselection)
                    if ( aCmdLineArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
                        pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
                    else if ( aCmdLineArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
                        pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
                    else if ( aCmdLineArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
                        pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
                    else if ( aCmdLineArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
                        pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
                }


				ImplPostProcessDocumentsEvent( pRequest );
			}
			else
			{
				// delete not used request again
				delete pRequest;
				pRequest = NULL;
			}
			if (( aArguments.CompareTo( sc_aShowSequence, sc_nShSeqLength ) == COMPARE_EQUAL ) ||
				aCmdLineArgs->IsEmpty() )
			{
				// no document was sent, just bring Office to front
				ApplicationEvent* pAppEvent =
						new ApplicationEvent( aEmpty, aEmpty, "APPEAR", aEmpty );
				ImplPostForeignAppEvent( pAppEvent );
			}

			// we don't need the mutex any longer...
			aGuard.clear();
			// wait for processing to finish
            if (bDocRequestSent)
    			cProcessed.wait();
			// processing finished, inform the requesting end
			nBytes = 0;
			while (
                   (nResult = maStreamPipe.send(sc_aConfirmationSequence+nBytes, sc_nCSeqLength-nBytes))>0 &&
                   ((nBytes += nResult) < sc_nCSeqLength) ) ;
			// now we can close, don't we?
			// maStreamPipe.close();

        }
        else
        {
#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
			fprintf( stderr, "Error on accept: %d\n", (int)nError );
#endif
			TimeValue tval;
			tval.Seconds = 1;
			tval.Nanosec = 0;
			sleep( tval );
		}
	} while( schedule() );
}

static void AddToDispatchList(
	DispatchWatcher::DispatchList& rDispatchList,
    boost::optional< rtl::OUString > const & cwdUrl,
	const OUString& aRequestList,
	DispatchWatcher::RequestType nType,
    const OUString& aParam,
    const OUString& aFactory )
{
	if ( aRequestList.getLength() > 0 )
	{
		sal_Int32 nIndex = 0;
		do
		{
			OUString aToken = aRequestList.getToken( 0, APPEVENT_PARAM_DELIMITER, nIndex );
			if ( aToken.getLength() > 0 )
				rDispatchList.push_back(
                    DispatchWatcher::DispatchRequest( nType, aToken, cwdUrl, aParam, aFactory ));
		}
		while ( nIndex >= 0 );
	}
}

sal_Bool OfficeIPCThread::ExecuteCmdLineRequests( ProcessDocumentsRequest& aRequest )
{
    // protect the dispatch list
    osl::ClearableMutexGuard aGuard( GetMutex() );

	static DispatchWatcher::DispatchList	aDispatchList;

	rtl::OUString aEmpty;
	// Create dispatch list for dispatch watcher
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aOpenList, DispatchWatcher::REQUEST_OPEN, aEmpty, aRequest.aModule );
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aViewList, DispatchWatcher::REQUEST_VIEW, aEmpty, aRequest.aModule );
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aStartList, DispatchWatcher::REQUEST_START, aEmpty, aRequest.aModule );
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintList, DispatchWatcher::REQUEST_PRINT, aEmpty, aRequest.aModule );
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aPrintToList, DispatchWatcher::REQUEST_PRINTTO, aRequest.aPrinterName, aRequest.aModule );
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceOpenList, DispatchWatcher::REQUEST_FORCEOPEN, aEmpty, aRequest.aModule );
    AddToDispatchList( aDispatchList, aRequest.aCwdUrl, aRequest.aForceNewList, DispatchWatcher::REQUEST_FORCENEW, aEmpty, aRequest.aModule );

	sal_Bool bShutdown( sal_False );

	if ( pGlobalOfficeIPCThread )
	{
        if( ! pGlobalOfficeIPCThread->AreRequestsEnabled() )
            return bShutdown;
        
		pGlobalOfficeIPCThread->mnPendingRequests += aDispatchList.size();
		if ( !pGlobalOfficeIPCThread->mpDispatchWatcher )
		{
			pGlobalOfficeIPCThread->mpDispatchWatcher = DispatchWatcher::GetDispatchWatcher();
			pGlobalOfficeIPCThread->mpDispatchWatcher->acquire();
		}

        // copy for execute
        DispatchWatcher::DispatchList aTempList( aDispatchList );
        aDispatchList.clear();
        
		aGuard.clear();

		// Execute dispatch requests
		bShutdown = pGlobalOfficeIPCThread->mpDispatchWatcher->executeDispatchRequests( aTempList, s_bInEnableRequests );

		// set processed flag
		if (aRequest.pcProcessed != NULL)
			aRequest.pcProcessed->set();
	}

	return bShutdown;
}

}
