private void PopulateReferencePointers( List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList, ulong bufferAddress) { for (int index = 0; index < bufferDataList.Count; ++index) { XDRPCStructArgumentInfo <T> .StructBufferData bufferData = bufferDataList[index]; if (bufferData.Info == null) { if (bufferData.ReferenceIndex != -1) { uint v = (uint)((ulong)this._referenceBufferDataList[bufferData.ReferenceIndex].BufferOffset + bufferAddress); bufferData.Info = (XDRPCArgumentInfo) new XDRPCArgumentInfo <uint>(v, ArgumentType.ByRef); bufferDataList[index] = bufferData; } } else if (bufferData.Info.GetRequiredReferenceSize() > 0) { XDRPCStructArgumentInfo <T> .StructBufferData referenceBufferData = this._referenceBufferDataList[bufferData.ReferenceIndex]; ulong bufferAddress1 = (ulong)referenceBufferData.BufferOffset + bufferAddress; bufferData.Info.SetReferenceAddress(bufferAddress1); referenceBufferData.Info = (XDRPCArgumentInfo) new XDRPCArrayArgumentInfo <byte[]>(bufferData.Info.PackReferenceData(), ArgumentType.ByRef); this._referenceBufferDataList[bufferData.ReferenceIndex] = referenceBufferData; } } }
private void FillPointerBufferData( out XDRPCStructArgumentInfo <T> .StructBufferData data, List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList, int packAttribute) { data = new XDRPCStructArgumentInfo <T> .StructBufferData(); data.BufferSize = MarshalingUtils.SizeOf(typeof(uint)); int packAlignment = this.CalculatePackAlignment(packAttribute, data.BufferSize); data.BufferOffset = this.GetCurrentOffset(bufferDataList, packAlignment); data.ReferenceIndex = this._referenceBufferDataList.Count; data.Info = (XDRPCArgumentInfo)null; }
private void SetNextOffset( List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList, int nextOffset) { if (bufferDataList.Count <= 0) { return; } int index = bufferDataList.Count - 1; XDRPCStructArgumentInfo <T> .StructBufferData bufferData = bufferDataList[index]; bufferData.NextOffset = nextOffset; bufferDataList[index] = bufferData; }
private object UnpackValuesRecursive( Type structType, object structToMarshal, ref List <XDRPCStructArgumentInfo <T> .StructBufferData> .Enumerator bufferEnum) { foreach (FieldInfo field in structType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { Type fieldType = field.FieldType; XDRPCStructArgumentInfo <T> .StructBufferData structBufferData = bufferEnum.Current; if (fieldType == typeof(string) || fieldType.IsArray || fieldType.IsPrimitive) { if (structBufferData.ReferenceIndex != -1) { if (structBufferData.Info.GetRequiredReferenceSize() == 0) { structBufferData = this._referenceBufferDataList[structBufferData.ReferenceIndex]; } if (structBufferData.Info.GetRequiredReferenceSize() > 0) { XDRPCArrayArgumentInfo <byte[]> info = (XDRPCArrayArgumentInfo <byte[]>) this._referenceBufferDataList[structBufferData.ReferenceIndex].Info; structBufferData.Info.UnpackReferenceData(info.Value); } } object obj = this.ValidateArgInfoNullValue(fieldType, structBufferData.Info); field.SetValue(structToMarshal, obj); bufferEnum.MoveNext(); } else if (fieldType.IsValueType) { object obj; if (structBufferData.ReferenceIndex != -1) { List <XDRPCStructArgumentInfo <T> .StructBufferData> .Enumerator enumerator = this._referenceBufferDataList.GetEnumerator(); do { enumerator.MoveNext(); }while (enumerator.Current.Info != this._referenceBufferDataList[structBufferData.ReferenceIndex].Info); obj = this.UnpackValuesRecursive(fieldType, field.GetValue(structToMarshal), ref enumerator); bufferEnum.MoveNext(); } else { obj = this.UnpackValuesRecursive(fieldType, field.GetValue(structToMarshal), ref bufferEnum); } field.SetValue(structToMarshal, obj); } } return(structToMarshal); }
private int GetCurrentOffset( List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList, int packAlignment) { int num = 0; if (bufferDataList.Count > 0) { XDRPCStructArgumentInfo <T> .StructBufferData bufferData = bufferDataList[bufferDataList.Count - 1]; int currOffset = bufferData.NextOffset; if (currOffset == 0) { currOffset = bufferData.BufferOffset + bufferData.BufferSize; } num = this.AlignOffset(currOffset, packAlignment); } return(num); }
public static T ExecuteRPC <T>( this IXboxConsole console, XDRPCExecutionOptions options, out ulong postMethodCallReturn, params XDRPCArgumentInfo[] args) where T : struct { Type t = typeof(T); postMethodCallReturn = 0UL; if (!XDRPCMarshaler.IsValidReturnType(t)) { if (!t.IsValueType) { throw new XDRPCInvalidReturnTypeException(t); } XDRPCStructArgumentInfo <T> structArgumentInfo = new XDRPCStructArgumentInfo <T>(default(T), ArgumentType.Out); XDRPCArgumentInfo[] xdrpcArgumentInfoArray = new XDRPCArgumentInfo[args.Length + 1]; xdrpcArgumentInfoArray[0] = (XDRPCArgumentInfo)structArgumentInfo; Array.Copy((Array)args, 0, (Array)xdrpcArgumentInfoArray, 1, args.Length); int num = (int)XDRPCMarshaler.ExecuteRPC <uint>(console, options, xdrpcArgumentInfoArray); return(structArgumentInfo.Value); } XDRPCExecutionState.XDRPCCallFlags flags = XDRPCExecutionState.XDRPCCallFlags.IntegerReturn; if (t == typeof(float) || t == typeof(double)) { flags = XDRPCExecutionState.XDRPCCallFlags.FloatingPointReturn; } XDRPCExecutionState xdrpcExecutionState = new XDRPCExecutionState(console, options, args, flags); xdrpcExecutionState.NoDevkit = XDRPCMarshaler.NoDevkit; xdrpcExecutionState.Invoke(); if (options.PostMethodCall != XDRPCPostMethodCall.None) { postMethodCallReturn = xdrpcExecutionState.PostMethodCallReturnValue; } object obj = XDRPCMarshaler.UnpackReturnType(t, xdrpcExecutionState.ReturnValue); if (obj == null) { return(default(T)); } return((T)obj); }
private void CalculateNextOffset( List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList, int packAlignment) { if (bufferDataList.Count <= 0) { return; } int index = bufferDataList.Count - 1; XDRPCStructArgumentInfo <T> .StructBufferData bufferData = bufferDataList[index]; int currOffset = bufferData.NextOffset; if (currOffset == 0) { currOffset = bufferData.BufferOffset + bufferData.BufferSize; } bufferData.NextOffset = this.AlignOffset(currOffset, packAlignment); bufferDataList[index] = bufferData; }
private bool FillUnionBufferData( ref XDRPCStructArgumentInfo <T> .StructBufferData data, FieldInfo fieldInfo, string unionWritingField) { bool flag = false; if (!string.IsNullOrEmpty(unionWritingField)) { data.BufferOffset = 0; if (unionWritingField != fieldInfo.Name) { data.Ignore = true; } else { flag = true; } } return(flag); }
private int PopulateStructBufferRecursive( Type structType, object structToMarshal, List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList, int depth, string unionWritingField) { if (depth > 3) { throw new XDRPCInvalidTypeException(structType, string.Format("Struct of type {0} has too many nested structs (more than {1} deep) which is not supported.", (object)typeof(T).Name, (object)3)); } if (!((IEnumerable <Type>)XDRPCStructArgumentInfo <T> .builtInStructAllowlist).Contains <Type>(structType)) { object[] customAttributes = structType.GetCustomAttributes(typeof(XDRPCStructAttribute), false); if (customAttributes == null || customAttributes.Length == 0) { throw new XDRPCInvalidTypeException(structType, string.Format("Struct of type {0} doesn't have the XDRPCStruct attribute.", (object)structType.Name)); } } FieldInfo[] fields = structType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int packAttribute = structType.StructLayoutAttribute.Value == LayoutKind.Sequential ? 8 : structType.StructLayoutAttribute.Pack; int num1 = 0; int num2 = 0; bool flag1 = false; foreach (FieldInfo fieldInfo in fields) { Type fieldType = fieldInfo.FieldType; MarshalAsAttribute marshalAsAttribute = (MarshalAsAttribute)null; XDRPCStructArgumentInfo <T> .StructBufferData data = new XDRPCStructArgumentInfo <T> .StructBufferData(); object[] customAttributes1 = fieldInfo.GetCustomAttributes(typeof(MarshalAsAttribute), false); if (customAttributes1 != null && customAttributes1.Length != 0) { marshalAsAttribute = (MarshalAsAttribute)customAttributes1[0]; } if (fieldType == typeof(string) || fieldType.IsArray) { if (marshalAsAttribute == null) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} of type {1} in struct type {2} doesn't have the required MarshalAsAttribute.", (object)fieldInfo.Name, (object)fieldType.Name, (object)structType.Name)); } if (marshalAsAttribute.Value != UnmanagedType.ByValArray && marshalAsAttribute.Value != UnmanagedType.LPArray) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} of type {1} in struct type {2} with its MarshalAs attribute not using the required UnmanagedType.ByValArray or UnmanagedType.LPArray.", (object)fieldInfo.Name, (object)fieldType.Name, (object)structType.Name)); } bool flag2 = marshalAsAttribute.Value == UnmanagedType.LPArray; int size = marshalAsAttribute.SizeConst; int num3; int cMax; if (fieldType.IsArray) { if (fieldType.GetArrayRank() > 1) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is a multidimensional array which is not supported by XDRPCStructArgumentInfo.", (object)fieldInfo.Name, (object)structType.Name)); } Type elementType = fieldType.GetElementType(); if (!XDRPCMarshaler.IsValidValueType(elementType)) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is an array of type {2} which is not supported by XDRPCStructArgumentInfo.", (object)fieldInfo.Name, (object)structType.Name, (object)elementType.Name)); } int num4 = MarshalingUtils.SizeOf(elementType); if (num4 == 0) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is an array of type {2} which is not supported by XDRPCStructArgumentInfo.", (object)fieldInfo.Name, (object)structType.Name, (object)elementType.Name)); } num3 = num4; if (XDRPCMarshaler.IsValidStructType(elementType)) { num3 = MarshalingUtils.AlignmentOf(elementType); } Array array = (Array)fieldInfo.GetValue(structToMarshal); if (flag2) { if (array != null && size < array.Length) { size = array.Length; } } else if (size == 0) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is an array being passed by value that doesn't have the required SizeConst part of the attribute defined.", (object)fieldInfo.Name, (object)structType.Name)); } cMax = num4 * size; data.Info = XDRPCMarshaler.GenerateArgumentInfo(fieldType, (object)array, ArgumentType.ByRef, size); } else { if (!XDRPCStructArgumentInfo <T> .EncodingMap.ContainsKey(marshalAsAttribute.ArraySubType)) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is a string with a MarshalAs attribute without a string UnmanagedType for its ArraySubType.", (object)fieldInfo.Name, (object)structType.Name)); } Encoding encoding = XDRPCStructArgumentInfo <T> .EncodingMap[marshalAsAttribute.ArraySubType]; int num4 = encoding == Encoding.Unicode ? 2 : 1; num3 = num4; cMax = size * num4; string v = (string)fieldInfo.GetValue(structToMarshal); if (flag2) { int num5 = 0; if (v != null) { num5 = encoding.GetByteCount(v + "\0"); } if (cMax < num5) { cMax = num5; } } else if (cMax == 0) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is a string being passed by value that doesn't have the required SizeConst part of the attribute defined.", (object)fieldInfo.Name, (object)structType.Name)); } data.Info = (XDRPCArgumentInfo) new XDRPCStringArgumentInfo(v, encoding, ArgumentType.ByRef, cMax, CountType.Byte); } int requiredReferenceSize = data.Info.GetRequiredReferenceSize(); if (requiredReferenceSize > 0) { XDRPCStructArgumentInfo <T> .StructBufferData structBufferData = new XDRPCStructArgumentInfo <T> .StructBufferData(); structBufferData.BufferOffset = this.GetCurrentOffset(this._referenceBufferDataList, 8); structBufferData.BufferSize = requiredReferenceSize; structBufferData.ReferenceIndex = -1; structBufferData.Info = (XDRPCArgumentInfo)null; data.ReferenceIndex = this._referenceBufferDataList.Count; this._referenceBufferDataList.Add(structBufferData); } else { data.ReferenceIndex = -1; } data.BufferSize = cMax; if (flag2) { if (cMax > 0) { XDRPCStructArgumentInfo <T> .StructBufferData structBufferData = data; structBufferData.BufferOffset = this.GetCurrentOffset(this._referenceBufferDataList, num3); this.FillPointerBufferData(out data, bufferDataList, packAttribute); this._referenceBufferDataList.Add(structBufferData); } else { this.FillPointerBufferData(out data, bufferDataList, packAttribute); data.Info = (XDRPCArgumentInfo) new XDRPCArgumentInfo <uint>(0U, ArgumentType.ByRef); data.ReferenceIndex = -1; } num3 = data.BufferSize; } else { int packAlignment = this.CalculatePackAlignment(packAttribute, num3); data.BufferOffset = this.GetCurrentOffset(bufferDataList, packAlignment); } num1 = Math.Max(num1, num3); num2 = Math.Max(num2, data.BufferSize); if (this.FillUnionBufferData(ref data, fieldInfo, unionWritingField)) { flag1 = true; } bufferDataList.Add(data); } else if (fieldType.IsPrimitive) { int num3 = MarshalingUtils.SizeOf(fieldType); if (num3 == 0) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Field {0} in struct type {1} is primitive type {2} which is not supported by XDRPCStructArgumentInfo.", (object)fieldInfo.Name, (object)structType.Name, (object)fieldType.Name)); } data.Info = XDRPCMarshaler.GenerateArgumentInfo(fieldType, fieldInfo.GetValue(structToMarshal), ArgumentType.ByRef); if (marshalAsAttribute != null && marshalAsAttribute.Value == UnmanagedType.LPStruct) { XDRPCStructArgumentInfo <T> .StructBufferData structBufferData = new XDRPCStructArgumentInfo <T> .StructBufferData(); structBufferData.Info = data.Info; structBufferData.BufferOffset = this.GetCurrentOffset(this._referenceBufferDataList, num3); structBufferData.BufferSize = num3; structBufferData.ReferenceIndex = -1; this.FillPointerBufferData(out data, bufferDataList, packAttribute); this._referenceBufferDataList.Add(structBufferData); } else { int packAlignment = this.CalculatePackAlignment(packAttribute, num3); data.BufferOffset = this.GetCurrentOffset(bufferDataList, packAlignment); data.BufferSize = num3; data.ReferenceIndex = -1; } num1 = Math.Max(num1, data.BufferSize); num2 = Math.Max(num2, data.BufferSize); if (this.FillUnionBufferData(ref data, fieldInfo, unionWritingField)) { flag1 = true; } bufferDataList.Add(data); } else { if (!fieldType.IsValueType) { throw new XDRPCInvalidTypeException(fieldType, string.Format("Type {0} found in struct type {1} is not supported by XDRPCStructArgumentInfo.", (object)fieldType.Name, (object)structType.Name)); } List <XDRPCStructArgumentInfo <T> .StructBufferData> bufferDataList1 = new List <XDRPCStructArgumentInfo <T> .StructBufferData>(); string empty = string.Empty; object[] customAttributes2 = fieldInfo.GetCustomAttributes(typeof(XDRPCUnionAttribute), false); if (customAttributes2 != null && customAttributes2.Length != 0) { empty = ((XDRPCUnionAttribute)customAttributes2[0]).Value; } int num3 = this.PopulateStructBufferRecursive(fieldType, fieldInfo.GetValue(structToMarshal), bufferDataList1, depth + 1, empty); if (marshalAsAttribute != null && marshalAsAttribute.Value == UnmanagedType.LPStruct) { this.FillPointerBufferData(out data, bufferDataList, packAttribute); if (this.FillUnionBufferData(ref data, fieldInfo, unionWritingField)) { flag1 = true; } bufferDataList.Add(data); int currentOffset = this.GetCurrentOffset(this._referenceBufferDataList, 8); for (int index = 0; index < bufferDataList1.Count; ++index) { XDRPCStructArgumentInfo <T> .StructBufferData structBufferData = bufferDataList1[index]; structBufferData.BufferOffset += currentOffset; if (structBufferData.NextOffset != 0) { structBufferData.NextOffset += currentOffset; } this._referenceBufferDataList.Add(structBufferData); } num1 = data.BufferSize; } else { data.BufferOffset = this.GetCurrentOffset(bufferDataList, this.CalculatePackAlignment(packAttribute, num3)); if (this.FillUnionBufferData(ref data, fieldInfo, unionWritingField)) { flag1 = true; } for (int index = 0; index < bufferDataList1.Count; ++index) { XDRPCStructArgumentInfo <T> .StructBufferData structBufferData = bufferDataList1[index]; structBufferData.BufferOffset += data.BufferOffset; if (structBufferData.NextOffset != 0) { data.BufferSize = structBufferData.NextOffset; structBufferData.NextOffset += data.BufferOffset; } if (data.Ignore) { structBufferData.Ignore = true; } bufferDataList.Add(structBufferData); } } num1 = Math.Max(num1, num3); num2 = Math.Max(num2, data.BufferSize); } } if (!string.IsNullOrEmpty(unionWritingField)) { if (!flag1) { throw new XDRPCInvalidTypeException(structType, string.Format("Struct of type {0} has the XDRPCUnion attribute with the non-existant field {1} specified, please provide a correct field name.", (object)structType.Name, (object)unionWritingField)); } this.SetNextOffset(bufferDataList, num2); } int packAlignment1 = this.CalculatePackAlignment(packAttribute, num1); this.CalculateNextOffset(bufferDataList, packAlignment1); return(packAlignment1); }