Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
6.1 KiB

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. Module Name:
  4. escape.c
  5. Abstract:
  6. This module contains the code to implement the DrvEscape() driver call
  7. Author:
  8. 15:30 on Mon 06 Dec 1993
  9. Created it
  10. [Environment:]
  11. GDI Device Driver - Plotter.
  12. [Notes:]
  13. Revision History:
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #define DBG_PLOTFILENAME DbgEscape
  18. #define DBG_DRVESCAPE 0x00000001
  19. DEFINE_DBGVAR(0);
  20. #define pbIn ((BYTE *)pvIn)
  21. #define pdwIn ((DWORD *)pvIn)
  22. #define pdwOut ((DWORD *)pvOut)
  23. ULONG
  24. DrvEscape(
  25. SURFOBJ *pso,
  26. ULONG iEsc,
  27. ULONG cjIn,
  28. PVOID pvIn,
  29. ULONG cjOut,
  30. PVOID pvOut
  31. )
  32. /*++
  33. Routine Description:
  34. Performs the escape functions. Currently, only 3 are defined -
  35. one to query the escapes supported, the other for raw data, and the
  36. last for setting the COPYCOUNT.
  37. Arguments:
  38. pso - The surface object interested
  39. iEsc - The function requested
  40. cjIn - Number of bytes in the following
  41. pvIn - Location of input data
  42. cjOut - Number of bytes in the following
  43. pvOut - Location of output area
  44. Return Value:
  45. ULONG depends on the escape
  46. Author:
  47. 05-Jul-1996 Fri 13:18:54 created
  48. Re-write comment, and fix the PASSTHROUGH problem
  49. Revision History:
  50. --*/
  51. {
  52. ULONG ulRes;
  53. PPDEV pPDev;
  54. DWORD cbWritten;
  55. UNREFERENCED_PARAMETER( cjOut );
  56. UNREFERENCED_PARAMETER( pvOut );
  57. if (!(pPDev = SURFOBJ_GETPDEV(pso))) {
  58. PLOTERR(("DrvEscape: Invalid pPDev"));
  59. return(FALSE);
  60. }
  61. ulRes = 0; /* Return failure, by default */
  62. switch (iEsc) {
  63. case QUERYESCSUPPORT:
  64. PLOTDBG(DBG_DRVESCAPE, ("DrvEscape: in QUERYESCAPESUPPORT"));
  65. if ((cjIn == 4) && (pvIn)) {
  66. //
  67. // Data may be valid, so check for supported function
  68. //
  69. switch (*pdwIn) {
  70. case QUERYESCSUPPORT:
  71. case PASSTHROUGH:
  72. ulRes = 1; /* ALWAYS supported */
  73. break;
  74. case SETCOPYCOUNT:
  75. //
  76. // if the target device actually allows us to tell it
  77. // how many copies to print of a document, then pass
  78. // that information back to the caller.
  79. //
  80. if (pPDev->pPlotGPC->MaxCopies > 1) {
  81. ulRes = 1;
  82. }
  83. break;
  84. }
  85. }
  86. break;
  87. case PASSTHROUGH:
  88. PLOTDBG(DBG_DRVESCAPE, ("DrvEscape: in PASSTHROUGH"));
  89. //
  90. // 05-Jul-1996 Fri 12:59:31 updated
  91. //
  92. // This simply passes the RAW data to the target device, untouched.
  93. //
  94. // Win 3.1 actually uses the first 2 bytes as a count of the number of
  95. // bytes that follow! So we will check if cjIn represents more data
  96. // than the first WORD of pvIn
  97. //
  98. if (EngCheckAbort(pPDev->pso)) {
  99. //
  100. // Set the cancel DOC flag
  101. //
  102. pPDev->Flags |= PDEVF_CANCEL_JOB;
  103. PLOTERR(("DrvEscape(PASSTHROUGH): Job Canceled"));
  104. } else if ((cjIn <= sizeof(WORD)) || (pvIn == NULL)) {
  105. SetLastError(ERROR_INVALID_PARAMETER);
  106. PLOTERR(("DrvEscape(PASSTHROUGH): cjIn <= 2 or pvIn=NULL, nothing to output"));
  107. } else {
  108. union {
  109. WORD wCount;
  110. BYTE bCount[2];
  111. } u;
  112. u.bCount[0] = pbIn[0];
  113. u.bCount[1] = pbIn[1];
  114. cbWritten = 0;
  115. if ((u.wCount == 0) ||
  116. ((cjIn - sizeof(WORD)) < (DWORD)u.wCount)) {
  117. PLOTERR(("DrvEscape(PASSTHROUGH): cjIn to small OR wCount is zero/too big"));
  118. SetLastError(ERROR_INVALID_DATA);
  119. } else if ((WritePrinter(pPDev->hPrinter,
  120. (LPVOID)(pbIn + 2),
  121. (DWORD)u.wCount,
  122. &cbWritten)) &&
  123. ((DWORD)u.wCount == cbWritten)) {
  124. ulRes = (DWORD)u.wCount;
  125. } else {
  126. PLOTERR(("DrvEscape(PASSTHROUGH): WritePrinter() FAILED, cbWritten=%ld bytes",
  127. cbWritten));
  128. }
  129. }
  130. break;
  131. case SETCOPYCOUNT:
  132. //
  133. // Input data is a DWORD count of copies
  134. //
  135. PLOTDBG(DBG_DRVESCAPE, ("DrvEscape: in SETCOPYCOUNT"));
  136. if ((pdwIn) && (*pdwIn)) {
  137. //
  138. // Load the value of current copies since we will, and Check that
  139. // is within the printers range, and truncate if it is not.
  140. // The device information structure, tells us the maximum amount
  141. // of copies the device can generate on its own. We save this new
  142. // Copy amount inside of our current DEVMODE that we have stored,
  143. // as part of our PDEV. The copy count actually gets output
  144. // later to the target device.
  145. //
  146. pPDev->PlotDM.dm.dmCopies = (SHORT)*pdwIn;
  147. if ((WORD)pPDev->PlotDM.dm.dmCopies > pPDev->pPlotGPC->MaxCopies) {
  148. pPDev->PlotDM.dm.dmCopies = (SHORT)pPDev->pPlotGPC->MaxCopies;
  149. }
  150. if ((pdwOut) && (cjOut)) {
  151. cbWritten = (DWORD)pPDev->PlotDM.dm.dmCopies;
  152. CopyMemory(pdwOut,
  153. &cbWritten,
  154. (cjOut >= sizeof(DWORD)) ? sizeof(DWORD) : cjOut);
  155. }
  156. //
  157. // Success!
  158. //
  159. ulRes = 1;
  160. }
  161. break;
  162. default:
  163. PLOTERR(("DrvEscape: Unsupported Escape Code : %d\n", iEsc ));
  164. SetLastError(ERROR_INVALID_FUNCTION);
  165. break;
  166. }
  167. return(ulRes);
  168. }