2007/08/10 10:58:31 obr 1.8.4.2: RESYNC: (1.8-1.12); FILE MERGED 2006/12/28 14:32:27 ydario 1.8.4.1: OS/2 initial import
		
			
				
	
	
		
			690 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			690 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*************************************************************************
 | |
|  *
 | |
|  *  OpenOffice.org - a multi-platform office productivity suite
 | |
|  *
 | |
|  *  $RCSfile: dllmgr.cxx,v $
 | |
|  *
 | |
|  *  $Revision: 1.13 $
 | |
|  *
 | |
|  *  last change: $Author: vg $ $Date: 2007-09-20 15:54:49 $
 | |
|  *
 | |
|  *  The Contents of this file are made available subject to
 | |
|  *  the terms of GNU Lesser General Public License Version 2.1.
 | |
|  *
 | |
|  *
 | |
|  *    GNU Lesser General Public License Version 2.1
 | |
|  *    =============================================
 | |
|  *    Copyright 2005 by Sun Microsystems, Inc.
 | |
|  *    901 San Antonio Road, Palo Alto, CA 94303, USA
 | |
|  *
 | |
|  *    This library is free software; you can redistribute it and/or
 | |
|  *    modify it under the terms of the GNU Lesser General Public
 | |
|  *    License version 2.1, as published by the Free Software Foundation.
 | |
|  *
 | |
|  *    This library is distributed in the hope that it will be useful,
 | |
|  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  *    Lesser General Public License for more details.
 | |
|  *
 | |
|  *    You should have received a copy of the GNU Lesser General Public
 | |
|  *    License along with this library; if not, write to the Free Software
 | |
|  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 | |
|  *    MA  02111-1307  USA
 | |
|  *
 | |
|  ************************************************************************/
 | |
| 
 | |
| // MARKER(update_precomp.py): autogen include statement, do not remove
 | |
| #include "precompiled_basic.hxx"
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #ifdef OS2
 | |
| #define INCL_DOSMODULEMGR
 | |
| #include <svpm.h>
 | |
| #endif
 | |
| 
 | |
| #if defined( WIN ) || defined( WNT )
 | |
| #ifndef _SVWIN_H
 | |
| #undef WB_LEFT
 | |
| #undef WB_RIGHT
 | |
| #include <tools/svwin.h>
 | |
| #endif
 | |
| #endif
 | |
| #ifndef _TOOLS_DEBUG_HXX //autogen
 | |
| #include <tools/debug.hxx>
 | |
| #endif
 | |
| #ifndef _STRING_HXX //autogen
 | |
| #include <tools/string.hxx>
 | |
| #endif
 | |
| #ifndef _ERRCODE_HXX //autogen
 | |
| #include <tools/errcode.hxx>
 | |
| #endif
 | |
| #ifndef _SBXVAR_HXX //autogen
 | |
| #include <basic/sbxvar.hxx>
 | |
| #endif
 | |
| #ifndef _SBXCLASS_HXX //autogen
 | |
| #include <basic/sbx.hxx>
 | |
| #endif
 | |
| 
 | |
| #if defined(WIN)
 | |
| typedef HINSTANCE SbiDllHandle;
 | |
| typedef FARPROC SbiDllProc;
 | |
| #elif defined(WNT)
 | |
| typedef HMODULE SbiDllHandle;
 | |
| typedef int(*SbiDllProc)();
 | |
| #elif defined(OS2)
 | |
| typedef HMODULE SbiDllHandle;
 | |
| typedef PFN SbiDllProc;
 | |
| #else
 | |
| typedef void* SbiDllHandle;
 | |
| typedef void* SbiDllProc;
 | |
| #endif
 | |
| 
 | |
| #define _DLLMGR_CXX
 | |
| #include "dllmgr.hxx"
 | |
| #include <basic/sberrors.hxx>
 | |
| 
 | |
| #ifndef WINAPI
 | |
| #ifdef WNT
 | |
