/*++ 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" #undef wsprintf #define wsprintf sprintf HRESULT SendABSMove( PDEVOBJ pdevobj, LPDWORD lpdwParams); HRESULT SpoolOut(PDEVOBJ pdevobj, FILE* pFile); 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 (dwLen == 0) 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) { 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++; } if (lpnp->wEndPad) { 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)); 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)); 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)); 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)); 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)); 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)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[0], ch, len); len = (WORD)wsprintf( &ch[0], "\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)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[2], ch, len); } else { len = (WORD)wsprintf( &ch[0], "\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)); DATASPOOL4CCB(pdevobj, lpnp->TempFile[0], ch, len); len = (WORD)wsprintf( &ch[0], "\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)); 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)); 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 (0xffffffff == 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; 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) { #if 0 TCHAR TempDir[MAX_PATH + 1]; INT iLength, iUniq; HANDLE hFile; if (0 == (iLength = GetTempPath(MAX_PATH, TempDir))) { ERR((DLLTEXT("GetTempPath failed (%d).\n"), GetLastError())) goto Error_Return; } TempDir[iLength] = __TEXT('\0'); if (0 == (iUniq = GetTempFileName(TempDir, TEMP_NAME_PREFIX, 0, pdevOEM->TempName[iPlane]))) { ERR((DLLTEXT("GetTempFileName failed (%d).\n"), GetLastError())) goto Error_Return; } #if DBG VERBOSE((DLLTEXT("Temp. file = %d\nPath: "), iUniq)); if (giDebugLevel <= DBG_VERBOSE) { OutputDebugString(pdevOEM->TempName[iPlane]); } VERBOSE(("\n")); #endif // DBG #endif // #if 0 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); 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; } }