~n-muench/ubuntu/oneiric/open-vm-tools/open-vm-tools.fix-836277

« back to all changes in this revision

Viewing changes to lib/ghIntegration/ghIntegration.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-15 21:21:40 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080815212140-05fhxj8wroosysmj
Tags: 2008.08.08-109361-1ubuntu1
* Merge from Debian unstable (LP: #258393), remaining Ubuntu change:
  - add ubuntu_toolchain_FTBFS.dpatch patch, fix FTBFS
* Update ubuntu_toolchain_FTBFS.dpatch patch for the new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********************************************************
 
2
 * Copyright (C) 2007 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
 * ghIntegration.c --
 
21
 *
 
22
 *    Guest-host integration functions.
 
23
 */
 
24
 
 
25
#include "vmware.h"
 
26
#include "appUtil.h"
 
27
#include "debug.h"
 
28
#include "dynxdr.h"
 
29
#include "ghIntegration.h"
 
30
#include "ghIntegrationInt.h"
 
31
#include "guestCaps.h"
 
32
#include "guestrpc/ghiGetBinaryHandlers.h"
 
33
#include "guestrpc/ghiProtocolHandler.h"
 
34
#include "guest_msg_def.h"
 
35
#include "rpcin.h"
 
36
#include "rpcout.h"
 
37
#include "str.h"
 
38
#include "strutil.h"
 
39
#include "unityCommon.h"
 
40
#include "util.h"
 
41
 
 
42
 
 
43
/*
 
44
 * Local functions
 
45
 */
 
46
 
 
47
static Bool GHITcloGetBinaryInfo(char const **result, size_t *resultLen,
 
48
                                 const char *name, const char *args,
 
49
                                 size_t argsSize, void *clientData);
 
50
static Bool GHITcloGetBinaryHandlers(RpcInData *data);
 
51
static Bool GHITcloGetStartMenuItem(char const **result,
 
52
                                    size_t *resultLen,
 
53
                                    const char *name,
 
54
                                    const char *args,
 
55
                                    size_t argsSize,
 
56
                                    void *clientData);
 
57
static Bool GHITcloOpenStartMenu(char const **result,
 
58
                                 size_t *resultLen,
 
59
                                 const char *name,
 
60
                                 const char *args,
 
61
                                 size_t argsSize,
 
62
                                 void *clientData);
 
63
static Bool GHITcloCloseStartMenu(char const **result,
 
64
                                  size_t *resultLen,
 
65
                                  const char *name,
 
66
                                  const char *args,
 
67
                                  size_t argsSize,
 
68
                                  void *clientData);
 
69
static Bool GHITcloShellOpen(char const **result,
 
70
                             size_t *resultLen,
 
71
                             const char *name,
 
72
                             const char *args,
 
73
                             size_t argsSize,
 
74
                             void *clientData);
 
75
static Bool GHITcloShellAction(char const **result,
 
76
                               size_t *resultLen,
 
77
                               const char *name,
 
78
                               const char *args,
 
79
                               size_t argsSize,
 
80
                               void *clientData);
 
81
static Bool GHITcloSetGuestHandler(RpcInData *data);
 
82
static Bool GHITcloRestoreDefaultGuestHandler(RpcInData *data);
 
83
 
 
84
static Bool GHIUpdateHost(GHIProtocolHandlerList *handlers);
 
85
 
 
86
DynBuf gTcloUpdate;
 
87
static GHIPlatform *ghiPlatformData;
 
88
 
 
89
DblLnkLst_Links launchMenu;
 
90
 
 
91
/*
 
92
 *----------------------------------------------------------------------------
 
93
 *
 
94
 * GHI_IsSupported --
 
95
 *
 
96
 *     Determine whether this guest supports guest-host integration.
 
97
 *
 
98
 * Results:
 
99
 *     TRUE if the guest supports guest-host integration
 
100
 *     FALSE otherwise
 
101
 *
 
102
 * Side effects:
 
103
 *     None
 
104
 *
 
105
 *----------------------------------------------------------------------------
 
106
 */
 
107
 
 
108
Bool
 
109
GHI_IsSupported(void)
 
110
{
 
111
   return GHIPlatformIsSupported();
 
112
}
 
113
 
 
114
 
 
115
/*
 
116
 *-----------------------------------------------------------------------------
 
117
 *
 
118
 * GHI_RegisterCaps  --
 
119
 *
 
120
 *     Called by the application (VMwareUser) to allow the GHI subsystem to
 
121
 *     register its capabilities.
 
122
 *
 
123
 * Results:
 
124
 *     None.
 
125
 *
 
126
 * Side effects:
 
127
 *     None.
 
128
 *
 
129
 *-----------------------------------------------------------------------------
 
130
 */
 
131
 
 
132
void
 
133
GHI_RegisterCaps(void)
 
134
{
 
135
   /* Register guest platform specific capabilities. */
 
136
   GHIPlatformRegisterCaps(ghiPlatformData);
 
137
}
 
138
 
 
139
 
 
140
/*
 
141
 *-----------------------------------------------------------------------------
 
142
 *
 
143
 * GHI_UnregisterCaps  --
 
144
 *
 
145
 *     Called by the application (VMwareUser) to allow the GHI subsystem to
 
146
 *     unregister its capabilities.
 
147
 *
 
148
 * Results:
 
149
 *     None.
 
150
 *
 
151
 * Side effects:
 
152
 *     None.
 
153
 *
 
154
 *-----------------------------------------------------------------------------
 
155
 */
 
156
 
 
157
void
 
158
GHI_UnregisterCaps(void)
 
159
{
 
160
   /* Unregister guest platform specific capabilities. */
 
161
   GHIPlatformUnregisterCaps(ghiPlatformData);
 
162
}
 
163
 
 
164
 
 
165
/*
 
166
 *-----------------------------------------------------------------------------
 
167
 *
 
168
 * GHI_Init --
 
169
 *
 
170
 *     One time initialization stuff.
 
171
 *
 
172
 * Results:
 
173
 *     None.
 
174
 *
 
175
 * Side effects:
 
176
 *     May register with the tools poll loop.
 
177
 *
 
178
 *-----------------------------------------------------------------------------
 
179
 */
 
180
 
 
181
void
 
182
GHI_Init(VMU_ControllerCB *vmuControllerCB, // IN
 
183
         void *ctx)                         // IN
 
184
{
 
185
   Debug("%s\n", __FUNCTION__);
 
186
 
 
187
   DblLnkLst_Init(&launchMenu);
 
188
 
 
189
   ghiPlatformData = GHIPlatformInit(vmuControllerCB, ctx);
 
190
}
 
191
 
 
192
 
 
193
/*
 
194
 *-----------------------------------------------------------------------------
 
195
 *
 
196
 * GHI_Cleanup --
 
197
 *
 
198
 *     One time cleanup.
 
199
 *
 
200
 * Results:
 
201
 *     None.
 
202
 *
 
203
 * Side effects:
 
204
 *     None.
 
205
 *
 
206
 *-----------------------------------------------------------------------------
 
207
 */
 
208
 
 
209
void
 
210
GHI_Cleanup(void)
 
211
{
 
212
   GHIPlatformCleanup(ghiPlatformData);
 
213
   ghiPlatformData = NULL;
 
214
}
 
215
 
 
216
 
 
217
/*
 
218
 *-----------------------------------------------------------------------------
 
219
 *
 
220
 * GHI_InitBackdoor --
 
221
 *
 
222
 *    One time initialization stuff for the backdoor.
 
223
 *
 
224
 * Results:
 
225
 *    None.
 
226
 *
 
227
 * Side effects:
 
228
 *    None.
 
229
 *
 
230
 *-----------------------------------------------------------------------------
 
231
 */
 
232
 
 
233
void
 
234
GHI_InitBackdoor(struct RpcIn *rpcIn)   // IN
 
235
{
 
236
   /*
 
237
    * Only register the callback if the guest is capable of supporting GHI.
 
238
    * This way, if the VMX/UI sends us a GHI request on a non-supported platform
 
239
    * (for whatever reason), we will reply with 'command not supported'.
 
240
    */
 
241
 
 
242
   if (GHI_IsSupported()) {
 
243
      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_BINARY_INFO,
 
244
                             GHITcloGetBinaryInfo, NULL);
 
245
      RpcIn_RegisterCallbackEx(rpcIn, UNITY_RPC_GET_BINARY_HANDLERS,
 
246
                               GHITcloGetBinaryHandlers, NULL);
 
247
      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_OPEN_LAUNCHMENU,
 
248
                             GHITcloOpenStartMenu, NULL);
 
249
      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_GET_LAUNCHMENU_ITEM,
 
250
                             GHITcloGetStartMenuItem, NULL);
 
