/// <summary> /// Callback function to allocate memory, used by NDR engine. /// Copied from midl.exe generated stub code. /// </summary> /// <param name="s">Buffer size.</param> /// <returns>Pointer to allocated memory.</returns> private static IntPtr MIDL_user_allocate(uint s) { IntPtr pcAllocated = Marshal.AllocHGlobal((int)s + 15); IntPtr pcUserPtr; // NDR engine will pad buffer according to NDR standard, // and leaves the padding as uninitialized. // So, to get consistency across test runs, // we must manually fill the allocated buffer with 0. for (int i = 0; i < (int)s + 15; i++) { Marshal.WriteByte(IntPtrUtility.Add(pcAllocated, i), 0x0); } // align to 8 pcUserPtr = IntPtrUtility.Align(pcAllocated, 8); if (pcUserPtr == pcAllocated) { pcUserPtr = IntPtrUtility.Add(pcAllocated, 8); } // record the offset byte offset = (byte)IntPtrUtility.CalculateOffset(pcUserPtr, pcAllocated); Marshal.WriteByte(IntPtrUtility.Add(pcUserPtr, -1), offset); return(pcUserPtr); }
/// <summary> /// Unmarshal a primitive type. /// </summary> /// <param name="type">Data type</param> /// <returns>Pointer to memory where pointer be unmarshalled.</returns> private IntPtr NdrUnmarshal(Type type) { int size = Marshal.SizeOf(type); int offset = Marshal.OffsetOf(typeof(NativeMethods.MIDL_STUB_MESSAGE), "Buffer").ToInt32(); IntPtr ptr = Marshal.ReadIntPtr(pStubMsg, offset); ptr = IntPtrUtility.Align(ptr, size); Marshal.WriteIntPtr( pStubMsg, offset, IntPtrUtility.Add(ptr, size)); return(ptr); }
public IntPtr NdrContextHandleUnmarshall(IntPtr contextHandle, int formatStringOffset) { // offset + 1 contains the flag of isHandlePtr. // offset + 3 contains the flag of isHandleComplex. IntPtr pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset + 1); bool isHandlePtr = (Marshal.ReadByte(pFormat) & 0x80) != 0; pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset + 3); bool isHandleComplex = (Marshal.ReadByte(pFormat) & 0x80) != 0; if ((isHandleComplex || isHandlePtr) && contextHandle != IntPtr.Zero) { contextHandle = Marshal.ReadIntPtr(contextHandle); } //Release old context handle. if (contextHandle != IntPtr.Zero) { Marshal.FreeHGlobal(contextHandle); } //Unmarshal int offset = Marshal.OffsetOf(typeof(NativeMethods.MIDL_STUB_MESSAGE), "Buffer").ToInt32(); IntPtr ptr = Marshal.ReadIntPtr(pStubMsg, offset); ptr = IntPtrUtility.Align(ptr, CONTEXT_HANDLE_ALIGNMENT); Marshal.WriteIntPtr( pStubMsg, offset, IntPtrUtility.Add(ptr, CONTEXT_HANDLE_WIRE_SIZE)); bool isZeroContextHandle = true; for (int i = 0; i < CONTEXT_HANDLE_WIRE_SIZE; i += sizeof(Int32)) { if (Marshal.ReadInt32(IntPtrUtility.Add(ptr, i)) != 0) { isZeroContextHandle = false; break; } } IntPtr contextPtr; if (isZeroContextHandle) { contextPtr = IntPtr.Zero; } else { contextPtr = Marshal.AllocHGlobal(CONTEXT_HANDLE_WIRE_SIZE); NativeMethods.RtlMoveMemory(contextPtr, ptr, CONTEXT_HANDLE_WIRE_SIZE); } if (isHandleComplex || isHandlePtr) { ptr = Marshal.AllocHGlobal(IntPtr.Size); FreeMemoryAtDispose(ptr); Marshal.WriteIntPtr(ptr, contextPtr); contextPtr = ptr; } return(contextPtr); }