PINIJOB FindFirstIniJobTimedOut( __in PINIPORT pIniPort, __int64 nTime, __deref_out_opt PINIJOB *ppPrevIniJob ) { PINIJOB pIniJob = pIniPort->pIniJob; SplInSem(); *ppPrevIniJob = NULL; // // Look for a job not in STARTDOC and timedout // while ( pIniJob && ( (pIniJob->status & PP_INSTARTDOC) || pIniJob->nTimeoutCount > nTime ) ) { *ppPrevIniJob = pIniJob; pIniJob = pIniJob->pNext; } if ( !pIniJob ) *ppPrevIniJob = NULL; return pIniJob; }
PINIJOB FindIniJobFromJobId( __in PINIPORT pIniPort, DWORD dwJobId, __deref_out_opt PINIJOB *ppPrevIniJob ) { PINIJOB pCur, pPre, pIniJob; SplInSem(); // // If JOB_RESTART is given there will be multiple jobs with same id // we need to find the last entry with given id in the list // for ( pCur = pIniPort->pIniJob, pPre = pIniJob = *ppPrevIniJob = NULL ; pCur ; pPre = pCur, pCur = pCur->pNext ) { if ( pCur->JobId == dwJobId ) { *ppPrevIniJob = pPre; pIniJob = pCur; } } return pIniJob; }
VOID LeaveSplSem( VOID ) { SplInSem(); LeaveCriticalSection(&pjlMonSection); }
VOID SendLastPageEjectedForIniJob( __in PINIPORT pIniPort, __in PINIJOB pIniJob ) { UNREFERENCED_PARAMETER(pIniPort); SplInSem(); if ( !SetJob(pIniJob->hPrinter, pIniJob->JobId, 0, NULL, JOB_CONTROL_LAST_PAGE_EJECTED) ) { DBG_MSG(DBG_WARN, ("SetJob failed with last error %d\n", GetLastError())); } }
PINIPORT FindIniPort( __in LPTSTR pszName ) { PINIPORT pIniPort = pIniFirstPort; if ( !pszName || !*pszName ) return NULL; SplInSem(); while ( pIniPort && lstrcmpi(pszName, pIniPort->pszPortName)) pIniPort = pIniPort->pNext; return pIniPort; }
BOOL DeletePrinterHandle( PSPOOL pSpool ) { BOOL bRet = FALSE; SplInSem(); if (pSpool->pIniPrintProc) { pSpool->pIniPrintProc->cRef--; } if (pSpool->pDevMode) FreeSplMem(pSpool->pDevMode); FreeSplStr(pSpool->pUserName); FreeSplStr(pSpool->pMachineName); FreeSplStr(pSpool->pDatatype); SetSpoolClosingChange(pSpool); FreeSplStr(pSpool->pName); bRet = ObjectCloseAuditAlarm( szSpooler, pSpool, pSpool->GenerateOnClose ); // // If there is a WaitForPrinterChange outstanding, we can't free // the pSpool, since we may try and reference it. // if (pSpool->ChangeEvent) { pSpool->eStatus |= STATUS_PENDING_DELETION; } else { FreeSplMem(pSpool); } return TRUE; }
VOID DeletePortEntry( __in PINIPORT pIniPort ) /*++ Routine Description: Deletes a port entry. Needs to be called inside monitor critical section Arguments: pIniPort : Pointer to the IniPort structure to be deleted Return Value: --*/ { SplInSem(); if ( pIniPort == pIniFirstPort ) { pIniFirstPort = pIniPort->pNext; } else { PINIPORT pPort; pPort = pIniFirstPort; while ( pPort && pPort->pNext != pIniPort ) pPort = pPort->pNext; if (pPort) { pPort->pNext = pIniPort->pNext; } else { DBG_MSG(DBG_ERROR, ("pjlmon: DeletePortEntry port not found\n")); return; } } if (pIniPort-> DoneWriting) { CloseHandle(pIniPort->DoneWriting); pIniPort->DoneWriting = NULL; } if (pIniPort-> DoneReading) { CloseHandle(pIniPort->DoneReading); pIniPort->DoneReading = NULL; } if (pIniPort-> WakeUp) { CloseHandle(pIniPort->WakeUp); pIniPort->WakeUp = NULL; } if (pIniPort-> hUstatusThread) { CloseHandle (pIniPort-> hUstatusThread); pIniPort->hUstatusThread = NULL; } FreeIniJobs(pIniPort); FreeSplStr(pIniPort->pszPortName); pIniPort->pszPortName = NULL; FreeSplMem(pIniPort); return; }
PINIPORT CreatePortEntry( __in LPTSTR pszPortName ) /*++ Routine Description: Creates a IniPort entry for a port. Needs to be called inside monitor critical section. Arguments: pszPortName : Name of the port Return Value: On success pointer to the IniPort stucture. On failure NULL --*/ { PINIPORT pIniPort = NULL; HANDLE DoneWriting = NULL; HANDLE DoneReading = NULL; HANDLE WakeUp = NULL; LPWSTR pszString = NULL; SplInSem(); DoneWriting = CreateEvent(NULL, FALSE, TRUE, NULL); if (!DoneWriting) { goto Fail; } WakeUp = CreateEvent(NULL, FALSE, FALSE, NULL); if (!WakeUp) { goto Fail; } // // manual-reset event, initially signal state // DoneReading = CreateEvent(NULL, TRUE, TRUE, NULL); if (!DoneReading) { goto Fail; } pIniPort = (PINIPORT) AllocSplMem(sizeof(*pIniPort)); if (!pIniPort) { goto Fail; } pszString = AllocSplStr(pszPortName); if (!pszString) { goto Fail; } pIniPort->pNext = NULL; pIniPort->signature = PJ_SIGNATURE; pIniPort->DoneWriting = DoneWriting; pIniPort->DoneReading = DoneReading; pIniPort->WakeUp = WakeUp; pIniPort->hUstatusThread= NULL; pIniPort->pszPortName = pszString; pIniPort->pNext = pIniFirstPort; pIniFirstPort = pIniPort; return pIniPort; Fail: if (DoneWriting) { CloseHandle (DoneWriting); } if (DoneReading) { CloseHandle (DoneReading); } if (WakeUp) { CloseHandle (WakeUp); } FreeSplMem (pszString); FreeSplMem (pIniPort); return NULL; }
DWORD CheckPrinterJobToken( LPCWSTR string, LPCWSTR pSecondPart, PDWORD pTypeofHandle, PINIPRINTER* ppIniPrinter, PINIJOB* ppIniJob, PHANDLE phReadFile, const PINISPOOLER pIniSpooler ) { HANDLE hImpersonationToken; DWORD Position; DWORD JobId; PINIPRINTER pIniPrinter; PINIJOB pIniJob, pCurrentIniJob; if( wcsncmp( pSecondPart, L"Job ", 4 ) != STRINGS_ARE_EQUAL || !( pIniPrinter = FindPrinter( string ))){ return ROUTER_UNKNOWN; } // // Get the Job ID ",Job xxxx" // pSecondPart += 4; JobId = Myatol( (LPWSTR)pSecondPart ); pIniJob = FindJob( pIniPrinter, JobId, &Position ); if( pIniJob == NULL ) { DBGMSG( DBG_WARN, ("OpenPrinter failed to find Job %d\n", JobId )); return ROUTER_UNKNOWN; } DBGMSG( DBG_TRACE, ("OpenPrinter: pIniJob->cRef = %d\n", pIniJob->cRef)); if( pIniJob->Status & JOB_DIRECT ) { SplInSem(); INCJOBREF( pIniJob ); *pTypeofHandle |= PRINTER_HANDLE_JOB | PRINTER_HANDLE_DIRECT; goto Success; } // // If this job is assigned to a port // Then pick up the correct chained jobid file instead of the master // JobId. // if ( pIniJob->pCurrentIniJob != NULL ) { SPLASSERT( pIniJob->pCurrentIniJob->signature == IJ_SIGNATURE ); DBGMSG( DBG_TRACE,("CheckPrinterJobToken pIniJob %x JobId %d using chain JobId %d\n", pIniJob, pIniJob->JobId, pIniJob->pCurrentIniJob->JobId )); pCurrentIniJob = pIniJob->pCurrentIniJob; SPLASSERT( pCurrentIniJob->signature == IJ_SIGNATURE ); } else { pCurrentIniJob = pIniJob; } GetFullNameFromId( pCurrentIniJob->pIniPrinter, pCurrentIniJob->JobId, TRUE, (LPWSTR)string, FALSE ); // !! BUGBUG !! // Even a user without previledge can open a ", JOB #" // if he is physically running on the machine. hImpersonationToken = RevertToPrinterSelf(); *phReadFile = CreateFile( string, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); ImpersonatePrinterClient( hImpersonationToken ); if( *phReadFile != INVALID_HANDLE_VALUE ) { DBGMSG( DBG_TRACE, ("OpenPrinter JobID %d pIniJob %x CreateFile( %ws ), hReadFile %x success", JobId, pIniJob, string, *phReadFile )); SplInSem(); INCJOBREF( pIniJob ); *pTypeofHandle |= PRINTER_HANDLE_JOB; goto Success; } DBGMSG( DBG_WARNING, ("LocalOpenPrinter CreateFile(%ws) GENERIC_READ failed : %d\n", string, GetLastError())); SPLASSERT( GetLastError( )); return ROUTER_STOP_ROUTING; Success: *ppIniJob = pIniJob; *ppIniPrinter = pIniPrinter; return ROUTER_SUCCESS; }