|
|
/*++
Copyright (c) 1997-1999 Microsoft Corporation
--*/
//-----------------------------------------------------------------------------
// This files contains the module name for this mini driver. Each mini driver
// must have a unique module name. The module name is used to obtain the
// module handle of this Mini Driver. The module handle is used by the
// generic library to load in tables from the Mini Driver.
//-----------------------------------------------------------------------------
#include "pdev.h"
#include "nc82jres.h"
#include <strsafe.h>
// #undef wsprintf
// #define wsprintf sprintf
HRESULT SendABSMove( PDEVOBJ pdevobj, LPDWORD lpdwParams);
HRESULT SpoolOut(PDEVOBJ pdevobj, FILE* pFile); HANDLE RevertToPrinterSelf( VOID ); BOOL ImpersonatePrinterClient( HANDLE );
HRESULT MDP_CreateTempFile( PDEVOBJ pdevobj, LPPCPRDATASTRUCTURE pdevOEM, INT iPlane);
HRESULT DataSpool( PDEVOBJ pdevobj, HANDLE hFile, LPSTR lpBuf, DWORD dwLen);
VOID BPBCalc( PDEVOBJ pdevobj, PBYTE pDataBuf, DWORD dwLen, BYTE BPBCommand);
/*************************** Function Header *******************************
* OEMEnablePDEV * (MiniDrvEnablePDEV) * * HISTORY: * 30 Apl 1996 -by- Sueya Sugihara [sueyas] * Created it, from NT/DDI spec. * 15 Apr 1998 -by- Yoshitaka Oku [yoshitao] * Conversion to NT5.0 spec driver * ***************************************************************************/ PDEVOEM APIENTRY OEMEnablePDEV( PDEVOBJ pdevobj, PWSTR pPrinterName, ULONG cPatterns, HSURF* phsurfPatterns, ULONG cjGdiInfo, GDIINFO* pGdiInfo, ULONG cjDevInfo, DEVINFO* pDevInfo, DRVENABLEDATA * pded) { LPPCPRDATASTRUCTURE lpnp;
//DbgPrint(DLLTEXT("OEMEnablePDEV(--) entry.\r\n"));
if ((lpnp = (PCPRDATASTRUCTURE *) MemAllocZ( sizeof(PCPRDATASTRUCTURE ))) == NULL) { return 0; }
memset(lpnp, 0, sizeof (PCPRDATASTRUCTURE)); memcpy(lpnp->pszSheetSetting, SHEET_CMD_DEFAULT, SHEET_CMDLEN );
pdevobj->pdevOEM = lpnp;
return lpnp; }
/*************************** Function Header *******************************
* OEMDisablePDEV * (MiniDrvDisablePDEV) * * HISTORY: * 30 Apl 1996 -by- Sueya Sugihara [sueyas] * Created it, from NT/DDI spec. * 15 Apr 1998 -by- Yoshitaka Oku [yoshitao] * Conversion to NT5.0 spec driver * ***************************************************************************/ VOID APIENTRY OEMDisablePDEV( PDEVOBJ pdevobj) {
//DbgPrint(DLLTEXT("OEMDisablePDEV(--) entry.\r\n"));
if ( pdevobj && pdevobj->pdevOEM ) { MemFree( pdevobj->pdevOEM ); }
}
BOOL APIENTRY OEMResetPDEV( PDEVOBJ pdevobjOld, PDEVOBJ pdevobjNew) { LPPCPRDATASTRUCTURE pOEMOld, pOEMNew;
pOEMOld = (LPPCPRDATASTRUCTURE)pdevobjOld->pdevOEM; pOEMNew = (LPPCPRDATASTRUCTURE)pdevobjNew->pdevOEM;
if (pOEMOld != NULL && pOEMNew != NULL) *pOEMNew = *pOEMOld;
return TRUE; }
BOOL APIENTRY OEMFilterGraphics ( PDEVOBJ pdevobj, PBYTE pBuf, DWORD dwLen) {
LPPCPRDATASTRUCTURE lpnp;
//DbgPrint(DLLTEXT("OEMFilterGraphics(%d bytes) entry.\r\n"),dwLen);
lpnp = (LPPCPRDATASTRUCTURE)(pdevobj->pdevOEM);
if (NULL == pBuf || dwLen == 0) { // Do nothing.
return TRUE; }
//if (dwLen != lpnp->wNumScans * lpnp->wScanWidth * 3)
//DbgPrint(DLLTEXT("OEMFilterGraphics(%d bytes - %d) entry.\r\n"),dwLen,lpnp->wNumScans * lpnp->wScanWidth * 3);
// YMC(K)
// lpnp->iColor : data's color
switch( lpnp->iColor ) { case YELLOW:
// Send YELLOW data.
DATASPOOL4FG(pdevobj, lpnp->TempFile[0], pBuf, dwLen); if ( (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4) || (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4LONG) ) { BPBCalc(pdevobj, pBuf, dwLen, BPB_COPY); } break;
case MAGENTA: // Send MAGENTA data.
DATASPOOL4FG(pdevobj, lpnp->TempFile[1], pBuf, dwLen); if ( (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4) || (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4LONG) ) { BPBCalc(pdevobj, pBuf, dwLen, BPB_AND); } break;
case CYAN: // Send CYAN data.
DATASPOOL4FG(pdevobj, lpnp->TempFile[2], pBuf, dwLen); if ( (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4) || (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4LONG) ) { BPBCalc(pdevobj, pBuf, dwLen, BPB_AND); DATASPOOL4FG(pdevobj, lpnp->TempFile[3], lpnp->BPBuf, dwLen); BPBCalc(pdevobj, pBuf, dwLen, BPB_CLR); } break;
case BLACK: // Send BLACK data.
if(lpnp->bComBlackMode) { DATASPOOL4FG(pdevobj, lpnp->TempFile[0], pBuf, dwLen); DATASPOOL4FG(pdevobj, lpnp->TempFile[1], pBuf, dwLen); DATASPOOL4FG(pdevobj, lpnp->TempFile[2], pBuf, dwLen); } else DATASPOOL4FG(pdevobj, lpnp->TempFile[3], pBuf, dwLen); break;
case RGB_COLOR:
//if( lpnp->iPlaneNumber == 4 )
//break;
if(((lpnp->iRibbon == CMDID_RIBBON_3COLOR_KAICHO) || (lpnp->iRibbon == CMDID_RIBBON_3COLOR_SHOKA)) && (lpnp->iColorMode == CMDID_MODE_COLOR)) { int i, j, iDiv; LPSTR lpByte; char pad[] = "\x00\x00\x00\x00\x00\x00\x00\x00";
i = dwLen; lpByte = pBuf;
// Convert RGB to CMY
while( --i > 0 ) *lpByte++ ^= ~((BYTE)0);
if(lpnp->iRibbon == CMDID_RIBBON_3COLOR_KAICHO) //iDiv = 29; // KAICHO DATA : 9 step 29=(255+8)/9
iDiv = 32; // adjustment
else iDiv = 4; // SHOKA DATA : 64 step 4=(255+63)/64
for( j = 0; j < lpnp->wNumScans; j++) {
if (lpnp->wTopPad > 0 && lpnp->wTopPad <= sizeof(pad)) { DATASPOOL4FG(pdevobj, lpnp->TempFile[0], pad, lpnp->wTopPad); DATASPOOL4FG(pdevobj, lpnp->TempFile[1], pad, lpnp->wTopPad); DATASPOOL4FG(pdevobj, lpnp->TempFile[2], pad, lpnp->wTopPad); }
for( i = 0; i < lpnp->wScanWidth; i++) { (BYTE)(*pBuf) /= (BYTE)iDiv; DATASPOOL4FG(pdevobj, lpnp->TempFile[2], pBuf, 1); pBuf++;
(BYTE)(*pBuf) /= (BYTE)iDiv; DATASPOOL4FG(pdevobj, lpnp->TempFile[1], pBuf, 1); pBuf++;
(BYTE)(*pBuf) /= (BYTE)iDiv; DATASPOOL4FG(pdevobj, lpnp->TempFile[0], pBuf, 1); pBuf++; }
// ISSUE-2002/3/27-takashim - Please make sure wEndPad < 8!
// It should be, but need to check.
if (lpnp->wEndPad > 0 && lpnp->wEndPad <= sizeof(pad)) { DATASPOOL4FG(pdevobj, lpnp->TempFile[0], pad, lpnp->wEndPad); DATASPOOL4FG(pdevobj, lpnp->TempFile[1], pad, lpnp->wEndPad); DATASPOOL4FG(pdevobj, lpnp->TempFile[2], pad, lpnp->wEndPad); } } } else { int h, i, j, iBlack; char SpoolBin[8];
if(lpnp->iRibbon == CMDID_RIBBON_3COLOR_KAICHO) iBlack = 8; // KAICHO DATA : 9 step
else iBlack = 63; // SHOKA DATA : 64 step
for( j = 0; j < lpnp->wNumScans; j++) { for( i = 0; i < lpnp->wScanWidth; i++) { for( h = 0; h < 8; h++) SpoolBin[h] = ((*pBuf << h) & 0x80) ? iBlack : 0; DATASPOOL4FG(pdevobj, lpnp->TempFile[0], SpoolBin, 8); DATASPOOL4FG(pdevobj, lpnp->TempFile[1], SpoolBin, 8); DATASPOOL4FG(pdevobj, lpnp->TempFile[2], SpoolBin, 8); pBuf++; } } } break;
default: //DbgPrint(DLLTEXT("OEMFilterGraphics: Invalid color(%d).\r\n"), lpnp->iColor);
break;
}
return TRUE; }
INT APIENTRY OEMCommandCallback( PDEVOBJ pdevobj, DWORD dwCmdCbID, DWORD dwCount, PDWORD pdwParams) {
LPPCPRDATASTRUCTURE lpnp; WORD len; BYTE ch[100]; WORD wOutByte; WORD wOld; INT i; INT iRet = 0; HANDLE hToken = NULL;
//DbgPrint(DLLTEXT("OEMCommandCallback(%d) entry.\r\n"),dwCmdCbID );
//if ((dwCmdCbID != 25) && (dwCmdCbID != 30)&& (dwCmdCbID != 31)&& (dwCmdCbID != 60))
//DbgPrint(DLLTEXT("OEMCommandCallback(%d) entry.\r\n"),dwCmdCbID );
lpnp = (LPPCPRDATASTRUCTURE)(pdevobj->pdevOEM);
switch ( dwCmdCbID ){
case CMDID_COLOR_YELLOW: case CMDID_COLOR_MAGENTA: case CMDID_COLOR_CYAN: case CMDID_COLOR_BLACK:
// if(!(lpnp->iPlaneNumber = UniDrvGetPlaneId(pdevobj)))
if(!(lpnp->iPlaneNumber = 1)) { // MINIDBG("pcpr820!fnOEMOutputCmd: Invalid iPlaneNumber = 0 \n");
}
switch( dwCmdCbID ) { case CMDID_COLOR_YELLOW:
// Color Y
// Send \x1B%lD\x83
// pdwParams: cbOut / iBytesPCol (+ 2)
lpnp->iColor = YELLOW;
if ( E_FAIL == SendABSMove( pdevobj, pdwParams ) ) { return -1; } wOutByte = (WORD)pdwParams[0] + 2;
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x83",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x83",LOBYTE(wOutByte), HIBYTE(wOutByte));
DATASPOOL4CCB(pdevobj, lpnp->TempFile[0], ch, len); break;
case CMDID_COLOR_MAGENTA:
// Color M
// Send \x1B%lDC
// pdwParams: cbOut / iBytesPCol (+ 2)
lpnp->iColor = MAGENTA;
if ( E_FAIL == SendABSMove( pdevobj, pdwParams )) { return -1; } wOutByte = (WORD)pdwParams[0] + 2;
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x43",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x43",LOBYTE(wOutByte), HIBYTE(wOutByte));
DATASPOOL4CCB(pdevobj, lpnp->TempFile[1], ch, len); break;
case CMDID_COLOR_CYAN:
// Color C
// Send \x1B%lD# with param
// pdwParams: cbOut / iBytesPCol (+ 2)
lpnp->iColor = CYAN;
if ( E_FAIL == SendABSMove( pdevobj, pdwParams )) { return -1; } wOutByte = (WORD)pdwParams[0] + 2;
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x23",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x23",LOBYTE(wOutByte), HIBYTE(wOutByte));
DATASPOOL4CCB(pdevobj, lpnp->TempFile[2], ch, len);
if ( (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4) || (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4LONG) ) { // len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x13",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x13",LOBYTE(wOutByte), HIBYTE(wOutByte)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[3], ch, len); }
break;
case CMDID_COLOR_BLACK:
// Color K
// Send \x1B%lD\x13
// pdwParams: cbOut / iBytesPCol (+ 2)
lpnp->iColor = BLACK;
if ( E_FAIL == SendABSMove( pdevobj, pdwParams )) { return -1; } wOutByte = (WORD)pdwParams[0] + 2;
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x13",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x13",LOBYTE(wOutByte), HIBYTE(wOutByte));
DATASPOOL4CCB(pdevobj, lpnp->TempFile[3], ch, len); break; } break;
case CMDID_COLOR_BLACKONLY:
if(lpnp->iRibbon == CMDID_RIBBON_3COLOR_A4) lpnp->bComBlackMode = TRUE;
lpnp->iColor = BLACK; lpnp->iPlaneNumber = BLACK;
if ( E_FAIL == SendABSMove( pdevobj, pdwParams )) { return -1; } wOutByte = (WORD)pdwParams[0] + 2;
if(lpnp->bComBlackMode) { // If an user selects glay scale with 3colors ribbon,
// we print it with CYAN ribbon because there is not black ribbon
// Spec change on NT5.
// Make black color by 3 colors composite on this situation.
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x83",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x83",LOBYTE(wOutByte), HIBYTE(wOutByte));
DATASPOOL4CCB(pdevobj, lpnp->TempFile[0], ch, len);
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x43",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x43",LOBYTE(wOutByte), HIBYTE(wOutByte));
DATASPOOL4CCB(pdevobj, lpnp->TempFile[1], ch, len);
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x23",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x23",LOBYTE(wOutByte), HIBYTE(wOutByte)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[2], ch, len); } else { // len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x13",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x13",LOBYTE(wOutByte), HIBYTE(wOutByte)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[3], ch, len); }
break;
case CMDID_COLOR_RGB:
if (pdwParams[0] == 0) break;
// DbgPrint(DLLTEXT("BlockData(%d,%d,%d)\r\n"),pdwParams[0],pdwParams[1],pdwParams[2] );
lpnp->iColor = RGB_COLOR;
// if(!(lpnp->iPlaneNumber = UniDrvGetPlaneId(pdevobj)))
if(!(lpnp->iPlaneNumber = 1)) { // MINIDBG("pcpr820!fnOEMOutputCmd: Invalid iPlaneNumber = 0 \n");
}
// This is 3 plane model.
if( lpnp->iPlaneNumber == 4 ) break;
if ( E_FAIL == SendABSMove( pdevobj, pdwParams )) { return -1; } wOutByte = (WORD)(lpnp->wScanBytes * lpnp->wNumScans * 8) + 2;
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x83",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x83",LOBYTE(wOutByte), HIBYTE(wOutByte)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[0], ch, len);
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x43",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x43",LOBYTE(wOutByte), HIBYTE(wOutByte)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[1], ch, len);
// len = (WORD)wsprintf( &ch[0], "\x1B%c%cD\x23",
// LOBYTE(wOutByte), HIBYTE(wOutByte));
len = 5; StringCchPrintfA(&ch[0],sizeof(ch),"\x1B%c%cD\x23",LOBYTE(wOutByte), HIBYTE(wOutByte)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[2], ch, len);
break;
// \x1B\x09\x00C%l%l param1 /8 param2 none
// store x and y positions
case CMDID_X_ABS_MOVE: wOld = lpnp->wXpos; lpnp->wXpos = (WORD)pdwParams[0]; return (lpnp->wXpos > wOld ? lpnp->wXpos - wOld : wOld - lpnp->wXpos);
case CMDID_Y_ABS_MOVE: wOld = lpnp->wYpos; lpnp->wYpos = (WORD)pdwParams[0]; return (lpnp->wYpos > wOld ? lpnp->wYpos - wOld : wOld - lpnp->wYpos);
case 60: // CmdYMoveRelDown
//DbgPrint(DLLTEXT("CmdYMoveRelDown(%d) \r\n"),pdwParams[0] );
lpnp->wYpos += (WORD)pdwParams[0]; return pdwParams[0];
case CMDID_BEGINPAGE:
BPBCalc(pdevobj, 0, BPB_SIZE, BPB_CLR);
if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x01\x00\x47", 4)) { return -1; } switch (lpnp->iRibbon) {
case CMDID_RIBBON_MONO: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x02\x00\x44\x10", 5)) { return -1; } break;
case CMDID_RIBBON_3COLOR_A4: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x02\x00\x44\xe0", 5)) { return -1; } break;
case CMDID_RIBBON_4COLOR_A4: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x02\x00\x44\xf0", 5)) { return -1; } break;
case CMDID_RIBBON_4COLOR_A4LONG: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x02\x00\x44\xf1", 5)) { return -1; } break;
case CMDID_RIBBON_3COLOR_KAICHO: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x02\x00\x44\xe2", 5)) { return -1; } break;
case CMDID_RIBBON_3COLOR_SHOKA: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x02\x00\x44\xe3", 5)) { return -1; } break;
default: // MINIDBG("pcpr820!fnOEMOutputCmd: Invalid Ribbon ID = %d \n", lpnp->iRibbon );
return FALSE; }
if ( E_FAIL == MDP_CreateTempFile(pdevobj, pdevobj->pdevOEM, 0)) { return -1; } if ( E_FAIL == MDP_CreateTempFile(pdevobj, pdevobj->pdevOEM, 1)) { return -1; } if ( E_FAIL == MDP_CreateTempFile(pdevobj, pdevobj->pdevOEM, 2)) { return -1; } if ( E_FAIL == MDP_CreateTempFile(pdevobj, pdevobj->pdevOEM, 3)) { return -1; } lpnp->wXpos = 0; lpnp->wYpos = 0; lpnp->iFirstColor = 0; lpnp->wOldNumScans = 0; lpnp->bComBlackMode = FALSE; break;
case CMDID_ENDPAGE:
SpoolOut(pdevobj, lpnp->TempFile[0]); SpoolOut(pdevobj, lpnp->TempFile[1]); SpoolOut(pdevobj, lpnp->TempFile[2]); SpoolOut(pdevobj, lpnp->TempFile[3]);
// Close cache files.
for (i = 0; i < 4; i++) { if (INVALID_HANDLE_VALUE != lpnp->TempFile[i]) { if (0 == CloseHandle(lpnp->TempFile[i])) { ERR((DLLTEXT("CloseHandle error %d\n"), GetLastError())); } lpnp->TempFile[i] = INVALID_HANDLE_VALUE;
hToken = RevertToPrinterSelf(); if (0 == DeleteFile(lpnp->TempName[i])) { ERR((DLLTEXT("DeleteName error %d\n"), GetLastError())); } if (hToken != NULL) { (VOID)ImpersonatePrinterClient(hToken); } lpnp->TempName[i][0] = __TEXT('\0'); } }
if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x01\x00\x48", 4)) { return -1; } break;
case CMDID_SELECT_RESOLUTION:
switch (lpnp->iRibbon) {
case CMDID_RIBBON_3COLOR_KAICHO: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x03\x00\x41\x2c\x01\x1b\x03\x00\x42\x10\x00", 12)) { return -1; } break;
case CMDID_RIBBON_3COLOR_SHOKA: if ( E_FAIL == WRITESPOOLBUF(pdevobj, (LPSTR)"\x1b\x03\x00\x41\x2c\x01\x1b\x03\x00\x42\x20\x00", 12)) { return -1; } break; }
break;
case CMDID_RIBBON_MONO: lpnp->iRibbon = CMDID_RIBBON_MONO; break;
case CMDID_RIBBON_3COLOR_A4: lpnp->iRibbon = CMDID_RIBBON_3COLOR_A4; break;
case CMDID_RIBBON_4COLOR_A4: lpnp->iRibbon = CMDID_RIBBON_4COLOR_A4; break;
case CMDID_RIBBON_4COLOR_A4LONG: lpnp->iRibbon = CMDID_RIBBON_4COLOR_A4LONG; break;
case CMDID_RIBBON_3COLOR_KAICHO: lpnp->iRibbon = CMDID_RIBBON_3COLOR_KAICHO; break;
case CMDID_RIBBON_3COLOR_SHOKA: lpnp->iRibbon = CMDID_RIBBON_3COLOR_SHOKA; break;
case CMDID_PSIZE_LETTER: lpnp->pszSheetSetting[4] = P1_LETTER; break;
case CMDID_PSIZE_LEGAL: lpnp->pszSheetSetting[4] = P1_LEGAL; break;
case CMDID_PSIZE_A4: lpnp->pszSheetSetting[4] = P1_A4; break;
case CMDID_PSIZE_A4LONG: lpnp->pszSheetSetting[4] = P1_A4LONG; break;
case CMDID_PSIZE_B5: lpnp->pszSheetSetting[4] = P1_B5; break;
case CMDID_PSIZE_POSTCARD: lpnp->pszSheetSetting[4] = P1_POSTCARD; break;
case CMDID_PSOURCE_HOPPER: lpnp->pszSheetSetting[5] = P2_HOPPER; if ( E_FAIL == WRITESPOOLBUF(pdevobj, lpnp->pszSheetSetting, SHEET_CMDLEN)) { return -1; } break;
case CMDID_PSOURCE_MANUAL: lpnp->pszSheetSetting[5] = P2_MANUAL; if ( E_FAIL == WRITESPOOLBUF(pdevobj, lpnp->pszSheetSetting, SHEET_CMDLEN)) { return -1; } break;
case CMDID_MODE_COLOR: lpnp->iColorMode = CMDID_MODE_COLOR; break;
case CMDID_MODE_MONO: lpnp->iColorMode = CMDID_MODE_MONO; break; } return iRet; }
/*
HRESULT SendABSMove
When this function succeeds, it returns S_OK. When this function fails, it returns E_FAIL */ HRESULT SendABSMove( PDEVOBJ pdevobj, LPDWORD lpdwParams) { LPPCPRDATASTRUCTURE lpnp; WORD len; BYTE ch[100];
lpnp = (LPPCPRDATASTRUCTURE)(pdevobj->pdevOEM);
lpnp->wNumScans = (WORD)lpdwParams[1]; lpnp->wScanWidth = (WORD)lpdwParams[2]; // already converted to byte unit in rasdd
if((lpnp->iColor == RGB_COLOR) && (lpnp->iColorMode == CMDID_MODE_COLOR)) { lpnp->wScanWidth /= 3; // one of RGB byte
lpnp->wScanBytes = (lpnp->wXpos + lpnp->wScanWidth)/8 - lpnp->wXpos/8 + 1; lpnp->wTopPad = lpnp->wXpos % 8; lpnp->wEndPad = (lpnp->wScanBytes * 8) - lpnp->wScanWidth - lpnp->wTopPad; } else { lpnp->wScanBytes = lpnp->wScanWidth; lpnp->wTopPad = 0; lpnp->wEndPad = 0; }
if (lpnp->iFirstColor == 0) lpnp->iFirstColor = lpnp->iColor;
if (lpnp->iFirstColor == lpnp->iColor) { lpnp->wYpos += lpnp->wOldNumScans; lpnp->wOldNumScans = lpnp->wNumScans; }
ch[0] = 0x1B; ch[1] = 0x09; ch[2] = 0;
// len = (WORD)wsprintf( &ch[3], "C%c%c%c%c%c%c%c%c",
// LOBYTE(lpnp->wXpos/8), HIBYTE(lpnp->wXpos/8),
// LOBYTE(lpnp->wYpos), HIBYTE(lpnp->wYpos),
// LOBYTE(lpnp->wScanBytes), HIBYTE(lpnp->wScanBytes),
// LOBYTE(lpnp->wNumScans), HIBYTE(lpnp->wNumScans));
len = 9; StringCchPrintfA(&ch[3],(sizeof(ch) - 3),"C%c%c%c%c%c%c%c%c", LOBYTE(lpnp->wXpos/8), HIBYTE(lpnp->wXpos/8), LOBYTE(lpnp->wYpos), HIBYTE(lpnp->wYpos), LOBYTE(lpnp->wScanBytes), HIBYTE(lpnp->wScanBytes), LOBYTE(lpnp->wNumScans), HIBYTE(lpnp->wNumScans));
switch (lpnp->iColor) { case YELLOW: return( DataSpool(pdevobj, lpnp->TempFile[0], ch, len+3) );
case MAGENTA: return( DataSpool(pdevobj, lpnp->TempFile[1], ch, len+3) ); break;
case CYAN: if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[2], ch, len+3) ){ return E_FAIL; }
if ( (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4) || (lpnp->iRibbon == CMDID_RIBBON_4COLOR_A4LONG) ) { if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[3], ch, len+3) ) { return E_FAIL; } } break;
case BLACK: if(lpnp->bComBlackMode) { if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[0], ch, len+3) ) { return E_FAIL; } if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[1], ch, len+3) ) { return E_FAIL; } if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[2], ch, len+3)) { return E_FAIL; } } else return( DataSpool(pdevobj, lpnp->TempFile[3], ch, len+3) ); break;
case RGB_COLOR: if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[0], ch, len+3) ) { return E_FAIL; } if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[1], ch, len+3) ) { return E_FAIL; } if ( E_FAIL == DataSpool(pdevobj, lpnp->TempFile[2], ch, len+3) ) { return E_FAIL; } break; }
// DbgPrint(DLLTEXT("SendABS(%d,%d,%d,%d)\r\n"), lpnp->wXpos, lpnp->wYpos, lpnp->wScanWidth, lpnp->wNumScans );
return S_OK;
}
/*
HRESULT SpoolOut
When this function succeeds, it returns S_OK. When this function fails, it returns E_FAIL */
HRESULT SpoolOut(PDEVOBJ pdevobj, FILE* pFile) { int Size, Move, Move2; #define BUF_SIZE 1024
BYTE Tmp[BUF_SIZE];
// spooled data output
Size = SetFilePointer(pFile, 0L, NULL, FILE_CURRENT); if (INVALID_SET_FILE_POINTER == Size) { ERR((DLLTEXT("SetFilePointer failed %d\n"), GetLastError())); return E_FAIL; }
if (0L != SetFilePointer(pFile, 0L, NULL, FILE_BEGIN)) {
ERR((DLLTEXT("SetFilePointer failed %d\n"), GetLastError())); return E_FAIL; }
while(Size){ Move = Size > BUF_SIZE ? BUF_SIZE : Size; if (0 == ReadFile(pFile, Tmp, Move, &Move2, NULL)) { ERR((DLLTEXT("ReadFile error in SendCachedData.\n"))); return E_FAIL; } if ( E_FAIL == WRITESPOOLBUF(pdevobj, Tmp, Move2)) { return E_FAIL; } Size -= Move2; } return S_OK; }
/*++
Routine Description:
This function comes up with a name for a spool file that we should be able to write to.
Note: The file name returned has already been created.
Arguments:
hPrinter - handle to the printer that we want a spool file for.
ppwchSpoolFileName: pointer that will receive an allocated buffer containing the file name to spool to. CALLER MUST FREE. Use LocalFree().
Return Value:
TRUE if everything goes as expected. FALSE if anything goes wrong.
--*/
BOOL GetSpoolFileName( IN HANDLE hPrinter, IN OUT PWCHAR pwchSpoolPath ) { PBYTE pBuffer = NULL; DWORD dwAllocSize; DWORD dwNeeded = 0; DWORD dwRetval; HANDLE hToken=NULL;
//
// In order to find out where the spooler's directory is, we add
// call GetPrinterData with DefaultSpoolDirectory.
//
dwAllocSize = ( MAX_PATH + 1 ) * sizeof (WCHAR);
for (;;) { pBuffer = LocalAlloc( LMEM_FIXED, dwAllocSize );
if ( pBuffer == NULL ) { ERR((DLLTEXT("LocalAlloc faild, %d\n"), GetLastError())); goto Failure; }
if ( GetPrinterData( hPrinter, SPLREG_DEFAULT_SPOOL_DIRECTORY, NULL, pBuffer, dwAllocSize, &dwNeeded ) == ERROR_SUCCESS ) { break; }
if ( ( dwNeeded < dwAllocSize ) ||( GetLastError() != ERROR_MORE_DATA )) { ERR((DLLTEXT("GetPrinterData failed in a non-understood way.\n"))); goto Failure; }
//
// Free the current buffer and increase the size that we try to allocate
// next time around.
//
LocalFree( pBuffer );
dwAllocSize = dwNeeded; }
hToken = RevertToPrinterSelf();
if( !GetTempFileName( (LPWSTR)pBuffer, TEMP_NAME_PREFIX, 0, pwchSpoolPath )) { goto Failure; }
//
// At this point, the spool file name should be done. Free the structure
// we used to get the spooler temp dir and return.
//
LocalFree( pBuffer );
if (NULL != hToken) { (VOID)ImpersonatePrinterClient(hToken); }
return( TRUE );
Failure:
//
// Clean up and fail.
//
if ( pBuffer != NULL ) { LocalFree( pBuffer ); }
if (hToken != NULL) { (VOID)ImpersonatePrinterClient(hToken); } return( FALSE ); }
/*
HRESULT MDP_CreateTempFile
When this function succeeds, it returns S_OK. When this function fails, it returns E_FAIL */
HRESULT MDP_CreateTempFile( PDEVOBJ pdevobj, LPPCPRDATASTRUCTURE pdevOEM, INT iPlane) { HANDLE hToken = NULL; HANDLE hFile;
if (!GetSpoolFileName(pdevobj->hPrinter, pdevOEM->TempName[iPlane])) { DBGPRINT(DBG_WARNING, ("GetSpoolFileName failed.\n")); return E_FAIL; }
hToken = RevertToPrinterSelf();
hFile = CreateFile(pdevOEM->TempName[iPlane], (GENERIC_READ | GENERIC_WRITE), 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hToken != NULL) { (VOID)ImpersonatePrinterClient(hToken); }
if (hFile == INVALID_HANDLE_VALUE) { ERR((DLLTEXT("CreateFile failed.\n"))) DeleteFile(pdevOEM->TempName[iPlane]); goto Error_Return; }
pdevOEM->TempFile[iPlane] = hFile;
// Normal return
return S_OK;
Error_Return: pdevOEM->TempName[iPlane][0] = __TEXT('\0'); pdevOEM->TempFile[iPlane] = INVALID_HANDLE_VALUE;
return E_FAIL; }
/*
HRESULT DataSpool
Sending data to a specified file or spooler. When this function succeeds, it returns S_OK. When this function fails, it returns E_FAIL */
HRESULT DataSpool( PDEVOBJ pdevobj, HANDLE hFile, LPSTR lpBuf, DWORD dwLen) { DWORD dwTemp, dwTemp2; BYTE *pTemp;
if (hFile != INVALID_HANDLE_VALUE) {
pTemp = lpBuf; dwTemp = dwLen; while (dwTemp > 0) {
if (0 == WriteFile(hFile, pTemp, dwTemp, &dwTemp2, NULL)) {
ERR((DLLTEXT("WriteFile error in CacheData %d.\n"), GetLastError())); return E_FAIL; } pTemp += dwTemp2; dwTemp -= dwTemp2; } return S_OK; } else { if ( S_OK == WRITESPOOLBUF(pdevobj, lpBuf, dwLen) ) { return S_OK; } }
return E_FAIL; }
VOID BPBCalc( PDEVOBJ pdevobj, PBYTE pDataBuf, DWORD dwLen, BYTE BPBCommand) { DWORD i; LPPCPRDATASTRUCTURE lpnp;
lpnp = (LPPCPRDATASTRUCTURE)(pdevobj->pdevOEM);
if (sizeof(lpnp->BPBuf)/sizeof(*lpnp->BPBuf) < dwLen) { // Can only process upto the length of our temp. buffer.
dwLen = sizeof(lpnp->BPBuf)/sizeof(*lpnp->BPBuf); }
switch(BPBCommand) { case BPB_CLR: for( i = 0; i < dwLen; i++ ) lpnp->BPBuf[i] = 0; break;
case BPB_COPY: for( i = 0; i < dwLen; i++ ) lpnp->BPBuf[i] = pDataBuf[i]; break;
case BPB_AND: for( i = 0; i < dwLen; i++ ) lpnp->BPBuf[i] &= pDataBuf[i]; break;
case BPB_OR: for( i = 0; i < dwLen; i++ ) lpnp->BPBuf[i] |= pDataBuf[i]; break;
} }
/*++
Routine Name
ImpersonationToken
Routine Description:
This routine checks if a token is a primary token or an impersonation token. Arguments:
hToken - impersonation token or primary token of the process Return Value:
TRUE, if the token is an impersonation token FALSE, otherwise. --*/ BOOL ImpersonationToken( IN HANDLE hToken ) { BOOL bRet = TRUE; TOKEN_TYPE eTokenType; DWORD cbNeeded; DWORD LastError;
//
// Preserve the last error. Some callers of ImpersonatePrinterClient (which
// calls ImpersonationToken) rely on the fact that ImpersonatePrinterClient
// does not alter the last error.
//
LastError = GetLastError(); //
// Get the token type from the thread token. The token comes
// from RevertToPrinterSelf. An impersonation token cannot be
// queried, because RevertToPRinterSelf doesn't open it with
// TOKEN_QUERY access. That's why we assume that hToken is
// an impersonation token by default
//
if (GetTokenInformation(hToken, TokenType, &eTokenType, sizeof(eTokenType), &cbNeeded)) { bRet = eTokenType == TokenImpersonation; } SetLastError(LastError);
return bRet; }
/*++
Routine Name
RevertToPrinterSelf
Routine Description:
This routine will revert to the local system. It returns the token that ImpersonatePrinterClient then uses to imersonate the client again. If the current thread doesn't impersonate, then the function merely returns the primary token of the process. (instead of returning NULL) Thus we honor a request for reverting to printer self, even if the thread is not impersonating. Arguments:
None. Return Value:
NULL, if the function failed HANDLE to token, otherwise. --*/ HANDLE RevertToPrinterSelf( VOID ) { HANDLE NewToken, OldToken, cToken; BOOL Status;
NewToken = NULL;
Status = OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &OldToken); if (Status) { //
// We are currently impersonating
//
cToken = GetCurrentThread(); Status = SetThreadToken(&cToken, NewToken); if (!Status) { return NULL; } } else if (GetLastError() == ERROR_NO_TOKEN) { //
// We are not impersonating
//
Status = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &OldToken);
if (!Status) { return NULL; } } return OldToken; }
/*++
Routine Name
ImpersonatePrinterClient
Routine Description:
This routine attempts to set the passed in hToken as the token for the current thread. If hToken is not an impersonation token, then the routine will simply close the token. Arguments:
hToken - impersonation token or primary token of the process Return Value:
TRUE, if the function succeeds in setting hToken FALSE, otherwise. --*/ BOOL ImpersonatePrinterClient( HANDLE hToken) { BOOL Status; HANDLE cToken;
//
// Check if we have an impersonation token
//
if (ImpersonationToken(hToken)) { cToken = GetCurrentThread(); Status = SetThreadToken(&cToken, hToken);
if (!Status) { return FALSE; } }
CloseHandle(hToken);
return TRUE; }
|