~n-muench/ubuntu/precise/open-vm-tools/open-vm-tools-precise.sid-merge1

« back to all changes in this revision

Viewing changes to lib/hgfsServerManagerGuest/hgfsChannelGuest.c

  • 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
 * hgfsChannelGuest.c --
 
21
 *
 
22
 *    Channel abstraction for the HGFS server.
 
23
 *
 
24
 */
 
25
 
 
26
#include <stdlib.h>
 
27
#include "vm_assert.h"
 
28
#include "vm_atomic.h"
 
29
#include "util.h"
 
30
#if defined(VMTOOLS_USE_GLIB)
 
31
#define G_LOG_DOMAIN "hgfsd"
 
32
#define Debug                 g_debug
 
33
#define Warning               g_warning
 
34
#include "vmware/tools/guestrpc.h"
 
35
#include "vmware/tools/utils.h"
 
36
// #include <glib.h>
 
37
#else
 
38
#include "debug.h"
 
39
#endif
 
40
#include "hgfsChannelGuestInt.h"
 
41
#include "hgfsServer.h"
 
42
#include "hgfsServerManager.h"
 
43
 
 
44
/*
 
45
 * HGFS server connection channel and state object usage.
 
46
 *
 
47
 * Currently, all plugins can share this same HGFS server channel and state.
 
48
 * This allows us to use a common channel so it is only initialized
 
49
 * once, by the first loaded plugin which requires an HGFS channel, and torn
 
50
 * down when the final plugin that uses the HGFS server is unloaded.
 
51
 *
 
52
 * Currently, the plugins are loaded (and unloaded) in any particular order,
 
53
 * and those operations are serialized. (For example the HGFS server plugin
 
54
 * maybe the first plugin loaded that uses this channel, but is not the final
 
55
 * plugin to be unloaded that uses the channel. This also may change in the
 
56
 * future, so no dependencies can be made on order of loading and unloading
 
57
 * of plugins.)
 
58
 * Furthermore, multiple plugins use the HGFS channel and server and some plugins
 
59
 * have multiple connections. Some plugins also create and teardown connections
 
60
 * during general mutlithreaded operation of the tools processes.
 
61
 *
 
62
 * In order to support the above, we must track how many users of the shared
 
63
 * connection there are. This allows us to tear down the shared connection
 
64
 * when the final plugin that is using it is unloaded, and when no
 
65
 * channels are in use the HGFS server state can be torn down.
 
66
 */
 
67
 
 
68
/*
 
69
 * The HGFS server state.
 
70
 *
 
71
 * This object is initiliazed once only and is shared across all
 
72
 * connections, shared or private.
 
73
 * Each new channel connection will reference the server and so the HGFS
 
74
 * server is initialized when the first new channel is being created. Each
 
75
 * new channel just increments the reference of server state object.
 
76
 * When the final channel is torn down the final HGFS server reference is
 
77
 * also removed and the HGFS server exit is called and this object is torn down.
 
78
 */
 
79
typedef struct HgfsChannelServerData {
 
80
   HgfsServerSessionCallbacks *serverCBTable; /* HGFS server entry points. */
 
81
   Atomic_uint32              refCount;       /* Server data reference count. */
 
82
} HgfsChannelServerData;
 
83
 
 
84
/*
 
85
 * Transport channels context.
 
86
 *
 
87
 * Multiple callers share this same channel currently as only one
 
88
 * transport channel is required. Therefore, the channel is referenced
 
89
 * for each client that it is returned to (a usage count).
 
90
 */
 
91
typedef struct HgfsChannelData {
 
92
   const char                 *name;          /* Channel name. */
 
93
   HgfsGuestChannelCBTable    *ops;           /* Channel operations. */
 
94
   uint32                     state;          /* Channel state (see flags below). */
 
95
   struct HgfsGuestConn       *connection;    /* Opaque server connection */
 
96
   HgfsChannelServerData      *serverInfo;    /* HGFS server entry points. */
 
97
   Atomic_uint32              refCount;       /* Channel reference count. */
 
98
} HgfsChannelData;
 
99
 
 
100
#define HGFS_CHANNEL_STATE_INIT         (1 << 0)
 
101
#define HGFS_CHANNEL_STATE_CBINIT       (1 << 1)
 
102
 
 
103
/* Static channel registration - assumes only one for now. */
 
104
static HgfsChannelData gHgfsChannels[] = {
 
105
   { "guest", &gGuestBackdoorOps, 0, NULL, NULL, {0} },
 
106
};
 
