Leaked source code of windows server 2003
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.
 
 
 
 
 
 

542 lines
17 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996.
//
// File: filtpars.cxx
//
// Contents: Definitions of the CFiltParse methods
//
// Classes:
//
// Functions: CFiltParse, ~CFiltParse, Init, GetNextConfig,
// ParseFlags, GetAttributes
//
// Coupling:
//
// Notes:
//
// History: 9-21-1996 ericne Created
//
//----------------------------------------------------------------------------
#include "pch.cxx"
#include <ctype.h>
#include "utility.hxx"
#include "mydebug.hxx"
#include "filtpars.hxx"
//+---------------------------------------------------------------------------
//
// Member: CFiltParse::CFiltParse
//
// Synopsis: Constructor. Default initialization
//
// Arguments: (none)
//
// Returns:
//
// History: 9-21-1996 ericne Created
//
// Notes:
//
//----------------------------------------------------------------------------
CFiltParse::CFiltParse( )
: m_pNextListNode( NULL )
{
// Zero all the fields of m_FirstListNode (this makes the "next" field 0)
memset( (void*) &m_FirstListNode, (int)0, sizeof( ListNode ) );
} //CFiltParse::CFiltParse
//+---------------------------------------------------------------------------
//
// Member: CFiltParse::~CFiltParse
//
// Synopsis: Destructor. Cleans up the heap
//
// Arguments: (none)
//
// Returns:
//
// History: 9-21-1996 ericne Created
//
// Notes:
//
//----------------------------------------------------------------------------
CFiltParse::~CFiltParse( )
{
ListNode *pCurrentNode = m_FirstListNode.next;
ListNode *pTempNode = NULL;
ULONG ul = 0;
while( NULL != pCurrentNode )
{
pTempNode = pCurrentNode;
pCurrentNode = pCurrentNode->next;
// If there are any attributes, delete any lpwstr's
for( ul=0; ul < pTempNode->Configuration.ulActNbrAttributes; ul++ )
{
if( PRSPEC_LPWSTR ==
pTempNode->Configuration.aAttributes[ ul ].psProperty.ulKind )
{
delete [] pTempNode->Configuration.aAttributes[ ul ].
psProperty.lpwstr;
}
}
if( pTempNode->Configuration.aAttributes )
delete [] pTempNode->Configuration.aAttributes;
delete pTempNode->Configuration.pdwFlags;
delete [] pTempNode->Configuration.szSectionName;
delete pTempNode;
}
} //CFiltParse::~CFiltParse
//+---------------------------------------------------------------------------
//
// Member: CFiltParse::Init
//
// Synopsis: Parses the contents of the .ini file
//
// Arguments: [pcFileName] -- name of data file
//
// Returns: TRUE if file was parsed successfully, FALSE otherwise
//
// History: 9-22-1996 ericne Created
//
// Notes: The full path to the *.ini file must be specified
//
//----------------------------------------------------------------------------
BOOL CFiltParse::Init( LPCTSTR szFileName )
{
int iFlags = 0;
int iSectionIndex = 0;
TCHAR szFlags[ MAX_LINE_SIZE ];
TCHAR szSectionNames[ MAX_SECTION_NAMES_SIZE ];
UINT uiAttributeCount = 0;
DWORD dwNbrChars = 0;
DWORD dwFileAttributes = 0;
ULONG ulNbrAttributes = 0;
ListNode *pNewNode = NULL;
ListNode *pLastListNode = &m_FirstListNode;
FULLPROPSPEC *pAttributes = NULL;
// Check to see if the ini file exists:
dwFileAttributes = GetFileAttributes( szFileName );
// If the file doesn't exist, create a default configuration
if( 0xFFFFFFFF == dwFileAttributes )
{
_tprintf( _T("WARNING: Initialization file %s not found. Using a")
_T(" default configuration.\r\n"), szFileName );
pNewNode = new ListNode;
pNewNode->Configuration.grfFlags = IFILTER_INIT_APPLY_INDEX_ATTRIBUTES;
pNewNode->Configuration.cAttributes = 0;
pNewNode->Configuration.aAttributes = NULL;
pNewNode->Configuration.pdwFlags = new DWORD(0);
pNewNode->Configuration.ulActNbrAttributes = 0;
pNewNode->Configuration.szSectionName =
new TCHAR[ _tcslen( szDefaultSectionName ) + 1 ];
_tcscpy( pNewNode->Configuration.szSectionName, szDefaultSectionName );
pNewNode->next = NULL;
m_pNextListNode = m_FirstListNode.next = pNewNode;
return( TRUE );
}
// Get the Section names from the *.ini file
dwNbrChars = GetPrivateProfileString( NULL,
NULL,
_T(""),
szSectionNames,
MAX_SECTION_NAMES_SIZE,
szFileName );
// Make sure we got some section names
if( 0 == dwNbrChars )
{
_tprintf( _T("Parsing error: no sections found in %s\r\n"),
szFileName );
return( FALSE );
}
// Make sure we didn't fill the buffer
if( MAX_SECTION_NAMES_SIZE - 2 == dwNbrChars )
{
_tprintf( _T("Parsing error: too many section names were found in ")
_T("%s\r\n"), szFileName );
return( FALSE );
}
while( szSectionNames[ iSectionIndex ] )
{
dwNbrChars =
GetPrivateProfileString( &szSectionNames[ iSectionIndex ],
_T("Flags"),
_T(""),
szFlags,
MAX_LINE_SIZE,
szFileName );
// Parse the flags
if( ! ParseFlags( szFlags, &iFlags ) )
return( FALSE );
// Get the number of attributes
uiAttributeCount =
GetPrivateProfileInt( &szSectionNames[ iSectionIndex ],
_T("cAttributes"),
0,
szFileName );
// Get the attributes listed in this section
if( ! GetAttributes( &szSectionNames[ iSectionIndex ],
szFileName,
pAttributes,
ulNbrAttributes ) )
{
return( FALSE );
}
// Create a new ListNode
pNewNode = new ListNode;
// Fill in the Configuration information
pNewNode->Configuration.grfFlags = iFlags;
pNewNode->Configuration.cAttributes = uiAttributeCount;
pNewNode->Configuration.aAttributes = pAttributes;
pNewNode->Configuration.ulActNbrAttributes = ulNbrAttributes;
// Create a new dword for the pdwFlags
pNewNode->Configuration.pdwFlags = new DWORD( 0 );
// Save the secion name in the CONFIG structure
pNewNode->Configuration.szSectionName =
new TCHAR[ _tcslen( &szSectionNames[ iSectionIndex ] ) + 1 ];
_tcscpy( pNewNode->Configuration.szSectionName,
&szSectionNames[ iSectionIndex ] );
// Put the node at the end of the list
pLastListNode->next = pNewNode;
pLastListNode = pNewNode;
pNewNode->next = NULL;
// Increment the section index past the current section name
while( szSectionNames[ iSectionIndex++ ] )
{
( (void)0 ); // No work needs to be done here
}
}
// Initialize the next node pointer
m_pNextListNode = m_FirstListNode.next;
// Successfully parsed the file:
return( TRUE );
} //CFiltParse::Init
//+---------------------------------------------------------------------------
//
// Member: CFiltParse::GetNextConfig
//
// Synopsis: extracts the next configuration from the list
//
// Arguments: [pConfiguration] -- pointer to the configuration structure
//
// Returns: TRUE if successful, FALSE if there are no more configurations
//
// History: 9-22-1996 ericne Created
//
// Notes: This function performs a bit-wise copy of the config structure
// which contains pointers. This is intentional. All pointers
// to dynamically allocated memory are stored in the linked list
// and are cleaned up in the destructor. The client is not
// responsible for deleting the memory, and shouldn't.
//
//----------------------------------------------------------------------------
BOOL CFiltParse::GetNextConfig( CONFIG *pConfiguration )
{
// If we are at the end of the list, return.
if( NULL == m_pNextListNode )
return( FALSE );
// Bit-wise copy the CONFIG structure, pointers included.
memcpy( (void*) pConfiguration,
(void*) &(m_pNextListNode->Configuration),
sizeof( CONFIG ) );
// Advance the current node pointer
m_pNextListNode = m_pNextListNode->next;
return( TRUE );
} //CFiltParse::GetNextConfig
//+---------------------------------------------------------------------------
//
// Member: CFiltParse::ParseFlags
//
// Synopsis: Makes extensive use of streams to extract individual tokens
// from a single line of the data file. The tokens should
// correspont to IFilter Init flags. Their values are bit-wise
// ORed together and stored in m_Flags
//
// Arguments: (none)
//
// Returns: TRUE if successful
// FALSE if an error occurs
//
// History: 9-22-1996 ericne Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CFiltParse::ParseFlags( LPTSTR szFlags, int * piFlags )
{
BOOL fIsLegalToken = FALSE;
LPCTSTR szTokenBuffer = _tcstok( szFlags, _T(" \t") );
// initialize *piFlags
*piFlags = 0;
// While there are more tokens in szFlags:
while( NULL != szTokenBuffer )
{
// Assume the token is not legal
fIsLegalToken = FALSE;
// Try to find a match for this token
for( int iCount = 0; iCount < 8; iCount++ )
{
if( 0 == _tcsicmp( szTokenBuffer, strInitFlags[ iCount ] ) )
{
// Bitwise-or of *piFlags with 1 left-shifted by iCount
*piFlags |= ( 1 << iCount );
fIsLegalToken = TRUE;
break;
}
}
// If no match was found
if( ! fIsLegalToken )
{
_tprintf( _T("Parsing error: Illegal Init flag: %s\r\n"),
szTokenBuffer );
return( FALSE );
}
// Get the next token
szTokenBuffer = _tcstok( NULL, _T(" \t") );
}
return( TRUE );
} //CFiltParse::GetFlags
//+---------------------------------------------------------------------------
//
// Member: CFiltParse::GetAttributes
//
// Synopsis: Gets the correct number of attributes from the data file
//
// Arguments: (none)
//
// Returns: TRUE if successful,
// FALSE if an error occurs or the end of file is reached
//
// History: 9-22-1996 ericne Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CFiltParse::GetAttributes( const TCHAR *szSectionName,
const TCHAR *szFileName,
FULLPROPSPEC *&pFullPropspec,
ULONG &ulNbrAttributes )
{
TCHAR szAttributeString[ MAX_LINE_SIZE ];
LPTSTR szGuidBuffer = NULL;
LPTSTR szPropspecBuffer = NULL;
LPTSTR szTestBuffer = NULL;
TCHAR szKeyNames[ MAX_KEY_NAMES_SIZE ];
UINT uiKeyIndex = 0;
UINT uiAttributeIndex = 0;
BOOL fSuccessful = FALSE;
DWORD dwNbrChars = 0;
// Initialize m_Attributes field
pFullPropspec = NULL;
ulNbrAttributes = 0;
// Enumerate all the Key names in this section:
dwNbrChars = GetPrivateProfileString( szSectionName,
NULL,
_T(""),
szKeyNames,
MAX_KEY_NAMES_SIZE,
szFileName );
// Make sure we had enough room:
if( MAX_KEY_NAMES_SIZE - 2 == dwNbrChars )
{
_tprintf( _T("Parse error: too many keys found in section %s ")
_T("in file %s\r\n"), szSectionName, szFileName );
return( FALSE );
}
// Find out how many attributes are specified:
while( szKeyNames[ uiKeyIndex ] )
{
if( &szKeyNames[ uiKeyIndex ] ==
_tcsstr( &szKeyNames[ uiKeyIndex ], _T("aAttributes") ) )
{
++ulNbrAttributes;
}
while( szKeyNames[ uiKeyIndex++ ] )
{
( (void)0 );
}
}
// If no attributes are specified, return TRUE (we're done)
if( 0 == ulNbrAttributes )
return( TRUE );
// Allocate the correct number of attributes
pFullPropspec = new FULLPROPSPEC[ ulNbrAttributes ];
// Reset the Key index
uiKeyIndex = 0;
// try-finally block simplifies clean-up
__try
{
// Loop over all the key names:
// The (dis)advantage of this approach is that it allows a user to
// specify a number of attributes in cAttributes, but then allocate a
// different number of attributes, to see how the filter handles this
while( szKeyNames[ uiKeyIndex ] )
{
// Assert that I don't overwrite the Attribute array
// (Debug version only)
_ASSERT( uiAttributeIndex < ulNbrAttributes );
// If this key is not specifying an attribute, continue
if( &szKeyNames[ uiKeyIndex ] !=
_tcsstr( &szKeyNames[ uiKeyIndex ], _T("aAttributes") ) )
{
while( szKeyNames[ uiKeyIndex++ ] )
{
( (void)0 );
}
continue;
}
// Get the attribute string
dwNbrChars = GetPrivateProfileString( szSectionName,
&szKeyNames[ uiKeyIndex ],
_T(""),
szAttributeString,
MAX_LINE_SIZE,
szFileName );
// Pull out the guid token:
if( NULL ==
( szGuidBuffer = _tcstok( szAttributeString, _T(" \t") ) ) )
{
_tprintf( _T("Parsing error: Expecting guid.\r\n") );
__leave;
}
// Pull out the Propid
if( NULL == ( szPropspecBuffer = _tcstok( NULL, _T(" \t") ) ) )
{
_tprintf( _T("Parsing error: Expecting propspec.\r\n") );
__leave;
}
// Make sure the string stream is empty now
if( NULL != ( szTestBuffer = _tcstok( NULL, _T(" \t") ) ) )
{
_tprintf( _T("Parsing error: %s was unexpected at this")
_T(" time.\r\n"), szTestBuffer );
__leave;
}
// Convert the guid string to a guid
if( ! StrToGuid( szGuidBuffer,
&pFullPropspec[ uiAttributeIndex ].guidPropSet ) )
{
_tprintf( _T("Parsing error: could not convert %s to")
_T(" a GUID\r\n"), szGuidBuffer );
__leave;
}
if( ! StrToPropspec( szPropspecBuffer,
&pFullPropspec[ uiAttributeIndex ].psProperty ) )
{
_tprintf( _T("Parsing error: could not convert %s to a")
_T(" PROPSPEC\r\n"), szPropspecBuffer );
__leave;
}
// Advanve the Attribute index
++uiAttributeIndex;
// Advance uiKeyIndex
while( szKeyNames[ uiKeyIndex++ ] )
{
( (void)0 );
}
}
// Assert that I copied exactly the correct number of attributes
// (Debug version only)
_ASSERT( uiAttributeIndex == ulNbrAttributes );
// Set the success flag
fSuccessful = TRUE;
}
__finally
{
// If not successful, clean the heap and reset return values
if( ! fSuccessful )
{
if( pFullPropspec )
{
delete [] pFullPropspec;
pFullPropspec = NULL;
}
ulNbrAttributes = 0;
}
}
return fSuccessful;
} //CFiltParse::GetAttributes