public static RpcMarshalArgument CalculateCorrelationArgument(this NdrCorrelationDescriptor correlation, int current_offset, IEnumerable <Tuple <int, string> > offset_to_name) { if (correlation.IsConstant) { return(RpcMarshalArgument.CreateFromPrimitive((long)correlation.Offset)); } int expected_offset = current_offset + correlation.Offset; foreach (var offset in offset_to_name) { if (offset.Item1 == expected_offset) { CodeExpression expr = GetVariable(offset.Item2); CodeExpression right_expr = null; CodeBinaryOperatorType operator_type = CodeBinaryOperatorType.Add; switch (correlation.Operator) { case NdrFormatCharacter.FC_ADD_1: right_expr = GetPrimitive(1); operator_type = CodeBinaryOperatorType.Add; break; case NdrFormatCharacter.FC_DIV_2: right_expr = GetPrimitive(2); operator_type = CodeBinaryOperatorType.Divide; break; case NdrFormatCharacter.FC_MULT_2: right_expr = GetPrimitive(2); operator_type = CodeBinaryOperatorType.Multiply; break; case NdrFormatCharacter.FC_SUB_1: right_expr = GetPrimitive(2); operator_type = CodeBinaryOperatorType.Multiply; break; } if (right_expr != null) { expr = new CodeBinaryOperatorExpression(expr, operator_type, right_expr); } return(new RpcMarshalArgument(expr, new CodeTypeReference(typeof(long)))); } else if (offset.Item1 > expected_offset) { break; } } // We failed to find the base name, just return a 0 for now. return(RpcMarshalArgument.CreateFromPrimitive(0L)); }
private RpcTypeDescriptor GetTypeDescriptorInternal(NdrBaseTypeReference type) { if (type is NdrSimpleTypeReference) { switch (type.Format) { case NdrFormatCharacter.FC_BYTE: case NdrFormatCharacter.FC_USMALL: return(new RpcTypeDescriptor(typeof(byte), "ReadByte", false, "WriteByte", type, null, null)); case NdrFormatCharacter.FC_SMALL: case NdrFormatCharacter.FC_CHAR: return(new RpcTypeDescriptor(typeof(sbyte), "ReadSByte", false, "WriteSByte", type, null, null)); case NdrFormatCharacter.FC_WCHAR: return(new RpcTypeDescriptor(typeof(char), "ReadChar", false, "WriteChar", type, null, null)); case NdrFormatCharacter.FC_SHORT: return(new RpcTypeDescriptor(typeof(short), "ReadInt16", false, "WriteInt16", type, null, null)); case NdrFormatCharacter.FC_USHORT: return(new RpcTypeDescriptor(typeof(ushort), "ReadUInt16", false, "WriteUInt16", type, null, null)); case NdrFormatCharacter.FC_LONG: case NdrFormatCharacter.FC_ENUM16: case NdrFormatCharacter.FC_ENUM32: return(new RpcTypeDescriptor(typeof(int), "ReadInt32", false, "WriteInt32", type, null, null)); case NdrFormatCharacter.FC_ULONG: case NdrFormatCharacter.FC_ERROR_STATUS_T: return(new RpcTypeDescriptor(typeof(uint), "ReadUInt32", false, "WriteUInt32", type, null, null)); case NdrFormatCharacter.FC_FLOAT: return(new RpcTypeDescriptor(typeof(float), "ReadFloat", false, "WriteFloat", type, null, null)); case NdrFormatCharacter.FC_HYPER: return(new RpcTypeDescriptor(typeof(long), "ReadInt64", false, "WriteInt64", type, null, null)); case NdrFormatCharacter.FC_DOUBLE: return(new RpcTypeDescriptor(typeof(double), "ReadDouble", false, "WriteDouble", type, null, null)); case NdrFormatCharacter.FC_INT3264: return(new RpcTypeDescriptor(typeof(NdrInt3264), "ReadInt3264", false, "WriteInt3264", type, null, null)); case NdrFormatCharacter.FC_UINT3264: return(new RpcTypeDescriptor(typeof(NdrUInt3264), "ReadUInt3264", false, "WriteUInt3264", type, null, null)); case NdrFormatCharacter.FC_C_WSTRING: return(new RpcTypeDescriptor(typeof(string), "ReadConformantString", false, "WriteConformantString", type, null, null)); case NdrFormatCharacter.FC_C_CSTRING: return(new RpcTypeDescriptor(typeof(string), "ReadAnsiConformantString", false, "WriteAnsiConformantString", type, null, null)); case NdrFormatCharacter.FC_CSTRING: case NdrFormatCharacter.FC_WSTRING: break; } } else if (type is NdrKnownTypeReference known_type) { switch (known_type.KnownType) { case NdrKnownTypes.GUID: return(new RpcTypeDescriptor(typeof(Guid), "ReadGuid", false, "WriteGuid", type, null, null)); case NdrKnownTypes.BSTR: case NdrKnownTypes.HSTRING: // Implement these custom marshallers. break; } } else if (type is NdrBaseStringTypeReference) { if (type is NdrConformantStringTypeReference conformant_str) { if (conformant_str.Format == NdrFormatCharacter.FC_C_CSTRING) { return(new RpcTypeDescriptor(typeof(string), "ReadAnsiConformantString", false, "WriteAnsiConformantString", type, null, null)); } return(new RpcTypeDescriptor(typeof(string), "ReadConformantString", false, "WriteConformantString", type, null, null)); } } else if (type is NdrSystemHandleTypeReference system_handle) { return(new RpcTypeDescriptor(system_handle.GetSystemHandleType(), "ReadSystemHandle", true, "WriteSystemHandle", type, null, null)); } else if (type is NdrSimpleArrayTypeReference simple_array) { RpcTypeDescriptor element_type = GetTypeDescriptor(simple_array.ElementType); RpcMarshalArgument arg = new RpcMarshalArgument { CodeType = new CodeTypeReference(typeof(int)), Expression = CodeGenUtils.GetPrimitive(simple_array.ElementCount) }; if (element_type.BuiltinType == typeof(char)) { return(new RpcTypeDescriptor(typeof(string), "ReadFixedString", false, "WriteFixedString", type, null, null, arg) { FixedCount = simple_array.ElementCount }); } else if (element_type.BuiltinType == typeof(byte)) { return(new RpcTypeDescriptor(typeof(byte[]), "ReadBytes", false, "WriteFixedBytes", type, null, null, arg) { FixedCount = simple_array.ElementCount }); } } else if (type is NdrPointerTypeReference pointer) { var desc = GetTypeDescriptor(pointer.Type); RpcPointerType pointer_type = RpcPointerType.None; switch (pointer.Format) { case NdrFormatCharacter.FC_UP: pointer_type = RpcPointerType.Unique; break; case NdrFormatCharacter.FC_RP: pointer_type = RpcPointerType.Reference; break; default: pointer_type = RpcPointerType.Full; break; } return(new RpcTypeDescriptor(desc, pointer_type)); } else if (type is NdrSupplementTypeReference supp) { return(GetTypeDescriptor(supp.SupplementType)); } else if (type is NdrHandleTypeReference handle) { if (handle.Format == NdrFormatCharacter.FC_BIND_CONTEXT) { return(new RpcTypeDescriptor(typeof(NdrContextHandle), "ReadContextHandle", false, "WriteContextHandle", type, null, null)); } } else if (type is NdrRangeTypeReference range) { return(GetTypeDescriptor(range.RangeType)); } else if (type is NdrBogusArrayTypeReference bogus_array) { RpcTypeDescriptor element_type = GetTypeDescriptor(bogus_array.ElementType); if (bogus_array.VarianceDescriptor.IsValid && bogus_array.VarianceDescriptor.ValidateCorrelation() && !bogus_array.ConformanceDescriptor.IsValid && element_type.Constructed) { // For now we only support constructed types with variance and no conformance. // The variance also needs to be a constant or a normal correlation. return(new RpcTypeDescriptor(new CodeTypeReference(element_type.CodeType, 1), false, "ReadVaryingBogusArrayStruct", true, "WriteVaryingBogusArrayStruct", type, null, bogus_array.VarianceDescriptor) { FixedCount = bogus_array.ElementCount }); } } var type_name_arg = new RpcMarshalArgument() { CodeType = new CodeTypeReference(typeof(string)), Expression = new CodePrimitiveExpression(type.Format.ToString()) }; return(new RpcTypeDescriptor(typeof(NdrUnsupported), "ReadUnsupported", false, "WriteUnsupported", type, null, null, type_name_arg)); }