~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to services/plugins/dndcp/dndGuest/dndCPTransportGuestRpc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********************************************************
 
2
 * Copyright (C) 2010 VMware, Inc. All rights reserved.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify it
 
5
 * under the terms of the GNU Lesser General Public License as published
 
6
 * by the Free Software Foundation version 2.1 and no later version.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
10
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
 
11
 * License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 
15
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 
16
 *
 
17
 *********************************************************/
 
18
 
 
19
/**
 
20
 * @dndCPTransportGuestRpc.cpp --
 
21
 *
 
22
 * GuestRpc implementation of the dndCPTransport interface.
 
23
 *
 
24
 * XXX Move this to a common lib or source location.
 
25
 */
 
26
 
 
27
#include "dndCPTransportGuestRpc.hpp"
 
28
#include "rpcBase.h"
 
29
 
 
30
extern "C" {
 
31
   #include "str.h"
 
32
   #include "hostinfo.h"
 
33
   #include "dndMsg.h"
 
34
   #include "util.h"
 
35
#ifdef VMX86_TOOLS
 
36
   #include "debug.h"
 
37
   #include "rpcout.h"
 
38
   #include "rpcin.h"
 
39
   #define LOG(level, msg) (Debug msg)
 
40
#else
 
41
   #include "dndCPInt.h"
 
42
   #include "guest_rpc.h"
 
43
   #include "tclodefs.h"
 
44
   #define LOGLEVEL_MODULE dnd
 
45
   #include "loglevel_user.h"
 
46
#endif
 
47
}
 
48
 
 
49
#ifdef VMX86_TOOLS
 
50
/**
 
51
 * Received a message from guestRpc. Forward the message to transport class.
 
52
 *
 
53
 * @param[out] result reply string.
 
54
 * @param[out] resultLen reply string length in byte.
 
55
 * @param[in] name guestRpc cmd name.
 
56
 * @param[in] args argument list.
 
57
 * @param[in] argsSize argument list size in byte.
 
58
 * @param[in] clientData callback client data.
 
59
 *
 
60
 * @return TRUE if success, FALSE otherwise.
 
61
 */
 
62
 
 
63
static gboolean
 
64
RecvMsgCB(RpcInData *data) // IN/OUT
 
65
{
 
66
   LOG(4, ("%s: receiving\n", __FUNCTION__));
 
67
 
 
68
   const uint8 *packet = (const uint8 *)(data->args + 1);
 
69
   size_t packetSize = data->argsSize - 1;
 
70
 
 
71
   /* '- 1' is to ignore empty space between command and args. */
 
72
   if ((data->argsSize - 1) <= 0) {
 
73
      Debug("%s: invalid argsSize\n", __FUNCTION__);
 
74
      return RPCIN_SETRETVALS(data, "invalid arg size", FALSE);
 
75
   }
 
76
   GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)data->clientData;
 
77
#else
 
78
/**
 
79
 * Received a message from guestRpc. Forward the message to transport class.
 
80
 *
 
81
 * @param[in] clientData callback client data.
 
82
 * @param[ignored] channelId
 
83
 * @param[in] args argument list.
 
84
 * @param[in] argsSize argument list size in byte.
 
85
 * @param[out] result reply string.
 
86
 * @param[out] resultSize reply string length in byte.
 
87
 *
 
88
 * @return TRUE if success, FALSE otherwise.
 
89
 */
 
90
 
 
91
static Bool
 
92
RecvMsgCB(void *clientData,
 
93
          uint16 channelId,
 
94
          const unsigned char *args,
 
95
          uint32 argsSize,
 
96
          unsigned char **result,
 
97
          uint32 *resultSize)
 
98
{
 
99
   const uint8 *packet = args;
 
100
   size_t packetSize = argsSize;
 
101
   GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)clientData;
 
102
#endif
 
103
 
 
104
   ASSERT(ctx);
 
105
   ASSERT(ctx->transport);
 
106
   ctx->transport->OnRecvPacket(ctx->type, packet, packetSize);
 
107
 
 
108
#ifdef VMX86_TOOLS
 
109
   return RPCIN_SETRETVALS(data, "", TRUE);
 
110
#else
 
111
   return GuestRpc_SetRetVals(result, resultSize, (char *)"", TRUE);
 
