Go to the documentation of this file.
54 #define TWNDSM_CMP_VISUALCPP 0x1001
55 #define TWNDSM_CMP_GNUGPP 0x1002
62 #define TWNDSM_OS_WINDOWS 0x2001
63 #define TWNDSM_OS_MACOSX 0x2002
64 #define TWNDSM_OS_LINUX 0x2003
98 #define TWNDSM_CMP TWNDSM_CMP_GNUGPP
99 #define TWNDSM_CMP_VERSION __GNUC__
100 #if defined(__APPLE__)
101 #define TWNDSM_OS TWNDSM_OS_MACOSX
103 #define TWNDSM_OS TWNDSM_OS_LINUX
105 #if defined(__x86_64__) || defined(__LP64__)
106 #define TWNDSM_OS_64BIT 1
108 #define TWNDSM_OS_32BIT 1
112 #elif defined(_MSC_VER)
113 #define TWNDSM_CMP TWNDSM_CMP_VISUALCPP
114 #define TWNDSM_CMP_VERSION _MSC_VER
115 #define TWNDSM_OS TWNDSM_OS_WINDOWS
116 #if defined(_M_X64) || defined(_M_IA64)
117 #define TWNDSM_OS_64BIT 1
119 #define TWNDSM_OS_32BIT 1
124 Sorry, we
do not recognize
this system...
133 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP)
134 #ifndef WIN32_LEAN_AND_MEAN
135 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
141 #elif (TWNDSM_CMP == TWNDSM_CMP_GNUGPP)
148 #include <sys/syscall.h>
149 #include <sys/time.h>
150 #define gettid() syscall(SYS_gettid)
153 #error Sorry, we do not recognize this system...
163 #include "resource.h"
173 #include <sys/stat.h>
174 #include <sys/types.h>
254 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP)
257 #define TWID_T TW_UINT32
258 #define TWIDDEST_T TW_UINT32
262 #define LOADLIBRARY(lib,hook,DSID) LoadLibrary(lib)
263 #define UNLOADLIBRARY(hmodule,unhook,DSID) FreeLibrary((HMODULE)hmodule)
268 HMODULE InstallTwain32DllHooks
270 const char*
const _lib,
274 BOOL UninstallTwain32DllHooks
276 const HMODULE _hmodule,
280 #define LOADLIBRARY(lib,hook,DSID) InstallTwain32DllHooks(lib,hook,DSID)
281 #define UNLOADLIBRARY(hmodule,unhook,DSID) UninstallTwain32DllHooks((HMODULE)hmodule,unhook,DSID)
284 #define DllExport __declspec( dllexport )
285 #define NCHARS(s) sizeof(s)/sizeof(s[0])
286 #define PATH_SEPERATOR '\\'
288 #define LOADFUNCTION(lib, func) GetProcAddress((HMODULE)lib, func)
291 #if (TWNDSM_CMP_VERSION >= 1400)
292 #define SNPRINTF _snprintf_s
294 #define SNPRINTF _snprintf
296 #define UNLINK _unlink
297 #define STRNICMP _strnicmp
298 #define DSMENTRY TW_UINT16 FAR PASCAL
299 #define GETTHREADID ::GetCurrentThreadId
300 #define FOPEN(pf, name, mode) pf = _fsopen(name, mode, _SH_DENYNO)
301 #ifndef kTWAIN_DS_DIR
303 #define kTWAIN_DS_DIR "twain_64"
305 #define kTWAIN_DS_DIR "twain_32"
309 #elif (TWNDSM_CMP == TWNDSM_CMP_GNUGPP)
311 #define NCHARS(s) sizeof(s)/sizeof(s[0])
312 #define PATH_SEPERATOR '/'
313 #if (TWNDSM_OS == TWNDSM_OS_MACOSX)
314 #define LOADLIBRARY(lib,hook,DSID) \
315 CFBundleCreate(0, CFURLCreateWithFileSystemPath(0, CFStringCreateWithCStringNoCopy(0, _pPath, kCFStringEncodingUTF8, 0), kCFURLPOSIXPathStyle, TRUE))
316 #define UNLOADLIBRARY(lib,unhook,DSID) 0; CFRelease((CFBundleRef)(lib))
318 #define LOADLIBRARY(lib,hook,DSID) dlopen(lib, RTLD_LAZY)
319 #define UNLOADLIBRARY(lib,unhook,DSID) dlclose(lib)
321 #define LOADFUNCTION(lib, func) dlsym(lib, func)
324 #define SNPRINTF snprintf
325 #define UNLINK unlink
326 #define STRNICMP strncasecmp
327 #define GETTHREADID gettid
328 #define FOPEN(pf,name,mode) pf = fopen(name,mode)
329 #ifndef kTWAIN_DS_DIR
330 #if (TWNDSM_OS == TWNDSM_OS_MACOSX)
331 #define kTWAIN_DS_DIR "/Library/Image Capture/TWAIN Data Sources"
333 #define kTWAIN_DS_DIR "/usr/local/lib/twain"
336 typedef unsigned int UINT;
337 typedef void* HINSTANCE;
339 #define DSMENTRY FAR PASCAL TW_UINT16
341 #if (TWNDSM_OS == TWNDSM_OS_MACOSX)
343 #define TWID_T unsigned long long
344 #define TWIDDEST_T TW_MEMREF
346 #define TWID_T unsigned long
347 #define TWIDDEST_T TW_MEMREF
350 #define TWID_T TW_UINT32
351 #define TWIDDEST_T TW_UINT32
361 #error Sorry, we do not recognize this system...
400 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP) && (TWNDSM_CMP_VERSION >= 1400)
401 #define SSTRCPY(d,z,s) strncpy_s(d,z,s,_TRUNCATE)
402 #define SSTRCAT(d,z,s) strncat_s(d,z,s,_TRUNCATE)
403 #define SSTRNCPY(d,z,s,m) strncpy_s(d,z,s,m)
404 #define SGETENV(d,z,n) ::GetEnvironmentVariable(n,d,z)
405 inline int SSNPRINTF(
char *d,
const size_t z,
const size_t c,
const char*
const f,...)
410 result = _vsnprintf_s(d,z,c,f,valist);
421 #define SSTRCPY(d,z,s) strlcpy(d,s,z)
422 #define SSTRCAT(d,z,s) strcat(d,s)
423 #define SSTRNCPY(d,z,s,m) strncpy(d,s,m)
424 #define SGETENV(d,z,n) strcpy(d,getenv(n)?getenv(n):"")
425 inline int SSNPRINTF(
char *d,
const size_t,
const size_t c,
const char*
const f,...)
430 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP)
431 result = _vsnprintf(d,c,f,valist);
432 #elif (TWNDSM_CMP == TWNDSM_CMP_GNUGPP)
433 result = vsnprintf(d,c,f,valist);
435 #error Sorry, we do not recognize this system...
447 #define SSTRCPY(d,z,s) strcpy(d,s)
448 #define SSTRCAT(d,z,s) strcat(d,s)
449 #define SSTRNCPY(d,z,s,m) strncpy(d,s,m)
450 #define SGETENV(d,z,n) strcpy(d,getenv(n)?getenv(n):"")
451 inline int SSNPRINTF(
char *d,
const size_t,
const size_t c,
const char*
const f,...)
456 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP)
457 result = _vsnprintf(d,c,f,valist);
458 #elif (TWNDSM_CMP == TWNDSM_CMP_GNUGPP)
459 result = vsnprintf(d,c,f,valist);
461 #error Sorry, we do not recognize this system...
485 #define kLOGINFO 0,__FILE__,__LINE__
490 #define kLOGERR 1,__FILE__,__LINE__
496 #define kLOG(a) if (g_ptwndsmlog) g_ptwndsmlog->Log a
507 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP)
508 #define kPANIC(msg) ::MessageBox(NULL,msg,"TWAIN Data Source Manager",MB_OK);
509 #elif (TWNDSM_CMP == TWNDSM_CMP_GNUGPP)
510 #define kPANIC(msg) fprintf(stderr,"TWAIN Data Source Manager: %s\r\n",msg);
512 #error Sorry, we do not recognize this system...
521 #define MAX_NUM_DS 50
575 void Log(
const int _doassert,
576 const char*
const _file,
578 const char*
const _format,
696 TW_UINT16 _conditioncode);
812 TW_BOOL _Processing);
832 TW_BOOL _Processing);
897 #if (TWNDSM_CMP == TWNDSM_CMP_VISUALCPP)
912 #elif (TWNDSM_CMP == TWNDSM_CMP_GNUGPP)
915 #error Sorry, we do not recognize this system...
1130 const TW_UINT32 _DG,
1131 const TW_UINT16 _DAT,
1132 const TW_UINT16 _MSG,
1133 const TW_MEMREF _pData);
1144 const TW_UINT16 _DAT,
1145 const TW_UINT16 _MSG,
1146 const TW_MEMREF _pData,
1147 const TW_UINT16 _RC);
1157 const TW_UINT16 _MSG);
1167 const TW_UINT16 _DAT);
1177 const TW_UINT32 _DG);
1187 const TW_UINT16 _Cap);
1197 const TW_UINT16 _ConType);
1207 const TW_UINT16 _rc);
1217 const TW_UINT16 _cc);
BOOL CALLBACK SelectDlgProc(HWND _hWnd, UINT _Message, WPARAM _wParam, LPARAM _lParam)
Selection dialog, for apps that don't want to do GetFirst GetNext.
void AppSetConditionCode(TW_IDENTITY *_pAppId, TW_UINT16 _conditioncode)
Set the condition code.
Impl Class to hold list of connected applications.
void DsSetProcessingMessage(TW_IDENTITY *_pAppId, TWID_T _DsId, TW_BOOL _Processing)
Set the ProcessingMessage flag.
char * DsGetPath(TW_IDENTITY *_pAppId, TWID_T _DsId)
Get a pointer to the driver file path and name, which is guaranteed to be unique, even if the Product...
TW_UINT16 AddApp(TW_IDENTITY *_pAppId, TW_MEMREF _MemRef)
Add an application.
CTwnDsmAppsImpl * m_ptwndsmappsimpl
The implementation pointer helps with encapulation.
We use a pod system because it help prevents us from making dumb initialization mistakes.
TW_BOOL AppValidateId(TW_IDENTITY *_pAppId)
Validate that an id is in range...
TW_IDENTITY * m_pSelectDlgDsId
The DS ID we end up with from SelectDlgProc.
Our implementation class where we hide our attributes...
TW_INT16 DSM_Parent(TW_IDENTITY *_pAppId, TW_UINT16 _MSG, TW_MEMREF _MemRef)
Initializes or closes the DSM.
TW_IDENTITY * DsGetIdentity(TW_IDENTITY *_pAppId, TWID_T _DsId)
Get a pointer to the identity of the specified driver...
TW_INT16 DSM_Identity(TW_IDENTITY *_pAppId, TW_UINT16 _MSG, TW_IDENTITY *_pDsId)
Source operations.
void * DSM_LoadFunction(void *_pHandle, const char *_pszSymbol)
This function wraps the function loading calls.
void Log(const int _doassert, const char *const _file, const int _line, const char *const _format,...)
The logging function.
TW_INT16 DSM_Status(TW_IDENTITY *_pAppId, TW_UINT16 _MSG, TW_STATUS *_pStatus)
Returns the current DSM status.
bool printTripletsInfo(const TW_IDENTITY *_pOrigin, const TW_IDENTITY *_pDest, const TW_UINT32 _DG, const TW_UINT16 _DAT, const TW_UINT16 _MSG, const TW_MEMREF _pData)
prints to stdout information about the triplets.
TWID_T m_nextDsId
The next id to test for GetFirst/GetNext...
void DsCallbackSetWaiting(TW_IDENTITY *_pAppId, TWID_T _DsId, TW_BOOL _Waiting)
Set the callback flag for the driver to TRUE if the callback needs to have its callback called,...
char m_DefaultDSPath[FILENAME_MAX]
The path to the default DS.
CTwnDsmLog * g_ptwndsmlog
The logging object, only access through macros.
TW_UINT16 RemoveApp(TW_IDENTITY *_pAppId)
Remove an application.
void StringFromDg(char *_szDg, const int _nChars, const TW_UINT32 _DG)
Translates the _DG passed in into a string and returns it.
TW_IDENTITY * m_pSelectDlgAppId
The Application ID we're using inside of SelectDlgProc.
void StringFromConditionCode(char *_szCondCode, const int _nChars, const TW_UINT16 _cc)
Translates the Condition Code passed in into a string and returns it.
@ dsmState_PreSession
Source Manager not loaded.
TW_BOOL DsCallbackIsWaiting(TW_IDENTITY *_pAppId, TWID_T _DsId)
Test if the driver has a callback pending for attention...
~CTwnDsm()
Our CTwnDsm destructor...
TW_INT16 DSM_Callback2(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId, TW_UINT16 _MSG, TW_CALLBACK2 *_pData)
Register application's callback.
TW_INT16 DSM_SetDefaultDS(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Set the default source.
CTwnDsm()
Our CTwnDsm constructor...
TW_BOOL DsIsProcessingMessage(TW_IDENTITY *_pAppId, TWID_T _DsId)
Check if the DS is still processing last message.
TW_BOOL AppValidateIds(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDSId)
Validate that the App ID and DS ID are in range...
TW_UINT16 AppGetConditionCode(TW_IDENTITY *_pAppId)
Get the condition code, then reset it internally to TWCC_SUCCESS, so you can only get it once,...
TW_BOOL DsIsAppProcessingCallback(TW_IDENTITY *_pAppId, TWID_T _DsId)
Check if the App is still processing last callback.
TW_INT16 DSM_Entrypoint(TW_IDENTITY *_pAppId, TW_UINT16 _MSG, TW_ENTRYPOINT *_pEntrypoint)
Gets entry points.
TW_INT16 LoadDS(TW_IDENTITY *_pAppId, TWID_T _DsId)
Loads a DS from disk and adds it to a global list of DS's.
void printResults(const TW_UINT32 _DG, const TW_UINT16 _DAT, const TW_UINT16 _MSG, const TW_MEMREF _pData, const TW_UINT16 _RC)
prints to stdout information about result of processing the triplets.
void StringFromRC(char *_szRc, const int _nChars, const TW_UINT16 _rc)
Translates the rc passed in into a string and returns it.
CTwnDsmLog()
The CTwnDsmLog constructor.
TW_INT16 DSM_Null(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId, TW_UINT16 _MSG)
Handles DAT_NULL calls from DS for Application.
@ dsmState_Open
Source Manager is open.
TW_INT16 GetIdentity(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Return back the tw_identity of the current source.
~CTwnDsmLog()
The CTwnDsmLog destructor.
TWID_T AppGetNumDs(TW_IDENTITY *_pAppId)
Get the number of drivers we found as the result of a successful call to LoadDS with _boolKeepOpen se...
TW_INT16 DSM_GetFirst(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Copies the applications first available source into _pDsId.
TW_INT16 OpenDS(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Opens the Data Source specified by pDSIdentity.
DSENTRYPROC DsGetEntryProc(TW_IDENTITY *_pAppId, TWID_T _DsId)
Get a pointer to the DS_Entry function of the specified driver...
TW_CALLBACK2 * DsCallback2Get(TW_IDENTITY *_pAppId, TWID_T _DsId)
Get a pointer to TW_CALLBACK structure for the specified driver...
void StringFromMsg(char *_szMsg, const int _nChars, const TW_UINT16 _MSG)
Translates the _MSG passed in into a string and returns it.
~CTwnDsmApps()
The CTwnDsmApps destructor.
TW_INT16 DSM_GetNext(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Copies the applications next available source into _pDsId.
void UnloadDS(TW_IDENTITY *_pAppId, TWID_T _DsId)
Unloads a DS and frees all its resources...
void DsSetAppProcessingCallback(TW_IDENTITY *_pAppId, TWID_T _DsId, TW_BOOL _Processing)
Set the AppProcessingCallback flag.
TW_INT16 CloseDS(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Closes the Data Source specified by pDSIdentity.
TW_INT16 DSM_Callback(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId, TW_UINT16 _MSG, TW_CALLBACK *_pData)
Register application's callback.
DSM_State DSMGetState()
Get the state of the DSM by checking the state of all applications.
void * AppHwnd(TW_IDENTITY *_pAppId)
Get the hwnd sent in with the call to MSG_OPENDSM.
TW_INT16 GetMatchingDefault(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
This routine will check if the current default source matches the applications supported groups.
void StringFromConType(char *_szConType, const int _nChars, const TW_UINT16 _ConType)
Translates the _ConType and _hContainer passed in into a string and returns it.
TW_UINT16 DSM_Entry(TW_IDENTITY *_pOrigin, TW_IDENTITY *_pDest, TW_UINT32 _DG, TW_UINT16 _DAT, TW_UINT16 _MSG, TW_MEMREF _pData)
The guts of the DSM_Entry, the resource management portion resides in a our DSM_Entry entry point,...
TWID_T AppGetNumApp()
Get number of allocated App slots (Last valid App ID +1)
void AppWakeup(TW_IDENTITY *_pAppId)
Poke the application to wake it up when sending a DAT_NULL message to it...
CTwnDsmApps * m_ptwndsmapps
The class takes care of our list of applications and drivers.
void Indent(int nChange)
Indent the logging to help with seeing recursive calls param[in] nChange Either +1 or -1.
DSM_State AppGetState()
Get the state of the DSM for all applications.
CTwnDsmLogImpl * m_ptwndsmlogimpl
The implementation pointer helps with encapulation.
TW_INT16 GetDSFromProductName(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Goes through the applications supported data sources looking for one that has the exact same name as ...
void StringFromDat(char *_szDat, const int _nChars, const TW_UINT16 _DAT)
Translates the _DAT passed in into a string and returns it.
CTwnDsmApps()
The CTwnDsmApps constructor.
TW_INT16 DSM_SelectDS(TW_IDENTITY *_pAppId, TW_IDENTITY *_pDsId)
Displays the source select dialog and sets the default source.
void StringFromCap(char *_szCap, const int _nChars, const TW_UINT16 _Cap)
Translates the _Cap passed in into a string and returns it.
DSM_State
Possible States of the DSM.
TW_INT16 DSM_TwunkIdentity(TW_IDENTITY *_pAppId, TW_UINT16 _MSG, TW_TWUNKIDENTITY *_pTwunkId)
This routine will return the path to a DS.
This is the main class for the Data Source Manager.
@ dsmState_Loaded
Source Manager is loaded, but not open.
struct CTwnDsm::_pod pod
Pieces of Data for the DSM class.
TW_IDENTITY * AppGetIdentity(TW_IDENTITY *_pAppId)
Return a pointer to the application's identity.
Class to hold list of connected applications.