[PATCH] localspl: Start implementation for OpenPrinter/ClosePrinter
Detlef Riekenberg
wine.dev at web.de
Fri May 1 04:59:55 CDT 2009
---
dlls/localspl/localspl_private.h | 5 +
dlls/localspl/provider.c | 216 +++++++++++++++++++++++++++++++++++++-
dlls/winspool.drv/info.c | 14 +++-
3 files changed, 232 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..945adc1 100644
--- a/dlls/localspl/provider.c
+++ b/dlls/localspl/provider.c
@@ -50,6 +50,16 @@ static CRITICAL_SECTION_DEBUG monitor_handles_cs_debug =
};
static CRITICAL_SECTION monitor_handles_cs = { &monitor_handles_cs_debug, -1, 0, 0, 0, 0 };
+
+static CRITICAL_SECTION printer_handles_cs;
+static CRITICAL_SECTION_DEBUG printer_handles_cs_debug =
+{
+ 0, 0, &printer_handles_cs,
+ { &printer_handles_cs_debug.ProcessLocksList, &printer_handles_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": printer_handles_cs") }
+};
+static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0, 0, 0, 0 };
+
/* ############################### */
typedef struct {
@@ -80,11 +90,19 @@ typedef struct {
LPCWSTR versionsubdir;
} printenv_t;
+typedef struct {
+ LPWSTR name;
+ LPWSTR printername;
+} printer_t;
+
/* ############################### */
static struct list monitor_handles = LIST_INIT( monitor_handles );
static monitor_t * pm_localport;
+static printer_t **printer_handles;
+static UINT nb_printer_handles;
+
static const PRINTPROVIDOR * pprovider = NULL;
static const WCHAR backslashW[] = {'\\',0};
@@ -274,6 +292,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 +951,102 @@ 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;
+ UINT handle = nb_printer_handles;
+ UINT i;
+
+ 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;
+ }
+
+ EnterCriticalSection(&printer_handles_cs);
+
+ for (i = 0; (handle >= nb_printer_handles) && (i < nb_printer_handles); i++) {
+ if (!printer_handles[i]) {
+ if (handle == nb_printer_handles) {
+ handle = i;
+ }
+ }
+ }
+
+ if (handle >= nb_printer_handles)
+ {
+ printer_t **new_array;
+ if (printer_handles)
+ new_array = heap_realloc_zero(printer_handles, (nb_printer_handles + 8) * sizeof(*new_array) );
+ else
+ new_array = heap_alloc_zero((nb_printer_handles + 8) * sizeof(*new_array));
+
+ if (!new_array)
+ {
+ handle = 0;
+ goto end;
+ }
+ printer_handles = new_array;
+ nb_printer_handles += 8;
+ }
+
+ printer = heap_alloc_zero(sizeof(*printer));
+ if (!printer) {
+ handle = 0;
+ 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)) {
+ handle = 0;
+ goto end;
+ }
+
+ printer_handles[handle] = printer;
+ handle++;
+end:
+ LeaveCriticalSection(&printer_handles_cs);
+ if (!handle && printer) {
+ /* Something failed: Free all resources */
+ printer_free(printer);
+ }
+ TRACE("==> %d\n", handle);
+ return (HANDLE)handle;
+}
+
+
/******************************************************************************
* myAddPrinterDriverEx [internal]
*
@@ -1213,6 +1353,43 @@ 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)
+{
+ UINT_PTR i = (UINT_PTR)hPrinter;
+ printer_t *printer = NULL;
+ BOOL ret = FALSE;
+
+ TRACE("(%p)\n", hPrinter);
+
+ EnterCriticalSection(&printer_handles_cs);
+
+ if ((i > 0) && (i <= nb_printer_handles))
+ printer = printer_handles[i - 1];
+
+ if (printer) {
+ printer_free(printer);
+ printer_handles[i - 1] = NULL;
+ ret = TRUE;
+ }
+ LeaveCriticalSection(&printer_handles_cs);
+ return ret;
+}
+
+
/******************************************************************
* fpDeleteMonitor [exported through PRINTPROVIDOR]
*
@@ -1425,13 +1602,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 +1674,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..ae7ec8f 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;
@@ -1129,6 +1130,8 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul
HKEY hkeyPrinters;
HKEY hkeyPrinter;
DWORD len;
+
+ if ((backend == NULL) && !load_backend()) return NULL;
servername = get_servername_from_name(name);
if (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);
--
1.5.4.3
--=-Do7tYLIvJA4pk6oRK4xg--
More information about the wine-patches
mailing list