summaryrefslogtreecommitdiff
path: root/svl/source/svdde/ddeml2.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svl/source/svdde/ddeml2.cxx')
-rw-r--r--svl/source/svdde/ddeml2.cxx1014
1 files changed, 1014 insertions, 0 deletions
diff --git a/svl/source/svdde/ddeml2.cxx b/svl/source/svdde/ddeml2.cxx
new file mode 100644
index 000000000000..e0cdee2d52d1
--- /dev/null
+++ b/svl/source/svdde/ddeml2.cxx
@@ -0,0 +1,1014 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ddeml2.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svl.hxx"
+
+#define INCL_DOS
+#include <stdlib.h>
+
+#include "ddemlimp.hxx"
+#define LOGFILE
+#define STATUSFILE
+#define DDEDATAFILE
+#include "ddemldeb.hxx"
+
+#if defined (OS2) && defined (__BORLANDC__)
+#pragma option -w-par
+#endif
+
+
+// ************************************************************************
+// Hilfsfunktionen Speicherverwaltung
+// ************************************************************************
+
+//
+// AllocAtomName
+//
+
+PSZ ImpDdeMgr::AllocAtomName( ATOM hString, ULONG& rBufLen )
+{
+ HATOMTBL hAtomTable = WinQuerySystemAtomTable();
+ ULONG nLen = WinQueryAtomLength( hAtomTable, hString );
+ nLen++;
+ PSZ pBuf = 0;
+ if ( !MyDosAllocMem( (PPVOID)&pBuf, nLen, PAG_READ|PAG_WRITE|PAG_COMMIT | OBJ_ANY,"Atom" ) )
+ {
+ WinQueryAtomName( hAtomTable, hString, pBuf, nLen );
+ rBufLen = nLen;
+ }
+ return pBuf;
+}
+
+
+//
+// MakeDDEObject
+//
+
+PDDESTRUCT ImpDdeMgr::MakeDDEObject( HWND hwnd, ATOM hItemName,
+ USHORT fsStatus, USHORT usFormat, PVOID pabData, ULONG usDataLen )
+{
+ PDDESTRUCT pddes = 0;
+ ULONG usItemLen;
+ PULONG pulSharedObj;
+ //WRITELOG("MakeDDEObject: Start")
+
+ PSZ pItemName = 0;
+ if( hItemName != NULL )
+ pItemName = AllocAtomName( hItemName, usItemLen );
+ else
+ usItemLen = 1;
+
+ ULONG nTotalSize = sizeof(DDESTRUCT) + usItemLen + usDataLen;
+
+ if( !(MyDosAllocSharedMem((PPVOID)&pulSharedObj, NULL,
+ nTotalSize,
+ PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GETTABLE | OBJ_GIVEABLE | OBJ_ANY,
+ "MakeDDEObject")))
+ {
+ pddes = (PDDESTRUCT) pulSharedObj;
+ // siehe "Glenn Puchtel, DDE for OS/2" p.60
+ pddes->cbData = (ULONG)usDataLen;
+ pddes->fsStatus = fsStatus;
+ pddes->usFormat = usFormat;
+ pddes->offszItemName = sizeof( DDESTRUCT );
+ if( (usDataLen) && (pabData != NULL ) )
+ pddes->offabData = sizeof(DDESTRUCT) + usItemLen;
+ else
+ pddes->offabData = 0;
+
+ if( pItemName != NULL )
+ memcpy(DDES_PSZITEMNAME(pddes), pItemName, usItemLen );
+ else
+ *(DDES_PSZITEMNAME(pddes)) = '\0';
+
+ if( pabData != NULL )
+ memcpy( DDES_PABDATA(pddes), pabData, usDataLen );
+ }
+
+ if ( pItemName )
+ {
+ MyDosFreeMem( pItemName,"MakeDDEObject" );
+ }
+ return pddes;
+}
+
+//
+// AllocNamedSharedMem
+//
+
+APIRET ImpDdeMgr::AllocNamedSharedMem( PPVOID ppBaseAddress, PSZ pName,
+ ULONG nElementSize, ULONG nElementCount )
+{
+ ULONG nObjSize = (ULONG)(nElementSize * nElementCount );
+ nObjSize += sizeof( ULONG ); // fuer ElementCount am Anfang des Blocks
+
+ *ppBaseAddress = 0;
+ APIRET nRet = MyDosAllocSharedMem( ppBaseAddress, pName, nObjSize,
+ PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY,
+ "AllocNamedSharedMem" );
+ if ( !nRet )
+ {
+ memset( *ppBaseAddress, 0, nObjSize );
+ ULONG* pULONG = (ULONG*)*ppBaseAddress;
+ *pULONG = nObjSize;
+ }
+ return nRet;
+}
+
+void ImpDdeMgr::CreateServerWnd()
+{
+ hWndServer = WinCreateWindow( HWND_DESKTOP, WC_FRAME, "DDEServer", 0,
+ 0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
+ WinSetWindowULong( hWndServer, 0, (ULONG)this );
+ WinSubclassWindow( hWndServer, ::ServerWndProc );
+ TID tidDummy;
+ WinQueryWindowProcess( hWndServer, &pidThis, &tidDummy );
+}
+
+void ImpDdeMgr::DestroyServerWnd()
+{
+ WinDestroyWindow( hWndServer );
+ hWndServer = NULLHANDLE;
+}
+
+HWND ImpDdeMgr::CreateConversationWnd()
+{
+ HWND hWnd = WinCreateWindow( HWND_OBJECT, WC_FRAME, "DDEConvWnd", 0,
+ 0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
+ if ( hWnd )
+ {
+ ImpConvWndData* pWndData = new ImpConvWndData;
+ pWndData->pThis = this;
+ pWndData->nRefCount = 0;
+ WinSetWindowULong( hWnd, 0, (ULONG)pWndData );
+ WinSubclassWindow( hWnd, ::ConvWndProc );
+#if 0 && defined( OV_DEBUG )
+ String aStr("ConvWnd created:");
+ aStr += (ULONG)hWnd;
+ WRITELOG((char*)aStr.GetStr())
+#endif
+ }
+ else
+ nLastErrInstance = DMLERR_SYS_ERROR;
+
+ return hWnd;
+}
+
+// static
+void ImpDdeMgr::DestroyConversationWnd( HWND hWnd )
+{
+ ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 );
+ if( pObj )
+ {
+ pObj->nRefCount--;
+ if( pObj->nRefCount == 0
+ // auch Windows mit Refcount vonm loeschen, da dieser in initial
+ // auf 0 gesetzt wird
+ || pObj->nRefCount == (USHORT)-1 )
+ {
+ delete pObj;
+ WinDestroyWindow( hWnd );
+#if 0 && defined( OV_DEBUG )
+ String aStr("ConvWnd destroyed:");
+ aStr += (ULONG)hWnd;
+ WRITELOG((char*)aStr.GetStr())
+#endif
+ }
+ else
+ {
+#if 0 && defined( OV_DEBUG )
+ String aStr("ConvWnd not destroyed (Refcount=");
+ aStr += pObj->nRefCount;
+ aStr += ") "; aStr += (ULONG)hWnd;
+ WRITELOG((char*)aStr.GetStr())
+#endif
+ }
+ }
+#if defined( OV_DEBUG )
+ else
+ {
+ WRITELOG("DestroyCnvWnd:Already destroyed/No win data/Partner died")
+ }
+#endif
+}
+
+// static
+USHORT ImpDdeMgr::GetConversationWndRefCount( HWND hWnd )
+{
+ ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 );
+ DBG_ASSERT(pObj,"Dde:ConvWnd has no data");
+ if( pObj )
+ return pObj->nRefCount;
+ return 0;
+}
+
+// static
+USHORT ImpDdeMgr::IncConversationWndRefCount( HWND hWnd )
+{
+#if 0 && defined( OV_DEBUG )
+ String aStr("IncConversationWndRefCount ");
+ aStr += (ULONG)hWnd;
+ WRITELOG((char*)aStr.GetStr())
+#endif
+ ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 );
+ DBG_ASSERT(pObj,"Dde:ConvWnd has no data");
+ if( pObj )
+ {
+ pObj->nRefCount++;
+ return pObj->nRefCount;
+ }
+ return 0;
+}
+
+ImpDdeMgrData* ImpDdeMgr::InitAll()
+{
+ ImpDdeMgrData* pBase = 0;
+ // nur dann neu anlegen, wenn die Tabelle nicht existiert
+ APIRET nRet=DosGetNamedSharedMem((PPVOID)&pBase,DDEMLDATA,PAG_READ| PAG_WRITE);
+ if ( nRet )
+ {
+ if ( nRet == 2 ) // ERROR_FILE_NOT_FOUND )
+ {
+ // DDECONVERSATIONCOUNT=4096
+ USHORT nConvTransCount = 128;
+ PSZ pResult;
+ nRet = DosScanEnv( "SOMAXDDECONN", (const char**)&pResult );
+ if( !nRet )
+ {
+ int nTemp = 0;
+ nTemp = atoi( pResult );
+ nTemp++; // der nullte Eintrag wird nicht benutzt
+ if( nTemp > 128 )
+ nConvTransCount = (USHORT)nTemp;
+ }
+ ULONG nSize = sizeof(ImpDdeMgrData);
+ nSize += sizeof(ImpHCONV) * nConvTransCount;
+ nSize += sizeof(Transaction) * nConvTransCount;
+ nSize += sizeof(HWND) * DDEMLAPPCOUNT;
+
+ nRet = ImpDdeMgr::AllocNamedSharedMem( (PPVOID)&pBase,
+ DDEMLDATA, nSize, 1 );
+ if ( !nRet )
+ {
+ pBase->nTotalSize = nSize;
+ ULONG nAppTable = (ULONG)&(pBase->aAppTable);
+ ULONG nCharBase = (ULONG)pBase;
+ pBase->nOffsAppTable = nAppTable - nCharBase;
+ pBase->nOffsConvTable = pBase->nOffsAppTable;
+ pBase->nOffsConvTable += sizeof(HWND) * DDEMLAPPCOUNT;
+ pBase->nOffsTransTable = pBase->nOffsConvTable;
+ pBase->nOffsTransTable += sizeof(ImpHCONV) * nConvTransCount;
+
+ pBase->nMaxAppCount = DDEMLAPPCOUNT;
+ pBase->nMaxConvCount = nConvTransCount;
+ pBase->nMaxTransCount = nConvTransCount;
+ }
+ }
+ }
+
+ if( pBase )
+ {
+ pConvTable = ImpDdeMgr::GetConvTable( pBase );
+ pTransTable = ImpDdeMgr::GetTransTable( pBase );
+ pAppTable = ImpDdeMgr::GetAppTable( pBase );
+ }
+
+ memset( &aDefaultContext, 0, sizeof(CONVCONTEXT) );
+ aDefaultContext.cb = sizeof(CONVCONTEXT);
+ aDefaultContext.idCountry = 49; // ??
+ aDefaultContext.usCodepage = 850; // ??
+
+ return pBase;
+}
+
+// static
+HCONV ImpDdeMgr::CreateConvHandle( ImpDdeMgrData* pData,
+ PID pidOwner,
+ HWND hWndMe, HWND hWndPartner,
+ HSZ hszPartner, HSZ hszServiceReq, HSZ hszTopic,
+ HCONV hPrevHCONV )
+{
+ DBG_ASSERT(pData,"DDE:Invalid data");
+ if( !pData )
+ return (HCONV)0;
+
+ ImpHCONV* pPtr = ImpDdeMgr::GetConvTable( pData );
+ USHORT nCount = pData->nMaxConvCount;
+ pPtr++;
+ nCount--; // ersten Handle (NULLHANDLE) ueberspringen
+ USHORT nIdx = 1;
+ DBG_ASSERT(pPtr,"No ConvTable");
+ if( !pPtr )
+ return (HCONV)0;
+
+ while( nCount && pPtr->hWndThis != (HWND)NULL )
+ {
+ nCount--;
+ pPtr++;
+ nIdx++;
+ }
+ if( !nCount )
+ return (HCONV)0;
+
+ DdeKeepStringHandle( hszPartner );
+ DdeKeepStringHandle( hszServiceReq );
+ DdeKeepStringHandle( hszTopic );
+ pPtr->hszPartner = hszPartner;
+ pPtr->hszServiceReq = hszServiceReq;
+ pPtr->hszTopic = hszTopic;
+
+ pPtr->hWndThis = hWndMe;
+ pPtr->hWndPartner = hWndPartner;
+ pPtr->pidOwner = pidOwner;
+ pPtr->hConvPartner = (HCONV)0;
+ pPtr->nPrevHCONV = (USHORT)hPrevHCONV;
+ pPtr->nNextHCONV = 0;
+ pPtr->nStatus = ST_CONNECTED;
+
+ pData->nCurConvCount++;
+
+ return (HCONV)nIdx;
+}
+
+// static
+void ImpDdeMgr::FreeConvHandle( ImpDdeMgrData* pBase, HCONV hConv,
+ BOOL bDestroyHWndThis )
+{
+ DBG_ASSERT(pBase,"DDE:No data");
+#if 0 && defined( OV_DEBUG )
+ String aStr("FreeConvHandle: Start ");
+ aStr += (ULONG)hConv;
+ aStr += " Destroy: "; aStr += (USHORT)bDestroyHWndThis;
+ WRITELOG((char*)aStr.GetStr());
+ WRITESTATUS("FreeConvHandle: Start");
+#endif
+ if( !pBase )
+ {
+ WRITELOG("FreeConvHandle: FAIL");
+ return;
+ }
+ DBG_ASSERT(hConv&&hConv<pBase->nMaxConvCount,"DDE:Invalid Conv-Handle");
+ if( hConv && hConv < pBase->nMaxConvCount )
+ {
+ ImpHCONV* pTable = ImpDdeMgr::GetConvTable( pBase );
+ ImpHCONV* pPtr = pTable + (USHORT)hConv;
+ if( pPtr->nStatus & ST_INLIST )
+ {
+ // Verkettung umsetzen
+ USHORT nPrev = pPtr->nPrevHCONV;
+ USHORT nNext = pPtr->nNextHCONV;
+ if( nPrev )
+ {
+ pPtr = pTable + nPrev;
+ pPtr->nNextHCONV = nNext;
+ }
+ if( nNext )
+ {
+ pPtr = pTable + nNext;
+ pPtr->nPrevHCONV = nPrev;
+ }
+ pPtr = pTable + (USHORT)hConv;
+ }
+
+ DdeFreeStringHandle( pPtr->hszPartner );
+ DdeFreeStringHandle( pPtr->hszServiceReq );
+ DdeFreeStringHandle( pPtr->hszTopic );
+ if( bDestroyHWndThis )
+ DestroyConversationWnd( pPtr->hWndThis );
+ memset( pPtr, 0, sizeof(ImpHCONV) );
+ DBG_ASSERT(pBase->nCurConvCount,"Dde:Invalid Trans. count");
+ pBase->nCurConvCount--;
+ }
+#if defined(OV_DEBUG)
+ else
+ {
+ WRITELOG("FreeConvHandle: FAIL");
+ }
+#endif
+ //WRITELOG("FreeConvHandle: END");
+ //WRITESTATUS("FreeConvHandle: End");
+}
+
+// static
+HCONV ImpDdeMgr::IsConvHandleAvailable( ImpDdeMgrData* pBase )
+{
+ DBG_ASSERT(pBase,"DDE:No data");
+ if( !pBase )
+ return 0;
+
+ ImpHCONV* pPtr = ImpDdeMgr::GetConvTable( pBase );
+ USHORT nCurPos = pBase->nMaxConvCount - 1;
+ pPtr += nCurPos; // von hinten aufrollen
+ while( nCurPos >= 1 )
+ {
+ if( pPtr->hWndThis == 0 )
+ return TRUE;
+ pPtr--;
+ nCurPos--;
+ }
+ return FALSE;
+}
+
+// static
+HCONV ImpDdeMgr::GetConvHandle( ImpDdeMgrData* pBase, HWND hWndThis,
+ HWND hWndPartner )
+{
+ DBG_ASSERT(pBase,"DDE:No data");
+ if( !pBase )
+ return 0;
+ ImpHCONV* pPtr = ImpDdeMgr::GetConvTable( pBase );
+ USHORT nCurPos = 1;
+ pPtr++; // ersten Handle ueberspringen
+ USHORT nCurConvCount = pBase->nCurConvCount;
+ while( nCurConvCount && nCurPos < pBase->nMaxConvCount )
+ {
+ if( pPtr->hWndThis )
+ {
+ if(pPtr->hWndThis == hWndThis && pPtr->hWndPartner == hWndPartner)
+ return (HCONV)nCurPos;
+ nCurConvCount--;
+ if( !nCurConvCount )
+ return (HCONV)0;
+ }
+ nCurPos++;
+ pPtr++;
+ }
+ return (HCONV)0;
+}
+
+
+
+// static
+ULONG ImpDdeMgr::CreateTransaction( ImpDdeMgrData* pBase, HCONV hOwner,
+ HSZ hszItem, USHORT nFormat, USHORT nTransactionType )
+{
+ DBG_ASSERT(pBase,"DDE:No Data");
+ DBG_ASSERT(hOwner!=0,"DDE:No Owner");
+
+ if( pBase && hOwner )
+ {
+ Transaction* pPtr = ImpDdeMgr::GetTransTable( pBase );
+ DBG_ASSERT(pPtr->hConvOwner==0,"DDE:Data corrupted");
+ USHORT nId = 1;
+ pPtr++;
+ while( nId < pBase->nMaxTransCount )
+ {
+ if( pPtr->hConvOwner == (HCONV)0 )
+ {
+ pPtr->hConvOwner = hOwner;
+ DdeKeepStringHandle( hszItem );
+ pPtr->hszItem = hszItem;
+ pPtr->nType = nTransactionType;
+ pPtr->nConvst = XST_CONNECTED;
+ pPtr->nFormat = nFormat;
+ pBase->nCurTransCount++;
+ return (ULONG)nId;
+ }
+ nId++;
+ pPtr++;
+ }
+ }
+ return 0;
+}
+
+// static
+void ImpDdeMgr::FreeTransaction( ImpDdeMgrData* pBase, ULONG nTransId )
+{
+ DBG_ASSERT(pBase,"DDE:No Data");
+ if( !pBase )
+ return;
+
+ DBG_ASSERT(nTransId<pBase->nMaxTransCount,"DDE:Invalid TransactionId");
+ if( nTransId >= pBase->nMaxTransCount )
+ return;
+
+ Transaction* pPtr = ImpDdeMgr::GetTransTable( pBase );
+ pPtr += nTransId;
+ DBG_ASSERT(pPtr->hConvOwner!=0,"DDE:TransId has no owner");
+ if( pPtr->hConvOwner )
+ {
+ //WRITELOG("Freeing transaction");
+ DdeFreeStringHandle( pPtr->hszItem );
+ memset( pPtr, 0, sizeof(Transaction) );
+ DBG_ASSERT(pBase->nCurTransCount,"Dde:Invalid Trans. count");
+ pBase->nCurTransCount--;
+ }
+}
+
+// static
+ULONG ImpDdeMgr::GetTransaction( ImpDdeMgrData* pBase,
+ HCONV hOwner, HSZ hszItem, USHORT nFormat )
+{
+ DBG_ASSERT(pBase,"DDE:No Data");
+ if( !pBase || !hOwner )
+ return 0;
+
+ Transaction* pTrans = ImpDdeMgr::GetTransTable( pBase );
+ DBG_ASSERT(pTrans,"DDE:No TransactionTable");
+ if( !pTrans )
+ return 0;
+ pTrans++; // NULLHANDLE ueberspringen
+
+ ImpHCONV* pConv = ImpDdeMgr::GetConvTable( pBase );
+ pConv += (USHORT)hOwner;
+ HCONV hConvPartner = pConv->hConvPartner;
+
+ USHORT nCurTransCount = pBase->nCurTransCount;
+ for( USHORT nTrans=1; nTrans< pBase->nMaxTransCount; nTrans++, pTrans++ )
+ {
+ if( pTrans->hConvOwner )
+ {
+ if(( pTrans->hConvOwner == hOwner ||
+ pTrans->hConvOwner == hConvPartner) &&
+ pTrans->nFormat == nFormat &&
+ pTrans->hszItem == hszItem )
+ {
+ // gefunden!
+ return (ULONG)nTrans;
+ }
+ nCurTransCount--;
+ if( !nCurTransCount )
+ return 0;
+ }
+ }
+ return 0; // narda
+}
+
+// static
+HSZ ImpDdeMgr::DdeCreateStringHandle( PSZ pszString, int iCodePage)
+{
+ if( !pszString || *pszString == '\0' )
+ return (HSZ)0;
+ // Atom-Table beachtet Gross/Kleinschreibung, DDEML aber nicht
+
+ // OV 12.4.96: Services,Topics,Items case-sensitiv!!!
+ // (Grosskundenanforderung (Reuter-DDE))
+ //strlwr( pszString );
+ //*pszString = (char)toupper(*pszString);
+
+ HATOMTBL hAtomTable = WinQuerySystemAtomTable();
+ ATOM aAtom = WinAddAtom( hAtomTable, pszString );
+ return (HSZ)aAtom;
+}
+
+// static
+ULONG ImpDdeMgr::DdeQueryString( HSZ hszStr, PSZ pszStr, ULONG cchMax, int iCodePage)
+{
+ HATOMTBL hAtomTable = WinQuerySystemAtomTable();
+ if ( !pszStr )
+ return WinQueryAtomLength( hAtomTable, (ATOM)hszStr);
+ else
+ {
+ *pszStr = 0;
+ return WinQueryAtomName( hAtomTable, (ATOM)hszStr, pszStr, cchMax );
+ }
+}
+
+// static
+BOOL ImpDdeMgr::DdeFreeStringHandle( HSZ hsz )
+{
+ if( !hsz )
+ return FALSE;
+ ATOM aResult = WinDeleteAtom( WinQuerySystemAtomTable(),(ATOM)hsz );
+ return (BOOL)(aResult==0);
+}
+
+// static
+BOOL ImpDdeMgr::DdeKeepStringHandle( HSZ hsz )
+{
+ if( !hsz )
+ return TRUE;
+ HATOMTBL hAtomTable = WinQuerySystemAtomTable();
+#ifdef DBG_UTIL
+ ULONG nUsageCount=WinQueryAtomUsage(hAtomTable,(ATOM)hsz);
+#endif
+ ULONG nAtom = 0xFFFF0000;
+ ULONG nPar = (ULONG)hsz;
+ nAtom |= nPar;
+ ATOM aAtom = WinAddAtom( hAtomTable, (PSZ)nAtom );
+#ifdef DBG_UTIL
+ if ( aAtom )
+ DBG_ASSERT(WinQueryAtomUsage(hAtomTable,(ATOM)hsz)==nUsageCount+1,"Keep failed");
+#endif
+ return (BOOL)(aAtom!=0);
+}
+
+
+// static
+int ImpDdeMgr::DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
+{
+ if ( hsz1 == hsz2 )
+ return 0;
+ if ( hsz1 < hsz2 )
+ return -1;
+ return 1;
+}
+
+HDDEDATA ImpDdeMgr::DdeCreateDataHandle( void* pSrc, ULONG cb,
+ ULONG cbOff, HSZ hszItem, USHORT wFmt, USHORT afCmd)
+{
+ char* pData = (char*)pSrc;
+ pData += cbOff;
+ USHORT nStatus;
+ if( afCmd & HDATA_APPOWNED )
+ nStatus = IMP_HDATAAPPOWNED;
+ else
+ nStatus = 0;
+ PDDESTRUCT hData=MakeDDEObject(0,(ATOM)hszItem,nStatus,wFmt,pData,cb);
+// WRITEDATA(hData)
+ if ( !hData )
+ ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER;
+ return (HDDEDATA)hData;
+}
+
+// static
+BYTE* ImpDdeMgr::DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize)
+{
+ BYTE* pRet = 0;
+ *pcbDataSize = 0;
+ if ( hData )
+ {
+ pRet = (BYTE*)hData;
+ pRet += hData->offabData;
+ ULONG nLen = hData->cbData;
+ // nLen -= hData->offabData;
+ *pcbDataSize = nLen;
+ }
+ else
+ ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER;
+ return pRet;
+}
+
+// static
+BOOL ImpDdeMgr::DdeUnaccessData(HDDEDATA hData)
+{
+ return TRUE; // nothing to do for us
+}
+
+// static
+BOOL ImpDdeMgr::DdeFreeDataHandle(HDDEDATA hData)
+{
+ DdeUnaccessData( hData );
+ MyDosFreeMem( (PSZ)hData, "DdeFreeDataHandle" );
+ return TRUE;
+}
+
+// static
+HDDEDATA ImpDdeMgr::DdeAddData(HDDEDATA hData,void* pSrc,ULONG cb,ULONG cbOff)
+{
+ return (HDDEDATA)0;
+}
+
+// static
+ULONG ImpDdeMgr::DdeGetData(HDDEDATA hData,void* pDst,ULONG cbMax,ULONG cbOff)
+{
+ return 0;
+}
+
+BOOL ImpDdeMgr::DisconnectAll()
+{
+ //WRITESTATUS("Before DisconnectAll()")
+ USHORT nCurConvCount = pData->nCurConvCount;
+ if( !nCurConvCount )
+ return TRUE;
+
+ BOOL bRet = TRUE;
+ ImpHCONV* pPtr = pConvTable;
+ pPtr++;
+
+ for( USHORT nPos=1; nPos < pData->nMaxConvCount; nPos++, pPtr++ )
+ {
+ if( pPtr->hWndThis )
+ {
+ if( !DdeDisconnect( (HCONV)nPos ) )
+ bRet = FALSE;
+ nCurConvCount--;
+ if( !nCurConvCount )
+ break;
+ }
+ }
+ //WRITESTATUS("After DisconnectAll()")
+ return bRet;
+}
+
+// static
+void ImpDdeMgr::FreeTransactions( ImpDdeMgrData* pData,HWND hWndThis,
+ HWND hWndPartner )
+{
+ USHORT nCurTransCount = pData->nCurTransCount;
+ if( !nCurTransCount )
+ return;
+
+ Transaction* pTrans = GetTransTable( pData );
+ ImpHCONV* pConvTable = GetConvTable( pData );
+ pTrans++;
+ for( USHORT nPos=1; nPos < pData->nMaxTransCount; nPos++, pTrans++ )
+ {
+ if( pTrans->hConvOwner )
+ {
+ ImpHCONV* pConv = pConvTable + (USHORT)(pTrans->hConvOwner);
+ if((pConv->hWndThis==hWndThis&& pConv->hWndPartner==hWndPartner)||
+ (pConv->hWndThis==hWndPartner && pConv->hWndPartner==hWndThis))
+ {
+ FreeTransaction( pData, (ULONG)nPos );
+ }
+ nCurTransCount--;
+ if( !nCurTransCount )
+ return;
+ }
+ }
+}
+
+// static
+void ImpDdeMgr::FreeTransactions( ImpDdeMgrData* pData, HCONV hConvOwner )
+{
+ USHORT nCurTransCount = pData->nCurTransCount;
+ if( !nCurTransCount )
+ return;
+
+ Transaction* pTrans = GetTransTable( pData );
+// ImpHCONV* pConvTable = GetConvTable( pData );
+ pTrans++;
+ for( USHORT nPos=1; nPos < pData->nMaxTransCount; nPos++, pTrans++ )
+ {
+ if( pTrans->hConvOwner == hConvOwner )
+ {
+ FreeTransaction( pData, (ULONG)nPos );
+ nCurTransCount--;
+ if( !nCurTransCount )
+ return;
+ }
+ }
+}
+
+// static
+void ImpDdeMgr::FreeConversations( ImpDdeMgrData* pData, HWND hWndThis,
+ HWND hWndPartner )
+{
+ USHORT nCurCount = pData->nCurConvCount;
+ if( !nCurCount )
+ return;
+
+ ImpHCONV* pPtr = GetConvTable( pData );
+ pPtr++;
+ for( USHORT nPos=1; nPos < pData->nMaxConvCount; nPos++, pPtr++ )
+ {
+ if( pPtr->hWndThis )
+ {
+ if( hWndThis && pPtr->hWndPartner==hWndPartner )
+ FreeConvHandle( pData, (HCONV)nPos );
+ nCurCount--;
+ if( !nCurCount )
+ return;
+ }
+ }
+}
+
+
+BOOL ImpDdeMgr::OwnsConversationHandles()
+{
+ //WRITESTATUS("OwnsConversationHandles()");
+#if 0 && defined( OV_DEBUG )
+ String aStr("OwnsConversationHandles Server:");
+ aStr += (ULONG)hWndServer;
+ WRITELOG((char*)aStr.GetStr())
+#endif
+ ImpHCONV* pPtr = GetConvTable( pData );
+ for( USHORT nCur = 1; nCur < pData->nMaxConvCount; nCur++, pPtr++ )
+ {
+ if( pPtr->hWndThis && pPtr->pidOwner == pidThis )
+ {
+ //WRITELOG("OwnsConversationHandles: TRUE");
+ return TRUE;
+ }
+ }
+ // WRITELOG("OwnsConversationHandles: FALSE");
+ return FALSE;
+}
+
+
+
+// *********************************************************************
+// *********************************************************************
+// *********************************************************************
+
+USHORT DdeInitialize(ULONG* pidInst, PFNCALLBACK pfnCallback,
+ ULONG afCmd, ULONG ulRes)
+{
+ if( (*pidInst)!=0 )
+ {
+ // Reinitialize wird noch nicht unterstuetzt
+ DBG_ASSERT(0,"DDEML:Reinitialize not supported");
+ return DMLERR_INVALIDPARAMETER;
+ }
+
+ ImpDdeMgr* pMgr = new ImpDdeMgr;
+ *pidInst = (ULONG)pMgr;
+ return pMgr->DdeInitialize( pfnCallback, afCmd );
+}
+
+BOOL DdeUninitialize(ULONG idInst)
+{
+ if( !idInst )
+ return FALSE;
+ ImpDdeMgr* pMgr = (ImpDdeMgr*)idInst;
+ // nur loeschen, wenn wir nicht mehr benutzt werden!
+ if( !pMgr->OwnsConversationHandles() )
+ {
+ WRITELOG("DdeUninitialize: TRUE");
+ delete pMgr;
+ return TRUE;
+ }
+ WRITELOG("DdeUninitialize: FALSE");
+ return FALSE;
+}
+
+
+HCONVLIST DdeConnectList(ULONG idInst, HSZ hszService, HSZ hszTopic,
+ HCONVLIST hConvList, CONVCONTEXT* pCC)
+{
+ if( !idInst )
+ return 0;
+ return ((ImpDdeMgr*)idInst)->DdeConnectList(hszService,hszTopic,
+ hConvList, pCC );
+}
+
+HCONV DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev)
+{
+ return ImpDdeMgr::DdeQueryNextServer( hConvList, hConvPrev );
+}
+
+BOOL DdeDisconnectList(HCONVLIST hConvList)
+{
+ return ImpDdeMgr::DdeDisconnectList( hConvList );
+}
+
+HCONV DdeConnect(ULONG idInst, HSZ hszService, HSZ hszTopic,
+ CONVCONTEXT* pCC)
+{
+ if( !idInst )
+ return 0;
+ return ((ImpDdeMgr*)idInst)->DdeConnect( hszService, hszTopic, pCC );
+}
+
+BOOL DdeDisconnect(HCONV hConv)
+{
+ return ImpDdeMgr::DdeDisconnect( hConv );
+}
+
+HCONV DdeReconnect(HCONV hConv)
+{
+ return ImpDdeMgr::DdeReconnect( hConv );
+}
+
+
+USHORT DdeQueryConvInfo(HCONV hConv, ULONG idTransact, CONVINFO* pCI )
+{
+ return ImpDdeMgr::DdeQueryConvInfo( hConv, idTransact, pCI );
+}
+
+BOOL DdeSetUserHandle(HCONV hConv, ULONG id, ULONG hUser)
+{
+ return ImpDdeMgr::DdeSetUserHandle( hConv, id, hUser );
+}
+
+BOOL DdeAbandonTransaction(ULONG idInst, HCONV hConv, ULONG idTransaction)
+{
+ if( !idInst )
+ return FALSE;
+ return ((ImpDdeMgr*)idInst)->DdeAbandonTransaction(hConv,idTransaction);
+}
+
+BOOL DdePostAdvise(ULONG idInst, HSZ hszTopic, HSZ hszItem)
+{
+ if( !idInst )
+ return FALSE;
+ return ((ImpDdeMgr*)idInst)->DdePostAdvise( hszTopic, hszItem );
+}
+
+BOOL DdeEnableCallback(ULONG idInst, HCONV hConv, USHORT wCmd)
+{
+ if( !idInst )
+ return FALSE;
+ return ((ImpDdeMgr*)idInst)->DdeEnableCallback( hConv, wCmd );
+}
+
+HDDEDATA DdeClientTransaction(void* pData, ULONG cbData,
+ HCONV hConv, HSZ hszItem, USHORT wFmt, USHORT wType,
+ ULONG dwTimeout, ULONG* pdwResult)
+{
+ return ImpDdeMgr::DdeClientTransaction( pData, cbData,
+ hConv, hszItem, wFmt, wType, dwTimeout, pdwResult );
+}
+
+HDDEDATA DdeCreateDataHandle(ULONG idInst, void* pSrc, ULONG cb,
+ ULONG cbOff, HSZ hszItem, USHORT wFmt, USHORT afCmd)
+{
+ if( !idInst )
+ return 0;
+ return ((ImpDdeMgr*)idInst)->DdeCreateDataHandle( pSrc, cb,
+ cbOff, hszItem, wFmt, afCmd );
+}
+
+HDDEDATA DdeAddData(HDDEDATA hData, void* pSrc, ULONG cb, ULONG cbOff)
+{
+ return ImpDdeMgr::DdeAddData( hData, pSrc, cb, cbOff );
+}
+
+ULONG DdeGetData(HDDEDATA hData, void* pDst, ULONG cbMax, ULONG cbOff)
+{
+ return ImpDdeMgr::DdeGetData( hData, pDst, cbMax, cbOff );
+}
+
+BYTE* DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize)
+{
+ return ImpDdeMgr::DdeAccessData( hData, pcbDataSize );
+}
+
+BOOL DdeUnaccessData(HDDEDATA hData)
+{
+ return ImpDdeMgr::DdeUnaccessData( hData );
+}
+
+BOOL DdeFreeDataHandle(HDDEDATA hData)
+{
+ return ImpDdeMgr::DdeFreeDataHandle( hData );
+}
+
+USHORT DdeGetLastError(ULONG idInst)
+{
+ if( !idInst )
+ return DMLERR_DLL_NOT_INITIALIZED;
+ return ((ImpDdeMgr*)idInst)->DdeGetLastError();
+}
+
+HSZ DdeCreateStringHandle(ULONG idInst, PSZ pszString,int iCodePage )
+{
+ if( !idInst )
+ return 0;
+ return ((ImpDdeMgr*)idInst)->DdeCreateStringHandle(pszString,iCodePage);
+}
+
+ULONG DdeQueryString( ULONG idInst, HSZ hsz, PSZ pBuf,
+ ULONG cchMax, int iCodePage )
+{
+ if( !idInst )
+ return 0;
+ return ((ImpDdeMgr*)idInst)->DdeQueryString( hsz,pBuf,cchMax,iCodePage);
+}
+
+BOOL DdeFreeStringHandle( ULONG idInst, HSZ hsz)
+{
+ if( !idInst )
+ return FALSE;
+ return ((ImpDdeMgr*)idInst)->DdeFreeStringHandle( hsz );
+}
+
+BOOL DdeKeepStringHandle( ULONG idInst, HSZ hsz )
+{
+ if( !idInst )
+ return FALSE;
+ return ((ImpDdeMgr*)idInst)->DdeKeepStringHandle( hsz );
+}
+
+int DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
+{
+ return ImpDdeMgr::DdeCmpStringHandles( hsz1, hsz2 );
+}
+
+HDDEDATA DdeNameService( ULONG idInst, HSZ hsz1, HSZ hszRes, USHORT afCmd )
+{
+ if( !idInst )
+ return 0;
+ return ((ImpDdeMgr*)idInst)->DdeNameService( hsz1, afCmd );
+}
+
+