コード例 #1
0
ファイル: RpcHandle.cs プロジェクト: pombredanne/NDceRpc
        public void Dispose(bool disposing)
        {
            try
            {
                RpcTrace.Verbose("RpcHandle.Dispose on {0}", Handle);

                if (Handle != IntPtr.Zero)
                {
                    DisposeHandle(ref Handle);
                }
                lock (_pinnedAddresses)
                {
                    for (int i = _pinnedAddresses.Count - 1; i >= 0; i--)
                    {
                        _pinnedAddresses[i].Dispose();
                    }
                    _pinnedAddresses.Clear();
                }
            }
            finally
            {
                Handle = IntPtr.Zero;
            }
            if (disposing)
            {
                GC.SuppressFinalize(this);
            }
        }
コード例 #2
0
ファイル: RpcRuntime.cs プロジェクト: pombredanne/NDceRpc
        internal static IntPtr Alloc(uint size)
        {
            IntPtr ptr = NativeMethods.LocalAlloc(LPTR, size);

            RpcTrace.Verbose("{0} = LocalAlloc({1})", ptr, size);
            return(ptr);
        }
コード例 #3
0
ファイル: RpcRuntime.cs プロジェクト: pombredanne/NDceRpc
 internal static void Free(IntPtr ptr)
 {
     if (ptr != IntPtr.Zero)
     {
         RpcTrace.Verbose("LocalFree({0})", ptr);
         NativeMethods.LocalFree(ptr);
     }
 }
コード例 #4
0
 /// <summary>
 /// Sends a message as an array of bytes and retrieves the response from the server, if
 /// AuthenticateAs() has not been called, the client will authenticate as Anonymous.
 /// </summary>
 public byte[] Execute(byte[] input)
 {
     if (!_authenticated)
     {
         RpcTrace.Warning("AuthenticateAs was not called, assuming Anonymous.");
         AuthenticateAs(Anonymous);
     }
     RpcTrace.Verbose("ExplicitBytesExecute(byte[{0}])", input.Length);
     return(InvokeRpc(_handle, IID, input));
 }
コード例 #5
0
 public ExplicitBytesServer(Guid iid, int maxCalls, int maxRequestBytes, bool allowAnonymousCallbacks)
 {
     IID = iid;
     RpcTrace.Verbose("ServerRegisterInterface({0})", iid);
     // Guid.Empty to avoid registration of any interface allowing access to AddProtocol/AddAuthentication
     if (Guid.Empty != iid)
     {
         Ptr <RPC_SERVER_INTERFACE> sIf = ServerInterfaceFactory.Create(_handle, iid, RpcRuntime.TYPE_FORMAT, RpcRuntime.FUNC_FORMAT,
                                                                        RpcEntryPoint);
         this.serverRegisterInterface(sIf, maxCalls, maxRequestBytes, allowAnonymousCallbacks);
     }
 }
コード例 #6
0
ファイル: RpcRuntime.cs プロジェクト: pombredanne/NDceRpc
        static RpcRuntime()
        {
            Is64BitProcess = (IntPtr.Size == 8);
            RpcTrace.Verbose("Is64BitProcess = {0}", Is64BitProcess);

            if (Is64BitProcess)
            {
                //Same as 32-bit except: [8] = 8; [32] = 24;
                TYPE_FORMAT = new byte[39]
                {
                    0x00, 0x00, 0x1b, 0x00, 0x01, 0x00, 0x28, 0x00, 0x08, 0x00,
                    0x01, 0x00, 0x01, 0x5b, 0x11, 0x0c, 0x08, 0x5c, 0x11, 0x14,
                    0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x01, 0x00,
                    0x28, 0x54, 0x18, 0x00, 0x01, 0x00, 0x01, 0x5b, 0x00
                };
                //Very different from 32-bit:
                FUNC_FORMAT = new byte[61]
                {
                    0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,
                    0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x00, 0x47, 0x05,
                    0x0a, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x48, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x10, 0x00,
                    0x02, 0x00, 0x50, 0x21, 0x18, 0x00, 0x08, 0x00, 0x13, 0x20,
                    0x20, 0x00, 0x12, 0x00, 0x70, 0x00, 0x28, 0x00, 0x10, 0x00,
                    0x00
                };
            }
            else
            {
                TYPE_FORMAT = new byte[39]
                {
                    0x00, 0x00, 0x1b, 0x00, 0x01, 0x00, 0x28, 0x00, 0x04, 0x00,
                    0x01, 0x00, 0x01, 0x5b, 0x11, 0x0c, 0x08, 0x5c, 0x11, 0x14,
                    0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x01, 0x00,
                    0x28, 0x54, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x5b, 0x00
                };
                FUNC_FORMAT = new byte[59]
                {
                    0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
                    0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x00, 0x47, 0x05,
                    0x08, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00,
                    0x04, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x02, 0x00,
                    0x50, 0x21, 0x0c, 0x00, 0x08, 0x00, 0x13, 0x20, 0x10, 0x00,
                    0x12, 0x00, 0x70, 0x00, 0x14, 0x00, 0x10, 0x00, 0x00
                };
            }
            FUNC_FORMAT_PTR = new Ptr <byte[]>(FUNC_FORMAT);
        }
