| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef IPC_IPC_CHANNEL_WIN_H_ |
| #define IPC_IPC_CHANNEL_WIN_H_ |
| |
| #include "ipc/ipc_channel.h" |
| |
| #include <queue> |
| #include <string> |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/win/scoped_handle.h" |
| #include "ipc/ipc_channel_reader.h" |
| |
| namespace base { |
| class ThreadChecker; |
| } |
| |
| namespace IPC { |
| |
| class ChannelWin : public Channel, |
| public internal::ChannelReader, |
| public base::MessageLoopForIO::IOHandler { |
| public: |
| // Mirror methods of Channel, see ipc_channel.h for description. |
| // |broker| must outlive the newly created object. |
| ChannelWin(const IPC::ChannelHandle& channel_handle, |
| Mode mode, |
| Listener* listener, |
| AttachmentBroker* broker); |
| ~ChannelWin() override; |
| |
| // Channel implementation |
| bool Connect() override; |
| void Close() override; |
| bool Send(Message* message) override; |
| AttachmentBroker* GetAttachmentBroker() override; |
| base::ProcessId GetPeerPID() const override; |
| base::ProcessId GetSelfPID() const override; |
| |
| static bool IsNamedServerInitialized(const std::string& channel_id); |
| |
| |
| private: |
| // ChannelReader implementation. |
| ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override; |
| bool ShouldDispatchInputMessage(Message* msg) override; |
| bool GetNonBrokeredAttachments(Message* msg) override; |
| bool DidEmptyInputBuffers() override; |
| void HandleInternalMessage(const Message& msg) override; |
| base::ProcessId GetSenderPID() override; |
| bool IsAttachmentBrokerEndpoint() override; |
| |
| static const base::string16 PipeName(const std::string& channel_id, |
| int32* secret); |
| bool CreatePipe(const IPC::ChannelHandle &channel_handle, Mode mode); |
| |
| bool ProcessConnection(); |
| bool ProcessOutgoingMessages(base::MessageLoopForIO::IOContext* context, |
| DWORD bytes_written); |
| |
| // Returns |false| on channel error. |
| // If |message| has brokerable attachments, those attachments are passed to |
| // the AttachmentBroker (which in turn invokes Send()), so this method must |
| // be re-entrant. |
| // Adds |message| to |output_queue_| and calls ProcessOutgoingMessages(). |
| bool ProcessMessageForDelivery(Message* message); |
| |
| // Moves all messages from |prelim_queue_| to |output_queue_| by calling |
| // ProcessMessageForDelivery(). |
| void FlushPrelimQueue(); |
| |
| // MessageLoop::IOHandler implementation. |
| void OnIOCompleted(base::MessageLoopForIO::IOContext* context, |
| DWORD bytes_transfered, |
| DWORD error) override; |
| |
| private: |
| struct State { |
| explicit State(ChannelWin* channel); |
| ~State(); |
| base::MessageLoopForIO::IOContext context; |
| bool is_pending; |
| }; |
| |
| State input_state_; |
| State output_state_; |
| |
| base::win::ScopedHandle pipe_; |
| |
| base::ProcessId peer_pid_; |
| |
| // Messages not yet ready to be sent are queued here. Messages removed from |
| // this queue are placed in the output_queue_. The double queue is |
| // unfortunate, but is necessary because messages with brokerable attachments |
| // can generate multiple messages to be sent (possibly from other channels). |
| // Some of these generated messages cannot be sent until |peer_pid_| has been |
| // configured. |
| // As soon as |peer_pid| has been configured, there is no longer any need for |
| // |prelim_queue_|. All messages are flushed, and no new messages are added. |
| std::queue<Message*> prelim_queue_; |
| |
| // Messages to be sent are queued here. |
| std::queue<Message*> output_queue_; |
| |
| // In server-mode, we have to wait for the client to connect before we |
| // can begin reading. We make use of the input_state_ when performing |
| // the connect operation in overlapped mode. |
| bool waiting_connect_; |
| |
| // This flag is set when processing incoming messages. It is used to |
| // avoid recursing through ProcessIncomingMessages, which could cause |
| // problems. TODO(darin): make this unnecessary |
| bool processing_incoming_; |
| |
| // Determines if we should validate a client's secret on connection. |
| bool validate_client_; |
| |
| // Tracks the lifetime of this object, for debugging purposes. |
| uint32 debug_flags_; |
| |
| // This is a unique per-channel value used to authenticate the client end of |
| // a connection. If the value is non-zero, the client passes it in the hello |
| // and the host validates. (We don't send the zero value fto preserve IPC |
| // compatability with existing clients that don't validate the channel.) |
| int32 client_secret_; |
| |
| scoped_ptr<base::ThreadChecker> thread_check_; |
| |
| // |broker_| must outlive this instance. |
| AttachmentBroker* broker_; |
| |
| base::WeakPtrFactory<ChannelWin> weak_factory_; |
| DISALLOW_COPY_AND_ASSIGN(ChannelWin); |
| }; |
| |
| } // namespace IPC |
| |
| #endif // IPC_IPC_CHANNEL_WIN_H_ |