112
#endif
 
113
}
 
114
 
 
115
 
 
116
/**
 
117
 * Constructor.
 
118
 */
 
119
 
 
120
TransportGuestRpcTables::TransportGuestRpcTables(void)
 
121
{
 
122
   for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) {
 
123
      mRpcList[i] = NULL;
 
124
      mCmdStrTable[i] = NULL;
 
125
      mDisableStrTable[i] = NULL;
 
126
#ifdef VMX86_TOOLS
 
127
   }
 
128
#else
 
129
      mCmdTable[i] = GUESTRPC_CMD_MAX;
 
130
   }
 
131
   mCmdTable[TRANSPORT_GUEST_CONTROLLER_DND] = GUESTRPC_CMD_DND_TRANSPORT;
 
132
   mCmdTable[TRANSPORT_GUEST_CONTROLLER_CP] = GUESTRPC_CMD_COPYPASTE_TRANSPORT;
 
133
#endif
 
134
 
 
135
   mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_CMD_STR_DND;
 
136
   mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CMD_STR_CP;
 
137
 
 
138
   mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_DND_DISABLE;
 
139
   mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CP_DISABLE;
 
140
}
 
141
 
 
142
 
 
143
/**
 
144
 * Destructor.
 
145
 */
 
146
 
 
147
TransportGuestRpcTables::~TransportGuestRpcTables(void)
 
148
{
 
149
}
 
150
 
 
151
 
 
152
/**
 
153
 * Get an rpc object by interface type.
 
154
 *
 
155
 * @param[in] type transport interface type
 
156
 *
 
157
 * @return a registered rpc, or NULL if the rpc for the type is not registered.
 
158
 */
 
159
 
 
160
RpcBase *
 
161
TransportGuestRpcTables::GetRpc(TransportInterfaceType type)
 
162
{
 
163
   ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND ||
 
164
          type == TRANSPORT_GUEST_CONTROLLER_CP ||
 
165
          type == TRANSPORT_GUEST_CONTROLLER_FT);
 
166
   return mRpcList[type];
 
167
}
 
168
 
 
169
 
 
170
/**
 
171
 * Add a rpc into rpc table.
 
172
 *
 
173
 * @param[in] type transport interface type
 
174
 * @param[in] rpc rpc which is added into the table.
 
175
 */
 
176
 
 
177
void
 
178
TransportGuestRpcTables::SetRpc(TransportInterfaceType type,
 
179
                                RpcBase *rpc)
 
180
{
 
181
   ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND ||
 
182
          type == TRANSPORT_GUEST_CONTROLLER_CP ||
 
183
          type == TRANSPORT_GUEST_CONTROLLER_FT);
 
184
   mRpcList[type] = rpc;
 
185
}
 
186
 
 
187
 
 
188
#ifndef VMX86_TOOLS
 
189
/**
 
190
 * Get a guestRpc cmd by interface type.
 
191
 *
 
192
 * @param[in] type transport interface type
 
193
 *
 
194
 * @return a guestRpc cmd.
 
195
 */
 
196
 
 
197
GuestRpcCmd
 
198
TransportGuestRpcTables::GetCmd(TransportInterfaceType type)
 
199
{
 
200
   ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND ||
 
201
          type == TRANSPORT_GUEST_CONTROLLER_CP ||
 
202
          type == TRANSPORT_GUEST_CONTROLLER_FT);
 
203
 
 
204
   return mCmdTable[type];
 
205
}
 
206
#endif
 
207
 
 
208
 
 
209
/**
 
210
 * Get a guestRpc cmd string by interface type.
 
211
 *
 
212
 * @param[in] type transport interface type
 
213
 *
 
214
 * @return a guestRpc cmd string.
 
215
 */
 
216
 
 
217
const char *
 
218
TransportGuestRpcTables::GetCmdStr(TransportInterfaceType type)
 
219
{
 
220
   ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND ||
 
221
          type == TRANSPORT_GUEST_CONTROLLER_CP ||
 
222
          type == TRANSPORT_GUEST_CONTROLLER_FT);
 
223
 
 
224
   return mCmdStrTable[type];
 
225
}
 
