vfs: check userland buffers before reading them.
[haiku.git] / src / kits / interface / WindowStack.cpp
blob34db295976713ec564a73526986357c4dfa3908c
1 /*
2 * Copyright 2010, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Clemens Zeidler <haiku@clemens-zeidler.de>
7 */
10 #include "WindowStack.h"
12 #include <new>
14 #include <Window.h>
16 #include <ApplicationPrivate.h>
17 #include <MessengerPrivate.h>
18 #include <PortLink.h>
19 #include <ServerProtocol.h>
21 #include "StackAndTilePrivate.h"
24 using namespace BPrivate;
27 BWindowStack::BWindowStack(BWindow* window)
29 fLink = window->fLink;
33 BWindowStack::~BWindowStack()
39 status_t
40 BWindowStack::AddWindow(const BWindow* window)
42 BMessenger messenger(window);
43 return AddWindow(messenger);
47 status_t
48 BWindowStack::AddWindow(const BMessenger& window)
50 return AddWindowAt(window, -1);
54 status_t
55 BWindowStack::AddWindowAt(const BWindow* window, int32 position)
57 BMessenger messenger(window);
58 return AddWindowAt(messenger, position);
62 status_t
63 BWindowStack::AddWindowAt(const BMessenger& window, int32 position)
65 _StartMessage(kAddWindowToStack);
67 _AttachMessenger(window);
68 fLink->Attach<int32>(position);
70 int32 code = B_ERROR;
71 if (fLink->FlushWithReply(code) != B_OK)
72 return code;
74 return B_OK;
78 status_t
79 BWindowStack::RemoveWindow(const BWindow* window)
81 BMessenger messenger(window);
82 return RemoveWindow(messenger);
86 status_t
87 BWindowStack::RemoveWindow(const BMessenger& window)
89 _StartMessage(kRemoveWindowFromStack);
90 _AttachMessenger(window);
92 if (fLink->Flush() != B_OK)
93 return B_ERROR;
95 return B_OK;
99 status_t
100 BWindowStack::RemoveWindowAt(int32 position, BMessenger* window)
102 _StartMessage(kRemoveWindowFromStackAt);
103 fLink->Attach<int32>(position);
105 int32 code = B_ERROR;
106 if (fLink->FlushWithReply(code) != B_OK)
107 return code;
109 if (window == NULL)
110 return B_OK;
112 return _ReadMessenger(*window);
116 int32
117 BWindowStack::CountWindows()
119 _StartMessage(kCountWindowsOnStack);
121 int32 code = B_ERROR;
122 fLink->FlushWithReply(code);
123 if (code != B_OK)
124 return -1;
126 int32 count;
127 if (fLink->Read<int32>(&count) != B_OK)
128 return -1;
130 return count;
134 status_t
135 BWindowStack::WindowAt(int32 position, BMessenger& messenger)
137 _StartMessage(kWindowOnStackAt);
138 fLink->Attach<int32>(position);
140 int32 code = B_ERROR;
141 fLink->FlushWithReply(code);
142 if (code != B_OK)
143 return code;
145 return _ReadMessenger(messenger);
149 bool
150 BWindowStack::HasWindow(const BWindow* window)
152 BMessenger messenger(window);
153 return HasWindow(messenger);
157 bool
158 BWindowStack::HasWindow(const BMessenger& window)
160 _StartMessage(kStackHasWindow);
161 _AttachMessenger(window);
163 int32 code = B_ERROR;
164 fLink->FlushWithReply(code);
165 if (code != B_OK)
166 return false;
168 bool hasWindow;
169 if (fLink->Read<bool>(&hasWindow) != B_OK)
170 return false;
172 return hasWindow;
176 status_t
177 BWindowStack::_AttachMessenger(const BMessenger& window)
179 BMessenger::Private messengerPrivate(const_cast<BMessenger&>(window));
180 fLink->Attach<port_id>(messengerPrivate.Port());
181 fLink->Attach<int32>(messengerPrivate.Token());
182 return fLink->Attach<team_id>(messengerPrivate.Team());
186 status_t
187 BWindowStack::_ReadMessenger(BMessenger& window)
189 port_id port;
190 int32 token;
191 team_id team;
192 fLink->Read<port_id>(&port);
193 fLink->Read<int32>(&token);
194 status_t status = fLink->Read<team_id>(&team);
195 if (status != B_OK)
196 return status;
197 BMessenger::Private messengerPrivate(window);
198 messengerPrivate.SetTo(team, port, token);
199 return B_OK;
203 status_t
204 BWindowStack::_StartMessage(int32 what)
206 fLink->StartMessage(AS_TALK_TO_DESKTOP_LISTENER);
207 fLink->Attach<int32>(kMagicSATIdentifier);
208 fLink->Attach<int32>(kStacking);
209 return fLink->Attach<int32>(what);