251
      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_CLOSE_LAUNCHMENU,
 
252
                             GHITcloCloseStartMenu, NULL);
 
253
      RpcIn_RegisterCallback(rpcIn, UNITY_RPC_SHELL_OPEN,
 
254
                             GHITcloShellOpen, NULL);
 
255
      RpcIn_RegisterCallback(rpcIn, GHI_RPC_GUEST_SHELL_ACTION,
 
256
                             GHITcloShellAction, NULL);
 
257
      RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_SET_GUEST_HANDLER,
 
258
                               GHITcloSetGuestHandler, NULL);
 
259
      RpcIn_RegisterCallbackEx(rpcIn, GHI_RPC_RESTORE_DEFAULT_GUEST_HANDLER,
 
260
                               GHITcloRestoreDefaultGuestHandler, NULL);
 
261
   }
 
262
}
 
263
 
 
264
 
 
265
/*
 
266
 *-----------------------------------------------------------------------------
 
267
 *
 
268
 * GHI_Gather --
 
269
 *
 
270
 *    Collects all the desired guest/host integration mapping details for
 
271
 *    URL Protocol handling and sending an RPC to the host with the collected
 
272
 *    details. Also initializes the global application -> filetype list.
 
273
 *
 
274
 * Result
 
275
 *    None.
 
276
 *
 
277
 * Side-effects
 
278
 *    Updates the global application -> filetype list.
 
279
 *
 
280
 *-----------------------------------------------------------------------------
 
281
 */
 
