Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

353 lines
6.8 KiB

// CallBkQ.cpp -- Implementation for class CCallbackQueue
#include "stdafx.h"
#include "CallBkQ.h"
#include "AbrtSrch.h"
CCallbackQueue *CCallbackQueue::NewInputCallQueue (PFNQCallBack pfn, PVOID pv)
{
CCallbackQueue *pcbq= NULL;
__try
{
pcbq= New CCallbackQueue();
pcbq->Initial(pfn, pv, FALSE);
}
__finally
{
if (_abnormal_termination() && pcbq)
{
delete pcbq; pcbq= NULL;
}
}
return pcbq;
}
CCallbackQueue *CCallbackQueue::NewOutputCallQueue(PFNQCallBack pfn, PVOID pv)
{
CCallbackQueue *pcbq= NULL;
__try
{
pcbq= New CCallbackQueue();
pcbq->Initial(pfn, pv, TRUE);
}
__finally
{
if (_abnormal_termination() && pcbq)
{
delete pcbq; pcbq= NULL;
}
}
return pcbq;
}
void CCallbackQueue::Initial(PFNQCallBack pfn, PVOID pv, BOOL fOutput)
{
m_pfn = pfn;
m_pvEnvironment = pv;
Enable(fOutput);
}
const UINT *CCallbackQueue::RawNextDWordsIn(PUINT pcdw)
{
ASSERT(!Writable());
CAbortSearch::CheckContinueState();
m_pfn(m_pvEnvironment, RequestInput, &m_pdwLast, &m_cdwReserved, *pcdw);
*pcdw= m_cdwReserved;
return m_pdwLast;
}
BOOL CCallbackQueue::RawEmptyRing()
{
ASSERT(!Writable());
BOOL fEmpty= m_cdwReserved;
m_pfn(m_pvEnvironment, QueryForEmptyRing, &m_pdwLast, PUINT(&fEmpty), 0);
return fEmpty;
}
UINT *CCallbackQueue::RawNextDWordsOut(PUINT pcdw)
{
ASSERT(Writable());
CAbortSearch::CheckContinueState();
m_pfn(m_pvEnvironment, RequestOutput, &m_pdwLast, &m_cdwReserved, *pcdw);
*pcdw= m_cdwReserved;
return m_pdwLast;
}
void CCallbackQueue::RawFlushOutput(BOOL fForceAll)
{
ASSERT(Writable());
CAbortSearch::CheckContinueState();
m_pfn(m_pvEnvironment, Flush, &m_pdwLast, &m_cdwReserved, fForceAll);
}
CDWInputQueue *CDWInputQueue::NewInputCallQueue (PFNPerDWordI pfn, PVOID pv)
{
CDWInputQueue *piq= NULL;
__try
{
piq= New CDWInputQueue();
piq->Initial(pfn, pv);
}
__finally
{
if (_abnormal_termination() && piq)
{
delete piq; piq= NULL;
}
}
return piq;
}
CDWInputQueue::CDWInputQueue()
{
m_pvEnvironment = NULL;
m_pfnI = NULL;
m_fEndOfInput = FALSE;
m_pdwLimit = m_adwBuffer;
}
void CDWInputQueue::Initial(PFNPerDWordI pfn, PVOID pv)
{
m_pfnI = pfn;
m_pvEnvironment = pv;
CCallbackQueue::Initial(CDWInputQueue::InputCallback, this);
UINT cdwActive= CDW_BUFFER;
if (pfn(pv, m_adwBuffer, &cdwActive)) m_fEndOfInput= TRUE;
m_pdwLimit= m_adwBuffer + cdwActive;
}
void CDWInputQueue::InputCallback(PVOID pv, CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
{
((CDWInputQueue *) pv)->Callback(cbt, ppdwLast, pcdwLast, cdwRequest);
}
void CDWInputQueue::Callback(CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
{
ASSERT(m_pfnI);
PUINT pdw;
UINT cdw;
switch(cbt)
{
case RequestInput:
pdw= *ppdwLast;
if (!pdw) pdw= m_adwBuffer;
pdw += *pcdwLast;
if (!cdwRequest) { *ppdwLast= pdw; *pcdwLast= 0; return; }
if (pdw == m_pdwLimit)
{
pdw= m_adwBuffer;
if (m_fEndOfInput) { *ppdwLast= NULL; *pcdwLast= 0; return; }
else
{
UINT cdwActive= CDW_BUFFER;
CAbortSearch::CheckContinueState();
if (m_pfnI(m_pvEnvironment, pdw, &cdwActive)) m_fEndOfInput= TRUE;
if (cdwActive) m_pdwLimit= pdw + cdwActive;
else { ASSERT(m_fEndOfInput); *ppdwLast= NULL; *pcdwLast= 0; return; }
}
}
cdw= m_pdwLimit - pdw;
*ppdwLast= pdw;
*pcdwLast= (cdw > cdwRequest)? cdwRequest : cdw;
return;
case QueryForEmptyRing:
pdw= *ppdwLast;
if (!pdw) pdw= m_adwBuffer;
pdw += *pcdwLast;
if (pdw < m_pdwLimit) { *pcdwLast= FALSE; return; }
if (m_fEndOfInput) { *pcdwLast= TRUE; return; }
return;
case RequestOutput:
ASSERT(FALSE); // Shouldn't be called for output functions...
return;
case Flush:
ASSERT(FALSE); // Shouldn't be called for output functions...
return;
case Disconnect:
return; // Don't have any disconnect actions to perform
default:
ASSERT(FALSE); // Unknown transaction type
return;
}
}
CDWOutputQueue::CDWOutputQueue()
{
m_pvEnvironment = NULL;
m_pfnO = NULL;
}
CDWOutputQueue::~CDWOutputQueue()
{
// FlushOutput(TRUE);
// Disable();
}
void CDWOutputQueue::Initial(PFNPerDWordO pfn, PVOID pv)
{
m_pfnO = pfn;
m_pvEnvironment = pv;
CCallbackQueue::Initial(OutputCallback, this, TRUE);
}
CDWOutputQueue *CDWOutputQueue::NewOutputCallQueue(PFNPerDWordO pfn, PVOID pv)
{
CDWOutputQueue *poq= NULL;
__try
{
poq= New CDWOutputQueue();
poq->Initial(pfn, pv);
}
__finally
{
if (_abnormal_termination() && poq)
{
delete poq; poq= NULL;
}
}
return poq;
}
void CDWOutputQueue::OutputCallback(PVOID pv, CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
{
((CDWOutputQueue *) pv)->Callback(cbt, ppdwLast, pcdwLast, cdwRequest);
}
void CDWOutputQueue::Callback(CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
{
ASSERT(m_pfnO);
PUINT pdw;
UINT cdw;
switch(cbt)
{
case RequestInput:
ASSERT(FALSE); // Shouldn't get any input transactions;
return;
case QueryForEmptyRing:
ASSERT(FALSE); // Shouldn't get any input transactions;
return;
case RequestOutput:
pdw= *ppdwLast;
if (!pdw) pdw= m_adwBuffer;
pdw += *pcdwLast;
cdw= CDW_BUFFER - (pdw - m_adwBuffer);
if (!cdw)
{
CAbortSearch::CheckContinueState();
m_pfnO(m_pvEnvironment, m_adwBuffer, CDW_BUFFER);
pdw = m_adwBuffer;
cdw = CDW_BUFFER;
}
if (cdw > cdwRequest) cdw= cdwRequest;
*ppdwLast= pdw;
*pcdwLast= cdw;
return;
case Flush:
pdw= *ppdwLast;
if (!pdw) pdw= m_adwBuffer;
pdw += *pcdwLast;
m_pfnO(m_pvEnvironment, m_adwBuffer, pdw - m_adwBuffer);
*ppdwLast= m_adwBuffer;
*pcdwLast= 0;
return;
case Disconnect:
return; // Don't have any disconnect actions to perform
default:
ASSERT(FALSE); // Unknown transaction type
return;
}
}