107
 
 
108
/* HGFS server info state. Referenced by each separate channel that uses it. */
 
109
static HgfsChannelServerData gHgfsChannelServerInfo = { NULL, {0} };
 
110
 
 
111
static void HgfsChannelTeardownChannel(HgfsChannelData *channel);
 
112
static void HgfsChannelTeardownServer(HgfsChannelServerData *serverInfo);
 
113
static void HgfsChannelExitChannel(HgfsChannelData *channel);
 
114
 
 
115
 
 
116
/*
 
117
 *----------------------------------------------------------------------------
 
118
 *
 
119
 * HGFS SERVER DATA FUNCTIONS
 
120
 *
 
121
 *----------------------------------------------------------------------------
 
122
 */
 
123
 
 
124
 
 
125
/*
 
126
 *----------------------------------------------------------------------------
 
127
 *
 
128
 * HgfsChannelGetServer --
 
129
 *
 
130
 *      Increment the server data reference count.
 
131
 *
 
132
 * Results:
 
133
 *      The value of the reference count before the increment.
 
134
 *
 
135
 * Side effects:
 
136
 *      None.
 
137
 *
 
138
 *----------------------------------------------------------------------------
 
139
 */
 
140
 
 
141
static uint32
 
142
HgfsChannelGetServer(HgfsChannelServerData *serverInfo)   // IN/OUT: ref count
 
143
{
 
144
   ASSERT(NULL != serverInfo);
 
145
   return Atomic_FetchAndInc(&serverInfo->refCount);
 
146
}
 
147
 
 
148
 
 
149
/*
 
150
 *----------------------------------------------------------------------------
 
151
 *
 
152
 * HgfsChannelPutServer --
 
153
 *
 
154
 *      Decrement server data reference count.
 
155
 *
 
156
 *      Teardown the server data object if removed the final reference.
 
157
 *
 
158
 * Results:
 
159
 *      None.
 
160
 *
 
161
 * Side effects:
 
162
 *      None.
 
163
 *
 
164
 *----------------------------------------------------------------------------
 
165
 */
 
166
 
 
167
static void
 
168
HgfsChannelPutServer(HgfsChannelServerData *serverInfo)   // IN/OUT: ref count
 
169
{
 
170
   ASSERT(NULL != serverInfo);
 
171
   if (Atomic_FetchAndDec(&serverInfo->refCount) == 1) {
 
172
      HgfsChannelTeardownServer(serverInfo);
 
173
   }
 
174
}
 
175
 
 
176
 
 
177
/*
 
178
 *----------------------------------------------------------------------------
 
179
 *
 
180
 * HgfsChannelInitServer --
 
181
 *
 
182
 *      Initialize HGFS server and save the state.
 
183
 *
 
184
 * Results:
 
185
 *      TRUE if success, FALSE otherwise.
 
186
 *
 
187
 * Side effects:
 
188
 *      None.
 
189
 *
 
190
 *----------------------------------------------------------------------------
 
191
 */
 
192
 
 
193
static Bool
 
194
HgfsChannelInitServer(HgfsChannelServerData *serverInfo)   // IN/OUT: ref count
 
195
{
 
196
   Bool result;
 
197
 
 
198
   ASSERT(NULL == serverInfo->serverCBTable);
 
199
 
 
200
   Debug("%s: Initialize Hgfs server.\n", __FUNCTION__);
 
201
   /* If we have a new connection initialize the server session. */
 
202
   result = HgfsServer_InitState(&serverInfo->serverCBTable, NULL);
 
203
   if (!result) {
 
204
      Debug("%s: Could not init Hgfs server.\n", __FUNCTION__);
 
205
   }
 
206
   return result;
 
207
}
 
208
 
 
209
 
 
210
/*
 
211
 *----------------------------------------------------------------------------
 
212
 *
 
213
 * HgfsChannelExitServer --
 
214
 *
 
215
 *      Reset the HGFS server and destroy the state.
 
216
 *
 
217
 * Results:
 
218
 *      None.
 
219
 *
 
220
 * Side effects:
 
221
 *      None.
 
222
 *
 
223
 *----------------------------------------------------------------------------
 
224
 */
 
225
 
 
226
static void
 
227
HgfsChannelExitServer(HgfsChannelServerData *serverInfo)   // IN/OUT: ref count
 