282
 
 
283
void
 
284
GHI_Gather(void)
 
285
{
 
286
   GHIProtocolHandlerList protocolHandlers;
 
287
 
 
288
   /* Get Protocol Handler information. */
 
289
   protocolHandlers.handlers.handlers_len = 0;
 
290
   protocolHandlers.handlers.handlers_val = NULL;
 
291
 
 
292
   if (!GHIPlatformGetProtocolHandlers(ghiPlatformData, &protocolHandlers)) {
 
293
      Debug("Failed to get protocol handler info.\n");
 
294
   } else {
 
295
      if (!GHIUpdateHost(&protocolHandlers)) {
 
296
         Debug("Failed to update the host.\n");
 
297
      }
 
298
   }
 
299
 
 
300
   VMX_XDR_FREE(xdr_GHIProtocolHandlerList, &protocolHandlers);
 
301
 
 
302
 
 
303
#ifdef _WIN32
 
304
   AppUtil_BuildGlobalApplicationList();
 
305
#endif // _WIN32
 
306
 
 
307
   Debug("Exited Guest/Host Integration Gather.\n");
 
308
}
 
309
 
 
310
 
 
311
/*
 
312
 *----------------------------------------------------------------------------
 
313
 *
 
314
 * GHITcloGetBinaryInfo --
 
315
 *
 
316
 *     RPC handler for 'unity.get.binary.info'. Get required binary info
 
317
 *     and send it back to the VMX.
 
318
 *
 
319
 * Results:
 
320
 *     TRUE if everything is successful.
 
321
 *     FALSE otherwise.
 
322
 *
 
323
 * Side effects:
 
324
 *     None.
 
325
 *
 
326
 *----------------------------------------------------------------------------
 
327
 */
 
328
 
 
329
static Bool
 
330
GHITcloGetBinaryInfo(char const **result,     // OUT
 
331
                     size_t *resultLen,       // OUT
 
332
                     const char *name,        // IN
 
333
                     const char *args,        // IN
 
334
                     size_t argsSize,         // ignored
 
335
                     void *clientData)        // ignored
 
336
 
 
337
{
 
338
   char *binaryPathUtf8;
 
339
   DynBuf *buf = &gTcloUpdate;
 
340
   unsigned int index = 0;
 
341
   Bool ret = TRUE;
 
342
 
 
343
   Debug("%s name:%s args:'%s'\n", __FUNCTION__, name, args);
 
344
 
 
345
   /* Skip the leading space. */
 
346
   index++;
 
347
 
 
348
   /* The binary path provided by the VMX is in UTF8. */
 
349
   binaryPathUtf8 = StrUtil_GetNextToken(&index, args, "");
 
350
 
 
351
   if (!binaryPathUtf8) {
 
352
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
353
      ret = RpcIn_SetRetVals(result, resultLen,
 
354
                             "Invalid arguments. Expected \"binary_path\"",
 
355
                             FALSE);
 
356
      goto exit;
 
357
   }
 
358
 
 
359
   DynBuf_SetSize(buf, 0);
 
360
   if (!GHIPlatformGetBinaryInfo(ghiPlatformData, binaryPathUtf8, buf)) {
 
361
      Debug("%s: Could not get binary info.\n", __FUNCTION__);
 
362
      ret = RpcIn_SetRetVals(result, resultLen,
 
363
                             "Could not get binary info",
 
364
                             FALSE);
 
365
      goto exit;
 
366
   }
 
367
 
 
368
   /*
 
369
    * Write the final result into the result out parameters and return!
 
370
    */
 
371
   *result = (char *)DynBuf_Get(buf);
 
372
   *resultLen = DynBuf_GetSize(buf);
 
373
 
 
374
exit:
 
375
   free(binaryPathUtf8);
 
376
   return ret;
 
377
}
 
