예제 #1
0
        /// <summary>
        /// SWN client invoke WitnessrGetInterfaceList method to retrieve information about the interfaces to which witness client connections can be made.
        /// </summary>
        /// <param name="InterfaceList">A pointer to a PWITNESS_INTERFACE_LIST, as specified in section 2.2.1.9.</param>
        /// <returns>Return zero if success, otherwise return nonzero.</returns>
        public int WitnessrGetInterfaceList(out WITNESS_INTERFACE_LIST InterfaceList)
        {
            Int3264[] paramList;
            int       retVal = 0;

            paramList = new Int3264[] {
                IntPtr.Zero, //out param
                IntPtr.Zero  //return value
            };

            using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SWN_OPNUM.WitnessrGetInterfaceList))
            {
                WITNESS_INTERFACE_LIST_RPC rpcList  = TypeMarshal.ToStruct <WITNESS_INTERFACE_LIST_RPC>(Marshal.ReadIntPtr(outParamList[0]));
                WITNESS_INTERFACE_INFO[]   infoList = new WITNESS_INTERFACE_INFO[rpcList.NumberOfInterfaces];
                int sizeInByte = Marshal.SizeOf(typeof(WITNESS_INTERFACE_INFO));
                for (int i = 0; i < rpcList.NumberOfInterfaces; i++)
                {
                    IntPtr pInfo = IntPtrUtility.Add(rpcList.InterfaceInfo, i * sizeInByte);
                    infoList[i] = (WITNESS_INTERFACE_INFO)Marshal.PtrToStructure(pInfo, typeof(WITNESS_INTERFACE_INFO));
                }

                InterfaceList = new WITNESS_INTERFACE_LIST();
                InterfaceList.NumberOfInterfaces = rpcList.NumberOfInterfaces;
                InterfaceList.InterfaceInfo      = infoList;

                retVal = outParamList[paramList.Length - 1].ToInt32();
            }
            return(retVal);
        }
        /// <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>
        /// Callback function to free allocated memory , used by NDR engine.
        /// Copied from midl.exe generated stub code.
        /// </summary>
        /// <param name="f">Pointer to allocated memory.</param>
        private static void MIDL_user_free(IntPtr f)
        {
            byte   offset      = Marshal.ReadByte(IntPtrUtility.Add(f, -1));
            IntPtr pcAllocated = IntPtrUtility.Add(f, -offset);

            Marshal.FreeHGlobal(pcAllocated);
        }
예제 #4
0
        /// <summary>
        /// Unmarshalls a non encapsulated union.
        /// </summary>
        /// <param name="formatStringOffset">Offset of the type format string</param>
        /// <param name="mustAlloc">Ignored</param>
        /// <returns>Double pointer to where the union should be unmarshalled.</returns>
        public IntPtr NdrNonEncapsulatedUnionUnmarshall(int formatStringOffset, byte mustAlloc)
        {
            IntPtr pValue  = IntPtr.Zero;
            IntPtr pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);

            NativeMethods.NdrNonEncapsulatedUnionUnmarshall(pStubMsg, ref pValue, pFormat, mustAlloc);
            return(pValue);
        }
예제 #5
0
        /// <summary>
        /// The NdrPointerUnmarshall function unmarshalls a top level pointer to anything.
        /// Pointers embedded in structures, arrays, or unions call NdrPointerUnmarshall directly.
        /// </summary>
        /// <param name="formatStringOffset">Offset of the type format string</param>
        /// <returns>Pointer to memory where pointer be unmarshalled.</returns>
        public IntPtr NdrPointerUnmarshall(int formatStringOffset)
        {
            IntPtr pValue  = IntPtr.Zero;
            IntPtr pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);

            NativeMethods.NdrPointerUnmarshall(pStubMsg, ref pValue, pFormat, 0);
            return(pValue);
        }
