mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 21:04:06 +00:00
10adf6b865
Fixes an activeDS.deviceHandle corruption bug.
639 lines
19 KiB
C
639 lines
19 KiB
C
/*
|
|
* 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;
|
|
}
|