378
 
 
379
 
 
380
/*
 
381
 *----------------------------------------------------------------------------
 
382
 *
 
383
 * GHITcloGetBinaryHandlers --
 
384
 *
 
385
 *     RPC handler for 'unity.get.binary.handlers'. Get filetypes supported
 
386
 *     by the binary and send it back to the VMX.
 
387
 *
 
388
 * Results:
 
389
 *     TRUE if everything is successful.
 
390
 *     FALSE otherwise.
 
391
 *
 
392
 * Side effects:
 
393
 *     None.
 
394
 *
 
395
 *----------------------------------------------------------------------------
 
396
 */
 
397
 
 
398
static Bool
 
399
GHITcloGetBinaryHandlers(RpcInData *data)        // IN/OUT
 
400
{
 
401
   char *binaryPathUtf8;
 
402
   XDR xdrs;
 
403
   unsigned int index = 0;
 
404
   Bool ret = TRUE;
 
405
 
 
406
   Debug("%s name:%s args:'%s'\n", __FUNCTION__, data->name, data->args);
 
407
 
 
408
   /* Skip the leading space. */
 
409
   index++;
 
410
 
 
411
   /* The binary path provided by the VMX is in UTF8. */
 
412
   binaryPathUtf8 = StrUtil_GetNextToken(&index, data->args, "");
 
413
 
 
414
   if (!binaryPathUtf8) {
 
415
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
416
      ret = RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"binary_path\"", FALSE);
 
417
      goto exit;
 
418
   }
 
419
 
 
420
   DynXdr_Create(&xdrs);
 
421
   if (!GHIPlatformGetBinaryHandlers(ghiPlatformData, binaryPathUtf8, &xdrs)) {
 
422
      Debug("%s: Could not get binary filetypes.\n", __FUNCTION__);
 
423
      ret = RPCIN_SETRETVALS(data, "Could not get binary filetypes", FALSE);
 
424
      DynXdr_Destroy(&xdrs, FALSE);
 
425
      goto exit;
 
426
   }
 
427
 
 
428
   /*
 
429
    * Write the final result into the result out parameters and return!
 
430
    */
 
431
    data->result = DynXdr_Get(&xdrs);
 
432
    data->resultLen = xdr_getpos(&xdrs);
 
433
    data->freeResult = TRUE;
 
434
    ret = TRUE;
 
435
 
 
436
    /*
 
437
     * Destroy the XDR structure but leave the data buffer alone since it will be
 
438
     * freed by the RpcIn layer.
 
439
     */
 
440
    DynXdr_Destroy(&xdrs, FALSE);
 
441
exit:
 
442
   free(binaryPathUtf8);
 
443
   return ret;
 
444
}
 
445
 
 
446
 
 
447
/*
 
448
 *----------------------------------------------------------------------------
 
449
 *
 
450
 * GHITcloOpenStartMenu --
 
451
 *
 
452
 *     RPC handler for 'unity.launchmenu.open'. Get the start menu sub-tree
 
453
 *     for a given item, save it in the array so it can be accessed
 
454
 *     later when the VMX needs to iterate over the items. Return the count
 
455
 *     of the items in the sub-tree and a handle to this sub-tree. The handle
 
456
 *     will be used by the VMX to iterate over the sub-items.
 
457
 *
 
458
 * Results:
 
459
 *     TRUE if everything is successful.
 
460
 *     FALSE otherwise.
 
461
 *
 
462
 * Side effects:
 
463
 *     None.
 
464
 *
 
465
 *----------------------------------------------------------------------------
 
466
 */
 
467
 
 
468
static Bool
 
469
GHITcloOpenStartMenu(char const **result,     // OUT
 
470
                     size_t *resultLen,       // OUT
 
471
                     const char *name,        // IN
 
472
                     const char *args,        // IN
 
473
                     size_t argsSize,         // ignored
 
474
                     void *clientData)        // ignored
 
475
{
 
476
   char *rootUtf8 = NULL;
 
477
   DynBuf *buf = &gTcloUpdate;
 
478
   uint32 index = 0;
 
479
   Bool ret = TRUE;
 
480
 
 
481
   Debug("%s name:%s args:'%s'\n", __FUNCTION__, name, args);
 
482
 
 
483
   /* Skip the leading space. */
 
484
   index++;
 
485
 
 
486
   /* The start menu root provided by the VMX is in UTF8. */
 
487
   rootUtf8 = StrUtil_GetNextToken(&index, args, "");
 
488
 
 
489
   if (!rootUtf8) {
 
490
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
491
      ret = RpcIn_SetRetVals(result, resultLen,
 
492
                             "Invalid arguments. Expected \"root\"",
 
493
                             FALSE);
 
494
      goto exit;
 
495
   }
 
496
 
 
497
   DynBuf_SetSize(buf, 0);
 
498
   if (!GHIPlatformOpenStartMenuTree(ghiPlatformData, rootUtf8, buf)) {
 
499
      Debug("%s: Could not open start menu.\n", __FUNCTION__);
 
500
      ret = RpcIn_SetRetVals(result, resultLen,
 
501
                             "Could not get start menu count",
 
502
                             FALSE);
 
503
      goto exit;
 
504
   }
 
505
 
 
506
   /*
 
507
    * Write the final result into the result out parameters and return!
 
508
    */
 
509
   *result = (char *)DynBuf_Get(buf);
 
510
   *resultLen = DynBuf_GetSize(buf);
 
511
 
 
512
exit:
 
513
   free(rootUtf8);
 
514
   return ret;
 
515
}
 
