/// <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()); }
/// <summary> /// Parse procedure header a from byte array to structure. /// </summary> /// <param name="procFormatString">Proc format string.</param> /// <param name="offset">Offset of a procedure in procFormatString.</param> /// <returns>The RpceProcedureHeaderDescriptor.</returns> public static RpceProcedureHeaderDescriptor ParseProcedureHeaderDescriptor( byte[] procFormatString, ref int offset) { //handle_type<1> //Oi_flags<1> //[rpc_flags<4>] //proc_num<2> //stack_size<2> //[explicit_handle_description<>] //constant_client_buffer_size<2> //constant_server_buffer_size<2> //INTERPRETER_OPT_FLAGS<1> //number_of_params<1> //extension_size<1> //[extension] const byte FC_BIND_PRIMITIVE = 0x32; const int PRIMITIVE_HANDLE_LENGTH = 4; const int OTHER_HANDLE_LENGTH = 6; const byte OI_HAS_RPCFLAGS = 0x08; const int EXTENSION_SIZE = 8; RpceProcedureHeaderDescriptor procHeaderDesc = new RpceProcedureHeaderDescriptor(); procHeaderDesc.HandleType = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.HandleType); procHeaderDesc.OiFlags = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.OiFlags); if ((procHeaderDesc.OiFlags & OI_HAS_RPCFLAGS) != 0) { procHeaderDesc.RpcFlags = BitConverter.ToUInt32(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.RpcFlags.Value); } procHeaderDesc.ProcNum = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ProcNum); procHeaderDesc.StackSize = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.StackSize); if (procHeaderDesc.HandleType == 0) // explicit handle { int length = (procFormatString[offset] == FC_BIND_PRIMITIVE) ? PRIMITIVE_HANDLE_LENGTH : OTHER_HANDLE_LENGTH; procHeaderDesc.ExplicitHandleDescription = ArrayUtility.SubArray(procFormatString, offset, length); offset += length; } procHeaderDesc.ClientBufferSize = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ClientBufferSize); procHeaderDesc.ServerBufferSize = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ServerBufferSize); procHeaderDesc.InterpreterOptFlags = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.InterpreterOptFlags); procHeaderDesc.NumberOfParams = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.NumberOfParams); byte extensionSize = procFormatString[offset]; if (extensionSize >= EXTENSION_SIZE) { procHeaderDesc.ExtensionSize = extensionSize; offset += Marshal.SizeOf(procHeaderDesc.ExtensionSize.Value); procHeaderDesc.ExtensionFlags2 = (RpceInterpreterOptFlags2)procFormatString[offset]; offset += Marshal.SizeOf((byte)procHeaderDesc.ExtensionFlags2); procHeaderDesc.ExtensionClientCorrHint = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ExtensionClientCorrHint.Value); procHeaderDesc.ExtensionServerCorrHint = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ExtensionServerCorrHint.Value); procHeaderDesc.ExtensionNotifyIndex = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ExtensionNotifyIndex.Value); offset += extensionSize - EXTENSION_SIZE; } else { offset += extensionSize; } return(procHeaderDesc); }
/// <summary> /// Parse procedure header a from byte array to structure. /// </summary> /// <param name="procFormatString">Proc format string.</param> /// <param name="offset">Offset of a procedure in procFormatString.</param> /// <returns>The RpceProcedureHeaderDescriptor.</returns> public static RpceProcedureHeaderDescriptor ParseProcedureHeaderDescriptor( byte[] procFormatString, ref int offset) { //handle_type<1> //Oi_flags<1> //[rpc_flags<4>] //proc_num<2> //stack_size<2> //[explicit_handle_description<>] //constant_client_buffer_size<2> //constant_server_buffer_size<2> //INTERPRETER_OPT_FLAGS<1> //number_of_params<1> //extension_size<1> //[extension] const byte FC_BIND_PRIMITIVE = 0x32; const int PRIMITIVE_HANDLE_LENGTH = 4; const int OTHER_HANDLE_LENGTH = 6; const byte OI_HAS_RPCFLAGS = 0x08; const int EXTENSION_SIZE = 8; RpceProcedureHeaderDescriptor procHeaderDesc = new RpceProcedureHeaderDescriptor(); procHeaderDesc.HandleType = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.HandleType); procHeaderDesc.OiFlags = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.OiFlags); if ((procHeaderDesc.OiFlags & OI_HAS_RPCFLAGS) != 0) { procHeaderDesc.RpcFlags = BitConverter.ToUInt32(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.RpcFlags.Value); } procHeaderDesc.ProcNum = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ProcNum); procHeaderDesc.StackSize = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.StackSize); if (procHeaderDesc.HandleType == 0) // explicit handle { int length = (procFormatString[offset] == FC_BIND_PRIMITIVE) ? PRIMITIVE_HANDLE_LENGTH : OTHER_HANDLE_LENGTH; procHeaderDesc.ExplicitHandleDescription = ArrayUtility.SubArray(procFormatString, offset, length); offset += length; } procHeaderDesc.ClientBufferSize = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ClientBufferSize); procHeaderDesc.ServerBufferSize = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ServerBufferSize); procHeaderDesc.InterpreterOptFlags = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.InterpreterOptFlags); procHeaderDesc.NumberOfParams = procFormatString[offset]; offset += Marshal.SizeOf(procHeaderDesc.NumberOfParams); byte extensionSize = procFormatString[offset]; if (extensionSize >= EXTENSION_SIZE) { procHeaderDesc.ExtensionSize = extensionSize; offset += Marshal.SizeOf(procHeaderDesc.ExtensionSize.Value); procHeaderDesc.ExtensionFlags2 = (RpceInterpreterOptFlags2)procFormatString[offset]; offset += Marshal.SizeOf((byte)procHeaderDesc.ExtensionFlags2); procHeaderDesc.ExtensionClientCorrHint = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ExtensionClientCorrHint.Value); procHeaderDesc.ExtensionServerCorrHint = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ExtensionServerCorrHint.Value); procHeaderDesc.ExtensionNotifyIndex = BitConverter.ToUInt16(procFormatString, offset); offset += Marshal.SizeOf(procHeaderDesc.ExtensionNotifyIndex.Value); offset += extensionSize - EXTENSION_SIZE; } else { offset += extensionSize; } return procHeaderDesc; }