sane.ds: Dynamically load libsane.so.

This change was triggered because of a bug in libsane-hpaio.so, namely
that it relies on libsane.so being dlopen'd RTLD_GLOBAL so that
sanei_init_debug can be resolved.
This commit is contained in:
Jeremy White 2007-03-14 13:10:03 -05:00 committed by Alexandre Julliard
parent 8f5f3f5b8e
commit 16f33d8b43
9 changed files with 211 additions and 52 deletions

76
configure vendored
View File

@ -15718,6 +15718,82 @@ cat >>confdefs.h <<_ACEOF
#define SONAME_LIBCAPI20 "$ac_cv_lib_soname_capi20"
_ACEOF
fi
{ echo "$as_me:$LINENO: checking for -lsane soname" >&5
echo $ECHO_N "checking for -lsane soname... $ECHO_C" >&6; }
if test "${ac_cv_lib_soname_sane+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_get_soname_save_LIBS=$LIBS
LIBS="-lsane $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char sane_init ();
int
main ()
{
return sane_init ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
case "$LIBEXT" in
dylib) ac_cv_lib_soname_sane=`otool -L conftest$ac_exeext | grep libsane\\.[0-9A-Za-z.]*dylib | sed -e "s/^.*\/\(libsane\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;;
so) ac_cv_lib_soname_sane=`$ac_cv_path_LDD conftest$ac_exeext | grep libsane\\.so | sed -e "s/^.*\(libsane\.so[^ ]*\).*$/\1/"';2,$d'` ;;
esac
if test "x$ac_cv_lib_soname_sane" = "x"
then
ac_cv_lib_soname_sane="libsane.$LIBEXT"
fi
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_soname_sane="libsane.$LIBEXT"
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_get_soname_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_soname_sane" >&5
echo "${ECHO_T}$ac_cv_lib_soname_sane" >&6; }
if test "${ac_cv_lib_soname_sane+set}" = set; then
cat >>confdefs.h <<_ACEOF
#define SONAME_LIBSANE "$ac_cv_lib_soname_sane"
_ACEOF
fi
fi

View File

@ -1169,6 +1169,7 @@ then
WINE_GET_SONAME(curses,waddch)
WINE_GET_SONAME(jpeg,jpeg_start_decompress)
WINE_GET_SONAME(capi20,capi20_isinstalled)
WINE_GET_SONAME(sane,sane_init)
fi

View File

@ -4,7 +4,6 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = sane.ds
IMPORTS = comctl32 user32 gdi32 kernel32 ntdll
EXTRALIBS = @SANELIBS@
EXTRAINCL = @SANEINCL@
C_SRCS = \

View File

@ -576,7 +576,7 @@ TW_UINT16 SANE_EnableDSUserInterface (pTW_IDENTITY pOrigin,
#ifdef HAVE_SANE
else
{
sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
activeDS.sane_param_valid = TRUE;
}
#endif

View File

@ -99,7 +99,7 @@ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin,
if (activeDS.currentState == 6)
{
/* return general image description information about the image about to be transferred */
status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
activeDS.sane_param_valid = TRUE;
TRACE("Getting parameters\n");
}
@ -217,23 +217,23 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
ScanningDialogBox(activeDS.progressWnd,0);
status = sane_start (activeDS.deviceHandle);
status = psane_start (activeDS.deviceHandle);
if (status != SANE_STATUS_GOOD)
{
WARN("sane_start: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
WARN("psane_start: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
status = sane_get_parameters (activeDS.deviceHandle,
status = psane_get_parameters (activeDS.deviceHandle,
&activeDS.sane_param);
activeDS.sane_param_valid = TRUE;
if (status != SANE_STATUS_GOOD)
{
WARN("sane_get_parameters: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
WARN("psane_get_parameters: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
@ -249,7 +249,7 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
/* access memory buffer */
if (pImageMemXfer->Memory.Length < activeDS.sane_param.bytes_per_line)
{
sane_cancel (activeDS.deviceHandle);
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_BADVALUE;
return TWRC_FAILURE;
}
@ -272,7 +272,7 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
while (consumed_len < (activeDS.sane_param.bytes_per_line*rows) &&
status == SANE_STATUS_GOOD)
{
status = sane_read (activeDS.deviceHandle, ptr,
status = psane_read (activeDS.deviceHandle, ptr,
(activeDS.sane_param.bytes_per_line*rows) - consumed_len ,
&buff_len);
consumed_len += buff_len;
@ -294,8 +294,8 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
if (status == SANE_STATUS_EOF)
{
ScanningDialogBox(activeDS.progressWnd, -1);
TRACE("sane_read: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
TRACE("psane_read: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
twRC = TWRC_XFERDONE;
}
activeDS.twCC = TWRC_SUCCESS;
@ -303,8 +303,8 @@ TW_UINT16 SANE_ImageMemXferGet (pTW_IDENTITY pOrigin,
else if (status != SANE_STATUS_EOF)
{
ScanningDialogBox(activeDS.progressWnd, -1);
WARN("sane_read: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
WARN("psane_read: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
twRC = TWRC_FAILURE;
}
@ -344,21 +344,21 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
else
{
/* Transfer an image from the source to the application */
status = sane_start (activeDS.deviceHandle);
status = psane_start (activeDS.deviceHandle);
if (status != SANE_STATUS_GOOD)
{
WARN("sane_start: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
WARN("psane_start: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
status = sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
status = psane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
activeDS.sane_param_valid = TRUE;
if (status != SANE_STATUS_GOOD)
{
WARN("sane_get_parameters: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
WARN("psane_get_parameters: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
@ -387,14 +387,14 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
DIB_RGB_COLORS, &pBits, 0, 0);
if (!hDIB)
{
sane_cancel (activeDS.deviceHandle);
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_LOWMEMORY;
return TWRC_FAILURE;
}
do
{
status = sane_read (activeDS.deviceHandle, buffer,
status = psane_read (activeDS.deviceHandle, buffer,
sizeof (buffer), &buff_len);
if (status == SANE_STATUS_GOOD)
{
@ -403,14 +403,14 @@ TW_UINT16 SANE_ImageNativeXferGet (pTW_IDENTITY pOrigin,
}
else if (status != SANE_STATUS_EOF)
{
WARN("sane_read: %s\n", sane_strstatus (status));
sane_cancel (activeDS.deviceHandle);
WARN("psane_read: %s\n", psane_strstatus (status));
psane_cancel (activeDS.deviceHandle);
activeDS.twCC = TWCC_OPERATIONERROR;
return TWRC_FAILURE;
}
} while (status == SANE_STATUS_GOOD);
sane_cancel (activeDS.deviceHandle);
psane_cancel (activeDS.deviceHandle);
ReleaseDC (activeDS.hwndOwner, dc);
*pHandle = (TW_UINT32)hDIB;
twRC = TWRC_XFERDONE;

View File

@ -25,6 +25,24 @@
#ifdef HAVE_SANE
# include <sane/sane.h>
#define MAKE_FUNCPTR(f) typeof(f) * p##f;
MAKE_FUNCPTR(sane_init)
MAKE_FUNCPTR(sane_exit)
MAKE_FUNCPTR(sane_get_devices)
MAKE_FUNCPTR(sane_open)
MAKE_FUNCPTR(sane_close)
MAKE_FUNCPTR(sane_get_option_descriptor)
MAKE_FUNCPTR(sane_control_option)
MAKE_FUNCPTR(sane_get_parameters)
MAKE_FUNCPTR(sane_start)
MAKE_FUNCPTR(sane_read)
MAKE_FUNCPTR(sane_cancel)
MAKE_FUNCPTR(sane_set_io_mode)
MAKE_FUNCPTR(sane_get_select_fd)
MAKE_FUNCPTR(sane_strstatus)
#undef MAKE_FUNCPTR
#endif
#include <stdarg.h>

View File

@ -19,6 +19,7 @@
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdio.h>
@ -28,11 +29,64 @@
#include "twain.h"
#include "sane_i.h"
#include "wine/debug.h"
#include "wine/library.h"
WINE_DEFAULT_DEBUG_CHANNEL(twain);
HINSTANCE SANE_instance;
#ifdef HAVE_SANE
#ifndef SONAME_LIBSANE
#define SONAME_LIBSANE "libsane.so"
#endif
static void *libsane_handle;
static void close_libsane(void *h)
{
if (h)
wine_dlclose(h, NULL, 0);
}
static void *open_libsane(void)
{
void *h;
h = wine_dlopen(SONAME_LIBSANE, RTLD_GLOBAL | RTLD_NOW, NULL, 0);
if (!h)
{
WARN("dlopen(%s) failed\n", SONAME_LIBSANE);
return NULL;
}
#define LOAD_FUNCPTR(f) \
if((p##f = wine_dlsym(h, #f, NULL, 0)) == NULL) { \
close_libsane(h); \
ERR("Could not dlsym %s\n", #f); \
return NULL; \
}
LOAD_FUNCPTR(sane_init)
LOAD_FUNCPTR(sane_exit)
LOAD_FUNCPTR(sane_get_devices)
LOAD_FUNCPTR(sane_open)
LOAD_FUNCPTR(sane_close)
LOAD_FUNCPTR(sane_get_option_descriptor)
LOAD_FUNCPTR(sane_control_option)
LOAD_FUNCPTR(sane_get_parameters)
LOAD_FUNCPTR(sane_start)
LOAD_FUNCPTR(sane_read)
LOAD_FUNCPTR(sane_cancel)
LOAD_FUNCPTR(sane_set_io_mode)
LOAD_FUNCPTR(sane_get_select_fd)
LOAD_FUNCPTR(sane_strstatus)
#undef LOAD_FUNCPTR
return h;
}
#endif /* HAVE_SANE */
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
@ -43,7 +97,12 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#ifdef HAVE_SANE
SANE_Status status;
SANE_Int version_code;
status = sane_init (&version_code, NULL);
libsane_handle = open_libsane();
if (! libsane_handle)
return FALSE;
status = psane_init (&version_code, NULL);
#endif
SANE_instance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
@ -52,7 +111,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_DETACH:
#ifdef HAVE_SANE
TRACE("calling sane_exit()\n");
sane_exit ();
psane_exit ();
close_libsane(libsane_handle);
libsane_handle = NULL;
#endif
SANE_instance = NULL;
break;
@ -81,7 +143,7 @@ static TW_UINT16 SANE_SourceControlHandler (
{
case MSG_CLOSEDS:
#ifdef HAVE_SANE
sane_close (activeDS.deviceHandle);
psane_close (activeDS.deviceHandle);
#endif
break;
case MSG_OPENDS:
@ -543,7 +605,7 @@ static void
detect_sane_devices(void) {
if (sane_devlist && sane_devlist[0]) return;
TRACE("detecting sane...\n");
if (sane_get_devices (&sane_devlist, SANE_FALSE) != SANE_STATUS_GOOD)
if (psane_get_devices (&sane_devlist, SANE_FALSE) != SANE_STATUS_GOOD)
return;
}
@ -599,13 +661,13 @@ static TW_UINT16 SANE_OpenDS( pTW_IDENTITY pOrigin, pTW_IDENTITY self) {
FIXME("Scanner not found? Using first one!\n");
i=0;
}
status = sane_open(sane_devlist[i]->name,&activeDS.deviceHandle);
status = psane_open(sane_devlist[i]->name,&activeDS.deviceHandle);
if (status == SANE_STATUS_GOOD) {
activeDS.currentState = 4;
activeDS.twCC = TWRC_SUCCESS;
return TWRC_SUCCESS;
}
FIXME("sane_open(%s): %s\n", sane_devlist[i]->name, sane_strstatus (status));
FIXME("sane_open(%s): %s\n", sane_devlist[i]->name, psane_strstatus (status));
return TWRC_FAILURE;
}
#endif

View File

@ -175,7 +175,7 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
{
SANE_Int i;
sane_control_option(activeDS.deviceHandle, id-ID_BASE,
psane_control_option(activeDS.deviceHandle, id-ID_BASE,
SANE_ACTION_GET_VALUE, &i,NULL);
sprintf(buffer,"%i",i);
@ -211,7 +211,7 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
i = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
sane_control_option(activeDS.deviceHandle, id-ID_BASE,
psane_control_option(activeDS.deviceHandle, id-ID_BASE,
SANE_ACTION_GET_VALUE, i, NULL);
dd = SANE_UNFIX(*i);
@ -255,7 +255,7 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
}
leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
id+ID_STATIC_BASE);
sane_control_option(activeDS.deviceHandle, id-ID_BASE,
psane_control_option(activeDS.deviceHandle, id-ID_BASE,
SANE_ACTION_GET_VALUE, buffer,NULL);
title = buffer;
@ -385,7 +385,7 @@ static LPDLGTEMPLATEW create_options_page(HDC hdc, int *from_index,
int group_offset = -1;
INT control_count = 0;
rc = sane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
rc = psane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
&optcount, NULL);
if (rc != SANE_STATUS_GOOD)
@ -404,7 +404,7 @@ static LPDLGTEMPLATEW create_options_page(HDC hdc, int *from_index,
int count;
int hold_for_group = 0;
opt = sane_get_option_descriptor(activeDS.deviceHandle, i);
opt = psane_get_option_descriptor(activeDS.deviceHandle, i);
if (opt->type == SANE_TYPE_GROUP && split_tabs)
{
if (control_len > 0)
@ -538,7 +538,7 @@ BOOL DoScannerUI(void)
hdc = GetDC(0);
memset(&psp,0,sizeof(psp));
rc = sane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
rc = psane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
&optcount, NULL);
while (index < optcount)
@ -546,7 +546,7 @@ BOOL DoScannerUI(void)
const SANE_Option_Descriptor *opt;
psp[page_count].u.pResource = create_options_page(hdc, &index,
TRUE);
opt = sane_get_option_descriptor(activeDS.deviceHandle, index);
opt = psane_get_option_descriptor(activeDS.deviceHandle, index);
if (opt->type == SANE_TYPE_GROUP)
{
@ -664,7 +664,7 @@ static BOOL UpdateSaneScrollOption(
else
si = position;
rc = sane_control_option (activeDS.deviceHandle,index,
rc = psane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, &si, &result);
}
@ -684,7 +684,7 @@ static BOOL UpdateSaneScrollOption(
*sf = SANE_FIX(dd);
rc = sane_control_option (activeDS.deviceHandle,index,
rc = psane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, sf, &result);
HeapFree(GetProcessHeap(),0,sf);
@ -707,7 +707,7 @@ static BOOL UpdateSaneBoolOption(int index, BOOL position)
si = position;
rc = sane_control_option (activeDS.deviceHandle,index,
rc = psane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, &si, &result);
if(rc == SANE_STATUS_GOOD)
@ -724,7 +724,7 @@ static BOOL UpdateSaneStringOption(int index, SANE_String value)
SANE_Status rc = SANE_STATUS_GOOD;
SANE_Int result = 0;
rc = sane_control_option (activeDS.deviceHandle,index,
rc = psane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, value, &result);
if(rc == SANE_STATUS_GOOD)
@ -743,7 +743,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
HWND control;
int i;
rc = sane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
rc = psane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
&optcount, NULL);
for ( i = 1; i < optcount; i++)
@ -755,7 +755,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
if (!control)
continue;
opt = sane_get_option_descriptor(activeDS.deviceHandle, i);
opt = psane_get_option_descriptor(activeDS.deviceHandle, i);
TRACE("%i %s %i %i\n",i,opt->title,opt->type,opt->constraint_type);
@ -777,13 +777,13 @@ static INT_PTR InitializeDialog(HWND hwnd)
(LPARAM)opt->constraint.string_list[j]);
j++;
}
sane_control_option(activeDS.deviceHandle, i, SANE_ACTION_GET_VALUE, buffer,NULL);
psane_control_option(activeDS.deviceHandle, i, SANE_ACTION_GET_VALUE, buffer,NULL);
SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer);
}
else if (opt->type == SANE_TYPE_BOOL)
{
SANE_Bool b;
sane_control_option(activeDS.deviceHandle, i,
psane_control_option(activeDS.deviceHandle, i,
SANE_ACTION_GET_VALUE, &b, NULL);
if (b)
SendMessageA(control,BM_SETCHECK,BST_CHECKED,0);
@ -806,7 +806,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
SendMessageA(control,SBM_SETRANGE,min,max);
sane_control_option(activeDS.deviceHandle, i,
psane_control_option(activeDS.deviceHandle, i,
SANE_ACTION_GET_VALUE, &si,NULL);
if (opt->constraint.range->quant)
si = si / opt->constraint.range->quant;
@ -842,7 +842,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
sf = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
sane_control_option(activeDS.deviceHandle, i,
psane_control_option(activeDS.deviceHandle, i,
SANE_ACTION_GET_VALUE, sf,NULL);
dd = SANE_UNFIX(*sf);
@ -874,7 +874,7 @@ static INT_PTR ProcessScroll(HWND hwnd, WPARAM wParam, LPARAM lParam)
if (index < 0)
return FALSE;
opt = sane_get_option_descriptor(activeDS.deviceHandle, index);
opt = psane_get_option_descriptor(activeDS.deviceHandle, index);
if (!opt)
return FALSE;
@ -929,7 +929,7 @@ static void ButtonClicked(HWND hwnd, INT id, HWND control)
if (index < 0)
return;
opt = sane_get_option_descriptor(activeDS.deviceHandle, index);
opt = psane_get_option_descriptor(activeDS.deviceHandle, index);
if (!opt)
return;
@ -954,7 +954,7 @@ static void ComboChanged(HWND hwnd, INT id, HWND control)
if (index < 0)
return;
opt = sane_get_option_descriptor(activeDS.deviceHandle, index);
opt = psane_get_option_descriptor(activeDS.deviceHandle, index);
if (!opt)
return;

View File

@ -1017,6 +1017,9 @@
/* Define to the soname of the libncurses library. */
#undef SONAME_LIBNCURSES
/* Define to the soname of the libsane library. */
#undef SONAME_LIBSANE
/* Define to the soname of the libssl library. */
#undef SONAME_LIBSSL