Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1702 lines
50 KiB

/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
ib587res.c
Abstract:
Implementation of GPD command callback for "test.gpd":
OEMCommandCallback
Environment:
Windows NT Unidrv driver
--*/
#include "pdev.h"
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
HANDLE RevertToPrinterSelf( VOID );
BOOL ImpersonatePrinterClient( HANDLE );
/*--------------------------------------------------------------------------*/
/* G L O B A L V A L U E */
/*--------------------------------------------------------------------------*/
//Command strings
//
const BYTE CMD_BEGIN_DOC_1[] = {0x1B,0x7E,0xB0,0x00,0x12,0x01} ;
const BYTE CMD_BEGIN_DOC_2[] = {0x01,0x01,0x00} ;
const BYTE CMD_BEGIN_DOC_3[] = {0x02,0x02,0xFF,0xFF} ;
const BYTE CMD_BEGIN_DOC_4[] = {0x03,0x02,0xFF,0xFF} ;
const BYTE CMD_BEGIN_DOC_5[] = {0x04,0x04,0xFF,0xFF,0xFF,0xFF} ;
// ISSUE-2002/3/18-takashim - Not sure why CMD_BEGIN_PAGE[] was defined as 2 bytes.
//const BYTE CMD_BEGIN_PAGE[] = {0xD4, 0x00} ;
const BYTE CMD_BEGIN_PAGE[] = {0xD4} ;
const BYTE CMD_END_JOB[] = {0x1B,0x7E,0xB0,0x00,0x04,0x01,0x01,0x01,0x01} ;
const BYTE CMD_END_PAGE[] = {0x20};
//SetPac
#define CMD_SETPAC pOEM->SetPac
#define CMD_SETPAC_FRONT_TRAY_PAPER_SIZE 4
#define CMD_SETPAC_INPUT_BIN 5
#define CMD_SETPAC_RESOLUTION 12
#define CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE 14
#define CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE 15
#define CMD_SETPAC_PAGE_LENGTH 19 // 4 bytes
#define CMD_SETPAC_TONER_SAVE_MODE 25
#define CMD_SETPAC_CUSTOM_DOTS_PER_LINE 26 // 2 bytes
#define CMD_SETPAC_CUSTOM_LINES_PER_PAGE 28 // 2 bytes
const BYTE CMD_SETPAC_TMPL[
CMD_SETPAC_SIZE] ={ 0xD7,
0x01,
0xD0,
0x1D, //CommandLength
0x00, //Front tray paper size
0x00, //Input-bin
0x01,
0x04, //Bit-assign1
0xD9, //Bit-assign2
0x04, //EET
0x02, //PrintDensity
0x01,
0x00, //Resolution
0x01,
0x00, //1st cassette paper size
0x00, //2nd cassette paper size
0x0F, //Time to Power Save
0x00,
0x01, //Compression Mode
0x00,0x00,0x00,0x00, //PageLength
0x07,
0x00, //Number of Copies
0x00, //Toner save mode
0x00,0x00, //Dot per line for custom size
0x00,0x00, //Data lines per page for custom size
0x00} ;
const BYTE Mask[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01} ;
const POINTL phySize300[] = {
// Width,Height Physical paper size for 300dpi
{3416,4872}, //A3
{2392,3416}, //A4
{1672,2392}, //A5
{2944,4208}, //B4
{2056,2944}, //B5
{1088,1656}, //PostCard
{2456,3208}, //Letter
{2456,4112}, //Legal
{0000,0000}, //user define
};
const POINTL phySize600[] = {
// Width,Height Physical paper size for 600dpi
{6832,9736}, //A3
{4776,6832}, //A4
{3336,4776}, //A5
{5888,8416}, //B4
{4112,5888}, //B5
{2176,3312}, //PostCard
{4912,6416}, //Letter
{4912,8216}, //Legal
{0000,0000}, //user define
};
/******************* FUNCTIONS *************************/
BOOL MyDeleteFile(PDEVOBJ pdevobj, LPSB lpsb) ;
BOOL InitSpoolBuffer(LPSB lpsb) ;
BOOL MyCreateFile(PDEVOBJ pdevobj, LPSB lpsb) ;
BOOL MySpool(PDEVOBJ pdevobj, LPSB lpsb, PBYTE pBuf, DWORD dwLen) ;
BOOL SpoolOut(PDEVOBJ pdevobj, LPSB lpsb) ;
BOOL MyEndDoc(PDEVOBJ pdevobj) ;
BOOL WriteFileForP_Paper(PDEVOBJ pdevobj, PBYTE pBuf, DWORD dwLen) ;
BOOL WriteFileForL_Paper(PDEVOBJ pdevobj, PBYTE pBuf, DWORD dwLen) ;
BOOL FillPageRestData(PDEVOBJ pdevobj) ;
BOOL SpoolWhiteData(PDEVOBJ pdevobj, DWORD dwWhiteLen, BOOL fComp) ;
BOOL SendPageData(PDEVOBJ pdevobj, PBYTE pSrcImage, DWORD dwLen) ;
BOOL SpoolOutChangedData(PDEVOBJ pdevobj, LPSB lpsb) ;
WORD GetPrintableArea(WORD physSize, INT iRes) ;
BOOL AllocTempBuffer(PIBMPDEV pOEM, DWORD dwNewBufLen) ;
BOOL MyEndPage(PDEVOBJ pdevobj) ;
BOOL MyStartDoc(PDEVOBJ pdevobj) ;
BOOL SpoolOutCompStart(PSOCOMP pSoc);
BOOL SpoolOutCompEnd(PSOCOMP pSoc, PDEVOBJ pdevobj, LPSB psb);
BOOL SpoolOutComp(PSOCOMP pSoc, PDEVOBJ pdevobj, LPSB psb,
PBYTE pjBuf, DWORD dwLen);
/*****************************************************************************/
/* */
/* Module: IB587RES.DLL *
/* */
/* Function: OEMEnablePDEV */
/* */
/* Syntax: PDEVOEM APIENTRY OEMEnablePDEV( */
/* PDEVOBJ pdevobj, */
/* PWSTR pPrinterName, */
/* ULONG cPatterns, */
/* HSURF *phsurfPatterns, */
/* ULONG cjGdiInfo, */
/* GDIINFO *pGdiInfo, */
/* ULONG cjDevInfo, */
/* DEVINFO *pDevInfo, */
/* DRVENABLEDATA *pded) */
/* */
/* Description: Allocate buffer of private data to pdevobj */
/* */
/*****************************************************************************/
PDEVOEM APIENTRY
OEMEnablePDEV(
PDEVOBJ pdevobj,
PWSTR pPrinterName,
ULONG cPatterns,
HSURF *phsurfPatterns,
ULONG cjGdiInfo,
GDIINFO *pGdiInfo,
ULONG cjDevInfo,
DEVINFO *pDevInfo,
DRVENABLEDATA *pded)
{
PIBMPDEV pOEM;
if (!VALID_PDEVOBJ(pdevobj))
{
return NULL;
}
if(!pdevobj->pdevOEM)
{
if(!(pdevobj->pdevOEM = MemAlloc(sizeof(IBMPDEV))))
{
//DBGPRINT(DBG_WARNING, (ERRORTEXT("OEMEnablePDEV:Memory alloc failed.\n")));
return NULL;
}
}
pOEM = (PIBMPDEV)(pdevobj->pdevOEM);
// Setup pdev specific conrol block fields
ZeroMemory(pOEM, sizeof(IBMPDEV));
CopyMemory(pOEM->SetPac, CMD_SETPAC_TMPL, sizeof(CMD_SETPAC_TMPL));
return pdevobj->pdevOEM;
}
/*****************************************************************************/
/* */
/* Module: IB587RES.DLL */
/* */
/* Function: OEMDisablePDEV */
/* */
/* Description: Free buffer of private data */
/* */
/*****************************************************************************/
VOID APIENTRY
OEMDisablePDEV(
PDEVOBJ pdevobj)
{
if (!VALID_PDEVOBJ(pdevobj))
{
return;
}
if(pdevobj->pdevOEM)
{
if (((PIBMPDEV)(pdevobj->pdevOEM))->pTempImage) {
MemFree(((PIBMPDEV)(pdevobj->pdevOEM))->pTempImage);
((PIBMPDEV)(pdevobj->pdevOEM))->pTempImage = 0;
}
MemFree(pdevobj->pdevOEM);
pdevobj->pdevOEM = NULL;
}
return;
}
BOOL APIENTRY OEMResetPDEV(
PDEVOBJ pdevobjOld,
PDEVOBJ pdevobjNew)
{
PIBMPDEV pOEMOld, pOEMNew;
PBYTE pTemp;
DWORD dwTemp;
if (!VALID_PDEVOBJ(pdevobjOld)
|| !VALID_PDEVOBJ(pdevobjNew))
{
return FALSE;
}
pOEMOld = (PIBMPDEV)pdevobjOld->pdevOEM;
pOEMNew = (PIBMPDEV)pdevobjNew->pdevOEM;
if (pOEMOld != NULL && pOEMNew != NULL) {
// Save pointer and length
pTemp = pOEMNew->pTempImage;
dwTemp = pOEMNew->dwTempBufLen;
*pOEMNew = *pOEMOld;
// Restore..
pOEMNew->pTempImage = pTemp;
pOEMNew->dwTempBufLen = dwTemp;
}
return TRUE;
}
/*****************************************************************************/
/* */
/* Module: OEMFilterGraphics */
/* */
/* Function: */
/* */
/* Syntax: BOOL APIENTRY OEMFilterGraphics(PDEVOBJ, PBYTE, DWORD) */
/* */
/* Input: pdevobj address of PDEVICE structure */
/* pBuf points to buffer of graphics data */
/* dwLen length of buffer in bytes */
/* */
/* Output: BOOL */
/* */
/* Notice: nFunction and Escape numbers are the same */
/* */
/*****************************************************************************/
BOOL
APIENTRY
OEMFilterGraphics(
PDEVOBJ pdevobj,
PBYTE pBuf,
DWORD dwLen)
{
PIBMPDEV pOEM;
BOOL bRet;
if (!VALID_PDEVOBJ(pdevobj))
{
return FALSE;
}
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
bRet = TRUE;
if(pOEM->fChangeDirection) {
bRet = WriteFileForL_Paper(pdevobj, pBuf, dwLen);
}else{
bRet = WriteFileForP_Paper(pdevobj, pBuf, dwLen);
}
return bRet;
}
/*****************************************************************************/
/* */
/* Module: OEMCommandCallback */
/* */
/* Function: */
/* */
/* Syntax: INT APIENTRY OEMCommandCallback(PDEVOBJ,DWORD,DWORD,PDWORD) */
/* */
/* Input: pdevobj */
/* dwCmdCbID */
/* dwCount */
/* pdwParams */
/* */
/* Output: INT */
/* */
/* Notice: */
/* */
/*****************************************************************************/
INT APIENTRY
OEMCommandCallback(
PDEVOBJ pdevobj, // Points to private data required by the Unidriver.dll
DWORD dwCmdCbID, // Callback ID
DWORD dwCount, // Counts of command parameter
PDWORD pdwParams ) // points to values of command params
{
PIBMPDEV pOEM;
WORD wPhysWidth;
WORD wPhysHeight;
WORD wDataLen ;
WORD wLines ;
WORD wNumOfByte ;
POINTL ptlUserDefSize;
BYTE byOutput[64];
DWORD dwNeeded;
DWORD dwOptionsReturned;
INT iRet;
if (!VALID_PDEVOBJ(pdevobj))
{
return FALSE;
}
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
iRet = 0;
switch(dwCmdCbID)
{
case PAGECONTROL_BEGIN_DOC:
if (!InitSpoolBuffer(&(pOEM->sb)))
goto fail;
if (!MyCreateFile(pdevobj, &(pOEM->sb)))
goto fail;
if (!MyCreateFile(pdevobj, &(pOEM->sbcomp)))
goto fail;
pOEM->fChangeDirection = FALSE ;
pOEM->sPageNum = 0 ;
if (!MyStartDoc(pdevobj))
goto fail;
break;
case PAGECONTROL_BEGIN_PAGE:
pOEM->dwCurCursorY = 0 ;
pOEM->dwOffset = 0 ;
pOEM->sPageNum ++ ;
if(pOEM->fChangeDirection == FALSE) {
if (!MySpool(pdevobj, &(pOEM->sb),
(PBYTE)CMD_BEGIN_PAGE, sizeof(CMD_BEGIN_PAGE)))
goto fail;
if (!SpoolOutCompStart(&pOEM->Soc))
goto fail;
}
break;
case PAGECONTROL_END_PAGE:
if(pOEM->fChangeDirection == FALSE){
if (!FillPageRestData(pdevobj))
goto fail;
if (!SpoolOutCompEnd(&pOEM->Soc, pdevobj, &pOEM->sb))
goto fail;
if (!MySpool(pdevobj,&(pOEM->sb),
(PBYTE)CMD_END_PAGE, sizeof(CMD_END_PAGE)))
goto fail;
}else{
if (!SpoolOutChangedData(pdevobj, &(pOEM->sbcomp)))
goto fail;
}
if (!MyEndPage(pdevobj))
goto fail;
break;
case PAGECONTROL_ABORT_DOC:
case PAGECONTROL_END_DOC:
if (!MyEndDoc(pdevobj))
goto fail;
break;
case RESOLUTION_300:
pOEM->ulHorzRes = 300;
pOEM->ulVertRes = 300;
CMD_SETPAC[CMD_SETPAC_RESOLUTION] = 0x02 ;
if (pOEM->sPaperSize < PHYS_PAPER_BASE
|| pOEM->sPaperSize > PHYS_PAPER_MAX)
{
goto fail;
}
else if( pOEM->sPaperSize == PHYS_PAPER_UNFIXED){
pOEM->szlPhysSize.cx = PARAM(pdwParams, 0);
pOEM->szlPhysSize.cy = PARAM(pdwParams, 1);
ptlUserDefSize.x = GetPrintableArea((WORD)pOEM->szlPhysSize.cx, RESOLUTION_300);
ptlUserDefSize.y = GetPrintableArea((WORD)pOEM->szlPhysSize.cy, RESOLUTION_300);
pOEM->ptlLogSize = ptlUserDefSize;
CMD_SETPAC[CMD_SETPAC_CUSTOM_DOTS_PER_LINE] = LOBYTE((WORD)(ptlUserDefSize.x));
CMD_SETPAC[CMD_SETPAC_CUSTOM_DOTS_PER_LINE + 1] = HIBYTE((WORD)(ptlUserDefSize.x));
CMD_SETPAC[CMD_SETPAC_CUSTOM_LINES_PER_PAGE] = LOBYTE((WORD)(ptlUserDefSize.y));
CMD_SETPAC[CMD_SETPAC_CUSTOM_LINES_PER_PAGE + 1] = HIBYTE((WORD)(ptlUserDefSize.y));
}
else
{
pOEM->ptlLogSize = phySize300[
pOEM->sPaperSize-PHYS_PAPER_BASE];
}
break;
case RESOLUTION_600:
pOEM->ulHorzRes = 600;
pOEM->ulVertRes = 600;
pOEM->ptlLogSize = phySize600[pOEM->sPaperSize-50];
CMD_SETPAC[CMD_SETPAC_RESOLUTION] = 0x20 ;
if (pOEM->sPaperSize < PHYS_PAPER_BASE
|| pOEM->sPaperSize > PHYS_PAPER_MAX)
{
goto fail;
}
else if( pOEM->sPaperSize == PHYS_PAPER_UNFIXED){
pOEM->szlPhysSize.cx = PARAM(pdwParams, 0);
pOEM->szlPhysSize.cy = PARAM(pdwParams, 1);
ptlUserDefSize.x = GetPrintableArea((WORD)pOEM->szlPhysSize.cx, RESOLUTION_600);
ptlUserDefSize.y = GetPrintableArea((WORD)pOEM->szlPhysSize.cy, RESOLUTION_600);
pOEM->ptlLogSize = ptlUserDefSize;
CMD_SETPAC[CMD_SETPAC_CUSTOM_DOTS_PER_LINE] = LOBYTE((WORD)(ptlUserDefSize.x));
CMD_SETPAC[CMD_SETPAC_CUSTOM_DOTS_PER_LINE + 1] = HIBYTE((WORD)(ptlUserDefSize.x));
CMD_SETPAC[CMD_SETPAC_CUSTOM_LINES_PER_PAGE] = LOBYTE((WORD)(ptlUserDefSize.y));
CMD_SETPAC[CMD_SETPAC_CUSTOM_LINES_PER_PAGE + 1] = HIBYTE((WORD)(ptlUserDefSize.y));
}
else {
pOEM->ptlLogSize = phySize600[
pOEM->sPaperSize-PHYS_PAPER_BASE];
}
break;
case SEND_BLOCK_DATA:
wNumOfByte = (WORD)PARAM(pdwParams, 0);
pOEM->wImgHeight = (WORD)PARAM(pdwParams, 1);
pOEM->wImgWidth = (WORD)PARAM(pdwParams, 2);
break;
case ORIENTATION_PORTRAIT: // 28
case ORIENTATION_LANDSCAPE: // 29
switch(pOEM->sPaperSize){
case PHYS_PAPER_A3 :
case PHYS_PAPER_B4 :
case PHYS_PAPER_LEGAL :
case PHYS_PAPER_POSTCARD :
pOEM->fChangeDirection = FALSE ;
pOEM->fComp = TRUE ;
break;
case PHYS_PAPER_A4 :
case PHYS_PAPER_A5 :
case PHYS_PAPER_B5 :
case PHYS_PAPER_LETTER :
pOEM->fChangeDirection = TRUE ;
pOEM->fComp = FALSE ;
break;
case PHYS_PAPER_UNFIXED : /* Paper is not rotated in UNFIXED case */
pOEM->fChangeDirection = FALSE ;
pOEM->fComp = TRUE ;
break;
}
break;
case PHYS_PAPER_A3: // 50
pOEM->sPaperSize = PHYS_PAPER_A3 ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x04 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x04 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x04 ;
break ;
case PHYS_PAPER_A4: // 51
pOEM->sPaperSize = PHYS_PAPER_A4 ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x83 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x83 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x83 ;
break ;
case PHYS_PAPER_B4: // 54
pOEM->sPaperSize = PHYS_PAPER_B4 ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x07 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x07 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x07 ;
break ;
case PHYS_PAPER_LETTER: // 57
pOEM->sPaperSize = PHYS_PAPER_LETTER ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x90 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x90 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x90 ;
break ;
case PHYS_PAPER_LEGAL: // 58
pOEM->sPaperSize = PHYS_PAPER_LEGAL ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x11 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x11 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x11 ;
break ;
case PHYS_PAPER_B5: // 55
pOEM->sPaperSize = PHYS_PAPER_B5 ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x86 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x86 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x86 ;
break ;
case PHYS_PAPER_A5: // 52
pOEM->sPaperSize = PHYS_PAPER_A5 ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x82 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x82 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x82 ;
break ;
case PHYS_PAPER_POSTCARD: // 59
pOEM->sPaperSize = PHYS_PAPER_POSTCARD ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x17 ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x17 ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x17 ;
break ;
case PHYS_PAPER_UNFIXED: // 60
pOEM->sPaperSize = PHYS_PAPER_UNFIXED ;
CMD_SETPAC[CMD_SETPAC_FRONT_TRAY_PAPER_SIZE] = 0x3F ;
CMD_SETPAC[CMD_SETPAC_1ST_CASSETTE_PAPER_SIZE] = 0x3F ;
CMD_SETPAC[CMD_SETPAC_2ND_CASSETTE_PAPER_SIZE] = 0x3F ;
break ;
case PAPER_SRC_FTRAY:
CMD_SETPAC[CMD_SETPAC_INPUT_BIN] = 0x01 ;
break ;
case PAPER_SRC_CAS1:
CMD_SETPAC[CMD_SETPAC_INPUT_BIN] = 0x02 ;
break;
case PAPER_SRC_CAS2:
CMD_SETPAC[CMD_SETPAC_INPUT_BIN] = 0x04 ;
break;
case PAPER_SRC_AUTO:
CMD_SETPAC[CMD_SETPAC_INPUT_BIN] = 0x04 ;
break;
case TONER_SAVE_MEDIUM: // 100
CMD_SETPAC[CMD_SETPAC_TONER_SAVE_MODE] = 0x02 ;
break;
case TONER_SAVE_DARK: // 101
CMD_SETPAC[CMD_SETPAC_TONER_SAVE_MODE] = 0x04 ;
break;
case TONER_SAVE_LIGHT: // 102
CMD_SETPAC[CMD_SETPAC_TONER_SAVE_MODE] = 0x01 ;
break;
case PAGECONTROL_MULTI_COPIES:
CMD_SETPAC[24] = (BYTE)PARAM(pdwParams, 0);
pOEM->sCopyNum = (BYTE)PARAM(pdwParams, 0);
break;
case Y_REL_MOVE :
if (0 == pOEM->ulHorzRes)
goto fail;
pOEM->dwYmove=(WORD)*pdwParams/(MASTERUNIT/(WORD)pOEM->ulHorzRes);
// ISSUE-2002/3/18-takashim - Faking Unidrv here?
// iRet = 0; below is intentional: Retuning dwYmove will cause
// incorrect outputs.
// DestYRel in GPD means the coordinate relative to the current
// cursor position. Here, minidriver is always returning 0 (no move)
// to Unidrv, so it is always absolute coordinate (relative to
// the origin)?
if(pOEM->dwCurCursorY < pOEM->dwYmove){
pOEM->dwYmove -= pOEM->dwCurCursorY ;
}else{
pOEM->dwYmove = 0 ;
}
// iRet = pOEM->dwYmove;
iRet = 0;
break;
default:
break;
}
return iRet;
fail:
return -1;
}
/*****************************************************************************/
/* */
/* Module: GetPrintableArea */
/* */
/* Function: Calculate PrintableArea for user defined paper */
/* */
/* Syntax: WORD GetPrintableArea(WORD physSize, INT iRes) */
/* */
/* Input: physSize */
/* iRes */
/* */
/* Output: WORD */
/* */
/* Notice: */
/* */
/*****************************************************************************/
WORD GetPrintableArea(WORD physSize, INT iRes)
{
DWORD dwArea ;
DWORD dwPhysSizeMMx10 = physSize * 254 / MASTERUNIT;
/* Unit of phySize is MASTERUNIT(=1200) */
if(iRes == RESOLUTION_300){
dwArea = (((WORD)(( ( (DWORD)(dwPhysSizeMMx10*300/25.4) -
2*( (DWORD)(4*300*10/25.4) ) ) / 10 +7)/8))) * 8;
}else{
dwArea = (((WORD)(( ( (DWORD)(dwPhysSizeMMx10*600/25.4) -
2*( (DWORD)(4*600*10/25.4) ) ) / 10 +7)/8))) * 8;
}
return (WORD)dwArea ;
}
// NOTICE-2002/3/18/-takashim - Comment
// // #94193: shold create temp. file on spooler directory.
//
/*++
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;
hToken = RevertToPrinterSelf();
//
// In order to find out where the spooler's directory is, we add
// call GetPrinterData with DefaultSpoolDirectory.
//
dwAllocSize = ( MAX_PATH ) * 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;
}
// FUTURE-2002/3/18-takashim - Temp file path restricted to ANSI.
// According to the SDK document, the pathname handled by GetTempFileName
// must be consist of ANSI characters. What happens with double-byte
// characters, etc??
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) {
if (!ImpersonatePrinterClient(hToken))
{
// failure..
return FALSE;
}
}
return( TRUE );
Failure:
//
// Clean up and fail.
//
if ( pBuffer != NULL )
{
LocalFree( pBuffer );
}
if (hToken != NULL)
{
(void)ImpersonatePrinterClient(hToken);
}
return ( FALSE );
}
//SPLBUF is used for control temp files.
//This printer need the number of bytes of whole page data.
BOOL InitSpoolBuffer(LPSB lpsb)
{
lpsb->dwWrite = 0 ;
lpsb->TempName[0] = __TEXT('\0') ;
lpsb->hFile = INVALID_HANDLE_VALUE ;
return TRUE;
}
BOOL MyCreateFile(PDEVOBJ pdevobj, LPSB lpsb)
{
HANDLE hToken = NULL;
BOOL bRet = FALSE;
if (!GetSpoolFileName(pdevobj->hPrinter, lpsb->TempName)) {
//DBGPRINT(DBG_WARNING, ("GetSpoolFileName failed.\n"));
goto fail;
}
hToken = RevertToPrinterSelf();
lpsb->hFile = CreateFile((LPCTSTR)lpsb->TempName,
(GENERIC_READ | GENERIC_WRITE),
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL) ;
if(lpsb->hFile == INVALID_HANDLE_VALUE)
{
//DBGPRINT(DBG_WARNING, ("Tmp file cannot create.\n"));
DeleteFile(lpsb->TempName);
lpsb->TempName[0] = __TEXT('\0') ;
goto fail;
}
bRet = TRUE;
fail:
if (hToken) (void)ImpersonatePrinterClient(hToken);
return bRet ;
}
BOOL MyDeleteFile(PDEVOBJ pdevobj, LPSB lpsb)
{
HANDLE hToken = NULL;
BOOL bRet = FALSE;
if(lpsb->hFile != INVALID_HANDLE_VALUE){
if (0 == CloseHandle(lpsb->hFile)) {
//DBGPRINT(DBG_WARNING, ("CloseHandle error %d\n"));
goto fail;
}
lpsb->hFile = INVALID_HANDLE_VALUE ;
hToken = RevertToPrinterSelf();
if (0 == DeleteFile(lpsb->TempName)) {
//DBGPRINT(DBG_WARNING, ("DeleteName error %d\n",GetLastError()));
goto fail;
}
lpsb->TempName[0] = __TEXT('\0');
}
bRet = TRUE;
fail:
if (hToken) (void)ImpersonatePrinterClient(hToken);
return bRet;
}
//Spool page data to temp file
BOOL MySpool
(PDEVOBJ pdevobj,
LPSB lpsb,
PBYTE pBuf,
DWORD dwLen)
{
DWORD dwTemp, dwTemp2;
BYTE *pTemp;
if (lpsb->hFile != INVALID_HANDLE_VALUE) {
pTemp = pBuf;
dwTemp = dwLen;
while (dwTemp > 0) {
if (0 == WriteFile(lpsb->hFile,
pTemp,
dwTemp,
&dwTemp2,
NULL)
|| dwTemp2 > dwTemp) {
ERR((DLLTEXT("WriteFile error in CacheData %d.\n"),
GetLastError()));
return FALSE;
}
pTemp += dwTemp2;
dwTemp -= dwTemp2;
lpsb->dwWrite += dwTemp2 ;
}
return TRUE;
}
else {
return WRITESPOOLBUF(pdevobj, pBuf, dwLen);
}
}
//Dump out temp file to printer
BOOL
SpoolOut(PDEVOBJ pdevobj, LPSB lpsb)
{
DWORD dwSize, dwTemp, dwTemp2;
HANDLE hFile;
BYTE Buf[SPOOL_OUT_BUF_SIZE];
hFile = lpsb->hFile ;
dwSize = lpsb->dwWrite ;
VERBOSE(("dwSize=%ld\n", dwSize));
if (0L != SetFilePointer(hFile, 0L, NULL, FILE_BEGIN)) {
ERR((DLLTEXT("SetFilePointer failed %d\n"),
GetLastError()));
return FALSE;
}
for ( ; dwSize > 0; dwSize -= dwTemp2) {
dwTemp = ((SPOOL_OUT_BUF_SIZE < dwSize)
? SPOOL_OUT_BUF_SIZE : dwSize);
if (0 == ReadFile(hFile, Buf, dwTemp, &dwTemp2, NULL)
|| dwTemp2 > dwTemp) {
ERR((DLLTEXT("ReadFile error in SendCachedData.\n")));
return FALSE;
}
if (dwTemp2 > 0) {
if (!WRITESPOOLBUF(pdevobj, Buf, dwTemp2))
return FALSE;
}
}
return TRUE;
}
BOOL MyStartDoc(PDEVOBJ pdevobj)
{
return
WRITESPOOLBUF(pdevobj, (PBYTE)CMD_BEGIN_DOC_1, sizeof(CMD_BEGIN_DOC_1)) &&
WRITESPOOLBUF(pdevobj, (PBYTE)CMD_BEGIN_DOC_2, sizeof(CMD_BEGIN_DOC_2)) &&
WRITESPOOLBUF(pdevobj, (PBYTE)CMD_BEGIN_DOC_3, sizeof(CMD_BEGIN_DOC_3)) &&
WRITESPOOLBUF(pdevobj, (PBYTE)CMD_BEGIN_DOC_4, sizeof(CMD_BEGIN_DOC_4)) &&
WRITESPOOLBUF(pdevobj, (PBYTE)CMD_BEGIN_DOC_5, sizeof(CMD_BEGIN_DOC_5));
}
BOOL MyEndPage(PDEVOBJ pdevobj)
{
PIBMPDEV pOEM;
LPSB lpsb, lpsbco ;
DWORD dwPageLen ;
WORD wTmph, wTmpl ;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
lpsb = &(pOEM->sb) ;
lpsbco = &(pOEM->sbcomp) ;
if(pOEM->fChangeDirection == FALSE) {
dwPageLen = lpsb->dwWrite;
}
else {
dwPageLen = lpsbco->dwWrite ;
}
// NOTICE-2002/3/18-takashim - What is this?
dwPageLen -= 3 ; //End page Command Len
VERBOSE(("MyEndPage - dwPageLen=%ld\n",
dwPageLen));
wTmpl = LOWORD(dwPageLen) ;
wTmph = HIWORD(dwPageLen) ;
CMD_SETPAC[CMD_SETPAC_PAGE_LENGTH] = LOBYTE(wTmpl);
CMD_SETPAC[CMD_SETPAC_PAGE_LENGTH + 1] = HIBYTE(wTmpl);
CMD_SETPAC[CMD_SETPAC_PAGE_LENGTH + 2] = LOBYTE(wTmph);
CMD_SETPAC[CMD_SETPAC_PAGE_LENGTH + 3] = HIBYTE(wTmph);
if (!WRITESPOOLBUF(pdevobj, CMD_SETPAC, sizeof(CMD_SETPAC)))
return FALSE;
if(pOEM->fChangeDirection == FALSE){
if (!SpoolOut(pdevobj, lpsb))
return FALSE;
}else{
if (!SpoolOut(pdevobj, lpsbco))
return FALSE;
}
//InitFiles
lpsbco->dwWrite = 0 ;
lpsb->dwWrite = 0 ;
if(INVALID_SET_FILE_POINTER==SetFilePointer(lpsb->hFile,0,NULL,FILE_BEGIN)){
ERR((DLLTEXT("SetFilePointer failed %d\n"),
GetLastError()));
return FALSE;
}
if(INVALID_SET_FILE_POINTER==SetFilePointer(lpsbco->hFile,0,NULL,FILE_BEGIN)){
ERR((DLLTEXT("SetFilePointer failed %d\n"),
GetLastError()));
return FALSE;
}
return TRUE;
}
BOOL MyEndDoc(PDEVOBJ pdevobj)
{
PIBMPDEV pOEM;
LPSB lpsb, lpsbco ;
WORD wTmph, wTmpl ;
DWORD dwPageLen ;
SHORT i ;
LPPD lppdTemp ;
BOOL bRet = FALSE;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
lpsb = &(pOEM->sb) ;
lpsbco = &(pOEM->sbcomp) ;
if (!WRITESPOOLBUF(pdevobj, (PBYTE)CMD_END_JOB, sizeof(CMD_END_JOB)))
goto fail;
if (!MyDeleteFile(pdevobj, lpsb))
goto fail;
if (!MyDeleteFile(pdevobj, lpsbco))
goto fail;
bRet = TRUE;
fail:
return bRet;
}
BOOL WriteFileForP_Paper(PDEVOBJ pdevobj, PBYTE pBuf, DWORD dwLen)
{
PIBMPDEV pOEM;
ULONG ulHorzPixel;
WORD wCompLen;
DWORD dwWhiteLen ;
DWORD dwTmp ;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
if (pOEM->dwYmove > 0) {
dwWhiteLen = pOEM->wImgWidth * pOEM->dwYmove;
if (!SpoolWhiteData(pdevobj, dwWhiteLen, TRUE))
return FALSE;
pOEM->dwCurCursorY += pOEM->dwYmove;
pOEM->dwYmove = 0;
}
pOEM->dwCurCursorY += dwLen/pOEM->wImgWidth - 1 ;
return SendPageData(pdevobj, pBuf, dwLen) ;
}
BOOL WriteFileForL_Paper(PDEVOBJ pdevobj, PBYTE pBuf, DWORD dwLen)
{
PIBMPDEV pOEM;
ULONG ulHorzPixel;
WORD wCompLen;
DWORD dwWhiteLen ;
DWORD i, j;
DWORD dwHeight, dwWidth;
PBYTE pTemp;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
if (pOEM->dwYmove > 0) {
dwWhiteLen = pOEM->wImgWidth * pOEM->dwYmove;
if (!SpoolWhiteData(pdevobj, dwWhiteLen, FALSE))
return FALSE;
pOEM->dwCurCursorY += pOEM->dwYmove;
pOEM->dwYmove = 0;
}
pOEM->dwCurCursorY += dwLen/pOEM->wImgWidth - 1 ;
pOEM->dwOffset ++ ;
return MySpool(pdevobj, &(pOEM->sb), pBuf,dwLen);
}
//fill page blanks.
BOOL FillPageRestData(PDEVOBJ pdevobj)
{
PIBMPDEV pOEM ;
DWORD dwRestHigh ;
DWORD dwWhiteLen ;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
dwRestHigh = pOEM->ptlLogSize.y - pOEM->dwCurCursorY ;
if(dwRestHigh <= 0)
return TRUE;
dwWhiteLen = pOEM->ptlLogSize.x * dwRestHigh;
return SpoolWhiteData(pdevobj, dwWhiteLen, pOEM->fComp);
}
//not white data
BOOL SendPageData(PDEVOBJ pdevobj, PBYTE pSrcImage, DWORD dwLen)
{
PIBMPDEV pOEM;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
return SpoolOutComp(&pOEM->Soc, pdevobj, &pOEM->sb, pSrcImage, dwLen);
}
BOOL SpoolWhiteData(PDEVOBJ pdevobj, DWORD dwWhiteLen, BOOL fComp)
{
PIBMPDEV pOEM;
PBYTE pWhite ;
WORD wCompLen ;
DWORD dwTempLen ;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
if(dwWhiteLen == 0)
return TRUE;
if(dwWhiteLen > MAXIMGSIZE){
dwTempLen = MAXIMGSIZE ;
}else{
dwTempLen = dwWhiteLen ;
}
if (!AllocTempBuffer(pOEM, dwTempLen))
return FALSE;
pWhite = pOEM->pTempImage;
ZeroMemory(pWhite, dwTempLen);
if(fComp == TRUE)
{
DWORD dwTemp;
while (0 < dwWhiteLen) {
if (MAXIMGSIZE <= dwWhiteLen)
dwTemp = MAXIMGSIZE;
else
dwTemp = dwWhiteLen;
if (!SpoolOutComp(&pOEM->Soc, pdevobj, &pOEM->sb, pWhite, dwTemp))
return FALSE;
dwWhiteLen -= dwTemp;
}
}
else{
if(dwWhiteLen > MAXIMGSIZE){
while(dwWhiteLen > MAXIMGSIZE){
if (!MySpool(pdevobj, &pOEM->sb, pWhite, MAXIMGSIZE))
return FALSE;
dwWhiteLen -= MAXIMGSIZE ;
}
}
if(dwWhiteLen > 0){
if (!MySpool(pdevobj, &pOEM->sb, pWhite, dwWhiteLen))
return FALSE;
}
}
return TRUE;
}
BOOL SpoolOutChangedData(PDEVOBJ pdevobj, LPSB lpsb)
{
PIBMPDEV pOEM;
POINTL ptlDataPos ;
DWORD dwFilePos, dwTemp;
HANDLE hFile ;
PBYTE pSaveFileData ;
PBYTE pTemp;
PBYTE pTransBuf ;
DWORD X, Y;
DWORD dwFirstPos ;
INT h, i, j, k;
POINTL ptlBand;
PBYTE pSrc, pDst, pSrcSave;
DWORD dwBandY, dwImageY, dwImageX;
BOOL bBlank, bZero;
BOOL bRet = FALSE;
pOEM = (PIBMPDEV)pdevobj->pdevOEM;
hFile = pOEM->sb.hFile ;
// band size in pixels
ptlBand.x = pOEM->ptlLogSize.y;
ptlBand.y = TRANS_BAND_Y_SIZE;
//ファイルの読み込み開始位置を計算
// Calculate read start positoin in the file
ptlDataPos.x = 0 ;
ptlDataPos.y = pOEM->dwCurCursorY + pOEM->dwOffset ;
//縦方向、1行のした部分余白
// Y direction, blank area beneth.
dwImageX = ((ptlDataPos.y + 7) / 8) * 8;
// Buffer for loading file data (scan lines for a band)
pSaveFileData = (PBYTE)MemAlloc((ptlBand.y / 8) * dwImageX);
if (NULL == pSaveFileData) {
ERR(("Failed to allocate memory.\n"));
return FALSE;
}
// Buffer for transpositions (one scan line)
pTransBuf = (PBYTE)MemAlloc((ptlBand.x / 8));
if (NULL == pTransBuf) {
ERR(("Failed to allocate memory.\n"));
// #441444: PREFIX: reference NULL pointer.
goto out;
}
//ファイルの読み込み位置指定。
// Specify read start positoin in the file
dwFirstPos = pOEM->wImgWidth - 1;
if (!MySpool(pdevobj,&(pOEM->sbcomp),
(PBYTE)CMD_BEGIN_PAGE, sizeof(CMD_BEGIN_PAGE)))
goto out;
if (!SpoolOutCompStart(&pOEM->Soc))
goto out;
dwImageY = pOEM->wImgWidth;
bBlank = FALSE;
bZero = FALSE;
for (X = 0; X < (DWORD)pOEM->ptlLogSize.x / 8; X += dwBandY) {
//余白部分を先にセット。読み飛ばす。
// Set blank area, then read skip.
dwBandY = ptlBand.y / 8;
if (dwBandY > (DWORD)pOEM->ptlLogSize.x / 8 - X)
dwBandY = (DWORD)pOEM->ptlLogSize.x / 8 - X;
// White scanlines. Currently the trailing ones only,
// desired to be udpated to include others.
if (X >= dwImageY) {
bBlank = TRUE;
}
// Output white scanline.
if (bBlank) {
if (!bZero) {
ZeroMemory(pTransBuf, (ptlBand.x / 8));
bZero = TRUE;
}
for (i = 0; i < (INT)dwBandY * 8; i++) {
if (!SpoolOutComp(&pOEM->Soc, pdevobj, &pOEM->sbcomp,
(PBYTE)pTransBuf, (ptlBand.x / 8)))
goto out;
}
continue;
}
// Non-white scanlines.
pTemp = pSaveFileData ;
dwFilePos = pOEM->wImgWidth - X - dwBandY;
//縦方向1行をファイルから読み取る。
// Read vertial one line from the file.
for (Y = 0; Y < dwImageX; pTemp += dwBandY, Y++) {
if (Y >= (DWORD)ptlDataPos.y) {
ZeroMemory(pTemp, dwBandY);
continue;
}
if(INVALID_SET_FILE_POINTER==SetFilePointer(hFile,dwFilePos,NULL,FILE_BEGIN)){
ERR((DLLTEXT("SetFilePointer failed %d\n"),
GetLastError()));
// #441442: PREFIX: leaking memory.
// return;
goto out;
}
if (0 == ReadFile(hFile, pTemp, dwBandY, &dwTemp, NULL)
|| dwTemp > dwBandY) {
ERR(("Faild reading data from file. (%d)\n",
GetLastError()));
// #441442: PREFIX: leaking memory.
// return;
goto out;
}
dwFilePos += pOEM->wImgWidth;
}//End of Y loop
// Transposition and output dwBandY * 8 scan lines
for (h = 0; h < (INT)dwBandY; h++) {
//VERBOSE(("> %d/%d\n", h, dwBandY));
pSrcSave = pSaveFileData + dwBandY - 1 - h;
// Transposition and output eight scan lines
for (j = 0; j < 8; j++) {
pSrc = pSrcSave;
pDst = pTransBuf;
ZeroMemory(pDst, (ptlBand.x / 8));
// Transposition one scan line
for (i = 0; i < (INT)(dwImageX / 8); i++){
for (k = 0; k < 8; k++) {
if (0 != (*pSrc & Mask[7 - j])) {
*pDst |= Mask[k];
}
pSrc += dwBandY;
}
pDst++;
}
// Output one scan line
if (!SpoolOutComp(&pOEM->Soc, pdevobj, &pOEM->sbcomp,
(PBYTE)pTransBuf, (ptlBand.x / 8)))
goto out;
}
}
}
// Mark end of image
if (!SpoolOutCompEnd(&pOEM->Soc, pdevobj, &pOEM->sbcomp))
goto out;
if (!MySpool(pdevobj, &(pOEM->sbcomp),
(PBYTE)CMD_END_PAGE, sizeof(CMD_END_PAGE)))
goto out;
bRet = TRUE;
// #441442: PREFIX: leaking memory.
out:
if (NULL != pSaveFileData){
MemFree(pSaveFileData);
}
if(NULL != pTransBuf){
MemFree(pTransBuf);
}
return bRet;
}
BOOL
AllocTempBuffer(
PIBMPDEV pOEM,
DWORD dwNewBufLen)
{
if (NULL == pOEM->pTempImage ||
dwNewBufLen > pOEM->dwTempBufLen) {
if (NULL != pOEM->pTempImage) {
MemFree(pOEM->pTempImage);
}
pOEM->pTempImage = (PBYTE)MemAlloc(dwNewBufLen);
if (NULL == pOEM->pTempImage) {
WARNING(("Failed to allocate memory. (%d)\n",
GetLastError()));
pOEM->dwTempBufLen = 0;
return FALSE;
}
pOEM->dwTempBufLen = dwNewBufLen;
}
return TRUE;
}
BOOL
SpoolOutCompStart(
PSOCOMP pSoc)
{
pSoc->iNRCnt = 0;
pSoc->iRCnt = 0;
pSoc->iPrv = -1;
return TRUE;
}
BOOL
SpoolOutCompEnd(
PSOCOMP pSoc,
PDEVOBJ pdevobj,
LPSB psb)
{
BYTE jTemp;
if (0 < pSoc->iNRCnt) {
jTemp = ((BYTE)pSoc->iNRCnt) - 1;
if (!MySpool(pdevobj, psb, &jTemp, 1))
return FALSE;
if (!MySpool(pdevobj, psb, pSoc->pjNRBuf, pSoc->iNRCnt))
return FALSE;
pSoc->iNRCnt = 0;
}
if (0 < pSoc->iRCnt) {
jTemp = (0 - (BYTE)pSoc->iRCnt) + 1;
if (!MySpool(pdevobj, psb, &jTemp, 1))
return FALSE;
if (!MySpool(pdevobj, psb, &pSoc->iPrv, 1))
return FALSE;
pSoc->iRCnt = 0;
}
return TRUE;
}
BOOL
SpoolOutComp(
PSOCOMP pSoc,
PDEVOBJ pdevobj,
LPSB psb,
PBYTE pjBuf,
DWORD dwLen)
{
BYTE jCur, jTemp;
while (0 < dwLen--) {
jCur = *pjBuf++;
if (pSoc->iPrv == jCur) {
if (0 < pSoc->iNRCnt) {
if (1 < pSoc->iNRCnt) {
jTemp = ((BYTE)pSoc->iNRCnt - 1) - 1;
if (!MySpool(pdevobj, psb, &jTemp, 1))
return FALSE;
if (!MySpool(pdevobj, psb, pSoc->pjNRBuf, pSoc->iNRCnt - 1))
return FALSE;
}
pSoc->iNRCnt = 0;
pSoc->iRCnt = 1;
}
pSoc->iRCnt++;
if (RPEAK == pSoc->iRCnt) {
jTemp = (0 - (BYTE)pSoc->iRCnt) + 1;
if (!MySpool(pdevobj, psb, &jTemp, 1))
return FALSE;
if (!MySpool(pdevobj, psb, &jCur, 1))
return FALSE;
pSoc->iRCnt = 0;
}
}
else {
if (0 < pSoc->iRCnt) {
jTemp = (0 - (BYTE)pSoc->iRCnt) + 1;
if (!MySpool(pdevobj, psb, &jTemp, 1))
return FALSE;
if (!MySpool(pdevobj, psb, &pSoc->iPrv, 1))
return FALSE;
pSoc->iRCnt = 0;
}
pSoc->pjNRBuf[pSoc->iNRCnt++] = jCur;
if (NRPEAK == pSoc->iNRCnt) {
jTemp = ((BYTE)pSoc->iNRCnt) - 1;
if (!MySpool(pdevobj, psb, &jTemp, 1))
return FALSE;
if (!MySpool(pdevobj, psb, pSoc->pjNRBuf, pSoc->iNRCnt))
return FALSE;
pSoc->iNRCnt = 0;
}
}
pSoc->iPrv = jCur;
}
return TRUE;
}
/*++
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;
}