1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_basic.hxx" 26 #include <tools/errcode.hxx> 27 #include <svl/svdde.hxx> 28 #include "ddectrl.hxx" 29 #ifndef _SBERRORS_HXX 30 #include <basic/sberrors.hxx> 31 #endif 32 33 #define DDE_FREECHANNEL ((DdeConnection*)0xffffffff) 34 35 #define DDE_FIRSTERR 0x4000 36 #define DDE_LASTERR 0x4011 37 38 static const SbError nDdeErrMap[] = 39 { 40 /* DMLERR_ADVACKTIMEOUT */ 0x4000, SbERR_DDE_TIMEOUT, 41 /* DMLERR_BUSY */ 0x4001, SbERR_DDE_BUSY, 42 /* DMLERR_DATAACKTIMEOUT */ 0x4002, SbERR_DDE_TIMEOUT, 43 /* DMLERR_DLL_NOT_INITIALIZED */ 0x4003, SbERR_DDE_ERROR, 44 /* DMLERR_DLL_USAGE */ 0x4004, SbERR_DDE_ERROR, 45 /* DMLERR_EXECACKTIMEOUT */ 0x4005, SbERR_DDE_TIMEOUT, 46 /* DMLERR_INVALIDPARAMETER */ 0x4006, SbERR_DDE_ERROR, 47 /* DMLERR_LOW_MEMORY */ 0x4007, SbERR_DDE_ERROR, 48 /* DMLERR_MEMORY_ERROR */ 0x4008, SbERR_DDE_ERROR, 49 /* DMLERR_NOTPROCESSED */ 0x4009, SbERR_DDE_NOTPROCESSED, 50 /* DMLERR_NO_CONV_ESTABLISHED */ 0x400a, SbERR_DDE_NO_CHANNEL, 51 /* DMLERR_POKEACKTIMEOUT */ 0x400b, SbERR_DDE_TIMEOUT, 52 /* DMLERR_POSTMSG_FAILED */ 0x400c, SbERR_DDE_QUEUE_OVERFLOW, 53 /* DMLERR_REENTRANCY */ 0x400d, SbERR_DDE_ERROR, 54 /* DMLERR_SERVER_DIED */ 0x400e, SbERR_DDE_PARTNER_QUIT, 55 /* DMLERR_SYS_ERROR */ 0x400f, SbERR_DDE_ERROR, 56 /* DMLERR_UNADVACKTIMEOUT */ 0x4010, SbERR_DDE_TIMEOUT, 57 /* DMLERR_UNFOUND_QUEUE_ID */ 0x4011, SbERR_DDE_NO_CHANNEL 58 }; 59 60 SbError SbiDdeControl::GetLastErr( DdeConnection* pConv ) 61 { 62 if( !pConv ) 63 return 0; 64 long nErr = pConv->GetError(); 65 if( !nErr ) 66 return 0; 67 if( nErr < DDE_FIRSTERR || nErr > DDE_LASTERR ) 68 return SbERR_DDE_ERROR; 69 return nDdeErrMap[ 2*(nErr - DDE_FIRSTERR) + 1 ]; 70 } 71 72 IMPL_LINK_INLINE( SbiDdeControl,Data , DdeData*, pData, 73 { 74 aData = String::CreateFromAscii( (char*)(const void*)*pData ); 75 return 1; 76 } 77 ) 78 79 SbiDdeControl::SbiDdeControl() 80 { 81 pConvList = new DdeConnections; 82 DdeConnection* pPtr = DDE_FREECHANNEL; 83 pConvList->Insert( pPtr ); 84 } 85 86 SbiDdeControl::~SbiDdeControl() 87 { 88 TerminateAll(); 89 delete pConvList; 90 } 91 92 sal_Int16 SbiDdeControl::GetFreeChannel() 93 { 94 sal_Int16 nListSize = (sal_Int16)pConvList->Count(); 95 DdeConnection* pPtr = pConvList->First(); 96 pPtr = pConvList->Next(); // nullten eintrag ueberspringen 97 sal_Int16 nChannel; 98 for( nChannel = 1; nChannel < nListSize; nChannel++ ) 99 { 100 if( pPtr == DDE_FREECHANNEL ) 101 return nChannel; 102 pPtr = pConvList->Next(); 103 } 104 pPtr = DDE_FREECHANNEL; 105 pConvList->Insert( pPtr, LIST_APPEND ); 106 return nChannel; 107 } 108 109 SbError SbiDdeControl::Initiate( const String& rService, const String& rTopic, 110 sal_Int16& rnHandle ) 111 { 112 SbError nErr; 113 DdeConnection* pConv = new DdeConnection( rService, rTopic ); 114 nErr = GetLastErr( pConv ); 115 if( nErr ) 116 { 117 delete pConv; 118 rnHandle = 0; 119 } 120 else 121 { 122 sal_Int16 nChannel = GetFreeChannel(); 123 pConvList->Replace( pConv, (sal_uIntPtr)nChannel ); 124 rnHandle = nChannel; 125 } 126 return 0; 127 } 128 129 SbError SbiDdeControl::Terminate( sal_Int16 nChannel ) 130 { 131 DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); 132 if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) 133 return SbERR_DDE_NO_CHANNEL; 134 pConvList->Replace( DDE_FREECHANNEL, (sal_uIntPtr)nChannel ); 135 delete pConv; 136 return 0L; 137 } 138 139 SbError SbiDdeControl::TerminateAll() 140 { 141 sal_Int16 nChannel = (sal_Int16)pConvList->Count(); 142 while( nChannel ) 143 { 144 nChannel--; 145 Terminate( nChannel ); 146 } 147 148 pConvList->Clear(); 149 DdeConnection* pPtr = DDE_FREECHANNEL; 150 pConvList->Insert( pPtr ); 151 152 return 0; 153 } 154 155 SbError SbiDdeControl::Request( sal_Int16 nChannel, const String& rItem, String& rResult ) 156 { 157 DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); 158 if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) 159 return SbERR_DDE_NO_CHANNEL; 160 161 DdeRequest aRequest( *pConv, rItem, 30000 ); 162 aRequest.SetDataHdl( LINK( this, SbiDdeControl, Data ) ); 163 aRequest.Execute(); 164 rResult = aData; 165 return GetLastErr( pConv ); 166 } 167 168 SbError SbiDdeControl::Execute( sal_Int16 nChannel, const String& rCommand ) 169 { 170 DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); 171 if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) 172 return SbERR_DDE_NO_CHANNEL; 173 DdeExecute aRequest( *pConv, rCommand, 30000 ); 174 aRequest.Execute(); 175 return GetLastErr( pConv ); 176 } 177 178 SbError SbiDdeControl::Poke( sal_Int16 nChannel, const String& rItem, const String& rData ) 179 { 180 DdeConnection* pConv = pConvList->GetObject( (sal_uIntPtr)nChannel ); 181 if( !nChannel || !pConv || pConv == DDE_FREECHANNEL ) 182 return SbERR_DDE_NO_CHANNEL; 183 DdePoke aRequest( *pConv, rItem, DdeData(rData), 30000 ); 184 aRequest.Execute(); 185 return GetLastErr( pConv ); 186 } 187 188 189