@@ -203,16 +203,21 @@ private static IEnumerable<NdrProcedureDefinition> ReadProcs(IMemoryReader reade
203203 return procs . AsReadOnly ( ) ;
204204 }
205205
206- private void ReadTypes ( IntPtr midl_type_pickling_info_ptr , IntPtr midl_stub_desc_ptr , IEnumerable < int > fmt_offsets )
206+ private void ReadTypes ( IntPtr midl_type_pickling_info_ptr , IntPtr midl_stub_desc_ptr , bool deref_stub_desc , Func < IMemoryReader , IntPtr , IEnumerable < int > > get_offsets )
207207 {
208208 if ( midl_type_pickling_info_ptr == IntPtr . Zero )
209209 {
210- throw new ArgumentException ( "Must specify the MIDL_TYPE_PICKLING_INFO pointer" ) ;
210+ throw new ArgumentException ( "Must specify a MIDL_TYPE_PICKLING_INFO pointer" ) ;
211211 }
212212
213213 if ( midl_stub_desc_ptr == IntPtr . Zero )
214214 {
215- throw new ArgumentException ( "Must specify the MIDL_STUB_DESC pointer" ) ;
215+ throw new ArgumentException ( $ "Must specify a { ( deref_stub_desc ? "MIDL_STUBLESS_PROXY_INFO" : "MIDL_STUB_DESC" ) } pointer") ;
216+ }
217+
218+ if ( deref_stub_desc )
219+ {
220+ midl_stub_desc_ptr = _reader . ReadIntPtr ( midl_stub_desc_ptr ) ;
216221 }
217222
218223 var pickle_info = _reader . ReadStruct < MIDL_TYPE_PICKLING_INFO > ( midl_type_pickling_info_ptr ) ;
@@ -225,7 +230,7 @@ private void ReadTypes(IntPtr midl_type_pickling_info_ptr, IntPtr midl_stub_desc
225230 MIDL_STUB_DESC stub_desc = _reader . ReadStruct < MIDL_STUB_DESC > ( midl_stub_desc_ptr ) ;
226231 NdrParseContext context = new NdrParseContext ( _type_cache , null , stub_desc , stub_desc . pFormatTypes , stub_desc . GetExprDesc ( _reader ) ,
227232 flags , _reader , NdrParserFlags . IgnoreUserMarshal ) ;
228- foreach ( var i in fmt_offsets )
233+ foreach ( var i in get_offsets ( _reader , stub_desc . pFormatTypes ) )
229234 {
230235 NdrBaseTypeReference . Read ( context , i ) ;
231236 }
@@ -407,6 +412,19 @@ private static IMemoryReader CreateReader(NtProcess process)
407412 }
408413 }
409414
415+ private static IEnumerable < NdrComplexTypeReference > ReadPicklingComplexTypes ( NdrParserFlags parser_flags , NtProcess process , IntPtr midl_type_pickling_info , IntPtr midl_stub_desc , bool deref_stub_desc , Func < IMemoryReader , IntPtr , IEnumerable < int > > get_offsets )
416+ {
417+ NdrParser parser = new NdrParser ( process , null , parser_flags ) ;
418+ RunWithAccessCatch ( ( ) => parser . ReadTypes ( midl_type_pickling_info , midl_stub_desc , deref_stub_desc , get_offsets ) ) ;
419+ return parser . ComplexTypes ;
420+ }
421+
422+ private static IEnumerable < int > GetPicklingTableOffsets ( IMemoryReader reader , IntPtr type_pickling_offset_table , IEnumerable < int > type_index )
423+ {
424+ var table = reader . ReadIntPtr ( type_pickling_offset_table ) ;
425+ return type_index . Select ( i => reader . ReadInt32 ( table + i * 4 ) ) ;
426+ }
427+
410428 #endregion
411429
412430 #region Internal Members
@@ -644,26 +662,87 @@ public IEnumerable<NdrBaseTypeReference> Types
644662 #endregion
645663
646664 #region Static Methods
665+
666+ /// <summary>
667+ /// Parse NDR complex type information from a pickling structure. Used to extract explicit Encode/Decode method information.
668+ /// </summary>
669+ /// <param name="process">The process to read from.</param>
670+ /// <param name="midl_type_pickling_info">Pointer to the MIDL_TYPE_PICKLING_INFO structure.</param>
671+ /// <param name="midl_stub_desc">The pointer to the MIDL_STUB_DESC structure.</param>
672+ /// <param name="type_offsets">Pointers to the the format string to the start of the types.</param>
673+ /// <param name="parser_flags">Specify additional parser flags.</param>
674+ /// <returns>The list of complex types.</returns>
675+ /// <remarks>This function is used to extract type information for calls to NdrMesTypeDecode2. MIDL_TYPE_PICKLING_INFO is the second parameter,
676+ /// MIDL_STUB_DESC is the third, the Type Offsets is the fourth parameter.</remarks>
677+ public static IEnumerable < NdrComplexTypeReference > ReadPicklingComplexTypes ( NtProcess process , IntPtr midl_type_pickling_info , IntPtr midl_stub_desc , IntPtr [ ] type_offsets , NdrParserFlags parser_flags )
678+ {
679+ if ( type_offsets . Length == 0 )
680+ {
681+ return new NdrComplexTypeReference [ 0 ] ;
682+ }
683+
684+ return ReadPicklingComplexTypes ( parser_flags , process , midl_type_pickling_info , midl_stub_desc , false , ( r , f ) => type_offsets . Select ( p => ( int ) ( p . ToInt64 ( ) - f . ToInt64 ( ) ) ) ) ;
685+ }
686+
687+ /// <summary>
688+ /// Parse NDR complex type information from a pickling structure. Used to extract explicit Encode/Decode method information.
689+ /// </summary>
690+ /// <param name="process">The process to read from.</param>
691+ /// <param name="midl_type_pickling_info">Pointer to the MIDL_TYPE_PICKLING_INFO structure.</param>
692+ /// <param name="midl_stubless_proxy">The pointer to the MIDL_STUBLESS_PROXY_INFO structure.</param>
693+ /// <param name="type_pickling_offset_table">Pointer to the type pickling offset table.</param>
694+ /// <param name="type_index">Index into type_pickling_offset_table array.</param>
695+ /// <param name="parser_flags">Specify additional parser flags.</param>
696+ /// <returns>The list of complex types.</returns>
697+ /// <remarks>This function is used to extract type information for calls to NdrMesTypeDecode3. MIDL_TYPE_PICKLING_INFO is the second parameter,
698+ /// MIDL_STUBLESS_PROXY_INFO is the third, the type pickling offset table is the fourth and the type index is the fifth.</remarks>
699+ public static IEnumerable < NdrComplexTypeReference > ReadPicklingComplexTypes ( NtProcess process , IntPtr midl_type_pickling_info ,
700+ IntPtr midl_stubless_proxy , IntPtr type_pickling_offset_table , int [ ] type_index , NdrParserFlags parser_flags )
701+ {
702+ if ( type_index . Length == 0 )
703+ {
704+ return new NdrComplexTypeReference [ 0 ] ;
705+ }
706+
707+ return ReadPicklingComplexTypes ( parser_flags , process , midl_type_pickling_info , midl_stubless_proxy , true , ( r , f ) => GetPicklingTableOffsets ( r , type_pickling_offset_table , type_index ) ) ;
708+ }
709+
647710 /// <summary>
648711 /// Parse NDR complex type information from a pickling structure. Used to extract explicit Encode/Decode method information.
649712 /// </summary>
650713 /// <param name="process">The process to read from.</param>
651714 /// <param name="midl_type_pickling_info">Pointer to the MIDL_TYPE_PICKLING_INFO structure.</param>
652715 /// <param name="midl_stub_desc">The pointer to the MIDL_STUB_DESC structure.</param>
653716 /// <param name="start_offsets">Offsets into the format string to the start of the types.</param>
717+ /// <param name="parser_flags">Specify additional parser flags.</param>
654718 /// <returns>The list of complex types.</returns>
655719 /// <remarks>This function is used to extract type information for calls to NdrMesTypeDecode2. MIDL_TYPE_PICKLING_INFO is the second parameter,
656720 /// MIDL_STUB_DESC is the third (minus the offset).</remarks>
657- public static IEnumerable < NdrComplexTypeReference > ReadPicklingComplexTypes ( NtProcess process , IntPtr midl_type_pickling_info , IntPtr midl_stub_desc , params int [ ] start_offsets )
721+ public static IEnumerable < NdrComplexTypeReference > ReadPicklingComplexTypes ( NtProcess process ,
722+ IntPtr midl_type_pickling_info , IntPtr midl_stub_desc , int [ ] start_offsets , NdrParserFlags parser_flags )
658723 {
659724 if ( start_offsets . Length == 0 )
660725 {
661726 return new NdrComplexTypeReference [ 0 ] ;
662727 }
663728
664- NdrParser parser = new NdrParser ( process , null , NdrParserFlags . IgnoreUserMarshal ) ;
665- RunWithAccessCatch ( ( ) => parser . ReadTypes ( midl_type_pickling_info , midl_stub_desc , start_offsets ) ) ;
666- return parser . ComplexTypes ;
729+ return ReadPicklingComplexTypes ( parser_flags , process , midl_type_pickling_info , midl_stub_desc , false , ( r , f ) => start_offsets ) ;
730+ }
731+
732+ /// <summary>
733+ /// Parse NDR complex type information from a pickling structure. Used to extract explicit Encode/Decode method information.
734+ /// </summary>
735+ /// <param name="process">The process to read from.</param>
736+ /// <param name="midl_type_pickling_info">Pointer to the MIDL_TYPE_PICKLING_INFO structure.</param>
737+ /// <param name="midl_stub_desc">The pointer to the MIDL_STUB_DESC structure.</param>
738+ /// <param name="start_offsets">Offsets into the format string to the start of the types.</param>
739+ /// <returns>The list of complex types.</returns>
740+ /// <remarks>This function is used to extract type information for calls to NdrMesTypeDecode2. MIDL_TYPE_PICKLING_INFO is the second parameter,
741+ /// MIDL_STUB_DESC is the third (minus the offset).</remarks>
742+ public static IEnumerable < NdrComplexTypeReference > ReadPicklingComplexTypes ( NtProcess process , IntPtr midl_type_pickling_info ,
743+ IntPtr midl_stub_desc , params int [ ] start_offsets )
744+ {
745+ return ReadPicklingComplexTypes ( process , midl_type_pickling_info , midl_stub_desc , start_offsets , NdrParserFlags . IgnoreUserMarshal ) ;
667746 }
668747
669748 /// <summary>
0 commit comments