|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: FDRIVER.CXX
//
// Contents: Filter driver
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <ciole.hxx>
#include <drep.hxx>
#include <tfilt.hxx>
#include <tsource.hxx>
#include <fwevent.hxx>
#include <cievtmsg.h>
#include <propspec.hxx>
#include <imprsnat.hxx>
#include <oleprop.hxx>
#include <fdaemon.hxx>
#include <ntopen.hxx>
#include <ciguid.hxx>
#include "fdriver.hxx"
#include "propfilt.hxx"
#include "docsum.hxx"
static GUID guidNull = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
//
// Local procedures
//
BOOL IsNonIndexableProp( CFullPropSpec const & fps, PROPVARIANT const & var );
static CFullPropSpec psRevName( guidQuery, DISPID_QUERY_REVNAME ); static CFullPropSpec psName( guidStorage, PID_STG_NAME ); static CFullPropSpec psPath( guidStorage, PID_STG_PATH); static CFullPropSpec psDirectory( guidStorage, PID_STG_DIRECTORY );
static CFullPropSpec psCharacterization( guidCharacterization, propidCharacterization );
static CFullPropSpec psTitle( guidDocSummary, propidTitle ); static GUID guidHtmlInformation = defGuidHtmlInformation;
static CFullPropSpec psAttrib( guidStorage, PID_STG_ATTRIBUTES );
//
// Helper functions
//
inline BOOL IsSpecialPid( FULLPROPSPEC const & fps ) { return ( fps.psProperty.ulKind == PRSPEC_PROPID && fps.psProperty.propid <= PID_CODEPAGE ); }
//+---------------------------------------------------------------------------
//
// Member: CFilterDriver::CFilterDriver, public
//
// Arguments:
// [drep] -- pointer to the data repository for filtered
// information
// [perfobj] -- performance object to update
// [cFilteredBlocks] -- Number of blocks filtered for the current
// document
// [cat] -- reference to a catalog proxy
//
//----------------------------------------------------------------------------
CFilterDriver::CFilterDriver ( CDataRepository * drep, ICiCAdviseStatus * pAdviseStatus, ICiCFilterClient * pFilterClient, CCiFrameworkParams & params, CI_CLIENT_FILTER_CONFIG_INFO const & configInfo, ULONG & cFilteredBlocks, CNonStoredProps & NonStoredProps, ULONG cbBuf ) : _drep( drep ), _llFileSize( 0 ), _cFilteredBlocks( cFilteredBlocks ), _params( params ), _pAdviseStatus( pAdviseStatus ), _pFilterClient( pFilterClient ), _configInfo( configInfo ), _NonStoredProps( NonStoredProps ), _cbBuf( cbBuf ), _attrib(0), _lcidSystemDefault( GetSystemDefaultLCID() ) { }
//+---------------------------------------------------------------------------
//
// Member: CFilterDriver::FillEntryBuffer, public
//
// Synopsis: Filters the document that IFilter loaded.
//
// Arguments: [pbDocName] -- Document in filter
// [cbDocName] -- Size of [pbDocName]
//
// Notes: Calls to SwitchToThread() give up processor.
//
//----------------------------------------------------------------------------
STATUS CFilterDriver::FillEntryBuffer( BYTE const * pbDocName, ULONG cbDocName ) { _status = CANNOT_OPEN_STREAM;
BOOL fFilterContents = FALSE; // Assume we should NOT filter contents
//
// Get opendoc for access to stored state and safely save it
//
ICiCOpenedDoc *pDocument; SCODE sc = _pFilterClient->GetOpenedDoc( &pDocument ); SwitchToThread();
if ( !SUCCEEDED( sc ) ) { ciDebugOut(( DEB_ERROR, "Unable to get OpenedDoc - %x\n", sc )); return _status; }
XInterface<ICiCOpenedDoc> Document( pDocument );
//
// Attempt to open the document
//
sc = Document->Open( pbDocName, cbDocName ); SwitchToThread();
if (!SUCCEEDED( sc )) { if ( ::IsSharingViolation( sc ) ) { _status = CI_SHARING_VIOLATION; } else { ciDebugOut(( DEB_IWARN, "Unable to open docname at 0x%X - 0x%X\n", pbDocName, sc ));
if ( FILTER_E_UNREACHABLE == sc ) _status = CI_NOT_REACHABLE;
return _status; } }
// Initialize LCIDs counter.
_cLCIDs = 0;
//
// Attempt to filter properties
//
CDocCharacterization docChar( _params.GenerateCharacterization() ? _params.GetMaxCharacterization() : 0 );
//
// Get the stat property enumerator and filter based on it.
//
CDocStatPropertyEnum CPEProp( Document.GetPointer() ); SwitchToThread();
fFilterContents = CPEProp.GetFilterContents( _params.FilterDirectories() ); _llFileSize = CPEProp.GetFileSize( );
FilterObject( CPEProp, *_drep, docChar ); SwitchToThread();
//
// filter security on the file.
//
if ( _configInfo.fSupportsSecurity ) { FilterSecurity( Document.GetPointer( ), *_drep ); SwitchToThread(); }
if ( CI_SHARING_VIOLATION == _status ) return _status;
_status = SUCCESS;
BOOL fFilterOleProperties = fFilterContents; BOOL fKnownFilter = TRUE; BOOL fIndexable = TRUE;
WCHAR const * pwcPath = (WCHAR const *) pbDocName;
#if 0
// c:\foo
// \\?\c:\foo
BOOL fRemote = ( ( L':' != pwcPath[1] ) && ( L':' != pwcPath[5] ) );
if ( fFilterContents && ( fRemote || ( 0 == ( FILE_ATTRIBUTE_ENCRYPTED & _attrib )) ) ) #else
if ( fFilterContents && ( 0 == ( FILE_ATTRIBUTE_ENCRYPTED & _attrib )) )
#endif
{ //
// Filter time in Mb / hr
//
CFwPerfTime filterCounter( _pAdviseStatus, CI_PERF_FILTER_TIME, 1024*1024, 1000*60*60 ); filterCounter.TStart();
CFwPerfTime bindCounter( _pAdviseStatus, CI_PERF_BIND_TIME ); bindCounter.TStart();
IFilter *pTmpIFilter; sc = Document->GetIFilter( &pTmpIFilter ); SwitchToThread();
if ( !SUCCEEDED( sc ) ) pTmpIFilter = 0;
_pIFilter.Set( pTmpIFilter );
bindCounter.TStop( );
if ( _pIFilter.IsNull( )) { //
// We could not obtain an IFilter but we have filtered properties.
// We should just return whatever status we have.
//
ciDebugOut(( DEB_IWARN, "Did not get a filter for document 0x%X\n", pbDocName ));
if ( ::IsSharingViolation( sc )) _status = CI_SHARING_VIOLATION; else if ( FILTER_E_UNREACHABLE == sc ) _status = CI_NOT_REACHABLE;
if ( fFilterOleProperties ) { //
// No filter, but it might have properties. Get them.
//
COLEPropertyEnum oleProp( Document.GetPointer( ) ); SwitchToThread(); BOOL fIsStorage = oleProp.IsStorage(); if (fIsStorage) FilterObject( oleProp, *_drep, docChar ); SwitchToThread(); } return _status; }
ULONG ulFlags; STAT_CHUNK statChunk; sc = _pIFilter->Init( IFILTER_INIT_CANON_PARAGRAPHS | IFILTER_INIT_CANON_HYPHENS | IFILTER_INIT_CANON_SPACES | IFILTER_INIT_APPLY_INDEX_ATTRIBUTES | IFILTER_INIT_INDEXING_ONLY, 0, 0, &ulFlags ); SwitchToThread(); if ( FAILED(sc) ) { ciDebugOut(( DEB_WARN, "IFilter->Init() failed.\n" )); THROW( CException( sc ) ); }
fFilterOleProperties = (( ulFlags & IFILTER_FLAGS_OLE_PROPERTIES ) != 0);
//
// Determine the maximum number of filtered blocks allowed for this
// file.
//
unsigned __int64 ullMultiplier = _params.GetMaxFilesizeMultiplier(); unsigned __int64 ullcbBuf = _cbBuf; unsigned __int64 ullcbFile = _llFileSize; unsigned __int64 ullcBlocks = 1 + ( ullcbFile / ullcbBuf ); unsigned __int64 ullmaxBlocks = ullcBlocks * ullMultiplier;
if ( ullmaxBlocks > ULONG_MAX ) ullmaxBlocks = ULONG_MAX;
ULONG ulMaxFilteredBlocks = (ULONG) ullmaxBlocks;
ciDebugOut(( DEB_ITRACE, "cbfile %I64d, cBlocks %I64d, maxcBlocks %I64d\n", ullcbFile, ullcBlocks, ullmaxBlocks ));
//
// Get the first chunk
//
do { sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread(); if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); } while ( SUCCEEDED(sc) && IsSpecialPid( statChunk.attribute ) );
_drep->InitFilteredBlockCount( ulMaxFilteredBlocks ); _cFilteredBlocks = 0;
NTSTATUS Status = STATUS_SUCCESS;
TRY { BOOL fBadEmbeddingReport = FALSE;
while ( SUCCEEDED(sc) || FILTER_E_LINK_UNAVAILABLE == sc || FILTER_E_EMBEDDING_UNAVAILABLE == sc ) { BOOL fInUse; Document->IsInUseByAnotherProcess( &fInUse ); SwitchToThread(); if ( fInUse ) { _status = FILTER_EXCEPTION; // Force retry in driver
break; // Stop filtering this doc
}
_cFilteredBlocks = _drep->GetFilteredBlockCount();
if ( SUCCEEDED(sc) ) { if ( IsSpecialPid( statChunk.attribute ) ) { sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread();
if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); continue; }
//
// Skip over unknown chunks.
//
if ( 0 == (statChunk.flags & (CHUNK_TEXT | CHUNK_VALUE)) ) { ciDebugOut(( DEB_WARN, "Filtering of docname at 0x%X produced bogus chunk (not text or value)\n", pbDocName )); sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread();
if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); continue; }
if ( statChunk.flags & CHUNK_VALUE ) { PROPVARIANT * pvar = 0;
sc = _pIFilter->GetValue( &pvar );
if ( SUCCEEDED(sc) ) { XPtr<CStorageVariant> xvar( (CStorageVariant *)(ULONG_PTR)pvar ); CFullPropSpec * pps = (CFullPropSpec *)(ULONG_PTR)(&statChunk.attribute);
//
// HACK #275: If we see a ROBOTS=NOINDEX tag, then bail out.
//
if ( IsNonIndexableProp( *pps, *pvar ) ) { ciDebugOut(( DEB_WARN, "Document %x is not indexable (robots Meta-tag)\n", pbDocName ));
sc = S_OK; fFilterOleProperties = FALSE; fIndexable = FALSE;
break; }
// Index this property twice -- once with default locale and with
// the chunk locale.
FilterProperty( *pvar, *pps, *_drep, docChar, statChunk.locale ); SwitchToThread();
if (_lcidSystemDefault != statChunk.locale) { FilterProperty( *pvar, *pps, *_drep, docChar, _lcidSystemDefault ); SwitchToThread(); }
//
// Only fetch next if we're done with this chunk.
//
if ( 0 == (statChunk.flags & CHUNK_TEXT) || !SUCCEEDED(sc) ) { sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread();
if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); continue; } } }
if ( (statChunk.flags & CHUNK_TEXT) && SUCCEEDED(sc) ) { if ( _drep->PutLanguage( statChunk.locale ) && _drep->PutPropName( *((CFullPropSpec *)&statChunk.attribute) ) ) { CTextSource tsource( _pIFilter.GetPointer( ), statChunk );
docChar.Add( tsource.awcBuffer + tsource.iCur, tsource.iEnd - tsource.iCur, statChunk.attribute ); SwitchToThread();
_drep->PutStream( &tsource ); SwitchToThread(); sc = tsource.GetStatus(); } else { sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread();
if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); }
if ( sc == FILTER_E_NO_TEXT && (statChunk.flags & CHUNK_VALUE) ) sc = S_OK; }
}
if ( FILTER_E_EMBEDDING_UNAVAILABLE == sc ) { if ( !fBadEmbeddingReport && (_params.GetEventLogFlags()&CI_EVTLOG_FLAGS_FAILED_EMBEDDING) ) { ReportFilterEmbeddingFailure( pbDocName, cbDocName ); fBadEmbeddingReport = TRUE; }
sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread();
if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); } else if ( FILTER_E_LINK_UNAVAILABLE == sc ) { sc = _pIFilter->GetChunk( &statChunk ); SwitchToThread();
if (SUCCEEDED(sc)) RegisterLocale(statChunk.locale); } } } CATCH ( CException, e ) { Status = e.GetErrorCode(); ciDebugOut(( DEB_IERROR, "Exception 0x%x thrown from filter DLL while filtering docName at 0x%X\n", Status, pbDocName )); } END_CATCH
if ( !NT_SUCCESS(Status) && Status != FDAEMON_E_TOOMANYFILTEREDBLOCKS ) { ciDebugOut(( DEB_FORCE, "error %#x, converting to FDAEMON_E_FATALERROR and exiting process\n", Status )); THROW( CException(FDAEMON_E_FATALERROR) ); }
if ( Status == FDAEMON_E_TOOMANYFILTEREDBLOCKS ) { Win4Assert( _drep->GetFilteredBlockCount() > ulMaxFilteredBlocks );
LogOverflow( pbDocName, cbDocName );
//
// Force exit from the loop
//
sc = FILTER_E_END_OF_CHUNKS; }
_pIFilter.Free( );
filterCounter.TStop( (ULONG)_llFileSize ); }
if ( FILTER_E_END_OF_CHUNKS != sc && FILTER_E_PARTIALLY_FILTERED != sc && FAILED( sc ) ) { ciDebugOut(( DEB_IWARN, "Filter document at 0x(%X) returned SCODE 0x%x\n", pbDocName, sc )); QUIETTHROW( CException( sc ) ); }
BOOL fIsStorage = FALSE;
if ( fFilterOleProperties ) { //
// filter ole properties only if it is a docfile
//
COLEPropertyEnum oleProp( Document.GetPointer( ) ); SwitchToThread(); fIsStorage = oleProp.IsStorage(); if (fIsStorage) FilterObject( oleProp, *_drep, docChar ); SwitchToThread(); }
//
// Store the document characterization in the property cache.
// Don't bother if characterization is turned off.
//
if ( _params.GenerateCharacterization() ) { PROPVARIANT var; WCHAR awcSummary[ CI_MAX_CHARACTERIZATION_MAX + 1 ];
if ( fIndexable && docChar.HasCharacterization() ) { unsigned cwcSummary = sizeof awcSummary / sizeof WCHAR;
// Use the raw text in the abstract unless we defaulted
// to the text filter and the file has ole properties.
BOOL fUseRawText = fKnownFilter || !fIsStorage;
docChar.Get( awcSummary, cwcSummary, fUseRawText ); SwitchToThread();
if ( 0 == cwcSummary ) { var.vt = VT_EMPTY; } else { var.vt = VT_LPWSTR; var.pwszVal = awcSummary; } } else { var.vt = VT_EMPTY; }
_drep->StoreValue( psCharacterization, var ); SwitchToThread(); }
return _status; }
//+---------------------------------------------------------------------------
//
// Member: CFilterDriver::LogOverflow
//
// Synopsis: Notifies the client that there were too many blocks in the
// given document
//
// Arguments: [pbDocName] - Document Name
// [cbDocName] - Number of bytes in the document name.
//
// History: 1-22-97 srikants Created
//
//----------------------------------------------------------------------------
void CFilterDriver::LogOverflow( BYTE const * pbDocName, ULONG cbDocName ) {
PROPVARIANT var[2];
var[0].vt = VT_VECTOR | VT_UI1; var[0].caub.cElems = cbDocName; var[0].caub.pElems = (BYTE *) pbDocName;
var[1].vt = VT_UI4; var[1].ulVal = _params.GetMaxFilesizeMultiplier();
SCODE sc = _pAdviseStatus->NotifyStatus( CI_NOTIFY_FILTER_TOO_MANY_BLOCKS, 2, var );
if ( !SUCCEEDED(sc) ) { ciDebugOut(( DEB_WARN, "Failed to report filter to many blocks event. Error 0x%X\n", sc )); } }
//+---------------------------------------------------------------------------
//
// Member: CFilterDriver::ReportFilterEmbeddingFailure
//
// Synopsis: Notifies the client that there was a failure filtering an
// embedding.
//
// Arguments: [pbDocName] - Document name
// [cbDocName] - Number of bytes in the serialized document name
//
// History: 1-22-97 srikants Created
//
//----------------------------------------------------------------------------
void CFilterDriver::ReportFilterEmbeddingFailure( BYTE const * pbDocName, ULONG cbDocName ) { PROPVARIANT var; var.vt = VT_VECTOR | VT_UI1; var.caub.cElems = cbDocName; var.caub.pElems = (BYTE *) pbDocName;
SCODE sc = _pAdviseStatus->NotifyStatus( CI_NOTIFY_FILTER_EMBEDDING_FAILURE, 1, &var );
if ( !SUCCEEDED(sc) ) { ciDebugOut(( DEB_WARN, "Failed to report filter embedding failure event. Error 0x%X\n", sc )); } }
//+---------------------------------------------------------------------------
//
// Method: CFilterDriver::FilterProperty
//
// Arguments: [var] -- Property value
// [ps] -- Property ID
// [drep] -- Data repository for filtered information
// [docChar] -- Characterization
//
// Notes: Calls to SwitchToThread() give up processor.
//
//----------------------------------------------------------------------------
inline void CFilterDriver::FilterProperty( CStorageVariant const & var, CFullPropSpec & ps, CDataRepository & drep, CDocCharacterization & docChar, LCID locale ) { //
// Filter one very special property: Backwards name
//
if (ps == psName && var.Type( ) == VT_LPWSTR) { const WCHAR *pwszPath = var.GetLPWSTR( );
int j = wcslen( pwszPath ); XGrowable<WCHAR> xwcsRevName( j + 1 ); int i;
for ( i = 0; i < j; i++ ) { xwcsRevName[i] = pwszPath[j - 1 - i]; }
xwcsRevName[i] = L'\0';
PROPVARIANT Variant; Variant.vt = VT_LPWSTR; Variant.pwszVal = xwcsRevName.Get();
//
// Cast to avoid turning the PROPVARIANT into a CStorageVariant for no good
// reason. Convert involves alloc/free.
//
CStorageVariant const * pvar = (CStorageVariant const *)(ULONG_PTR)(&Variant); FilterProperty( *pvar, psRevName, drep, docChar, 0 ); SwitchToThread();
}
//
// Don't filter paths
//
if ( ps != psPath ) { Win4Assert( psDirectory != ps );
vqDebugOut(( DEB_FILTER, "Filter property 0x%x\n", ps.GetPropertyPropid() ));
//
// Save some property values for use in document characterization
//
docChar.Add( var, ps ); SwitchToThread();
//
// output the property to the data repository
//
drep.PutLanguage( locale ); drep.PutPropName( ps ); drep.PutValue( var ); SwitchToThread();
// Store the value in the property cache if it should be stored there
if ( !_NonStoredProps.IsNonStored( ps ) ) { BOOL fStoredInCache;
if ( IsNullPointerVariant( (PROPVARIANT *) & var ) ) { PROPVARIANT propVar; propVar.vt = VT_EMPTY; fStoredInCache = drep.StoreValue( ps, propVar ); SwitchToThread(); } else { fStoredInCache = drep.StoreValue( ps, var ); SwitchToThread(); }
// should we ignore this property in the future?
if ( !fStoredInCache ) _NonStoredProps.Add( ps ); } }
if ( ps == psAttrib ) _attrib = var.GetUI4(); } //FilterProperty
//+---------------------------------------------------------------------------
//
// Method: CFilterDriver::FilterObject
//
// Arguments: [propEnum] -- iterator for properties in a file
// [drep] -- pointer to the data repository for filtered
// information
// [docChar] -- some property values are written here so that
// document characterization can happen
//
// Notes: Calls to SwitchToThread() give up processor.
//
//----------------------------------------------------------------------------
void CFilterDriver::FilterObject( CPropertyEnum & propEnum, CDataRepository & drep, CDocCharacterization & docChar ) { #if CIDBG == 1
ULONG ulStartTime = GetTickCount(); #endif
CFullPropSpec ps;
// Get the locale for the property set. Use that if available, else use all the
// known locales to maximize the chances of retrieving a property.
LCID locale;
BOOL fUseKnownLocale = SUCCEEDED( propEnum.GetPropertySetLocale(locale));
for ( CStorageVariant const * pvar = propEnum.Next( ps ); pvar != 0; pvar = propEnum.Next( ps ) ) { //
// Filter each of the properties and property sets until we run
// out of them. Register each property for each of the registered locales.
//
FilterProperty( *pvar, ps, drep, docChar, _lcidSystemDefault ); SwitchToThread();
if (fUseKnownLocale) { ciDebugOut((DEB_FILTER, "Propset locale is 0x%x\n", locale));
if (locale != _lcidSystemDefault) { FilterProperty( *pvar, ps, drep, docChar, locale ); SwitchToThread(); } } else { // We want to index this property with all the known locales only if it
// is a "string" type. For non-string types, locale doesn't matter
VARTYPE vt = pvar->Type() | VT_VECTOR; // enables check with or without vt_vector bit
if (vt == (VT_VECTOR | VT_LPWSTR) || vt == (VT_VECTOR | VT_BSTR) || vt == (VT_VECTOR | VT_LPSTR) ) { int iMin = min(_cLCIDs, cLCIDMax); for (int i = 0; i < iMin; i++) { ciDebugOut(( DEB_ITRACE, "Filtering property 0x%x with locale 0x%x\n", pvar, _alcidSeen[i] )); if (_alcidSeen[i] != _lcidSystemDefault) { FilterProperty( *pvar, ps, drep, docChar, _alcidSeen[i] ); SwitchToThread(); } } } } }
#if CIDBG == 1
ULONG ulEndTime = GetTickCount(); ciDebugOut (( DEB_USER1, "Filtering properties took %d ms\n", ulEndTime-ulStartTime )); #endif
}
//+-------------------------------------------------------------------------
//
// Member: CFilterDriver::FilterSecurity, private
//
// Synopsis: Store the security descriptor and map to an SDID
//
// Arguments: [wcsFileName] - file name (used only for error reporting)
// [oplock] - oplock held on the file
// [drep] - data repository
//
// Notes: using ACCESS_SYSTEM_SECURITY AccessMode will cause an
// oplock break, so we should call FilterSecurity before
// taking the oplock.
//
// Notes: Calls to SwitchToThread() give up processor.
//
//--------------------------------------------------------------------------
void CFilterDriver::FilterSecurity( ICiCOpenedDoc *Document, CDataRepository & drep ) { BOOL fCouldStore = FALSE; SCODE sc;
//
// Initial guess about security descriptor size
//
const cInitSD = 512; BYTE abBuffer[cInitSD];
ULONG cbSD = cInitSD; BYTE * pbBuffer = abBuffer;
XPtr<SECURITY_DESCRIPTOR> xSD;
while (TRUE) {
//
// Attempt to get the security descriptor into the buffer
//
sc = Document->GetSecurity( pbBuffer, &cbSD ); SwitchToThread();
//
// If we don't need to resize, then exit while
//
if (SUCCEEDED( sc ) || CI_E_BUFFERTOOSMALL != sc) { break; }
//
// Allocate a bigger buffer and retrieve the security information into
// it.
//
xSD.Free(); xSD.Set( (SECURITY_DESCRIPTOR *) new BYTE [cbSD] ); pbBuffer = (BYTE *) xSD.GetPointer(); }
if ( !SUCCEEDED( sc ) || 0 == cbSD ) { //
// Store NULL security descriptor for the file
//
fCouldStore = drep.StoreSecurity( 0, 0 ); SwitchToThread(); } else { // Now store away the security descriptor and map to an SDID
fCouldStore = drep.StoreSecurity( pbBuffer, cbSD ); SwitchToThread(); }
if (! fCouldStore) { ciDebugOut(( DEB_ERROR, "Failed to store security info\n" )); } }
//+---------------------------------------------------------------------------
//
// Function: CFilterDriver::RegisterLocale, private
//
// Synopsis: Registers a locale
//
// Arguments: [locale] - the locale
//
// Returns: none
//
// History: 27-Jan-99 KrishnaN Created
//
//----------------------------------------------------------------------------
void CFilterDriver::RegisterLocale(LCID locale) { // Ensure that the locale wasn't already registered
int iMin = min(_cLCIDs, cLCIDMax); for (int i = 0; i < iMin; i++) { if (locale == _alcidSeen[i]) return; }
_alcidSeen[_cLCIDs % cLCIDMax] = locale; ciDebugOut(( DEB_ITRACE, "Registered %d locale 0x%x\n", _cLCIDs+1, locale)); _cLCIDs++; }
//+---------------------------------------------------------------------------
//
// Function: IsNonIndexableProp, private
//
// Synopsis: Looks for ROBOTS=NOINDEX tag
//
// Arguments: [fps] -- Property
// [var] -- Value
//
// Returns: TRUE if property [fps] == ROBOTS and value [var] == NOINDEX
//
// History: 7-Oct-97 KyleP Stole from Site Server
//
// Notes: I based my changes to this code in information found at:
// http://info.webcrawler.com/mak/projects/robots/meta-user.html
//
//----------------------------------------------------------------------------
BOOL IsNonIndexableProp( CFullPropSpec const & fps, PROPVARIANT const & var ) { static GUID guidHTMLMeta = HTMLMetaGuid;
BOOL fIsNonIndexable = FALSE;
if ( fps.IsPropertyName() && fps.GetPropSet() == guidHTMLMeta && _wcsicmp( fps.GetPropertyName(), L"ROBOTS" ) == 0 && (var.vt == VT_LPWSTR || var.vt == VT_BSTR) && 0 != var.pwszVal ) { //
// Convert to lowercase to do wcsstr search.
//
unsigned cc = wcslen( var.pwszVal ) + 1;
XGrowable<WCHAR> xwcsTemp( cc );
RtlCopyMemory( xwcsTemp.Get(), var.pwszVal, cc * sizeof(WCHAR) );
_wcslwr( xwcsTemp.Get() );
//
// Check "noindex"
//
fIsNonIndexable = wcsstr( xwcsTemp.Get(), L"noindex") != 0;
//
// Check "all"
//
if ( !fIsNonIndexable ) fIsNonIndexable = wcsstr( xwcsTemp.Get(), L"none") != 0; }
return fIsNonIndexable; }
|