| /* | |
| * TWAIN32 functions | |
| * | |
| * Copyright 2000 Shi Quan He <shiquan@cyberdude.com> | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library 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 for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| */ | |
| #include "config.h" | |
| #include <stdarg.h> | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "twain.h" | |
| #include "twain_i.h" | |
| #include "wine/debug.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(twain); | |
| BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | |
| { | |
| TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved); | |
| switch (fdwReason) | |
| { | |
| case DLL_PROCESS_ATTACH: | |
| DisableThreadLibraryCalls(hinstDLL); | |
| DSM_currentState = 2; | |
| break; | |
| case DLL_PROCESS_DETACH: | |
| DSM_currentState = 1; | |
| break; | |
| } | |
| return TRUE; | |
| } | |
| TW_UINT16 TWAIN_SourceManagerHandler ( | |
| pTW_IDENTITY pOrigin, | |
| TW_UINT16 DAT, | |
| TW_UINT16 MSG, | |
| TW_MEMREF pData) | |
| { | |
| TW_UINT16 twRC = TWRC_SUCCESS; | |
| switch (DAT) | |
| { | |
| case DAT_IDENTITY: | |
| switch (MSG) | |
| { | |
| case MSG_CLOSEDS: | |
| twRC = TWAIN_CloseDS (pOrigin, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_IdentityGetDefault (pOrigin, pData); | |
| break; | |
| case MSG_GETFIRST: | |
| twRC = TWAIN_IdentityGetFirst (pOrigin, pData); | |
| break; | |
| case MSG_GETNEXT: | |
| twRC = TWAIN_IdentityGetNext (pOrigin, pData); | |
| break; | |
| case MSG_OPENDS: | |
| twRC = TWAIN_OpenDS (pOrigin, pData); | |
| break; | |
| case MSG_USERSELECT: | |
| twRC = TWAIN_UserSelect (pOrigin, pData); | |
| break; | |
| default: | |
| /* Unrecognized operation triplet */ | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| break; | |
| } | |
| break; | |
| case DAT_PARENT: | |
| switch (MSG) | |
| { | |
| case MSG_CLOSEDSM: | |
| twRC = TWAIN_CloseDSM (pOrigin, pData); | |
| break; | |
| case MSG_OPENDSM: | |
| twRC = TWAIN_OpenDSM (pOrigin, pData); | |
| break; | |
| default: | |
| /* Unrecognized operation triplet */ | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| } | |
| break; | |
| case DAT_STATUS: | |
| if (MSG == MSG_GET) | |
| { | |
| twRC = TWAIN_GetDSMStatus (pOrigin, pData); | |
| } | |
| else | |
| { | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| } | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| break; | |
| } | |
| return twRC; | |
| } | |
| TW_UINT16 TWAIN_SourceControlHandler ( | |
| pTW_IDENTITY pOrigin, | |
| pTW_IDENTITY pDest, | |
| TW_UINT16 DAT, | |
| TW_UINT16 MSG, | |
| TW_MEMREF pData) | |
| { | |
| TW_UINT16 twRC = TWRC_SUCCESS; | |
| switch (DAT) | |
| { | |
| case DAT_CAPABILITY: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_CapabilityGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETCURRENT: | |
| twRC = TWAIN_CapabilityGetCurrent (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_CapabilityGetDefault (pOrigin, pDest, pData); | |
| break; | |
| case MSG_QUERYSUPPORT: | |
| twRC = TWAIN_CapabilityQuerySupport (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_CapabilityReset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_CapabilitySet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| WARN("unrecognized opertion triplet\n"); | |
| } | |
| break; | |
| case DAT_CUSTOMDSDATA: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_CustomDSDataGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_CustomDSDataSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| break; | |
| } | |
| break; | |
| case DAT_FILESYSTEM: | |
| switch (MSG) | |
| { | |
| /*case MSG_AUTOMATICCAPTUREDIRECTORY: | |
| twRC = TWAIN_AutomaticCaptureDirectory | |
| (pOrigin, pDest, pData); | |
| break;*/ | |
| case MSG_CHANGEDIRECTORY: | |
| twRC = TWAIN_ChangeDirectory (pOrigin, pDest, pData); | |
| break; | |
| /*case MSG_COPY: | |
| twRC = TWAIN_FileSystemCopy (pOrigin, pDest, pData); | |
| break;*/ | |
| case MSG_CREATEDIRECTORY: | |
| twRC = TWAIN_CreateDirectory (pOrigin, pDest, pData); | |
| break; | |
| case MSG_DELETE: | |
| twRC = TWAIN_FileSystemDelete (pOrigin, pDest, pData); | |
| break; | |
| case MSG_FORMATMEDIA: | |
| twRC = TWAIN_FormatMedia (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETCLOSE: | |
| twRC = TWAIN_FileSystemGetClose (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETFIRSTFILE: | |
| twRC = TWAIN_FileSystemGetFirstFile | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETINFO: | |
| twRC = TWAIN_FileSystemGetInfo (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETNEXTFILE: | |
| twRC = TWAIN_FileSystemGetNextFile | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RENAME: | |
| twRC = TWAIN_FileSystemRename (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| break; | |
| } | |
| break; | |
| case DAT_EVENT: | |
| if (MSG == MSG_PROCESSEVENT) | |
| twRC = TWAIN_ProcessEvent (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_PASSTHRU: | |
| if (MSG == MSG_PASSTHRU) | |
| twRC = TWAIN_PassThrough (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_PENDINGXFERS: | |
| switch (MSG) | |
| { | |
| case MSG_ENDXFER: | |
| twRC = TWAIN_PendingXfersEndXfer (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GET: | |
| twRC = TWAIN_PendingXfersGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_PendingXfersReset (pOrigin, pDest, pData); | |
| break; | |
| /*case MSG_STOPFEEDER: | |
| twRC = TWAIN_PendingXfersStopFeeder | |
| (pOrigin, pDest, pData); | |
| break;*/ | |
| default: | |
| twRC = TWRC_FAILURE; | |
| } | |
| break; | |
| case DAT_SETUPFILEXFER: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_SetupFileXferGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_SetupFileXferGetDefault | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_SetupFileXferReset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_SetupFileXferSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| break; | |
| } | |
| break; | |
| /*case DAT_SETUPFILEXFER2: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_SetupFileXfer2Get (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_SetupFileXfer2GetDefault | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_SetupFileXfer2Reset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_SetupFileXfer2Set (pOrigin, pDest, pData); | |
| break; | |
| } | |
| break;*/ | |
| case DAT_SETUPMEMXFER: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_SetupMemXferGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_STATUS: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_GetDSStatus (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_USERINTERFACE: | |
| switch (MSG) | |
| { | |
| case MSG_DISABLEDS: | |
| twRC = TWAIN_DisableDSUserInterface | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_ENABLEDS: | |
| twRC = TWAIN_EnableDSUserInterface | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_ENABLEDSUIONLY: | |
| twRC = TWAIN_EnableDSUIOnly (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| break; | |
| } | |
| break; | |
| case DAT_XFERGROUP: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_XferGroupGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_XferGroupSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| break; | |
| } | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| break; | |
| } | |
| return twRC; | |
| } | |
| TW_UINT16 TWAIN_ControlGroupHandler ( | |
| pTW_IDENTITY pOrigin, | |
| pTW_IDENTITY pDest, | |
| TW_UINT16 DAT, | |
| TW_UINT16 MSG, | |
| TW_MEMREF pData) | |
| { | |
| TW_UINT16 twRC = TWRC_SUCCESS; | |
| if (pDest) | |
| { | |
| /* This operation's destination is a source */ | |
| twRC = TWAIN_SourceControlHandler (pOrigin, pDest, DAT, MSG, pData); | |
| } | |
| else | |
| { | |
| /* This operation's destination is the Source Manager */ | |
| twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData); | |
| } | |
| return twRC; | |
| } | |
| TW_UINT16 TWAIN_ImageGroupHandler ( | |
| pTW_IDENTITY pOrigin, | |
| pTW_IDENTITY pDest, | |
| TW_UINT16 DAT, | |
| TW_UINT16 MSG, | |
| TW_MEMREF pData) | |
| { | |
| TW_UINT16 twRC = TWRC_SUCCESS; | |
| if (pDest == NULL) | |
| { | |
| DSM_twCC = TWCC_BADDEST; | |
| return TWRC_FAILURE; | |
| } | |
| switch (DAT) | |
| { | |
| case DAT_CIECOLOR: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_CIEColorGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_EXTIMAGEINFO: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_ExtImageInfoGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_GRAYRESPONSE: | |
| switch (MSG) | |
| { | |
| case MSG_RESET: | |
| twRC = TWAIN_GrayResponseReset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_GrayResponseSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| break; | |
| } | |
| break; | |
| case DAT_IMAGEFILEXFER: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_ImageFileXferGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_IMAGEINFO: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_ImageInfoGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_IMAGELAYOUT: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_ImageLayoutGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_ImageLayoutGetDefault (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_ImageLayoutReset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_ImageLayoutSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| break; | |
| } | |
| break; | |
| case DAT_IMAGEMEMXFER: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_ImageMemXferGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_IMAGENATIVEXFER: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_ImageNativeXferGet (pOrigin, pDest, pData); | |
| else | |
| twRC = TWRC_FAILURE; | |
| break; | |
| case DAT_JPEGCOMPRESSION: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_JPEGCompressionGet (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_JPEGCompressionGetDefault | |
| (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_JPEGCompressionReset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_JPEGCompressionSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| break; | |
| } | |
| break; | |
| case DAT_PALETTE8: | |
| switch (MSG) | |
| { | |
| case MSG_GET: | |
| twRC = TWAIN_Palette8Get (pOrigin, pDest, pData); | |
| break; | |
| case MSG_GETDEFAULT: | |
| twRC = TWAIN_Palette8GetDefault (pOrigin, pDest, pData); | |
| break; | |
| case MSG_RESET: | |
| twRC = TWAIN_Palette8Reset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_Palette8Set (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| } | |
| break; | |
| case DAT_RGBRESPONSE: | |
| switch (MSG) | |
| { | |
| case MSG_RESET: | |
| twRC = TWAIN_RGBResponseReset (pOrigin, pDest, pData); | |
| break; | |
| case MSG_SET: | |
| twRC = TWAIN_RGBResponseSet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| break; | |
| } | |
| break; | |
| default: | |
| twRC = TWRC_FAILURE; | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| WARN("unrecognized operation triplet\n"); | |
| } | |
| return twRC; | |
| } | |
| TW_UINT16 TWAIN_AudioGroupHandler ( | |
| pTW_IDENTITY pOrigin, | |
| pTW_IDENTITY pDest, | |
| TW_UINT16 DAT, | |
| TW_UINT16 MSG, | |
| TW_MEMREF pData) | |
| { | |
| TW_UINT16 twRC = TWRC_FAILURE; | |
| switch (DAT) | |
| { | |
| case DAT_AUDIOFILEXFER: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_AudioFileXferGet (pOrigin, pDest, pData); | |
| break; | |
| case DAT_AUDIOINFO: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_AudioInfoGet (pOrigin, pDest, pData); | |
| break; | |
| case DAT_AUDIONATIVEXFER: | |
| if (MSG == MSG_GET) | |
| twRC = TWAIN_AudioNativeXferGet (pOrigin, pDest, pData); | |
| break; | |
| default: | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| twRC = TWRC_FAILURE; | |
| break; | |
| } | |
| return twRC; | |
| } | |
| /* Main entry point for the TWAIN library */ | |
| TW_UINT16 WINAPI | |
| DSM_Entry (pTW_IDENTITY pOrigin, | |
| pTW_IDENTITY pDest, | |
| TW_UINT32 DG, | |
| TW_UINT16 DAT, | |
| TW_UINT16 MSG, | |
| TW_MEMREF pData) | |
| { | |
| TW_UINT16 twRC = TWRC_SUCCESS; /* Return Code */ | |
| TRACE("(DG=%ld DAT=%d MSG=%d)\n", DG, DAT, MSG); | |
| switch (DG) | |
| { | |
| case DG_CONTROL: | |
| twRC = TWAIN_ControlGroupHandler (pOrigin,pDest,DAT,MSG,pData); | |
| break; | |
| case DG_IMAGE: | |
| twRC = TWAIN_ImageGroupHandler (pOrigin,pDest,DAT,MSG,pData); | |
| break; | |
| case DG_AUDIO: | |
| twRC = TWAIN_AudioGroupHandler (pOrigin,pDest,DAT,MSG,pData); | |
| break; | |
| default: | |
| DSM_twCC = TWCC_BADPROTOCOL; | |
| twRC = TWRC_FAILURE; | |
| } | |
| return twRC; | |
| } | |
| /* A helper function that looks up a destination identity in the active | |
| source list */ | |
| activeDS *TWAIN_LookupSource (pTW_IDENTITY pDest) | |
| { | |
| activeDS *pSource; | |
| for (pSource = activeSources; pSource; pSource = pSource->next) | |
| if (pSource->identity.Id == pDest->Id) | |
| break; | |
| return pSource; | |
| } |