Jeremy White : twain: Reconcile sane's long names to TWAIN's 32 byte
limit.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Feb 14 07:28:32 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 63e8d34a42f717897635fa1d6bc39fb805bc1ff2
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=63e8d34a42f717897635fa1d6bc39fb805bc1ff2
Author: Jeremy White <jwhite at codeweavers.com>
Date: Tue Feb 14 13:06:06 2006 +0100
twain: Reconcile sane's long names to TWAIN's 32 byte limit.
---
dlls/twain/dsm_ctrl.c | 65 ++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/dlls/twain/dsm_ctrl.c b/dlls/twain/dsm_ctrl.c
index f744939..6ebff41 100644
--- a/dlls/twain/dsm_ctrl.c
+++ b/dlls/twain/dsm_ctrl.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <stdarg.h>
+#include <stdio.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
@@ -83,6 +84,40 @@ TW_UINT16 TWAIN_CloseDS (pTW_IDENTITY pO
#endif
}
+/* Sane returns device names that are longer than the 32 bytes allowed
+ by TWAIN. However, it colon separates them, and the last bit is
+ the most interesting. So we use the last bit, and add a signature
+ to ensure uniqueness */
+#ifdef HAVE_SANE
+static void copy_sane_short_name(const char *in, char *out, size_t outsize)
+{
+ const char *p;
+ int signature = 0;
+
+ if (strlen(in) <= outsize - 1)
+ {
+ strcpy(out, in);
+ return;
+ }
+
+ for (p = in; *p; p++)
+ signature += *p;
+
+ p = strrchr(in, ':');
+ if (!p)
+ p = in;
+ else
+ p++;
+
+ if (strlen(p) > outsize - 7 - 1)
+ p += strlen(p) - (outsize - 7 - 1);
+
+ strcpy(out, p);
+ sprintf(out + strlen(out), "(%04X)", signature % 0x10000);
+
+}
+#endif
+
/* DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT */
TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
@@ -109,14 +144,16 @@ TW_UINT16 TWAIN_IdentityGetDefault (pTW_
if (device_list && device_list[0])
{
pSourceIdentity->Id = DSM_sourceId ++;
- strcpy (pSourceIdentity->ProductName, device_list[0]->name);
- strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor);
- strcpy (pSourceIdentity->ProductFamily, device_list[0]->model);
+ copy_sane_short_name(device_list[0]->name, pSourceIdentity->ProductName, sizeof(pSourceIdentity->ProductName) - 1);
+ TRACE("got: %s (short [%s]), %s, %s\n", device_list[0]->name, pSourceIdentity->ProductName, device_list[0]->vendor, device_list[0]->model);
+ lstrcpynA (pSourceIdentity->Manufacturer, device_list[0]->vendor, sizeof(pSourceIdentity->Manufacturer) - 1);
+ lstrcpynA (pSourceIdentity->ProductFamily, device_list[0]->model, sizeof(pSourceIdentity->ProductFamily) - 1);
pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
twRC = TWRC_SUCCESS;
DSM_twCC = TWCC_SUCCESS;
+
}
else
{
@@ -146,11 +183,11 @@ TW_UINT16 TWAIN_IdentityGetFirst (pTW_ID
{
if (device_list[0])
{
- TRACE("got: %s, %s, %s\n", device_list[0]->name, device_list[0]->vendor, device_list[0]->model);
pSourceIdentity->Id = DSM_sourceId ++;
- strcpy (pSourceIdentity->ProductName, device_list[0]->name);
- strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor);
- strcpy (pSourceIdentity->ProductFamily, device_list[0]->model);
+ copy_sane_short_name(device_list[0]->name, pSourceIdentity->ProductName, sizeof(pSourceIdentity->ProductName) - 1);
+ TRACE("got: %s (short [%s]), %s, %s\n", device_list[0]->name, pSourceIdentity->ProductName, device_list[0]->vendor, device_list[0]->model);
+ lstrcpynA (pSourceIdentity->Manufacturer, device_list[0]->vendor, sizeof(pSourceIdentity->Manufacturer) - 1);
+ lstrcpynA (pSourceIdentity->ProductFamily, device_list[0]->model, sizeof(pSourceIdentity->ProductFamily) - 1);
pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
@@ -199,9 +236,10 @@ TW_UINT16 TWAIN_IdentityGetNext (pTW_IDE
device_list[DSM_currentDevice]->model)
{
pSourceIdentity->Id = DSM_sourceId ++;
- strcpy (pSourceIdentity->ProductName, device_list[DSM_currentDevice]->name);
- strcpy (pSourceIdentity->Manufacturer, device_list[DSM_currentDevice]->vendor);
- strcpy (pSourceIdentity->ProductFamily, device_list[DSM_currentDevice]->model);
+ copy_sane_short_name(device_list[DSM_currentDevice]->name, pSourceIdentity->ProductName, sizeof(pSourceIdentity->ProductName) - 1);
+ TRACE("got: %s (short [%s]), %s, %s\n", device_list[DSM_currentDevice]->name, pSourceIdentity->ProductName, device_list[DSM_currentDevice]->vendor, device_list[DSM_currentDevice]->model);
+ lstrcpynA (pSourceIdentity->Manufacturer, device_list[DSM_currentDevice]->vendor, sizeof(pSourceIdentity->Manufacturer) - 1);
+ lstrcpynA (pSourceIdentity->ProductFamily, device_list[DSM_currentDevice]->model, sizeof(pSourceIdentity->ProductFamily) - 1);
pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
DSM_currentDevice ++;
@@ -228,6 +266,7 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOr
#else
TW_UINT16 twRC = TWRC_SUCCESS, i = 0;
pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
+ TW_STR32 shortname;
activeDS *newSource;
SANE_Status status;
@@ -251,9 +290,11 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOr
/* Make sure the source to be opened exists in the device list */
for (i = 0; device_list[i]; i ++)
{
- if (strcmp (device_list[i]->name, pIdentity->ProductName) == 0)
+ copy_sane_short_name(device_list[i]->name, shortname, sizeof(shortname) - 1);
+ if (strcmp (shortname, pIdentity->ProductName) == 0)
break;
}
+
}
if (device_list[i])
@@ -266,7 +307,7 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOr
if (status == SANE_STATUS_GOOD)
{
/* Assign name and id for the opened data source */
- strcpy (pIdentity->ProductName, device_list[i]->name);
+ lstrcpynA (pIdentity->ProductName, shortname, sizeof(pIdentity->ProductName) - 1);
pIdentity->Id = DSM_sourceId ++;
/* add the data source to an internal active source list */
newSource->next = activeSources;
More information about the wine-cvs
mailing list