298 lines
8.3 KiB
C++
298 lines
8.3 KiB
C++
/***************************************************************************
|
||
* 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;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|