516
 
 
517
 
 
518
/*
 
519
 *----------------------------------------------------------------------------
 
520
 *
 
521
 * GHITcloGetStartMenuItem --
 
522
 *
 
523
 *     RPC handler for 'unity.launchmenu.next'. Get the start menu item
 
524
 *     at the given index for the tree with a given handle.
 
525
 *     If there's no item at the given index, return FALSE.
 
526
 *
 
527
 * Results:
 
528
 *     TRUE if the item was found.
 
529
 *     FALSE otherwise (i.e. if the VMX provides a wrong handle or if there's
 
530
                        no items left).
 
531
 *
 
532
 * Side effects:
 
533
 *     None.
 
534
 *
 
535
 *----------------------------------------------------------------------------
 
536
 */
 
537
 
 
538
static Bool
 
539
GHITcloGetStartMenuItem(char const **result,     // OUT
 
540
                        size_t *resultLen,       // OUT
 
541
                        const char *name,        // IN
 
542
                        const char *args,        // IN
 
543
                        size_t argsSize,         // ignored
 
544
                        void *clientData)        // ignored
 
545
{
 
546
   DynBuf *buf = &gTcloUpdate;
 
547
   uint32 index = 0;
 
548
   Bool ret = TRUE;
 
549
   uint32 itemIndex = 0;
 
550
   uint32 handle = 0;
 
551
 
 
552
   Debug("%s name:%s args:'%s'\n", __FUNCTION__, name, args);
 
553
 
 
554
   /* Parse the handle of the menu tree that VMX wants. */
 
555
   if (!StrUtil_GetNextUintToken(&handle, &index, args, " ")) {
 
556
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
557
      return RpcIn_SetRetVals(result, resultLen,
 
558
                              "Invalid arguments. Expected handle index",
 
559
                              FALSE);
 
560
   }
 
561
 
 
562
   /* The index of the menu item to be send back. */
 
563
   if (!StrUtil_GetNextUintToken(&itemIndex, &index, args, " ")) {
 
564
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
565
      return RpcIn_SetRetVals(result, resultLen,
 
566
                              "Invalid arguments. Expected handle index",
 
567
                              FALSE);
 
568
   }
 
569
 
 
570
   DynBuf_SetSize(buf, 0);
 
571
   if (!GHIPlatformGetStartMenuItem(ghiPlatformData, handle, itemIndex, buf)) {
 
572
      Debug("%s: Could not get start menu item.\n", __FUNCTION__);
 
573
      return RpcIn_SetRetVals(result, resultLen,
 
574
                              "Could not get start menu item",
 
575
                              FALSE);
 
576
   }
 
577
 
 
578
   /*
 
579
    * Write the final result into the result out parameters and return!
 
580
    */
 
581
   *result = (char *)DynBuf_Get(buf);
 
582
   *resultLen = DynBuf_GetSize(buf);
 
583
 
 
584
   return ret;
 
585
}
 
586
 
 
587
 
 
588
/*
 
589
 *----------------------------------------------------------------------------
 
590
 *
 
591
 * GHITcloCloseStartMenu --
 
592
 *
 
593
 *     RPC handler for 'unity.launchmenu.close'. The VMX is done with this
 
594
 *     particular start menu tree. Free all memory and cleanup.
 
595
 *
 
596
 * Results:
 
597
 *     None.
 
598
 *
 
599
 * Side effects:
 
600
 *     Memory allocated when the start menu tree was opened is finally freed.
 
601
 *
 
602
 *----------------------------------------------------------------------------
 
603
 */
 
604
 
 
605
static Bool
 
606
GHITcloCloseStartMenu(char const **result,     // OUT
 
607
                      size_t *resultLen,       // OUT
 
608
                      const char *name,        // IN
 
609
                      const char *args,        // IN
 
610
                      size_t argsSize,         // ignored
 
611
                      void *clientData)        // ignored
 
