From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 102 +++++++++++++++++++++++++----------- dlls/winspool.drv/info.c | 108 ++++++--------------------------------- 2 files changed, 87 insertions(+), 123 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 68ff0c23dff..4b557e15a9c 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -225,6 +225,7 @@ typedef struct { WCHAR *port; WCHAR *document_title; DEVMODEW *devmode; + HANDLE hf; } job_t;
typedef struct { @@ -531,6 +532,7 @@ static void free_job(job_t *job) free(job->port); free(job->document_title); free(job->devmode); + CloseHandle(job->hf); free(job); }
@@ -2086,32 +2088,6 @@ 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; -} - /****************************************************************************** * fpConfigurePort [exported through PRINTPROVIDOR] * @@ -2907,7 +2883,7 @@ 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) +static job_t* add_job(printer_t *printer, DOC_INFO_1W *info, BOOL create) { DWORD job_id, last_id; size_t len; @@ -2941,6 +2917,21 @@ static job_t* add_job(printer_t *printer, DOC_INFO_1W *info)
job->id = job_id; get_spool_filename(job_id, job->filename, len); + if (create) + { + job->hf = CreateFileW(job->filename, GENERIC_WRITE, FILE_SHARE_READ, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (job->hf == INVALID_HANDLE_VALUE) + { + free(job->filename); + free(job); + return NULL; + } + } + else + { + job->hf = NULL; + } job->document_title = wcsdup(info->pDocName); job->devmode = dup_devmode(printer->devmode);
@@ -2988,7 +2979,7 @@ static BOOL WINAPI fpAddJob(HANDLE hprinter, DWORD level, BYTE *data, DWORD size
memset(&doc_info, 0, sizeof(doc_info)); doc_info.pDocName = (WCHAR *)L"Local Downlevel Document"; - job = add_job(printer, &doc_info); + job = add_job(printer, &doc_info, FALSE); if (!job) return FALSE;
@@ -3025,10 +3016,31 @@ static DWORD WINAPI fpStartDocPrinter(HANDLE hprinter, DWORD level, BYTE *doc_in return 0; }
- printer->doc = add_job(printer, info); + printer->doc = add_job(printer, info, TRUE); return printer->doc ? printer->doc->id : 0; }
+static BOOL WINAPI fpWritePrinter(HANDLE hprinter, void *buf, DWORD size, DWORD *written) +{ + printer_t *printer = (printer_t *)hprinter; + + TRACE("(%p, %p, %ld, %p)\n", hprinter, buf, size, written); + + if(!printer || !printer->info) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if(!printer->doc) + { + SetLastError(ERROR_SPL_NO_STARTDOC); + return FALSE; + } + + return WriteFile(printer->doc->hf, buf, size, written, NULL); +} + static job_t * get_job(printer_info_t *info, DWORD job_id) { job_t *job; @@ -3362,11 +3374,41 @@ static BOOL WINAPI fpEndDocPrinter(HANDLE hprinter) return FALSE; }
+ CloseHandle(printer->doc->hf); + printer->doc->hf = NULL; ret = fpScheduleJob(hprinter, printer->doc->id); printer->doc = NULL; return ret; }
+/****************************************************************************** + * 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) + return FALSE; + + if(printer->doc) + fpEndDocPrinter(hprinter); + printer_free(printer); + return TRUE; +} + static const PRINTPROVIDOR backend = { fpOpenPrinter, fpSetJob, @@ -3389,7 +3431,7 @@ static const PRINTPROVIDOR backend = { NULL, /* fpEnumPrintProcessorDatatypes */ fpStartDocPrinter, NULL, /* fpStartPagePrinter */ - NULL, /* fpWritePrinter */ + fpWritePrinter, NULL, /* fpEndPagePrinter */ NULL, /* fpAbortPrinter */ NULL, /* fpReadPrinter */ diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c index cfdf66f4d21..656477553ba 100644 --- a/dlls/winspool.drv/info.c +++ b/dlls/winspool.drv/info.c @@ -70,15 +70,9 @@ static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0,
/* ############################### */
-typedef struct { - DWORD job_id; - HANDLE hf; -} started_doc_t; - typedef struct { LPWSTR name; HANDLE backend_printer; - started_doc_t *doc; } opened_printer_t;
typedef struct { @@ -2336,31 +2330,19 @@ BOOL WINAPI DeletePortW (LPWSTR pName, HWND hWnd, LPWSTR pPortName) /****************************************************************************** * WritePrinter [WINSPOOL.@] */ -BOOL WINAPI WritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten) +BOOL WINAPI WritePrinter(HANDLE printer, void *buf, DWORD size, DWORD *written) { - opened_printer_t *printer; - BOOL ret = FALSE; + HANDLE handle = get_backend_handle(printer);
- TRACE("(%p, %p, %ld, %p)\n", hPrinter, pBuf, cbBuf, pcWritten); + TRACE("(%p, %p, %ld, %p)\n", printer, buf, size, written);
- EnterCriticalSection(&printer_handles_cs); - printer = get_opened_printer(hPrinter); - if(!printer) + if (!handle) { SetLastError(ERROR_INVALID_HANDLE); - goto end; - } - - if(!printer->doc) - { - SetLastError(ERROR_SPL_NO_STARTDOC); - goto end; + return FALSE; }
- ret = WriteFile(printer->doc->hf, pBuf, cbBuf, pcWritten, NULL); -end: - LeaveCriticalSection(&printer_handles_cs); - return ret; + return backend->fpWritePrinter(handle, buf, size, written); }
/***************************************************************************** @@ -2768,11 +2750,7 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter)
if(printer) { - TRACE("closing %s (doc: %p)\n", debugstr_w(printer->name), printer->doc); - - if(printer->doc) - EndDocPrinter(hPrinter); - + TRACE("closing %s\n", debugstr_w(printer->name)); if (printer->backend_printer) { backend->fpClosePrinter(printer->backend_printer); } @@ -3088,29 +3066,19 @@ BOOL WINAPI SetJobW(HANDLE printer, DWORD job_id, DWORD level, /***************************************************************************** * EndDocPrinter [WINSPOOL.@] */ -BOOL WINAPI EndDocPrinter(HANDLE hprinter) +BOOL WINAPI EndDocPrinter(HANDLE printer) { - opened_printer_t *printer = get_opened_printer(hprinter); + HANDLE handle = get_backend_handle(printer);
TRACE("(%p)\n", printer);
- if (!printer || !printer->backend_printer) + if (!handle) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; }
- if (!printer->doc) - { - SetLastError(ERROR_SPL_NO_STARTDOC); - return FALSE; - } - - CloseHandle(printer->doc->hf); - free(printer->doc); - printer->doc = NULL; - - return backend->fpEndDocPrinter(printer->backend_printer); + return backend->fpEndDocPrinter(handle); }
/***************************************************************************** @@ -3162,71 +3130,25 @@ DWORD WINAPI StartDocPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo) return ret; }
-static size_t get_spool_filename(DWORD job_id, WCHAR *buf, size_t len) -{ - static const WCHAR spool_path[] = L"spool\PRINTERS\"; - size_t ret; - - ret = GetSystemDirectoryW(NULL, 0) + ARRAY_SIZE(spool_path) + 10; - if (len < ret) - return ret; - - ret = GetSystemDirectoryW(buf, ret); - if (buf[ret - 1] != '\') - buf[ret++] = '\'; - memcpy(buf + ret, spool_path, sizeof(spool_path)); - ret += ARRAY_SIZE(spool_path) - 1; - swprintf(buf + ret, 10, L"%05d.SPL", job_id); - ret += 10; - return ret; -} - /***************************************************************************** * StartDocPrinterW [WINSPOOL.@] */ -DWORD WINAPI StartDocPrinterW(HANDLE hprinter, DWORD level, BYTE *doc_info) +DWORD WINAPI StartDocPrinterW(HANDLE printer, DWORD level, BYTE *doc_info) { - opened_printer_t *printer = get_opened_printer(hprinter); + HANDLE handle = get_backend_handle(printer); DOC_INFO_1W *info = (DOC_INFO_1W *)doc_info; - WCHAR filename[MAX_PATH]; - HANDLE handle; - DWORD job_id; - HANDLE hf;
TRACE("(%p, %ld, %p {%s, %s, %s})\n", printer, level, doc_info, debugstr_w(info->pDocName), debugstr_w(info->pOutputFile), debugstr_w(info->pDatatype));
- if (!printer || !printer->backend_printer) + if (!handle) { SetLastError(ERROR_INVALID_HANDLE); return 0; } - handle = printer->backend_printer; - - job_id = backend->fpStartDocPrinter(handle, level, doc_info); - if (!job_id) - return 0; - - /* TODO: remove when WritePrinter is implemented in providor */ - if (get_spool_filename(job_id, filename, ARRAY_SIZE(filename)) > ARRAY_SIZE(filename)) - { - backend->fpEndDocPrinter(handle); - SetLastError(ERROR_INTERNAL_ERROR); - return 0; - } - hf = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hf == INVALID_HANDLE_VALUE) - { - backend->fpEndDocPrinter(handle); - return 0; - }
- printer->doc = malloc(sizeof(*printer->doc)); - printer->doc->job_id = job_id; - printer->doc->hf = hf; - return job_id; + return backend->fpStartDocPrinter(handle, level, doc_info); }
/*****************************************************************************