Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winspool.drv/Makefile.in | 1 + dlls/winspool.drv/cups.c | 101 ++++++++++++++++++++++++++++++++++ dlls/winspool.drv/info.c | 40 +++----------- dlls/winspool.drv/wspool.c | 31 ++++++----- dlls/winspool.drv/wspool.h | 5 ++ 5 files changed, 130 insertions(+), 48 deletions(-) create mode 100644 dlls/winspool.drv/cups.c
diff --git a/dlls/winspool.drv/Makefile.in b/dlls/winspool.drv/Makefile.in index a0d0f9504f2..d40813d649c 100644 --- a/dlls/winspool.drv/Makefile.in +++ b/dlls/winspool.drv/Makefile.in @@ -8,6 +8,7 @@ EXTRALIBS = $(APPLICATIONSERVICES_LIBS) EXTRADLLFLAGS = -mcygwin
C_SRCS = \ + cups.c \ info.c \ wspool.c
diff --git a/dlls/winspool.drv/cups.c b/dlls/winspool.drv/cups.c new file mode 100644 index 00000000000..207c95c568a --- /dev/null +++ b/dlls/winspool.drv/cups.c @@ -0,0 +1,101 @@ +/* + * CUPS functions + * + * Copyright 2021 Huw Davies + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include "config.h" +#include "wine/port.h" + +#include <stdarg.h> +#include <string.h> +#ifdef HAVE_CUPS_CUPS_H +#include <cups/cups.h> +#endif +#ifdef HAVE_CUPS_PPD_H +#include <cups/ppd.h> +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winuser.h" +#include "winerror.h" +#include "winreg.h" +#include "wingdi.h" +#include "winspool.h" +#include "ddk/winsplp.h" +#include "wine/debug.h" + +#include "wspool.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winspool); + +#ifdef SONAME_LIBCUPS + +void *libcups_handle = NULL; + +#define CUPS_FUNCS \ + DO_FUNC(cupsAddOption); \ + DO_FUNC(cupsFreeDests); \ + DO_FUNC(cupsFreeOptions); \ + DO_FUNC(cupsGetDests); \ + DO_FUNC(cupsGetOption); \ + DO_FUNC(cupsParseOptions); \ + DO_FUNC(cupsPrintFile) +#define CUPS_OPT_FUNCS \ + DO_FUNC(cupsGetNamedDest); \ + DO_FUNC(cupsGetPPD); \ + DO_FUNC(cupsGetPPD3); \ + DO_FUNC(cupsLastErrorString) + +#define DO_FUNC(f) typeof(f) *p##f = NULL +CUPS_FUNCS; +#undef DO_FUNC +cups_dest_t * (*pcupsGetNamedDest)(http_t *, const char *, const char *) = NULL; +const char * (*pcupsGetPPD)(const char *) = NULL; +http_status_t (*pcupsGetPPD3)(http_t *, const char *, time_t *, char *, size_t) = NULL; +const char * (*pcupsLastErrorString)(void) = NULL; + +#endif /* SONAME_LIBCUPS */ + +NTSTATUS unix_process_attach( void *arg ) +{ +#ifdef SONAME_LIBCUPS + libcups_handle = dlopen( SONAME_LIBCUPS, RTLD_NOW ); + TRACE( "%p: %s loaded\n", libcups_handle, SONAME_LIBCUPS ); + if (!libcups_handle) return STATUS_DLL_NOT_FOUND; + +#define DO_FUNC(x) \ + p##x = dlsym( libcups_handle, #x ); \ + if (!p##x) \ + { \ + ERR( "failed to load symbol %s\n", #x ); \ + libcups_handle = NULL; \ + return STATUS_ENTRYPOINT_NOT_FOUND; \ + } + CUPS_FUNCS; +#undef DO_FUNC +#define DO_FUNC(x) p##x = dlsym( libcups_handle, #x ) + CUPS_OPT_FUNCS; +#undef DO_FUNC + return STATUS_SUCCESS; +#else /* SONAME_LIBCUPS */ + return STATUS_NOT_SUPPORTED; +#endif /* SONAME_LIBCUPS */ +} diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 660a5afe74d..fd02d2b2b3e 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -967,7 +967,7 @@ static void unlink_ppd( const WCHAR *ppd )
#ifdef SONAME_LIBCUPS
-static void *cupshandle; +extern void *libcups_handle;
#define CUPS_FUNCS \ DO_FUNC(cupsAddOption); \ @@ -983,13 +983,13 @@ static void *cupshandle; DO_FUNC(cupsGetPPD3); \ DO_FUNC(cupsLastErrorString)
-#define DO_FUNC(f) static typeof(f) *p##f +#define DO_FUNC(f) extern typeof(f) *p##f CUPS_FUNCS; #undef DO_FUNC -static cups_dest_t * (*pcupsGetNamedDest)(http_t *, const char *, const char *); -static const char * (*pcupsGetPPD)(const char *); -static http_status_t (*pcupsGetPPD3)(http_t *, const char *, time_t *, char *, size_t); -static const char * (*pcupsLastErrorString)(void); +extern cups_dest_t * (*pcupsGetNamedDest)(http_t *, const char *, const char *); +extern const char * (*pcupsGetPPD)(const char *); +extern http_status_t (*pcupsGetPPD3)(http_t *, const char *, time_t *, char *, size_t); +extern const char * (*pcupsLastErrorString)(void);
static http_status_t cupsGetPPD3_wrapper( http_t *http, const char *name, time_t *modtime, char *buffer, @@ -1072,28 +1072,6 @@ static cups_ptype_t get_cups_printer_type( const cups_dest_t *dest ) return ret; }
-static void load_cups(void) -{ - cupshandle = dlopen( SONAME_LIBCUPS, RTLD_NOW ); - if (!cupshandle) return; - - TRACE("%p: %s loaded\n", cupshandle, SONAME_LIBCUPS); - -#define DO_FUNC(x) \ - p##x = dlsym( cupshandle, #x ); \ - if (!p##x) \ - { \ - ERR("failed to load symbol %s\n", #x); \ - cupshandle = NULL; \ - return; \ - } - CUPS_FUNCS; -#undef DO_FUNC -#define DO_FUNC(x) p##x = dlsym( cupshandle, #x ) - CUPS_OPT_FUNCS; -#undef DO_FUNC -} - static BOOL CUPS_LoadPrinters(void) { int i, nrofdests; @@ -1106,7 +1084,7 @@ static BOOL CUPS_LoadPrinters(void) HANDLE added_printer; cups_ptype_t printer_type;
- if (!cupshandle) return FALSE; + if (!libcups_handle) return FALSE;
if(RegCreateKeyW(HKEY_LOCAL_MACHINE, PrintersW, &hkeyPrinters) != ERROR_SUCCESS) { @@ -1807,10 +1785,6 @@ void WINSPOOL_LoadSystemPrinters(void) WCHAR PrinterName[256]; BOOL done = FALSE;
-#ifdef SONAME_LIBCUPS - load_cups(); -#endif - /* FIXME: The init code should be moved to spoolsv.exe */ init_mutex = CreateMutexW( NULL, TRUE, winspool_mutex_name ); if (!init_mutex) diff --git a/dlls/winspool.drv/wspool.c b/dlls/winspool.drv/wspool.c index bbfb0fb0f42..90d35bee73e 100644 --- a/dlls/winspool.drv/wspool.c +++ b/dlls/winspool.drv/wspool.c @@ -110,22 +110,23 @@ BOOL load_backend(void) * Winspool entry point. * */ -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID lpReserved) +BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) { - switch (reason) - { - case DLL_PROCESS_ATTACH: { - WINSPOOL_hInstance = hInstance; - DisableThreadLibraryCalls(hInstance); - WINSPOOL_LoadSystemPrinters(); - break; - } + switch (reason) + { + case DLL_PROCESS_ATTACH: + WINSPOOL_hInstance = instance; + DisableThreadLibraryCalls( instance ); + UNIX_CALL( process_attach, NULL ); + WINSPOOL_LoadSystemPrinters(); + break; + case DLL_PROCESS_DETACH: - if (lpReserved) break; - DeleteCriticalSection(&backend_cs); - FreeLibrary(hlocalspl); - break; - } + if (reserved) break; + DeleteCriticalSection(&backend_cs); + FreeLibrary(hlocalspl); + break; + }
- return TRUE; + return TRUE; } diff --git a/dlls/winspool.drv/wspool.h b/dlls/winspool.drv/wspool.h index 06c28231330..bca4a5ea02d 100644 --- a/dlls/winspool.drv/wspool.h +++ b/dlls/winspool.drv/wspool.h @@ -21,6 +21,7 @@
#include <windef.h> #include <winuser.h> +#include <winternl.h>
extern HINSTANCE WINSPOOL_hInstance DECLSPEC_HIDDEN;
@@ -35,3 +36,7 @@ extern void WINSPOOL_LoadSystemPrinters(void) DECLSPEC_HIDDEN;
#define FILENAME_DIALOG 100 #define EDITBOX 201 + +#define UNIX_CALL( func, params ) unix_ ## func( params ) + +NTSTATUS unix_process_attach( void * ) DECLSPEC_HIDDEN;