예제 #6
0
        /// <summary>
        /// Unmarshalls a conformant varying structure.
        /// </summary>
        /// <param name="formatStringOffset">Offset of the type format string</param>
        /// <param name="mustAlloc">Ignored.</param>
        /// <returns>Pointer to memory where pointer be unmarshalled.</returns>
        public IntPtr NdrConformantVaryingStructUnmarshall(int formatStringOffset, byte mustAlloc)
        {
            IntPtr pValue  = IntPtr.Zero;
            IntPtr pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);

            NativeMethods.NdrConformantVaryingStructUnmarshall(pStubMsg, ref pValue, pFormat, mustAlloc);

            return(pValue);
        }
예제 #7
0
        /*/// <summary>
         * /// Unmarshalls a transmit as or represent as argument.
         * /// </summary>
         * /// <param name="formatStringOffset">Offset of the type format string</param>
         * /// <param name="mustAlloc">Ignored.</param>
         * /// <returns>Pointer to memory where pointer be unmarshalled.</returns>
         * public IntPtr NdrXmitOrRepAsUnmarshall(int formatStringOffset, byte mustAlloc)
         * {
         *  IntPtr pValue = IntPtr.Zero;
         *  IntPtr pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);
         *  NativeMethods.NdrXmitOrRepAsUnmarshall(pStubMsg, ref pValue, pFormat, mustAlloc);
         *
         *  return pValue;
         * }*/


        /// <summary>
        /// Unmarshalls a byte count pointer.
        /// </summary>
        /// <param name="formatStringOffset">Offset of the type format string</param>
        /// <param name="pMemory">Client allocated memory</param>
        /// <param name="mustAlloc">Ignored.</param>
        /// <returns>Pointer to memory where pointer be unmarshalled.</returns>
        public IntPtr NdrByteCountPointerUnmarshall(int formatStringOffset, IntPtr pMemory, byte mustAlloc)
        {
            IntPtr pValue  = pMemory;
            IntPtr pFormat = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);

            NativeMethods.NdrByteCountPointerUnmarshall(pStubMsg, ref pValue, pFormat, mustAlloc);

            return(pValue);
        }
예제 #8
0
        public IntPtr NdrRangeUnmarshall(int formatStringOffset)
        {
            // offset + 1 is the place of real format string of this parameter.
            IntPtr             pFormat    = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset + 1);
            RpceFormatCharType formatChar = (RpceFormatCharType)Marshal.ReadByte(pFormat);

            //Range is base type only.
            //pArg is ignored for base types.
            IntPtr pValue = NdrUnmarshalRoutines(IntPtr.Zero, formatStringOffset, formatChar);

            return(pValue);
        }
예제 #9
0
        public IntPtr NdrSupplementUnmarshall(IntPtr pArg, int formatStringOffset, byte mustAlloc)
        {
            // offset + 2 is the size of supplement header size (ushort), skip the size.
            formatStringOffset += 2;
            IntPtr pFormat          = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);
            int    supplementOffset = Marshal.ReadInt16(pFormat);

            formatStringOffset += supplementOffset;
            pFormat             = IntPtrUtility.Add(pFormat, supplementOffset);
            RpceFormatCharType formatChar = (RpceFormatCharType)Marshal.ReadByte(pFormat);

            return(NdrUnmarshalRoutines(pArg, formatStringOffset, formatChar));
        }
예제 #10
0
        /// <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);
        }
        /// <summary>
        /// The NdrConvert function converts the network buffer from the data representation of
        /// the sender to the data representation of the receiver if they are different.
        /// </summary>
        /// <param name="formatStringOffset">Offset of a parameter in typeFormatString.</param>
        public void NdrConvertIfNecessary(int formatStringOffset)
        {
            IntPtr offset;

            offset = Marshal.OffsetOf(typeof(NativeMethods.MIDL_STUB_MESSAGE), "RpcMsg");
            IntPtr pRpcMsg = Marshal.ReadIntPtr(pStubMsg, offset.ToInt32());

            offset = Marshal.OffsetOf(typeof(NativeMethods.RPC_MESSAGE), "DataRepresentation");
            uint dataRepresentation = (uint)Marshal.ReadInt32(pRpcMsg, offset.ToInt32());

            if ((dataRepresentation & 0x0000FFFFU) != NativeMethods.NDR_LOCAL_DATA_REPRESENTATION)
            {
                IntPtr fmt = IntPtrUtility.Add(stubDesc.pFormatTypes, formatStringOffset);
                NativeMethods.NdrConvert(pStubMsg, fmt);
            }
        }
