winspool: document spooling functions
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Fri Jul 8 07:46:58 CDT 2005
Huw Davies <huw at codeweavers.com>
Implement {Start,End}DocPrinter and WritePrinter.
{Start,End}PagePrinter are still stubs but return TRUE.
--
Huw Davies
huw at codeweavers.com
Index: dlls/winspool/info.c
===================================================================
RCS file: /home/wine/wine/dlls/winspool/info.c,v
retrieving revision 1.111
diff -u -p -r1.111 info.c
--- dlls/winspool/info.c 6 Jul 2005 15:44:15 -0000 1.111
+++ dlls/winspool/info.c 8 Jul 2005 12:40:23 -0000
@@ -68,8 +68,14 @@ static CRITICAL_SECTION_DEBUG printer_ha
static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0, 0, 0, 0 };
typedef struct {
+ DWORD job_id;
+ HANDLE hf;
+} started_doc_t;
+
+typedef struct {
LPWSTR name;
struct list jobs;
+ started_doc_t *doc;
} opened_printer_t;
typedef struct {
@@ -610,6 +616,7 @@ static HANDLE get_opened_printer_entry(
printer->name = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(WCHAR));
strcpyW(printer->name, name);
list_init(&printer->jobs);
+ printer->doc = NULL;
printer_handles[handle] = printer;
handle++;
@@ -1157,16 +1164,31 @@ SetPrinterW(
/******************************************************************************
* WritePrinter [WINSPOOL.@]
*/
-BOOL WINAPI
-WritePrinter(
- HANDLE hPrinter,
- LPVOID pBuf,
- DWORD cbBuf,
- LPDWORD pcWritten) {
+BOOL WINAPI WritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten)
+{
+ opened_printer_t *printer;
+ BOOL ret = FALSE;
- FIXME("():stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ TRACE("(%p, %p, %ld, %p)\n", hPrinter, pBuf, cbBuf, pcWritten);
+
+ EnterCriticalSection(&printer_handles_cs);
+ printer = get_opened_printer(hPrinter);
+ if(!printer)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ goto end;
+ }
+
+ 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;
}
/*****************************************************************************
@@ -1577,6 +1599,10 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter
if(printer)
{
struct list *cursor, *cursor2;
+
+ if(printer->doc)
+ EndDocPrinter(hPrinter);
+
LIST_FOR_EACH_SAFE(cursor, cursor2, &printer->jobs)
{
job_t *job = LIST_ENTRY(cursor, job_t, entry);
@@ -1721,8 +1747,33 @@ BOOL WINAPI SetJobW(HANDLE hPrinter, DWO
*/
BOOL WINAPI EndDocPrinter(HANDLE hPrinter)
{
- FIXME("(hPrinter=%p): stub\n", hPrinter);
- return FALSE;
+ opened_printer_t *printer;
+ BOOL ret = FALSE;
+ TRACE("(%p)\n", hPrinter);
+
+ EnterCriticalSection(&printer_handles_cs);
+
+ printer = get_opened_printer(hPrinter);
+ if(!printer)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ goto end;
+ }
+
+ if(!printer->doc)
+ {
+ SetLastError(ERROR_SPL_NO_STARTDOC);
+ goto end;
+ }
+
+ CloseHandle(printer->doc->hf);
+ ScheduleJob(hPrinter, printer->doc->job_id);
+ HeapFree(GetProcessHeap(), 0, printer->doc);
+ printer->doc = NULL;
+ ret = TRUE;
+end:
+ LeaveCriticalSection(&printer_handles_cs);
+ return ret;
}
/*****************************************************************************
@@ -1730,8 +1781,8 @@ BOOL WINAPI EndDocPrinter(HANDLE hPrinte
*/
BOOL WINAPI EndPagePrinter(HANDLE hPrinter)
{
- FIXME("(hPrinter=%p): stub\n", hPrinter);
- return FALSE;
+ FIXME("(%p): stub\n", hPrinter);
+ return TRUE;
}
/*****************************************************************************
@@ -1780,11 +1831,64 @@ DWORD WINAPI StartDocPrinterA(HANDLE hPr
DWORD WINAPI StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
{
DOC_INFO_2W *doc = (DOC_INFO_2W *)pDocInfo;
+ opened_printer_t *printer;
+ BYTE addjob_buf[MAX_PATH * sizeof(WCHAR) + sizeof(ADDJOB_INFO_1W)];
+ ADDJOB_INFO_1W *addjob = (ADDJOB_INFO_1W*) addjob_buf;
+ DWORD needed, ret = 0;
+ HANDLE hf;
+ WCHAR *filename;
- FIXME("(hPrinter = %p, Level = %ld, pDocInfo = %p {pDocName = %s, pOutputFile = %s, pDatatype = %s}): stub\n",
+ TRACE("(hPrinter = %p, Level = %ld, pDocInfo = %p {pDocName = %s, pOutputFile = %s, pDatatype = %s}):\n",
hPrinter, Level, doc, debugstr_w(doc->pDocName), debugstr_w(doc->pOutputFile),
debugstr_w(doc->pDatatype));
- return FALSE;
+
+ if(Level < 1 || Level > 3)
+ {
+ SetLastError(ERROR_INVALID_LEVEL);
+ return 0;
+ }
+
+ EnterCriticalSection(&printer_handles_cs);
+ printer = get_opened_printer(hPrinter);
+ if(!printer)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ goto end;
+ }
+
+ if(printer->doc)
+ {
+ SetLastError(ERROR_INVALID_PRINTER_STATE);
+ goto end;
+ }
+
+ /* Even if we're printing to a file we still add a print job, we'll
+ just ignore the spool file name */
+
+ if(!AddJobW(hPrinter, 1, addjob_buf, sizeof(addjob_buf), &needed))
+ {
+ ERR("AddJob failed gle %08lx\n", GetLastError());
+ goto end;
+ }
+
+ if(doc->pOutputFile)
+ filename = doc->pOutputFile;
+ else
+ filename = addjob->Path;
+
+ hf = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if(hf == INVALID_HANDLE_VALUE)
+ goto end;
+
+ /* FIXME should set doc title with SetJob */
+
+ printer->doc = HeapAlloc(GetProcessHeap(), 0, sizeof(*printer->doc));
+ printer->doc->hf = hf;
+ ret = printer->doc->job_id = addjob->JobId;
+end:
+ LeaveCriticalSection(&printer_handles_cs);
+
+ return ret;
}
/*****************************************************************************
@@ -1792,8 +1896,8 @@ DWORD WINAPI StartDocPrinterW(HANDLE hPr
*/
BOOL WINAPI StartPagePrinter(HANDLE hPrinter)
{
- FIXME("(hPrinter=%p): stub\n", hPrinter);
- return FALSE;
+ FIXME("(%p): stub\n", hPrinter);
+ return TRUE;
}
/*****************************************************************************
More information about the wine-patches
mailing list