15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef IPC_IPC_CHANNEL_WIN_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_IPC_CHANNEL_WIN_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <queue>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_reader.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ThreadChecker;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Channel::ChannelImpl : public internal::ChannelReader,
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             public base::MessageLoopForIO::IOHandler {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mirror methods of Channel, see ipc_channel.h for description.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChannelImpl(const IPC::ChannelHandle &channel_handle, Mode mode,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Listener* listener);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ChannelImpl();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Connect();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Close();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Send(Message* message);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsNamedServerInitialized(const std::string& channel_id);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessId peer_pid() const { return peer_pid_; }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChannelReader implementation.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ReadState ReadData(char* buffer,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int buffer_len,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int* bytes_read) OVERRIDE;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool WillDispatchInputMessage(Message* msg) OVERRIDE;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DidEmptyInputBuffers() OVERRIDE;
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void HandleInternalMessage(const Message& msg) OVERRIDE;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const string16 PipeName(const std::string& channel_id,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int32* secret);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CreatePipe(const IPC::ChannelHandle &channel_handle, Mode mode);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ProcessConnection();
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool ProcessOutgoingMessages(base::MessageLoopForIO::IOContext* context,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               DWORD bytes_written);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop::IOHandler implementation.
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnIOCompleted(base::MessageLoopForIO::IOContext* context,
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             DWORD bytes_transfered,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             DWORD error);
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct State {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit State(ChannelImpl* channel);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~State();
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoopForIO::IOContext context;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_pending;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State input_state_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State output_state_;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE pipe_;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessId peer_pid_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Messages to be sent are queued here.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::queue<Message*> output_queue_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In server-mode, we have to wait for the client to connect before we
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can begin reading.  We make use of the input_state_ when performing
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the connect operation in overlapped mode.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_connect_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This flag is set when processing incoming messages.  It is used to
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // avoid recursing through ProcessIncomingMessages, which could cause
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // problems.  TODO(darin): make this unnecessary
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool processing_incoming_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determines if we should validate a client's secret on connection.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool validate_client_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is a unique per-channel value used to authenticate the client end of
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a connection. If the value is non-zero, the client passes it in the hello
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the host validates. (We don't send the zero value fto preserve IPC
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compatability with existing clients that don't validate the channel.)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 client_secret_;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<ChannelImpl> weak_factory_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::ThreadChecker> thread_check_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace IPC
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // IPC_IPC_CHANNEL_WIN_H_
107