228
{
 
229
   if (NULL != serverInfo->serverCBTable) {
 
230
      Debug("%s: Teardown Hgfs server.\n", __FUNCTION__);
 
231
      HgfsServer_ExitState();
 
232
      serverInfo->serverCBTable = NULL;
 
233
   }
 
234
}
 
235
 
 
236
 
 
237
/*
 
238
 *----------------------------------------------------------------------------
 
239
 *
 
240
 * HgfsChannelTeardownServer --
 
241
 *
 
242
 *      Teardown the HGFS server state for all connections.
 
243
 *
 
244
 * Results:
 
245
 *      None.
 
246
 *
 
247
 * Side effects:
 
248
 *      None.
 
249
 *
 
250
 *----------------------------------------------------------------------------
 
251
 */
 
252
 
 
253
static void
 
254
HgfsChannelTeardownServer(HgfsChannelServerData *serverInfo) // IN/OUT: connection manager object
 
255
{
 
256
   HgfsChannelExitServer(serverInfo);
 
257
}
 
258
 
 
259
 
 
260
/*
 
261
 *----------------------------------------------------------------------------
 
262
 *
 
263
 * CHANNEL DATA FUNCTIONS
 
264
 *
 
265
 *----------------------------------------------------------------------------
 
266
 */
 
267
 
 
268
 
 
269
 /*
 
270
 *----------------------------------------------------------------------------
 
271
 *
 
272
 * HgfsChannelGetChannel --
 
273
 *
 
274
 *      Increment channel data reference count.
 
275
 *
 
276
 * Results:
 
277
 *      The value of the reference count before the increment.
 
278
 *
 
279
 * Side effects:
 
280
 *      None.
 
281
 *
 
282
 *----------------------------------------------------------------------------
 
283
 */
 
284
 
 
285
uint32
 
286
HgfsChannelGetChannel(HgfsChannelData *channel)   // IN/OUT: ref count
 
287
{
 
288
   ASSERT(NULL != channel);
 
289
   return Atomic_FetchAndInc(&channel->refCount);
 
290
}
 
291
 
 
292
 
 
293
/*
 
294
 *----------------------------------------------------------------------------
 
295
 *
 
296
 * HgfsChannelPutChannel --
 
297
 *
 
298
 *      Decrement channel reference count.
 
299
 *
 
300
 *      Teardown channel object if removed the final reference.
 
301
 *
 
302
 * Results:
 
303
 *      None.
 
304
 *
 
305
 * Side effects:
 
306
 *      None.
 
307
 *
 
308
 *----------------------------------------------------------------------------
 
309
 */
 
310
 
 
311
static void
 
312
HgfsChannelPutChannel(HgfsChannelData *channel)   // IN/OUT: ref count
 
313
{
 
314
   ASSERT(NULL != channel);
 
315
   if (Atomic_FetchAndDec(&channel->refCount) == 1) {
 
316
      HgfsChannelTeardownChannel(channel);
 
317
   }
 
318
}
 
319
 
 
320
 
 
321
/*
 
322
 *-----------------------------------------------------------------------------
 
323
 *
 
324
 * HgfsChannelInitChannel --
 
325
 *
 
326
 *      Initializes a channel by initializing the HGFS server state.
 
327
 *
 
328
 * Results:
 
329
 *      TRUE if the channel initialized, FALSE otherwise.
 
330
 *
 
331
 * Side effects:
 
332
 *      None.
 
333
 *
 
334
 *-----------------------------------------------------------------------------
 
335
 */
 
336
 
 
337
static Bool
 
338
HgfsChannelInitChannel(HgfsChannelData *channel,          // IN/OUT: channel object
 
339
                       HgfsChannelServerData *serverInfo) // IN/OUT: server info
 
340
{
 
341
   Bool result = TRUE;
 
342
   uint32 serverInfoCount;
 
343
 
 
344
   channel->state = 0;
 
345
   /*
 
346
    * Reference the HGFS server as it will be used by the new channel.
 
347
    * The HGFS server should only be initialized once, i.e. on the first
 
348
    * caller instance, otherwise only reference the server info for
 
349
    * the new channel.
 
350
    */
 
351
   serverInfoCount = HgfsChannelGetServer(serverInfo);
 
352
   /* Referenced the server, save it for dereferencing. */
 
353
   channel->serverInfo = serverInfo;
 
354
   if (0 == serverInfoCount) {
 
355
      /* The HGFS server has not been initialized, do it now. */
 
356
      result = HgfsChannelInitServer(channel->serverInfo);
 
357
      if (!result) {
 
358
         Debug("%s: Could not init Hgfs server.\n", __FUNCTION__);
 
359
         goto exit;
 
360
      }
 
361
   }
 
362
 
 
363
   channel->state |= HGFS_CHANNEL_STATE_INIT;
 
364
 
 
365
exit:
 
366
   if (!result) {
 
367
      HgfsChannelExitChannel(channel);
 
368
   }
 
369
   Debug("%s: Init channel return %d.\n", __FUNCTION__, result);
 
370
   return result;
 
371
}
 
