-- v2: winspool: Call providor in ReadPrinter implementation. localspl: Add ReadPrinter implementation. localspl: Add support for Job handles. localspl: Rename job_t structure to job_info_t. localspl: Use separate structure to store printserver handles. localspl: Use separate structure to store XcvPort and XcvMonitor handles.
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 4b557e15a9c..2a5a453fddf 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -1573,9 +1573,10 @@ static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault)
/* clone the full name */ printer->name = wcsdup(name); - if (name && (!printer->name)) { + if (name && !printer->name) { printer_free(printer); printer = NULL; + goto end; } if (printername) { len = ARRAY_SIZE(L",XcvMonitor ") - 1;
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 2a5a453fddf..e927edb7b28 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -240,6 +240,16 @@ typedef struct { } printer_info_t;
typedef struct { + enum + { + HANDLE_SERVER, + HANDLE_PRINTER, + HANDLE_XCV, + } type; +} handle_header_t; + +typedef struct { + handle_header_t header; printer_info_t *info; LPWSTR name; monitor_t * pm; @@ -1618,6 +1628,7 @@ static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault) printer = NULL; goto end; } + printer->header.type = HANDLE_XCV; } else { @@ -1629,11 +1640,13 @@ static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault) printer = NULL; goto end; } + printer->header.type = HANDLE_PRINTER; } } else { TRACE("using the local printserver\n"); + printer->header.type = HANDLE_SERVER; }
if (pDefault && pDefault->pDevMode) @@ -2679,13 +2692,13 @@ static BOOL WINAPI fpXcvData(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus) { - printer_t *printer = (printer_t * ) hXcv; + printer_t *printer = (printer_t *)hXcv;
TRACE("(%p, %s, %p, %ld, %p, %ld, %p, %p)\n", hXcv, debugstr_w(pszDataName), pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded, pdwStatus);
- if (!printer || (!printer->hXcv)) { + if (!printer || printer->header.type != HANDLE_XCV) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } @@ -2952,7 +2965,7 @@ static BOOL WINAPI fpAddJob(HANDLE hprinter, DWORD level, BYTE *data, DWORD size
TRACE("(%p %ld %p %ld %p)\n", hprinter, level, data, size, needed);
- if (!printer || !printer->info) + if (!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; @@ -2999,7 +3012,7 @@ static DWORD WINAPI fpStartDocPrinter(HANDLE hprinter, DWORD level, BYTE *doc_in hprinter, level, doc_info, debugstr_w(info->pDocName), debugstr_w(info->pOutputFile), debugstr_w(info->pDatatype));
- if (!printer || !printer->info) + if (!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return 0; @@ -3027,7 +3040,7 @@ static BOOL WINAPI fpWritePrinter(HANDLE hprinter, void *buf, DWORD size, DWORD
TRACE("(%p, %p, %ld, %p)\n", hprinter, buf, size, written);
- if(!printer || !printer->info) + if(!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; @@ -3064,7 +3077,7 @@ static BOOL WINAPI fpSetJob(HANDLE hprinter, DWORD job_id, TRACE("(%p, %ld, %ld, %p, %ld)\n", hprinter, job_id, level, data, command); FIXME("Ignoring everything other than document title\n");
- if (!printer || !printer->info) + if (!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return 0; @@ -3141,7 +3154,7 @@ static BOOL WINAPI fpGetJob(HANDLE hprinter, DWORD job_id, DWORD level,
TRACE("%p %ld %ld %p %ld %p\n", hprinter, job_id, level, data, size, needed);
- if (!printer || !printer->info) + if (!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; @@ -3270,7 +3283,7 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id)
TRACE("%p %ld\n", hprinter, job_id);
- if (!printer || !printer->info) + if (!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; @@ -3363,7 +3376,7 @@ static BOOL WINAPI fpEndDocPrinter(HANDLE hprinter)
TRACE("%p\n", hprinter);
- if (!printer || !printer->info) + if (!printer || printer->header.type != HANDLE_PRINTER) { SetLastError(ERROR_INVALID_HANDLE); return FALSE;
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 258 +++++++++++++++++++++------------------ 1 file changed, 141 insertions(+), 117 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index e927edb7b28..f1303508d80 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -248,12 +248,16 @@ typedef struct { } type; } handle_header_t;
+typedef struct { + handle_header_t header; + monitor_t *pm; + HANDLE hxcv; +} xcv_t; + typedef struct { handle_header_t header; printer_info_t *info; LPWSTR name; - monitor_t * pm; - HANDLE hXcv; DEVMODEW *devmode; job_t *doc; } printer_t; @@ -314,6 +318,7 @@ static const DWORD di_sizeof[] = {0, sizeof(DRIVER_INFO_1W), sizeof(DRIVER_INFO_ sizeof(DRIVER_INFO_5W), sizeof(DRIVER_INFO_6W), 0, sizeof(DRIVER_INFO_8W)};
+static BOOL WINAPI fpClosePrinter(HANDLE);
/****************************************************************** * apd_copyfile [internal] @@ -1531,130 +1536,101 @@ 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) +static HANDLE xcv_alloc_handle(const WCHAR *name, PRINTER_DEFAULTSW *def, BOOL *stop_search) { - if (printer->hXcv) - { - if (printer->pm->monitor.pfnXcvClosePort) - printer->pm->monitor.pfnXcvClosePort(printer->hXcv); - } + static const WCHAR xcv_monitor[] = L"XcvMonitor "; + static const WCHAR xcv_port[] = L"XcvPort "; + BOOL mon, port; + xcv_t *xcv;
- monitor_unload(printer->pm); + *stop_search = FALSE; + if (!name || name[0] != ',') + return NULL;
- release_printer_info(printer->info); - free(printer->name); - free(printer->devmode); - free(printer); -} + name++; + while (*name == ' ') + name++;
-/****************************************************************** - * 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; - DWORD len; + mon = !wcsncmp(name, xcv_monitor, ARRAY_SIZE(xcv_monitor) - 1); + if (mon) + { + name += ARRAY_SIZE(xcv_monitor) - 1; + } + else + { + port = !wcsncmp(name, xcv_port, ARRAY_SIZE(xcv_port) - 1); + name += ARRAY_SIZE(xcv_port) - 1; + } + if (!port && !mon) + return NULL;
- if (copy_servername_from_name(name, servername)) { - FIXME("server %s not supported\n", debugstr_w(servername)); - SetLastError(ERROR_INVALID_PRINTER_NAME); + *stop_search = TRUE; + xcv = calloc(1, sizeof(*xcv)); + if (!xcv) return NULL; - } + xcv->header.type = HANDLE_XCV;
- printername = get_basename_from_name(name); - if (name != printername) TRACE("converted %s to %s\n", debugstr_w(name), debugstr_w(printername)); + if (mon) + xcv->pm = monitor_load(name, NULL); + else + xcv->pm = monitor_load_by_port(name); + if (!xcv->pm) + { + free(xcv); + SetLastError(ERROR_UNKNOWN_PORT); + return NULL; + }
- /* an empty printername is invalid */ - if (printername && (!printername[0])) { + if (xcv->pm->monitor.pfnXcvOpenPort) + { + xcv->pm->monitor.pfnXcvOpenPort(xcv->pm->hmon, name, + def ? def->DesiredAccess : 0, &xcv->hxcv); + } + if (!xcv->hxcv) + { + fpClosePrinter((HANDLE)xcv); SetLastError(ERROR_INVALID_PARAMETER); return NULL; } + return (HANDLE)xcv; +} + +static HANDLE printer_alloc_handle(const WCHAR *name, const WCHAR *basename, + PRINTER_DEFAULTSW *def) +{ + printer_t *printer;
- printer = calloc(1, sizeof(printer_t)); - if (!printer) goto end; + printer = calloc(1, sizeof(*printer)); + if (!printer) + return NULL; + printer->header.type = HANDLE_PRINTER;
/* clone the full name */ printer->name = wcsdup(name); - if (name && !printer->name) { - printer_free(printer); - printer = NULL; - goto end; - } - if (printername) { - len = ARRAY_SIZE(L",XcvMonitor ") - 1; - if (wcsncmp(printername, L",XcvMonitor ", len) == 0) { - /* OpenPrinter(",XcvMonitor ", ...) detected */ - TRACE(",XcvMonitor: %s\n", debugstr_w(&printername[len])); - printer->pm = monitor_load(&printername[len], NULL); - if (printer->pm == NULL) { - printer_free(printer); - SetLastError(ERROR_UNKNOWN_PORT); - printer = NULL; - goto end; - } - } - else - { - len = ARRAY_SIZE(L",XcvPort ") - 1; - if (wcsncmp( printername, L",XcvPort ", len) == 0) { - /* OpenPrinter(",XcvPort ", ...) detected */ - TRACE(",XcvPort: %s\n", debugstr_w(&printername[len])); - printer->pm = monitor_load_by_port(&printername[len]); - if (printer->pm == NULL) { - printer_free(printer); - SetLastError(ERROR_UNKNOWN_PORT); - printer = NULL; - goto end; - } - } - } - - if (printer->pm) { - if (printer->pm->monitor.pfnXcvOpenPort) - printer->pm->monitor.pfnXcvOpenPort(printer->pm->hmon, &printername[len], - pDefault ? pDefault->DesiredAccess : 0, - &printer->hXcv); - if (printer->hXcv == NULL) { - printer_free(printer); - SetLastError(ERROR_INVALID_PARAMETER); - printer = NULL; - goto end; - } - printer->header.type = HANDLE_XCV; - } - else - { - printer->info = get_printer_info(printername); - if (!printer->info) - { - printer_free(printer); - SetLastError(ERROR_INVALID_PRINTER_NAME); - printer = NULL; - goto end; - } - printer->header.type = HANDLE_PRINTER; - } + if (name && !printer->name) + { + fpClosePrinter((HANDLE)printer); + return NULL; } - else + + if (!basename) { TRACE("using the local printserver\n"); printer->header.type = HANDLE_SERVER; + return (HANDLE)printer; }
- if (pDefault && pDefault->pDevMode) - printer->devmode = dup_devmode(pDefault->pDevMode); + printer->info = get_printer_info(basename); + if (!printer->info) + { + fpClosePrinter((HANDLE)printer); + SetLastError(ERROR_INVALID_PRINTER_NAME); + return NULL; + }
-end: + if (def && def->pDevMode) + printer->devmode = dup_devmode(def->pDevMode);
- TRACE("==> %p\n", printer); return (HANDLE)printer; }
@@ -2643,15 +2619,39 @@ static BOOL WINAPI fpGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironmen * * */ -static BOOL WINAPI fpOpenPrinter(LPWSTR lpPrinterName, HANDLE *pPrinter, - LPPRINTER_DEFAULTSW pDefaults) +static BOOL WINAPI fpOpenPrinter(WCHAR *name, HANDLE *hprinter, + PRINTER_DEFAULTSW *def) { + WCHAR servername[MAX_COMPUTERNAME_LENGTH + 1]; + const WCHAR *basename; + BOOL stop_search;
- TRACE("(%s, %p, %p)\n", debugstr_w(lpPrinterName), pPrinter, pDefaults); + TRACE("(%s, %p, %p)\n", debugstr_w(name), hprinter, def);
- *pPrinter = printer_alloc_handle(lpPrinterName, pDefaults); + if (copy_servername_from_name(name, servername)) + { + FIXME("server %s not supported\n", debugstr_w(servername)); + SetLastError(ERROR_INVALID_PRINTER_NAME); + return FALSE; + } + + basename = get_basename_from_name(name); + if (name != basename) TRACE("converted %s to %s\n", + debugstr_w(name), debugstr_w(basename));
- return (*pPrinter != 0); + /* an empty basename is invalid */ + if (basename && (!basename[0])) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + *hprinter = xcv_alloc_handle(basename, def, &stop_search); + if (!*hprinter && !stop_search) + *hprinter = printer_alloc_handle(name, basename, def); + + TRACE("==> %p\n", *hprinter); + return *hprinter != 0; }
/****************************************************************************** @@ -2692,13 +2692,13 @@ static BOOL WINAPI fpXcvData(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus) { - printer_t *printer = (printer_t *)hXcv; + xcv_t *xcv = (xcv_t *)hXcv;
TRACE("(%p, %s, %p, %ld, %p, %ld, %p, %p)\n", hXcv, debugstr_w(pszDataName), pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded, pdwStatus);
- if (!printer || printer->header.type != HANDLE_XCV) { + if (!xcv || xcv->header.type != HANDLE_XCV) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } @@ -2715,8 +2715,8 @@ static BOOL WINAPI fpXcvData(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
*pcbOutputNeeded = 0;
- if (printer->pm->monitor.pfnXcvDataPort) - *pdwStatus = printer->pm->monitor.pfnXcvDataPort(printer->hXcv, pszDataName, + if (xcv->pm->monitor.pfnXcvDataPort) + *pdwStatus = xcv->pm->monitor.pfnXcvDataPort(xcv->hxcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
return TRUE; @@ -3410,16 +3410,40 @@ static BOOL WINAPI fpEndDocPrinter(HANDLE hprinter) */ static BOOL WINAPI fpClosePrinter(HANDLE hprinter) { - printer_t *printer = (printer_t *)hprinter; + handle_header_t *header = (handle_header_t *)hprinter;
TRACE("(%p)\n", hprinter);
- if (!printer) + if (!header) return FALSE;
- if(printer->doc) - fpEndDocPrinter(hprinter); - printer_free(printer); + if (header->type == HANDLE_XCV) + { + xcv_t *xcv = (xcv_t *)hprinter; + + if (xcv->hxcv && xcv->pm->monitor.pfnXcvClosePort) + xcv->pm->monitor.pfnXcvClosePort(xcv->hxcv); + + monitor_unload(xcv->pm); + free(xcv); + } + else if (header->type == HANDLE_SERVER || header->type == HANDLE_PRINTER) + { + printer_t *printer = (printer_t *)hprinter; + + if(printer->doc) + fpEndDocPrinter(hprinter); + + release_printer_info(printer->info); + free(printer->name); + free(printer->devmode); + free(printer); + } + else + { + ERR("invalid handle type\n"); + return FALSE; + } return TRUE; }
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 41 +++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index f1303508d80..236cf7aaf6e 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -248,6 +248,8 @@ typedef struct { } type; } handle_header_t;
+typedef handle_header_t server_t; + typedef struct { handle_header_t header; monitor_t *pm; @@ -1536,6 +1538,24 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname) return hui; }
+static HANDLE server_alloc_handle(const WCHAR *name, BOOL *stop_search) +{ + server_t *server; + + *stop_search = FALSE; + if (name) + return NULL; + + server = malloc(sizeof(*server)); + if (!server) + { + *stop_search = TRUE; + return NULL; + } + server->type = HANDLE_SERVER; + return (HANDLE)server; +} + static HANDLE xcv_alloc_handle(const WCHAR *name, PRINTER_DEFAULTSW *def, BOOL *stop_search) { static const WCHAR xcv_monitor[] = L"XcvMonitor "; @@ -1544,7 +1564,7 @@ static HANDLE xcv_alloc_handle(const WCHAR *name, PRINTER_DEFAULTSW *def, BOOL * xcv_t *xcv;
*stop_search = FALSE; - if (!name || name[0] != ',') + if (name[0] != ',') return NULL;
name++; @@ -1613,13 +1633,6 @@ static HANDLE printer_alloc_handle(const WCHAR *name, const WCHAR *basename, return NULL; }
- if (!basename) - { - TRACE("using the local printserver\n"); - printer->header.type = HANDLE_SERVER; - return (HANDLE)printer; - } - printer->info = get_printer_info(basename); if (!printer->info) { @@ -2646,7 +2659,9 @@ static BOOL WINAPI fpOpenPrinter(WCHAR *name, HANDLE *hprinter, return FALSE; }
- *hprinter = xcv_alloc_handle(basename, def, &stop_search); + *hprinter = server_alloc_handle(basename, &stop_search); + if (!*hprinter && !stop_search) + *hprinter = xcv_alloc_handle(basename, def, &stop_search); if (!*hprinter && !stop_search) *hprinter = printer_alloc_handle(name, basename, def);
@@ -3417,7 +3432,11 @@ static BOOL WINAPI fpClosePrinter(HANDLE hprinter) if (!header) return FALSE;
- if (header->type == HANDLE_XCV) + if (header->type == HANDLE_SERVER) + { + free(header); + } + else if (header->type == HANDLE_XCV) { xcv_t *xcv = (xcv_t *)hprinter;
@@ -3427,7 +3446,7 @@ static BOOL WINAPI fpClosePrinter(HANDLE hprinter) monitor_unload(xcv->pm); free(xcv); } - else if (header->type == HANDLE_SERVER || header->type == HANDLE_PRINTER) + else if (header->type == HANDLE_PRINTER) { printer_t *printer = (printer_t *)hprinter;
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 236cf7aaf6e..5b0b6b339a2 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -226,7 +226,7 @@ typedef struct { WCHAR *document_title; DEVMODEW *devmode; HANDLE hf; -} job_t; +} job_info_t;
typedef struct { WCHAR *name; @@ -261,7 +261,7 @@ typedef struct { printer_info_t *info; LPWSTR name; DEVMODEW *devmode; - job_t *doc; + job_info_t *doc; } printer_t;
/* ############################### */ @@ -542,7 +542,7 @@ static printer_info_t* get_printer_info(const WCHAR *name) return info; }
-static void free_job(job_t *job) +static void free_job(job_info_t *job) { list_remove(&job->entry); free(job->filename); @@ -569,7 +569,7 @@ static void release_printer_info(printer_info_t *info) DeleteCriticalSection(&info->jobs_cs); while (!list_empty(&info->jobs)) { - job_t *job = LIST_ENTRY(list_head(&info->jobs), job_t, entry); + job_info_t *job = LIST_ENTRY(list_head(&info->jobs), job_info_t, entry); free_job(job); } free(info); @@ -2912,11 +2912,11 @@ static size_t get_spool_filename(DWORD job_id, WCHAR *buf, size_t len) return ret; }
-static job_t* add_job(printer_t *printer, DOC_INFO_1W *info, BOOL create) +static job_info_t* add_job(printer_t *printer, DOC_INFO_1W *info, BOOL create) { DWORD job_id, last_id; size_t len; - job_t *job; + job_info_t *job;
job = calloc(1, sizeof(*job)); if (!job) @@ -2975,7 +2975,7 @@ static BOOL WINAPI fpAddJob(HANDLE hprinter, DWORD level, BYTE *data, DWORD size ADDJOB_INFO_1W *addjob = (ADDJOB_INFO_1W *)data; printer_t *printer = (printer_t *)hprinter; DOC_INFO_1W doc_info; - job_t *job; + job_info_t *job; size_t len;
TRACE("(%p %ld %p %ld %p)\n", hprinter, level, data, size, needed); @@ -3070,11 +3070,11 @@ static BOOL WINAPI fpWritePrinter(HANDLE hprinter, void *buf, DWORD size, DWORD return WriteFile(printer->doc->hf, buf, size, written, NULL); }
-static job_t * get_job(printer_info_t *info, DWORD job_id) +static job_info_t * get_job(printer_info_t *info, DWORD job_id) { - job_t *job; + job_info_t *job;
- LIST_FOR_EACH_ENTRY(job, &info->jobs, job_t, entry) + LIST_FOR_EACH_ENTRY(job, &info->jobs, job_info_t, entry) { if(job->id == job_id) return job; @@ -3087,7 +3087,7 @@ static BOOL WINAPI fpSetJob(HANDLE hprinter, DWORD job_id, { printer_t *printer = (printer_t *)hprinter; BOOL ret = FALSE; - job_t *job; + job_info_t *job;
TRACE("(%p, %ld, %ld, %p, %ld)\n", hprinter, job_id, level, data, command); FIXME("Ignoring everything other than document title\n"); @@ -3164,7 +3164,7 @@ static BOOL WINAPI fpGetJob(HANDLE hprinter, DWORD job_id, DWORD level, printer_t *printer = (printer_t *)hprinter; BOOL ret = TRUE; DWORD s = 0; - job_t *job; + job_info_t *job; WCHAR *p;
TRACE("%p %ld %ld %p %ld %p\n", hprinter, job_id, level, data, size, needed); @@ -3288,11 +3288,11 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id) const WCHAR *port_name, *port; WCHAR output[1024]; DOC_INFO_1W info; + job_info_t *job; monitor_t *mon; BYTE buf[4096]; HANDLE hport; DWORD r, w; - job_t *job; HANDLE hf; HKEY hkey;
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 135 +++++++++++++++++++++++++++++++++------ 1 file changed, 117 insertions(+), 18 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 5b0b6b339a2..4cb30afd076 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -245,6 +245,7 @@ typedef struct { HANDLE_SERVER, HANDLE_PRINTER, HANDLE_XCV, + HANDLE_JOB, } type; } handle_header_t;
@@ -256,6 +257,11 @@ typedef struct { HANDLE hxcv; } xcv_t;
+typedef struct { + handle_header_t header; + HANDLE hf; +} job_t; + typedef struct { handle_header_t header; printer_info_t *info; @@ -490,24 +496,39 @@ static void monitor_unloadall(void) LeaveCriticalSection(&monitor_handles_cs); }
-static printer_info_t* get_printer_info(const WCHAR *name) +static printer_info_t *find_printer_info(const WCHAR *name, unsigned int len) { - HKEY hkey, hprinter = NULL; printer_info_t *info; - WCHAR port[MAX_PATH]; - LSTATUS ret; - DWORD size;
EnterCriticalSection(&printers_cs); LIST_FOR_EACH_ENTRY(info, &printers, printer_info_t, entry) { - if (!wcscmp(info->name, name)) + if (!wcsncmp(info->name, name, len) && (len == -1 || !info->name[len])) { InterlockedIncrement(&info->ref); LeaveCriticalSection(&printers_cs); return info; } } + LeaveCriticalSection(&printers_cs); + return NULL; +} + +static printer_info_t* get_printer_info(const WCHAR *name) +{ + HKEY hkey, hprinter = NULL; + printer_info_t *info; + WCHAR port[MAX_PATH]; + LSTATUS ret; + DWORD size; + + EnterCriticalSection(&printers_cs); + info = find_printer_info(name, -1); + if (info) + { + LeaveCriticalSection(&printers_cs); + return info; + }
ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, printersW, &hkey); if (ret == ERROR_SUCCESS) @@ -1538,6 +1559,18 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname) return hui; }
+static job_info_t * get_job(printer_info_t *info, DWORD job_id) +{ + job_info_t *job; + + LIST_FOR_EACH_ENTRY(job, &info->jobs, job_info_t, entry) + { + if(job->id == job_id) + return job; + } + return NULL; +} + static HANDLE server_alloc_handle(const WCHAR *name, BOOL *stop_search) { server_t *server; @@ -1615,6 +1648,75 @@ static HANDLE xcv_alloc_handle(const WCHAR *name, PRINTER_DEFAULTSW *def, BOOL * return (HANDLE)xcv; }
+static HANDLE job_alloc_handle(const WCHAR *name, BOOL *stop_search) +{ + static const WCHAR jobW[] = L"Job "; + + unsigned int name_len, job_id; + printer_info_t *printer_info; + job_info_t *job_info; + job_t *job; + + *stop_search = FALSE; + name_len = 0; + for (name_len = 0; name[name_len] != ','; name_len++) + { + if (!name[name_len]) + return NULL; + } + + for (job_id = name_len + 1; name[job_id] == ' '; job_id++); + if (!name[job_id]) + return NULL; + + if (wcsncmp(name + job_id, jobW, ARRAY_SIZE(jobW) - 1)) + return NULL; + + *stop_search = TRUE; + job_id += ARRAY_SIZE(jobW) - 1; + job_id = wcstoul(name + job_id, NULL, 10); + + printer_info = find_printer_info(name, name_len); + if (!printer_info) + { + SetLastError(ERROR_INVALID_PRINTER_NAME); + return NULL; + } + + EnterCriticalSection(&printer_info->jobs_cs); + + job_info = get_job(printer_info, job_id); + if (!job_info) + { + LeaveCriticalSection(&printer_info->jobs_cs); + release_printer_info(printer_info); + SetLastError(ERROR_INVALID_PRINTER_NAME); + return NULL; + } + + job = malloc(sizeof(*job)); + if (!job) + { + LeaveCriticalSection(&printer_info->jobs_cs); + release_printer_info(printer_info); + return NULL; + } + job->header.type = HANDLE_JOB; + job->hf = CreateFileW(job_info->filename, GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + + LeaveCriticalSection(&printer_info->jobs_cs); + release_printer_info(printer_info); + + if (job->hf == INVALID_HANDLE_VALUE) + { + free(job); + return NULL; + } + return (HANDLE)job; +} + static HANDLE printer_alloc_handle(const WCHAR *name, const WCHAR *basename, PRINTER_DEFAULTSW *def) { @@ -2662,6 +2764,8 @@ static BOOL WINAPI fpOpenPrinter(WCHAR *name, HANDLE *hprinter, *hprinter = server_alloc_handle(basename, &stop_search); if (!*hprinter && !stop_search) *hprinter = xcv_alloc_handle(basename, def, &stop_search); + if (!*hprinter && !stop_search) + *hprinter = job_alloc_handle(basename, &stop_search); if (!*hprinter && !stop_search) *hprinter = printer_alloc_handle(name, basename, def);
@@ -3070,18 +3174,6 @@ static BOOL WINAPI fpWritePrinter(HANDLE hprinter, void *buf, DWORD size, DWORD return WriteFile(printer->doc->hf, buf, size, written, NULL); }
-static job_info_t * get_job(printer_info_t *info, DWORD job_id) -{ - job_info_t *job; - - LIST_FOR_EACH_ENTRY(job, &info->jobs, job_info_t, entry) - { - if(job->id == job_id) - return job; - } - return NULL; -} - static BOOL WINAPI fpSetJob(HANDLE hprinter, DWORD job_id, DWORD level, BYTE *data, DWORD command) { @@ -3446,6 +3538,13 @@ static BOOL WINAPI fpClosePrinter(HANDLE hprinter) monitor_unload(xcv->pm); free(xcv); } + else if (header->type == HANDLE_JOB) + { + job_t *job = (job_t *)hprinter; + + CloseHandle(job->hf); + free(job); + } else if (header->type == HANDLE_PRINTER) { printer_t *printer = (printer_t *)hprinter;
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 4cb30afd076..f3881ba7269 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -3476,6 +3476,21 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id) return ret; }
+static BOOL WINAPI fpReadPrinter(HANDLE hprinter, void *buf, DWORD size, DWORD *bytes_read) +{ + job_t *job = (job_t *)hprinter; + + TRACE("%p %p %lu %p\n", hprinter, buf, size, bytes_read); + + if (!job || (job->header.type != HANDLE_JOB)) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + return ReadFile(job->hf, buf, size, bytes_read, NULL); +} + static BOOL WINAPI fpEndDocPrinter(HANDLE hprinter) { printer_t *printer = (printer_t *)hprinter; @@ -3590,7 +3605,7 @@ static const PRINTPROVIDOR backend = { fpWritePrinter, NULL, /* fpEndPagePrinter */ NULL, /* fpAbortPrinter */ - NULL, /* fpReadPrinter */ + fpReadPrinter, fpEndDocPrinter, fpAddJob, fpScheduleJob,
From: Piotr Caban piotr@codeweavers.com
--- dlls/winspool.drv/info.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index 656477553ba..e58ae925c2b 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -3229,11 +3229,19 @@ BOOL WINAPI SetFormW( HANDLE printer, WCHAR *name, DWORD level, BYTE *form ) /***************************************************************************** * ReadPrinter [WINSPOOL.@] */ -BOOL WINAPI ReadPrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, - LPDWORD pNoBytesRead) +BOOL WINAPI ReadPrinter(HANDLE printer, void *buf, DWORD size, DWORD *bytes_read) { - FIXME("(%p,%p,%ld,%p): stub\n",hPrinter,pBuf,cbBuf,pNoBytesRead); - return FALSE; + HANDLE handle = get_backend_handle(printer); + + TRACE("(%p,%p,%ld,%p)\n", printer, buf, size, bytes_read); + + if (!handle) + { + SetLastError( ERROR_INVALID_HANDLE ); + return FALSE; + } + + return backend->fpReadPrinter(handle, buf, size, bytes_read); }
/*****************************************************************************
I've pushed a change to some brace placements.
This merge request was approved by Huw Davies.