/// <summary> /// Decode byte array to parameter list in one method call. /// Calling this method assumes that decoding the stub doesn't depends on any parameter. /// Only for decoding the stub data from the client side. /// </summary> /// <param name="runtimeTargetPlatform">Runtime platform, x86 or amd64.</param> /// <param name="typeFormatString">Type format string generated by MIDL.</param> /// <param name="exprEvalRoutines">ExprEvalRoutines generated by MIDL if exists.</param> /// <param name="procFormatString">Proc format string generated by MIDL.</param> /// <param name="procFormatStringOffset">Offset of the procedure in procFormatString.</param> /// <param name="isClient">Is client side.</param> /// <param name="bytesToDecode">Bytes to decode.</param> /// <returns>The decoded parameter list.</returns> /// <exception cref="ArgumentNullException"> /// Thrown when typeFormatString is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Thrown when runtimeTargetPlatform doesn't match current platform at runtime. /// </exception> public static RpceInt3264Collection ToParamList( RpceStubTargetPlatform runtimeTargetPlatform, byte[] typeFormatString, RpceStubExprEval[] exprEvalRoutines, byte[] procFormatString, int procFormatStringOffset, bool isClient, byte[] bytesToDecode) { int offset = procFormatStringOffset; RpceProcedureHeaderDescriptor procHeaderInfo = RpceStubHelper.ParseProcedureHeaderDescriptor(procFormatString, ref offset); return(ToParamList(runtimeTargetPlatform, typeFormatString, exprEvalRoutines, procFormatString, procFormatStringOffset, isClient, bytesToDecode, new Int3264[procHeaderInfo.NumberOfParams])); }
private Int3264[] NdrParametersUnmarshall( byte[] procFormatString, int offset, bool isClient, params Int3264[] parameters) { if (procFormatString == null) { throw new ArgumentNullException("procFormatString"); } RpceProcedureHeaderDescriptor procHeaderInfo = RpceStubHelper.ParseProcedureHeaderDescriptor(procFormatString, ref offset); if (procHeaderInfo.NumberOfParams != parameters.Length) { throw new InvalidOperationException("Number of parameters doesn't match expectation."); } SaveParametersIntoStack(procFormatString, offset, procHeaderInfo.StackSize, parameters); if ((procHeaderInfo.ExtensionFlags2 & RpceInterpreterOptFlags2.HasConformanceRange) != 0) { SetCorrDespIncrement(RANGED_NDR_CORR_EXTENSION_SIZE); } else { SetCorrDespIncrement(NDR_CORR_EXTENSION_SIZE); } NdrConvertIfNecessary(procFormatString, offset, procHeaderInfo.NumberOfParams, isClient); List <Int3264> parameterList = new List <Int3264>(parameters); for (int i = 0; i < procHeaderInfo.NumberOfParams; i++) { RpceParameterAttributes parameterFlags = (RpceParameterAttributes)BitConverter.ToUInt16(procFormatString, offset); offset += sizeof(RpceParameterAttributes); offset += sizeof(ushort); //skip stack size/top ushort parameterTypeFormatStringOffset = BitConverter.ToUInt16(procFormatString, offset); offset += sizeof(ushort); //move to next parameter. bool sameDirection = (isClient ? (parameterFlags & RpceParameterAttributes.IsOut) : (parameterFlags & RpceParameterAttributes.IsIn)) != 0; if (!sameDirection) { continue; } if ((parameterFlags & RpceParameterAttributes.IsPipe) != 0) { continue; } if (!isClient && (parameterFlags & RpceParameterAttributes.IsPartialIgnore) != 0) { parameterList[i] = NdrInt32Unmarshal() != 0 ? 1 : 0; continue; } RpceFormatCharType formatChar; if ((parameterFlags & RpceParameterAttributes.IsBaseType) != 0) { formatChar = (RpceFormatCharType)parameterTypeFormatStringOffset; } else { formatChar = (RpceFormatCharType)Marshal.ReadByte( stubDesc.pFormatTypes, parameterTypeFormatStringOffset); } parameterList[i] = NdrUnmarshalRoutines(parameters[i], parameterTypeFormatStringOffset, formatChar); if ((parameterFlags & RpceParameterAttributes.IsBaseType) != 0 && (parameterFlags & RpceParameterAttributes.IsSimpleRef) != 0) { IntPtr ptr = Marshal.AllocHGlobal(sizeof(ulong));//ulong is max size of simple type. FreeMemoryAtDispose(ptr); Marshal.WriteIntPtr(ptr, parameterList[i]); parameterList[i] = ptr; } } return(parameterList.ToArray()); }