226
 
 
227
 
 
228
/**
 
229
 * Get a guestRpc cmd disable string by interface type.
 
230
 *
 
231
 * @param[in] type transport interface type
 
232
 *
 
233
 * @return a guestRpc cmd disable string.
 
234
 */
 
235
 
 
236
const char *
 
237
TransportGuestRpcTables::GetDisableStr(TransportInterfaceType type)
 
238
{
 
239
   ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND ||
 
240
          type == TRANSPORT_GUEST_CONTROLLER_CP ||
 
241
          type == TRANSPORT_GUEST_CONTROLLER_FT);
 
242
 
 
243
   return mDisableStrTable[type];
 
244
}
 
245
 
 
246
 
 
247
/**
 
248
 * Constructor.
 
249
 *
 
250
 * @param[in] rpcIn
 
251
 */
 
252
 
 
253
#ifdef VMX86_TOOLS
 
254
DnDCPTransportGuestRpc::DnDCPTransportGuestRpc(RpcChannel *chan)
 
255
   : mRpcChannel(chan)
 
256
#else
 
257
DnDCPTransportGuestRpc::DnDCPTransportGuestRpc(void)
 
258
#endif
 
259
{
 
260
   for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) {
 
261
      mCBCtx[i].transport = this;
 
262
      mCBCtx[i].type = (TransportInterfaceType)i;
 
263
   }
 
264
}
 
265
 
 
266
 
 
267
/**
 
268
 * Register a rpc callback to an interface.
 
269
 *
 
270
 * @param[in] rpc rpc which is listening to the message.
 
271
 * @param[in] type the interface type rpc is listening to.
 
272
 *
 
273
 * @return true on success, false otherwise.
 
274
 */
 
275
 
 
276
bool
 
277
DnDCPTransportGuestRpc::RegisterRpc(RpcBase *rpc,
 
278
                                    TransportInterfaceType type)
 
279
{
 
280
   if (mTables.GetRpc(type)) {
 
281
      LOG(0, ("%s: the type %d is already registered\n", __FUNCTION__, type));
 
282
      UnregisterRpc(type);
 
283
   }
 
284
   const char *cmdStr = (const char *)mTables.GetCmdStr(type);
 
285
   const char *disableStr = mTables.GetDisableStr(type);
 
286
 
 
287
   if (!cmdStr || !disableStr) {
 
288
      LOG(0, ("%s: can not find valid cmd for %d, cmdStr %s disableStr %s\n", __FUNCTION__, type, (cmdStr ? cmdStr : "NULL"), (disableStr ? disableStr : "NULL")));
 
289
      return false;
 
290
   }
 
291
 
 
292
   ASSERT(mCBCtx);
 
293
   ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND ||
 
294
          type == TRANSPORT_GUEST_CONTROLLER_CP ||
 
295
          type == TRANSPORT_GUEST_CONTROLLER_FT);
 
296
   LOG(4, ("%s: for %s\n", __FUNCTION__, cmdStr));
 
297
 
 
298
#ifdef VMX86_TOOLS
 
299
   ASSERT(mRpcChannel);
 
300
   mRpcChanCBList[type].name = cmdStr;
 
301
   mRpcChanCBList[type].callback = RecvMsgCB;
 
302
   mRpcChanCBList[type].clientData = &mCBCtx[type];
 
303
   mRpcChanCBList[type].xdrIn = NULL;
 
304
   mRpcChanCBList[type].xdrOut = NULL;
 
305
   mRpcChanCBList[type].xdrInSize = 0;
 
306
   RpcChannel_RegisterCallback(mRpcChannel, &mRpcChanCBList[type]);
 
307
#else
 
308
   GuestRpc_RegisterCommand(mTables.GetCmd(type), disableStr,
 
309
                            (const unsigned char *)cmdStr, RecvMsgCB, &mCBCtx[type]);
 
310
#endif
 
311
   mTables.SetRpc(type, rpc);
 
312
   return true;
 
313
}
 
314
 
 
315
 
 
316
/**
 
317
 * Unregister a rpc callback.
 
318
 *
 
319
 * @param[in] type the interface type rpc is listening to.
 
320
 *
 
321
 * @return true on success, false otherwise.
 
322
 */
 
323
 
 
324
bool
 
