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.
|
|
//=============================================================================
//
// MODULE: ASN1Sequence.cxx
//
// Description:
//
// Implementation of ASN.1 sequence parsing logic
//
// Modification History
//
// Mark Pustilnik Date: 06/08/02 - created
//
//=============================================================================
#include "ASN1Parser.hxx"
//
// Parsing a sequence with optional elements entails invoking successive parsers
// and stepping over optional blocks which were not found in the sequence
//
DWORD ASN1ParserSequence::Parse( IN OUT ASN1FRAME * Frame ) { DWORD dw; ASN1FRAME FrameIn = *Frame; DWORD Length = DataLength( Frame ); BOOLEAN FrameLevelChanged = FALSE; ULPBYTE SequenceEnd;
dw = VerifyAndSkipHeader( Frame );
if ( dw != ERROR_SUCCESS ) { goto Cleanup; }
if ( *Frame->Address != BuildDescriptor( ctUniversal, pcConstructed, utSequence )) { dw = ERROR_INVALID_DATA; goto Cleanup; }
//
// Remember the length of the sequence
//
Length = DataLength( Frame );
//
// Skip over the the descriptor
//
Frame->Address++;
//
// Skip over the length header
//
Frame->Address += HeaderLength( Frame->Address );
//
// Remember where the sequence ends so we know when to stop iterating
//
SequenceEnd = Frame->Address + Length;
//
// Display the sequence summary
//
if ( m_hPropertySummary ) { if ( FALSE == AttachPropertyInstanceEx( Frame->hFrame, m_hPropertySummary, (DWORD)(SequenceEnd - FrameIn.Address), FrameIn.Address, 0, NULL, 0, Frame->Level, 0 )) { dw = ERROR_CAN_NOT_COMPLETE; goto Cleanup; }
//
// Anything from this point on is indented
//
Frame->Level += 1; FrameLevelChanged = TRUE; }
while ( Frame->Address < SequenceEnd ) { for ( ULONG i = 0; i < m_Count; i++ ) { ASN1ParserBase * Parser = m_Parsers[i];
dw = Parser->Parse( Frame );
if ( dw == ERROR_INVALID_USER_BUFFER && Parser->IsOptional()) { //
// Failed to parse, but it was optional anyway
// Clear the error code and proceed
//
dw = ERROR_SUCCESS; continue; } else if ( dw != ERROR_SUCCESS ) { goto Cleanup; }
//
// Make sure the sequence is not overstepped
//
if ( Frame->Address > SequenceEnd ) { dw = ERROR_INVALID_DATA; goto Cleanup; } } }
if ( !m_Extensible ) { //
// Any ASN.1 encoding worth it salt is exact, so enforce that
//
if ( Frame->Address != SequenceEnd ) { dw = ERROR_INVALID_DATA; goto Cleanup; } } else { //
// Pretend we've parsed the rest successfully
//
Frame->Address = SequenceEnd; }
//
// If we are a value collector, display the collected values now
//
dw = DisplayCollectedValues( Frame, (DWORD)(SequenceEnd-FrameIn.Address), FrameIn.Address );
PurgeCollectedValues();
if ( dw != ERROR_SUCCESS ) { goto Cleanup; }
Cleanup:
//
// Restore the indent level
//
if ( dw != ERROR_SUCCESS ) { *Frame = FrameIn; } else if ( FrameLevelChanged ) { Frame->Level -= 1; }
return dw; }
DWORD ASN1ParserSequence::CollectValue( IN ASN1VALUE * Value ) { ASN1VALUE * NewValue = Value ? Value->Clone() : NULL; PASN1VALUE * NewValuesCollected = new PASN1VALUE[m_ValueCount + 1];
if (( Value != NULL && NewValue == NULL ) || NewValuesCollected == NULL ) { delete NewValue; delete [] NewValuesCollected;
return ERROR_NOT_ENOUGH_MEMORY; }
RtlCopyMemory( NewValuesCollected, m_ValuesCollected, m_ValueCount * sizeof( PASN1VALUE ) );
delete [] m_ValuesCollected; m_ValuesCollected = NewValuesCollected; m_ValuesCollected[m_ValueCount++] = NewValue;
return ERROR_SUCCESS; }
|