372
 
 
373
 
 
374
/*
 
375
 *-----------------------------------------------------------------------------
 
376
 *
 
377
 * HgfsChannelExitChannel --
 
378
 *
 
379
 *      Teardown the channel and teardown the HGFS server.
 
380
 *
 
381
 * Results:
 
382
 *      None.
 
383
 *
 
384
 * Side effects:
 
385
 *      None.
 
386
 *
 
387
 *-----------------------------------------------------------------------------
 
388
 */
 
389
 
 
390
static void
 
391
HgfsChannelExitChannel(HgfsChannelData *channel) // IN/OUT: channel object
 
392
{
 
393
   if (NULL != channel->serverInfo) {
 
394
      /* Remove the reference for the HGFS server info. */
 
395
      HgfsChannelPutServer(channel->serverInfo);
 
396
      channel->serverInfo = NULL;
 
397
    }
 
398
   channel->state = 0;
 
399
   Debug("%s: Exit channel returns.\n", __FUNCTION__);
 
400
}
 
401
 
 
402
 
 
403
/*
 
404
 *-----------------------------------------------------------------------------
 
405
 *
 
406
 * HgfsChannelActivateChannel --
 
407
 *
 
408
 *      Activate a channel by calling the channels init callback.
 
409
 *
 
410
 * Results:
 
411
 *      TRUE if a channel is active.
 
412
 *
 
413
 * Side effects:
 
414
 *      None.
 
415
 *
 
416
 *-----------------------------------------------------------------------------
 
417
 */
 
418
 
 
419
static Bool
 
420
HgfsChannelActivateChannel(HgfsChannelData *channel,   // IN/OUT: channel object
 
421
                           void *rpc,                  // IN: Rpc channel
 
422
                           void *rpcCallback)          // IN: Rpc callback
 
423
{
 
424
   Bool success = FALSE;
 
425
   struct HgfsGuestConn *connData = NULL;
 
426
 
 
427
   if (channel->ops->init(channel->serverInfo->serverCBTable,
 
428
                          rpc,
 
429
                          rpcCallback,
 
430
                          &connData)) {
 
431
      channel->state |= HGFS_CHANNEL_STATE_CBINIT;
 
432
      channel->connection = connData;
 
433
      success = TRUE;
 
434
   }
 
435
   return success;
 
436
}
 
437
 
 
438
 
 
439
/*
 
440
 *-----------------------------------------------------------------------------
 
441
 *
 
442
 * HgfsChannelDeactivateChannel --
 
443
 *
 
444
 *      Deactivate a channel by calling the channels exit callback.
 
445
 *
 
446
 * Results:
 
447
 *      None.
 
448
 *
 
449
 * Side effects:
 
450
 *      None.
 
451
 *
 
452
 *-----------------------------------------------------------------------------
 
453
 */
 
454
 
 
455
static void
 
456
HgfsChannelDeactivateChannel(HgfsChannelData *channel)   // IN/OUT: channel object
 
457
{
 
458
   channel->ops->exit(channel->connection);
 
459
   channel->state &= ~HGFS_CHANNEL_STATE_CBINIT;
 
460
   channel->connection = NULL;
 
461
}
 
462
 
 
463
 
 
464
/*
 
465
 *-----------------------------------------------------------------------------
 
466
 *
 
467
 * HgfsChannelIsChannelActive --
 
468
 *
 
469
 *      Is the channel active (initialized) for processing requests.
 
470
 *
 
471
 * Results:
 
472
 *      TRUE if a channel is active.
 
473
 *
 
474
 * Side effects:
 
475
 *      None.
 
476
 *
 
477
 *-----------------------------------------------------------------------------
 
478
 */
 
479
 
 
480
static Bool
 
481
HgfsChannelIsChannelActive(HgfsChannelData *channel) // IN/OUT: channel object
 
482
{
 
483
   return (0 != (channel->state & HGFS_CHANNEL_STATE_INIT) &&
 
484
           0 != (channel->state & HGFS_CHANNEL_STATE_CBINIT));
 
485
}
 