612
{
 
613
   uint32 index = 0;
 
614
   uint32 handle = 0;
 
615
 
 
616
   Debug("%s name:%s args:'%s'\n", __FUNCTION__, name, args);
 
617
 
 
618
   /* Parse the handle of the menu tree that VMX wants. */
 
619
   if (!StrUtil_GetNextIntToken(&handle, &index, args, " ")) {
 
620
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
621
      return RpcIn_SetRetVals(result, resultLen,
 
622
                              "Invalid arguments. Expected handle",
 
623
                              FALSE);
 
624
   }
 
625
 
 
626
   GHIPlatformCloseStartMenuTree(ghiPlatformData, handle);
 
627
 
 
628
   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
 
629
}
 
630
 
 
631
 
 
632
/*
 
633
 *----------------------------------------------------------------------------
 
634
 *
 
635
 * GHITcloShellOpen --
 
636
 *
 
637
 *     RPC handler for 'unity.shell.open'. Open the specified file with the
 
638
 *     default shell handler. Note that the file path may be either a URI
 
639
 *     (originated with Tools >= NNNNN), or a regular path (originated with
 
640
 *     Tools < NNNNN).
 
641
 *
 
642
 * Results:
 
643
 *     TRUE if everything is successful.
 
644
 *     FALSE otherwise.
 
645
 *
 
646
 * Side effects:
 
647
 *     None.
 
648
 *
 
649
 *----------------------------------------------------------------------------
 
650
 */
 
651
 
 
652
static Bool
 
653
GHITcloShellOpen(char const **result, // OUT
 
654
                 size_t *resultLen,   // OUT
 
655
                 const char *name,    // IN
 
656
                 const char *args,    // IN
 
657
                 size_t argsSize,     // ignored
 
658
                 void *clientData)    // ignored
 
659
{
 
660
   char *fileUtf8 = NULL;
 
661
   Bool ret = TRUE;
 
662
   unsigned int index = 0;
 
663
 
 
664
   Debug("%s: name: '%s', args: '%s'\n", __FUNCTION__, name, args);
 
665
 
 
666
   /* Skip the leading space. */
 
667
   index++;
 
668
 
 
669
   /* The file path provided by the VMX is in UTF8. */
 
670
   fileUtf8 = StrUtil_GetNextToken(&index, args, "");
 
671
 
 
672
   if (!fileUtf8) {
 
673
      Debug("%s: Invalid RPC arguments.\n", __FUNCTION__);
 
674
      return RpcIn_SetRetVals(result, resultLen,
 
675
                              "Invalid arguments. Expected file_name",
 
676
                              FALSE);
 
677
   }
 
678
 
 
679
   ret = GHIPlatformShellOpen(ghiPlatformData, fileUtf8);
 
680
   free(fileUtf8);
 
681
 
 
682
   if (!ret) {
 
683
      Debug("%s: Could not perform the requested shell open action.\n", __FUNCTION__);
 
684
      return RpcIn_SetRetVals(result, resultLen,
 
685
                              "Could not perform the requested shell open action.",
 
686
                              FALSE);
 
687
   }
 
688
 
 
689
   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
 
690
}
 
691
 
 
692
 
 
693
/*
 
694
 *----------------------------------------------------------------------------
 
695
 *
 
696
 * GHITcloShellAction --
 
697
 *
 
698
 *     RPC handler for "ghi.guest.shell.action". The action command has three
 
699
 *     arguments: an action URI, a target URI, and an array of location URIs.
 
700
 *     Action URIs are in the form: "x-vmware-action://<verb>", where <verb> is
 
701
 *     the name of a specific action to perform.
 
702
 *     The target URI is a guest-specific URI that was previously given to the
 
703
 *     host (usually a path to an application to run). Note that this may be
 
704
 *     either a URI (new Tools) or a regular path (old Tools).
 
705
 *     The locations can be files or URLs. Files are typically specified as
 
706
 *     HGFS shared folder locations (see below), but can potentially use the
 
707
 *     "file://<path>" URIs as well.
 
708
 *     Each guest can specify the features it supports using capability flags:
 
709
 *
 
710
 *     Capability                      Description
 
711
 *
 
712
 *     GHI_CAP_CMD_SHELL_ACTION        Guest allows 'ghi.guest.shell.action'.
 
713
 *                                     This encompasses this entire command
 
714
 *                                     and the rest of the capabilities.
 
715
 *
 
716
 *     GHI_CAP_SHELL_ACTION_BROWSE     Guest supports the 'browse' action verb,
 
717
 *                                     used to open a file browser window with
 
718
 *                                     a given set of locations.
 
719
 *
 
720
 *     GHI_CAP_SHELL_ACTION_RUN        Guest supports the 'run' action verb,
 
721
 *                                     used for running applications as well
 
722
 *                                     as opening file or URL locations.
 
723
 *
 
724
 *     GHI_CAP_SHELL_LOCATION_HGFS     Guest supports HGFS share location URIs:
 
725
 *                                     "x-vmware-share://<path>", where <path>
 
726
 *                                     specifies a shared folder name and an
 
727
 *                                     optional path within the shared folder.
 
728
 *
 
729
 * Results:
 
730
 *     TRUE if everything is successful.
 
731
 *     FALSE otherwise.
 
732
 *
 
733
 * Side effects:
 
734
 *     None.
 
735
 *
 
736
 *----------------------------------------------------------------------------
 
737
 */
 