325
DnDCPTransportGuestRpc::UnregisterRpc(TransportInterfaceType type)
 
326
{
 
327
   if (!mTables.GetRpc(type)) {
 
328
      LOG(0, ("%s: the type %d is not registered\n", __FUNCTION__, type));
 
329
      return false;
 
330
   }
 
331
#ifdef VMX86_TOOLS
 
332
   ASSERT(mRpcChannel);
 
333
   RpcChannel_UnregisterCallback(mRpcChannel, &mRpcChanCBList[type]);
 
334
#else
 
335
   GuestRpc_UnregisterCommand(mTables.GetCmd(type));
 
336
#endif
 
337
   mTables.SetRpc(type, NULL);
 
338
   return true;
 
339
}
 
340
 
 
341
 
 
342
/**
 
343
 * Wrap the buffer into an rpc and send it to the peer.
 
344
 *
 
345
 * @param[ignored] destId destination address id
 
346
 * @param[in] type transport interface type
 
347
 * @param[in] data Payload buffer
 
348
 * @param[in] dataSize Payload buffer size
 
349
 *
 
350
 * @return true on success, false otherwise.
 
351
 */
 
352
 
 
353
bool
 
354
DnDCPTransportGuestRpc::SendPacket(uint32 destId,
 
355
                                   TransportInterfaceType type,
 
356
                                   const uint8 *msg,
 
357
                                   size_t length)
 
358
{
 
359
   char *rpc = NULL;
 
360
   size_t rpcSize = 0;
 
361
   size_t nrWritten = 0;
 
362
   const char *cmd = mTables.GetCmdStr(type);
 
363
   bool ret = true;
 
364
 
 
365
   if (!cmd) {
 
366
      LOG(0, ("%s: can not find valid cmd for %d\n", __FUNCTION__, type));
 
367
      return false;
 
368
   }
 
369
   rpcSize = strlen(cmd) + 1 + length;
 
370
   rpc = (char *)Util_SafeMalloc(rpcSize);
 
371
   nrWritten = Str_Sprintf(rpc, rpcSize, "%s ", cmd);
 
372
 
 
373
   if (length > 0) {
 
374
      ASSERT(nrWritten + length <= rpcSize);
 
375
      memcpy(rpc + nrWritten, msg, length);
 
376
   }
 
377
 
 
378
#ifdef VMX86_TOOLS
 
379
   ret = (TRUE == RpcChannel_Send(mRpcChannel, rpc, rpcSize, NULL, NULL));
 
380
 
 
381
   if (!ret) {
 
382
      LOG(0, ("%s: failed to send msg to host\n", __FUNCTION__));
 
383
   }
 
384
 
 
385
   LOG(4, ("%s: sending [%s]\n", __FUNCTION__, rpc));
 
386
 
 
387
   free(rpc);
 
388
   LOG(4, ("%s: sending\n", __FUNCTION__));
 
389
#else
 
390
   GuestRpc_SendWithTimeOut((const unsigned char *)TOOLS_DND_NAME,
 
391
                            (const unsigned char *)rpc, rpcSize,
 
392
                            GuestRpc_GenericCompletionRoutine, rpc,
 
393
                            DND_TIMEOUT);
 
394
   LOG(4, ("%s: sending [%s]\n", __FUNCTION__, rpc));
 
395
 
 
396
#endif
 
397
   return ret;
 
398
}
 
399
 
 
400
 
 
401
/**
 
402
 * Callback after receiving a guestRpc message.
 
403
 *
 
404
 * @param[in] type transport interface type
 
405
 * @param[in] packet Payload buffer
 
406
 * @param[in] packetSize Payload buffer size
 
407
 */
 
408
 
 
409
void
 
410
DnDCPTransportGuestRpc::OnRecvPacket(TransportInterfaceType type,
 
411
                                     const uint8 *packet,
 
412
                                     size_t packetSize)
 
413
{
 
414
   RpcBase *rpc = mTables.GetRpc(type);
 
415
   if (!rpc) {
 
416
      LOG(0, ("%s: can not find valid rpc for %d\n", __FUNCTION__, type));
 
417
      return;
 
418
   }
 
419
   rpc->OnRecvPacket(DEFAULT_CONNECTION_ID, packet, packetSize);
 
420
}