VOID FreeIniJobs( __inout PINIPORT pIniPort ) /*++ Routine Description: Free all the InJob structures assigned to this port Arguments: pIniPort : IniPort for the port for which all jobs need to be freed --*/ { PINIJOB pIniJob, pIniNextJob; EnterSplSem(); pIniJob = pIniPort->pIniJob; while ( pIniJob ) { pIniNextJob = pIniJob->pNext; FreeIniJob(pIniJob); pIniJob = pIniNextJob; } pIniPort->pIniJob = NULL; LeaveSplSem(); }
BOOL WINAPI PJLMonStartDocPort( IN HANDLE hPort, IN LPTSTR pszPrinterName, IN DWORD dwJobId, IN DWORD dwLevel, IN LPBYTE pDocInfo ) /*++ Routine Description: Language monitor StartDocPort Arguments: hPort : Port handle pszPrinterName : Printer name dwJobId : Job identifier dwLevel : Level of Doc info strucuture pDocInfo : Pointer to doc info structure Return Value: TRUE on success, FALSE on error --*/ { PINIPORT pIniPort = (PINIPORT)((INIPORT *)hPort); PINIJOB pIniJob = NULL; DWORD cbJob; BOOL bRet = FALSE; // // Validate parameters // if ( !pIniPort || pIniPort->signature != PJ_SIGNATURE || !pDocInfo || !pszPrinterName || !*pszPrinterName ) { SPLASSERT(pIniPort && pIniPort->signature == PJ_SIGNATURE && pDocInfo); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if ( dwLevel != 1 ) { SPLASSERT(dwLevel == 1); SetLastError(ERROR_INVALID_LEVEL); return FALSE; } // // Serialize access to the port // if ( pIniPort->status & PP_INSTARTDOC ) { SetLastError(ERROR_BUSY); return FALSE; } WaitForSingleObject(pIniPort->DoneWriting, INFINITE); cbJob = sizeof(*pIniJob) + lstrlen(pszPrinterName) * sizeof(TCHAR) + sizeof(TCHAR); pIniJob = (PINIJOB) AllocSplMem(cbJob); if ( !pIniJob ) { goto Cleanup; } pIniJob->pszPrinterName = wcscpy((LPTSTR)(pIniJob+1), pszPrinterName); if ( !OpenPrinter(pIniJob->pszPrinterName, &pIniJob->hPrinter, NULL) ) { DBGMSG(DBG_WARNING, ("pjlmon: OpenPrinter failed for %s, last error %d\n", pIniJob->pszPrinterName, GetLastError())); goto Cleanup; } pIniPort->status |= PP_INSTARTDOC; bRet = (*pIniPort->fn.pfnStartDocPort)(pIniPort->hPort, pszPrinterName, dwJobId, dwLevel, pDocInfo); if ( !bRet ) { pIniPort->status &= ~PP_INSTARTDOC; goto Cleanup; } // // If Ustatus thread is not running then check if printer understands // PJL, unless we determined that printer does not understand PJL earlier // if ( !(pIniPort->status & PP_RUN_THREAD) && !(pIniPort->status & PP_DONT_TRY_PJL) ) { if ( IsPJL(pIniPort) ) pIniPort->status |= PP_IS_PJL; else pIniPort->status &= ~PP_IS_PJL; } // // set PP_SEND_PJL flag here so the first write of the job // will try to send PJL command to initiate the job control // pIniJob->JobId = dwJobId; pIniJob->status |= PP_INSTARTDOC; if ( pIniPort->status & PP_IS_PJL ) pIniJob->status |= PP_SEND_PJL; EnterSplSem(); if ( !pIniPort->pIniJob ) { pIniPort->pIniJob = pIniJob; } else { pIniJob->pNext = pIniPort->pIniJob; pIniPort->pIniJob = pIniJob; } LeaveSplSem(); if ( (pIniPort->status & PP_IS_PJL) && !(pIniPort->status & PP_RUN_THREAD) ) { // // only create the read thread if printer is PJL capable // CreateUstatusThread(pIniPort); } Cleanup: if ( !bRet ) { SetEvent(pIniPort->DoneWriting); if ( pIniJob ) FreeIniJob(pIniJob); } return bRet; }
VOID SendJobLastPageEjected( __in PINIPORT pIniPort, __int64 nValue, BOOL bTime ) /*++ Routine Description: Send LastPageEjected notification for 1 or more jobs to spooler Arguments: pIniPort : IniPort for the port for which all jobs need to be freed nValue : if bTime is TRUE send EOJ to any jobs rcvd before nValue else nValue is JobId -- ALL_JOBS is for all jobs bTime : Tells how to interpret nValue (FALSE means it is a DWORD JobId) --*/ { PINIJOB pIniJob; EnterSplSem(); // // JobId == ALL_JOBS is a special case where we want to send LastPage // ejected for all jobs pending // if ( (!bTime) && (ALL_JOBS == nValue) ) { pIniJob = pIniPort->pIniJob; pIniPort->pIniJob = NULL; while ( pIniJob ) { PINIJOB pTempJob = pIniJob; SendLastPageEjectedForIniJob(pIniPort, pIniJob); pIniJob = pIniJob->pNext; FreeIniJob(pTempJob); } } else { PINIJOB pPrevIniJob = NULL; pIniJob = pIniPort->pIniJob; // // If bTime we want to send LastPageEjected for all jobs timedout // if ( bTime ) { pIniJob = FindFirstIniJobTimedOut(pIniPort, nValue, &pPrevIniJob); } else { pIniJob = FindIniJobFromJobId(pIniPort, (DWORD)nValue, &pPrevIniJob); } if ( pIniJob ) { // // Send notifications for any previous jobs too // if ( pIniPort->pIniJob == pIniJob ) pIniPort->pIniJob = NULL; else pPrevIniJob->pNext = NULL; do { SendLastPageEjectedForIniJob(pIniPort, pIniJob); pPrevIniJob = pIniJob; pIniJob = pIniJob->pNext; FreeIniJob(pPrevIniJob); } while ( pIniJob ); } } LeaveSplSem(); }