855 lines
25 KiB
C++
855 lines
25 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1991 - 2000.
|
||
|
//
|
||
|
// File: FDAEMON.CXX
|
||
|
//
|
||
|
// Contents: Filter driver
|
||
|
//
|
||
|
// History: 23-Mar-93 AmyA Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <pch.cxx>
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <fdaemon.hxx>
|
||
|
#include <widtab.hxx>
|
||
|
#include <lang.hxx>
|
||
|
#include <drep.hxx>
|
||
|
#include <cci.hxx>
|
||
|
#include <pfilter.hxx>
|
||
|
#include <pageman.hxx>
|
||
|
#include <propspec.hxx>
|
||
|
#include <pidmap.hxx>
|
||
|
#include <imprsnat.hxx>
|
||
|
#include <frmutils.hxx>
|
||
|
#include <ntopen.hxx>
|
||
|
#include <ciguid.hxx>
|
||
|
|
||
|
#include "fdriver.hxx"
|
||
|
#include "ebufhdlr.hxx"
|
||
|
#include "ikrep.hxx"
|
||
|
|
||
|
#if DEVL==1
|
||
|
void DebugPrintStatus( STATUS stat );
|
||
|
#endif // DEVL
|
||
|
|
||
|
const GUID guidHtmlMeta = HTMLMetaGuid;
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CDocBufferIter
|
||
|
//
|
||
|
// Purpose: To iterate through a docBuffer passed back from the
|
||
|
// FilterDataReady call
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
class CDocBufferIter
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
CDocBufferIter( const BYTE *pBuffer, int cbBuffer );
|
||
|
|
||
|
BOOL AtEnd();
|
||
|
|
||
|
const BYTE * GetCurrent(unsigned & iDoc, ULONG & cbDoc );
|
||
|
void Next();
|
||
|
unsigned GetCount() const { return _iDoc; }
|
||
|
|
||
|
private:
|
||
|
|
||
|
const BYTE * _pCurrent;
|
||
|
const BYTE * _pEnd;
|
||
|
|
||
|
USHORT _cDocs; // Document Count
|
||
|
USHORT _iDoc; // Current document
|
||
|
USHORT _cbCurrDoc; // Number of bytes in the current doc
|
||
|
};
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//----------------------------------------------------------------------------
|
||
|
CDocBufferIter::CDocBufferIter(const BYTE *pBuffer, int cbBuffer) :
|
||
|
_pCurrent(pBuffer+sizeof USHORT),
|
||
|
_pEnd(pBuffer+cbBuffer),
|
||
|
_iDoc(0),
|
||
|
_cbCurrDoc(0)
|
||
|
{
|
||
|
Win4Assert( cbBuffer >= sizeof USHORT );
|
||
|
RtlCopyMemory( &_cDocs, pBuffer, sizeof USHORT );
|
||
|
Win4Assert( _cDocs <= CI_MAX_DOCS_IN_WORDLIST );
|
||
|
|
||
|
//
|
||
|
// Setup for the first document.
|
||
|
//
|
||
|
if ( _cDocs > 0 )
|
||
|
{
|
||
|
Win4Assert( _pCurrent + sizeof USHORT <= _pEnd );
|
||
|
RtlCopyMemory( &_cbCurrDoc, _pCurrent, sizeof USHORT );
|
||
|
_pCurrent += sizeof USHORT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL CDocBufferIter::AtEnd()
|
||
|
{
|
||
|
Win4Assert( _iDoc <= _cDocs );
|
||
|
Win4Assert( _pCurrent <= _pEnd );
|
||
|
|
||
|
return (_iDoc == _cDocs);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//----------------------------------------------------------------------------
|
||
|
const BYTE * CDocBufferIter::GetCurrent(unsigned & iDoc, ULONG & cbDoc )
|
||
|
{
|
||
|
Win4Assert( !AtEnd() );
|
||
|
|
||
|
iDoc = _iDoc; // Number of current document
|
||
|
Win4Assert( iDoc < CI_MAX_DOCS_IN_WORDLIST );
|
||
|
cbDoc = _cbCurrDoc;
|
||
|
|
||
|
return _pCurrent;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//----------------------------------------------------------------------------
|
||
|
void CDocBufferIter::Next()
|
||
|
{
|
||
|
//
|
||
|
// Setup next document
|
||
|
//
|
||
|
if ( !AtEnd() )
|
||
|
{
|
||
|
_pCurrent += _cbCurrDoc;
|
||
|
|
||
|
if ( _pCurrent < _pEnd )
|
||
|
{
|
||
|
Win4Assert( _pCurrent + sizeof USHORT <= _pEnd );
|
||
|
|
||
|
RtlCopyMemory( &_cbCurrDoc, _pCurrent, sizeof USHORT );
|
||
|
_pCurrent += sizeof USHORT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Win4Assert( _pCurrent == _pEnd );
|
||
|
_cbCurrDoc = 0;
|
||
|
}
|
||
|
|
||
|
_iDoc++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::CFilterDaemon, public
|
||
|
//
|
||
|
// History: 23-Mar-93 AmyA Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CFilterDaemon::CFilterDaemon ( CiProxy & proxy,
|
||
|
CCiFrameworkParams & params,
|
||
|
CLangList & LangList,
|
||
|
BYTE * buf,
|
||
|
ULONG cbMax,
|
||
|
ICiCFilterClient *pICiCFilterClient )
|
||
|
: _proxy( proxy ),
|
||
|
_params( params ),
|
||
|
_cFilteredDocuments( 0 ),
|
||
|
_cFilteredBlocks( 0 ),
|
||
|
_pbCurrentDocument( NULL ),
|
||
|
_cbCurrentDocument( 0 ),
|
||
|
_fStopFilter( FALSE ),
|
||
|
_fWaitingForDocument( FALSE ),
|
||
|
_fOwned( FALSE ),
|
||
|
_entryBuffer( buf ),
|
||
|
_cbMax( cbMax ),
|
||
|
_xFilterClient( pICiCFilterClient ),
|
||
|
_LangList( LangList ),
|
||
|
_pidmap( &_proxy )
|
||
|
{
|
||
|
//
|
||
|
// Even though we've saved pICiCFilterClient in a safe pointer, it is
|
||
|
// NOT correctly referenced by the caller. That is our responsibility
|
||
|
//
|
||
|
|
||
|
_xFilterClient->AddRef( );
|
||
|
|
||
|
//
|
||
|
// get ICiCAdviseStatus interface pointer
|
||
|
//
|
||
|
|
||
|
SCODE sc = _xFilterClient->QueryInterface( IID_ICiCAdviseStatus, _xAdviseStatus.GetQIPointer() );
|
||
|
|
||
|
if ( S_OK != sc )
|
||
|
{
|
||
|
THROW( CException(sc) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get optional filter status interface.
|
||
|
//
|
||
|
|
||
|
sc = _xFilterClient->QueryInterface( IID_ICiCFilterStatus, _xFilterStatus.GetQIPointer() );
|
||
|
|
||
|
Win4Assert( ( SUCCEEDED(sc) && !_xFilterStatus.IsNull() ) ||
|
||
|
( FAILED(sc) && _xFilterStatus.IsNull() ) );
|
||
|
|
||
|
//
|
||
|
// Get config info
|
||
|
//
|
||
|
|
||
|
sc = _xFilterClient->GetConfigInfo( &_configInfo );
|
||
|
if ( FAILED(sc) )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ERROR, "GetConfigInfo failed. Error 0x%X\n", sc ));
|
||
|
THROW( CException(sc) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
if ( 0 == buf )
|
||
|
{
|
||
|
_cbMax = _params.GetFilterBufferSize() * 1024;
|
||
|
_entryBuffer = (BYTE *)VirtualAlloc(
|
||
|
0, // Requested position.
|
||
|
_cbMax, // Size (in bytes)
|
||
|
MEM_COMMIT, // We want it now.
|
||
|
PAGE_READWRITE ); // Full access, please.
|
||
|
|
||
|
_fOwned = TRUE;
|
||
|
}
|
||
|
|
||
|
_docBuffer = (BYTE *)(CPageManager::GetPage());
|
||
|
_cbTotal = PAGE_SIZE;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::~CFilterDaemon, public
|
||
|
//
|
||
|
// History: 17-May-93 AmyA Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CFilterDaemon::~CFilterDaemon()
|
||
|
{
|
||
|
if ( _fOwned )
|
||
|
VirtualFree( _entryBuffer, 0, MEM_RELEASE );
|
||
|
|
||
|
CPageManager::FreePage( _docBuffer );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::DoUpdates, private
|
||
|
//
|
||
|
// Synopsis: Filters Documents and creates word lists
|
||
|
//
|
||
|
// History: 18-Apr-93 AmyA Created
|
||
|
//
|
||
|
// Notes: This interface is exported across query.DLL, and hence can not
|
||
|
// throw an exception. If this routine ever returns, it is
|
||
|
// the result of an error.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
SCODE CFilterDaemon::DoUpdates()
|
||
|
{
|
||
|
SCODE scode = STATUS_SUCCESS;
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
ULONG cLoops = 0;
|
||
|
|
||
|
while (STATUS_SUCCESS == scode)
|
||
|
{
|
||
|
cLoops++;
|
||
|
|
||
|
// Trim our working set every n docs
|
||
|
|
||
|
if ( 20 == cLoops )
|
||
|
{
|
||
|
SetProcessWorkingSetSize( GetCurrentProcess(), -1, -1 );
|
||
|
cLoops = 0;
|
||
|
}
|
||
|
|
||
|
ULONG cbNeeded = _cbTotal;
|
||
|
_cbHdr = sizeof(ULONG);
|
||
|
|
||
|
Win4Assert( _cbTotal > _cbHdr );
|
||
|
_cbDocBuffer = _cbTotal-_cbHdr;
|
||
|
|
||
|
{
|
||
|
CLock lock( _mutex );
|
||
|
if ( _fStopFilter )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ITRACE, "Quitting filtering\n" ));
|
||
|
return STATUS_REQUEST_ABORTED;
|
||
|
}
|
||
|
else
|
||
|
_fWaitingForDocument = TRUE;
|
||
|
}
|
||
|
|
||
|
scode = _proxy.FilterReady( _docBuffer, cbNeeded,
|
||
|
CI_MAX_DOCS_IN_WORDLIST );
|
||
|
|
||
|
while ( STATUS_SUCCESS == scode && cbNeeded > _cbTotal )
|
||
|
{
|
||
|
// need more memory
|
||
|
CPageManager::FreePage( _docBuffer );
|
||
|
|
||
|
unsigned ccPages = cbNeeded / PAGE_SIZE;
|
||
|
if ( ccPages * PAGE_SIZE < cbNeeded )
|
||
|
{
|
||
|
ccPages++;
|
||
|
}
|
||
|
|
||
|
_docBuffer = (BYTE *)(CPageManager::GetPage( ccPages ));
|
||
|
_cbTotal = cbNeeded = ccPages * PAGE_SIZE;
|
||
|
|
||
|
scode = _proxy.FilterReady( _docBuffer, cbNeeded,
|
||
|
CI_MAX_DOCS_IN_WORDLIST );
|
||
|
}
|
||
|
|
||
|
|
||
|
{
|
||
|
CLock lock( _mutex );
|
||
|
if ( _fStopFilter )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ITRACE, "Quitting filtering\n" ));
|
||
|
return STATUS_REQUEST_ABORTED;
|
||
|
}
|
||
|
else
|
||
|
_fWaitingForDocument = FALSE;
|
||
|
}
|
||
|
|
||
|
if ( NT_SUCCESS( scode ) && (_cbTotal > _cbHdr) )
|
||
|
{
|
||
|
_cbDocBuffer = _cbTotal-_cbHdr;
|
||
|
|
||
|
//
|
||
|
// SLM_HACK
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// If the number of remaining documents (after this
|
||
|
// doc buffer) is less than a threshold value,
|
||
|
// then wait for some time before continuing
|
||
|
//
|
||
|
ULONG cDocsLeft;
|
||
|
RtlCopyMemory( &cDocsLeft, _docBuffer, sizeof(ULONG) );
|
||
|
if ( cDocsLeft < _params.GetFilterRemainingThreshold() )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ITRACE,
|
||
|
"CiFilterDaemon. Number of Docs Left %d < %d. Sleep %d s.\n",
|
||
|
cDocsLeft,
|
||
|
_params.GetFilterRemainingThreshold(),
|
||
|
_params.GetFilterDelayInterval() ));
|
||
|
Sleep(_params.GetFilterDelayInterval()*1000);
|
||
|
}
|
||
|
|
||
|
FilterDocs();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
CATCH (CException, e)
|
||
|
{
|
||
|
scode = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
return scode;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::FilterDataReady, public
|
||
|
//
|
||
|
// Synopsis: Sends a buffer to be added to the current word list
|
||
|
//
|
||
|
// Arguments:
|
||
|
// [pEntryBuf] -- pointer to the entry buffer
|
||
|
// [cb] -- count of bytes in the buffer
|
||
|
//
|
||
|
// History: 31-Mar-93 AmyA Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
SCODE CFilterDaemon::FilterDataReady ( const BYTE * pEntryBuf, ULONG cb )
|
||
|
{
|
||
|
return _proxy.FilterDataReady ( pEntryBuf, cb );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::StopFiltering
|
||
|
//
|
||
|
// History: 12-Sep-93 SitaramR Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID CFilterDaemon::StopFiltering()
|
||
|
{
|
||
|
CLock lock( _mutex );
|
||
|
|
||
|
_fStopFilter = TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::IsWaitingForDocument
|
||
|
//
|
||
|
// Returns: Whether we are waiting for documents to update
|
||
|
//
|
||
|
// History: 12-Sep-93 SitaramR Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL CFilterDaemon::IsWaitingForDocument()
|
||
|
{
|
||
|
CLock lock( _mutex );
|
||
|
|
||
|
return _fWaitingForDocument;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CFilterDocument
|
||
|
//
|
||
|
// Purpose: A class to filter a document by retrying different impersonation
|
||
|
// contexts if necessary.
|
||
|
//
|
||
|
// History: 7-18-96 srikants Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
class CFilterDocument
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
CFilterDocument( CDataRepository & drep,
|
||
|
CFilterDaemon & fDaemon,
|
||
|
CCiFrameworkParams & params,
|
||
|
CI_CLIENT_FILTER_CONFIG_INFO const & configInfo,
|
||
|
STATUS * aStatus,
|
||
|
ULONG iDoc,
|
||
|
CNonStoredProps & NonStoredProps,
|
||
|
ULONG cbBuf )
|
||
|
: _drep(drep),
|
||
|
_fDaemon(fDaemon),
|
||
|
_params(params),
|
||
|
_configInfo(configInfo),
|
||
|
_aStatus(aStatus),
|
||
|
_iDoc(iDoc),
|
||
|
_NonStoredProps( NonStoredProps ),
|
||
|
_cbBuf( cbBuf )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG DoIt();
|
||
|
|
||
|
private:
|
||
|
|
||
|
CDataRepository & _drep;
|
||
|
CFilterDaemon & _fDaemon;
|
||
|
CCiFrameworkParams & _params;
|
||
|
CI_CLIENT_FILTER_CONFIG_INFO const & _configInfo;
|
||
|
STATUS * _aStatus;
|
||
|
ULONG _iDoc;
|
||
|
CNonStoredProps & _NonStoredProps;
|
||
|
ULONG _cbBuf;
|
||
|
};
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDocument::DoIt
|
||
|
//
|
||
|
// Synopsis: Tries to filter the file in the current impersonation context.
|
||
|
//
|
||
|
// Returns: Count of bytes filtered.
|
||
|
//
|
||
|
// History: 7-18-96 srikants Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
ULONG CFilterDocument::DoIt()
|
||
|
{
|
||
|
CFilterDriver filterDriver ( &_drep,
|
||
|
_fDaemon._xAdviseStatus.GetPointer( ),
|
||
|
_fDaemon._xFilterClient.GetPointer( ),
|
||
|
_params,
|
||
|
_configInfo,
|
||
|
_fDaemon._cFilteredBlocks,
|
||
|
_NonStoredProps,
|
||
|
_cbBuf );
|
||
|
|
||
|
if ( _fDaemon._fStopFilter )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ITRACE, "Aborting filtering\n" ));
|
||
|
THROW( CException(STATUS_TOO_LATE) );
|
||
|
}
|
||
|
|
||
|
_aStatus[_iDoc] = filterDriver.FillEntryBuffer( _fDaemon._pbCurrentDocument,
|
||
|
_fDaemon._cbCurrentDocument );
|
||
|
|
||
|
// In case we filtered a monster file, just round down to 4 gig.
|
||
|
|
||
|
if ( 0 != filterDriver.GetFileSize().HighPart )
|
||
|
return 0xffffffff;
|
||
|
|
||
|
return filterDriver.GetFileSize().LowPart;
|
||
|
} //DoIt
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFilterDaemon::FilterDocs, private
|
||
|
//
|
||
|
// Synopsis: Creates a Filter Driver and filters documents in _docBuffer
|
||
|
//
|
||
|
// History: 21-Apr-93 AmyA Created.
|
||
|
// 05-Nov-93 DwightKr Removed PROP_ALL code - we'll determine
|
||
|
// what to filter after opening the object
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CFilterDaemon::FilterDocs()
|
||
|
{
|
||
|
ciAssert ( _docBuffer != 0 );
|
||
|
|
||
|
ciDebugOut (( DEB_ITRACE, "CFilterDaemon::FilterDocs\n" ));
|
||
|
|
||
|
CEntryBufferHandler entryBufHandler ( _cbMax,
|
||
|
_entryBuffer,
|
||
|
*this,
|
||
|
_proxy,
|
||
|
_pidmap );
|
||
|
|
||
|
// STACK: this is a big object.
|
||
|
CIndexKeyRepository krep( entryBufHandler );
|
||
|
|
||
|
CDataRepository drep( krep, 0, FALSE, 0, _pidmap, _LangList );
|
||
|
|
||
|
STATUS aStatus [CI_MAX_DOCS_IN_WORDLIST];
|
||
|
for( unsigned i=0; i<CI_MAX_DOCS_IN_WORDLIST; i++ ) // set array
|
||
|
aStatus[i] = WL_IGNORE;
|
||
|
|
||
|
unsigned iDoc;
|
||
|
|
||
|
CDocBufferIter iter(_docBuffer+_cbHdr, _cbTotal-_cbHdr);
|
||
|
|
||
|
while ( !iter.AtEnd() )
|
||
|
{
|
||
|
|
||
|
_pbCurrentDocument = iter.GetCurrent(iDoc, _cbCurrentDocument);
|
||
|
|
||
|
iter.Next();
|
||
|
|
||
|
Win4Assert (iDoc < CI_MAX_DOCS_IN_WORDLIST );
|
||
|
ciDebugOut((DEB_ITRACE, "\t%2d 0x%X\n",
|
||
|
iDocToFakeWid(iDoc), _pbCurrentDocument ));
|
||
|
drep.PutWorkId ( iDocToFakeWid(iDoc) );
|
||
|
|
||
|
_cFilteredDocuments++;
|
||
|
_cFilteredBlocks = 0;
|
||
|
|
||
|
if ( 0 == _cbCurrentDocument )
|
||
|
{
|
||
|
// This represents a deleted document.
|
||
|
ciDebugOut(( DEB_IWARN, "Null document name 0x%x\n", _pbCurrentDocument ));
|
||
|
aStatus[iDoc] = SUCCESS;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
BOOL fTookException = FALSE;
|
||
|
|
||
|
CFwPerfTime filterTotalCounter( _xAdviseStatus.GetPointer(),
|
||
|
CI_PERF_FILTER_TIME_TOTAL,
|
||
|
1024*1024, 1000*60*60 );
|
||
|
ULONG cbLow = 0;
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
//
|
||
|
// Filter time in Mb / hr
|
||
|
//
|
||
|
filterTotalCounter.TStart();
|
||
|
|
||
|
|
||
|
if ( !_xFilterStatus.IsNull() )
|
||
|
{
|
||
|
SCODE sc = _xFilterStatus->PreFilter( _pbCurrentDocument, _cbCurrentDocument );
|
||
|
|
||
|
if ( FAILED(sc) )
|
||
|
{
|
||
|
ciDebugOut(( DEB_WARN, "Failing filtering because PreFilter returned 0x%x\n", sc ));
|
||
|
THROW( CException( sc ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If necessary impersonate for accessing this file
|
||
|
//
|
||
|
CFilterDocument filterDocument( drep,
|
||
|
*this,
|
||
|
_params,
|
||
|
_configInfo,
|
||
|
aStatus,
|
||
|
iDoc,
|
||
|
_NonStoredProps,
|
||
|
_cbMax );
|
||
|
|
||
|
cbLow = filterDocument.DoIt();
|
||
|
|
||
|
}
|
||
|
CATCH ( CException, e )
|
||
|
{
|
||
|
fTookException = TRUE;
|
||
|
|
||
|
ciDebugOut(( DEB_ITRACE,
|
||
|
"FilterDriver exception 0x%x filtering %d caught in FilterDocs.\n",
|
||
|
e.GetErrorCode(), iDoc ));
|
||
|
|
||
|
if ( !_xFilterStatus.IsNull() )
|
||
|
_xFilterStatus->PostFilter( _pbCurrentDocument,
|
||
|
_cbCurrentDocument,
|
||
|
e.GetErrorCode() );
|
||
|
|
||
|
if ( IsSharingViolation( e.GetErrorCode()) )
|
||
|
{
|
||
|
aStatus[iDoc] = CI_SHARING_VIOLATION;
|
||
|
}
|
||
|
else if ( IsNetDisconnect( e.GetErrorCode()) ||
|
||
|
CI_NOT_REACHABLE == e.GetErrorCode() )
|
||
|
{
|
||
|
aStatus[iDoc] = CI_NOT_REACHABLE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
aStatus[iDoc] = FILTER_EXCEPTION;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Certain errors occuring while filtering are fatal. They
|
||
|
// will cause the filter daemon to terminate.
|
||
|
|
||
|
if ( (e.GetErrorCode() == FDAEMON_E_FATALERROR) ||
|
||
|
(e.GetErrorCode() == STATUS_ACCESS_VIOLATION) ||
|
||
|
(e.GetErrorCode() == STATUS_NO_MEMORY) ||
|
||
|
(e.GetErrorCode() == STATUS_INSUFFICIENT_RESOURCES) ||
|
||
|
(e.GetErrorCode() == STATUS_DATATYPE_MISALIGNMENT) ||
|
||
|
(e.GetErrorCode() == STATUS_INSTRUCTION_MISALIGNMENT)
|
||
|
)
|
||
|
{
|
||
|
RETHROW();
|
||
|
}
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
if ( !_xFilterStatus.IsNull() && !fTookException )
|
||
|
_xFilterStatus->PostFilter( _pbCurrentDocument,
|
||
|
_cbCurrentDocument,
|
||
|
S_OK );
|
||
|
|
||
|
filterTotalCounter.TStop( cbLow );
|
||
|
|
||
|
if ( entryBufHandler.WordListFull() ) // finish current word list
|
||
|
{
|
||
|
//
|
||
|
// Does not throw
|
||
|
//
|
||
|
|
||
|
entryBufHandler.Done();
|
||
|
|
||
|
#if CIDBG == 1
|
||
|
for (unsigned j=0; j<CI_MAX_DOCS_IN_WORDLIST; j++)
|
||
|
{
|
||
|
DebugPrintStatus( aStatus[j] );
|
||
|
}
|
||
|
#endif // CIDBG == 1
|
||
|
|
||
|
//
|
||
|
// If we have filled the buffer, and there are no more documents
|
||
|
// to filter then don't call FilterMore. Exit the loop so that
|
||
|
// FilterDone can be called to finish this docList.
|
||
|
//
|
||
|
if ( iter.AtEnd() )
|
||
|
break;
|
||
|
|
||
|
SCODE scode = _proxy.FilterMore( aStatus, CI_MAX_DOCS_IN_WORDLIST );
|
||
|
if ( FAILED(scode) )
|
||
|
{
|
||
|
ciDebugOut (( DEB_IERROR, "FilterMore returned with error 0x%x\n", scode ));
|
||
|
THROW( CException( scode ) );
|
||
|
}
|
||
|
|
||
|
for( unsigned i = 0; i <= iDoc; i++ ) // reset array
|
||
|
aStatus[i] = WL_IGNORE;
|
||
|
entryBufHandler.Init();
|
||
|
}
|
||
|
} // end of for loop
|
||
|
|
||
|
_pbCurrentDocument = 0;
|
||
|
_cbCurrentDocument = 0;
|
||
|
|
||
|
//
|
||
|
// Does not throw
|
||
|
//
|
||
|
entryBufHandler.Done();
|
||
|
|
||
|
#if CIDBG == 1
|
||
|
for (i = 0; i < CI_MAX_DOCS_IN_WORDLIST; i++)
|
||
|
{
|
||
|
DebugPrintStatus(aStatus[i]);
|
||
|
}
|
||
|
#endif // CIDBG == 1
|
||
|
|
||
|
if ( iter.GetCount() > 0 )
|
||
|
{
|
||
|
SCODE scode = _proxy.FilterDone( aStatus, CI_MAX_DOCS_IN_WORDLIST );
|
||
|
|
||
|
if ( FAILED( scode ) )
|
||
|
{
|
||
|
ciDebugOut (( DEB_IERROR, "FilterDone returned with error 0x%x\n", scode ));
|
||
|
THROW( CException( scode ) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: CNonStoredProps::Add
|
||
|
//
|
||
|
// Synopsis: Adds the property to the list of properties that shouldn't
|
||
|
// be stored.
|
||
|
//
|
||
|
// Arguments: [ps] -- Property ID
|
||
|
//
|
||
|
// History: 9-Feb-97 dlee Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CNonStoredProps::Add( CFullPropSpec const & ps )
|
||
|
{
|
||
|
if ( ( guidStorage == ps.GetPropSet() ) &&
|
||
|
( ps.IsPropertyPropid() ) &&
|
||
|
( ps.GetPropertyPropid() < CSTORAGEPROPERTY ) )
|
||
|
{
|
||
|
Win4Assert( ps.GetPropertyPropid() != PID_STG_SIZE );
|
||
|
|
||
|
_afStgPropNonStored[ ps.GetPropertyPropid() ] = TRUE;
|
||
|
}
|
||
|
else if ( guidHtmlMeta == ps.GetPropSet() )
|
||
|
{
|
||
|
if ( _cMetaSpecs < maxCachedSpecs )
|
||
|
_aMetaSpecs[ _cMetaSpecs++ ] = ps;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( _cSpecs < maxCachedSpecs )
|
||
|
_aSpecs[ _cSpecs++ ] = ps;
|
||
|
}
|
||
|
} //Add
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: CNonStoredProps::IsNonStored
|
||
|
//
|
||
|
// Synopsis: Returns TRUE if the property shouldn't be stored
|
||
|
//
|
||
|
// Arguments: [ps] -- Property ID
|
||
|
//
|
||
|
// History: 9-Feb-97 dlee Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
BOOL CNonStoredProps::IsNonStored( CFullPropSpec const & ps )
|
||
|
{
|
||
|
if ( ( guidStorage == ps.GetPropSet() ) &&
|
||
|
( ps.IsPropertyPropid() ) &&
|
||
|
( ps.GetPropertyPropid() < CSTORAGEPROPERTY ) )
|
||
|
{
|
||
|
return _afStgPropNonStored[ ps.GetPropertyPropid() ];
|
||
|
}
|
||
|
else if ( guidHtmlMeta == ps.GetPropSet() )
|
||
|
{
|
||
|
for ( int x = 0; x < _cMetaSpecs; x++ )
|
||
|
if ( ps == _aMetaSpecs[ x ] )
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for ( int x = 0; x < _cSpecs; x++ )
|
||
|
if ( ps == _aSpecs[ x ] )
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
} //IsNonStored
|
||
|
|
||
|
#if CIDBG == 1
|
||
|
void DebugPrintStatus( STATUS stat )
|
||
|
{
|
||
|
switch(stat)
|
||
|
{
|
||
|
case SUCCESS:
|
||
|
// ciDebugOut((DEB_ITRACE, "Status: SUCCESS\n"));
|
||
|
break;
|
||
|
case PREEMPTED:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: PREEMPTED\n"));
|
||
|
break;
|
||
|
case BIND_FAILED:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: BIND_FAILED\n"));
|
||
|
break;
|
||
|
case CORRUPT_OBJECT:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: CORRUPT_OBJECT\n"));
|
||
|
break;
|
||
|
case MISSING_PROTOCOL:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: MISSING_PROTOCOL\n"));
|
||
|
break;
|
||
|
case CANNOT_OPEN_STREAM:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: CANNOT_OPEN_STREAM\n"));
|
||
|
break;
|
||
|
case DELETED:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: DELETED\n"));
|
||
|
break;
|
||
|
case ENCRYPTED:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: ENCRYPTED\n"));
|
||
|
break;
|
||
|
case FILTER_EXCEPTION:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: FILTER_EXCEPTION\n"));
|
||
|
break;
|
||
|
case OUT_OF_MEMORY:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: OUT_OF_MEMORY\n"));
|
||
|
break;
|
||
|
case PENDING:
|
||
|
ciDebugOut((DEB_ITRACE, "Status: PENDING\n"));
|
||
|
break;
|
||
|
case WL_IGNORE:
|
||
|
// ciDebugOut((DEB_ITRACE, "Status: WL_IGNORE\n"));
|
||
|
break;
|
||
|
case WL_NULL:
|
||
|
// ciDebugOut((DEB_ITRACE, "Status: WL_NULL\n"));
|
||
|
break;
|
||
|
case CI_SHARING_VIOLATION:
|
||
|
ciDebugOut(( DEB_ITRACE, "Status: CI_SHARING_VIOLATION\n" ));
|
||
|
break;
|
||
|
case CI_NOT_REACHABLE:
|
||
|
ciDebugOut(( DEB_ITRACE, "Status: CI_NOT_REACHABLE\n" ));
|
||
|
break;
|
||
|
default:
|
||
|
ciDebugOut((DEB_ITRACE, "This status is incorrect\n"));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif // CIDBG == 1
|