|
|
/*
* spool.c - WritePrinter hook. * * Need to be manipulate the spooler data for Canon CPCA architecture. */
#include "pdev.h"
// NTRAID#NTBUG9-172276-2002/03/08-yasuho-: CPCA support
#define MAX_CPCA_PACKET_SIZE 4096 // Must be <= 64KB-1
// CPCA Operation codes
#define CPCA_JobStart 0x0011
#define CPCA_JobEnd 0x0013
#define CPCA_BinderStart 0x0014
#define CPCA_SetBinder 0x0015
#define CPCA_BinderEnd 0x0016
#define CPCA_DocumentStart 0x0017
#define CPCA_SetDocument 0x0018
#define CPCA_DocumentEnd 0x0019
#define CPCA_Send 0x001A
#define CPCA_ExecutiveMethod 0x001D
// CPCA Flags
#define F_Cont 0x02
// CPCA Attributes
#define ATT_DOCFORMAT 0x002E
#define DOCFORMAT_LIPS 0x27
#define ATT_RESOLUTION 0x003A
#define RESOLUTION_QUICK 0x05
#define RESOLUTION_FINE 0x06
#define RESOLUTION_SUPERFINE 0x07
#define ATT_COPIES 0x07D7
#define ATT_OUTPUT 0x07D8
#define OUTPUT_NO_COLLATE 0x08
#define OUTPUT_COLLATE 0x0B
#define OUTPUT_GROUP_COLLATE 0x0F
#define ATT_OUTPUTBIN 0x07D9
#define OUTPUTBIN_FACEUP 0x01
#define OUTPUTBIN_FACEDOWN 0x02
#define OUTPUTBIN_SORT 0x11
#define OUTPUTBIN_NUMBER 0x12
#define OUTPUTBIN_STACK 0x15
#define ATT_FINISHING 0x07DA
#define FINISHING_STAPLE 0x0C
#define FINISHING_COUNT_1 0x66
#define FINISHING_COUNT_2 0x67
#define ATT_OUTPUTPARTITION 0x084A
#define OUTPART_JOBOFFSET 0x01
#define OUTPART_NONE 0x04
#define ATT_OUTPUTFACE 0x084B
#define OUTPUTFACE_FACEUP 0x01
#define OUTPUTFACE_FACEDOWN 0x02
#define OUTPUTFACE_NONE 0x03
static WORD wStapleModes[] = { 0x00CA, // top_left
0x00D5, // top
0x00CC, // top_right
0x00D3, // left
0x00EE, // center (NOT USED)
0x00D4, // right
0x00CB, // bottom_left
0x00D6, // bottom
0x00CD, // bottom_right
};
extern LIPSCmd cmdEndDoc4; extern LIPSCmd cmdEndDoc4C;
/*
* FlushCPCABuffer */ static BOOL FlushCPCABuffer(PDEVOBJ pdevobj, PLIPSPDEV pOEM) { DWORD dwCount;
if (pOEM->CPCABcount == 0) return TRUE;
if (!WritePrinter(pdevobj->hPrinter, pOEM->CPCABuf, pOEM->CPCABcount, &dwCount) || dwCount != pOEM->CPCABcount) return FALSE; pOEM->CPCABcount = 0;
return TRUE; }
/*
* SendCPCAPacket */ static BOOL SendCPCAPacket( PDEVOBJ pdevobj, WORD wCmd, BYTE flags, PBYTE pParams, WORD nParams) { PLIPSPDEV pOEM; PBYTE pBuf; DWORD dwCount;
pOEM = (PLIPSPDEV)pdevobj->pdevOEM; dwCount = pOEM->CPCABcount; if (dwCount + CPCA_PACKET_SIZE + nParams > CPCA_BUFFER_SIZE) { if (!FlushCPCABuffer(pdevobj, pOEM)) return FALSE; // NTRAID#NTBUG9-548450-2002/03/08-yasuho-: possible buffer overrun.
dwCount = 0; }
pBuf = pOEM->CPCAPKT; pBuf[3] = flags; pBuf[4] = HIBYTE(wCmd); pBuf[5] = LOBYTE(wCmd); pBuf[8] = HIBYTE(nParams); pBuf[9] = LOBYTE(nParams);
CopyMemory(&pOEM->CPCABuf[dwCount], pOEM->CPCAPKT, CPCA_PACKET_SIZE); dwCount += CPCA_PACKET_SIZE; if (nParams) { CopyMemory(&pOEM->CPCABuf[dwCount], pParams, nParams); dwCount += nParams; } pOEM->CPCABcount = dwCount;
return TRUE; }
/*
* CPCAInit */ VOID CPCAInit(PLIPSPDEV pOEM) { pOEM->CPCAPKT[0] = 0xCD; // Header ID
pOEM->CPCAPKT[1] = 0xCA; pOEM->CPCAPKT[2] = 0x10; // Version
pOEM->CPCABcount = 0; }
/*
* CPCAStart */ VOID CPCAStart(PDEVOBJ pdevobj) { PLIPSPDEV pOEM = (PLIPSPDEV)pdevobj->pdevOEM; WORD wTemp; BYTE param[32];
ZeroMemory(param, sizeof param); param[4] = 0x01; (VOID)SendCPCAPacket(pdevobj, CPCA_JobStart, 0, param, 13);
// ZeroMemory(param, 4);
(VOID)SendCPCAPacket(pdevobj, CPCA_BinderStart, 0, param, 4);
param[0] = HIBYTE(ATT_COPIES); param[1] = LOBYTE(ATT_COPIES); // NTRAID#NTBUG9-501162-2002/03/08-yasuho-: Collate does not work
if (pOEM->sorttype == SORTTYPE_SORT || pOEM->collate == COLLATE_ON) { param[2] = HIBYTE(pOEM->copies); param[3] = LOBYTE(pOEM->copies); } else { param[2] = 0x00; param[3] = 0x01; } (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 4);
// NTRAID#NTBUG9-278671-2002/03/08-yasuho-: Finisher !work
// NTRAID#NTBUG9-293002-2002/03/08-yasuho-:
// Features are different from H/W options.
if (pOEM->fCPCA2) { param[0] = HIBYTE(ATT_OUTPUT); param[1] = LOBYTE(ATT_OUTPUT); param[2] = OUTPUT_COLLATE; (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 3); }
// NTRAID#NTBUG9-203340-2002/03/08-yasuho-:
// Output tray could not selected correctly.
// NTRAID#NTBUG9-293002-2002/03/08-yasuho-:
// Features are different from H/W options.
param[0] = HIBYTE(ATT_OUTPUTBIN); param[1] = LOBYTE(ATT_OUTPUTBIN); if (pOEM->tray == INIT || pOEM->tray == 100) { param[2] = OUTPUTBIN_FACEDOWN; ZeroMemory(¶m[3], 4); } else if (pOEM->tray == 0) { param[2] = OUTPUTBIN_STACK; ZeroMemory(¶m[3], 4); } else if (pOEM->tray == 101) { param[2] = OUTPUTBIN_FACEUP; ZeroMemory(¶m[3], 4); } else { param[2] = OUTPUTBIN_NUMBER; param[3] = (BYTE)pOEM->tray; ZeroMemory(¶m[4], 3); } (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 7);
if (pOEM->method != INIT) { // Staple stacker
param[0] = HIBYTE(ATT_OUTPUTPARTITION); param[1] = LOBYTE(ATT_OUTPUTPARTITION); param[2] = (pOEM->method == METHOD_JOBOFFSET) ? OUTPART_JOBOFFSET : OUTPART_NONE; (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 3);
param[0] = HIBYTE(ATT_OUTPUTFACE); param[1] = LOBYTE(ATT_OUTPUTFACE); param[2] = (pOEM->method == METHOD_FACEUP) ? OUTPUTFACE_FACEUP : OUTPUTFACE_FACEDOWN; (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 3);
if (pOEM->method == METHOD_STAPLE) { param[0] = HIBYTE(ATT_FINISHING); param[1] = LOBYTE(ATT_FINISHING); param[2] = 1; param[3] = FINISHING_STAPLE; wTemp = pOEM->staple; if (wTemp < 0 || wTemp >= 9) wTemp = 0; // NTRAID#NTBUG9-292998-2002/03/08-yasuho-: Stapling operate incorrectly.
switch (wTemp) { default: param[4] = FINISHING_COUNT_1; break; case 1: // top
case 3: // left
case 5: // right
case 7: // center
param[4] = FINISHING_COUNT_2; break; } wTemp = wStapleModes[wTemp]; param[5] = HIBYTE(wTemp); param[6] = LOBYTE(wTemp); (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 7); } else { param[0] = HIBYTE(ATT_FINISHING); param[1] = LOBYTE(ATT_FINISHING); param[2] = 0; (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 3); } } else if (pOEM->sorttype != INIT) { // Sorter
param[0] = HIBYTE(ATT_OUTPUTBIN); param[1] = LOBYTE(ATT_OUTPUTBIN); param[2] = (pOEM->sorttype == SORTTYPE_SORT) ? OUTPUTBIN_SORT : OUTPUTBIN_STACK; ZeroMemory(¶m[3], 4); (VOID)SendCPCAPacket(pdevobj, CPCA_SetBinder, 0, param, 7); }
ZeroMemory(param, 4); (VOID)SendCPCAPacket(pdevobj, CPCA_DocumentStart, 0, param, 4);
param[0] = HIBYTE(ATT_DOCFORMAT); param[1] = LOBYTE(ATT_DOCFORMAT); param[2] = DOCFORMAT_LIPS; param[3] = 0; param[4] = 0; (VOID)SendCPCAPacket(pdevobj, CPCA_SetDocument, 0, param, 5);
// NTRAID#NTBUG9-244001-2002/03/08-yasuho-: 1200dpi doesn't work on LBP-470.
param[0] = HIBYTE(ATT_RESOLUTION); param[1] = LOBYTE(ATT_RESOLUTION); if (pOEM->resolution == 1200) param[2] = RESOLUTION_SUPERFINE; else if (pOEM->resolution == 600) param[2] = RESOLUTION_FINE; else param[2] = RESOLUTION_QUICK; ZeroMemory(¶m[3], 4); (VOID)SendCPCAPacket(pdevobj, CPCA_SetDocument, 0, param, 7);
param[0] = HIBYTE(ATT_COPIES); param[1] = LOBYTE(ATT_COPIES); // NTRAID#NTBUG9-501162-2002/03/08-yasuho-: Collate does not work
if (pOEM->sorttype != SORTTYPE_SORT && pOEM->collate != COLLATE_ON) { param[2] = HIBYTE(pOEM->copies); param[3] = LOBYTE(pOEM->copies); } else { param[2] = 0x00; param[3] = 0x01; } (VOID)SendCPCAPacket(pdevobj, CPCA_SetDocument, 0, param, 4);
(VOID)FlushCPCABuffer(pdevobj, pOEM); }
/*
* CPCAEnd */ VOID CPCAEnd(PDEVOBJ pdevobj, BOOL fColor) { PLIPSPDEV pOEM = (PLIPSPDEV)pdevobj->pdevOEM; LIPSCmd *pCmd; BYTE param[32];
param[0] = 0x01; pCmd = fColor ? &cmdEndDoc4C : &cmdEndDoc4; CopyMemory(¶m[1], pCmd->pCmdStr, pCmd->cbSize); (VOID)SendCPCAPacket(pdevobj, CPCA_Send, 0, param, pCmd->cbSize + 1);
(VOID)SendCPCAPacket(pdevobj, CPCA_DocumentEnd, 0, NULL, 0);
(VOID)SendCPCAPacket(pdevobj, CPCA_BinderEnd, 0, NULL, 0);
param[0] = 0x00; (VOID)SendCPCAPacket(pdevobj, CPCA_JobEnd, 0, param, 1);
(VOID)FlushCPCABuffer(pdevobj, pOEM); }
/*
* OEMWritePrinter */ BOOL APIENTRY OEMWritePrinter( PDEVOBJ pdevobj, PVOID pBuf, DWORD cbBuffer, PDWORD pcbWritten) { PLIPSPDEV pOEM; PBYTE pTemp, pCmd; DWORD dwSize, dwCount, dwWritten; WORD wCount; BYTE cmd[CPCA_PACKET_SIZE+1];
// This is used for UNIDRV to detect the plug-in.
if (pBuf == NULL && cbBuffer == 0) return TRUE;
pOEM = (PLIPSPDEV)pdevobj->pdevOEM;
// If printer is not CPCA, pass through to the spooler.
if (!pOEM->fCPCA) return WritePrinter(pdevobj->hPrinter, pBuf, cbBuffer, pcbWritten) && cbBuffer == *pcbWritten;
pTemp = (PBYTE)pBuf; dwSize = cbBuffer; while (dwSize > 0) { dwCount = min(dwSize, MAX_CPCA_PACKET_SIZE); // Build Send packet
pCmd = pOEM->CPCAPKT; pCmd[3] = F_Cont; pCmd[4] = HIBYTE(CPCA_Send); pCmd[5] = LOBYTE(CPCA_Send); wCount = (WORD)(dwCount + 1); pCmd[8] = HIBYTE(wCount); pCmd[9] = LOBYTE(wCount); CopyMemory(cmd, pOEM->CPCAPKT, CPCA_PACKET_SIZE); cmd[CPCA_PACKET_SIZE] = 0x01; if (!WritePrinter(pdevobj->hPrinter, cmd, sizeof cmd, &dwWritten) || sizeof cmd != dwWritten) return FALSE; if (!WritePrinter(pdevobj->hPrinter, pTemp, dwCount, &dwWritten) || dwCount != dwWritten) return FALSE; pTemp += dwCount; dwSize -= dwCount; }
*pcbWritten = cbBuffer; return TRUE; }
|