1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=8 et :
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at:
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is Mozilla Code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * The Mozilla Foundation
21 : * Portions created by the Initial Developer are Copyright (C) 2010
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Chris Jones <jones.chris.g@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "base/process_util.h"
42 :
43 : #include "mozilla/ipc/AsyncChannel.h"
44 : #include "mozilla/ipc/ProtocolUtils.h"
45 : #include "mozilla/ipc/Transport.h"
46 :
47 : using namespace base;
48 : using namespace IPC;
49 :
50 : namespace mozilla {
51 : namespace ipc {
52 :
53 : class ChannelOpened : public IPC::Message
54 0 : {
55 : public:
56 0 : ChannelOpened(TransportDescriptor aDescriptor,
57 : ProcessId aOtherProcess,
58 : ProtocolId aProtocol)
59 : : IPC::Message(MSG_ROUTING_CONTROL, // these only go to top-level actors
60 : CHANNEL_OPENED_MESSAGE_TYPE,
61 0 : PRIORITY_NORMAL)
62 : {
63 0 : IPC::WriteParam(this, aDescriptor);
64 0 : IPC::WriteParam(this, aOtherProcess);
65 0 : IPC::WriteParam(this, static_cast<uint32>(aProtocol));
66 0 : }
67 :
68 0 : static bool Read(const IPC::Message& aMsg,
69 : TransportDescriptor* aDescriptor,
70 : ProcessId* aOtherProcess,
71 : ProtocolId* aProtocol)
72 : {
73 0 : void* iter = nsnull;
74 0 : if (!IPC::ReadParam(&aMsg, &iter, aDescriptor) ||
75 0 : !IPC::ReadParam(&aMsg, &iter, aOtherProcess) ||
76 0 : !IPC::ReadParam(&aMsg, &iter, reinterpret_cast<uint32*>(aProtocol))) {
77 0 : return false;
78 : }
79 0 : aMsg.EndRead(iter);
80 0 : return true;
81 : }
82 : };
83 :
84 : bool
85 0 : Bridge(const PrivateIPDLInterface&,
86 : AsyncChannel* aParentChannel, ProcessHandle aParentProcess,
87 : AsyncChannel* aChildChannel, ProcessHandle aChildProcess,
88 : ProtocolId aProtocol)
89 : {
90 0 : ProcessId parentId = GetProcId(aParentProcess);
91 0 : ProcessId childId = GetProcId(aChildProcess);
92 0 : if (!parentId || !childId) {
93 0 : return false;
94 : }
95 :
96 0 : TransportDescriptor parentSide, childSide;
97 0 : if (!CreateTransport(aParentProcess, aChildProcess,
98 0 : &parentSide, &childSide)) {
99 0 : return false;
100 : }
101 :
102 0 : if (!aParentChannel->Send(new ChannelOpened(parentSide,
103 : childId,
104 0 : aProtocol)) ||
105 : !aChildChannel->Send(new ChannelOpened(childSide,
106 : parentId,
107 0 : aProtocol))) {
108 0 : CloseDescriptor(parentSide);
109 0 : CloseDescriptor(childSide);
110 0 : return false;
111 : }
112 0 : return true;
113 : }
114 :
115 : bool
116 0 : Open(const PrivateIPDLInterface&,
117 : AsyncChannel* aOpenerChannel, ProcessHandle aOtherProcess,
118 : Transport::Mode aOpenerMode,
119 : ProtocolId aProtocol)
120 : {
121 0 : bool isParent = (Transport::MODE_SERVER == aOpenerMode);
122 0 : ProcessHandle thisHandle = GetCurrentProcessHandle();
123 0 : ProcessHandle parentHandle = isParent ? thisHandle : aOtherProcess;
124 0 : ProcessHandle childHandle = !isParent ? thisHandle : aOtherProcess;
125 0 : ProcessId parentId = GetProcId(parentHandle);
126 0 : ProcessId childId = GetProcId(childHandle);
127 0 : if (!parentId || !childId) {
128 0 : return false;
129 : }
130 :
131 0 : TransportDescriptor parentSide, childSide;
132 0 : if (!CreateTransport(parentHandle, childHandle,
133 0 : &parentSide, &childSide)) {
134 0 : return false;
135 : }
136 :
137 0 : Message* parentMsg = new ChannelOpened(parentSide, childId, aProtocol);
138 0 : Message* childMsg = new ChannelOpened(childSide, parentId, aProtocol);
139 0 : nsAutoPtr<Message> messageForUs(isParent ? parentMsg : childMsg);
140 0 : nsAutoPtr<Message> messageForOtherSide(!isParent ? parentMsg : childMsg);
141 0 : if (!aOpenerChannel->Echo(messageForUs.forget()) ||
142 0 : !aOpenerChannel->Send(messageForOtherSide.forget())) {
143 0 : CloseDescriptor(parentSide);
144 0 : CloseDescriptor(childSide);
145 0 : return false;
146 : }
147 0 : return true;
148 : }
149 :
150 : bool
151 0 : UnpackChannelOpened(const PrivateIPDLInterface&,
152 : const Message& aMsg,
153 : TransportDescriptor* aTransport,
154 : ProcessId* aOtherProcess,
155 : ProtocolId* aProtocol)
156 : {
157 0 : return ChannelOpened::Read(aMsg, aTransport, aOtherProcess, aProtocol);
158 : }
159 :
160 : } // namespace ipc
161 : } // namespace mozilla
|