486
 
 
487
 
 
488
/*
 
489
 *-----------------------------------------------------------------------------
 
490
 *
 
491
 * HgfsChannelReceive --
 
492
 *
 
493
 *      Received a request on a channel pass on to the channel callback.
 
494
 *
 
495
 * Results:
 
496
 *      TRUE if a channel ws deactivated.
 
497
 *
 
498
 * Side effects:
 
499
 *      None.
 
500
 *
 
501
 *-----------------------------------------------------------------------------
 
502
 */
 
503
 
 
504
static Bool
 
505
HgfsChannelReceive(HgfsChannelData *channel,   // IN/OUT: channel object
 
506
                   char const *packetIn,       // IN: incoming packet
 
507
                   size_t packetInSize,        // IN: incoming packet size
 
508
                   char *packetOut,            // OUT: outgoing packet
 
509
                   size_t *packetOutSize)      // IN/OUT: outgoing packet size
 
510
{
 
511
   return channel->ops->receive(channel->connection,
 
512
                                packetIn,
 
513
                                packetInSize,
 
514
                                packetOut,
 
515
                                packetOutSize);
 
516
}
 
517
 
 
518
 
 
519
/*
 
520
 *----------------------------------------------------------------------------
 
521
 *
 
522
 * HgfsChannelTeardownChannel --
 
523
 *
 
524
 *      Teardown the channel for HGFS.
 
525
 *
 
526
 * Results:
 
527
 *      None.
 
528
 *
 
529
 * Side effects:
 
530
 *      None.
 
531
 *
 
532
 *----------------------------------------------------------------------------
 
533
 */
 
534
 
 
535
static void
 
536
HgfsChannelTeardownChannel(HgfsChannelData *channel) // IN/OUT: connection manager object
 
537
{
 
538
   if (HgfsChannelIsChannelActive(channel)) {
 
539
      HgfsChannelDeactivateChannel(channel);
 
540
   }
 
541
   HgfsChannelExitChannel(channel);
 
542
}
 
543
 
 
544
 
 
545
/*
 
546
 *----------------------------------------------------------------------------
 
547
 *
 
548
 * CHANNEL PUBLIC FUNCTIONS
 
549
 *
 
550
 *----------------------------------------------------------------------------
 
551
 */
 
552
 
 
553
 
 
554
/*
 
555
 *----------------------------------------------------------------------------
 
556
 *
 
557
 * HgfsChannelGuest_Init --
 
558
 *
 
559
 *      Sets up the channel for HGFS.
 
560
 *
 
561
 *      Initialize all the defined channels.
 
562
 *      At least one channel should succeed it's initialization
 
563
 *      completely, else we fail.
 
564
 *
 
565
 * Results:
 
566
 *      TRUE on success, FALSE on failure.
 
567
 *
 
568
 * Side effects:
 
569
 *      None.
 
570
 *
 
571
 *----------------------------------------------------------------------------
 
572
 */
 
573
 
 
574
Bool
 
575
HgfsChannelGuest_Init(HgfsServerMgrData *mgrData) // IN/OUT: connection manager object
 
576
{
 
577
   Bool success = FALSE;
 
578
   HgfsChannelData *channel = &gHgfsChannels[0]; // Shared channel (internal RPC)
 
579
   uint32 channelRefCount;
 
580
 
 
581
   ASSERT(NULL != mgrData);
 
582
   ASSERT(NULL == mgrData->connection);
 
583
   /* Currently, the RPC override is not implemented. */
 
584
   ASSERT(NULL == mgrData->rpc);
 
585
   ASSERT(NULL == mgrData->rpcCallback);
 
586
   ASSERT(NULL != mgrData->appName);
 
587
 
 
588
   Debug("%s: app %s rpc = %p rpc cb = %p.\n", __FUNCTION__,
 
589
         mgrData->appName, mgrData->rpc, mgrData->rpcCallback);
 
590
 
 
591
   if (NULL != mgrData->rpc || NULL != mgrData->rpcCallback) {
 
592
      /*
 
593
       * XXX - Would malloc a new channel here and activate
 
594
       * with the required RPC.
 
595
       */
 
596
 
 
597
      Debug("%s: Guest channel RPC override not supported.\n", __FUNCTION__);
 
598
      goto exit;
 
599
   }
 
600
 
 
601
   /*
 
602
    * Reference the channel. Initialize only for the first
 
603
    * caller instance, otherwise only reference the channel for
 
604
    * return to the caller.
 
605
    */
 
606
   channelRefCount = HgfsChannelGetChannel(channel);
 
607
   /* We have referenced the channel, save it for later dereference. */
 
608
   mgrData->connection = channel;
 
609
   if (0 == channelRefCount) {
 
610
 
 
611
      /* Initialize channels objects. */
 
612
      if (!HgfsChannelInitChannel(channel, &gHgfsChannelServerInfo)) {
 
613
         Debug("%s: Could not init channel.\n", __FUNCTION__);
 
614
         goto exit;
 
615
      }
 
616
 
 
617
      /* Call the channels initializers. */
 
618
      if (!HgfsChannelActivateChannel(channel,
 
619
                                      mgrData->rpc,
 
620
                                      mgrData->rpcCallback)) {
 
621
         Debug("%s: Could not activate channel.\n", __FUNCTION__);
 
622
         goto exit;
 
623
      }
 
624
   }
 
625
 
 
626
   success = TRUE;
 
627
 
 
628
exit:
 
629
   if (!success) {
 
630
      HgfsChannelGuest_Exit(mgrData);
 
631
   }
 
632
   return success;
 
633
}
 
