1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * PURPOSE: GDI Printing Support
5 * FILE: dll/win32/gdi32/objects/printdrv.c
6 * PROGRAMER:
7 *
8 */
9
10 // For the wine code:
11 /*
12 * Implementation of some printer driver bits
13 *
14 * Copyright 1996 John Harvey
15 * Copyright 1998 Huw Davies
16 * Copyright 1998 Andreas Mohr
17 * Copyright 1999 Klaas van Gend
18 *
19 * This library is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public
21 * License as published by the Free Software Foundation; either
22 * version 2.1 of the License, or (at your option) any later version.
23 *
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 */
33
34 #include <precomp.h>
35
36 #define NDEBUG
37 #include <debug.h>
38
39 /* GLOBALS *******************************************************************/
40 HANDLE ghSpooler = NULL;
41
42 static ABORTPRINTER fpAbortPrinter;
43 CLOSEPRINTER fpClosePrinter;
44 static CLOSESPOOLFILEHANDLE fpCloseSpoolFileHandle;
45 static COMMITSPOOLDATA fpCommitSpoolData;
46 //static fpConnectToLd64In32Server;
47 static DOCUMENTEVENT fpDocumentEvent;
48 static DOCUMENTPROPERTIESW fpDocumentPropertiesW;
49 static ENDDOCPRINTER fpEndDocPrinter;
50 static ENDPAGEPRINTER fpEndPagePrinter;
51 static GETSPOOLFILEHANDLE fpGetSpoolFileHandle;
52 static GETPRINTERW fpGetPrinterW;
53 static GETPRINTERDRIVERW fpGetPrinterDriverW;
54 static ISVALIDDEVMODEW fpIsValidDevmodeW;
55 OPENPRINTERW fpOpenPrinterW;
56 static QUERYSPOOLMODE fpQuerySpoolMode;
57 static QUERYREMOTEFONTS fpQueryRemoteFonts;
58 static QUERYCOLORPROFILE fpQueryColorProfile;
59 static READPRINTER fpReadPrinter;
60 static RESETPRINTERW fpResetPrinterW;
61 static SEEKPRINTER fpSeekPrinter;
62 static SPLDRIVERUNLOADCOMPLETE fpSplDriverUnloadComplete;
63 static SPLREADPRINTER fpSplReadPrinter;
64 static STARTDOCDLGW fpStartDocDlgW;
65 static STARTDOCPRINTERW fpStartDocPrinterW;
66 static STARTPAGEPRINTER fpStartPagePrinter;
67
68 /* PRIVATE FUNCTIONS *********************************************************/
69
70 static
71 int
72 FASTCALL
IntEndPage(HDC hdc,BOOL Form)73 IntEndPage(
74 HDC hdc,
75 BOOL Form
76 )
77 {
78 PLDC pldc;
79 int Ret = SP_ERROR;
80 ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
81
82 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
83 {
84 SetLastError(ERROR_INVALID_HANDLE);
85 return SP_ERROR;
86 }
87
88 pldc = GdiGetLDC(hdc);
89 if ( !pldc )
90 {
91 SetLastError(ERROR_INVALID_HANDLE);
92 return SP_ERROR;
93 }
94
95 if (pldc->Flags & LDC_ATENDPAGE) return 1;
96
97 if (pldc->Flags & LDC_META_PRINT)
98 {
99 if ( Form )
100 {
101 // Do MF EndPageForm
102 }
103 else
104 {
105 // Do MF EndPage
106 }
107 return Ret;
108 }
109
110 if (pldc->Flags & LDC_KILL_DOCUMENT || pldc->Flags & LDC_INIT_PAGE)
111 {
112 SetLastError(ERROR_INVALID_PARAMETER);
113 return SP_ERROR;
114 }
115
116 if (pldc->Flags & LDC_SAPCALLBACK) GdiSAPCallback(pldc);
117
118 pldc->Flags &= ~LDC_INIT_PAGE;
119
120 DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDPAGE, 0, NULL, 0, NULL);
121
122 ((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->cSpins = 0;
123
124 if ( NtGdiEndPage(hdc) )
125 {
126 BOOL Good;
127 // if (pldc->pUMPDev)
128 Good = EndPagePrinterEx(NULL,pldc->hPrinter);
129
130 if (Good) pldc->Flags |= LDC_STARTPAGE;
131 Ret = 1;
132 }
133 else
134 SetLastError(ERROR_INVALID_PARAMETER);
135 return Ret;
136 }
137
138 /* FUNCTIONS *****************************************************************/
139
140 BOOL
141 FASTCALL
AbortPrinterEx(PVOID pvUMPDev,HANDLE hPrinter)142 AbortPrinterEx(
143 PVOID pvUMPDev,
144 HANDLE hPrinter
145 )
146 {
147 return fpAbortPrinter(hPrinter);
148 }
149
150 int
151 FASTCALL
DocumentEventEx(PVOID pvUMPDev,HANDLE hPrinter,HDC hdc,int iEsc,ULONG cbIn,PVOID pvIn,ULONG cbOut,PVOID pvOut)152 DocumentEventEx(
153 PVOID pvUMPDev,
154 HANDLE hPrinter,
155 HDC hdc,
156 int iEsc,
157 ULONG cbIn,
158 PVOID pvIn,
159 ULONG cbOut,
160 PVOID pvOut
161 )
162 {
163 return fpDocumentEvent(hPrinter,hdc,iEsc,cbIn,pvIn,cbOut,pvOut);
164 }
165
166 BOOL
167 FASTCALL
EndDocPrinterEx(PVOID pvUMPDev,HANDLE hPrinter)168 EndDocPrinterEx(
169 PVOID pvUMPDev,
170 HANDLE hPrinter
171 )
172 {
173 return fpEndDocPrinter(hPrinter);
174 }
175
176 BOOL
177 FASTCALL
EndPagePrinterEx(PVOID pvUMPDev,HANDLE hPrinter)178 EndPagePrinterEx(
179 PVOID pvUMPDev,
180 HANDLE hPrinter
181 )
182 {
183 return fpEndPagePrinter(hPrinter);
184 }
185
186 BOOL
187 FASTCALL
LoadTheSpoolerDrv(VOID)188 LoadTheSpoolerDrv(VOID)
189 {
190 HMODULE hModWinSpoolDrv;
191
192 if ( !ghSpooler )
193 {
194 RtlEnterCriticalSection(&semLocal);
195
196 hModWinSpoolDrv = LoadLibraryW(L"WINSPOOL.DRV");
197
198 if (hModWinSpoolDrv)
199 {
200 fpAbortPrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "AbortPrinter");
201 fpClosePrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "ClosePrinter");
202 fpCloseSpoolFileHandle = (PVOID)GetProcAddress(hModWinSpoolDrv, "CloseSpoolFileHandle");
203 fpCommitSpoolData = (PVOID)GetProcAddress(hModWinSpoolDrv, "CommitSpoolData");
204 // fpConnectToLd64In32Server = (PVOID)GetProcAddress(hModWinSpoolDrv, (LPCSTR)224);
205 fpDocumentEvent = (PVOID)GetProcAddress(hModWinSpoolDrv,"DocumentEvent");
206 fpDocumentPropertiesW = (PVOID)GetProcAddress(hModWinSpoolDrv, "DocumentPropertiesW");
207 fpEndDocPrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "EndDocPrinter");
208 fpEndPagePrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "EndPagePrinter");
209 fpGetPrinterW = (PVOID)GetProcAddress( hModWinSpoolDrv,"GetPrinterW");
210 fpGetPrinterDriverW = (PVOID)GetProcAddress(hModWinSpoolDrv,"GetPrinterDriverW");
211 fpGetSpoolFileHandle = (PVOID)GetProcAddress(hModWinSpoolDrv, "GetSpoolFileHandle");
212 fpIsValidDevmodeW = (PVOID)GetProcAddress(hModWinSpoolDrv, "IsValidDevmodeW");
213 fpOpenPrinterW = (PVOID)GetProcAddress(hModWinSpoolDrv, "OpenPrinterW");
214 fpQueryColorProfile = (PVOID)GetProcAddress(hModWinSpoolDrv,"QueryColorProfile");
215 fpQueryRemoteFonts = (PVOID)GetProcAddress(hModWinSpoolDrv, "QueryRemoteFonts");
216 fpQuerySpoolMode = (PVOID)GetProcAddress(hModWinSpoolDrv, "QuerySpoolMode");
217 fpReadPrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "ReadPrinter");
218 fpResetPrinterW = (PVOID)GetProcAddress(hModWinSpoolDrv, "ResetPrinterW");
219 fpSeekPrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "SeekPrinter");
220 fpSplDriverUnloadComplete = (PVOID)GetProcAddress(hModWinSpoolDrv, "SplDriverUnloadComplete");
221 fpSplReadPrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, (LPCSTR)205);
222 fpStartDocDlgW = (PVOID)GetProcAddress(hModWinSpoolDrv, "StartDocDlgW");
223 fpStartDocPrinterW = (PVOID)GetProcAddress(hModWinSpoolDrv, "StartDocPrinterW");
224 fpStartPagePrinter = (PVOID)GetProcAddress(hModWinSpoolDrv, "StartPagePrinter");
225
226 if ( !fpAbortPrinter ||
227 !fpClosePrinter ||
228 !fpCloseSpoolFileHandle ||
229 !fpCommitSpoolData ||
230 !fpDocumentEvent ||
231 !fpDocumentPropertiesW ||
232 !fpEndDocPrinter ||
233 !fpEndPagePrinter ||
234 !fpGetPrinterW ||
235 !fpGetPrinterDriverW ||
236 !fpGetSpoolFileHandle ||
237 !fpIsValidDevmodeW ||
238 !fpOpenPrinterW ||
239 !fpQueryColorProfile ||
240 !fpQueryRemoteFonts ||
241 !fpQuerySpoolMode ||
242 !fpReadPrinter ||
243 !fpResetPrinterW ||
244 !fpSeekPrinter ||
245 !fpSplDriverUnloadComplete ||
246 !fpSplReadPrinter ||
247 !fpStartDocDlgW ||
248 !fpStartDocPrinterW ||
249 !fpStartPagePrinter )
250 {
251 FreeLibrary(hModWinSpoolDrv);
252 hModWinSpoolDrv = NULL;
253 }
254 ghSpooler = hModWinSpoolDrv;
255 }
256 RtlLeaveCriticalSection(&semLocal);
257 }
258 else
259 return TRUE;
260
261 if ( !ghSpooler ) SetLastError(ERROR_NOT_ENOUGH_MEMORY);
262
263 return (ghSpooler != NULL);
264 }
265
266 /*
267 Note from msdn:
268
269 The sequence for a print job is as follows:
270
271 1. To begin a print job, call StartDocPrinter.
272 2. To begin each page, call StartPagePrinter.
273 3. To write data to a page, call WritePrinter.
274 4. To end each page, call EndPagePrinter.
275 5. Repeat 2, 3, and 4 for as many pages as necessary.
276 6. To end the print job, call EndDocPrinter.
277
278 */
279 DWORD
280 FASTCALL
StartDocPrinterWEx(PVOID pvUMPDev,HANDLE hPrinter,DWORD Level,LPBYTE pDocInfo)281 StartDocPrinterWEx(
282 PVOID pvUMPDev,
283 HANDLE hPrinter,
284 DWORD Level,
285 LPBYTE pDocInfo
286 )
287 {
288 return fpStartDocPrinterW(hPrinter,Level,pDocInfo);
289 }
290
291 BOOL
292 FASTCALL
StartPagePrinterEx(PVOID pvUMPDev,HANDLE hPrinter)293 StartPagePrinterEx(
294 PVOID pvUMPDev,
295 HANDLE hPrinter
296 )
297 {
298 return fpStartPagePrinter(hPrinter);
299 }
300
301 /* SYSCALLS ******************************************************************/
302
303 /*
304 * @unimplemented
305 */
306 int
307 WINAPI
AbortDoc(HDC hdc)308 AbortDoc(
309 HDC hdc
310 )
311 {
312 PLDC pldc;
313 int Ret = SP_ERROR;
314 ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
315
316 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
317 {
318 SetLastError(ERROR_INVALID_HANDLE);
319 return SP_ERROR;
320 }
321
322 pldc = GdiGetLDC(hdc);
323 if ( !pldc )
324 {
325 SetLastError(ERROR_INVALID_HANDLE);
326 return SP_ERROR;
327 }
328
329 if ( !(pldc->Flags & LDC_INIT_DOCUMENT) ) return 1;
330
331 DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ABORTDOC, 0, NULL, 0, NULL);
332
333 ((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->cSpins = 0;
334
335 if ( pldc->Flags & LDC_META_PRINT)
336 {
337 UNIMPLEMENTED;
338 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
339 return Ret;
340 }
341
342 if (NtGdiAbortDoc(hdc))
343 {
344 if (fpAbortPrinter(pldc->hPrinter)) Ret = 1;
345 }
346 else
347 Ret = SP_ERROR;
348
349 pldc->Flags &= ~(LDC_ATENDPAGE|LDC_META_PRINT|LDC_STARTPAGE|LDC_INIT_PAGE|LDC_INIT_DOCUMENT|LDC_SAPCALLBACK);
350
351 return Ret;
352 }
353
354 /*
355 * @unimplemented
356 */
357 int
358 WINAPI
EndDoc(HDC hdc)359 EndDoc(
360 HDC hdc
361 )
362 {
363 PLDC pldc;
364 int Ret = SP_ERROR;
365 ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
366
367 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
368 {
369 SetLastError(ERROR_INVALID_HANDLE);
370 return SP_ERROR;
371 }
372
373 pldc = GdiGetLDC(hdc);
374 if ( !pldc )
375 {
376 SetLastError(ERROR_INVALID_HANDLE);
377 return SP_ERROR;
378 }
379
380 if (pldc->Flags & LDC_META_PRINT)
381 {
382 UNIMPLEMENTED;
383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
384 return Ret;
385 }
386
387 if (pldc->Flags & LDC_INIT_DOCUMENT)
388 {
389 BOOL Good;
390 if (pldc->Flags & LDC_INIT_PAGE) EndPage(hdc);
391
392 DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDDOC, 0, NULL, 0, NULL);
393
394 ((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->cSpins = 0;
395
396 Good = NtGdiEndDoc(hdc);
397
398 // if (pldc->pUMPDev)
399 Good = EndDocPrinterEx(NULL,pldc->hPrinter);
400
401 if (Good)
402 {
403 DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDDOCPOST, 0, NULL, 0, NULL);
404 Ret = 1;
405 }
406 pldc->Flags &= ~(LDC_ATENDPAGE|LDC_STARTPAGE|LDC_INIT_DOCUMENT|LDC_SAPCALLBACK);
407 }
408 return Ret;
409 }
410
411 /*
412 * @implemented
413 */
414 int
415 WINAPI
EndFormPage(HDC hdc)416 EndFormPage(HDC hdc)
417 {
418 return IntEndPage(hdc,TRUE);
419 }
420
421 /*
422 * @implemented
423 */
424 int
425 WINAPI
EndPage(HDC hdc)426 EndPage(HDC hdc )
427 {
428 return IntEndPage(hdc,FALSE);
429 }
430
431 /*
432 * @unimplemented
433 */
434 HANDLE
435 WINAPI
GdiGetSpoolFileHandle(LPWSTR pwszPrinterName,LPDEVMODEW pDevmode,LPWSTR pwszDocName)436 GdiGetSpoolFileHandle(LPWSTR pwszPrinterName,
437 LPDEVMODEW pDevmode,
438 LPWSTR pwszDocName)
439 {
440 UNIMPLEMENTED;
441 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
442 return 0;
443 }
444
445 /*
446 * @unimplemented
447 */
448 BOOL
449 WINAPI
GdiDeleteSpoolFileHandle(HANDLE SpoolFileHandle)450 GdiDeleteSpoolFileHandle(HANDLE SpoolFileHandle)
451 {
452 UNIMPLEMENTED;
453 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
454 return 0;
455 }
456
457 /*
458 * @unimplemented
459 */
460 DWORD
461 WINAPI
GdiGetPageCount(HANDLE SpoolFileHandle)462 GdiGetPageCount(HANDLE SpoolFileHandle)
463 {
464 UNIMPLEMENTED;
465 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
466 return 0;
467 }
468
469 /*
470 * @unimplemented
471 */
472 int
473 WINAPI
StartDocW(HDC hdc,CONST DOCINFOW * lpdi)474 StartDocW(
475 HDC hdc,
476 CONST DOCINFOW *lpdi
477 )
478 {
479 PLDC pldc;
480 DOCINFOW diW;
481 DOC_INFO_1W di1W;
482 LPWSTR lpwstrRet = NULL;
483 BOOL Banding;
484 int PrnJobNo, Ret = SP_ERROR;
485 ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
486
487 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
488 return SP_ERROR;
489
490 pldc = GdiGetLDC(hdc);
491 if ( !pldc || pldc->Flags & LDC_ATENDPAGE)
492 {
493 SetLastError(ERROR_INVALID_HANDLE);
494 return SP_ERROR;
495 }
496
497 if (!pldc->hPrinter) return SP_ERROR;
498
499 pldc->Flags &= ~LDC_KILL_DOCUMENT;
500
501 if (lpdi)
502 RtlCopyMemory(&diW, lpdi, sizeof(DOCINFOW));
503 else
504 {
505 diW.cbSize = sizeof(DOCINFOW);
506 diW.lpszDocName = NULL;
507 diW.lpszOutput = NULL;
508 diW.lpszDatatype = NULL;
509 diW.fwType = 0;
510 }
511
512 if (!diW.lpszOutput)
513 if (pldc->pwszPort) diW.lpszOutput = pldc->pwszPort;
514
515 lpwstrRet = fpStartDocDlgW(pldc->hPrinter, &diW);
516 if (lpwstrRet == (LPWSTR)SP_APPABORT)
517 {
518 pldc->Flags |= LDC_KILL_DOCUMENT;
519 return SP_ERROR;
520 }
521 if (lpwstrRet == (LPWSTR)SP_ERROR) return SP_ERROR;
522
523 if (lpwstrRet != 0) diW.lpszOutput = lpwstrRet;
524
525 Ret = DocumentEventEx( NULL,
526 pldc->hPrinter,
527 hdc,
528 DOCUMENTEVENT_STARTDOC,
529 sizeof(ULONG),
530 &diW,
531 0,
532 NULL);
533
534 if (Ret == SP_APPABORT)
535 {
536 pldc->Flags |= LDC_KILL_DOCUMENT;
537 Ret = SP_ERROR;
538 }
539 if (Ret == SP_ERROR)
540 {
541 if (lpwstrRet) LocalFree(lpwstrRet);
542 return Ret;
543 }
544
545 di1W.pDocName = (LPWSTR)diW.lpszDocName;
546 di1W.pOutputFile = (LPWSTR)diW.lpszOutput;
547 di1W.pDatatype = (LPWSTR)diW.lpszDatatype;
548
549 Ret = SP_ERROR;
550
551 PrnJobNo = StartDocPrinterWEx(NULL, pldc->hPrinter, 1, (LPBYTE)&di1W);
552 if (PrnJobNo <= 0)
553 {
554 Ret = NtGdiStartDoc( hdc, &diW, &Banding, PrnJobNo);
555 if (Ret)
556 {
557 if (pldc->pAbortProc)
558 {
559 GdiSAPCallback(pldc);
560 pldc->Flags |= LDC_SAPCALLBACK;
561 pldc->CallBackTick = GetTickCount();
562 }
563 pldc->Flags |= LDC_INIT_DOCUMENT;
564 if (!Banding) pldc->Flags |= LDC_STARTPAGE;
565 }
566 }
567 if (Ret == SP_ERROR)
568 {
569 //if ( pldc->pUMPDev )
570 AbortPrinterEx(NULL, pldc->hPrinter);
571 DPRINT1("StartDoc Died!!!\n");
572 }
573 else
574 {
575 if ( DocumentEventEx( NULL,
576 pldc->hPrinter,
577 hdc,
578 DOCUMENTEVENT_STARTDOCPOST,
579 sizeof(ULONG),
580 &Ret,
581 0,
582 NULL) == SP_ERROR)
583 {
584 AbortDoc(hdc);
585 Ret = SP_ERROR;
586 }
587 }
588 if (lpwstrRet) LocalFree(lpwstrRet);
589 return Ret;
590 }
591
592 /*
593 * @implemented
594 */
595 int
596 WINAPI
StartDocA(HDC hdc,CONST DOCINFOA * lpdi)597 StartDocA(
598 HDC hdc,
599 CONST DOCINFOA *lpdi
600 )
601 {
602 LPWSTR szDocName = NULL, szOutput = NULL, szDatatype = NULL;
603 DOCINFOW docW;
604 INT ret, len;
605
606 docW.cbSize = lpdi->cbSize;
607 if (lpdi->lpszDocName)
608 {
609 len = MultiByteToWideChar(CP_ACP,0,lpdi->lpszDocName,-1,NULL,0);
610 szDocName = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
611 MultiByteToWideChar(CP_ACP,0,lpdi->lpszDocName,-1,szDocName,len);
612 }
613 if (lpdi->lpszOutput)
614 {
615 len = MultiByteToWideChar(CP_ACP,0,lpdi->lpszOutput,-1,NULL,0);
616 szOutput = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
617 MultiByteToWideChar(CP_ACP,0,lpdi->lpszOutput,-1,szOutput,len);
618 }
619 if (lpdi->lpszDatatype)
620 {
621 len = MultiByteToWideChar(CP_ACP,0,lpdi->lpszDatatype,-1,NULL,0);
622 szDatatype = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
623 MultiByteToWideChar(CP_ACP,0,lpdi->lpszDatatype,-1,szDatatype,len);
624 }
625
626 docW.lpszDocName = szDocName;
627 docW.lpszOutput = szOutput;
628 docW.lpszDatatype = szDatatype;
629 docW.fwType = lpdi->fwType;
630
631 ret = StartDocW(hdc, &docW);
632
633 HeapFree( GetProcessHeap(), 0, szDocName );
634 HeapFree( GetProcessHeap(), 0, szOutput );
635 HeapFree( GetProcessHeap(), 0, szDatatype );
636
637 return ret;
638 }
639
640 /*
641 * @unimplemented
642 */
643 int
644 WINAPI
StartPage(HDC hdc)645 StartPage(
646 HDC hdc
647 )
648 {
649 PLDC pldc;
650 ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
651
652 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
653 {
654 SetLastError(ERROR_INVALID_HANDLE);
655 return SP_ERROR;
656 }
657
658 pldc = GdiGetLDC(hdc);
659 if ( !pldc )
660 {
661 SetLastError(ERROR_INVALID_HANDLE);
662 return SP_ERROR;
663 }
664
665 if (pldc->Flags & LDC_META_PRINT)
666 {
667 UNIMPLEMENTED;
668 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
669 return SP_ERROR;
670 }
671
672 pldc->Flags &= ~(LDC_ATENDPAGE|LDC_STARTPAGE);
673
674 if (pldc->Flags & LDC_INIT_PAGE) return 1;
675
676 if (DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_STARTPAGE, 0, NULL, 0, NULL) != SP_ERROR)
677 {
678 pldc->Flags |= LDC_INIT_PAGE;
679
680 ((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->cSpins = 0;
681
682 if (StartPagePrinterEx(NULL, pldc->hPrinter))
683 {
684 if (NtGdiStartPage(hdc)) return 1;
685 }
686
687 pldc->Flags &= ~(LDC_INIT_PAGE);
688 EndDoc(hdc);
689 SetLastError(ERROR_INVALID_HANDLE);
690 }
691 return SP_ERROR;
692 }
693
694 /*
695 * @implemented
696 */
697 int
698 WINAPI
StartFormPage(HDC hdc)699 StartFormPage(HDC hdc)
700 {
701 return StartPage(hdc);
702 }
703
704
705 /*
706 * @implemented
707 */
708 int
709 WINAPI
SetAbortProc(HDC hdc,ABORTPROC lpAbortProc)710 SetAbortProc(
711 HDC hdc,
712 ABORTPROC lpAbortProc)
713 {
714 PLDC pldc;
715 ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
716
717 if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
718 return SP_ERROR;
719
720 pldc = GdiGetLDC(hdc);
721 if ( pldc )
722 {
723 if ( lpAbortProc )
724 {
725 if ( pldc->Flags & LDC_INIT_DOCUMENT )
726 {
727 pldc->Flags |= LDC_SAPCALLBACK;
728 pldc->CallBackTick = GetTickCount();
729 }
730 }
731 else
732 {
733 pldc->Flags &= ~LDC_SAPCALLBACK;
734 }
735 pldc->pAbortProc = lpAbortProc;
736 return 1;
737 }
738 else
739 {
740 SetLastError(ERROR_INVALID_HANDLE);
741 }
742 return SP_ERROR;
743 }
744
745 /*
746 * @unimplemented
747 */
748 DWORD
749 WINAPI
gdiPlaySpoolStream(DWORD a0,DWORD a1,DWORD a2,DWORD a3,DWORD a4,DWORD a5)750 gdiPlaySpoolStream(
751 DWORD a0,
752 DWORD a1,
753 DWORD a2,
754 DWORD a3,
755 DWORD a4,
756 DWORD a5
757 )
758 {
759 UNIMPLEMENTED;
760 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
761 return 0;
762 }
763
764 /*
765 * @unimplemented
766 */
767 HDC
768 WINAPI
GdiGetDC(HANDLE SpoolFileHandle)769 GdiGetDC(HANDLE SpoolFileHandle)
770 {
771 UNIMPLEMENTED;
772 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
773 return 0;
774 }
775
776 /*
777 * @unimplemented
778 */
779 HANDLE
780 WINAPI
GdiGetPageHandle(HANDLE SpoolFileHandle,DWORD Page,LPDWORD pdwPageType)781 GdiGetPageHandle(HANDLE SpoolFileHandle,
782 DWORD Page,
783 LPDWORD pdwPageType)
784 {
785 UNIMPLEMENTED;
786 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
787 return 0;
788 }
789
790 /*
791 * @unimplemented
792 */
793 BOOL
794 WINAPI
GdiStartDocEMF(HANDLE SpoolFileHandle,DOCINFOW * pDocInfo)795 GdiStartDocEMF(HANDLE SpoolFileHandle,
796 DOCINFOW *pDocInfo)
797 {
798 UNIMPLEMENTED;
799 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
800 return 0;
801 }
802
803 /*
804 * @unimplemented
805 */
806 BOOL
807 WINAPI
GdiStartPageEMF(HANDLE SpoolFileHandle)808 GdiStartPageEMF(HANDLE SpoolFileHandle)
809 {
810 UNIMPLEMENTED;
811 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
812 return 0;
813 }
814
815 /*
816 * @unimplemented
817 */
818 BOOL
819 WINAPI
GdiPlayPageEMF(HANDLE SpoolFileHandle,HANDLE hemf,RECT * prectDocument,RECT * prectBorder,RECT * prectClip)820 GdiPlayPageEMF(HANDLE SpoolFileHandle,
821 HANDLE hemf,
822 RECT *prectDocument,
823 RECT *prectBorder,
824 RECT *prectClip)
825 {
826 UNIMPLEMENTED;
827 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
828 return 0;
829 }
830
831 /*
832 * @unimplemented
833 */
834 BOOL
835 WINAPI
GdiEndPageEMF(HANDLE SpoolFileHandle,DWORD dwOptimization)836 GdiEndPageEMF(HANDLE SpoolFileHandle,
837 DWORD dwOptimization)
838 {
839 UNIMPLEMENTED;
840 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
841 return 0;
842 }
843
844 /*
845 * @unimplemented
846 */
847 BOOL
848 WINAPI
GdiEndDocEMF(HANDLE SpoolFileHandle)849 GdiEndDocEMF(HANDLE SpoolFileHandle)
850 {
851 UNIMPLEMENTED;
852 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
853 return 0;
854 }
855
856 /*
857 * @unimplemented
858 */
859 BOOL
860 WINAPI
GdiGetDevmodeForPage(HANDLE SpoolFileHandle,DWORD dwPageNumber,PDEVMODEW * pCurrDM,PDEVMODEW * pLastDM)861 GdiGetDevmodeForPage(HANDLE SpoolFileHandle,
862 DWORD dwPageNumber,
863 PDEVMODEW *pCurrDM,
864 PDEVMODEW *pLastDM)
865 {
866 UNIMPLEMENTED;
867 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
868 return 0;
869 }
870
871 /*
872 * @unimplemented
873 */
874 BOOL
875 WINAPI
GdiResetDCEMF(HANDLE SpoolFileHandle,PDEVMODEW pCurrDM)876 GdiResetDCEMF(HANDLE SpoolFileHandle,
877 PDEVMODEW pCurrDM)
878 {
879 UNIMPLEMENTED;
880 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
881 return 0;
882 }
883
884
885 /*
886 * @unimplemented
887 */
888 BOOL
889 WINAPI
GdiPlayEMF(LPWSTR pwszPrinterName,LPDEVMODEW pDevmode,LPWSTR pwszDocName,EMFPLAYPROC pfnEMFPlayFn,HANDLE hPageQuery)890 GdiPlayEMF(LPWSTR pwszPrinterName,
891 LPDEVMODEW pDevmode,
892 LPWSTR pwszDocName,
893 EMFPLAYPROC pfnEMFPlayFn,
894 HANDLE hPageQuery
895 )
896 {
897 UNIMPLEMENTED;
898 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
899 return 0;
900 }
901
902 /*
903 * @unimplemented
904 */
905 BOOL
906 WINAPI
GdiPlayPrivatePageEMF(HANDLE SpoolFileHandle,DWORD unknown,RECT * prectDocument)907 GdiPlayPrivatePageEMF(HANDLE SpoolFileHandle,
908 DWORD unknown,
909 RECT *prectDocument)
910 {
911 UNIMPLEMENTED;
912 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
913 return 0;
914 }
915
916 /*
917 * @unimplemented
918 */
919 BOOL
920 WINAPI
GdiPrinterThunk(IN HUMPD humpd,DWORD * status,DWORD unuse)921 GdiPrinterThunk(
922 IN HUMPD humpd,
923 DWORD *status,
924 DWORD unuse)
925 {
926 /* FIXME figout the protypes, the HUMPD are a STRUCT or COM object */
927 /* status contain some form of return value that being save, what it is I do not known */
928 /* unsue seam have zero effect, what it is for I do not known */
929
930 // ? return NtGdiSetPUMPDOBJ(humpd->0x10,TRUE, humpd, ?) <- blackbox, OpenRCE info, and api hooks for anylaysing;
931 return FALSE;
932 }
933
934 /*
935 * @unimplemented
936 */
937 BOOL
938 WINAPI
GdiArtificialDecrementDriver(LPWSTR pDriverName,BOOL unknown)939 GdiArtificialDecrementDriver(LPWSTR pDriverName,BOOL unknown)
940 {
941 UNIMPLEMENTED;
942 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
943 return 0;
944 }
945