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.

222 lines
4.9 KiB

  1. //=============================================================================
  2. //
  3. // MODULE: ASN1Sequence.cxx
  4. //
  5. // Description:
  6. //
  7. // Implementation of ASN.1 sequence parsing logic
  8. //
  9. // Modification History
  10. //
  11. // Mark Pustilnik Date: 06/08/02 - created
  12. //
  13. //=============================================================================
  14. #include "ASN1Parser.hxx"
  15. //
  16. // Parsing a sequence with optional elements entails invoking successive parsers
  17. // and stepping over optional blocks which were not found in the sequence
  18. //
  19. DWORD
  20. ASN1ParserSequence::Parse(
  21. IN OUT ASN1FRAME * Frame
  22. )
  23. {
  24. DWORD dw;
  25. ASN1FRAME FrameIn = *Frame;
  26. DWORD Length = DataLength( Frame );
  27. BOOLEAN FrameLevelChanged = FALSE;
  28. ULPBYTE SequenceEnd;
  29. dw = VerifyAndSkipHeader( Frame );
  30. if ( dw != ERROR_SUCCESS )
  31. {
  32. goto Cleanup;
  33. }
  34. if ( *Frame->Address != BuildDescriptor(
  35. ctUniversal,
  36. pcConstructed,
  37. utSequence ))
  38. {
  39. dw = ERROR_INVALID_DATA;
  40. goto Cleanup;
  41. }
  42. //
  43. // Remember the length of the sequence
  44. //
  45. Length = DataLength( Frame );
  46. //
  47. // Skip over the the descriptor
  48. //
  49. Frame->Address++;
  50. //
  51. // Skip over the length header
  52. //
  53. Frame->Address += HeaderLength( Frame->Address );
  54. //
  55. // Remember where the sequence ends so we know when to stop iterating
  56. //
  57. SequenceEnd = Frame->Address + Length;
  58. //
  59. // Display the sequence summary
  60. //
  61. if ( m_hPropertySummary )
  62. {
  63. if ( FALSE == AttachPropertyInstanceEx(
  64. Frame->hFrame,
  65. m_hPropertySummary,
  66. (DWORD)(SequenceEnd - FrameIn.Address),
  67. FrameIn.Address,
  68. 0,
  69. NULL,
  70. 0,
  71. Frame->Level,
  72. 0 ))
  73. {
  74. dw = ERROR_CAN_NOT_COMPLETE;
  75. goto Cleanup;
  76. }
  77. //
  78. // Anything from this point on is indented
  79. //
  80. Frame->Level += 1;
  81. FrameLevelChanged = TRUE;
  82. }
  83. while ( Frame->Address < SequenceEnd )
  84. {
  85. for ( ULONG i = 0; i < m_Count; i++ )
  86. {
  87. ASN1ParserBase * Parser = m_Parsers[i];
  88. dw = Parser->Parse( Frame );
  89. if ( dw == ERROR_INVALID_USER_BUFFER &&
  90. Parser->IsOptional())
  91. {
  92. //
  93. // Failed to parse, but it was optional anyway
  94. // Clear the error code and proceed
  95. //
  96. dw = ERROR_SUCCESS;
  97. continue;
  98. }
  99. else if ( dw != ERROR_SUCCESS )
  100. {
  101. goto Cleanup;
  102. }
  103. //
  104. // Make sure the sequence is not overstepped
  105. //
  106. if ( Frame->Address > SequenceEnd )
  107. {
  108. dw = ERROR_INVALID_DATA;
  109. goto Cleanup;
  110. }
  111. }
  112. }
  113. if ( !m_Extensible )
  114. {
  115. //
  116. // Any ASN.1 encoding worth it salt is exact, so enforce that
  117. //
  118. if ( Frame->Address != SequenceEnd )
  119. {
  120. dw = ERROR_INVALID_DATA;
  121. goto Cleanup;
  122. }
  123. }
  124. else
  125. {
  126. //
  127. // Pretend we've parsed the rest successfully
  128. //
  129. Frame->Address = SequenceEnd;
  130. }
  131. //
  132. // If we are a value collector, display the collected values now
  133. //
  134. dw = DisplayCollectedValues(
  135. Frame,
  136. (DWORD)(SequenceEnd-FrameIn.Address),
  137. FrameIn.Address
  138. );
  139. PurgeCollectedValues();
  140. if ( dw != ERROR_SUCCESS )
  141. {
  142. goto Cleanup;
  143. }
  144. Cleanup:
  145. //
  146. // Restore the indent level
  147. //
  148. if ( dw != ERROR_SUCCESS )
  149. {
  150. *Frame = FrameIn;
  151. }
  152. else if ( FrameLevelChanged )
  153. {
  154. Frame->Level -= 1;
  155. }
  156. return dw;
  157. }
  158. DWORD
  159. ASN1ParserSequence::CollectValue(
  160. IN ASN1VALUE * Value
  161. )
  162. {
  163. ASN1VALUE * NewValue = Value ? Value->Clone() : NULL;
  164. PASN1VALUE * NewValuesCollected = new PASN1VALUE[m_ValueCount + 1];
  165. if (( Value != NULL && NewValue == NULL ) ||
  166. NewValuesCollected == NULL )
  167. {
  168. delete NewValue;
  169. delete [] NewValuesCollected;
  170. return ERROR_NOT_ENOUGH_MEMORY;
  171. }
  172. RtlCopyMemory(
  173. NewValuesCollected,
  174. m_ValuesCollected,
  175. m_ValueCount * sizeof( PASN1VALUE )
  176. );
  177. delete [] m_ValuesCollected;
  178. m_ValuesCollected = NewValuesCollected;
  179. m_ValuesCollected[m_ValueCount++] = NewValue;
  180. return ERROR_SUCCESS;
  181. }