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.
 
 
 
 
 
 

806 lines
23 KiB

//***************************************************************************
//
// ANALYSER.CPP
//
// Module: OLE MS Provider Framework
//
// Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include <instpath.h>
#include <provexpt.h>
#include <strsafe.h>
WbemLexicon :: WbemLexicon () : position ( 0 ) , tokenStream ( NULL )
{
value.string = NULL ;
value.token = NULL ;
}
WbemLexicon :: ~WbemLexicon ()
{
switch ( token )
{
case TOKEN_ID:
{
delete [] value.token ;
}
break ;
case STRING_ID:
{
delete [] value.string ;
}
break ;
default:
{
} ;
}
}
WbemLexicon :: LexiconToken WbemLexicon :: GetToken ()
{
return token ;
}
WbemLexiconValue *WbemLexicon :: GetValue ()
{
return &value ;
}
WbemAnalyser :: WbemAnalyser ( WCHAR *tokenStream ) : status ( TRUE ) , position ( 0 ) , stream ( NULL )
{
if ( tokenStream )
{
DWORD t_TextLength = wcslen ( tokenStream ) + 1 ;
stream = new WCHAR [ t_TextLength ] ;
StringCchCopyW ( stream , t_TextLength , tokenStream ) ;
}
}
WbemAnalyser :: ~WbemAnalyser ()
{
delete [] stream ;
}
void WbemAnalyser :: Set ( WCHAR *tokenStream )
{
status = 0 ;
position = NULL ;
delete [] stream ;
DWORD t_TextLength = wcslen ( tokenStream ) + 1 ;
stream = new WCHAR [ t_TextLength ] ;
StringCchCopyW ( stream , t_TextLength , tokenStream ) ;
}
void WbemAnalyser :: PutBack ( WbemLexicon *token )
{
position = token->position ;
}
BOOL WbemAnalyser :: IsLeadingDecimal ( WCHAR token )
{
return iswdigit ( token ) && ( token != L'0' ) ;
}
BOOL WbemAnalyser :: IsDecimal ( WCHAR token )
{
return iswdigit ( token ) ;
}
BOOL WbemAnalyser :: IsHex ( WCHAR token )
{
return iswxdigit ( token ) ;
}
BOOL WbemAnalyser :: IsWhitespace ( WCHAR token )
{
return iswspace ( token ) ;
}
BOOL WbemAnalyser :: IsOctal ( WCHAR token )
{
return ( token >= L'0' && token <= L'7' ) ;
}
BOOL WbemAnalyser :: IsAlpha ( WCHAR token )
{
return iswalpha ( token ) ;
}
BOOL WbemAnalyser :: IsAlphaNumeric ( WCHAR token )
{
return iswalnum ( token ) || ( token == L'_' ) || ( token == L'-' ) ;
}
BOOL WbemAnalyser :: IsEof ( WCHAR token )
{
return token == 0 ;
}
LONG WbemAnalyser :: OctToDec ( WCHAR token )
{
return token - L'0' ;
}
LONG WbemAnalyser :: HexToDec ( WCHAR token )
{
if ( token >= L'0' && token <= L'9' )
{
return token - L'0' ;
}
else if ( token >= L'a' && token <= L'f' )
{
return token - L'a' + 10 ;
}
else if ( token >= L'A' && token <= L'F' )
{
return token - L'A' + 10 ;
}
else
{
return 0 ;
}
}
WbemAnalyser :: operator void * ()
{
return status ? this : NULL ;
}
#define DEC_INTEGER_START 1000
#define HEX_INTEGER_START 2000
#define OCT_INTEGER_START 3000
#define STRING_START 4000
#define TOKEN_START 5000
#define OID_START 6000
#define OID_STATE 9000
#define TOKEN_STATE 9001
#define STRING_STATE 9002
#define EOF_STATE 9003
#define DEC_INTEGER_STATE 9004
#define HEX_INTEGER_STATE 9005
#define OCT_INTEGER_STATE 9006
#define ACCEPT_STATE 10000
#define REJECT_STATE 10001
WbemLexicon *WbemAnalyser :: Get ()
{
WbemLexicon *lexicon = NULL ;
if ( stream )
{
lexicon = GetToken () ;
}
else
{
lexicon = new WbemLexicon ;
lexicon->position = position ;
lexicon->token = WbemLexicon :: EOF_ID ;
}
return lexicon ;
}
WbemLexicon *WbemAnalyser :: GetToken ()
{
WbemLexicon *lexicon = new WbemLexicon ;
lexicon->position = position ;
ULONG state = 0 ;
/*
* Integer Definitions
*/
BOOL negative = FALSE ;
LONG magicMult = ( LONG ) ( ( ( ULONG ) ( 1L << 31L ) ) / 10L ) ;
LONG magicNegDigit = 8 ;
LONG magicPosDigit = 7 ;
LONG datum = 0 ;
/*
* String Definitions
*/
ULONG string_start = 0 ;
ULONG string_length = 0 ;
WCHAR *string = NULL ;
/*
* Token Definitions
*/
ULONG token_start = 0 ;
/*
* OID Definitions
*/
ULONG hex_datum = 0 ;
ULONG brace_position = 0 ;
ULONG hex_repetitions = 0 ;
ULONG nybbleRepetitions = 0 ;
while ( state != REJECT_STATE && state != ACCEPT_STATE )
{
WCHAR token = stream [ position ] ;
switch ( state )
{
case 0:
{
if ( IsLeadingDecimal ( token ) )
{
state = DEC_INTEGER_START + 1 ;
datum = ( token - 48 ) ;
}
else if ( token == L'@' )
{
lexicon->token = WbemLexicon :: AT_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L'\\' )
{
lexicon->token = WbemLexicon :: BACKSLASH_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L'\"' )
{
state = STRING_START ;
string_start = position + 1 ;
}
else if ( token == L'{' )
{
state = OID_START ;
hex_datum = 0 ;
brace_position = position ;
hex_repetitions = 0 ;
nybbleRepetitions = 0 ;
}
else if ( token == L'}' )
{
lexicon->token = WbemLexicon :: CLOSE_BRACE_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L'=' )
{
lexicon->token = WbemLexicon :: EQUALS_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L'.' )
{
lexicon->token = WbemLexicon :: DOT_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L',' )
{
lexicon->token = WbemLexicon :: COMMA_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L':' )
{
lexicon->token = WbemLexicon :: COLON_ID ;
state = ACCEPT_STATE ;
}
else if ( token == L'+' )
{
state = DEC_INTEGER_START ;
}
else if ( token == L'-' )
{
negative = TRUE ;
state = DEC_INTEGER_START ;
}
else if ( token == L'0' )
{
state = 1 ;
}
else if ( IsWhitespace ( token ) )
{
state = 0 ;
}
else if ( IsEof ( token ) )
{
lexicon->token = WbemLexicon :: EOF_ID ;
state = ACCEPT_STATE ;
}
else if ( IsAlpha ( token ) )
{
state = TOKEN_START ;
token_start = position ;
}
else state = REJECT_STATE ;
}
break ;
case 1:
{
if ( token == L'x' || token == L'X' )
{
state = HEX_INTEGER_START ;
}
else if ( IsOctal ( token ) )
{
state = OCT_INTEGER_START ;
datum = ( token - 48 ) ;
}
else
{
lexicon->token = WbemLexicon :: INTEGER_ID ;
lexicon->value.integer = 0 ;
position -- ;
state = ACCEPT_STATE ;
}
}
break ;
case STRING_START:
{
if ( token == L'\"' )
{
lexicon->token = WbemLexicon :: STRING_ID ;
state = ACCEPT_STATE ;
if ( position == string_start )
{
lexicon->value.string = new WCHAR [ 1 ] ;
lexicon->value.string [ 0 ] = 0 ;
}
else
{
lexicon->value.string = new WCHAR [ string_length + 1 ] ;
wcsncpy (
lexicon->value.string ,
string ,
string_length
) ;
lexicon->value.string [ string_length ] = 0 ;
free (string);
}
}
else if ( token == IsEof ( token ) )
{
state = REJECT_STATE ;
free (string);
}
else
{
realloc_throw ( &string , sizeof ( WCHAR ) * ( string_length + 1 ) ) ;
string [ string_length ] = token ;
string_length ++ ;
state = STRING_START ;
}
}
break ;
case STRING_START+1:
{
if ( token == L'\"' )
{
realloc_throw ( &string , sizeof ( WCHAR ) * ( string_length + 1 ) ) ;
string [ string_length ] = L'\"' ;
string_length ++ ;
state = STRING_START ;
}
else if ( token == IsEof ( token ) )
{
state = REJECT_STATE ;
}
else
{
realloc_throw ( &string , sizeof ( WCHAR ) * ( string_length + 1 ) ) ;
string [ string_length ] = token ;
string_length ++ ;
state = STRING_START ;
}
}
break ;
case TOKEN_START:
{
if ( IsAlphaNumeric ( token ) )
{
state = TOKEN_START ;
}
else
{
state = ACCEPT_STATE ;
lexicon->token = WbemLexicon :: TOKEN_ID ;
lexicon->value.token = new WCHAR [ position - token_start + 1 ] ;
wcsncpy (
lexicon->value.token ,
& stream [ token_start ] ,
position - token_start
) ;
lexicon->value.token [ position - token_start ] = 0 ;
position -- ;
}
}
break ;
case HEX_INTEGER_START:
{
if ( IsHex ( token ) )
{
datum = HexToDec ( token ) ;
state = HEX_INTEGER_START + 1 ;
}
else
{
state = REJECT_STATE ;
}
}
break ;
case HEX_INTEGER_START+1:
{
if ( IsHex ( token ) )
{
state = HEX_INTEGER_START + 1 ;
if ( datum > magicMult )
{
state = REJECT_STATE ;
}
else if ( datum == magicMult )
{
if ( HexToDec ( token ) > magicPosDigit )
{
state = REJECT_STATE ;
}
}
datum = ( datum << 4 ) + HexToDec ( token ) ;
}
else
{
lexicon->token = WbemLexicon :: INTEGER_ID ;
lexicon->value.integer = datum ;
state = ACCEPT_STATE ;
position -- ;
}
}
break ;
case OCT_INTEGER_START:
{
if ( IsOctal ( token ) )
{
state = OCT_INTEGER_START ;
if ( datum > magicMult )
{
state = REJECT_STATE ;
}
else if ( datum == magicMult )
{
if ( OctToDec ( token ) > magicPosDigit )
{
state = REJECT_STATE ;
}
}
datum = ( datum << 3 ) + OctToDec ( token ) ;
}
else
{
lexicon->token = WbemLexicon :: INTEGER_ID ;
lexicon->value.integer = datum ;
state = ACCEPT_STATE ;
position -- ;
}
}
break ;
case DEC_INTEGER_START:
{
if ( IsDecimal ( token ) )
{
state = DEC_INTEGER_START + 1 ;
datum = ( token - 48 ) ;
}
else
if ( IsWhitespace ( token ) )
{
state = DEC_INTEGER_START ;
}
else state = REJECT_STATE ;
}
break ;
case DEC_INTEGER_START+1:
{
if ( IsDecimal ( token ) )
{
state = DEC_INTEGER_START + 1 ;
if ( datum > magicMult )
{
state = REJECT_STATE ;
}
else if ( datum == magicMult )
{
if ( negative )
{
if ( ( token - 48 ) > magicNegDigit )
{
state = REJECT_STATE ;
}
}
else
{
if ( ( token - 48 ) > magicPosDigit )
{
state = REJECT_STATE ;
}
}
}
datum = datum * 10 + ( token - 48 ) ;
}
else
{
lexicon->token = WbemLexicon :: INTEGER_ID ;
if ( negative )
{
lexicon->value.integer = datum * -1 ;
}
else
{
lexicon->value.integer = datum ;
}
state = ACCEPT_STATE ;
position -- ;
}
}
break ;
case OID_START: // {xxxxxxxx
{
if ( IsHex ( token ) )
{
hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 7 - hex_repetitions ) << 2 ) ) ;
hex_repetitions ++ ;
if ( hex_repetitions == 8 )
{
state = OID_START + 1 ;
lexicon->value.guid.Data1 = hex_datum ;
hex_repetitions = 0 ;
hex_datum = 0 ;
}
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+1: // {xxxxxxxx-
{
if ( token == L'-' )
{
state = OID_START + 2 ;
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+2: // {xxxxxxxx-xxxx
{
if ( IsHex ( token ) )
{
hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 3 - hex_repetitions ) << 2 ) ) ;
hex_repetitions ++ ;
if ( hex_repetitions == 4 )
{
lexicon->value.guid.Data2 = ( USHORT ) hex_datum ;
hex_repetitions = 0 ;
hex_datum = 0 ;
state = OID_START + 3 ;
}
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+3: // {xxxxxxxx-xxxx-
{
if ( token == L'-' )
{
state = OID_START + 4 ;
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+4: // {xxxxxxxx-xxxx-xxxx
{
if ( IsHex ( token ) )
{
hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 3 - hex_repetitions ) <<2 ) ) ;
hex_repetitions ++ ;
if ( hex_repetitions == 4 )
{
lexicon->value.guid.Data3 = ( USHORT ) hex_datum ;
hex_repetitions = 0 ;
hex_datum = 0 ;
state = OID_START + 5 ;
}
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+5: // {xxxxxxxx-xxxx-xxxx-
{
if ( token == L'-' )
{
state = OID_START + 6 ;
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+6: // {xxxxxxxx-xxxx-xxxx-xxxx
{
if ( IsHex ( token ) )
{
hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 1 - nybbleRepetitions ) << 2 ) ) ;
hex_repetitions ++ ;
nybbleRepetitions ++ ;
if ( hex_repetitions == 2 )
{
lexicon->value.guid.Data4 [ 0 ] = ( char ) hex_datum ;
hex_datum = 0 ;
nybbleRepetitions = 0 ;
}
else if ( hex_repetitions == 4 )
{
lexicon->value.guid.Data4 [ 1 ] = ( char ) hex_datum ;
hex_repetitions = 0 ;
hex_datum = 0 ;
nybbleRepetitions = 0 ;
state = OID_START + 7 ;
}
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+7: // {xxxxxxxx-xxxx-xxxx-xxxx-
{
if ( token == L'-' )
{
state = OID_START + 8 ;
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+8: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{
if ( IsHex ( token ) )
{
hex_datum = hex_datum + ( HexToDec ( token ) << ( ( 1 - nybbleRepetitions ) << 2 ) ) ;
hex_repetitions ++ ;
nybbleRepetitions ++ ;
if ( hex_repetitions == 12 )
{
lexicon->value.guid.Data4 [ 7 ] = ( char ) hex_datum ;
hex_repetitions = 0 ;
nybbleRepetitions = 0 ;
hex_datum = 0 ;
state = OID_START + 9 ;
}
else if ( hex_repetitions % 2 == 0 )
{
lexicon->value.guid.Data4 [ 1 + ( hex_repetitions >> 1 ) ] = ( char ) hex_datum ;
hex_datum = 0 ;
nybbleRepetitions = 0 ;
}
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case OID_START+9: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
{
if ( token == L'}' )
{
lexicon->token = WbemLexicon :: OID_ID ;
state = ACCEPT_STATE ;
}
else
{
state = ACCEPT_STATE ;
position = brace_position ;
lexicon->token = WbemLexicon :: OPEN_BRACE_ID ;
}
}
break ;
case ACCEPT_STATE:
case REJECT_STATE:
default:
{
state = REJECT_STATE ;
} ;
break ;
}
position ++ ;
}
status = ( state != REJECT_STATE ) ;
return lexicon ;
}