vfs: check userland buffers before reading them.
[haiku.git] / src / apps / cortex / NodeManager / AddOnHost.cpp
blobba3aa614dc280742dd26ca179da6b46ba8e0dd33
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "AddOnHost.h"
33 #include "AddOnHostProtocol.h"
35 #include <Application.h>
36 #include <Debug.h>
37 #include <Entry.h>
38 #include <MediaNode.h>
39 #include <MediaRoster.h>
40 #include <Messenger.h>
41 #include <Path.h>
42 #include <Roster.h>
44 #include <OS.h>
46 #include <cstdlib>
47 #include <cstring>
49 __USE_CORTEX_NAMESPACE
51 // -------------------------------------------------------- //
52 // constants
53 // -------------------------------------------------------- //
55 BMessenger AddOnHost::s_messenger;
57 // -------------------------------------------------------- //
58 // *** static interface
59 // -------------------------------------------------------- //
61 /*static*/
62 status_t AddOnHost::FindInstance(
63 BMessenger* outMessenger) {
65 status_t err;
67 // no current app? launch one
68 if(!s_messenger.IsValid()) {
69 s_messenger = BMessenger(
70 addon_host::g_appSignature,
71 -1,
72 &err);
74 if(err < B_OK)
75 return err;
76 if(!s_messenger.IsValid())
77 return B_ERROR;
80 *outMessenger = s_messenger;
81 return B_OK;
84 /*static*/
85 status_t AddOnHost::Kill(
86 bigtime_t timeout) {
88 if(!s_messenger.IsValid())
89 return B_NOT_ALLOWED;
91 status_t err = kill_team(s_messenger.Team());
92 return err;
95 /*static*/
96 status_t AddOnHost::Launch(
97 BMessenger* outMessenger) {
99 if(s_messenger.IsValid())
100 return B_NOT_ALLOWED;
102 status_t err;
104 // find it
105 entry_ref appRef;
106 err = be_roster->FindApp(addon_host::g_appSignature, &appRef);
107 if(err < B_OK)
108 return err;
110 // start it
111 team_id team;
112 const char* arg = "--addon-host";
113 err = be_roster->Launch(
114 &appRef,
116 &arg,
117 &team);
118 if(err < B_OK)
119 return err;
121 // fetch messenger to the new app and return it
122 s_messenger = BMessenger(
123 addon_host::g_appSignature,
124 team,
125 &err);
127 if(err < B_OK)
128 return err;
129 if(!s_messenger.IsValid())
130 return B_ERROR;
132 if(outMessenger)
133 *outMessenger = s_messenger;
135 return B_OK;
138 /*static*/
139 status_t AddOnHost::InstantiateDormantNode(
140 const dormant_node_info& info,
141 media_node* outNode,
142 bigtime_t timeout) {
144 status_t err;
146 if(!s_messenger.IsValid()) {
147 err = Launch(0);
149 if(err < B_OK) {
150 // give up
151 PRINT((
152 "!!! AddOnHost::InstantiateDormantNode(): Launch() failed:\n"
153 " %s\n",
154 strerror(err)));
155 return err;
159 // do it
160 ASSERT(s_messenger.IsValid());
161 BMessage request(addon_host::M_INSTANTIATE);
162 request.AddData("info", B_RAW_TYPE, &info, sizeof(dormant_node_info));
164 BMessage reply(B_NO_REPLY);
165 err = s_messenger.SendMessage(
166 &request,
167 &reply,
168 timeout,
169 timeout);
171 // PRINT((
172 // "### SendMessage() returned '%s'\n", strerror(err)));
174 if(err < B_OK) {
175 PRINT((
176 "!!! AddOnHost::InstantiateDormantNode(): SendMessage() failed:\n"
177 " %s\n",
178 strerror(err)));
179 return err;
182 if(reply.what == B_NO_REPLY) {
183 PRINT((
184 "!!! AddOnHost::InstantiateDormantNode(): no reply.\n"));
185 return B_ERROR;
188 if(reply.what == addon_host::M_INSTANTIATE_COMPLETE) {
189 media_node_id nodeID;
191 // fetch node ID
192 err = reply.FindInt32("node_id", &nodeID);
193 if(err < B_OK) {
194 PRINT((
195 "!!! AddOnHost::InstantiateDormantNode(): 'node_id' missing from reply.\n"));
196 return B_ERROR;
199 // fetch node
200 err = BMediaRoster::Roster()->GetNodeFor(nodeID, outNode);
201 if(err < B_OK) {
202 PRINT((
203 "!!! AddOnHost::InstantiateDormantNode(): node missing!\n"));
204 return B_ERROR;
207 // // now solely owned by the add-on host team
208 // BMediaRoster::Roster()->ReleaseNode(*outNode);
210 return B_OK;
213 // failed:
214 return (reply.FindInt32("error", &err) == B_OK) ? err : B_ERROR;
217 /*static*/
218 status_t AddOnHost::ReleaseInternalNode(
219 const live_node_info& info,
220 bigtime_t timeout) {
222 status_t err;
224 if(!s_messenger.IsValid()) {
225 err = Launch(0);
227 if(err < B_OK) {
228 // give up
229 PRINT((
230 "!!! AddOnHost::ReleaseInternalNode(): Launch() failed:\n"
231 " %s\n",
232 strerror(err)));
233 return err;
237 // do it
238 ASSERT(s_messenger.IsValid());
239 BMessage request(addon_host::M_RELEASE);
240 request.AddData("info", B_RAW_TYPE, &info, sizeof(live_node_info));
242 BMessage reply(B_NO_REPLY);
243 err = s_messenger.SendMessage(
244 &request,
245 &reply,
246 timeout,
247 timeout);
250 if(err < B_OK) {
251 PRINT((
252 "!!! AddOnHost::ReleaseInternalNode(): SendMessage() failed:\n"
253 " %s\n",
254 strerror(err)));
255 return err;
258 if(reply.what == B_NO_REPLY) {
259 PRINT((
260 "!!! AddOnHost::InstantiateDormantNode(): no reply.\n"));
261 return B_ERROR;
264 if(reply.what == addon_host::M_RELEASE_COMPLETE) {
265 return B_OK;
268 // failed:
269 return (reply.FindInt32("error", &err) == B_OK) ? err : B_ERROR;