diff options
Diffstat (limited to 'svtools/source/svdde/ddeml1.cxx')
-rw-r--r-- | svtools/source/svdde/ddeml1.cxx | 2661 |
1 files changed, 0 insertions, 2661 deletions
diff --git a/svtools/source/svdde/ddeml1.cxx b/svtools/source/svdde/ddeml1.cxx deleted file mode 100644 index 6cc09b612ecf..000000000000 --- a/svtools/source/svdde/ddeml1.cxx +++ /dev/null @@ -1,2661 +0,0 @@ -/************************************************************************* - * - * 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: ddeml1.cxx,v $ - * $Revision: 1.5 $ - * - * 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_svtools.hxx" - -/* - ToDo / Bugs: - - - DdeInitiate: Eigener Thread? - - Timeout bei Disconnects (IBM:nicht auf Ack warten!) - - Konzept Errorhandling (globale/lokale Fehler) - - Bedeutung/Anwendung Conversation-Contexte - - Bei Zugriffen auf ConversationHandles WindowHandles checken - - Namen der Partner-App ermitteln - - Codepage-Geraffel -*/ -#define INCL_DOSPROCESS - -#include "ddemlimp.hxx" - -#define LOGFILE -#define STATUSFILE -#define DDEDATAFILE -#include "ddemldeb.hxx" - - -#if defined (OS2) && defined (__BORLANDC__) -#pragma option -w-par -#endif - -// static -inline BOOL ImpDdeMgr::MyWinDdePostMsg( HWND hWndTo, HWND hWndFrom, - USHORT nMsg, PDDESTRUCT pData, ULONG nFlags ) -{ - BOOL bSuccess = WinDdePostMsg( hWndTo,hWndFrom,nMsg,pData,nFlags); - if( !bSuccess ) - { - WRITELOG("WinDdePostMsg:Failed!") - if ( !(nFlags & DDEPM_NOFREE) ) - { - MyDosFreeMem( pData,"MyWinDdePostMsg" ); - } - } - return bSuccess; -} - - -// ********************************************************************* -// ImpDdeMgr -// ********************************************************************* - -USHORT ImpDdeMgr::nLastErrInstance = 0; - -// -// Conversation-WndProc -// Steuert Transaktionen eines Conversationhandles -// -MRESULT EXPENTRY ConvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2) -{ -#if defined(DBG_UTIL) && defined(OV_DEBUG) - if( nMsg >= WM_DDE_FIRST && nMsg <= WM_DDE_LAST) - { - ////WRITELOG("::ConvWndProc:DDE-Msg received") - } -#endif - ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 ); - return pObj->pThis->ConvWndProc( hWnd, nMsg, nPar1, nPar2 ); -} - -// -// Server-WndProc -// DDE-Server-Window der App -// -MRESULT EXPENTRY ServerWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2) -{ -#if defined(DBG_UTIL) && defined(OV_DEBUG) - if( nMsg >= WM_DDE_FIRST && nMsg <= WM_DDE_LAST) - { - ////WRITELOG("::ServerWndProc:DDE-Msg received") - } -#endif - ImpDdeMgr* pObj = (ImpDdeMgr*)WinQueryWindowULong( hWnd, 0 ); - return pObj->SrvWndProc( hWnd, nMsg, nPar1, nPar2 ); -} - - -inline HDDEDATA ImpDdeMgr::Callback( USHORT nTransactionType, - USHORT nClipboardFormat, HCONV hConversationHandle, HSZ hsz1, - HSZ hsz2, HDDEDATA hData, ULONG nData1, ULONG nData2 ) -{ - HDDEDATA hRet = (HDDEDATA)0; - if( pCallback ) - hRet = (*pCallback)(nTransactionType, nClipboardFormat, - hConversationHandle, hsz1, hsz2, hData, nData1, nData2); - return hRet; -} - - - -ImpDdeMgr::ImpDdeMgr() -{ - nLastErrInstance = DMLERR_NO_ERROR; - pCallback = 0; - nTransactFilter = 0; - nServiceCount = 0; - pServices = 0; - pAppTable = 0; - pConvTable = 0; - pTransTable = 0; - bServFilterOn = TRUE; - bInSyncTrans = FALSE; - - CreateServerWnd(); - pData = InitAll(); - if ( !pData ) - nLastErrInstance = DMLERR_MEMORY_ERROR; - else - RegisterDDEMLApp(); -} - -ImpDdeMgr::~ImpDdeMgr() -{ - CleanUp(); - DestroyServerWnd(); -// Named Shared Mem vom BS loeschen lassen, da nicht bekannt ist, -// wieviele DDEML-Instanzen die App erzeugt hat, und OS/2 -// keinen App-Referenzzaehler fuer shared mem fuehrt. -// if ( pData ) -// DosFreeMem( pData ); -} - - -BOOL ImpDdeMgr::IsSameInstance( HWND hWnd ) -{ - TID tid; PID pid; - WinQueryWindowProcess( hWnd, &pid, &tid ); - return (BOOL)(pid == pidThis); -} - -HSZ ImpDdeMgr::GetAppName( HWND hWnd ) -{ - return 0; -} - -// static -ImpDdeMgr* ImpDdeMgr::GetImpDdeMgrInstance( HWND hWnd ) -{ - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if( !pData ) - return 0; - - ImpDdeMgr* pResult = 0; - TID tid; PID pidApp; - WinQueryWindowProcess( hWnd, &pidApp, &tid ); - HWND* pApp = ImpDdeMgr::GetAppTable( pData ); - USHORT nCurApp = 0; - while( nCurApp < pData->nMaxAppCount ) - { - HWND hCurWin = *pApp; - if( hCurWin ) - { - PID pidCurApp; - WinQueryWindowProcess( hCurWin, &pidCurApp, &tid ); - if( pidCurApp == pidApp ) - { - pResult = (ImpDdeMgr*)WinQueryWindowULong( hCurWin, 0 ); - break; - } - } - pApp++; - nCurApp++; - } - return pResult; -} - - - - - -void ImpDdeMgr::CleanUp() -{ - DisconnectAll(); - ImpService* pPtr = pServices; - if( pPtr ) - { - for( USHORT nIdx = 0; nIdx < nServiceCount; nIdx++, pPtr++ ) - { - HSZ hStr = pPtr->hBaseServName; - if( hStr ) - DdeFreeStringHandle( hStr ); - hStr = pPtr->hInstServName; - if( hStr ) - DdeFreeStringHandle( hStr ); - } - nServiceCount = 0; - delete pServices; - pServices = 0; - } - bServFilterOn = TRUE; // default setting DDEML - UnregisterDDEMLApp(); -} - -void ImpDdeMgr::RegisterDDEMLApp() -{ - HWND* pPtr = pAppTable; - HWND hCur; - USHORT nPos = 0; - while( nPos < pData->nMaxAppCount ) - { - hCur = *pPtr; - if (hCur == (HWND)0 ) - { - // in Tabelle stellen - *pPtr = hWndServer; - break; - } - nPos++; - pPtr++; - } -} - -void ImpDdeMgr::UnregisterDDEMLApp() -{ - HWND* pPtr = pAppTable; - USHORT nPos = 0; - while( nPos < pData->nMaxAppCount ) - { - if (*pPtr == hWndServer ) - { - *pPtr = 0; - break; - } - nPos++; - pPtr++; - } -} - -// static -ImpDdeMgrData* ImpDdeMgr::AccessMgrData() -{ - ImpDdeMgrData* pData = 0; - APIRET nRet = DosGetNamedSharedMem((PPVOID)&pData,DDEMLDATA,PAG_READ|PAG_WRITE); - DBG_ASSERT(!nRet,"DDE:AccessMgrData failed"); - return pData; -} - -USHORT ImpDdeMgr::DdeGetLastError() -{ - USHORT nErr; - if ( !pData ) - nErr = DMLERR_DLL_NOT_INITIALIZED; - else if ( nLastErrInstance ) - nErr = nLastErrInstance; - else - nErr = pData->nLastErr; - - nLastErrInstance = 0; - pData->nLastErr = 0; - return nErr; -} - - - -USHORT ImpDdeMgr::DdeInitialize( PFNCALLBACK pCallbackProc, ULONG nTransactionFilter ) -{ - if ( !nLastErrInstance ) - { - if ( !pCallbackProc ) - { - nLastErrInstance = DMLERR_INVALIDPARAMETER; - return nLastErrInstance; - } - pCallback = pCallbackProc; - nTransactFilter = nTransactionFilter; - nTransactFilter |= CBF_FAIL_SELFCONNECTIONS; - } - return nLastErrInstance; -} - - -// static -HWND ImpDdeMgr::NextFrameWin( HENUM hEnum ) -{ - char aBuf[ 10 ]; - - HWND hWnd = WinGetNextWindow( hEnum ); - while( hWnd ) - { - WinQueryClassName( hWnd, sizeof(aBuf)-1, (PCH)aBuf ); - // Frame-Window ? - if( !strcmp( aBuf, "#1" ) ) // #define WC_FRAME ((PSZ)0xffff0001L) - break; - hWnd = WinGetNextWindow( hEnum ); - } - return hWnd; -} - - -HCONV ImpDdeMgr::DdeConnectImp( HSZ hszService,HSZ hszTopic,CONVCONTEXT* pCC) -{ - hCurConv = 0; - if( !pCC ) - pCC = &aDefaultContext; - - ULONG nBufLen; - PSZ pService = AllocAtomName( (ATOM)hszService, nBufLen ); - PSZ pTopic = AllocAtomName( (ATOM)hszTopic, nBufLen ); -#if 0 && defined(OV_DEBUG) - String aStr("DdeConnectImp Service:"); - aStr += pService; - aStr += " Topic:"; - aStr += pTopic; - WRITELOG((char*)(const char*)aStr) -#endif - -#if defined(OV_DEBUG) - if( !strcmp(pService,"oliver voeltz") ) - { - WRITESTATUS("Table of connections"); - MyDosFreeMem( pTopic,"DdeConnectImp" ); - MyDosFreeMem( pService,"DdeConnectImp" ); - return 0; - } -#endif - -#if 0 - // original pm-fkt benutzen - HWND hWndCurClient = CreateConversationWnd(); - WinDdeInitiate( hWndCurClient, pService, pTopic, pCC ); - if( GetConversationWndRefCount(hWndCurClient) == 0) - DestroyConversationWnd( hWndCurClient ); -#else - // eigener Verbindungsaufbau - HENUM hEnum = WinBeginEnumWindows( HWND_DESKTOP ); - HWND hWndCurSrv = NextFrameWin( hEnum ); - HWND hWndCurClient = CreateConversationWnd(); - while( hWndCurSrv && !hCurConv ) - { - if( hWndCurSrv != hWndServer || - ((nTransactFilter & CBF_FAIL_SELFCONNECTIONS)==0 )) - { - // pro DDE-Server ein Conversation-Window erzeugen - if( GetConversationWndRefCount(hWndCurClient) >= 2) - { - DestroyConversationWnd( hWndCurClient ); - hWndCurClient = CreateConversationWnd(); - } - MyInitiateDde(hWndCurSrv,hWndCurClient,hszService,hszTopic,pCC); - if( !bListConnect && hCurConv ) - break; - } - hWndCurSrv = NextFrameWin( hEnum ); - } - - if( GetConversationWndRefCount(hWndCurClient) == 0) - DestroyConversationWnd( hWndCurClient ); - WinEndEnumWindows( hEnum ); -#endif - - if( !hCurConv ) - nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; - -#if 0 && defined(OV_DEBUG) - String aCStr( "DdeConnectImp:End "); - if( nLastErrInstance != DMLERR_NO_CONV_ESTABLISHED ) - aCStr += "(Success)"; - else - aCStr += "(Failed)"; - WRITELOG((char*)aCStr.GetStr()) -#endif - - MyDosFreeMem( pTopic,"DdeConnectImp" ); - MyDosFreeMem( pService,"DdeConnectImp" ); - return hCurConv; -} - -HCONV ImpDdeMgr::DdeConnect( HSZ hszService, HSZ hszTopic, CONVCONTEXT* pCC) -{ - ////WRITELOG("DdeConnect:Start") - bListConnect = FALSE; - HCONV hResult = DdeConnectImp( hszService, hszTopic, pCC ); - ////WRITELOG("DdeConnect:End") - ////WRITESTATUS("DdeConnect:End") - return hResult; -} - - -HCONVLIST ImpDdeMgr::DdeConnectList( HSZ hszService, HSZ hszTopic, - HCONVLIST hConvList, CONVCONTEXT* pCC ) -{ - nPrevConv = 0; - ////WRITESTATUS("Before DdeConnectList") - if( hConvList ) - { - HCONV hLastConvInList; - - hCurListId = hConvList; - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConvList; - if( (USHORT)hConvList >= pData->nMaxConvCount ||pConv->hWndThis==0 ) - { - nLastErrInstance = DMLERR_INVALIDPARAMETER; - return 0; - } - GetLastServer(pData, hConvList, hLastConvInList); - nPrevConv = (USHORT)hLastConvInList; - } - else - hCurListId = (HCONVLIST)WinCreateWindow( HWND_OBJECT, WC_FRAME, - CONVLISTNAME, 0,0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0,0,0); - - bListConnect = TRUE; - DdeConnectImp( hszService, hszTopic, pCC ); -#if 0 && defined(OV_DEBUG) - WRITELOG("DdeConnectList:ConnectionList:") - HCONV hDebug = 0; - do - { - hDebug = DdeQueryNextServer( hCurListId, hDebug); - String aStr( (ULONG)hDebug ); - WRITELOG((char*)(const char*)aStr) - } while( hDebug ); -#endif - ////WRITESTATUS("After DdeConnectList") - return (HCONVLIST)hCurListId; -} - -DDEINIT* ImpDdeMgr::CreateDDEInitData( HWND hWndDestination, HSZ hszService, - HSZ hszTopic, CONVCONTEXT* pCC ) -{ - ULONG nLen1 = 0, nLen2 = 0; - HATOMTBL hAtomTable = WinQuerySystemAtomTable(); - - if( hszService ) - nLen1 = WinQueryAtomLength( hAtomTable, hszService ); - if( hszTopic ) - nLen2 = WinQueryAtomLength( hAtomTable, hszTopic ); - nLen1++; nLen2++; - - DDEINIT* pBuf = 0; - - ULONG nLen = sizeof(DDEINIT) + nLen1+ nLen2 + sizeof(CONVCONTEXT); - if( !(MyDosAllocSharedMem((PPVOID)&pBuf, NULL, nLen, - PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | OBJ_ANY, - "CreateDDEInitData"))) - { - memset( pBuf, 0, nLen ); - - /* - PID pid; TID tid; - WinQueryWindowProcess( hWndDestination, &pid, &tid ); - APIRET nRet = DosGiveSharedMem( pBuf, pid, PAG_READ | PAG_WRITE ); - */ - - pBuf->cb = nLen; - pBuf->offConvContext = sizeof( DDEINIT ); - char* pBase = (char*)pBuf; - pBase += sizeof(DDEINIT); - if( pCC ) - memcpy( pBase, pCC, sizeof(CONVCONTEXT) ); - pBase += sizeof(CONVCONTEXT); - pBuf->pszAppName = pBase; - if( hszService ) - WinQueryAtomName( hAtomTable, hszService, pBase, nLen1 ); - pBase += nLen1; - pBuf->pszTopic = pBase; - if( hszTopic ) - WinQueryAtomName( hAtomTable, hszTopic, pBase, nLen2 ); - } - return pBuf; -} - - - -void ImpDdeMgr::MyInitiateDde( HWND hWndSrv, HWND hWndClient, - HSZ hszService, HSZ hszTopic, CONVCONTEXT* pCC ) -{ - DDEINIT* pBuf = CreateDDEInitData( hWndSrv, hszService, hszTopic, pCC ); - if( pBuf ) - { - PID pid; TID tid; - WinQueryWindowProcess( hWndSrv, &pid, &tid ); - APIRET nRet = DosGiveSharedMem( pBuf, pid, PAG_READ | PAG_WRITE ); - WinSendMsg( hWndSrv,WM_DDE_INITIATE,(MPARAM)hWndClient,(MPARAM)pBuf); - MyDosFreeMem( pBuf,"MyInitiateDde" ); - } -} - -// static -ImpHCONV* ImpDdeMgr::GetFirstServer(ImpDdeMgrData* pData, HCONVLIST hConvList, - HCONV& rhConv ) -{ - ImpHCONV* pPtr = GetConvTable( pData ); - HCONV hConv; - if( !rhConv ) - { - pPtr++; - hConv = 1; - } - else - { - // Startposition - pPtr += (USHORT)rhConv; - hConv = rhConv; - pPtr++; hConv++; // auf den naechsten - } - while( hConv < pData->nMaxConvCount ) - { - if( pPtr->hConvList == hConvList ) - { - rhConv = hConv; - return pPtr; - } - pPtr++; - hConv++; - } - rhConv = 0; - return 0; -} - -// static -ImpHCONV* ImpDdeMgr::GetLastServer(ImpDdeMgrData* pData, HCONVLIST hConvList, - HCONV& rhConv ) -{ - ImpHCONV* pPtr = GetConvTable( pData ); - pPtr += pData->nMaxConvCount; - pPtr--; - HCONV hConv = pData->nMaxConvCount; - hConv--; - while( hConv > 0 ) - { - if( pPtr->hConvList == hConvList ) - { - rhConv = hConv; - return pPtr; - } - pPtr--; - hConv--; - } - rhConv = 0; - return 0; -} - -// static -BOOL ImpDdeMgr::CheckConvListId( HCONVLIST hConvListId ) -{ - HAB hAB = WinQueryAnchorBlock( (HWND)hConvListId ); - if( hAB ) - return WinIsWindow( hAB, (HWND)hConvListId ); - return FALSE; - /* - HAB hAB = WinQueryAnchorBlock( (HWND)hConvListId ); - if( hAB ) - { - char aBuf[ 16 ]; - WinQueryWindowText( (HWND)hConvListId, sizeof(aBuf), aBuf ); - if( strcmp(aBuf, CONVLISTNAME ) == 0 ) - return TRUE; - } - return FALSE; - */ -} - -// static -HCONV ImpDdeMgr::DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev) -{ - if( !CheckConvListId( hConvList ) ) - return (HCONV)0; - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - GetFirstServer( pData, hConvList, hConvPrev ); - return hConvPrev; -} - -// static - -// Idee: DisconnectAll uebergibt das ServerWindow. Zu jedem HCONV -// wird das Creator-Server-Wnd gespeichert. Disconnect braucht -// dann nur noch die Window-Handles zu vergleichen -BOOL ImpDdeMgr::DdeDisconnect( HCONV hConv ) -{ - WRITELOG("DdeDisconnect:Start") - ////WRITESTATUS("DdeDisconnect:Start") - - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if ( !pData ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return FALSE; - } - ImpHCONV* pConv = GetConvTable(pData) + (USHORT)hConv; - - if( (USHORT)hConv >= pData->nMaxConvCount || pConv->hWndThis==0 ) - { - nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; - return FALSE; - } - - PID pidApp; TID tid; - HWND hWndDummy = WinCreateWindow( HWND_OBJECT, WC_FRAME, - "Bla", 0, 0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 ); - WinQueryWindowProcess( hWndDummy, &pidApp, &tid ); - WinDestroyWindow( hWndDummy ); - PID pidThis; PID pidPartner; - - HWND hWndThis = pConv->hWndThis; - HWND hWndPartner = pConv->hWndPartner; - - WinQueryWindowProcess( hWndThis, &pidThis, &tid ); - WinQueryWindowProcess( hWndPartner, &pidPartner, &tid ); - if( pidApp != pidThis && pidApp != pidPartner ) - return TRUE; // gehoert nicht der App -> ueberspringen - - HCONV hConvPartner = pConv->hConvPartner; - - // die App benachrichtigen, dass alle offenen Advise-Loops - // beendet werden, egal ob sie vom Server oder Client - // initiiert wurden. Die Dinger aber nicht loeschen, da sie evtl. - // noch vom Partner gebraucht werden. - ImpConvWndData* pObj = - (ImpConvWndData*)WinQueryWindowULong( pConv->hWndThis, 0 ); - ImpDdeMgr* pThis = pObj->pThis; - pThis->SendUnadvises( hConv, 0, FALSE ); // alle Formate & NICHT loeschen - pThis->SendUnadvises( hConvPartner, 0, FALSE ); // alle Formate & NICHT loeschen - - pConv->nStatus |= ST_TERMINATED; - - HAB hAB = WinQueryAnchorBlock( pConv->hWndThis ); - // um die MessageQueue inne Gaenge zu halten - ULONG nTimerId = WinStartTimer( hAB, 0, 0, 50 ); - - /* - Die Partner-App muss ein DDE_TERMINATE posten, auf das - wir warten muessen, um alle Messages zu bearbeiten, die - _vor_ dem DdeDisconnect von der Partner-App gepostet - wurden. - */ - WRITELOG("DdeDisconnect:Waiting for acknowledge...") - WinDdePostMsg( hWndPartner, hWndThis, WM_DDE_TERMINATE, - (PDDESTRUCT)0,DDEPM_RETRY); - - QMSG aQueueMsg; - BOOL bContinue = TRUE; - while( bContinue ) - { - if( WinGetMsg( hAB, &aQueueMsg, 0, 0, 0 )) - { - WinDispatchMsg( hAB, &aQueueMsg ); - if( (!WinIsWindow( hAB, hWndPartner)) || - (pConv->nStatus & ST_TERMACKREC) ) - { - bContinue = FALSE; - if( pConv->nStatus & ST_TERMACKREC ) - { - WRITELOG("DdeDisconnect: TermAck received") - } - else - { - WRITELOG("DdeDisconnect: Partner died") - } - } - } - else - bContinue = FALSE; - } - - WinStopTimer( hAB, 0, nTimerId ); - - // WRITELOG("DdeDisconnect:Freeing data") - // Transaktionstabelle aufraeumen - FreeTransactions( pData, hConv ); - if( hConvPartner ) - FreeTransactions( pData, hConvPartner ); - - FreeConvHandle( pData, hConv ); - - WRITELOG("DdeDisconnect:End") - //WRITESTATUS("DdeDisconnect:End") - return TRUE; -} - -// static -BOOL ImpDdeMgr::DdeDisconnectList( HCONVLIST hConvList ) -{ - if( !CheckConvListId( hConvList ) ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; - return FALSE; - } - - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if ( !pData ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return FALSE; - } - HCONV hConv = 0; - GetFirstServer( pData, hConvList, hConv ); - while( hConv ) - { - DdeDisconnect( hConv ); - GetFirstServer( pData, hConvList, hConv ); - } - WinDestroyWindow( (HWND)hConvList ); - return TRUE; -} - - - -// static -HCONV ImpDdeMgr::DdeReconnect(HCONV hConv) -{ - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if ( !pData ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return 0; - } - return 0; -} - -// static -USHORT ImpDdeMgr::DdeQueryConvInfo(HCONV hConv, ULONG nTransId, CONVINFO* pCI) -{ - if( !pCI || pCI->nSize == 0) - return 0; - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if ( !pData ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return 0; - } - Transaction* pTrans; - if( nTransId != QID_SYNC ) - { - pTrans = ImpDdeMgr::GetTransTable( pData ); - pTrans += nTransId; - if( nTransId >= pData->nMaxTransCount || pTrans->hConvOwner == 0 ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_UNFOUND_QUEUE_ID; - return 0; - } - } - else - pTrans = 0; - - ImpHCONV* pConv = ImpDdeMgr::GetConvTable( pData ); - pConv += (ULONG)hConv; - if( hConv >= pData->nMaxConvCount || pConv->hWndThis == 0 ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; - return 0; - } - - USHORT nSize = pCI->nSize; - if( nSize > sizeof(CONVINFO) ) - nSize = sizeof(CONVINFO); - CONVINFO aTempInfo; - memset( &aTempInfo, 0, sizeof(CONVINFO) ); - aTempInfo.nSize = pCI->nSize; - aTempInfo.hConvPartner = pConv->hConvPartner; - aTempInfo.hszPartner = pConv->hszPartner; - aTempInfo.hszServiceReq = pConv->hszServiceReq; - aTempInfo.hszTopic = pConv->hszTopic; - aTempInfo.nStatus = pConv->nStatus; - aTempInfo.hConvList = pConv->hConvList; - aTempInfo.aConvCtxt = pConv->aConvContext; - if( pTrans ) - { - aTempInfo.nUser = pTrans->nUser; - aTempInfo.hszItem = pTrans->hszItem; - aTempInfo.nFormat = pTrans->nFormat; - aTempInfo.nType = pTrans->nType; - aTempInfo.nConvst = pTrans->nConvst; - aTempInfo.nLastError= pTrans->nLastError; - } - memcpy( pCI, &aTempInfo, nSize ); - - return nSize; -} - -// static -BOOL ImpDdeMgr::DdeSetUserHandle(HCONV hConv, ULONG nTransId, ULONG hUser) -{ - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if ( !pData ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return FALSE; - } - Transaction* pTrans = GetTransTable( pData ); - pTrans += nTransId; - if( !nTransId || !hConv || nTransId >= pData->nMaxTransCount || - pTrans->hConvOwner != hConv ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; - return FALSE; - } - if( !pTrans->hConvOwner) - { - ImpDdeMgr::nLastErrInstance = DMLERR_UNFOUND_QUEUE_ID; - return FALSE; - } - pTrans->nUser = hUser; - return TRUE; -} - -BOOL ImpDdeMgr::DdeAbandonTransaction( HCONV hConv, ULONG nTransId ) -{ - ////WRITELOG("DdeAbandonTransaction:Start") - if( !pData ) - { - nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return FALSE; - } - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - if( nTransId < 1 || nTransId >= pData->nMaxTransCount || - hConv < 1 || hConv >= pData->nMaxConvCount || !pConv->hWndThis) - { - nLastErrInstance = DMLERR_INVALIDPARAMETER; - return FALSE; - } - if( !hConv ) - { - DBG_ASSERT(0,"DdeAbandonTransaction:NULL-hConv not supported"); - nLastErrInstance = DMLERR_INVALIDPARAMETER; - return FALSE; - } - Transaction* pTrans = pTransTable; - pTrans += (USHORT)nTransId; - if( pTrans->hConvOwner != hConv ) - { - nLastErrInstance = DMLERR_UNFOUND_QUEUE_ID; - return FALSE; - } - - if( bInSyncTrans && nTransId == nSyncTransId ) - { - bSyncAbandonTrans = TRUE; - return TRUE; - } - USHORT nTempType = pTrans->nType; - nTempType &= (~XTYPF_MASK); - if( nTempType == (XTYP_ADVREQ & ~(XTYPF_NOBLOCK))) - { - ////WRITELOG("DdeAbandTrans:Advise Loop") - -// ---------------------------------------------------------------------- -// Der von der Deutschen Bank eingesetzte DDE-Server -// "Invision V2.71 Build 36 Mar 12 1999 V4.8.2" hat einen Bug, der -// dazu fuehrt, dass auf per WM_DDE_TERMINATE geschlossene Verbindungen -// nicht mit einem WM_DDE_TERMINATE geantwortet wird, wenn der -// entsprechende Link vorher per WM_DDE_UNADVISE beendet wurde. Dieser -// Bug tritt ab zwei parallel laufenden Links auf. Auf Wunsch der DB -// wurde das folgende Workaround eingebaut. -// ---------------------------------------------------------------------- -#define DEUTSCHE_BANK -#ifndef DEUTSCHE_BANK - -// Acknowledge ist beim Unadvise nicht ueblich -//#define SO_DDE_ABANDON_TRANSACTION_WAIT_ACK -#ifdef SO_DDE_ABANDON_TRANSACTION_WAIT_ACK - DDESTRUCT* pOutDDEData = MakeDDEObject( pConv->hWndPartner, - pTrans->hszItem, DDE_FACKREQ, 0 /*pTrans->nFormat*/, 0, 0); -#else - DDESTRUCT* pOutDDEData = MakeDDEObject( pConv->hWndPartner, - pTrans->hszItem, 0, 0 /*pTrans->nFormat*/, 0, 0); -#endif - WRITELOG("DdeAbandTrans:Waiting for acknowledge...") - pTrans->nConvst = XST_UNADVSENT; - if ( !MyWinDdePostMsg( pConv->hWndPartner, pConv->hWndThis, - WM_DDE_UNADVISE, pOutDDEData, DDEPM_RETRY ) ) - { - WRITELOG("DdeAbandTrans:PostMsg Failed") - return FALSE; - } -#ifdef SO_DDE_ABANDON_TRANSACTION_WAIT_ACK - WaitTransState( pTrans, nTransId, XST_UNADVACKRCVD, 0 ); -#else - pTrans->nConvst = XST_UNADVACKRCVD; -#endif - -#endif // DEUTSCHE_BANK - - WRITELOG("DdeAbandTrans:Ack received->Freeing transaction") - FreeTransaction( pData, nTransId ); - } - WRITELOG("DdeAbandonTransaction:End") - return TRUE; -} - -// wird von einem Server aufgerufen, wenn sich die Daten des -// Topic/Item-Paars geaendert haben. Diese Funktion fordert -// dann den Server auf, die Daten zu rendern (bei Hotlinks) und -// benachrichtigt die Clients -BOOL ImpDdeMgr::DdePostAdvise( HSZ hszTopic, HSZ hszItem) -{ - ////WRITELOG("DdePostAdvise:Start") - ////WRITESTATUS("DdePostAdvise:Start") - -#if 0 && defined( OV_DEBUG ) - String aDebStr("DdePostAdvise:Item "); - aDebStr += (ULONG)hszItem; - WRITELOG((char*)(const char*)aDebStr) -#endif - - Transaction* pTrans = pTransTable; - pTrans++; - USHORT nCurTrans = 1; - USHORT nUsedTransactions = pData->nCurTransCount; - while( nUsedTransactions && nCurTrans < pData->nMaxTransCount ) - { - HCONV hOwner = pTrans->hConvOwner; - if( hOwner ) - { - nUsedTransactions--; - USHORT nTempType = pTrans->nType; - nTempType &= (~XTYPF_MASK); - if( nTempType == (XTYP_ADVREQ & (~XTYPF_NOBLOCK) ) ) - { - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hOwner; - if(hszItem == pTrans->hszItem && pConv->hszTopic == hszTopic) - { - if( pConv->hConvPartner ) - { - // Transaktionen werden immer vom Client erzeugt - // -> auf Server-HCONV umschalten - hOwner = pConv->hConvPartner; - pConv = pConvTable; - pConv += (USHORT)hOwner; - } - HWND hWndClient = pConv->hWndPartner; - HWND hWndServer = pConv->hWndThis; -#if 0 && defined( OV_DEBUG ) - String aDebStr("DdePostAdvise: Server:"); - aDebStr += (ULONG)hWndServer; - aDebStr += " Client:"; - aDebStr += (ULONG)hWndClient; - WRITELOG((char*)(const char*)aDebStr) -#endif - DDESTRUCT* pOutDDEData; - if ( pTrans->nType & XTYPF_NODATA ) - { - // Warm link - ////WRITELOG("DdePostAdvise:Warm link found") - pOutDDEData = MakeDDEObject( hWndClient, hszItem, - DDE_FNODATA, pTrans->nFormat, 0, 0 ); - } - else - { - // Hot link - ////WRITELOG("DdePostAdvise:Hot link found") - pOutDDEData = Callback( XTYP_ADVREQ, - pTrans->nFormat, hOwner, hszTopic, - hszItem, (HDDEDATA)0, 1, 0 ); - } - if( pOutDDEData ) - { - // todo: FACK_REQ in Out-Data setzen, wenn pTrans->nType & XTYPF_ACKREQ - ////WRITELOG("DdePostAdvise:Sending data/notification") - BOOL bSuccess = MyWinDdePostMsg( hWndClient, - hWndServer,WM_DDE_DATA, pOutDDEData, DDEPM_RETRY); - if( bSuccess ) - { - // auf Acknowledge des Partners warten ? - if( pTrans->nType & XTYPF_ACKREQ ) - { - pTrans->nConvst = XST_ADVDATASENT; - // Impl. ist falsch! => korrekt: XST_ADVDATAACKRCVD - WaitTransState(pTrans, nCurTrans, - XST_UNADVACKRCVD, 0); - } - } - else - { - ////WRITELOG("DdePostAdvise:PostMsg failed") - nLastErrInstance = DMLERR_POSTMSG_FAILED; - } - } - else - { - ////WRITELOG("DdePostAdvise:No data to send") - } - } - } - } - nCurTrans++; - pTrans++; - } - ////WRITELOG("DdePostAdvise:End") - return TRUE; -} - -BOOL ImpDdeMgr::DdeEnableCallback( HCONV hConv, USHORT wCmd) -{ - return FALSE; -} - -// Rueckgabe: 0==Service nicht registriert; sonst Pointer auf Service-Eintrag -ImpService* ImpDdeMgr::GetService( HSZ hszService ) -{ - ImpService* pPtr = pServices; - if( !pPtr || !hszService ) - return 0; - for( ULONG nIdx = 0; nIdx < nServiceCount; nIdx++, pPtr++ ) - { - if(( hszService == pPtr->hBaseServName ) || - ( hszService == pPtr->hInstServName ) ) - return pPtr; - } - return 0; -} - - -// legt Service in Service-Tabelle ab. Tabelle wird ggf. expandiert -ImpService* ImpDdeMgr::PutService( HSZ hszService ) -{ - if( !pServices ) - { - DBG_ASSERT(nServiceCount==0,"DDE:Bad ServiceCount"); - pServices = new ImpService[ DDEMLSERVICETABLE_INISIZE ]; - memset( pServices, 0, DDEMLSERVICETABLE_INISIZE* sizeof(ImpService)); - nServiceCount = DDEMLSERVICETABLE_INISIZE; - } - ImpService* pPtr = pServices; - USHORT nCurPos = 0; - while( pPtr ) - { - if( pPtr->hBaseServName == 0 ) - break; - nCurPos++; - if( nCurPos < nServiceCount ) - pPtr++; - else - pPtr = 0; - } - if( !pPtr ) - { - // Tabelle vergroessern - pPtr = new ImpService[ nServiceCount + DDEMLSERVICETABLE_INISIZE ]; - memset( pPtr, 0, DDEMLSERVICETABLE_INISIZE* sizeof(ImpService)); - memcpy( pPtr, pServices, nServiceCount * sizeof(ImpService) ); -#ifdef DBG_UTIL - memset( pServices, 0, nServiceCount * sizeof(ImpService) ); -#endif - delete pServices; - pServices = pPtr; - pPtr += nServiceCount; // zeigt auf erste neue Position - nServiceCount += DDEMLSERVICETABLE_INISIZE; - } - DBG_ASSERT(pPtr->hBaseServName==0,"DDE:Service not empty"); - DBG_ASSERT(pPtr->hInstServName==0,"DDE:Service not empty"); - - DdeKeepStringHandle( hszService ); - - USHORT nStrLen = (USHORT)DdeQueryString( hszService, 0, 0, 0); - char* pBuf = new char[ nStrLen + 1 ]; - DdeQueryString(hszService, pBuf, nStrLen, 850 /* CodePage*/ ); - pBuf[ nStrLen ] = 0; - String aStr( (ULONG)hWndServer ); - aStr += pBuf; - HSZ hszInstServ = DdeCreateStringHandle( (PSZ)(const char*)pBuf, 850 ); - delete pBuf; - - pPtr->hBaseServName = hszService; - pPtr->hInstServName = hszInstServ; - return pPtr; -} - -void ImpDdeMgr::BroadcastService( ImpService* pService, BOOL bRegistered ) -{ - DBG_ASSERT(pService,"DDE:No Service"); - if( !pService ) - return; - MPARAM aMp1 = (MPARAM)(pService->hBaseServName); - MPARAM aMp2 = (MPARAM)(pService->hInstServName); - ULONG nMsg; - if( bRegistered ) - nMsg = WM_DDEML_REGISTER; - else - nMsg = WM_DDEML_UNREGISTER; - - HWND* pPtr = pAppTable; - for( USHORT nPos = 0; nPos < pData->nMaxAppCount; nPos++, pPtr++ ) - { - HWND hWndCurWin = *pPtr; - if ( hWndCurWin && hWndCurWin != hWndServer ) - WinSendMsg( hWndCurWin, nMsg, aMp1, aMp2 ); - } -} - -HDDEDATA ImpDdeMgr::DdeNameService( HSZ hszService, USHORT afCmd ) -{ - HDDEDATA hRet = (HDDEDATA)1; - - if( afCmd & DNS_FILTERON ) - bServFilterOn = TRUE; - else if( afCmd & DNS_FILTEROFF ) - bServFilterOn = FALSE; - ImpService* pService = GetService( hszService ); - BOOL bRegister = (BOOL)(afCmd & DNS_REGISTER); - if( bRegister ) - { - if( !pService ) - { - pService = PutService( hszService ); - BroadcastService( pService, TRUE ); - } - } - else - { - if( pService ) - { - BroadcastService( pService, FALSE ); - DdeFreeStringHandle( pService->hBaseServName ); - pService->hBaseServName = 0; - DdeFreeStringHandle( pService->hInstServName ); - pService->hInstServName = 0; - } - hRet = (HDDEDATA)0; // Service nicht gefunden - } - return hRet; -} - - -// static -HDDEDATA ImpDdeMgr::DdeClientTransaction(void* pDdeData, ULONG cbData, - HCONV hConv, HSZ hszItem, USHORT nFormat, USHORT nType, - ULONG nTimeout, ULONG* pResult) -{ - //WRITELOG("DdeClientTransaction:Start") - -#if 0 && defined(OV_DEBUG) - if( nType == XTYP_REQUEST ) - { - WRITELOG("Start XTYP_REQUEST"); - WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, - "Start XTYP_REQUEST","DdeClientTransaction", - HWND_DESKTOP,MB_OK); - } -#endif - - if( pResult ) - *pResult = 0; - - ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); - if ( !pData ) - { - ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; - return (HDDEDATA)0; - } - - BOOL bIsDdeHandle = (BOOL)(pDdeData && cbData==0xffffffff); - BOOL bAppOwnsHandle = (BOOL)( bIsDdeHandle && - (((DDESTRUCT*)pDdeData)->fsStatus & IMP_HDATAAPPOWNED) ); - - BOOL bNoData = (BOOL)(nType & XTYPF_NODATA)!=0; - BOOL bAckReq = (BOOL)(nType & XTYPF_ACKREQ)!=0; - USHORT nTypeFlags = nType & XTYPF_MASK; - nType &= (~XTYPF_MASK); - - BOOL bSync = (BOOL)( nTimeout != TIMEOUT_ASYNC ) != 0; - if( nType == XTYP_ADVSTART ) - bSync = TRUE; - - // Mapping transaction -> OS/2-Message - USHORT nTimeoutErr, nMsg; - switch ( nType ) - { - case XTYP_ADVSTART: - nMsg = WM_DDE_ADVISE; - nTimeoutErr = DMLERR_ADVACKTIMEOUT; -{ - nTimeout = 60000; -#if 0 && defined(OV_DEBUG) - char aBuf[ 128 ]; - ImpDdeMgr::DdeQueryString( hszItem,aBuf,127,850); - String aXXStr("Establishing hotlink "); - aXXStr += aBuf; - WRITELOG((char*)aXXStr.GetStr()); -#endif - -} - break; - - case XTYP_ADVSTOP: - nMsg = WM_DDE_UNADVISE; - nTimeoutErr = DMLERR_UNADVACKTIMEOUT; - break; - - case XTYP_REQUEST: - nMsg = WM_DDE_REQUEST; - nTimeoutErr = DMLERR_DATAACKTIMEOUT; - break; - - case XTYP_POKE: - nMsg = WM_DDE_POKE; - nTimeoutErr = DMLERR_POKEACKTIMEOUT; - break; - - case XTYP_EXECUTE: - nMsg = WM_DDE_EXECUTE; - nTimeoutErr = DMLERR_EXECACKTIMEOUT; - break; - - default: - nMsg = 0; - } - if(!hConv || (USHORT)hConv>= pData->nMaxConvCount || !nType || !nMsg || - (nType != XTYP_EXECUTE && (!hszItem || !nFormat)) ) - { - WRITELOG("DdeClientTransaction:Invalid parameter") - ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; - if( bIsDdeHandle && !bAppOwnsHandle ) - DdeFreeDataHandle( (HDDEDATA)pDdeData ); - return (HDDEDATA)0; - } - - // ueber den Conversation handle das ImpDdeMgr-Objekt holen - ImpHCONV* pConv = GetConvTable( pData ); - pConv += (USHORT)hConv; - ImpConvWndData* pObj = - (ImpConvWndData*)WinQueryWindowULong( pConv->hWndThis, 0 ); - ImpDdeMgr* pThis = pObj->pThis; - - if( bSync && pThis->bInSyncTrans ) - { - WRITELOG("DdeClientTransaction:Already in sync. transaction") - ImpDdeMgr::nLastErrInstance = DMLERR_REENTRANCY; - if( bIsDdeHandle && !bAppOwnsHandle ) - DdeFreeDataHandle( (HDDEDATA)pDdeData ); - return (HDDEDATA)0; - } - - Transaction* pTrans; - - BOOL bReqOnAdvLoop = FALSE; - ULONG nTransId = GetTransaction( pData, hConv, hszItem, nFormat ); - if( nTransId ) - { - // WRITELOG("DdeClientTransaction:Transaction found") - pTrans = GetTransTable( pData ); - pTrans += (USHORT)nTransId; - USHORT nTransType = pTrans->nType; - nTransType &= (~XTYPF_MASK); - if( (nType != XTYP_REQUEST && nTransType == nType) || - // wird Advise-Loop schon zum requesten missbraucht ? - (nType == XTYP_REQUEST && - nTransType == XTYP_ADVREQ && - pTrans->nConvst == XST_WAITING_REQDATA)) - { - // dieser Kanal ist dicht! - WRITELOG("DdeClientTransaction:Transaction already used") - ImpDdeMgr::nLastErrInstance = DMLERR_REENTRANCY; - if( bIsDdeHandle && !bAppOwnsHandle ) - DdeFreeDataHandle( (HDDEDATA)pDdeData ); - return (HDDEDATA)0; - } - else if( nTransType == XTYP_ADVREQ ) - { - switch( nType ) - { - case XTYP_ADVSTOP: - //WRITELOG("DdeClientTransaction:Stopping advise trans") - pTrans->nType = XTYP_ADVSTOP; - break; - - case XTYP_ADVSTART: - //WRITELOG("DdeClientTransaction:Adj. Advise-Params") - pTrans->nType = XTYP_ADVREQ; - if( bNoData ) - pTrans->nType |= XTYPF_NODATA; - if( bAckReq ) - pTrans->nType |= XTYPF_ACKREQ; - if( pResult ) - *pResult = nTransId; - return (HDDEDATA)TRUE; - - case XTYP_REQUEST: - // WRITELOG("DdeClientTransaction:Using adv trans for req") - // nConvst wird unten auf XST_WAITING_REQDATA gesetzt - bReqOnAdvLoop = TRUE; - break; - - default: - WRITELOG("DdeClientTransaction:Invalid parameter") - ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; - if( bIsDdeHandle && !bAppOwnsHandle ) - DdeFreeDataHandle( (HDDEDATA)pDdeData ); - return (HDDEDATA)FALSE; - } - } - } - else - { - // WRITELOG("DdeClientTransaction:Creating transaction") - nTransId = CreateTransaction(pData, hConv, hszItem, nFormat, nType); - } - - pTrans = GetTransTable( pData ); - pTrans += (USHORT)nTransId; - pTrans->nConvst = XST_WAITING_ACK; - if( nType == XTYP_REQUEST ) - pTrans->nConvst = XST_WAITING_REQDATA; - - HWND hWndServer = pConv->hWndPartner; - HWND hWndClient = pConv->hWndThis; - - HDDEDATA pOutDDEData; - if( bIsDdeHandle ) - { - if( bAppOwnsHandle ) - { - // wir muessen leider leider duplizieren, da uns OS/2 - // keine Chance laesst, diesen Status im Datenobjekt - // zu versenken. - ////WRITELOG("DdeClientTransaction:Copying handle") - HDDEDATA pNew; - HDDEDATA pData = (HDDEDATA)pDdeData; - if( !(MyDosAllocSharedMem((PPVOID)&pNew, NULL, pData->cbData, - PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | OBJ_ANY, - "MakeDDEObject"))) - { - memcpy( pNew, pData, pData->cbData ); - pOutDDEData = pNew; - } - else - { - WRITELOG("DdeClientTransaction:No Memory") - ImpDdeMgr::nLastErrInstance = DMLERR_LOW_MEMORY; - return (HDDEDATA)0; - } - } - else - pOutDDEData = (HDDEDATA)pDdeData; - } - else - pOutDDEData=MakeDDEObject(hWndServer,hszItem,0,nFormat,pDdeData,cbData); - - pOutDDEData->fsStatus |= nTypeFlags; - - HDDEDATA pDDEInData = 0; - if( bSync ) - { - if( nType != XTYP_REQUEST ) - pOutDDEData->fsStatus |= DDE_FACKREQ; - - // WRITELOG("DdeClientTransaction:Starting sync. trans.") - pThis->hSyncResponseData = (HDDEDATA)0; - pThis->nSyncResponseMsg = 0; - pThis->bInSyncTrans = TRUE; - pThis->nSyncTransId = nTransId; - pThis->bSyncAbandonTrans = FALSE; - - if ( !MyWinDdePostMsg( hWndServer, hWndClient, nMsg, pOutDDEData, - DDEPM_RETRY) ) - { - WRITELOG("DdeClientTransaction:PostMsg failed") - nLastErrInstance = DMLERR_POSTMSG_FAILED; - if( !bReqOnAdvLoop ) - FreeTransaction( pData, nTransId ); - else - { - DBG_ASSERT(pTrans->nType==XTYP_ADVREQ,"DDE:Error!") - pTrans->nConvst = 0; - } - return FALSE; - } - HAB hAB = WinQueryAnchorBlock( hWndClient ); - ULONG nDummyTimer = WinStartTimer( hAB, 0, 0, 50 ); - ULONG nTimeoutId = TID_USERMAX - nTransId; - WinStartTimer( hAB, hWndClient, nTimeoutId, nTimeout ); - QMSG aQueueMsg; - BOOL bLoop = TRUE; - while( bLoop ) - { - if( pThis->nSyncResponseMsg ) - bLoop = FALSE; - else - { - if( WinGetMsg(hAB,&aQueueMsg,0,0,0 )) - { - WinDispatchMsg( hAB, &aQueueMsg ); - } - else - bLoop = FALSE; - } - } - - WinStopTimer( hAB, hWndClient, nTimeoutId ); - WinStopTimer( hAB, 0, nDummyTimer ); - - // - // Der Speicherblock pOutDDEData muss vom Server geloescht worden sein! - // Ueberlegen: Nochmal loeschen, falls Server buggy ist, ansonsten - // platzt uns bald der Adressraum! - // - if( !pThis->nSyncResponseMsg ) - { - // unsere App wurde beendet - ////WRITELOG("DdeClientTransaction:App terminated") - return 0; - } - pDDEInData = pThis->hSyncResponseData; - nMsg = pThis->nSyncResponseMsg; - pThis->hSyncResponseData= 0; - pThis->nSyncResponseMsg = 0; - pThis->bInSyncTrans = FALSE; - pThis->nSyncTransId = 0; - if( !pDDEInData && nMsg != WM_TIMER ) - { - DBG_ASSERT(0,"Dde:No data!"); - WRITELOG("DdeClientTransaction: No Data!") - return (HDDEDATA)0; - } - switch( nMsg ) - { - case WM_TIMER: - WRITELOG("DdeClientTransaction:Timeout!") - nLastErrInstance = nTimeoutErr; - if( bReqOnAdvLoop ) - // auf normalen Loop-Betrieb zurueckschalten - pTrans->nConvst = XST_WAITING_ADVDATA; - break; - - case WM_DDE_ACK: - { - // WRITELOG("DdeClientTransaction:Ack received") - BOOL bPositive = (BOOL)(pDDEInData->fsStatus & DDE_FACK); - MyDosFreeMem( pDDEInData,"DdeClientTransaction" ); - pDDEInData = (HDDEDATA)bPositive; - if( nType == XTYP_ADVSTART && pDDEInData ) - { - -#if 0 && defined(OV_DEBUG) - char aBuf[ 128 ]; - ImpDdeMgr::DdeQueryString( pTrans->hszItem,aBuf,128,850); - String aXXStr("Hotlink "); -#endif - - if( bPositive ) - { - pTrans->nType = XTYP_ADVREQ; - // Hot/Warmlink, Ack - pTrans->nType |= nTypeFlags; - // XST_WAITING_ACK ==> XST_WAITING_ADVDATA - pTrans->nConvst = XST_WAITING_ADVDATA; - -#if 0 && defined(OV_DEBUG) - aXXStr += "established "; - aXXStr += aBuf; -#endif - - } - -#if 0 && defined(OV_DEBUG) - else - { - aXXStr += "failed "; - aXXStr += aBuf; - } - WRITELOG((char*)aXXStr.GetStr()); -#endif - - } - } - break; - - case WM_DDE_DATA: - // WRITELOG("DdeClientTransaction:Data received") - // WRITEDATA(pDDEInData) - if( bReqOnAdvLoop ) - { - DBG_ASSERT(pTrans->nConvst==XST_WAITING_REQDATA,"DDE:Bad state"); - DBG_ASSERT(pTrans->nType==XTYP_ADVREQ,"DDE:Bad state"); - // auf Loop-Betrieb umschalten - pTrans->nConvst = XST_WAITING_ADVDATA; - } - break; - - default: - WRITELOG("DdeClientTransaction:Unexpected msg") - MyDosFreeMem( pDDEInData,"DdeClientTransaction" ); - pDDEInData = 0; - } - pThis->bSyncAbandonTrans = FALSE; - pThis->bInSyncTrans = FALSE; - if( pThis->bSyncAbandonTrans && bReqOnAdvLoop ) - pThis->DdeAbandonTransaction( hConv, nTransId ); - } - else - { - // WRITELOG("DdeClientTransaction:Starting async. trans.") - pDDEInData = (HDDEDATA)MyWinDdePostMsg( hWndServer, hWndClient, nMsg, - pOutDDEData, DDEPM_RETRY); - if( !pDDEInData ) - { - WRITELOG("DdeClientTransaction:PostMsg failed") - nLastErrInstance = DMLERR_POSTMSG_FAILED; - if( !bReqOnAdvLoop ) - FreeTransaction( pData, nTransId ); - else - { - DBG_ASSERT(pTrans->nType==XTYP_ADVREQ,"DDE:Error!") - pTrans->nConvst = 0; - } - } - else - { - // WRITELOG("DdeClientTransaction:Async trans. success") - if( pResult ) - *pResult = nTransId; - } - } -#if 0 && defined( OV_DEBUG ) - if( nType == XTYP_REQUEST ) - { - WRITELOG("End XTYP_REQUEST"); - WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, - "End XTYP_REQUEST","DdeClientTransaction", - HWND_DESKTOP,MB_OK); - } -#endif - //WRITELOG("DdeClientTransaction:End") - //WRITESTATUS("DdeClientTransaction:End") - return pDDEInData; -} - -MRESULT ImpDdeMgr::DdeRegister( ImpWndProcParams* pParams ) -{ - MRESULT nRet = (MRESULT)0; - if ( !(nTransactFilter & CBF_SKIP_REGISTRATIONS) ) - { - HSZ hSBaseName = (HSZ)pParams->nPar1; - HSZ hIBaseName = (HSZ)pParams->nPar2; - nRet=(MRESULT)Callback(XTYP_REGISTER,0,0,hSBaseName,hIBaseName,0,0,0); - } - return nRet; -} - -MRESULT ImpDdeMgr::DdeUnregister( ImpWndProcParams* pParams ) -{ - MRESULT nRet = (MRESULT)0; - if ( !(nTransactFilter & CBF_SKIP_UNREGISTRATIONS) ) - { - HSZ hSBaseName = (HSZ)pParams->nPar1; - HSZ hIBaseName = (HSZ)pParams->nPar2; - nRet=(MRESULT)Callback(XTYP_UNREGISTER,0,0,hSBaseName,hIBaseName,0,0,0); - } - return nRet; -} - -MRESULT ImpDdeMgr::DdeTimeout( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeTimeout:Received") - if( nSyncResponseMsg ) - { - ////WRITELOG("DdeTimeout:Trans already processed->ignoring timeout") - return (MRESULT)1; - } - ULONG nTimerId = (ULONG)pParams->nPar1; - ULONG nTransId = TID_USERMAX - nTimerId; - Transaction* pTrans = pTransTable; - pTrans += (USHORT)nTransId; - if( nTransId < 1 || nTransId >= pData->nMaxTransCount || - pTrans->hConvOwner == 0 ) - { - DBG_ASSERT(0,"DdeTimeout:Invalid TransactionId"); - return (MRESULT)1; - } - if( bInSyncTrans && nTransId == nSyncTransId ) - { - USHORT nTempType = pTrans->nType; - nTempType &= (~XTYPF_MASK); - // advise-loops koennen nur innerhalb synchroner - // requests timeouts bekommen. die transaktion wird - // in diesem fall nicht geloescht. - if( nTempType != (XTYP_ADVREQ & (~XTYPF_NOBLOCK) )) - { - ////WRITELOG("DdeTimeout:Freeing transaction") - FreeTransaction( pData, nTransId ); - } - nSyncResponseMsg = WM_TIMER; -#if 0 && defined( OV_DEBUG ) - String aMsg("DdeTimeout:Transaction="); - aMsg += nTransId; - WRITELOG((char*)(const char*)aMsg) -#endif - } - else - { - ////WRITELOG("DdeTimeout:Async transaction timed out") - pTrans->nConvst = XST_TIMEOUT; - } - return (MRESULT)1; -} - - - -MRESULT ImpDdeMgr::DdeTerminate( ImpWndProcParams* pParams ) -{ - WRITELOG("DdeTerminate:Received") - HWND hWndThis = pParams->hWndReceiver; - HWND hWndPartner = (HWND)(pParams->nPar1); - - HCONV hConv = GetConvHandle( pData, hWndThis, hWndPartner ); -#if 0 && defined( OV_DEBUG ) - String strDebug("DdeTerminate:ConvHandle="); - strDebug += (USHORT)hConv; - WRITELOG((char*)(const char*)strDebug) -#endif - ImpHCONV* pConv = pConvTable + (USHORT)hConv; - if( hConv ) - { - // warten wir auf ein DDE_TERMINATE Acknowledge ? - if( pConv->nStatus & ST_TERMINATED ) - { - ////WRITELOG("DdeTerminate:TERMINATE-Ack received") - pConv->nStatus |= ST_TERMACKREC; - return (MRESULT)0; // DdeDisconnect raeumt jetzt auf - } - - // sind wir Server?, wenn ja: die App benachrichtigen, - // dass die Advise loops gestoppt wurden und die - // Transaktionen loeschen - - // OV 26.07.96: Die das TERMINATE empfangende App muss - // die Transaction-Tabelle abraeumen, egal ob Server oder Client!! - // Es muessen alle Trans geloescht werden, die als Owner den - // Client oder den Server haben! - // if( !(pConv->nStatus & ST_CLIENT ) ) - SendUnadvises( hConv, 0, FALSE ); // alle Formate & nicht loeschen - SendUnadvises( pConv->hConvPartner, 0, FALSE ); - - // wir werden von draussen gekillt - if ( !(nTransactFilter & CBF_SKIP_DISCONNECTS) ) - { - Callback( XTYP_DISCONNECT, 0, hConv, 0, 0, 0, - 0, (ULONG)IsSameInstance(hWndPartner)); - } - - // kann unsere Partner-App DDEML ? - if( !(pConv->hConvPartner) ) - { - // nein, deshalb Transaktionstabelle selbst loeschen - ////WRITELOG("DdeTerminate:Freeing transactions") - FreeTransactions( pData, hConv ); - } - } - else - nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; - -#if 0 && defined(OV_DEBUG) - if( !WinIsWindow(0,hWndPartner)) - { - WRITELOG("DdeTerminate:hWndPartner not valid") - } - if(!WinIsWindow(0,hWndThis)) - { - WRITELOG("DdeTerminate:hWndThis not valid") - } -#endif - - if( hConv ) - { - // hWndThis nicht loeschen, da wir den Handle noch fuer - // das Acknowledge brauchen - ////WRITELOG("DdeTerminate:Freeing conversation") - FreeConvHandle( pData, hConv, FALSE ); - } - - ////WRITELOG("DdeTerminate:Acknowledging DDE_TERMINATE") - -#ifdef OV_DEBUG - DBG_ASSERT(WinIsWindow( 0, hWndThis ),"hWndThis not valid"); -#endif - - if( !WinDdePostMsg( hWndPartner, hWndThis, WM_DDE_TERMINATE, 0, DDEPM_RETRY )) - { - ////WRITELOG("DdeTerminate:Acknowledging DDE_TERMINATE failed") - } - // jetzt hWndThis loeschen - DestroyConversationWnd( hWndThis ); - - return (MRESULT)0; -} - - -/* - Zuordnung des Conversationhandles: - - Verbindungsaufbau: - Client: DdeInitiate( HWNDClient ) - Server: Post( WM_DDE_INITIATEACK( HWNDServer )) - Client: CreateConvHandle( HWNDClient, HWNDServer ) - - Datenaustausch: - Server: Post(WM_DDE_ACK( HWNDSender )) - Client: GetConvHandle( HWNDClient, HWNDSender ) -*/ - -MRESULT ImpDdeMgr::ConvWndProc( HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2 ) -{ - ImpWndProcParams aParams; - - MRESULT nRet = (MRESULT)0; - aParams.hWndReceiver= hWnd; - aParams.nPar1 = nPar1; - aParams.nPar2 = nPar2; - - switch( nMsg ) - { - -#ifdef DBG_UTIL - case WM_DDE_INITIATE : - DBG_ASSERT(0,"dde:unexpected msg"); - nRet = (MRESULT)TRUE; - break; -#endif - - case WM_DDE_INITIATEACK : nRet = DdeInitiateAck(&aParams); break; - case WM_DDE_ACK : nRet = DdeAck( &aParams ); break; - case WM_DDE_ADVISE : nRet = DdeAdvise( &aParams ); break; - case WM_DDE_DATA : nRet = DdeData( &aParams ); break; - case WM_DDE_EXECUTE : nRet = DdeExecute( &aParams ); break; - case WM_DDE_POKE : nRet = DdePoke( &aParams ); break; - case WM_DDE_REQUEST : nRet = DdeRequest( &aParams ); break; - case WM_DDE_TERMINATE : nRet = DdeTerminate( &aParams ); break; - case WM_DDE_UNADVISE : nRet = DdeUnadvise( &aParams ); break; - case WM_TIMER : nRet = DdeTimeout( &aParams ); break; - } - return nRet; -} - -MRESULT ImpDdeMgr::SrvWndProc( HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2 ) -{ - MRESULT nRet = (MRESULT)0; - - ImpWndProcParams aParams; - aParams.hWndReceiver= hWnd; - aParams.nPar1 = nPar1; - aParams.nPar2 = nPar2; - - switch( nMsg ) - { -#ifdef DBG_UTIL - case WM_DDE_ACK : - case WM_DDE_ADVISE : - case WM_DDE_EXECUTE : - case WM_DDE_POKE : - case WM_DDE_REQUEST : - case WM_DDE_UNADVISE : - case WM_DDE_DATA : - case WM_DDE_INITIATEACK : - DBG_ASSERT(0,"dde:unexpected msg"); - nRet = (MRESULT)TRUE; - break; -#endif - - case WM_DDE_TERMINATE : - break; // DDE_INITIATE wurde im DDE_INITIATEACK terminiert - - // ein Client will was von uns - case WM_DDE_INITIATE : - nRet = DdeInitiate( &aParams ); - break; - - // eine ddeml-faehige App. hat einen Service (typ. AppName) [de]reg. - case WM_DDEML_REGISTER : - nRet = DdeRegister( &aParams ); - break; - - case WM_DDEML_UNREGISTER : - nRet = DdeUnregister( &aParams ); - break; - }; - return nRet; -} - - -MRESULT ImpDdeMgr::DdeAck( ImpWndProcParams* pParams ) -{ - //WRITELOG("DdeAck:Start") - HSZ hszItem; - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - if( pInDDEData ) - { - BOOL bPositive = (BOOL)(pInDDEData->fsStatus & DDE_FACK ) != 0; - BOOL bBusy = bPositive ? FALSE : (BOOL)(pInDDEData->fsStatus & DDE_FBUSY ) != 0; - BOOL bNotProcessed = (BOOL)(pInDDEData->fsStatus & DDE_NOTPROCESSED ) != 0; -#if 0 && defined( OV_DEBUG ) - String aDebStr("DdeAck:Received "); - if( bPositive ) - aDebStr += "(positive)"; - else - aDebStr += "(negative)"; - if( bBusy ) - aDebStr += "(busy)"; - if( bNotProcessed ) - aDebStr += "(not processed)"; - WRITELOG((char*)(const char*)aDebStr) -#endif - // ein DDE_ACK niemals bestaetigen (um endlosschleifen zu vermeiden) - pInDDEData->fsStatus &= (~DDE_FACKREQ); - } - else - { - //WRITELOG("DdeAck:Received (no data!)") - return (MRESULT)0; - } - - HCONV hConv = CheckIncoming(pParams, 0, hszItem); -#ifdef OV_DEBUG - if( !hConv ) - { - WRITELOG("DdeAck:HCONV not found") - } -#endif - ULONG nTransId=GetTransaction(pData,hConv,hszItem,pInDDEData->usFormat); - if( !nTransId ) - { - WRITELOG("DdeAck:Transaction not found") - MyDosFreeMem( pInDDEData,"DdeAck" ); - return (MRESULT)0; - } - - BOOL bThisIsSync = (BOOL)( bInSyncTrans && nTransId == nSyncTransId ); -#if 0 && defined( OV_DEBUG ) - if( bThisIsSync) - WRITELOG("DdeAck: sync transaction") - else - WRITELOG("DdeAck: async transaction") -#endif - // pruefen, ob die Transaktion abgeschlossen ist. - Transaction* pTrans = pTransTable; - pTrans += (USHORT)nTransId; - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - - if( pTrans->nConvst == XST_UNADVSENT ) - { - //WRITELOG("DdeAck:Unadvise-Ack received") - pTrans->nConvst = XST_UNADVACKRCVD; - MyDosFreeMem( pInDDEData,"DdeAck" ); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; - } - if( pTrans->nConvst == XST_ADVDATASENT ) - { - //WRITELOG("DdeAck:AdvData-Ack received") - pTrans->nConvst = XST_ADVDATAACKRCVD; - MyDosFreeMem( pInDDEData,"DdeAck" ); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; - } - - USHORT nType = pTrans->nType; - nType &= (~XTYPF_MASK); - // beginn einer advise-loop oder request auf advise-loop ? - // wenn ja: transaktion nicht loeschen - BOOL bFinished = (BOOL)(nType != XTYP_ADVSTART && - nType != (XTYP_ADVREQ & (~XTYPF_NOBLOCK)) ); - if( bFinished ) - { - if( !bThisIsSync ) - { - ////WRITELOG("DdeAck:Transaction completed") - Callback( XTYP_XACT_COMPLETE, pInDDEData->usFormat, hConv, - pConv->hszTopic, hszItem, (HDDEDATA)0, nTransId, 0 ); - } - ////WRITELOG("DdeAck:Freeing transaction") - FreeTransaction( pData, nTransId ); - } - - if( bThisIsSync ) - { - hSyncResponseData = pInDDEData; - nSyncResponseMsg = WM_DDE_ACK; - } - else - { - MyDosFreeMem( pInDDEData,"DdeAck" ); - } - - DdeFreeStringHandle( hszItem ); - - return (MRESULT)0; -} - - -USHORT ImpDdeMgr::SendUnadvises(HCONV hConvServer,USHORT nFormat,BOOL bFree) -{ - USHORT nTransFound = 0; - BOOL bCallApp = (BOOL)(!(nTransactFilter & CBF_FAIL_ADVISES)); -#if 0 && defined( OV_DEBUG ) - String aStr("Unadvising transactions for HCONV="); - aStr += (ULONG)hConvServer; - aStr += " CallApp:"; aStr += (USHORT)bCallApp; - WRITELOG((char*)aStr.GetStr()) -#endif - - - // wenn wir weder loeschen noch die App benachrichtigen sollen, - // koennen wir gleich wieder returnen - if( !hConvServer || ( !bFree && !bCallApp ) ) - return 0; - - ImpHCONV* pConvSrv = pConvTable; - pConvSrv += (USHORT)hConvServer; - HSZ hszTopic = pConvSrv->hszTopic; - - Transaction* pTrans = pTransTable; - pTrans++; - USHORT nCurTransId = 1; - USHORT nCurTransactions = pData->nCurTransCount; - while( nCurTransactions && nCurTransId < pData->nMaxTransCount ) - { - if( pTrans->hConvOwner ) - nCurTransactions--; - if( pTrans->hConvOwner == hConvServer && - (pTrans->nType & XTYP_ADVREQ) ) - { - if( !nFormat || (nFormat == pTrans->nFormat) ) - { - nTransFound++; - if( bCallApp ) - { - //WRITELOG("SendUnadvises:Notifying App") - Callback( XTYP_ADVSTOP, pTrans->nFormat, hConvServer, - hszTopic, pTrans->hszItem, 0,0,0 ); - } - if( bFree ) - FreeTransaction( pData, (ULONG)nCurTransId ); - } - } - nCurTransId++; - pTrans++; - } - return nTransFound; -} - - - -HCONV ImpDdeMgr::CheckIncoming( ImpWndProcParams* pParams, ULONG nTransMask, - HSZ& rhszItem ) -{ -// ////WRITELOG("CheckIncoming") - rhszItem = 0; - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - if( !pInDDEData ) - { - // ////WRITELOG("CheckIncoming:PDDESTRUCT==0") - return (HCONV)0; - } - - HWND hWndThis = pParams->hWndReceiver; - HWND hWndClient = (HWND)pParams->nPar1; - - BOOL bReject = (BOOL)(nTransactFilter & nTransMask); - HCONV hConv; - if( !bReject ) - hConv = GetConvHandle( pData, hWndThis, hWndClient ); - if ( bReject || !hConv ) - return (HCONV)0; - - rhszItem = DdeCreateStringHandle( - ((char*)(pInDDEData)+pInDDEData->offszItemName), 850 ); - - // ////WRITELOG("CheckIncoming:OK"); - return hConv; -} - - -MRESULT ImpDdeMgr::DdeAdvise( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeAdvise:Received") - HSZ hszItem; - HCONV hConv = CheckIncoming(pParams, CBF_FAIL_ADVISES, hszItem); - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - HWND hWndThis = pParams->hWndReceiver; - HWND hWndClient = (HWND)pParams->nPar1; - if( !hConv ) - { - ////WRITELOG("DdeAdvise:Conversation not found") - pInDDEData->fsStatus &= (~DDE_FACK); - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; - } - - Transaction* pTrans = pTransTable; - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - - // existiert schon ein Link auf Topic/Item/Format-Vektor ? - - ULONG nTransId=GetTransaction(pData,hConv,hszItem,pInDDEData->usFormat); - if( nTransId ) - { - ////WRITELOG("DdeAdvise:Transaction already exists") - pTrans += (USHORT)nTransId; - // ist es eine AdviseLoop ? - USHORT nTempType = pTrans->nType; - nTempType &= (~XTYPF_MASK); - if( nTempType == XTYP_ADVREQ ) - { - // Flags der laufenden Advise-Loop aktualisieren - ////WRITELOG("DdeAdvise:Adjusting Advise-Params") - pTrans->nType = XTYP_ADVREQ; - if( pInDDEData->fsStatus & DDE_FNODATA ) - pTrans->nType |= XTYPF_NODATA; - if( pInDDEData->fsStatus & DDE_FACKREQ ) - pTrans->nType |= XTYPF_ACKREQ; - pInDDEData->fsStatus |= DDE_FACK; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; - } - else if( nTempType != XTYP_ADVSTART ) - { - ////WRITELOG("DdeAdvise:Not a advise transaction") - pInDDEData->fsStatus &= (~DDE_FACK); - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; - } - } - - if( !nTransId ) - { - ////WRITELOG("DdeAdvise:Creating Transaction") - ////WRITESTATUS("DdeAdvise:Creating Transaction") - nTransId = CreateTransaction( pData, hConv, hszItem, - pInDDEData->usFormat, XTYP_ADVREQ ); - ////WRITESTATUS("DdeAdvise:Created Transaction") - } - if( nTransId ) - { - pTrans = pTransTable; - pTrans += (USHORT)nTransId; - if( pInDDEData->fsStatus & DDE_FNODATA ) - pTrans->nType |= XTYPF_NODATA; - if( pInDDEData->fsStatus & DDE_FACKREQ ) - pTrans->nType |= XTYPF_ACKREQ; - } - else - { - ////WRITELOG("DdeAdvise:Cannot create Transaction") - pInDDEData->fsStatus &= (~DDE_FACK); - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; - } - - ////WRITELOG("DdeAdvise:Calling Server") - - if ( Callback( XTYP_ADVSTART, pInDDEData->usFormat, - hConv, pConv->hszTopic, hszItem, (HDDEDATA)0, 0, 0 ) ) - { - // - // ServerApp erlaubt AdviseLoop - // - ////WRITELOG("DdeAdvise:Advise loop established") - pInDDEData->fsStatus |= DDE_FACK; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - else - { - ////WRITELOG("DdeAdvise:Advise loop not established") - FreeTransaction( pData, nTransId ); - pInDDEData->fsStatus &= (~DDE_FACK); // DDE_FNOTPROCESSED; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - ////WRITESTATUS("DdeAdvise:End") - ////WRITELOG("DdeAdvise:End") - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; -} - -MRESULT ImpDdeMgr::DdeData( ImpWndProcParams* pParams ) -{ - WRITELOG("DdeData:Received") - HSZ hszItem; - HCONV hConv = CheckIncoming(pParams, 0, hszItem); - HWND hWndThis = pParams->hWndReceiver; - HWND hWndClient = (HWND)pParams->nPar1; - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); -#if 0 && defined( OV_DEBUG ) - { - String aStr("DdeData Address:"); - aStr += (ULONG)pInDDEData; - WRITELOG((char*)aStr.GetStr()) - } -#endif - - BOOL bSendAck; - if( pInDDEData && (pInDDEData->fsStatus & DDE_FACKREQ )) - { - WRITELOG("DdeData: Ackn requested") - bSendAck = TRUE; - } - else - { - WRITELOG("DdeData: Ackn not requested") - bSendAck = FALSE; - } - - ULONG nTransId = GetTransaction(pData,hConv,hszItem,pInDDEData->usFormat); - if( !nTransId ) - { - WRITELOG("DdeData:Transaction not found") - WRITEDATA(pInDDEData) - if( bSendAck ) - { - WRITELOG("DdeData: Posting Ackn") - pInDDEData->fsStatus &= (~DDE_FACK); // NOTPROCESSED; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - else - { - MyDosFreeMem( pInDDEData,"DdeData" ); - } - return (MRESULT)0; - } - -#if 0 && defined( OV_DEBUG ) - if( pInDDEData ) - { - WRITEDATA(pInDDEData) - } -#endif - - BOOL bThisIsSync = (BOOL)( bInSyncTrans && nTransId == nSyncTransId ); - - // pruefen, ob die Transaktion abgeschlossen ist. - Transaction* pTrans = pTransTable; - pTrans += (USHORT)nTransId; - - if( pTrans->nConvst == XST_WAITING_ACK ) - { - // dieser Fall kann eintreten, wenn ein Server innerhalb - // einer WM_DDE_ADVISE-Msg. oder bevor beim Client das - // Ack eintrifft, Advise-Daten sendet. - WRITELOG("DdeData:Ignoring unexpected data") - if( bSendAck ) - { - WRITELOG("DdeData: Posting Ackn") - pInDDEData->fsStatus &= (~DDE_FACK); // NOTPROCESSED; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - else - { - MyDosFreeMem( pInDDEData,"DdeData" ); - } - return (MRESULT)0; - } - - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - - USHORT nType = pTrans->nType; - nType &= (~XTYPF_MASK); - BOOL bNotAdviseLoop = (BOOL)(nType != (XTYP_ADVREQ & (~XTYPF_NOBLOCK))); - if( !bThisIsSync ) - { - // WRITELOG("DdeData:Is async transaction") - if( bNotAdviseLoop ) - { - // WRITELOG("DdeData:Transaction completed -> calling client") - Callback( XTYP_XACT_COMPLETE, pInDDEData->usFormat, hConv, - pConv->hszTopic, hszItem, pInDDEData, nTransId, 0 ); - // WRITELOG("DdeData:Freeing transaction") - FreeTransaction( pData, nTransId ); - } - else - { - WRITELOG("DdeData:Advise-Loop -> calling client") - HDDEDATA pToSend = pInDDEData; - if( pTrans->nType & XTYPF_NODATA ) - { - pToSend = 0; - // WRITELOG("DdeData:Is warm link") - } - Callback( XTYP_ADVDATA, pInDDEData->usFormat, hConv, - pConv->hszTopic, hszItem, pToSend, nTransId, 0 ); - } - if( bSendAck ) - { - WRITELOG("DdeData: Posting Ackn") - pInDDEData->fsStatus = DDE_FACK; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - else - MyDosFreeMem( pInDDEData,"DdeData" ); - } - else // synchrone Transaktion (Datenhandle nicht freigeben!) - { - // WRITELOG("DdeData:Is sync transaction") - hSyncResponseData = pInDDEData; - nSyncResponseMsg = WM_DDE_DATA; - if( bSendAck ) - { - pInDDEData->fsStatus |= DDE_FACK; - WRITELOG("DdeData: Posting Ackn") - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData, - DDEPM_RETRY | DDEPM_NOFREE ); - } - } - - DdeFreeStringHandle( hszItem ); - // WRITELOG("DdeData:End") - return (MRESULT)0; -} - -MRESULT ImpDdeMgr::DdeExecute( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeExecute:Received") - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - HSZ hszItem; - HCONV hConv = CheckIncoming(pParams, 0, hszItem); - BOOL bSuccess = FALSE; - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - if ( hConv && !(nTransactFilter & CBF_FAIL_EXECUTES) && pInDDEData ) - { - if ( Callback( XTYP_EXECUTE, pInDDEData->usFormat, hConv, - pConv->hszTopic, hszItem, pInDDEData, 0, 0 ) - == (DDESTRUCT*)DDE_FACK ) - bSuccess = TRUE; - } - else - { - ////WRITELOG("DdeExecute:Not processed") - } - if( pInDDEData ) - { - if( bSuccess ) - pInDDEData->fsStatus |= DDE_FACK; - else - pInDDEData->fsStatus &= (~DDE_FACK); - MyWinDdePostMsg( pConv->hWndPartner, pConv->hWndThis, WM_DDE_ACK, - pInDDEData, DDEPM_RETRY ); - } - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; -} - -HCONV ImpDdeMgr::ConnectWithClient( HWND hWndClient, - HSZ hszPartner, HSZ hszService, HSZ hszTopic, BOOL bSameInst, - DDEINIT* pDDEData, CONVCONTEXT* pCC ) -{ - ////WRITELOG("ConnectWithClient:Start") - HWND hWndSrv = CreateConversationWnd(); - IncConversationWndRefCount( hWndSrv ); - HCONV hConv = CreateConvHandle( pData, pidThis, hWndSrv, hWndClient, - hszPartner, hszService, hszTopic ); - if(!hConv ) - return 0; - BOOL bFreeDdeData = FALSE; - if( !pDDEData ) - { - bFreeDdeData = TRUE; - pDDEData = CreateDDEInitData( hWndClient,hszService,hszTopic, pCC ); - PID pid; TID tid; - WinQueryWindowProcess( hWndClient, &pid, &tid ); - DosGiveSharedMem( pDDEData, pid, PAG_READ | PAG_WRITE); - } - HAB hAB = WinQueryAnchorBlock( hWndSrv ); - WinGetLastError( hAB ); // fehlercode zuruecksetzen - WinSendMsg(hWndClient,WM_DDE_INITIATEACK,(MPARAM)hWndSrv,(MPARAM)pDDEData); - if( WinGetLastError( hAB ) ) - { - // ////WRITELOG("DdeConnectWithClient:Client died") - if( bFreeDdeData ) - { - MyDosFreeMem( pDDEData,"ConnectWithClient" ); - } - FreeConvHandle( pData, hConv ); - return (HCONV)0; - } - - if( !(nTransactFilter & CBF_SKIP_CONNECT_CONFIRMS) ) - { - Callback( XTYP_CONNECT_CONFIRM, 0, hConv, hszTopic, hszService, - 0, 0, (ULONG)bSameInst ); - } - - if( bFreeDdeData ) - { - MyDosFreeMem( pDDEData,"ConnectWithClient" ); - } - // HCONV der PartnerApp suchen & bei uns eintragen - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - pConv->hConvPartner = GetConvHandle( pData, hWndClient, hWndSrv ); -#if 0 && defined(OV_DEBUG) - if( !pConv->hConvPartner ) - { - WRITELOG("DdeConnectWithClient:Partner not found") - } -#endif - pConv->nStatus = ST_CONNECTED; - //WRITESTATUS("Server:Connected with client") - //WRITELOG("ConnectWithClient:End") - return hConv; -} - -MRESULT ImpDdeMgr::DdeInitiate( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeInitiate:Received") - HWND hWndClient = (HWND)(pParams->nPar1); -// BOOL bSameInst = IsSameInstance( hWndClient ); - BOOL bSameInst = (BOOL)(hWndClient==hWndServer); - DDEINIT* pDDEData = (DDEINIT*)pParams->nPar2; - - if ( ( nTransactFilter & (CBF_FAIL_CONNECTIONS | APPCMD_CLIENTONLY)) || - (( nTransactFilter & CBF_FAIL_SELFCONNECTIONS) && bSameInst ) - ) - { - MyDosFreeMem( pDDEData,"DdeInitiate" ); - return (MRESULT)FALSE; // narda - } - - HSZ hszService = (HSZ)0; - if( *(pDDEData->pszAppName) != '\0' ) - { - hszService = DdeCreateStringHandle( pDDEData->pszAppName, 850 ); - ////WRITELOG(pDDEData->pszAppName); - } - HSZ hszTopic = (HSZ)0; - if( *(pDDEData->pszTopic) != '\0' ) - { - hszTopic = DdeCreateStringHandle( pDDEData->pszTopic, 850 ); - ////WRITELOG(pDDEData->pszTopic); - } - HSZ hszPartner = GetAppName( hWndClient ); - - // nur weitermachen, wenn Service registriert oder - // Service-Name-Filtering ausgeschaltet. - if( !bServFilterOn || GetService(hszService) ) - { - // XTYP_CONNECT-Transaktionen erfolgen nur mit - // Services & Topics ungleich 0! - if( hszService && hszTopic ) - { - if( IsConvHandleAvailable(pData) && Callback( XTYP_CONNECT, - 0, 0, hszTopic,hszService, 0, 0, (ULONG)bSameInst)) - { - // App erlaubt Verbindung mit Client - ConnectWithClient( hWndClient, hszPartner, - hszService, hszTopic, bSameInst, pDDEData ); - } - } - else - { - // ** Wildcard-Connect ** - ////WRITELOG("DdeInitiate:Wildconnect") - // vom Server eine Liste aller Service/Topic-Paare anfordern - CONVCONTEXT* pCC=(CONVCONTEXT*)(pDDEData+pDDEData->offConvContext); - DDESTRUCT* hList = Callback( XTYP_WILDCONNECT, 0, (HCONV)0, - hszTopic,hszService, (HDDEDATA)0, (ULONG)pCC, (ULONG)bSameInst ); - if( hList ) - { - HSZPAIR* pPairs = (HSZPAIR*)((char*)hList+hList->offabData); - while( pPairs->hszSvc ) - { - ////WRITELOG("DdeInitiate:Wildconnect.Connecting") - ConnectWithClient( hWndClient, hszPartner, - pPairs->hszSvc, pPairs->hszTopic, bSameInst, 0, pCC); - // Stringhandles gehoeren der App! (nicht free-en) - pPairs++; - } - DdeFreeDataHandle( hList ); - } - } - } -#if 0 && defined(OV_DEBUG) - else - { - WRITELOG("DdeInitiate:Service filtered") - } -#endif - DdeFreeStringHandle( hszTopic ); - DdeFreeStringHandle( hszService ); - DdeFreeStringHandle( hszPartner ); - MyDosFreeMem( pDDEData,"DdeInitiate" ); - ////WRITELOG("DdeInitiate:End") - return (MRESULT)TRUE; -} - -MRESULT ImpDdeMgr::DdeInitiateAck( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeInitiateAck:Received") - DDEINIT* pDDEData = (DDEINIT*)(pParams->nPar2); - - if( !bListConnect && hCurConv ) - { - ////WRITELOG("DdeInitiateAck:Already connected") - MyDosFreeMem( pDDEData,"DdeInitiateAck" ); - WinPostMsg( hWndServer, WM_DDE_TERMINATE, (MPARAM)hWndServer, 0 ); - return (MRESULT)FALSE; - } - - HWND hWndThis = pParams->hWndReceiver; - // Referenz-Count unseres Client-Windows inkrementieren - IncConversationWndRefCount( hWndThis ); - - HWND hWndSrv = (HWND)(pParams->nPar1); - HSZ hszService = DdeCreateStringHandle( pDDEData->pszAppName, 850 ); - HSZ hszTopic = DdeCreateStringHandle( pDDEData->pszTopic, 850 ); - HSZ hszPartnerApp = GetAppName( hWndSrv ); - - hCurConv = CreateConvHandle( pData, pidThis, hWndThis, hWndSrv, - hszPartnerApp, hszService, hszTopic, 0 ); - - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hCurConv; - - // HCONV der PartnerApp suchen & bei uns eintragen - pConv->hConvPartner = GetConvHandle( pData, hWndSrv, hWndThis ); - // nicht asserten, da ja non-ddeml-Partner moeglich - // DBG_ASSERT(pConv->hConvPartner,"DDE:Partner not found"); - pConv->nStatus = ST_CONNECTED | ST_CLIENT; - - if( bListConnect ) - { - ////WRITELOG("DdeInitiateAck:ListConnect/Connecting hConvs") - // Status setzen & verketten - pConv->hConvList = hCurListId; - pConv->nPrevHCONV = nPrevConv; - pConv->nStatus |= ST_INLIST; - if( nPrevConv ) - { - pConv = pConvTable; - pConv += nPrevConv; - pConv->nNextHCONV = (USHORT)hCurConv; - } - nPrevConv = (USHORT)hCurConv; - } - - DdeFreeStringHandle( hszService ); - DdeFreeStringHandle( hszTopic ); - DdeFreeStringHandle( hszPartnerApp ); - MyDosFreeMem( pDDEData,"DdeInitiateAck" ); - ////WRITESTATUS("After DdeInitiateAck") - ////WRITELOG("DdeInitiateAck:End") - return (MRESULT)TRUE; -} - -MRESULT ImpDdeMgr::DdePoke( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdePoke:Received") - HSZ hszItem = 0; - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - HCONV hConv = CheckIncoming( pParams, CBF_FAIL_REQUESTS, hszItem ); - BOOL bSuccess =FALSE; - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - if ( hConv && !(nTransactFilter & CBF_FAIL_POKES) && pInDDEData ) - { - if( Callback( XTYP_POKE, pInDDEData->usFormat, hConv, - pConv->hszTopic, hszItem, pInDDEData, 0, 0 ) - == (DDESTRUCT*)DDE_FACK ) - bSuccess = TRUE; - } -#if 0 && defined( OV_DEBUG ) - else - { - WRITELOG("DdePoke:Not processed") - } -#endif - if( pInDDEData ) - { - if( bSuccess ) - pInDDEData->fsStatus |= DDE_FACK; - else - pInDDEData->fsStatus &= (~DDE_FACK); - - MyWinDdePostMsg( pConv->hWndPartner, pConv->hWndThis, WM_DDE_ACK, - pInDDEData, DDEPM_RETRY ); - } - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; -} - -MRESULT ImpDdeMgr::DdeRequest( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeRequest:Received") - HSZ hszItem = 0; - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - if( pInDDEData ) - // ist fuer Requests nicht definiert - pInDDEData->fsStatus = 0; - HCONV hConv = CheckIncoming( pParams, CBF_FAIL_REQUESTS, hszItem ); - HWND hWndThis = pParams->hWndReceiver; - HWND hWndClient = (HWND)pParams->nPar1; - if( hConv ) - { - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - - DDESTRUCT* pOutDDEData = Callback( XTYP_REQUEST, pInDDEData->usFormat, - hConv, pConv->hszTopic, hszItem, (HDDEDATA)0, 0, 0 ); - - if ( !pOutDDEData ) - { - ////WRITELOG("DdeRequest:Not processed") - pInDDEData->fsStatus &= (~DDE_FACK); - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - else - { - ////WRITELOG("DdeRequest:Success") - MyDosFreeMem( pInDDEData,"DdeRequest" ); - pOutDDEData->fsStatus |= DDE_FRESPONSE; - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_DATA,pOutDDEData,DDEPM_RETRY); - } - } - else - { - pInDDEData->fsStatus &= (~DDE_FACK); - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - } - - DdeFreeStringHandle( hszItem ); - ////WRITELOG("DdeRequest:End") - return (MRESULT)0; -} - - -MRESULT ImpDdeMgr::DdeUnadvise( ImpWndProcParams* pParams ) -{ - ////WRITELOG("DdeUnadvise:Received") - - HSZ hszItem; - HCONV hConv = CheckIncoming( pParams, 0, hszItem ); - DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); - HWND hWndThis = pParams->hWndReceiver; - HWND hWndClient = (HWND)pParams->nPar1; - USHORT nClosedTransactions = 0; - if( hConv ) - { - USHORT nFormat = pInDDEData->usFormat; - // alle Transaktionen des HCONVs loeschen ? - if( !hszItem ) - { - // App benachrichtigen & Transaktionen loeschen - nClosedTransactions = SendUnadvises( hConv, nFormat, TRUE ); - } - else - { - ULONG nTransId = GetTransaction(pData, hConv, hszItem, nFormat); - if( nTransId ) - { - ////WRITELOG("DdeUnadvise:Transaction found") - Transaction* pTrans = pTransTable; - pTrans += (USHORT)nTransId; - ImpHCONV* pConv = pConvTable; - pConv += (USHORT)hConv; - nClosedTransactions = 1; - if( !(nTransactFilter & CBF_FAIL_ADVISES) ) - Callback( XTYP_ADVSTOP, nFormat, hConv, - pConv->hszTopic, hszItem, 0, 0, 0 ); - if( !pConv->hConvPartner ) - FreeTransaction( pData, nTransId ); - } -#if defined(OV_DEBUG) - else - { - WRITELOG("DdeUnadvise:Transaction not found") - } -#endif - } - } -#if defined(OV_DEBUG) - else - { - WRITELOG("DdeUnadvise:Conversation not found") - } -#endif - - if( !nClosedTransactions ) - pInDDEData->fsStatus &= (~DDE_FACK); - else - pInDDEData->fsStatus |= DDE_FACK; - - MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); - DdeFreeStringHandle( hszItem ); - return (MRESULT)0; -} - -BOOL ImpDdeMgr::WaitTransState( Transaction* pTrans, ULONG nTransId, - USHORT nNewState, ULONG nTimeout ) -{ - ////WRITELOG("WaitTransState:Start") - ImpHCONV* pConv = pConvTable; - pConv += pTrans->hConvOwner; - HAB hAB = WinQueryAnchorBlock( pConv->hWndThis ); - ULONG nTimerId = WinStartTimer( hAB, 0, 0, 50 ); - QMSG aQueueMsg; - -// while( WinGetMsg( hAB, &aQueueMsg, 0, 0, 0 ) && -// WinIsWindow( hAB, pConv->hWndPartner) && -// pTrans->nConvst != nNewState ) -// { -// WinDispatchMsg( hAB, &aQueueMsg ); -// } - - BOOL bContinue = TRUE; - while( bContinue ) - { - if( WinGetMsg( hAB, &aQueueMsg, 0, 0, 0 )) - { - WinDispatchMsg( hAB, &aQueueMsg ); - if( (!WinIsWindow( hAB, pConv->hWndPartner)) || - (pTrans->nConvst == nNewState) ) - { - bContinue = FALSE; - } - } - else - bContinue = FALSE; - } - - WinStopTimer( hAB, 0, nTimerId ); - ////WRITELOG("WaitTransState:End") - return TRUE; -} - - - - |