📄 printqueue.cpp
字号:
PrintJob *
SMBPrintQueue::GetJobNextJobThatIsReady()
{
CCritSection csLock(&csJobListLock);
PrintJob *pJob = NULL;
csLock.Lock();
if(0 != this->GetNumJobs()) {
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator it;
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator itEnd = PrintJobList.end();
for(it=PrintJobList.begin(); it!=itEnd; it++) {
BOOL fInQueue = (*it)->GetInternalStatus() & JOB_STATUS_IN_QUEUE;
BOOL fAborted = (*it)->GetInternalStatus() & JOB_STATUS_ABORTED;
BOOL fPrinted = (*it)->GetInternalStatus() & JOB_STATUS_PRINTED;
if(fInQueue &&
!fAborted &&
!fPrinted) {
pJob = (*it);
}
}
}
return pJob;
}
PrintJob *
SMBPrintQueue::WaitForJobThatIsReady()
{
PrintJob *pPrintJob = NULL;
//
// If we are shutting down return back
if(TRUE == ShuttingDown()) {
TRACEMSG(ZONE_PRINTQUEUE, (L"SMBSRV-PRINTQUEUE: shutting down print spool!"));
goto Done;
}
//
// See if we have a job waiting (no need to block then)... the rule on blocking
// is you can only do it once... meaning once a job is put in the queue
// and the semaphore is incremented you can only WaitForSingleObject
// on that one once. this makes sense -- but its nice to call GetNextJobWithData()
// again in the case of LPT failure (where CreateFile failes).
// so dont block if there is something in the queue already.
if(NULL != (pPrintJob = GetJobNextJobThatIsReady())) {
goto Done;
}
//
// Now since there isnt anything in the queue, block untile there is
//
if(WAIT_FAILED == WaitForSingleObject(ReadyToPrintSemaphore, INFINITE)) {
TRACEMSG(ZONE_INIT, (L"SMBSRV-PRINTQUEUE:Waiting for spool semaphore FAILED -- stopping thread!"));
ASSERT(FALSE);
goto Done;
}
//
// The way we signal the print queue to terminate is by setting shutdown
// and settingthe ReadyToPrintSemaphore -- so handle that here
if(TRUE == ShuttingDown()) {
TRACEMSG(ZONE_PRINTQUEUE, (L"SMBSRV-PRINTQUEUE: shutting down print spool!"));
goto Done;
}
//
// Since we are awake, there prob is a job... fetch it
if(0 != this->GetNumJobs()) {
pPrintJob = GetJobNextJobThatIsReady();
goto Done;
}
Done:
// NOTE: do *NOT* addref this. when the flag JOB_STATUS_IN_QUEUE
// is set, THEN do the addref
return pPrintJob;
}
/*
VOID
SMBPrintQueue::RemoveNextJobWithData()
{
CCritSection csLock(&csPrintJobsWithData);
PrintJob *pMyJob = NULL;
csLock.Lock();
if(NULL != (pMyJob = PrintJobsWithData.front())) {
PrintJobsWithData.pop_front();
pMyJob->Release();
}
}
HRESULT
SMBPrintQueue::RemoveJobWithData(USHORT usFID)
{
CCritSection csLockWithData(&csPrintJobsWithData);
csLockWithData.Lock();
HRESULT hr = E_FAIL;
//
// Check jobs that are in the queue
ce::list<PrintJob *>::iterator itWithData;
ce::list<PrintJob *>::iterator itEndWithData = PrintJobsWithData.end();
for(itWithData = PrintJobsWithData.begin(); itWithData != itEndWithData; ++itWithData) {
if(usFID == (*itWithData)->JobID()) {
PrintJobsWithData.erase(itWithData++);
hr = S_OK;
break;
}
}
return hr;
}
*/
HRESULT
SMBPrintQueue::GetJobsInQueue(ce::list<PrintJob *, PRINTJOB_LIST_ALLOC> *pJobList)
{
CCritSection csLockWithData(&csJobListLock);
csLockWithData.Lock();
HRESULT hr = E_FAIL;
//
// Check jobs that are in the queue
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator itWithData;
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator itEndWithData = PrintJobList.end();
//
// Verify incoming args
if(NULL == pJobList) {
ASSERT(FALSE);
hr = E_INVALIDARG;
goto Done;
}
ASSERT(0 == pJobList->size());
for(itWithData = PrintJobList.begin(); itWithData != itEndWithData; ++itWithData) {
BOOL fInQueue = (*itWithData)->GetInternalStatus() & JOB_STATUS_IN_QUEUE;
BOOL fAborted = (*itWithData)->GetInternalStatus() & JOB_STATUS_ABORTED;
BOOL fPrinted = (*itWithData)->GetInternalStatus() & JOB_STATUS_PRINTED;
if(fInQueue &&
!fAborted &&
!fPrinted) {
if(!pJobList->push_front(*itWithData)) {
hr = E_OUTOFMEMORY;
goto Done;
}
(*itWithData)->AddRef();
}
}
//
// Success
hr = S_OK;
Done:
return hr;
}
USHORT
SMBPrintQueue::GetPriority()
{
return Priority;
}
VOID
SMBPrintQueue::SetPriority(USHORT prio)
{
Priority = prio;
}
USHORT
SMBPrintQueue::GetStartTime()
{
return StartTime;
}
VOID
SMBPrintQueue::SetStartTime(USHORT sTime)
{
StartTime = sTime;
}
USHORT
SMBPrintQueue::GetUntilTime()
{
return UntilTime;
}
VOID
SMBPrintQueue::SetUntilTime(USHORT sUntil)
{
UntilTime = sUntil;
}
USHORT
SMBPrintQueue::GetStatus()
{
return Status;
}
USHORT
SMBPrintQueue::GetNumJobs()
{
CCritSection csLock(&csJobListLock);
csLock.Lock();
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator it;
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator itEnd = PrintJobList.end();
UINT uiCnt = 0;
for(it=PrintJobList.begin(); it!=itEnd; it++) {
BOOL fInQueue = (*it)->GetInternalStatus() & JOB_STATUS_IN_QUEUE;
BOOL fAborted = (*it)->GetInternalStatus() & JOB_STATUS_ABORTED;
BOOL fPrinted = (*it)->GetInternalStatus() & JOB_STATUS_PRINTED;
if(fInQueue &&
!fAborted &&
!fPrinted) {
uiCnt ++;
}
}
return uiCnt;
}
VOID
SMBPrintQueue::SetStatus(USHORT status)
{
Status = status;
}
const CHAR *
SMBPrintQueue::GetDriverName()
{
return pDriverName;
}
HRESULT
SMBPrintQueue::SetDriverName(const CHAR *_pName)
{
return SetString(&pDriverName, _pName);
}
const CHAR *
SMBPrintQueue::GetName()
{
return pName;
}
HRESULT
SMBPrintQueue::SetName(const CHAR *_pName)
{
return SetString(&pName, _pName);
}
const CHAR *
SMBPrintQueue::GetSepFile()
{
return pSepFile;
}
HRESULT
SMBPrintQueue::SetSepFile(const CHAR *_pName)
{
return SetString(&pSepFile, _pName);
}
const CHAR *
SMBPrintQueue::GetPrProc()
{
return pPrProc;
}
HRESULT
SMBPrintQueue::SetPrProc(const CHAR *_pName)
{
return SetString(&pPrProc, _pName);
}
const CHAR *
SMBPrintQueue::GetParams()
{
return pParams;
}
HRESULT
SMBPrintQueue::SetParams(const CHAR *_pName)
{
return SetString(&pParams, _pName);
}
const CHAR *
SMBPrintQueue::GetComment()
{
return pComment;
}
HRESULT
SMBPrintQueue::SetComment(const CHAR *_pName)
{
return SetString(&pComment, _pName);
}
const CHAR *
SMBPrintQueue::GetPrinters()
{
return pPrinters;
}
HRESULT
SMBPrintQueue::SetPrinters(const CHAR *_pName)
{
return SetString(&pPrinters, _pName);
}
const CHAR *
SMBPrintQueue::GetDriverData()
{
return pDriverData;
}
const WCHAR *
SMBPrintQueue::GetPortName()
{
return wPortName;
}
HRESULT
SMBPrintQueue::SetDriverData(const CHAR *_pName)
{
return SetString(&pDriverData, _pName);
}
HRESULT
SMBPrintQueue::SetPortName(const WCHAR *_pName)
{
//BUGBUG: make this more robust
UINT uiSize = wcslen(_pName) + 1;
if(NULL == (wPortName = new WCHAR[uiSize])) {
return E_OUTOFMEMORY;
}
wcscpy(wPortName, _pName);
return S_OK;
}
HRESULT
SMBPrintQueue::AddJobToSpool(PrintJob *pPrintJob)
{
HRESULT hr;
CCritSection csLock(&csJobListLock);
csLock.Lock();
//
// Add the print job (note: WE DO NOT AddRef()... this is because the
// *ONLY* person to be removing us is the PrintJob destructor
if(!PrintJobList.push_front(pPrintJob)) {
hr = E_OUTOFMEMORY;
} else {
hr = S_OK;
}
return hr;
}
HRESULT
SMBPrintQueue::JobReadyForPrint(PrintJob *pPrintJob)
{
HRESULT hr = E_FAIL;
if(INVALID_HANDLE_VALUE == ReadyToPrintSemaphore) {
hr = E_UNEXPECTED;
TRACEMSG(ZONE_ERROR, (L"SMBSRV-PRINTQUEUE: ERROR!! print queue semaphore is invalid!!"));
ASSERT(FALSE);
goto Done;
}
//
// NOTE: NULL is valid for the case of shutdown
if(pPrintJob) {
TRACEMSG(ZONE_PRINTQUEUE, (L"SMBSRV-PRINTQUEUE: Job %d ready for print -- transfering to print queue list", pPrintJob->JobID()));
ASSERT(FALSE == (pPrintJob->GetInternalStatus() & JOB_STATUS_IN_QUEUE));
pPrintJob->SetInternalStatus(pPrintJob->GetInternalStatus() | JOB_STATUS_IN_QUEUE);
//
// Give a reference to the print spool
pPrintJob->AddRef();
}
//
// Note: its OKAY (not cool) to say your ready to print
// multiple times... the printing thread will just loop
ReleaseSemaphore(ReadyToPrintSemaphore, 1, NULL);
hr = S_OK;
Done:
return hr;
}
VOID
SMBPrintQueue::StopAllJobs()
{
CCritSection csLock(&csJobListLock);
csLock.Lock();
//
// Shut down any print jobs that might be outstanding
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator it;
ce::list<PrintJob *, PRINTJOB_LIST_ALLOC >::iterator itEnd = PrintJobList.end();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -