twain2/hugaotwainds/DSMInterface.cpp

298 lines
8.3 KiB
C++
Raw Blame History

/***************************************************************************
* Copyright <20> 2007 TWAIN Working Group:
* Adobe Systems Incorporated, AnyDoc Software Inc., Eastman Kodak Company,
* Fujitsu Computer Products of America, JFL Peripheral Solutions Inc.,
* Ricoh Corporation, and Xerox Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the TWAIN Working Group nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TWAIN Working Group ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL TWAIN Working Group BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************/
/**
* @file DSMInterface.cpp
* Common defines and typedefs used for accessing DSM for Twain Data Sources.
* @author TWAIN Working Group
* @date April 2007
*/
#include "stdafx.h"
#include "DSMInterface.h"
#include <iostream>
using namespace std;
/**
* gloabal pointer to the Data Source Manager
*/
HMODULE gpDSM = 0;
/**
* gloabal pointer to the Data Source Manager's Entry point
* - cleared & init'd in @see LoadDSMLib
*/
TW_ENTRYPOINT g_DSM_Entry =
{
0,// TW_UINT32 Size;
0,// DSMENTRYPROC DSM_Entry;
0,// DSM_MEMALLOCATE DSM_MemAllocate;
0,// DSM_MEMFREE DSM_MemFree;
0,// DSM_MEMLOCK DSM_MemLock;
0 // DSM_MEMUNLOCK DSM_MemUnlock;
};
#ifdef TWH_CMP_GNU
#include <dlfcn.h>
#endif
#ifdef TWNDS_OS_APPLE
// #include "CarbonCore/MacMemory.h"
#include <Carbon/Carbon.h>
#endif
/**
* This is the same as the main DS_Entry function. Routes traffic
* to the proper location.
* @param[in] _pOrigin Identifies the source DS for the message.
* @param[in] _pDest Identifies the destination application for the message.
* @param[in] _DG The Data Group.
* @param[in] _DAT The Data Attribute Type.
* @param[in] _MSG The message with respect to the Data Group and the Data Attribute Type.
* @param[in,out] _pData A pointer to the data structure or variable identified
* by the Data Attribute Type.
* @return a valid TWRC_xxxx return code.
*/
TW_UINT16 _DSM_Entry( pTW_IDENTITY _pOrigin,
pTW_IDENTITY _pDest,
TW_UINT32 _DG,
TW_UINT16 _DAT,
TW_UINT16 _MSG,
TW_MEMREF _pData)
{
TW_UINT16 ret = TWRC_FAILURE;
// With DSM2 we do not need to load the DSM. We should have recieved
// Message with the entry points that we use.
// On windows with DSM1(twain_32.dll) we will need to first laod the dll
// then find the entry point First check to see if you have an entry point.
// On Mac we will use the dynamicaly linked at build time dll.
if(0 == g_DSM_Entry.DSM_Entry)
{
// We do not already have the entry point for regisry callback
#ifdef TWNDS_OS_APPLE
// This should only happen if not being called by the DSM2
// Other words only on Mac with an older DSM
// So we use the old dll
g_DSM_Entry.DSM_Entry = DSM_Entry;
// ret = DSM_Entry(_pOrigin, _pDest, _DG, _DAT, _MSG, _pData);
#elif defined (TWH_CMP_MSC)
// This should only happen if not being called by the DSM2
// Other words only on Windows with an older DSM
// So we load the old dll
char DSMName[MAX_PATH];
memset(DSMName, 0, MAX_PATH*sizeof(char));
if(GetWindowsDirectory (DSMName, MAX_PATH)==0)
{
DSMName[0]=0;
}
#if (TWNDS_CMP_VERSION >= 1400)
if (DSMName[strlen(DSMName)-1] != '\\')
{
strcat_s(DSMName,MAX_PATH, "\\");
}
strcat_s (DSMName,MAX_PATH, "TWAIN_32.dll");
#else
if (DSMName[strlen(DSMName)-1] != '\\')
{
strcat(DSMName, "\\");
}
strcat(DSMName, "TWAIN_32.dll");
#endif
if((0 == gpDSM) && !LoadDSMLib(DSMName))
{
cerr << "Could not load the DSM" << endl;
return TWRC_FAILURE;
}
#endif // TWNDS_OS_APPLE & TWH_CMP_MSC
}
if(0 == g_DSM_Entry.DSM_Entry)
{
cerr << "No Entry Point for DSM_Entry" << endl;
return TWRC_FAILURE;
}
// If we did not have an enty point before we do now.
ret = g_DSM_Entry.DSM_Entry(_pOrigin, _pDest, _DG, _DAT, _MSG, _pData);
return ret;
}
/////////////////////////////////////////////////////////////////////////////
bool LoadDSMLib(char* _pszLibName)
{
// check if already opened
if(0 != gpDSM)
{
return true;
}
memset(&g_DSM_Entry, 0, sizeof(TW_ENTRYPOINT));
#ifdef TWH_CMP_GNU
char *error;
#endif //TWH_CMP_GNU
if((gpDSM=LOADLIBRARY(_pszLibName)) != 0)
{
if((g_DSM_Entry.DSM_Entry=(DSMENTRYPROC)LOADFUNCTION(gpDSM, "DSM_Entry")) == 0)
{
#ifdef TWH_CMP_MSC // dlsym returning NULL is not an error on Unix
cerr << "Error - Could not find DSM_Entry function in DSM: " << _pszLibName << endl;
return false;
#endif //TWH_CMP_MSC
}
#ifdef TWH_CMP_GNU
if ((error = dlerror()) != 0)
{
cerr << "App - dlsym: " << error << endl;
return false;
}
#endif //TWH_CMP_GNU
}
else
{
cerr << "Error - Could not load DSM: " << _pszLibName << endl;
#ifdef TWH_CMP_GNU
cerr << "App - dlopen: " << dlerror() << endl;
#endif //TWH_CMP_GNU
return false;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
void unLoadDSMLib()
{
if(gpDSM)
{
memset(&g_DSM_Entry, 0, sizeof(TW_ENTRYPOINT));
UNLOADLIBRARY(gpDSM);
gpDSM = 0;
}
}
/////////////////////////////////////////////////////////////////////////////
void setEntryPoints(pTW_ENTRYPOINT _pEntryPoints)
{
if(_pEntryPoints)
{
g_DSM_Entry = *_pEntryPoints;
}
else
{
memset(&g_DSM_Entry, 0, sizeof(TW_ENTRYPOINT));
}
}
//////////////////////////////////////////////////////////////////////////////
// The following functions are defined in the DSM2,
// For backwards compatibiltiy on windows call the default function
TW_HANDLE _DSM_Alloc(TW_UINT32 _size)
{
if(g_DSM_Entry.DSM_MemAllocate)
{
return g_DSM_Entry.DSM_MemAllocate(_size);
}
#ifdef TWH_CMP_MSC
return ::GlobalAlloc(GPTR, _size);
#elif defined (TWNDS_OS_APPLE)
return NewHandle(_size);
#endif
return 0;
}
//////////////////////////////////////////////////////////////////////////////
void _DSM_Free(TW_HANDLE _hMemory)
{
if(g_DSM_Entry.DSM_MemFree)
{
return g_DSM_Entry.DSM_MemFree(_hMemory);
}
#ifdef TWH_CMP_MSC
::GlobalFree(_hMemory);
#elif defined (TWNDS_OS_APPLE)
DisposeHandle(_hMemory);
#endif
return;
}
//////////////////////////////////////////////////////////////////////////////
TW_MEMREF _DSM_LockMemory(TW_HANDLE _hMemory)
{
if(g_DSM_Entry.DSM_MemLock)
{
return g_DSM_Entry.DSM_MemLock(_hMemory);
}
#ifdef TWH_CMP_MSC
return (TW_MEMREF)::GlobalLock(_hMemory);
#elif defined (TWNDS_OS_APPLE)
return (TW_MEMREF)(*_hMemory);
#endif
return 0;
}
//////////////////////////////////////////////////////////////////////////////
void _DSM_UnlockMemory(TW_HANDLE _hMemory)
{
if(g_DSM_Entry.DSM_MemUnlock)
{
return g_DSM_Entry.DSM_MemUnlock(_hMemory);
}
#ifdef TWH_CMP_MSC
::GlobalUnlock(_hMemory);
#elif defined (TWNDS_OS_APPLE)
// do nothing
#endif
return;
}
//////////////////////////////////////////////////////////////////////////////