634
 
 
635
 
 
636
/*
 
637
 *----------------------------------------------------------------------------
 
638
 *
 
639
 * HgfsChannelGuest_Exit --
 
640
 *
 
641
 *      Dereference the channel which for the final reference will
 
642
 *      close the channel for HGFS.
 
643
 *
 
644
 * Results:
 
645
 *      None.
 
646
 *
 
647
 * Side effects:
 
648
 *      None.
 
649
 *
 
650
 *----------------------------------------------------------------------------
 
651
 */
 
652
 
 
653
void
 
654
HgfsChannelGuest_Exit(HgfsServerMgrData *mgrData) // IN/OUT: connection manager object
 
655
{
 
656
   HgfsChannelData *channel;
 
657
 
 
658
   ASSERT(NULL != mgrData);
 
659
   ASSERT(NULL != mgrData->appName);
 
660
 
 
661
   channel = mgrData->connection;
 
662
 
 
663
   Debug("%s: app %s rpc = %p rpc cb = %p chn = %p.\n", __FUNCTION__,
 
664
         mgrData->appName, mgrData->rpc, mgrData->rpcCallback, channel);
 
665
 
 
666
   if (NULL != channel) {
 
667
      HgfsChannelPutChannel(channel);
 
668
      mgrData->connection = NULL;
 
669
   }
 
670
}
 
671
 
 
672
 
 
673
/*
 
674
 *----------------------------------------------------------------------------
 
675
 *
 
676
 * HgfsChannelGuest_Receive --
 
677
 *
 
678
 *    Process packet not associated with an HGFS only registered callback.
 
679
 *
 
680
 *
 
681
 * Results:
 
682
 *    TRUE if successfully processed FALSE otherwise.
 
683
 *
 
684
 * Side effects:
 
685
 *    None
 
686
 *
 
687
 *----------------------------------------------------------------------------
 
688
 */
 
689
 
 
690
Bool
 
691
HgfsChannelGuest_Receive(HgfsServerMgrData *mgrData, // IN/OUT : conn manager
 
692
                         char const *packetIn,       // IN: incoming packet
 
693
                         size_t packetInSize,        // IN: incoming packet size
 
694
                         char *packetOut,            // OUT: outgoing packet
 
695
                         size_t *packetOutSize)      // IN/OUT: outgoing packet size
 
696
{
 
697
   HgfsChannelData *channel = NULL;
 
698
   Bool result = FALSE;
 
699
 
 
700
   ASSERT(NULL != mgrData);
 
701
   ASSERT(NULL != mgrData->connection);
 
702
   ASSERT(NULL != mgrData->appName);
 
703
 
 
704
   channel = mgrData->connection;
 
705
 
 
706
   Debug("%s: %s Channel receive request.\n", __FUNCTION__, mgrData->appName);
 
707
 
 
708
   if (HgfsChannelIsChannelActive(channel)) {
 
709
      result = HgfsChannelReceive(channel,
 
710
                                  packetIn,
 
711
                                  packetInSize,
 
712
                                  packetOut,
 
713
                                  packetOutSize);
 
714
   }
 
715
 
 
716
   Debug("%s: Channel receive returns %#x.\n", __FUNCTION__, result);
 
717
 
 
718
   return result;
 
719
}