예제 #12
0
        /// <summary>
        /// Initialize NDR server context.
        /// </summary>
        public void NdrServerInitializeNew()
        {
            NativeMethods.RPC_MESSAGE rpcMessage = new NativeMethods.RPC_MESSAGE();
            rpcMessage.Buffer             = pBytesToDecode;
            rpcMessage.BufferLength       = (uint)bytesToDecodeLength;
            rpcMessage.DataRepresentation = dataRepresentationFormat;
            rpcMessage.RpcFlags           = NativeMethods.RPC_BUFFER_COMPLETE;
            pRpcMsg = Marshal.AllocHGlobal(Marshal.SizeOf(rpcMessage));
            Marshal.StructureToPtr(rpcMessage, pRpcMsg, false);

            NativeMethods.MIDL_STUB_MESSAGE stubMsg = new NativeMethods.MIDL_STUB_MESSAGE();
            stubMsg.Buffer       = rpcMessage.Buffer;
            stubMsg.BufferStart  = rpcMessage.Buffer;
            stubMsg.BufferLength = rpcMessage.BufferLength;
            stubMsg.BufferEnd    = IntPtrUtility.Add(stubMsg.BufferStart, (int)stubMsg.BufferLength);
            pStubMsg             = Marshal.AllocHGlobal(Marshal.SizeOf(stubMsg));
            Marshal.StructureToPtr(stubMsg, pStubMsg, false);

            pStubDesc = Marshal.AllocHGlobal(Marshal.SizeOf(stubDesc));
            Marshal.StructureToPtr(stubDesc, pStubDesc, false);

            NativeMethods.NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDesc);
        }
예제 #13
0
        /// <summary>
        /// This function converts the network buffer from the data representation of
        /// the sender to the data representation of the receiver if they are different.
        /// </summary>
        /// <param name="procFormatString">Proc format string generated by MIDL.</param>
        /// <param name="formatStringOffset">Offset of a parameter in typeFormatString.</param>
        /// <param name="numberParams">The number of parameters in the procedure.</param>
        /// <param name="isClient">Is client side.</param>
        public void NdrConvertIfNecessary(byte[] procFormatString, int formatStringOffset, long numberParams, bool isClient)
        {
            IntPtr offset;

            offset = Marshal.OffsetOf(typeof(NativeMethods.MIDL_STUB_MESSAGE), "RpcMsg");
            IntPtr pRpcMsg = Marshal.ReadIntPtr(pStubMsg, offset.ToInt32());

            offset = Marshal.OffsetOf(typeof(NativeMethods.RPC_MESSAGE), "DataRepresentation");
            uint dataRepresentation = (uint)Marshal.ReadInt32(pRpcMsg, offset.ToInt32());

            if ((dataRepresentation & 0x0000FFFFU) == NativeMethods.NDR_LOCAL_DATA_REPRESENTATION)
            {
                return;
            }

            if (isClient)
            {
                IntPtr pFormat = Marshal.AllocHGlobal(procFormatString.Length);
                Marshal.Copy(procFormatString, 0, pFormat, procFormatString.Length);
                IntPtr fmt = IntPtrUtility.Add(pFormat, formatStringOffset);

                // We use server stub when decoding, so pStubMsg->IsClient is false.
                // However, this flag is used when doing endian convert. So we save it first and
                // then set it to true and convert back.
                //
                // NdrConvert2 is the entry point for endian conversion of all parameters. We use
                // NdrConvert2 here instead of calling the type specific convert routine ourselves
                // (like what we do in marshal/unmarshal), because convert routines for each type
                // are not exported in rpcrt4.dll, unlike marshal/unmarshal routines.
                bool stubIsClientSaved = GetIsClient();
                SetIsClient(isClient);
                NativeMethods.NdrConvert2(pStubMsg, fmt, numberParams);
                SetIsClient(stubIsClientSaved);

                Marshal.FreeHGlobal(pFormat);
            }
        }
예제 #14
0
        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);
        }