⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 separatorpp.cpp

📁 Separator Print Processor Sample
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1990-2003  Microsoft Corporation
All Rights Reserved

Abstract:

    Win32 print processor support functions.


--*/

#include "local.h"

#include <excpt.h>

LPWSTR  Datatypes[]={
    L"RAW",
    L"NT EMF 1.006",
    L"NT EMF 1.007",
    L"NT EMF 1.008",
    L"TEXT",
    0};

/** Misc. constants **/

#define BASE_TAB_SIZE 8

/**
 *  For localization:
**/

PWCHAR pTabsKey     = L"TABS";
PWCHAR pCopiesKey   = L"COPIES";


/**
    Prototypes
**/

/** Functions found in parsparm.c **/

extern USHORT GetKeyValue(
    IN      PWCHAR,
    IN      PWCHAR,
    IN      USHORT,
    IN OUT  PUSHORT,
    OUT     PVOID);

/** Functions found in raw.c **/

extern BOOL PrintRawJob(
    IN PPRINTPROCESSORDATA,
    IN LPWSTR,
    IN UINT);

/** Functions found in text.c **/

extern BOOL PrintTextJob(
    IN PPRINTPROCESSORDATA,
    IN LPWSTR);

/** Functions found in emf.c */

extern BOOL PrintEMFJob(
    IN PPRINTPROCESSORDATA,
    IN LPWSTR);

/** Functions found in support.c **/

extern PUCHAR GetPrinterInfo(
    IN  HANDLE hPrinter,
    IN  ULONG,
    OUT PULONG);

BOOL BReleasePPData(
        IN  PPRINTPROCESSORDATA * ppData );



BOOL
__stdcall 
DllMain(
    HANDLE hModule,
    DWORD dwReason,
    LPVOID lpRes
)
{
    return TRUE;
}    


