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 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 142 AbortPrinterEx( 143 PVOID pvUMPDev, 144 HANDLE hPrinter 145 ) 146 { 147 return fpAbortPrinter(hPrinter); 148 } 149 150 int 151 FASTCALL 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 168 EndDocPrinterEx( 169 PVOID pvUMPDev, 170 HANDLE hPrinter 171 ) 172 { 173 return fpEndDocPrinter(hPrinter); 174 } 175 176 BOOL 177 FASTCALL 178 EndPagePrinterEx( 179 PVOID pvUMPDev, 180 HANDLE hPrinter 181 ) 182 { 183 return fpEndPagePrinter(hPrinter); 184 } 185 186 BOOL 187 FASTCALL 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 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 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 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 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 416 EndFormPage(HDC hdc) 417 { 418 return IntEndPage(hdc,TRUE); 419 } 420 421 /* 422 * @implemented 423 */ 424 int 425 WINAPI 426 EndPage(HDC hdc ) 427 { 428 return IntEndPage(hdc,FALSE); 429 } 430 431 /* 432 * @unimplemented 433 */ 434 HANDLE 435 WINAPI 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 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 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 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 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 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 699 StartFormPage(HDC hdc) 700 { 701 return StartPage(hdc); 702 } 703 704 705 /* 706 * @implemented 707 */ 708 int 709 WINAPI 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 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 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 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 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 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 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 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 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 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 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 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 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 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 939 GdiArtificialDecrementDriver(LPWSTR pDriverName,BOOL unknown) 940 { 941 UNIMPLEMENTED; 942 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 943 return 0; 944 } 945