コード例 #7
0
        private uint RpcEntryPoint(IntPtr clientHandle, uint szInput, IntPtr input, out uint szOutput, out IntPtr output)
        {
            output   = IntPtr.Zero;
            szOutput = 0;

            try
            {
                byte[] bytesIn = new byte[szInput];
                Marshal.Copy(input, bytesIn, 0, bytesIn.Length);

                byte[] bytesOut;
                using (RpcCallInfo call = new RpcCallInfo(clientHandle))
                {
                    bytesOut = Execute(call, bytesIn);
                }
                if (bytesOut == null)
                {
                    return((uint)RPC_STATUS.RPC_S_NOT_LISTENING);
                }

                szOutput = (uint)bytesOut.Length;
                output   = RpcRuntime.Alloc(szOutput);
                Marshal.Copy(bytesOut, 0, output, bytesOut.Length);

                return((uint)RPC_STATUS.RPC_S_OK);
            }
            catch (Exception ex)
            {
                RpcRuntime.Free(output);
                output   = IntPtr.Zero;
                szOutput = 0;

                RpcTrace.Error(ex);
                return((uint)RPC_STATUS.RPC_E_FAIL);
            }
        }
コード例 #8
0
        private static byte[] InvokeRpc(RpcHandle handle, Guid iid, byte[] input)
        {
            RpcTrace.Verbose("InvokeRpc on {0}, sending {1} bytes", handle.Handle, input.Length);
            Ptr <MIDL_STUB_DESC> pStub;

            if (!handle.GetPtr(out pStub))
            {
                pStub =
                    handle.CreatePtr(new MIDL_STUB_DESC(handle, handle.Pin(ClientInterfaceFactory.CreatExplicitBytesClient(iid)),
                                                        RpcRuntime.TYPE_FORMAT,
                                                        false));
            }
            int    szResponse = 0;
            IntPtr response, result;

            using (Ptr <byte[]> pInputBuffer = new Ptr <byte[]>(input))
            {
                if (RpcRuntime.Is64BitProcess)
                {
                    try
                    {
                        result = NativeMethods.NdrClientCall2x64(pStub.Handle, RpcRuntime.FUNC_FORMAT_PTR.Handle, handle.Handle,
                                                                 input.Length,
                                                                 pInputBuffer.Handle, out szResponse, out response);
                    }
                    catch (SEHException ex)
                    {
                        RpcTrace.Error(ex);
                        Guard.Assert(ex.ErrorCode);
                        throw;
                    }
                }
                else
                {
                    using (Ptr <Int32[]> pStack32 = new Ptr <Int32[]>(new Int32[10]))
                    {
                        pStack32.Data[0] = handle.Handle.ToInt32();
                        pStack32.Data[1] = input.Length;
                        pStack32.Data[2] = pInputBuffer.Handle.ToInt32();
                        pStack32.Data[3] = pStack32.Handle.ToInt32() + (sizeof(int) * 6);
                        pStack32.Data[4] = pStack32.Handle.ToInt32() + (sizeof(int) * 8);
                        pStack32.Data[5] = 0; //reserved
                        pStack32.Data[6] = 0; //output: int dwSizeResponse
                        pStack32.Data[8] = 0; //output: byte* lpResponse

                        try
                        {
                            result = NativeMethods.NdrClientCall2x86(pStub.Handle, RpcRuntime.FUNC_FORMAT_PTR.Handle, pStack32.Handle);
                        }
                        catch (SEHException ex)
                        {
                            RpcTrace.Error(ex);
                            Guard.Assert(ex.ErrorCode);
                            throw;
                        }

                        szResponse = pStack32.Data[6];
                        response   = new IntPtr(pStack32.Data[8]);
                    }
                }
                GC.KeepAlive(pInputBuffer);
            }

            // on local machine
            // if 32 bit server just throws Exception in server side handler
            // then 32 bits client can see "-2147467259" debug view of pointer result
            // then 64 bits client can see "2147500037" debug view of pointer result
            // then 32 bits client can do ToInt32 and things work fine
            // then 64 bits client can do ToInt32 and get arithmetic overflow exception
            // hence using ToInt64 for 64 bits client
            if (IntPtr.Size == 8)
            {
                Guard.Assert(result.ToInt64());
            }
            else
            {
                Guard.Assert(result.ToInt32());
            }

            RpcTrace.Verbose("InvokeRpc.InvokeRpc response on {0}, received {1} bytes", handle.Handle, szResponse);
            byte[] output = new byte[szResponse];
            if (szResponse > 0 && response != IntPtr.Zero)
            {
                Marshal.Copy(response, output, 0, output.Length);
            }
            RpcRuntime.Free(response);

            return(output);
        }
コード例 #9
0
ファイル: RpcCallInfo.cs プロジェクト: pombredanne/NDceRpc
        private RPC_CALL_ATTRIBUTES_V2 GetCallInfo()
        {
            if (_callAttrs.Version != 0)
            {
                return(_callAttrs);
            }
            var attrs = new RPC_CALL_ATTRIBUTES_V2
            {
                Version = 2,
                Flags   = RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_NO_AUTH_REQUIRED
            };
            RPC_STATUS err = NativeMethods.RpcServerInqCallAttributes(_clientHandle, ref attrs);

            if (err == RPC_STATUS.RPC_S_INVALID_ARG) //may not support v2 on early edditions of XP/SP3
            {
                attrs.Version = 1;
                err           = NativeMethods.RpcServerInqCallAttributes(_clientHandle, ref attrs);
            }

            if (err == RPC_STATUS.RPC_S_OK)
            {
                _callAttrs       = attrs;
                _isAuthenticated = false;
                attrs.Flags      = RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_IS_CLIENT_LOCAL |
                                   RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_NO_AUTH_REQUIRED;
                if ((err = NativeMethods.RpcServerInqCallAttributes(_clientHandle, ref attrs)) == RPC_STATUS.RPC_S_OK)
                {
                    _callAttrs.IsClientLocal = attrs.IsClientLocal;

                    if (_callAttrs.ProtocolSequence == RpcProtoseqType.LRPC)
                    {
                        attrs.Flags = RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_CLIENT_PID;
                        if ((err = NativeMethods.RpcServerInqCallAttributes(_clientHandle, ref attrs)) == RPC_STATUS.RPC_S_OK)
                        {
                            _callAttrs.ClientPID = attrs.ClientPID;
                        }
                    }
                }

                if (_callAttrs.ProtocolSequence != RpcProtoseqType.LRPC)
                {
                    using (Ptr <byte[]> callerAddress = new Ptr <byte[]>(new byte[1024]))
                    {
                        var localAddress = new RPC_CALL_LOCAL_ADDRESS_V1();
                        localAddress.Version       = 1;
                        localAddress.Buffer        = callerAddress.Handle;
                        localAddress.BufferSize    = 1024;
                        localAddress.AddressFormat = RpcLocalAddressFormat.Invalid;
                        _callAttrs = attrs;

                        using (var callerAddressv1 = new Ptr <RPC_CALL_LOCAL_ADDRESS_V1>(localAddress))
                        {
                            attrs.CallLocalAddress = callerAddressv1.Handle;
                            attrs.Flags            = RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_CALL_LOCAL_ADDRESS |
                                                     RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_NO_AUTH_REQUIRED;
                            if ((err = NativeMethods.RpcServerInqCallAttributes(_clientHandle, ref attrs)) == RPC_STATUS.RPC_S_OK)
                            {
                                _clientAddress = new byte[callerAddressv1.Data.BufferSize];
                                Array.Copy(callerAddress.Data, _clientAddress, _clientAddress.Length);
                            }
                        }
                    }
                }

                using (Ptr <byte[]> clientPrincipal = new Ptr <byte[]>(new byte[1024]))
                {
                    attrs.ClientPrincipalName             = clientPrincipal.Handle;
                    attrs.ClientPrincipalNameBufferLength = 1024;
                    attrs.Flags = RPC_CALL_ATTRIBUTES_FLAGS.RPC_QUERY_CLIENT_PRINCIPAL_NAME;
                    if ((err = NativeMethods.RpcServerInqCallAttributes(_clientHandle, ref attrs)) == RPC_STATUS.RPC_S_OK)
                    {
                        _clientPrincipalName = Marshal.PtrToStringUni(clientPrincipal.Handle);

                        if (!String.IsNullOrEmpty(_clientPrincipalName))
                        {
                            _isAuthenticated = true;
                            //On Windows XP this only returns a value on LRPC so we know they are local
                            if (attrs.Version == 1)
                            {
                                _callAttrs.IsClientLocal = RpcCallClientLocality.Local;
                            }
                        }
                    }
                }
            }
            else
            {
                RpcTrace.Warning("RpcServerInqCallAttributes error {0} = {1}", err, new RpcException(err).Message);
            }


            return(_callAttrs);
        }