📄 pjlmon.c
字号:
msg[0] = '\0';
#endif
OldStatus = pIniPort->PrinterStatus;
pIniPort->PrinterStatus = 0;
for (i = 0; i < nTokenParsed; i++) {
// DBGMSG(DBG_INFO, ("pjlmon!Token=0x%x, Value=%d\n",
// tokenPairs[i].token, tokenPairs[i].value));
switch(tokenPairs[i].token) {
case TOKEN_INFO_STATUS_CODE:
case TOKEN_USTATUS_DEVICE_CODE:
for (pMap = PJLToStatus; pMap->pjl; pMap++) {
if (pMap->pjl == tokenPairs[i].value) {
pIniPort->PrinterStatus = pMap->status;
dwSeverity = SeverityFromPjlStatus(pMap->pjl);
if ( dwSeverity == PORT_STATUS_TYPE_ERROR )
pIniPort->status |= PP_PRINTER_OFFLINE;
else
pIniPort->status &= ~PP_PRINTER_OFFLINE;
break;
}
}
if ( pMap->pjl && pMap->pjl == tokenPairs[i].value )
break;
//
// some printers use this to signal online/ready
//
if ( tokenPairs[i].value == 10001 ||
tokenPairs[i].value == 10002 ||
tokenPairs[i].value == 11002 ) {
pIniPort->status &= ~PP_PRINTER_OFFLINE;
pIniPort->PrinterStatus = 0;
dwSeverity = 0;
}
//
// background or foreground paper out
//
if ( tokenPairs[i].value > 11101 && tokenPairs[i].value < 12000 ||
tokenPairs[i].value > 41101 && tokenPairs[i].value < 42000 ) {
pIniPort->PrinterStatus = PORT_STATUS_PAPER_OUT;
if ( tokenPairs[i].value > 4000 ) {
dwSeverity = PORT_STATUS_TYPE_ERROR;
pIniPort->status |= PP_PRINTER_OFFLINE;
} else {
dwSeverity = PORT_STATUS_TYPE_WARNING;
}
} else if (tokenPairs[i].value > 40000) {
pIniPort->PrinterStatus = PORT_STATUS_USER_INTERVENTION;
pIniPort->status |= PP_PRINTER_OFFLINE;
dwSeverity = PORT_STATUS_TYPE_ERROR;
}
break;
case TOKEN_INFO_STATUS_ONLINE:
case TOKEN_USTATUS_DEVICE_ONLINE:
// DBGMSG(DBG_INFO, ("PJLMON:ONLINE = %d\n", tokenPairs[i].value));
if (tokenPairs[i].value) {
pIniPort->status &= ~PP_PRINTER_OFFLINE;
dwSeverity = pIniPort->PrinterStatus ? PORT_STATUS_TYPE_WARNING :
0;
} else {
if ( !pIniPort->PrinterStatus )
pIniPort->PrinterStatus = PORT_STATUS_OFFLINE;
pIniPort->status |= PP_PRINTER_OFFLINE;
dwSeverity = PORT_STATUS_TYPE_ERROR;
}
break;
case TOKEN_USTATUS_JOB_NAME_MSJOB:
#ifdef DEBUG
sprintf(msg, "EOJ for %d\n", tokenPairs[i].value);
OutputDebugStringA(msg);
#endif
SendJobLastPageEjected(pIniPort, (DWORD)tokenPairs[i].value, FALSE);
break;
case TOKEN_INFO_CONFIG_MEMORY:
case TOKEN_INFO_CONFIG_MEMORY_SPACE:
// IMPORTANT NOTE:
//
// Use SetPrinterData to cache the information in printer's registry.
// GDI's DrvGetPrinterData will check the printer's registry first,
// and if cache data is available, it will use it and not call
// GetPrinterData (which calls language monitor's
// GetPrinterDataFromPort).
#ifdef DEBUG
sprintf(msg, "PJLMON installed memory %d\n", tokenPairs[i].value);
OutputDebugStringA(msg);
#endif
pIniPort->dwInstalledMemory = (DWORD)tokenPairs[i].value;
break;
case TOKEN_INFO_MEMORY_TOTAL:
// IMPORTANT NOTE:
//
// Use SetPrinterData to cache the information in printer's registry.
// GDI's DrvGetPrinterData will check the printer's registry first,
// and if cache data is available, it will use it and not call
// GetPrinterData (which calls language monitor's
// GetPrinterDataFromPort).
#ifdef DEBUG
sprintf(msg, "PJLMON available memory %d\n", tokenPairs[i].value);
OutputDebugStringA(msg);
#endif
pIniPort->dwAvailableMemory = (DWORD)tokenPairs[i].value;
break;
default:
break;
}
}
if ( OldStatus != pIniPort->PrinterStatus ) {
ZeroMemory(&PortInfo3, sizeof(PortInfo3));
PortInfo3.dwStatus = pIniPort->PrinterStatus;
PortInfo3.dwSeverity = dwSeverity;
if ( !SetPort(NULL,
pIniPort->pszPortName,
3,
(LPBYTE)&PortInfo3) ) {
DBGMSG(DBG_WARNING,
("pjlmon: SetPort failed %d (LE: %d)\n",
pIniPort->PrinterStatus, GetLastError()));
pIniPort->PrinterStatus = OldStatus;
}
}
}
VOID
ProcessParserError(
DWORD status
)
/*++
Routine Description:
Print error messages on parsing error
Arguments:
status : status
Return Value:
None
--*/
{
#ifdef DEBUG
LPSTR pString;
switch (status)
{
case STATUS_REACHED_END_OF_COMMAND_OK:
pString = "STATUS_REACHED_END_OF_COMMAND_OK\n";
break;
case STATUS_CONTINUE:
pString = "STATUS_CONTINUE\n";
break;
case STATUS_REACHED_FF:
pString = "STATUS_REACHED_FF\n";
break;
case STATUS_END_OF_STRING:
pString = "STATUS_END_OF_STRING\n";
break;
case STATUS_SYNTAX_ERROR:
pString = "STATUS_SYNTAX_ERROR\n";
break;
case STATUS_ATPJL_NOT_FOUND:
pString = "STATUS_ATPJL_NOT_FOUND\n";
break;
case STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS:
pString = "STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS\n";
break;
default:
pString = "INVALID STATUS RETURNED!!!!!!\n";
break;
};
OutputDebugStringA(pString);
#endif
}
#define MODEL "MODEL:"
#define MDL "MDL:"
#define COMMAND "COMMAND SET:"
#define CMD "CMD:"
#define COLON ':'
#define SEMICOLON ';'
LPSTR
FindP1284Key(
PINIPORT pIniPort,
LPSTR lpKey
)
/*++
Routine Description:
Find the 1284 key identifying the device id
Arguments:
status : status
Return Value:
Pointer to the command string, NULL if not found.
--*/
{
LPSTR lpValue; // Pointer to the Key's value
WORD wKeyLength; // Length for the Key (for stringcmps)
LPSTR ret = NULL;
// While there are still keys to look at.
#ifdef DEBUG
OutputDebugStringA("PJLMon!DeviceId : <");
OutputDebugStringA(lpKey);
OutputDebugStringA(">\n");
#endif
while (lpKey && *lpKey) {
//
// Is there a terminating COLON character for the current key?
//
if (!(lpValue = mystrchr(lpKey, COLON)) ) {
//
// N: OOPS, somthing wrong with the Device ID
//
return ret;
}
//
// The actual start of the Key value is one past the COLON
//
++lpValue;
//
// Compute the Key length for Comparison, including the COLON
// which will serve as a terminator
//
wKeyLength = (WORD)(lpValue - lpKey);
//
// Compare the Key to the Know quantities. To speed up the comparison
// a Check is made on the first character first, to reduce the number
// of strings to compare against.
// If a match is found, the appropriate lpp parameter is set to the
// key's value, and the terminating SEMICOLON is converted to a NULL
// In all cases lpKey is advanced to the next key if there is one.
//
if ( *lpKey == 'C' ) {
//
// Look for COMMAND SET or CMD
//
if ( !mystrncmp(lpKey, COMMAND, wKeyLength) ||
!mystrncmp(lpKey, CMD, wKeyLength) ) {
ret = lpValue;
}
}
// Go to the next Key
if ( lpKey = mystrchr(lpValue, SEMICOLON) ) {
*lpKey = '\0';
++lpKey;
}
}
return ret;
}
BOOL
IsPJL(
PINIPORT pIniPort
)
/*++
Routine Description:
Finds out if the printer is a PJL bi-di printer
Arguments:
pIniPort : Points to an INIPORT
Return Value:
TRUE if printer is PJL bi-di, else FALSE
On failure PP_DONT_TRY_PJL is set
--*/
{
char szID[MAX_DEVID];
DWORD cbRet;
LPSTR lpCMD;
HANDLE hPort = (HANDLE)pIniPort;
BOOL bRet = FALSE;
//
// for printers that supports P1284 plug and play like LJ 4L, DJ540.
// we parse the COMMAND string and see if PJL is supported
//
if (pIniPort->fn.pfnGetPrinterDataFromPort) {
//
// Only try P1284 if port monitor supports DeviceIOCtl
//
memset((LPBYTE)szID, 0, sizeof(szID));
cbRet = 0;
if ((*pIniPort->fn.pfnGetPrinterDataFromPort)
(pIniPort->hPort, GETDEVICEID, NULL, NULL,
0, (LPWSTR)szID, sizeof(szID), &cbRet)
&& cbRet) {
//
// succeeded the P1284 plug and play protocol
//
szID[cbRet] = '\0';
if ( lpCMD = FindP1284Key(pIniPort, szID) ) {
// found the COMMAND string
while (*lpCMD) {
//
// look for "PJL"
//
if ( lpCMD[0] == 'P' && lpCMD[1] == 'J' && lpCMD[2] == 'L' ){
pIniPort->status &= ~PP_DONT_TRY_PJL;
bRet = TRUE;
goto Cleanup;
}
lpCMD++;
}
pIniPort->status |= PP_DONT_TRY_PJL;
goto Cleanup;
}
}
//
// fall thru to try PJL bi-di if we failed the P1284 communication
// or P1284 didn't return a COMMAND string
//
}
//
// for printers that don't support P1284 plug and play, but support PJL
// language command, like LJ 4 and 4M. we try to write/read PJL
// command and see if it succeeds.
// if we can't set the time outs we don't want to try to read, just fail.
//
if ( pIniPort->fn.pfnSetPortTimeOuts &&
!(pIniPort->status & PP_DONT_TRY_PJL)) {
COMMTIMEOUTS CTO;
memset((LPSTR)&CTO, 0, sizeof(CTO));
CTO.ReadTotalTimeoutConstant = 5000;
CTO.ReadIntervalTimeout = 200;
if ( !(*pIniPort->fn.pfnSetPortTimeOuts)(pIniPort->hPort, &CTO, 0) ) {
goto Cleanup;
}
// This <ESC>*s1M is a PCL5 command to determine the amount of memory
// in a PCL5 printer, and if the printer is PCL5 and bi-di capable,
// it will return "PCL\015\012INFO MEMORY".
// See PJL Tech Ref Manual page 7-21.
pIniPort->status &= ~PP_IS_PJL;
if ( !WriteCommand(hPort, "\033*s1M") )
goto Cleanup;
// ReadCommand->ProcessPJLString will set PP_IS_PJL
// if we read any valid PJL command back from the printer
if ( !ReadCommand(hPort) ) {
//
// We have jumped through the hoop to determin if this printer can
// understand PJL. It DOES NOT. We are not going to try again.
// until there is a printer change.
//
pIniPort->status |= PP_DONT_TRY_PJL;
}
if (pIniPort->status & PP_IS_PJL) {
bRet = TRUE;
goto Cleanup;
}
}
Cleanup:
if ( bRet ) {
WriteCommand(hPort, "\033%-12345X@PJL \015\012@PJL USTATUS TIMED 30 \015\012\033%-12345X");
pIniPort->dwLastReadTime = GetTickCount();
}
return bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -