Module: wine Branch: master Commit: b4120c7f27bdd2dbc90f751d0adba96e5c34cf5f URL: http://source.winehq.org/git/wine.git/?a=commit;h=b4120c7f27bdd2dbc90f751d0a...
Author: Detlef Riekenberg wine.dev@web.de Date: Tue May 5 05:24:34 2009 +0200
localspl: Start implementation of OpenPrinter/ClosePrinter.
---
dlls/localspl/localspl_private.h | 5 + dlls/localspl/provider.c | 156 +++++++++++++++++++++++++++++++++++++- dlls/winspool.drv/info.c | 14 +++- 3 files changed, 172 insertions(+), 3 deletions(-)
diff --git a/dlls/localspl/localspl_private.h b/dlls/localspl/localspl_private.h index 0ac6369..5174a1a 100644 --- a/dlls/localspl/localspl_private.h +++ b/dlls/localspl/localspl_private.h @@ -62,6 +62,11 @@ static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero( size_t len ) return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); }
+static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero( void * mem, size_t len ) +{ + return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len ); +} + static inline BOOL heap_free( void *mem ) { return HeapFree( GetProcessHeap(), 0, mem ); diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index f308e36..70c7f8c 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -80,6 +80,11 @@ typedef struct { LPCWSTR versionsubdir; } printenv_t;
+typedef struct { + LPWSTR name; + LPWSTR printername; +} printer_t; + /* ############################### */
static struct list monitor_handles = LIST_INIT( monitor_handles ); @@ -274,6 +279,32 @@ static LONG copy_servername_from_name(LPCWSTR name, LPWSTR target) }
/****************************************************************** + * get_basename_from_name (internal) + * + * skip over the serverpart from the full name + * + */ +static LPCWSTR get_basename_from_name(LPCWSTR name) +{ + if (name == NULL) return NULL; + if ((name[0] == '\') && (name[1] == '\')) { + /* skip over the servername and search for the following '' */ + name = strchrW(&name[2], '\'); + if ((name) && (name[1])) { + /* found a separator ('') followed by a name: + skip over the separator and return the rest */ + name++; + } + else + { + /* no basename present (we found only a servername) */ + return NULL; + } + } + return name; +} + +/****************************************************************** * monitor_unload [internal] * * release a printmonitor and unload it from memory, when needed @@ -907,6 +938,64 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname) return hui; }
+/****************************************************************** + * printer_free + * free the data pointer of an opened printer + */ +static VOID printer_free(printer_t * printer) +{ + + heap_free(printer->printername); + heap_free(printer->name); + heap_free(printer); +} + +/****************************************************************** + * printer_alloc_handle + * alloc a printer handle and remember the data pointer in the printer handle table + * + */ +static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault) +{ + WCHAR servername[MAX_COMPUTERNAME_LENGTH + 1]; + printer_t *printer = NULL; + LPCWSTR printername; + + if (copy_servername_from_name(name, servername)) { + FIXME("server %s not supported\n", debugstr_w(servername)); + SetLastError(ERROR_INVALID_PRINTER_NAME); + return NULL; + } + + printername = get_basename_from_name(name); + if (name != printername) TRACE("converted %s to %s\n", debugstr_w(name), debugstr_w(printername)); + + /* an empty printername is invalid */ + if (printername && (!printername[0])) { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + printer = heap_alloc_zero(sizeof(printer_t)); + if (!printer) goto end; + + /* clone the base name. This is NULL for the printserver */ + printer->printername = strdupW(printername); + + /* clone the full name */ + printer->name = strdupW(name); + if (name && (!printer->name)) { + printer_free(printer); + printer = NULL; + } + +end: + + TRACE("==> %p\n", printer); + return (HANDLE)printer; +} + + /****************************************************************************** * myAddPrinterDriverEx [internal] * @@ -1213,6 +1302,34 @@ static BOOL WINAPI fpAddPrinterDriverEx(LPWSTR pName, DWORD level, LPBYTE pDrive
return myAddPrinterDriverEx(level, pDriverInfo, dwFileCopyFlags, TRUE); } + +/****************************************************************************** + * fpClosePrinter [exported through PRINTPROVIDOR] + * + * Close a printer handle and free associated resources + * + * PARAMS + * hPrinter [I] Printerhandle to close + * + * RESULTS + * Success: TRUE + * Failure: FALSE + * + */ +static BOOL WINAPI fpClosePrinter(HANDLE hPrinter) +{ + printer_t *printer = (printer_t *) hPrinter; + + TRACE("(%p)\n", hPrinter); + + if (printer) { + printer_free(printer); + return TRUE; + } + return FALSE; +} + + /****************************************************************** * fpDeleteMonitor [exported through PRINTPROVIDOR] * @@ -1425,13 +1542,48 @@ emP_cleanup: return (res); }
+/****************************************************************************** + * fpOpenPrinter [exported through PRINTPROVIDOR] + * + * Open a Printer / Printserver or a Printer-Object + * + * PARAMS + * lpPrinterName [I] Name of Printserver, Printer, or Printer-Object + * pPrinter [O] The resulting Handle is stored here + * pDefaults [I] PTR to Default Printer Settings or NULL + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + * NOTES + * lpPrinterName is one of: + *| Printserver (NT only): "Servername" or NULL for the local Printserver + *| Printer: "PrinterName" + *| Printer-Object: "PrinterName,Job xxx" + *| XcvMonitor: "Servername,XcvMonitor MonitorName" + *| XcvPort: "Servername,XcvPort PortName" + * + * + */ +static BOOL WINAPI fpOpenPrinter(LPWSTR lpPrinterName, HANDLE *pPrinter, + LPPRINTER_DEFAULTSW pDefaults) +{ + + TRACE("(%s, %p, %p)\n", debugstr_w(lpPrinterName), pPrinter, pDefaults); + + *pPrinter = printer_alloc_handle(lpPrinterName, pDefaults); + + return (*pPrinter != 0); +} + /***************************************************** * setup_provider [internal] */ void setup_provider(void) { static const PRINTPROVIDOR backend = { - NULL, /* fpOpenPrinter */ + fpOpenPrinter, NULL, /* fpSetJob */ NULL, /* fpGetJob */ NULL, /* fpEnumJobs */ @@ -1462,7 +1614,7 @@ void setup_provider(void) NULL, /* fpGetPrinterData */ NULL, /* fpSetPrinterData */ NULL, /* fpWaitForPrinterChange */ - NULL, /* fpClosePrinter */ + fpClosePrinter, NULL, /* fpAddForm */ NULL, /* fpDeleteForm */ NULL, /* fpGetForm */ diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 8160957..d2a40d0 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -111,6 +111,7 @@ typedef struct { LPWSTR printername; monitor_t *pm; HANDLE hXcv; + HANDLE backend_printer; jobqueue_t *queue; started_doc_t *doc; } opened_printer_t; @@ -1119,7 +1120,7 @@ static LPCWSTR get_basename_from_name(LPCWSTR name) * ToDo: * - pDefault is ignored */ -static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault) +static HANDLE get_opened_printer_entry(LPWSTR name, LPPRINTER_DEFAULTSW pDefault) { UINT_PTR handle = nb_printer_handles, i; jobqueue_t *queue = NULL; @@ -1130,6 +1131,8 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul HKEY hkeyPrinter; DWORD len;
+ if ((backend == NULL) && !load_backend()) return NULL; + servername = get_servername_from_name(name); if (servername) { FIXME("server %s not supported\n", debugstr_w(servername)); @@ -1188,6 +1191,11 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul goto end; }
+ /* get a printer handle from the backend */ + if (! backend->fpOpenPrinter(name, &printer->backend_printer, pDefault)) { + handle = 0; + goto end; + }
/* clone the base name. This is NULL for the printserver */ printer->printername = strdupW(printername); @@ -2893,6 +2901,10 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter) debugstr_w(printer->pm ? printer->pm->dllname : NULL), printer->hXcv, debugstr_w(printer->name), printer->doc );
+ if (printer->backend_printer) { + backend->fpClosePrinter(printer->backend_printer); + } + if(printer->doc) EndDocPrinter(hPrinter);