738
 
 
739
static Bool
 
740
GHITcloShellAction(char const **result, // OUT
 
741
                   size_t *resultLen,   // OUT
 
742
                   const char *name,    // IN
 
743
                   const char *args,    // IN
 
744
                   size_t argsSize,     // IN
 
745
                   void *clientData)    // ignored
 
746
{
 
747
   Bool ret = TRUE;
 
748
   XDR xdrs;
 
749
 
 
750
   /*
 
751
    * Build an XDR Stream from the argument data which beings are args + 1
 
752
    * since there is a space separator between the RPC name and the XDR serialization.
 
753
    */
 
754
   xdrmem_create(&xdrs, (char *) args + 1, argsSize - 1, XDR_DECODE);
 
755
 
 
756
   ret = GHIPlatformShellAction(ghiPlatformData, &xdrs);
 
757
 
 
758
   xdr_destroy(&xdrs);
 
759
 
 
760
   if (!ret) {
 
761
      Debug("%s: Could not perform the requested shell action.\n", __FUNCTION__);
 
762
      return RpcIn_SetRetVals(result, resultLen,
 
763
                              "Could not perform the requested shell action.",
 
764
                              FALSE);
 
765
   }
 
766
 
 
767
   return RpcIn_SetRetVals(result, resultLen, "", TRUE);
 
768
}
 
769
 
 
770
 
 
771
/*
 
772
 *----------------------------------------------------------------------------
 
773
 *
 
774
 * GHITcloSetGuestHandler --
 
775
 *
 
776
 *     RPC handler for 'ghi.guest.handler.set'. Changes the nominated handlerType
 
777
 *     to use the VMwareHostOpen proxy app to open files or URLs in the host.
 
778
 *
 
779
 * Results:
 
780
 *     TRUE if everything is successful.
 
781
 *     FALSE otherwise.
 
782
 *
 
783
 * Side effects:
 
784
 *     None.
 
785
 *
 
786
 *----------------------------------------------------------------------------
 
787
 */
 
788
 
 
789
static Bool
 
790
GHITcloSetGuestHandler(RpcInData *data)        // IN/OUT
 
791
{
 
792
   Bool ret = FALSE;
 
793
   XDR xdrs;
 
794
 
 
795
   Debug("%s name:%s args length: %"FMTSZ"u\n", __FUNCTION__, data->name, data->argsSize);
 
796
 
 
797
   /*
 
798
    * Build an XDR Stream from the argument data which beings are args + 1
 
799
    * since there is a space separator between the RPC name and the XDR serialization.
 
800
    */
 
801
   xdrmem_create(&xdrs, (char *) data->args + 1, data->argsSize - 1, XDR_DECODE);
 
802
   ret = GHIPlatformSetGuestHandler(ghiPlatformData, &xdrs);
 
803
   xdr_destroy(&xdrs);
 
804
 
 
805
   if (ret == FALSE) {
 
806
      Debug("%s: Unable to set guest handler\n", __FUNCTION__);
 
807
      ret = RPCIN_SETRETVALS(data, "Unable to set guest handler", FALSE);
 
808
      goto exit;
 
809
   }
 
810
   /*
 
811
    * Write the final result into the result out parameters and return!
 
812
    */
 
813
    data->result = "";
 
814
    data->resultLen = 0;
 
815
    data->freeResult = FALSE;
 
816
    ret = TRUE;
 
817
 
 
818
exit:
 
819
    return ret;
 
820
}
 
821
 
 
822
 
 
823
/*
 
824
 *----------------------------------------------------------------------------
 
825
 *
 
826
 * GHITcloRestoreDefaultGuestHandler --
 
827
 *
 
828
 *     RPC handler for 'ghi.guest.handler.restoreDefault'. Changes the nominated
 
829
 *     handlerType back to the value in use prior to any changes by tools.
 
830
 *
 
831
 * Results:
 
832
 *     TRUE if everything is successful.
 
833
 *     FALSE otherwise.
 
834
 *
 
835
 * Side effects:
 
836
 *     None.
 
837
 *
 
838
 *----------------------------------------------------------------------------
 
839
 */
 
