internal NdrPointerTypeReference(NdrParseContext context, NdrFormatCharacter format, BinaryReader reader) : base(format)
 {
     Flags = (NdrPointerFlags)reader.ReadByte();
     if ((Flags & NdrPointerFlags.FC_SIMPLE_POINTER) == NdrPointerFlags.FC_SIMPLE_POINTER)
     {
         Type = new NdrSimpleTypeReference(ReadFormat(reader));
     }
     else
     {
         Type = Read(context, ReadTypeOffset(reader));
     }
 }
        internal NdrByteCountPointerReferenceType(NdrParseContext context, BinaryReader reader) : base(NdrFormatCharacter.FC_BYTE_COUNT_POINTER)
        {
            NdrFormatCharacter format = (NdrFormatCharacter)reader.ReadByte();

            if (format != NdrFormatCharacter.FC_PAD)
            {
                Type        = new NdrSimpleTypeReference(format);
                Description = new NdrCorrelationDescriptor();
            }
            else
            {
                Description = new NdrCorrelationDescriptor(context, reader);
                Type        = Read(context, ReadTypeOffset(reader));
            }
        }
        internal NdrProcedureParameter(NdrParseContext context, BinaryReader reader)
        {
            ushort attr = reader.ReadUInt16();

            Attributes      = (NdrParamAttributes)(attr & ~ServerAllocSizeMask);
            ServerAllocSize = (attr & ServerAllocSizeMask) >> 10;
            Offset          = reader.ReadUInt16();
            if ((Attributes & NdrParamAttributes.IsBasetype) == 0)
            {
                int type_ofs = reader.ReadUInt16();
                Type = NdrBaseTypeReference.Read(context, type_ofs);
            }
            else
            {
                Type = new NdrSimpleTypeReference((NdrFormatCharacter)reader.ReadByte());
                // Remove padding.
                reader.ReadByte();
            }
        }
 public NdrRangeTypeReference(BinaryReader reader) : base(NdrFormatCharacter.FC_RANGE)
 {
     RangeType = new NdrSimpleTypeReference((NdrFormatCharacter)reader.ReadByte());
     MinValue  = reader.ReadInt32();
     MaxValue  = reader.ReadInt32();
 }
        internal NdrProcedureDefinition(IMemoryReader mem_reader, NdrTypeCache type_cache,
                                        ISymbolResolver symbol_resolver, MIDL_STUB_DESC stub_desc,
                                        IntPtr proc_desc, IntPtr type_desc, NDR_EXPR_DESC expr_desc, IntPtr dispatch_func,
                                        string name, NdrParserFlags parser_flags)
        {
            BinaryReader        reader       = mem_reader.GetReader(proc_desc);
            NdrFormatCharacter  handle_type  = (NdrFormatCharacter)reader.ReadByte();
            NdrInterpreterFlags old_oi_flags = (NdrInterpreterFlags)reader.ReadByte();

            if ((old_oi_flags & NdrInterpreterFlags.HasRpcFlags) == NdrInterpreterFlags.HasRpcFlags)
            {
                RpcFlags = reader.ReadUInt32();
            }

            ProcNum = reader.ReadUInt16();

            if (string.IsNullOrWhiteSpace(name))
            {
                if (symbol_resolver != null && dispatch_func != IntPtr.Zero)
                {
                    Name = symbol_resolver.GetSymbolForAddress(dispatch_func, false, true);
                }

                Name = Name ?? $"Proc{ProcNum}";
            }
            else
            {
                Name = name;
            }

            StackSize = reader.ReadUInt16();
            if (handle_type == 0)
            {
                // read out handle type.
                handle_type = (NdrFormatCharacter)reader.ReadByte();
                NdrHandleParamFlags flags      = (NdrHandleParamFlags)reader.ReadByte();
                ushort handle_offset           = reader.ReadUInt16();
                NdrBaseTypeReference base_type = new NdrSimpleTypeReference(handle_type);
                if (handle_type == NdrFormatCharacter.FC_BIND_PRIMITIVE)
                {
                    flags = flags != 0 ? NdrHandleParamFlags.HANDLE_PARAM_IS_VIA_PTR : 0;
                }
                else if (handle_type == NdrFormatCharacter.FC_BIND_GENERIC)
                {
                    // Remove the size field, we might do something with this later.
                    flags = (NdrHandleParamFlags)((byte)flags & 0xF0);
                    // Read out the remaining data.
                    reader.ReadByte();
                    reader.ReadByte();
                }
                else if (handle_type == NdrFormatCharacter.FC_BIND_CONTEXT)
                {
                    // Read out the remaining data.
                    reader.ReadByte();
                    reader.ReadByte();
                }
                else
                {
                    throw new ArgumentException($"Unsupported explicit handle type {handle_type}");
                }
                Handle = new NdrProcedureHandleParameter(0,
                                                         (flags & NdrHandleParamFlags.HANDLE_PARAM_IS_VIA_PTR) != 0 ? new NdrPointerTypeReference(base_type)
                            : base_type, handle_offset, true, flags, handle_type == NdrFormatCharacter.FC_BIND_GENERIC);
            }
            else
            {
                Handle = new NdrProcedureHandleParameter(0, new NdrSimpleTypeReference(handle_type), 0, false, 0, false);
            }

            ushort constant_client_buffer_size = reader.ReadUInt16();
            ushort constant_server_buffer_size = reader.ReadUInt16();

            InterpreterFlags = (NdrInterpreterOptFlags)reader.ReadByte();
            int number_of_params = reader.ReadByte();

            NdrProcHeaderExts exts = new NdrProcHeaderExts();

            if ((InterpreterFlags & NdrInterpreterOptFlags.HasExtensions) == NdrInterpreterOptFlags.HasExtensions)
            {
                int ext_size = reader.ReadByte();
                reader.BaseStream.Position -= 1;
                // Read out extension bytes.
                byte[] extension = reader.ReadAll(ext_size);
                if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(NdrProcHeaderExts)) <= ext_size)
                {
                    using (var buffer = new SafeStructureInOutBuffer <NdrProcHeaderExts>(ext_size, false))
                    {
                        buffer.WriteArray(0, extension, 0, ext_size);
                        exts = buffer.Result;
                    }
                }
            }

            NdrParseContext context         = new NdrParseContext(type_cache, symbol_resolver, stub_desc, type_desc, expr_desc, exts.Flags2, mem_reader, parser_flags);
            List <NdrProcedureParameter> ps = new List <NdrProcedureParameter>();

            bool has_return  = InterpreterFlags.HasFlag(NdrInterpreterOptFlags.HasReturn);
            int  param_count = has_return ? number_of_params - 1 : number_of_params;

            for (int param = 0; param < param_count; ++param)
            {
                ps.Add(new NdrProcedureParameter(context, reader, $"p{param}"));
            }

            if (Handle.Explicit && !Handle.Generic)
            {
                // Insert handle into parameter list at the best location.
                int index = 0;
                while (index < ps.Count)
                {
                    if (ps[index].Offset > Handle.Offset)
                    {
                        ps.Insert(index, Handle);
                        break;
                    }
                    index++;
                }
            }

            Params = ps.AsReadOnly();
            if (has_return)
            {
                ReturnValue = new NdrProcedureParameter(context, reader, "retval");
            }
            DispatchFunction = dispatch_func;
        }