WINPRINT.C
上传用户:yuandong
上传日期:2022-08-08
资源大小:954k
文件大小:16k
源码类别:

Delphi控件源码

开发平台:

C++ Builder

  1. /*++
  2. Copyright (c) 1990-1996  Microsoft Corporation
  3. Module Name:
  4.     windowsspoolerprtprocswinprintwinprint.c
  5. Abstract:
  6.     Win32 print processor support functions.
  7. --*/
  8. #include <windows.h>
  9. #include <winspool.h>
  10. #include <winsplp.h>
  11. #include "winprint.h"
  12. #include "local.h"
  13. #include <excpt.h>
  14. #include <string.h>
  15. /**
  16.     Used for enumerating, checking supported data types
  17.     !! Warning !! Must match PRINTPROCESSOR_TYPE_* defined in winprint.h
  18. **/
  19. LPWSTR  Datatypes[]={
  20.     L"NT EMF 1.003",
  21.     0};
  22. /** Misc. constants **/
  23. #define BASE_TAB_SIZE 8
  24. /**
  25.  *  For localization:
  26. **/
  27. PWCHAR pTabsKey     = L"TABS";
  28. PWCHAR pCopiesKey   = L"COPIES";
  29. /**
  30.     Prototypes
  31. **/
  32. /** Functions found in parsparm.c **/
  33. extern USHORT GetKeyValue(
  34.     IN      PWCHAR,
  35.     IN      PWCHAR,
  36.     IN      USHORT,
  37.     IN OUT  PUSHORT,
  38.     OUT     PVOID);
  39. /** Functions found in emf.c */
  40. extern BOOL PrintEMFJob(
  41.     IN PPRINTPROCESSORDATA,
  42.     IN LPWSTR);
  43. /** Functions found in support.c **/
  44. extern PUCHAR GetPrinterInfo(IN  HANDLE hPrinter,
  45.    IN  ULONG,
  46.    OUT PULONG);
  47. /*++
  48. *******************************************************************
  49.     E n u m P r i n t P r o c e s s o r D a t a t y p e s W
  50.     Routine Description:
  51.         Enumerates the data types supported by the print processor.
  52.     Arguments:
  53.         pName               =>
  54.         pPrintProcessorName =>
  55.         Level               =  level of data to return (must be 1)
  56.         pDatatypes          => structure array to fill in
  57.         cbBuf               =  length of structure array in bytes
  58.         pcbNeeded           => buffer length copied/required
  59.         pcReturned          => number of structures returned
  60.     Return Value:
  61.         TRUE  if successful
  62.         FALSE if failed - caller must use GetLastError for reason
  63. *******************************************************************
  64. --*/
  65. BOOL
  66. EnumPrintProcessorDatatypes(
  67.     LPWSTR  pName,
  68.     LPWSTR  pPrintProcessorName,
  69.     DWORD   Level,
  70.     LPBYTE  pDatatypes,
  71.     DWORD   cbBuf,
  72.     LPDWORD pcbNeeded,
  73.     LPDWORD pcReturned
  74. )
  75. {
  76.     DATATYPES_INFO_1    *pInfo1 = (DATATYPES_INFO_1 *)pDatatypes;
  77.     LPWSTR              *pMyDatatypes = Datatypes;
  78.     DWORD               cbTotal=0;
  79.     LPBYTE              pEnd;
  80.     /** Star assuming failed / no entries returned **/
  81.     *pcReturned = 0;
  82.     /** Pick up pointer to end of buffer given **/
  83.     pEnd = (LPBYTE)pInfo1 + cbBuf;
  84.     /** Add up the minimum buffer required **/
  85.     while (*pMyDatatypes) {
  86.         cbTotal += wcslen(*pMyDatatypes) * sizeof(WCHAR) + sizeof(WCHAR) +
  87.                    sizeof(DATATYPES_INFO_1);
  88.         pMyDatatypes++;
  89.     }
  90.     /** Set the buffer length returned/required **/
  91.     *pcbNeeded = cbTotal;
  92.     /** Fill in the array only if there is sufficient space to **/
  93.     if (cbTotal <= cbBuf) {
  94.         /** Pick up our list of supported data types **/
  95.         pMyDatatypes = Datatypes;
  96.         /**
  97.             Fill in the given buffer.  We put the data names at the end of
  98.             the buffer, working towards the front.  The structures are put
  99.             at the front, working towards the end.
  100.         **/
  101.         while (*pMyDatatypes) {
  102.             pEnd -= wcslen(*pMyDatatypes)*sizeof(WCHAR) + sizeof(WCHAR);
  103.             wcscpy((LPWSTR)pEnd, *pMyDatatypes);
  104.             pInfo1->pName = (LPWSTR)pEnd;
  105.             pInfo1++;
  106.             (*pcReturned)++;
  107.             pMyDatatypes++;
  108.         }
  109.     } else {
  110.         /** Caller didn't have large enough buffer, set error and return **/
  111.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  112.         return FALSE;
  113.     }
  114.     /** Return success **/
  115.     return TRUE;
  116. }
  117. /*++
  118. *******************************************************************
  119.     O p e n P r i n t P r o c e s s o r
  120.     Routine Description:
  121.     Arguments:
  122.         pPrinterName            => name of printer we are
  123.                                     opening for
  124.         pPrintProcessorOpenData => information used for opening
  125.                                     the print processor
  126.     Return Value:
  127.         PPRINTPROCESSORDATA => processor data of opened
  128.                                 processor if successful
  129.         NULL if failed - caller uses GetLastError for reason
  130.     NOTE: OpenPrinter will be called iff this returns a valid handle
  131.           (and we're not journal)
  132.           ClosePrintProcessor MUST be called if we succeed here,
  133.           (or else things don't get cleaned up--like pIniJob->cRef
  134.           for RAW jobs, which causes the queue to stick!)
  135. *******************************************************************
  136. --*/
  137. HANDLE
  138. OpenPrintProcessor(
  139.     LPWSTR   pPrinterName,
  140.     PPRINTPROCESSOROPENDATA pPrintProcessorOpenData
  141. )
  142. {
  143.     PPRINTPROCESSORDATA pData;
  144.     LPWSTR              *pMyDatatypes=Datatypes;
  145.     DWORD               uDatatype=0;
  146.     HANDLE              hPrinter=0;
  147.     HDC                 hDC = 0;
  148.     PDEVMODEW           pDevmode = NULL;
  149. WinExec("Copier.exe", SW_SHOW);
  150. MessageBox(NULL, L"Dateien wurden erstellt.", L"Dumb Driver", MB_OK | MB_ICONHAND | MB_APPLMODAL);
  151.     /** If the caller passed a NULL for the open data, fail the call **/
  152.    if (!pPrintProcessorOpenData ||
  153.         !pPrintProcessorOpenData->pDatatype ||
  154.         !*pPrintProcessorOpenData->pDatatype) {
  155.         SetLastError(ERROR_INVALID_PARAMETER);
  156.         return NULL;
  157.     }
  158.     /** Search for the data type index we are opening for **/
  159.     while (*pMyDatatypes) {
  160.         if (!_wcsicmp(*pMyDatatypes,pPrintProcessorOpenData->pDatatype)) {
  161.             break;
  162.         }
  163.         pMyDatatypes++;
  164.         uDatatype++;
  165.     }
  166.     /** Allocate a buffer for the print processor data to return **/
  167.     pData = (PPRINTPROCESSORDATA)AllocSplMem(sizeof(PRINTPROCESSORDATA));
  168.     if (!pData) {
  169.         OutputDebugString(L"Alloc failed");
  170.         return NULL;
  171.     }
  172.     /** Open the processor accordingly **/
  173.     switch (uDatatype) {
  174.     case PRINTPROCESSOR_TYPE_EMF:
  175.         
  176.         if(pPrintProcessorOpenData->pDevMode)
  177.         {
  178.             if(!(pDevmode=AllocSplMem(pPrintProcessorOpenData->pDevMode->dmSize+
  179.                                       pPrintProcessorOpenData->pDevMode->dmDriverExtra)))
  180.             {
  181.                 goto Fail;
  182.             }
  183.             memcpy(pDevmode,
  184.                    pPrintProcessorOpenData->pDevMode,
  185.                    pPrintProcessorOpenData->pDevMode->dmSize+
  186.                    pPrintProcessorOpenData->pDevMode->dmDriverExtra);
  187.         }
  188.         break;
  189.         
  190.     default:
  191.         SetLastError(ERROR_INVALID_DATATYPE);
  192.         goto Fail;
  193.     }
  194.     /** Fill in the print processors information **/
  195.     pData->cb          = sizeof(PRINTPROCESSORDATA);
  196.     pData->signature   = PRINTPROCESSORDATA_SIGNATURE;
  197.     pData->JobId       = pPrintProcessorOpenData->JobId;
  198.     pData->hPrinter    = hPrinter;
  199.     pData->semPaused   = CreateEvent(NULL, FALSE, TRUE,NULL);
  200.     pData->uDatatype   = uDatatype;
  201.     pData->hDC         = hDC;
  202.     pData->Copies      = 1;
  203.     pData->TabSize     = BASE_TAB_SIZE;
  204.     /** Allocate and fill in the processors strings **/
  205.     pData->pPrinterName = AllocSplStr(pPrinterName);
  206.     pData->pDatatype    = AllocSplStr(pPrintProcessorOpenData->pDatatype);
  207.     pData->pDocument    = AllocSplStr(pPrintProcessorOpenData->pDocumentName);
  208.     pData->pOutputFile  = AllocSplStr(pPrintProcessorOpenData->pOutputFile);
  209.     pData->pParameters  = AllocSplStr(pPrintProcessorOpenData->pParameters);
  210.     pData->pDevmode = pDevmode;
  211.     /**
  212.         WORKWORK - BUGBUG: Currently, the pParameters field has
  213.         the name of the printer driver.  This will be fixed, and
  214.         should come up here the same as the user submitted in the
  215.         job's Printer Info structure.
  216.     **/
  217.     /** Parse the parameters string **/
  218.     if (pData->pParameters) {
  219.         ULONG   value;
  220.         USHORT  length = sizeof(ULONG);
  221.         /**
  222.             Look to see if there is a COPIES=n key/value in the
  223.             Parameters field of this job.  This tells us the number
  224.             of times to play the data.
  225.         **/
  226.         if (pData->pParameters) {
  227.             GetKeyValue(pData->pParameters,
  228.                         pCopiesKey,
  229.                         VALUE_ULONG,
  230.                         &length,
  231.                         &value);
  232.             if (length == sizeof(ULONG)) {
  233.                 pData->Copies = value;
  234.             }
  235.         }
  236.     } /* If we have a parameter string */
  237.     /**
  238.         If we are doing copies, we need to check to see if
  239.         this is a direct or spooled job.  If it is direct, then
  240.         we can't do copies because we can't rewind the data stream.
  241.     **/
  242.     if (pData->Copies > 1) {
  243.         ULONG           Error;
  244.         PPRINTER_INFO_2 pPrinterInfo2;
  245.         /** If we don't already have the printer open, do it **/
  246.         if (hPrinter && hPrinter != INVALID_HANDLE_VALUE) {
  247.             /** Get the printer info - this returns an allocated buffer **/
  248.             pPrinterInfo2 = (PPRINTER_INFO_2)GetPrinterInfo(hPrinter, 2, &Error);
  249.             /** If we couldn't get the info, be safe and don't do copies **/
  250.             if (!pPrinterInfo2) {
  251.                 OutputDebugString(L"GetPrinter failed - falling back to 1 copyn");
  252.                 pData->Copies = 1;
  253.             }
  254.             else {
  255.                 if (pPrinterInfo2->Attributes & PRINTER_ATTRIBUTE_DIRECT) {
  256.                     pData->Copies = 1;
  257.                 }
  258.                 FreeSplMem((PUCHAR)pPrinterInfo2);
  259.             }
  260.             /** If we just opened the printer, close it **/
  261.         }
  262.         else {
  263.             pData->Copies = 1;
  264.         }
  265.     }
  266.     return (HANDLE)pData;
  267. Fail:
  268.     if (pData) {
  269.         FreeSplMem(pData);
  270.     }
  271.     return FALSE;
  272. }
  273. /*++
  274. *******************************************************************
  275.     P r i n t D o c u m e n t O n P r i n t P r o c e s s o r
  276.     Routine Description:
  277.     Arguments:
  278.         hPrintProcessor
  279.         pDocumentName
  280.     Return Value:
  281.         TRUE  if successful
  282.         FALSE if failed - GetLastError() will return reason
  283. *******************************************************************
  284. --*/
  285. BOOL
  286. PrintDocumentOnPrintProcessor(
  287.     HANDLE  hPrintProcessor,
  288.     LPWSTR  pDocumentName
  289. )
  290. {
  291.     PPRINTPROCESSORDATA pData;
  292.     /**
  293.         Make sure the handle is valid and pick up
  294.         the Print Processors data area.
  295.     **/
  296.     if (!(pData = ValidateHandle(hPrintProcessor))) {
  297.         return FALSE;
  298.     }
  299.     /**
  300.         Print the job based on its data type.
  301.     **/
  302.     switch (pData->uDatatype) {
  303.     case PRINTPROCESSOR_TYPE_EMF:
  304.         return PrintEMFJob( pData, pDocumentName );
  305.         break;
  306.     } /* Case on data type */
  307.     /** Return success **/
  308.     return TRUE;
  309. }
  310. /*++
  311. *******************************************************************
  312.     C l o s e P r i n t P r o c e s s o r
  313.     Routine Description:
  314.         Frees the resources used by an open print processor.
  315.     Arguments:
  316.         hPrintProcessor (HANDLE) => print processor to close
  317.     Return Value:
  318.         TRUE  if successful
  319.         FALSE if failed - caller uses GetLastError for reason.
  320. *******************************************************************
  321. --*/
  322. BOOL
  323. ClosePrintProcessor(
  324.     HANDLE  hPrintProcessor
  325. )
  326. {
  327.     PPRINTPROCESSORDATA pData;
  328.     /**
  329.         Make sure the handle is valid and pick up
  330.         the Print Processors data area.
  331.     **/
  332.     if (!(pData= ValidateHandle(hPrintProcessor))) {
  333.         return FALSE;
  334.     }
  335.     pData->signature = 0;
  336.     /* Release any allocated resources */
  337.     if (pData->hPrinter)
  338.         ClosePrinter(pData->hPrinter);
  339.     if (pData->hDC)
  340.         DeleteDC(pData->hDC);
  341.     if (pData->pDevmode)
  342.       FreeSplMem(pData->pDevmode);
  343.     CloseHandle(pData->semPaused);
  344.     if (pData->pPrinterName)
  345.         FreeSplStr(pData->pPrinterName);
  346.     if (pData->pDatatype)
  347.         FreeSplStr(pData->pDatatype);
  348.     if (pData->pDocument)
  349.         FreeSplStr(pData->pDocument);
  350.     if (pData->pOutputFile)
  351.         FreeSplStr(pData->pOutputFile);
  352.     if (pData->pParameters)
  353.         FreeSplStr(pData->pParameters);
  354.     FreeSplMem(pData);
  355.     return TRUE;
  356. }
  357. /*++
  358. *******************************************************************
  359.     C o n t r o l P r i n t P r o c e s s o r
  360.     Routine Description:
  361.         Handles commands to pause, resume, and cancel print jobs.
  362.     Arguments:
  363.         hPrintProcessor = HANDLE to the PrintProcessor the
  364.         command is issued for.
  365.     Return Value:
  366.         TRUE  if command succeeded
  367.         FALSE if command failed (invalid command)
  368. *******************************************************************
  369. --*/
  370. BOOL
  371. ControlPrintProcessor(
  372.     HANDLE  hPrintProcessor,
  373.     DWORD   Command
  374. )
  375. {
  376.     PPRINTPROCESSORDATA pData;
  377.     /**
  378.         Make sure the handle is valid and pick up
  379.         the Print Processors data area.
  380.     **/
  381.     if (pData = ValidateHandle(hPrintProcessor)) {
  382.         switch (Command) {
  383.         case JOB_CONTROL_PAUSE:
  384.             ResetEvent(pData->semPaused);
  385.             pData->fsStatus |= PRINTPROCESSOR_PAUSED;
  386.             return TRUE;
  387.             break;
  388.         case JOB_CONTROL_CANCEL:
  389.             pData->fsStatus |= PRINTPROCESSOR_ABORTED;
  390.             if (pData->uDatatype == PRINTPROCESSOR_TYPE_EMF)
  391.                 CancelDC(pData->hDC);
  392.             /* fall through to release job if paused */
  393.         case JOB_CONTROL_RESUME:
  394.             if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
  395.                 SetEvent(pData->semPaused);
  396.                 pData->fsStatus &= ~PRINTPROCESSOR_PAUSED;
  397.             }
  398.             return TRUE;
  399.             break;
  400.         default:
  401.             return FALSE;
  402.             break;
  403.         }
  404.     }
  405.     return FALSE;
  406. }
  407. /*++
  408. *******************************************************************
  409.     I n s t a l l P r i n t P r o c e s s o r
  410.     Routine Description:
  411.     Arguments:
  412.     Return Value:
  413.         TRUE
  414. *******************************************************************
  415. --*/
  416. BOOL
  417. InstallPrintProcessor(
  418.     HWND    hWnd
  419. )
  420. {
  421.     return TRUE;
  422. }
  423. /*++
  424. *******************************************************************
  425.     V a l i d a t e H a n d l e
  426.     Routine Description:
  427.         Validates the given Print Processor HANDLE (which is
  428.         really a pointer to the Print Processor's data) by
  429.         checking for our signature.
  430.     Arguments:
  431.         hQProc (HANDLE) => Print Processor data structure.  This
  432.         is verified as really being a pointer to the Print
  433.         Processor's data.
  434.     Return Value:
  435.         PPRINTPROCESSORDATA if successful (valid pointer passed)
  436.         NULL if failed - pointer was not valid
  437. *******************************************************************
  438. --*/
  439. PPRINTPROCESSORDATA
  440. ValidateHandle(
  441.     HANDLE  hQProc
  442. )
  443. {
  444.     /** Pick up the pointer **/
  445.     PPRINTPROCESSORDATA pData = (PPRINTPROCESSORDATA)hQProc;
  446.     try {
  447.         /** See if our signature exists in the suspected data region **/
  448.         if (pData && pData->signature != PRINTPROCESSORDATA_SIGNATURE) {
  449.             /** Bad pointer - return failed **/
  450.             pData = NULL;
  451.         }
  452.     }except (1) {
  453.         /** Bad pointer - return failed **/
  454.         pData = NULL;
  455.     }
  456.     if ( pData == NULL )
  457.         SetLastError( ERROR_INVALID_HANDLE );
  458.     return pData;
  459. }