| #define WINAPI __far __pascal
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| extern "C" {
 | |
| #if defined(INTEL) && (defined(WIN) || defined(WNT))
 | |
| 
 | |
| extern INT16 WINAPI CallINT( SbiDllProc, char *stack, short nstack);
 | |
| extern INT32 WINAPI CallLNG( SbiDllProc, char *stack, short nstack);
 | |
| #ifndef WNT
 | |
| extern float WINAPI CallSNG( SbiDllProc, char *stack, short nstack);
 | |
| #endif
 | |
| extern double WINAPI CallDBL( SbiDllProc, char *stack, short nstack);
 | |
| extern char* WINAPI CallSTR( SbiDllProc, char *stack, short nstack);
 | |
| // extern CallFIX( SbiDllProc, char *stack, short nstack);
 | |
| 
 | |
| #else
 | |
| 
 | |
| INT16 CallINT( SbiDllProc, char *, short ) { return 0; }
 | |
| INT32 CallLNG( SbiDllProc, char *, short ) { return 0; }
 | |
| float CallSNG( SbiDllProc, char *, short ) { return 0; }
 | |
| double CallDBL( SbiDllProc, char *, short) { return 0; }
 | |
| char* CallSTR( SbiDllProc, char *, short ) { return 0; }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| SV_IMPL_OP_PTRARR_SORT(ImplDllArr,ByteStringPtr)
 | |
| 
 | |
| /* mit Optimierung An stuerzt unter Win95 folgendes Makro ab:
 | |
| declare Sub MessageBeep Lib "user32" (ByVal long)
 | |
| sub main
 | |
|     MessageBeep( 1 )
 | |
| end sub
 | |
| */
 | |
| #if defined (WNT) && defined (MSC)
 | |
| //#pragma optimize ("", off)
 | |
| #endif
 | |
| 
 | |
| //
 | |
| // ***********************************************************************
 | |
| //
 | |
| 
 | |
| class ImplSbiProc : public ByteString
 | |
| {
 | |
|     SbiDllProc pProc;
 | |
|     ImplSbiProc();
 | |
|     ImplSbiProc( const ImplSbiProc& );
 | |
| 
 | |
| public:
 | |
|     ImplSbiProc( const ByteString& rName, SbiDllProc pFunc )
 | |
|         : ByteString( rName ) { pProc = pFunc;  }
 | |
|     SbiDllProc GetProc() const { return pProc; }
 | |
| };
 | |
| 
 | |
| //
 | |
| // ***********************************************************************
 | |
| //
 | |
| 
 | |
| class ImplSbiDll : public ByteString
 | |
| {
 | |
|     ImplDllArr      aProcArr;
 | |
|     SbiDllHandle    hDLL;
 | |
| 
 | |
|     ImplSbiDll( const ImplSbiDll& );
 | |
| public:
 | |
|     ImplSbiDll( const ByteString& rName, SbiDllHandle hHandle )
 | |
|         : ByteString( rName ) { hDLL = hHandle; }
 | |
|     ~ImplSbiDll();
 | |
|     SbiDllHandle GetHandle() const { return hDLL; }
 | |
|     SbiDllProc GetProc( const ByteString& rName ) const;
 | |
|     void InsertProc( const ByteString& rName, SbiDllProc pProc );
 | |
| };
 | |
| 
 | |
| ImplSbiDll::~ImplSbiDll()
 | |
| {
 | |
|     USHORT nCount = aProcArr.Count();
 | |
|     for( USHORT nCur = 0; nCur < nCount; nCur++ )
 | |
|     {
 | |
|         ImplSbiProc* pProc = (ImplSbiProc*)aProcArr.GetObject( nCur );
 | |
|         delete pProc;
 | |
|     }
 | |
| }
 | |
| 
 | |
| SbiDllProc ImplSbiDll::GetProc( const ByteString& rName ) const
 | |
| {
 | |
|     USHORT nPos;
 | |
|     BOOL bRet = aProcArr.Seek_Entry( (ByteStringPtr)&rName, &nPos );
 | |
|     if( bRet )
 | |
|     {
 | |
|         ImplSbiProc* pImplProc = (ImplSbiProc*)aProcArr.GetObject(nPos);
 | |
|         return pImplProc->GetProc();
 | |
|     }
 | |
|     return (SbiDllProc)0;
 | |
| }
 | |
| 
 | |
| void ImplSbiDll::InsertProc( const ByteString& rName, SbiDllProc pProc )
 | |
| {
 | |
|     DBG_ASSERT(aProcArr.Seek_Entry((ByteStringPtr)&rName,0)==0,"InsertProc: Already in table");
 | |
|     ImplSbiProc* pImplProc = new ImplSbiProc( rName, pProc );
 | |
|     aProcArr.Insert( (ByteStringPtr)pImplProc );
 | |
| }
 | |
| 
 | |
| 
 | |
| //
 | |
| // ***********************************************************************
 | |
| //
 | |
| 
 | |
| SbiDllMgr::SbiDllMgr( const SbiDllMgr& )
 | |
| {
 | |
| }
 | |
| 
 | |
| SbiDllMgr::SbiDllMgr()
 | |
| {
 | |
| }
 | |
| 
 | |
| SbiDllMgr::~SbiDllMgr()
 | |
| {
 | |
|     USHORT nCount = aDllArr.Count();
 | |
|     for( USHORT nCur = 0; nCur < nCount; nCur++ )
 | |
|     {
 | |
|         ImplSbiDll* pDll = (ImplSbiDll*)aDllArr.GetObject( nCur );
 | |
|         FreeDllHandle( pDll->GetHandle() );
 | |
|         delete pDll;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void SbiDllMgr::FreeDll( const ByteString& rDllName )
 | |
| {
 | |
|     USHORT nPos;
 | |
|     BOOL bRet = aDllArr.Seek_Entry( (ByteStringPtr)&rDllName, &nPos );
 | |
|     if( bRet )
 | |
|     {
 | |
|         ImplSbiDll* pDll = (ImplSbiDll*)aDllArr.GetObject(nPos);
 | |
|         FreeDllHandle( pDll->GetHandle() );
 | |
|         delete pDll;
 | |
|         aDllArr.Remove( nPos, 1 );
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| ImplSbiDll* SbiDllMgr::GetDll( const ByteString& rDllName )
 | |
| {
 | |
|     USHORT nPos;
 | |
|     ImplSbiDll* pDll = 0;
 | |
|     BOOL bRet = aDllArr.Seek_Entry( (ByteStringPtr)&rDllName, &nPos );
 | |
|     if( bRet )
 | |
|         pDll = (ImplSbiDll*)aDllArr.GetObject(nPos);
 | |
|     else
 | |
|     {
 | |
|         SbiDllHandle hDll = CreateDllHandle( rDllName );
 | |
|         if( hDll )
 | |
|         {
 | |
|             pDll = new ImplSbiDll( rDllName, hDll );
 | |
|             aDllArr.Insert( (ByteStringPtr)pDll );
 | |
|         }
 | |
|     }
 | |
|     return pDll;
 | |
| }
 | |
| 
 | |
| SbiDllProc SbiDllMgr::GetProc( ImplSbiDll* pDll, const ByteString& rProcName )
 | |
| {
 | |
|     DBG_ASSERT(pDll,"GetProc: No dll-ptr");
 | |
|     SbiDllProc pProc;
 | |
|     pProc = pDll->GetProc( rProcName );
 | |
|     if( !pProc )
 | |
|     {
 | |
|         pProc = GetProcAddr( pDll->GetHandle(), rProcName );
 | |
|         if( pProc )
 | |
|             pDll->InsertProc( rProcName, pProc );
 | |
|     }
 | |
|     return pProc;
 | |
| }
 | |
| 
 | |
| 
 | |
| SbError SbiDllMgr::Call( const char* pProcName, const char* pDllName,
 | |
|     SbxArray* pArgs, SbxVariable& rResult, BOOL bCDecl )
 | |
| {
 | |
|     DBG_ASSERT(pProcName&&pDllName,"Call: Bad parms");
 | |
|     SbError nSbErr = 0;
 | |
|     ByteString aDllName( pDllName );
 | |
|     CheckDllName( aDllName );
 | |
|     ImplSbiDll* pDll = GetDll( aDllName );
 | |
|     if( pDll )
 | |
|     {
 | |
|         SbiDllProc pProc = GetProc( pDll, pProcName );
 | |
|         if( pProc )
 | |
|         {
 | |
|             if( bCDecl )
 | |
|                 nSbErr = CallProcC( pProc, pArgs, rResult );
 | |
|             else
 | |
|                 nSbErr = CallProc( pProc, pArgs, rResult );
 | |
|         }
 | |
|         else
 | |
|             nSbErr = SbERR_PROC_UNDEFINED;
 | |
|     }
 | |
|     else
 | |
|         nSbErr = SbERR_BAD_DLL_LOAD;
 | |
|     return nSbErr;
 | |
| }
 | |
| 
 | |
| //  ***********************************************************************
 | |
| //  ******************* abhaengige Implementationen ***********************
 | |
| //  ***********************************************************************
 | |
| 
 | |
| void SbiDllMgr::CheckDllName( ByteString& rDllName )
 | |
| {
 | |
| #if defined(WIN) || defined(WNT) || defined(OS2)
 | |
|     if( rDllName.Search('.') == STRING_NOTFOUND )
 | |
|         rDllName += ".DLL";
 | |
| #else
 | |
|     (void)rDllName;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| SbiDllHandle SbiDllMgr::CreateDllHandle( const ByteString& rDllName )
 | |
| {
 | |
|     (void)rDllName;
 | |
| 
 | |
| #if defined(UNX)
 | |
|     SbiDllHandle hLib=0;
 | |
| #else
 | |
|     SbiDllHandle hLib;
 | |
| #endif
 | |
| 
 | |
| #if defined(WIN)
 | |
|     hLib = LoadLibrary( (const char*)rDllName );
 | |
|     if( (ULONG)hLib < 32 )
 | |
|         hLib = 0;
 | |
| 
 | |
| #elif defined(WNT)
 | |
|     hLib = LoadLibrary( rDllName.GetBuffer() );
 | |
|     if( !(ULONG)hLib  )
 | |
|     {
 | |
| #ifdef DBG_UTIL
 | |
|         ULONG nLastErr;
 | |
|         nLastErr = GetLastError();
 | |
| #endif
 | |
|         hLib = 0;
 | |
|     }
 | |
| 
 | |
| #elif defined(OS2)
 | |
|     char cErr[ 100 ];
 | |
|     if( DosLoadModule( (PSZ) cErr, 100, (const char*)rDllName.GetBuffer(), &hLib ) )
 | |
|         hLib = 0;
 | |
| #endif
 | |
|     return hLib;
 | |
| }
 | |
| 
 | |
| void SbiDllMgr::FreeDllHandle( SbiDllHandle hLib )
 | |
| {
 | |
| #if defined(WIN) || defined(WNT)
 | |
|     if( hLib )
 | |
|         FreeLibrary ((HINSTANCE) hLib);
 | |
| #elif defined(OS2)
 | |
|        if( hLib )
 | |
|                DosFreeModule( (HMODULE) hLib );
 | |
| #else
 | |
|     (void)hLib;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| SbiDllProc SbiDllMgr::GetProcAddr(SbiDllHandle hLib, const ByteString& rProcName)
 | |
| {
 | |
|     char buf1 [128] = "";
 | |
|     char buf2 [128] = "";
 | |
| 
 | |
|     SbiDllProc pProc = 0;
 | |
|     int nOrd = 0;
 | |
| 
 | |
|     // Ordinal?
 | |
|     if( rProcName.GetBuffer()[0] == '@' )
 | |
|         nOrd = atoi( rProcName.GetBuffer()+1 );
 | |
| 
 | |
|     // Moegliche Parameter weg:
 | |
|     DBG_ASSERT( sizeof(buf1) > rProcName.Len(),
 | |
|                 "SbiDllMgr::GetProcAddr: buffer to small!" );
 | |
|     strncpy( buf1, rProcName.GetBuffer(), sizeof(buf1)-1 );
 | |
|     char *p = strchr( buf1, '#' );
 | |
|     if( p )
 | |
|         *p = 0;
 | |
| 
 | |
|     DBG_ASSERT( sizeof(buf2) > strlen(buf1) + 1,
 | |
|                 "SbiDllMgr::GetProcAddr: buffer to small!" );
 | |
|     strncpy( buf2, "_",  sizeof(buf2)-1 );
 | |
|     strncat( buf2, buf1, sizeof(buf2)-1-strlen(buf2) );
 | |
| 
 | |
| #if defined(WIN) || defined(WNT)
 | |
|     if( nOrd > 0 )
 | |
|         pProc = (SbiDllProc)GetProcAddress( hLib, (char*)(long) nOrd );
 | |
|     else
 | |
|     {
 | |
|         // 2. mit Parametern:
 | |
|         pProc = (SbiDllProc)GetProcAddress ( hLib, rProcName.GetBuffer() );
 | |
|         // 3. nur der Name:
 | |
|         if (!pProc)
 | |
|             pProc = (SbiDllProc)GetProcAddress( hLib, buf1 );
 | |
|         // 4. der Name mit Underline vorweg:
 | |
|         if( !pProc )
 | |
|             pProc = (SbiDllProc)GetProcAddress( hLib, buf2 );
 | |
|     }
 | |
| 
 | |
| #elif defined(OS2)
 | |
|     PSZ pp;
 | |
|     APIRET rc;
 | |
|     // 1. Ordinal oder mit Parametern:
 | |
|     rc = DosQueryProcAddr( hLib, nOrd, pp = (char*)rProcName.GetBuffer(), &pProc );
 | |
|     // 2. nur der Name:
 | |
|     if( rc )
 | |
|         rc = DosQueryProcAddr( hLib, 0, pp = (PSZ)buf1, &pProc );
 | |
|     // 3. der Name mit Underline vorweg:
 | |
|     if( rc )
 | |
|         rc = DosQueryProcAddr( hLib, 0, pp = (PSZ)buf2, &pProc );
 | |
|     if( rc )
 | |
|         pProc = NULL;
 | |
|     else
 | |
|     {
 | |
|         // 16-bit oder 32-bit?
 | |
|         ULONG nInfo = 0;
 | |
|         if( DosQueryProcType( hLib, nOrd, pp, &nInfo ) )
 | |
|             nInfo = 0;;
 | |
|     }
 | |
| #else
 | |
|     (void)hLib;
 | |
| #endif
 | |
|     return pProc;
 | |
| }
 | |
| 
 | |
| SbError SbiDllMgr::CallProc( SbiDllProc pProc, SbxArray* pArgs,
 | |
|   SbxVariable& rResult )
 | |
| {
 | |
| //  ByteString aStr("Calling DLL at ");
 | |
| //  aStr += (ULONG)pProc;
 | |
| //  InfoBox( 0, aStr ).Execute();
 | |
|     INT16 nInt16; int nInt; INT32 nInt32; double nDouble;
 | |
|     char* pStr;
 | |
| 
 | |
|     USHORT nSize;
 | |
|     char* pStack = (char*)CreateStack( pArgs, nSize );
 | |
|     switch( rResult.GetType() )
 | |
|     {
 | |
|         case SbxINTEGER:
 | |
|             nInt16 = CallINT(pProc, pStack, (short)nSize );
 | |
|             rResult.PutInteger( nInt16 );
 | |
|             break;
 | |
| 
 | |
|         case SbxUINT:
 | |
|         case SbxUSHORT:
 | |
|             nInt16 = (INT16)CallINT(pProc, pStack, (short)nSize );
 | |
|             rResult.PutUShort( (USHORT)nInt16 );
 | |
|             break;
 | |
| 
 | |
|         case SbxERROR:
 | |
|             nInt16 = (INT16)CallINT(pProc, pStack, (short)nSize );
 | |
|             rResult.PutErr( (USHORT)nInt16 );
 | |
|             break;
 | |
| 
 | |
|         case SbxINT:
 | |
|             nInt = CallINT(pProc, pStack, (short)nSize );
 | |
|             rResult.PutInt( nInt );
 | |
|             break;
 | |
| 
 | |
|         case SbxLONG:
 | |
|             nInt32 = CallLNG(pProc, pStack, (short)nSize );
 | |
|             rResult.PutLong( nInt32 );
 | |
|             break;
 | |
| 
 | |
|         case SbxULONG:
 | |
|             nInt32 = CallINT(pProc, pStack, (short)nSize );
 | |
|             rResult.PutULong( (ULONG)nInt32 );
 | |
|             break;
 | |
| 
 | |
| #ifndef WNT
 | |
|         case SbxSINGLE:
 | |
|         {
 | |
|             float nSingle = CallSNG(pProc, pStack, (short)nSize );
 | |
|             rResult.PutSingle( nSingle );
 | |
|             break;
 | |
|         }
 | |
| #endif
 | |
| 
 | |
|         case SbxDOUBLE:
 | |
| #ifdef WNT
 | |
|         case SbxSINGLE:
 | |
| #endif
 | |
|             nDouble = CallDBL(pProc, pStack, (short)nSize );
 | |
|             rResult.PutDouble( nDouble );
 | |
|             break;
 | |
| 
 | |
|         case SbxDATE:
 | |
|             nDouble = CallDBL(pProc, pStack, (short)nSize );
 | |
|             rResult.PutDate( nDouble );
 | |
|             break;
 | |
| 
 | |
|         case SbxCHAR:
 | |
|         case SbxBYTE:
 | |
|         case SbxBOOL:
 | |
|             nInt16 = CallINT(pProc, pStack, (short)nSize );
 | |
|             rResult.PutByte( (BYTE)nInt16 );
 | |
|             break;
 | |
| 
 | |
|         case SbxSTRING:
 | |
|         case SbxLPSTR:
 | |
|             pStr = CallSTR(pProc, pStack, (short)nSize );
 | |
|             rResult.PutString( String::CreateFromAscii( pStr ) );
 | |
|             break;
 | |
| 
 | |
|         case SbxNULL:
 | |
|         case SbxEMPTY:
 | |
|             nInt16 = CallINT(pProc, pStack, (short)nSize );
 | |
|             // Rueckgabe nur zulaessig, wenn variant!
 | |
|             if( !rResult.IsFixed() )
 | |
|                 rResult.PutInteger( nInt16 );
 | |
|             break;
 | |
| 
 | |
|         case SbxCURRENCY:
 | |
|         case SbxOBJECT:
 | |
|         case SbxDATAOBJECT:
 | |
|         default:
 | |
|             CallINT(pProc, pStack, (short)nSize );
 | |
|             break;
 | |
|     }
 | |
|     delete [] pStack;
 | |
| 
 | |
|     if( pArgs )
 | |
|     {
 | |
|         // die Laengen aller uebergebenen Strings anpassen
 | |
|         USHORT nCount = pArgs->Count();
 | |
|         for( USHORT nCur = 1; nCur < nCount; nCur++ )
 | |
|         {
 | |
|             SbxVariable* pVar = pArgs->Get( nCur );
 | |
|             BOOL bIsString = ( pVar->GetType() == SbxSTRING ) ||
 | |
|                              ( pVar->GetType() == SbxLPSTR  );
 | |
| 
 | |
|             if( pVar->GetFlags() & SBX_REFERENCE )
 | |
|             {
 | |
|                 pVar->ResetFlag( SBX_REFERENCE );   // Sbx moechte es so
 | |
|                 if( bIsString )
 | |
|                 {
 | |
|                     ByteString aByteStr( (char*)pVar->GetUserData() );
 | |
|                     String aStr( aByteStr, gsl_getSystemTextEncoding() );
 | |
|                     pVar->PutString( aStr );
 | |
|                 }
 | |
|             }
 | |
|             if( bIsString )
 | |
|             {
 | |
|                 delete (char*)(pVar->GetUserData());
 | |
|                 pVar->SetUserData( 0 );
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| SbError SbiDllMgr::CallProcC( SbiDllProc pProc, SbxArray* pArgs,
 | |
|     SbxVariable& rResult )
 | |
| {
 | |
|     (void)pProc;
 | |
|     (void)pArgs;
 | |
|     (void)rResult;
 | |
| 
 | |
|     DBG_ERROR("C calling convention not supported");
 | |
|     return SbERR_BAD_ARGUMENT;
 | |
| }
 | |
| 
 | |
| void* SbiDllMgr::CreateStack( SbxArray* pArgs, USHORT& rSize )
 | |
| {
 | |
|     if( !pArgs )
 | |
|     {
 | |
|         rSize = 0;
 | |
|         return 0;
 | |
|     }
 | |
|     char* pStack = new char[ 2048 ];
 | |
|     char* pTop = pStack;
 | |
|     USHORT nCount = pArgs->Count();
 | |
|     // erstes Element ueberspringen
 | |
| #ifndef WIN
 | |
|     for( USHORT nCur = 1; nCur < nCount; nCur++ )
 | |
| #else
 | |
|     // unter 16-Bit Windows anders rum (OS/2 ?????)
 | |
|     for( USHORT nCur = nCount-1; nCur >= 1; nCur-- )
 | |
| #endif
 | |
|     {
 | |
|         SbxVariable* pVar = pArgs->Get( nCur );
 | |
|         // AB 22.1.1996, Referenz
 | |
|         if( pVar->GetFlags() & SBX_REFERENCE )  // Es ist eine Referenz
 | |
|         {
 | |
|             switch( pVar->GetType() )
 | |
|             {
 | |
|                 case SbxINTEGER:
 | |
|                 case SbxUINT:
 | |
|                 case SbxINT:
 | |
|                 case SbxUSHORT:
 | |
|                 case SbxLONG:
 | |
|                 case SbxULONG:
 | |
|                 case SbxSINGLE:
 | |
|                 case SbxDOUBLE:
 | |
|                 case SbxCHAR:
 | |
|                 case SbxBYTE:
 | |
|                 case SbxBOOL:
 | |
|                     *((void**)pTop) = (void*)&(pVar->aData);
 | |
|                     pTop += sizeof( void* );
 | |
|                     break;
 | |
| 
 | |
|                 case SbxSTRING:
 | |
|                 case SbxLPSTR:
 | |
|                     {
 | |
|                     USHORT nLen = 256;
 | |
|                     ByteString rStr( pVar->GetString(), gsl_getSystemTextEncoding() );
 | |
|                     if( rStr.Len() > 255 )
 | |
|                         nLen = rStr.Len() + 1;
 | |
| 
 | |
|                     char* pStr = new char[ nLen ];
 | |
|                     strcpy( pStr, rStr.GetBuffer() ); // #100211# - checked
 | |
|                     // ist nicht so sauber, aber wir sparen ein Pointerarray
 | |
|                     DBG_ASSERT(sizeof(UINT32)>=sizeof(char*),"Gleich krachts im Basic");
 | |
|                     pVar->SetUserData( (sal_uIntPtr)pStr );
 | |
|                     *((const char**)pTop) = pStr;
 | |
|                     pTop += sizeof( char* );
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case SbxNULL:
 | |
|                 case SbxEMPTY:
 | |
|                 case SbxERROR:
 | |
|                 case SbxDATE:
 | |
|                 case SbxCURRENCY:
 | |
|                 case SbxOBJECT:
 | |
|                 case SbxDATAOBJECT:
 | |
|                 default:
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             // ByVal
 | |
|             switch( pVar->GetType() )
 | |
|             {
 | |
|                 case SbxINTEGER:
 | |
|                 case SbxUINT:
 | |
|                 case SbxINT:
 | |
|                 case SbxUSHORT:
 | |
|                     *((INT16*)pTop) = pVar->GetInteger();
 | |
|                     pTop += sizeof( INT16 );
 | |
|                     break;
 | |
| 
 | |
|                 case SbxLONG:
 | |
|                 case SbxULONG:
 | |
|                     *((INT32*)pTop) = pVar->GetLong();
 | |
|                     pTop += sizeof( INT32 );
 | |
|                     break;
 | |
| 
 | |
|                 case SbxSINGLE:
 | |
|                     *((float*)pTop) = pVar->GetSingle();
 | |
|                     pTop += sizeof( float );
 | |
|                     break;
 | |
| 
 | |
|                 case SbxDOUBLE:
 | |
|                     *((double*)pTop) = pVar->GetDouble();
 | |
|                     pTop += sizeof( double );
 | |
|                     break;
 | |
| 
 | |
|                 case SbxSTRING:
 | |
|                 case SbxLPSTR:
 | |
|                     {
 | |
|                     char* pStr = new char[ pVar->GetString().Len() + 1 ];
 | |
|                     ByteString aByteStr( pVar->GetString(), gsl_getSystemTextEncoding() );
 | |
|                     strcpy( pStr, aByteStr.GetBuffer() ); // #100211# - checked
 | |
|                     // ist nicht so sauber, aber wir sparen ein Pointerarray
 | |
|                     DBG_ASSERT(sizeof(UINT32)>=sizeof(char*),"Gleich krachts im Basic");
 | |
|                     pVar->SetUserData( (sal_uIntPtr)pStr );
 | |
|                     *((const char**)pTop) = pStr;
 | |
|                     pTop += sizeof( char* );
 | |
|                     }
 | |
|                     break;
 | |
| 
 | |
|                 case SbxCHAR:
 | |
|                 case SbxBYTE:
 | |
|                 case SbxBOOL:
 | |
|                     *((BYTE*)pTop) = pVar->GetByte();
 | |
|                     pTop += sizeof( BYTE );
 | |
|                     break;
 | |
| 
 | |
|                 case SbxNULL:
 | |
|                 case SbxEMPTY:
 | |
|                 case SbxERROR:
 | |
|                 case SbxDATE:
 | |
|                 case SbxCURRENCY:
 | |
|                 case SbxOBJECT:
 | |
|                 case SbxDATAOBJECT:
 | |
|                 default:
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     rSize = (USHORT)((ULONG)pTop - (ULONG)pStack);
 | |
|     return pStack;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |