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); } }
internal static IntPtr Alloc(uint size) { IntPtr ptr = NativeMethods.LocalAlloc(LPTR, size); RpcTrace.Verbose("{0} = LocalAlloc({1})", ptr, size); return(ptr); }
internal static void Free(IntPtr ptr) { if (ptr != IntPtr.Zero) { RpcTrace.Verbose("LocalFree({0})", ptr); NativeMethods.LocalFree(ptr); } }
/// <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)); }
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); } }
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); }
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); } }
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); }
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); }