840
 
 
841
static Bool
 
842
GHITcloRestoreDefaultGuestHandler(RpcInData *data)        // IN/OUT
 
843
{
 
844
   Bool ret = FALSE;
 
845
   XDR xdrs;
 
846
 
 
847
   Debug("%s name:%s args length: %"FMTSZ"u\n", __FUNCTION__, data->name, data->argsSize);
 
848
 
 
849
   /*
 
850
    * Build an XDR Stream from the argument data which beings are args + 1
 
851
    * since there is a space separator between the RPC name and the XDR serialization.
 
852
    */
 
853
   xdrmem_create(&xdrs, (char *) data->args + 1, data->argsSize - 1, XDR_DECODE);
 
854
   ret = GHIPlatformRestoreDefaultGuestHandler(ghiPlatformData, &xdrs);
 
855
   xdr_destroy(&xdrs);
 
856
 
 
857
   if (ret == FALSE) {
 
858
      Debug("%s: Unable to restore guest handler\n", __FUNCTION__);
 
859
      ret = RPCIN_SETRETVALS(data, "Unable to restore guest handler", FALSE);
 
860
      goto exit;
 
861
   }
 
862
   /*
 
863
    * Write the final result into the result out parameters and return!
 
864
    */
 
865
    data->result = "";
 
866
    data->resultLen = 0;
 
867
    data->freeResult = FALSE;
 
868
    ret = TRUE;
 
869
 
 
870
exit:
 
871
    return ret;
 
872
}
 
873
 
 
874
 
 
875
/*
 
876
 *----------------------------------------------------------------------------
 
877
 *
 
878
 * GHILaunchMenuChangeRPC --
 
879
 *
 
880
 *     Informs host that one or more Launch Menu changes have been detected.
 
881
 *
 
882
 * Results:
 
883
 *     TRUE on success
 
884
 *     FALSE on error
 
885
 *
 
886
 * Side effects:
 
887
 *     None.
 
888
 *
 
889
 *----------------------------------------------------------------------------
 
890
 */
 
891
 
 
892
Bool
 
893
GHILaunchMenuChangeRPC(void)
 
894
{
 
895
   if (!RpcOut_sendOne(NULL, NULL, GHI_RPC_LAUNCHMENU_CHANGE)) {
 
896
      Debug("%s: could not send unity launchmenu change\n", __FUNCTION__);
 
897
      return FALSE;
 
898
   }
 
899
 
 
900
   return TRUE;
 
901
}
 
902
 
 
903
 
 
904
/*
 
905
 *-----------------------------------------------------------------------------
 
906
 *
 
907
 * GHIUpdateHost --
 
908
 *
 
909
 *    Update the host with new guest/host integration information.
 
910
 *
 
911
 * Results:
 
912
 *    TRUE on success, FALSE on failure.
 
913
 *
 
914
 * Side effects:
 
915
 *    VMDB is updated if the given value has changed.
 
916
 *
 
917
 *-----------------------------------------------------------------------------
 
918
 */
 
919
 
 
920
Bool
 
921
GHIUpdateHost(GHIProtocolHandlerList *handlers) // IN: type specific information
 
922
{
 
923
   /* +1 for the space separator */
 
924
   char request[sizeof GHI_RPC_PROTOCOL_HANDLER_INFO + 1];
 
925
   Bool status;
 
926
   XDR xdrs;
 
927
 
 
928
   ASSERT(handlers);
 
929
 
 
930
   if (DynXdr_Create(&xdrs) == NULL) {
 
931
      return FALSE;
 
932
   }
 
933
 
 
934
   Str_Sprintf(request,
 
935
               sizeof request,
 
936
               "%s ",
 
937
               GHI_RPC_PROTOCOL_HANDLER_INFO);
 
938
 
 
939
   /* Write preamble and serialized protocol handler info to XDR stream. */
 
940
   if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) ||
 
941
       !xdr_GHIProtocolHandlerList(&xdrs, handlers)) {
 
942
      Debug("%s: could not serialize protocol handler info\n", __FUNCTION__);
 
943
      DynXdr_Destroy(&xdrs, TRUE);
 
944
      return FALSE;
 
945
   }
 
946
 
 
947
   status = RpcOut_SendOneRaw(DynXdr_Get(&xdrs),
 
948
                              xdr_getpos(&xdrs),
 
949
                              NULL,
 
950
                              NULL);
 
951
   DynXdr_Destroy(&xdrs, TRUE);
 
952
 
 
953
   if (!status) {
 
954
      Debug("%s: failed to update protocol handler information\n",
 
955
            __FUNCTION__);
 
956
   }
 
957
   return status;
 
958
}