/*++
*******************************************************************
    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

    Routine Description:
        Enumerates the data types supported by the print processor.

    Arguments:
        pName               => server name
        pPrintProcessorName => print processor name
        Level               => level of data to return (must be 1)
        pDatatypes          => structure array to fill in
        cbBuf               => length of structure array in bytes
        pcbNeeded           => buffer length copied/required
        pcReturned          => number of structures returned

    Return Value:
        TRUE  if successful
        FALSE if failed - caller must use GetLastError for reason
*******************************************************************
--*/
BOOL
EnumPrintProcessorDatatypes(
	IN LPWSTR	pName,
    IN LPWSTR	pPrintProcessorName,
    IN DWORD	Level,
    OUT LPBYTE	pDatatypes,
    IN DWORD	cbBuf,
    OUT LPDWORD	pcbNeeded,
    OUT LPDWORD	pcReturned
)
{
    DATATYPES_INFO_1    *pInfo1 = (DATATYPES_INFO_1 *)pDatatypes;
    LPWSTR              *pMyDatatypes = Datatypes;
    DWORD               cbTotal=0;
    ULONG               cchBuf =0;
    LPBYTE              pEnd;


    if ( NULL == pcbNeeded  ||
         NULL == pcReturned )
    {
        return FALSE;
        SetLastError (ERROR_INVALID_PARAMETER);
    }

    /** Start assuming failure, no entries returned **/

    *pcReturned = 0;

    /** Add up the minimum buffer required **/

    while (*pMyDatatypes) {

        cbTotal += wcslen(*pMyDatatypes) * sizeof(WCHAR) + sizeof(WCHAR) +
                   sizeof(DATATYPES_INFO_1);

        pMyDatatypes++;
    }

    /** Set the buffer length returned/required **/

    *pcbNeeded = cbTotal;

    /** Fill in the array only if there is sufficient space **/

    if (cbTotal <= cbBuf) {

        if ( NULL == pInfo1 ) //pInfo1 is same as pDatatypes
        {
            SetLastError (ERROR_INVALID_PARAMETER);
            return FALSE;
        }

        /** Pick up pointer to end of the given buffer **/

        pEnd = (LPBYTE)pInfo1 + cbBuf;

    
        /** Pick up our list of supported data types **/

        pMyDatatypes = Datatypes;

        /**
            Fill in the given buffer.  We put the data names at the end of
            the buffer, working towards the front.  The structures are put
            at the front, working towards the end.
        **/

        while (*pMyDatatypes) {

            cchBuf = wcslen(*pMyDatatypes) + 1; //+1 is for \0.
            pEnd -= cchBuf*sizeof(WCHAR); 

            StringCchCopy ( (LPWSTR)pEnd, cchBuf, *pMyDatatypes);
            pInfo1->pName = (LPWSTR)pEnd;
            pInfo1++;
            (*pcReturned)++;

            pMyDatatypes++;
        }

    } else {

        /** Caller didn't have large enough buffer, set error and return **/

        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    /** Return success **/

    return TRUE;
}


/*++
*******************************************************************
    O p e n P r i n t P r o c e s s o r

    Routine Description:

    Arguments:
        pPrinterName            => name of printer we are
                                    opening for
        pPrintProcessorOpenData => information used for opening
                                    the print processor

    Return Value:
        PPRINTPROCESSORDATA => processor data of opened
                                processor if successful
        NULL if failed - caller uses GetLastError for reason

    NOTE: OpenPrinter will be called iff this returns a valid handle
          (and we're not journal)

*******************************************************************
--*/
HANDLE
OpenPrintProcessor(
    LPWSTR   pPrinterName,
    PPRINTPROCESSOROPENDATA pPrintProcessorOpenData
)
{
    PPRINTPROCESSORDATA pData;
    LPWSTR              *pMyDatatypes=Datatypes;
    DWORD               uDatatype=0;
    HANDLE              hPrinter=0;
    HDC                 hDC = 0;
    PDEVMODEW           pDevmode = NULL;


    /** If the caller passed a NULL for the open data, fail the call.
        pPrintProcessorOpenData->pDevMode can be NULL **/

    if (!pPrintProcessorOpenData ||
        !pPrintProcessorOpenData->pDatatype ||
        !*pPrintProcessorOpenData->pDatatype) {

        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /** Search for the data type index we are opening for **/

    while (*pMyDatatypes) {

        if (!_wcsicmp(*pMyDatatypes,pPrintProcessorOpenData->pDatatype)) {
            break;
        }
        pMyDatatypes++;
        uDatatype++;
    }

    /** Allocate a buffer for the print processor data to return **/

    pData = (PPRINTPROCESSORDATA)AllocSplMem(sizeof(PRINTPROCESSORDATA));

    if (!pData) {
        ODS(("Alloc failed in OpenPrintProcessor, while printing on %ws\n", pPrinterName));
        return NULL;
    }

    ZeroMemory ( pData, sizeof (PRINTPROCESSORDATA) );

    /** Open the processor accordingly **/

    switch (uDatatype) {

    case PRINTPROCESSOR_TYPE_RAW:
        if (!OpenPrinter(pPrinterName, &hPrinter, NULL))
            goto Fail;
        break;

    case PRINTPROCESSOR_TYPE_EMF_50_1:
    case PRINTPROCESSOR_TYPE_EMF_50_2:
    case PRINTPROCESSOR_TYPE_EMF_50_3:

        if(pPrintProcessorOpenData->pDevMode)
        {
            if(!(pDevmode=(DEVMODEW*)AllocSplMem(pPrintProcessorOpenData->pDevMode->dmSize+
                                      pPrintProcessorOpenData->pDevMode->dmDriverExtra)))
            {
                goto Fail;
            }
            memcpy(pDevmode,
                   pPrintProcessorOpenData->pDevMode,
                   pPrintProcessorOpenData->pDevMode->dmSize+
                   pPrintProcessorOpenData->pDevMode->dmDriverExtra);
        }
        break;

    case PRINTPROCESSOR_TYPE_TEXT:
        if (!(hDC = CreateDC(L"", pPrinterName, L"",
                             pPrintProcessorOpenData->pDevMode)))
            goto Fail;
        break;

    default:
        SetLastError(ERROR_INVALID_DATATYPE);
        goto Fail;
    }

    /** Fill in the print processors information **/

    pData->cb          = sizeof(PRINTPROCESSORDATA);
    pData->signature   = PRINTPROCESSORDATA_SIGNATURE;
    pData->JobId       = pPrintProcessorOpenData->JobId;
    pData->hPrinter    = hPrinter;
    pData->semPaused   = CreateEvent(NULL, TRUE, TRUE,NULL);
    pData->uDatatype   = uDatatype;
    pData->hDC         = hDC;
    pData->Copies      = 1;
    pData->TabSize     = BASE_TAB_SIZE;

    /** Allocate and fill in the processors strings **/

    pData->pPrinterName = AllocSplStr(pPrinterName);
    pData->pDatatype    = AllocSplStr(pPrintProcessorOpenData->pDatatype);
    pData->pDocument    = AllocSplStr(pPrintProcessorOpenData->pDocumentName);
    pData->pOutputFile  = AllocSplStr(pPrintProcessorOpenData->pOutputFile);
    pData->pParameters  = AllocSplStr(pPrintProcessorOpenData->pParameters);
    pData->pDevmode     = pDevmode;
    pData->pPrinterNameFromOpenData = AllocSplStr(pPrintProcessorOpenData->pPrinterName);

    //
    // Check for validity of pData. In the AllocSplStr above, if RHS is non-null, then LHS
    // should be non-null. 
    //
    if ( NULL == pData->semPaused ||
        ( NULL != pPrinterName                           && NULL == pData->pPrinterName )  ||
        ( NULL != pPrintProcessorOpenData->pDatatype     && NULL == pData->pDatatype    )  ||
        ( NULL != pPrintProcessorOpenData->pDocumentName && NULL == pData->pDocument    )  ||
        ( NULL != pPrintProcessorOpenData->pOutputFile   && NULL == pData->pOutputFile  )  ||
        ( NULL != pPrintProcessorOpenData->pParameters   && NULL == pData->pParameters  )  ||
        ( NULL != pPrintProcessorOpenData->pPrinterName  && NULL == pData->pPrinterNameFromOpenData)
      )
    {
        goto Fail;
    }


    /** Parse the parameters string **/
    if (pData->pParameters) {
        ULONG   value;
        USHORT  length = sizeof(ULONG);

        /**
            Look to see if there is a COPIES=n key/value in the
            Parameters field of this job.  This tells us the number
            of times to play the data.
        **/

        if (pData->pParameters) {

            GetKeyValue(pData->pParameters,
                        pCopiesKey,
                        VALUE_ULONG,
                        &length,
                        &value);

            if (length == sizeof(ULONG)) {
                pData->Copies = value;
            }
        }

        /** If this is a text job, see if the tab size is in there **/

        if (uDatatype == PRINTPROCESSOR_TYPE_TEXT) {
            length = sizeof(ULONG);

            GetKeyValue(pData->pParameters,
                        pTabsKey,
                        VALUE_ULONG,
                        &length,
                        &value);

            if ((length == sizeof(ULONG)) && value) {
                pData->TabSize = value;
            }
        }
    } /* If we have a parameter string */

    /**
        If we are doing copies, we need to check to see if
        this is a direct or spooled job.  If it is direct, then
        we can't do copies because we can't rewind the data stream.
    **/

    if (pData->Copies > 1) {
        ULONG           Error;
        PPRINTER_INFO_2 pPrinterInfo2;

        /** If we don't already have the printer open, open it **/

        if (uDatatype != PRINTPROCESSOR_TYPE_RAW
            ) {

            OpenPrinter(pPrinterName, &hPrinter, NULL);
        }
        if (hPrinter && hPrinter != INVALID_HANDLE_VALUE) {

            /** Get the printer info - this returns an allocated buffer **/

            pPrinterInfo2 = (PPRINTER_INFO_2)GetPrinterInfo(hPrinter, 2, &Error);

            /** If we couldn't get the info, be safe and don't do copies **/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -