mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:54:05 +00:00
winspool: Use providor for WritePrinter implementation.
This commit is contained in:
parent
e164b8cefb
commit
9c939184f3
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!printer->doc)
|
||||
{
|
||||
SetLastError(ERROR_SPL_NO_STARTDOC);
|
||||
goto end;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
Loading…
Reference in a new issue