mirror of https://github.com/lianthony/NT4.0
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.
196 lines
6.2 KiB
196 lines
6.2 KiB
/****************************** MODULE HEADER *******************************
|
|
* cleanup.c
|
|
* Called to clean up the printer at the end of (a raw) job, or when
|
|
* the output was cancelled.
|
|
*
|
|
* Copyright (C) 1992 Microsoft Corporation.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
#include "rasuipch.h"
|
|
#pragma hdrstop("rasuipch.h")
|
|
#define GLOBAL_MACS
|
|
#include "gblmac.h"
|
|
#undef GLOBAL_MACS
|
|
|
|
extern HANDLE hHeap;
|
|
|
|
/* The only local function in here */
|
|
|
|
BOOL
|
|
bSendCmd(
|
|
HANDLE hPrinter, /* Need to talk to spooler */
|
|
OCD ocd, /* Offset to command descriptor in GPC heap */
|
|
PRASDDUIINFO pRasdduiInfo /* Rasddui UI data */
|
|
);
|
|
|
|
|
|
/*************************** Function Header *******************************
|
|
* DrvCleanUp
|
|
* Called by the spooler to place the printer in a known, safe state
|
|
* after either aborting the output, OR at the end of raw copy. The
|
|
* latter is important because, at a minimum, there may be no end
|
|
* if job information, so we need to be sure that the page is finished.
|
|
*
|
|
* RETURNS:
|
|
* TRUE/FALSE - TRUE if output successfully sent.
|
|
*
|
|
* HISTORY:
|
|
* 11:27 on Fri 28 Aug 1992 -by- Lindsay Harris [lindsayh]
|
|
* Gotta start somewhere.
|
|
*
|
|
****************************************************************************/
|
|
|
|
BOOL
|
|
DrvCleanup( hPrinter, pwstrDataFileName, pwstrModel, bClean )
|
|
HANDLE hPrinter; /* Access to the printer via spooler */
|
|
PWSTR pwstrDataFileName; /* Printer characteristic information */
|
|
PWSTR pwstrModel; /* Which model in the above */
|
|
BOOL bClean; /* TRUE if job ended normally */
|
|
{
|
|
|
|
int cjSend;
|
|
BOOL bRet = FALSE; /* Value returned */
|
|
|
|
BYTE ajNull[ 1024 ];
|
|
|
|
PAGECONTROL *pPC; /* END_DOC, END_PAGE information */
|
|
CURSORMOVE *pCM; /* FORM_FEED information */
|
|
PRASDDUIINFO pRasdduiInfo = NULL; /* Common UI Data */
|
|
|
|
TRY
|
|
/* Allocate the global data structure */
|
|
if (!(pRasdduiInfo = pGetUIInfo(hPrinter, 0, eInfo, eNoChange, eNoHelp)))
|
|
{
|
|
RASUIDBGP(DEBUG_ERROR,("Rasddui!DrvCleanup: Allocation failed; pRasdduiInfo is NULL\n") );
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/*
|
|
* Onto the action. If bClean is TRUE, all we need do is send
|
|
* the end of page activity. Otherwise, we presume the printer is
|
|
* in a messy state, and so must ensure that we send enough nulls
|
|
* to get the printer out of whatever state it may be in.
|
|
*/
|
|
|
|
if( !bClean )
|
|
{
|
|
/*
|
|
* The messy option. We need to send some number of nulls, as
|
|
* we do not know in what state the printer remains. As a worst
|
|
* case example, it could have been in the middle of a font
|
|
* download. In the LaserJet family, this could mean we are
|
|
* sending a block of binary data up to 32k bytes! We could also
|
|
* be in the midst of sending binary graphics data, and this too
|
|
* needs to be terminated because such data is typically sent
|
|
* as a count followed by that many bytes.
|
|
*/
|
|
|
|
/* !!!LindsayH - send the worst case, for safety and our convenience */
|
|
memset( ajNull, 0, sizeof( ajNull ) );
|
|
for( cjSend = 0; cjSend < (33 * 1024); cjSend += sizeof( ajNull ) )
|
|
{
|
|
DWORD cjSent; /* What the spooler sent */
|
|
|
|
if( !WritePrinter( hPrinter, ajNull, sizeof( ajNull ), &cjSent ) ||
|
|
cjSent != sizeof( ajNull ) )
|
|
{
|
|
/* Bad news - give up now */
|
|
LEAVE;
|
|
}
|
|
}
|
|
}
|
|
|
|
bRet = TRUE; /* Presumed innocent */
|
|
|
|
/*
|
|
* Now for the end of page stuff. Basically we wish to determine
|
|
* the commands to send to complete processing of any page that
|
|
* may have been sent.
|
|
*
|
|
* Processing involves grovelling over the GPC data, and finding
|
|
* the END_PAGE, END_DOC and FORMFEED information.
|
|
*/
|
|
|
|
/* First comes FORM_FEED */
|
|
|
|
pCM = GetTableInfoIndex( pdh, HE_CURSORMOVE,
|
|
pModel->rgi[ MD_I_CURSORMOVE ] );
|
|
|
|
if( pCM )
|
|
{
|
|
/* If there is a FORM FEED command, send it now! */
|
|
bRet = bSendCmd( hPrinter, pCM->rgocd[ CM_OCD_FF ], pRasdduiInfo );
|
|
}
|
|
|
|
pPC = GetTableInfoIndex( pdh, HE_PAGECONTROL,
|
|
pModel->rgi[ MD_I_PAGECONTROL ] );
|
|
|
|
if( bRet && pPC )
|
|
{
|
|
/* Send the END_PAGE and END_DOC commands */
|
|
|
|
if( !bSendCmd( hPrinter, pPC->rgocd[ PC_OCD_ENDPAGE ], pRasdduiInfo ) ||
|
|
!bSendCmd( hPrinter, pPC->rgocd[ PC_OCD_ENDDOC ], pRasdduiInfo ) )
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
ENDTRY
|
|
|
|
FINALLY
|
|
vReleaseUIInfo(&pRasdduiInfo);
|
|
ENDFINALLY
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/************************** Function Header ******************************
|
|
* bSendCmd
|
|
* Given an offset to the Command Descriptor, send the command off
|
|
* to the printer via the spooler.
|
|
* NOTE: It is presumed that none of the commands processed in here
|
|
* require (numeric) parameters.
|
|
*
|
|
* RETURNS:
|
|
* TRUE/FALSE, FALSE only being for an error return from the spooler.
|
|
*
|
|
* HISTORY:
|
|
* 14:19 on Fri 28 Aug 1992 -by- Lindsay Harris [lindsayh]
|
|
* First incarnation, borrowed from rasdd.
|
|
*
|
|
**************************************************************************/
|
|
|
|
BOOL
|
|
bSendCmd(
|
|
HANDLE hPrinter, /* Need to talk to spooler */
|
|
OCD ocd, /* Offset to command descriptor in GPC heap */
|
|
PRASDDUIINFO pRasdduiInfo /* Rasddui UI data */
|
|
)
|
|
{
|
|
DWORD dwWrit; /* How much the spooler wrote */
|
|
CD *pCD; /* The data to send */
|
|
|
|
|
|
/*
|
|
* First verify that the ocd is valid. It could be a "we have
|
|
* no command for this" type of data.
|
|
*/
|
|
|
|
if( ocd == (OCD)NOOCD )
|
|
return TRUE;
|
|
|
|
/*
|
|
* Find this in the GPC data, then send it off to the spooler.
|
|
* NOTE the presumption that there are no parameters involved.
|
|
*/
|
|
|
|
pCD = (CD *)((BYTE *)pdh + pdh->loHeap + ocd);
|
|
|
|
WritePrinter( hPrinter, pCD->rgchCmd, (DWORD)pCD->wLength, &dwWrit );
|
|
|
|
|
|
return dwWrit == (DWORD)pCD->wLength;
|
|
}
|