]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Per session capabilities
authorVMware, Inc <>
Tue, 19 Oct 2010 20:09:43 +0000 (13:09 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Tue, 19 Oct 2010 20:09:43 +0000 (13:09 -0700)
Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/hgfsServer/hgfsServerInt.h
open-vm-tools/lib/hgfsServer/hgfsServerParameters.c
open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c
open-vm-tools/lib/include/hgfsServer.h

index 231a21bed819a5ce657459f69a305f69a8859a22..c4f252802751a93b6986c91eb62d2375ee4e1ebe 100644 (file)
 /* Default maximun number of open nodes that have server locks. */
 #define MAX_LOCKED_FILENODES 10
 
-
 /* Maximum number of cached open nodes. */
 static unsigned int maxCachedOpenNodes;
 
@@ -159,6 +158,7 @@ static void HgfsServerSessionReceive(HgfsPacket *packet,
                                      void *clientData);
 static Bool HgfsServerSessionConnect(void *transportData,
                                      HgfsServerChannelCallbacks *channelCbTable,
+                                     uint32 channelCapabililies,
                                      void **clientData);
 static void HgfsServerSessionDisconnect(void *clientData);
 static void HgfsServerSessionClose(void *clientData);
@@ -2988,6 +2988,43 @@ HgfsGenerateSessionId(void)
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerSetSessionCapability --
+ *
+ *    Sets session capability for a specific operation code.
+ *
+ * Results:
+ *    TRUE is the capability for the operation has been changed.
+ *    FALSE if the operation is not represented in the capabilities array.
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+HgfsServerSetSessionCapability(HgfsOp op,                  // IN: operation code
+                               uint32 flags,               // IN: flags that describe level of support
+                               HgfsSessionInfo *session)   // INOUT: session to update
+{
+   int i;
+   Bool result = FALSE;
+
+   for ( i = 0; i < ARRAYSIZE(session->hgfsSessionCapabilities); i++) {
+      if (session->hgfsSessionCapabilities[i].op == op) {
+         session->hgfsSessionCapabilities[i].flags = flags;
+         result = TRUE;
+      }
+   }
+   LOG(4, ("%s: Setting capabilitiy flags %x for op code %d %s\n", __FUNCTION__, flags,
+           op, result ? "succeeded" : "failed"));
+   return result;
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -3010,6 +3047,7 @@ HgfsGenerateSessionId(void)
 static Bool
 HgfsServerSessionConnect(void *transportData,                         // IN: transport session context
                          HgfsServerChannelCallbacks *channelCbTable,  // IN: Channel callbacks
+                         uint32 channelCapabililies,                  // IN: channel capabilities
                          void **sessionData)                          // OUT: server session context
 {
    int i;
@@ -3102,10 +3140,19 @@ HgfsServerSessionConnect(void *transportData,                         // IN: tra
    session->channelCbTable = channelCbTable;
    Atomic_Write(&session->refCount, 0);
 
+   /* Get common to all sessions capabiities. */
+   HgfsServerGetDefaultCapabilities(session->hgfsSessionCapabilities,
+                                    &session->numberOfCapabilities);
+
    /* Give our session a reference to hold while we are open. */
    HgfsServerSessionGet(session);
    *sessionData = session;
 
+   if (channelCapabililies & HGFS_CHANNEL_SHARED_MEM) {
+      HgfsServerSetSessionCapability(HGFS_OP_READ_FAST_V4, HGFS_REQUEST_SUPPORTED, session);
+      HgfsServerSetSessionCapability(HGFS_OP_WRITE_FAST_V4, HGFS_REQUEST_SUPPORTED, session);
+   }
+
    return TRUE;
 }
 
index e978f82bff6117689fc472b5e8fd47f6bd79b5c0..e67837390c1355ea1e341fb53c5ed42efdd23e08 100644 (file)
@@ -348,6 +348,11 @@ typedef struct HgfsSessionInfo {
    DblLnkLst_Links searchFreeList;
    /** END SEARCH ARRAY ****************************************************/
 
+   /* Array of session specific capabiities. */
+   HgfsCapability hgfsSessionCapabilities[HGFS_OP_MAX];
+
+   uint32 numberOfCapabilities;
+
 } HgfsSessionInfo;
 
 
@@ -787,6 +792,9 @@ HgfsPackDestorySessionReply(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
                             char const *packetHeader,  // IN: packet header
                             size_t *payloadSize,       // OUT: size of packet
                             HgfsSessionInfo *session); // IN: Session Info
+void
+HgfsServerGetDefaultCapabilities(HgfsCapability *capabilities,   // OUT:
+                                 uint32 *numberOfCapabilities);  // OUT:
 /* Node cache functions. */
 
 Bool
index d9330ac87014aaca88bca32b0f39edb430631b93..3829055a58c588c0089c66efda0c55ae1e794acf 100644 (file)
       ASSERT(payloadSize); \
    } while(0)
 
-/* Capabilities of the HGFS server. */
-static HgfsCapability hgfsServerCapabilities[] =
+/*
+ * This is the default/minimal set of capabilities which is supported by every transport.
+ * Every transport and session may have additional capabilities in addition to these.
+ */
+static HgfsCapability hgfsDefaultCapabilityTable[] =
 {
    {HGFS_OP_OPEN,                  HGFS_REQUEST_SUPPORTED},
    {HGFS_OP_READ,                  HGFS_REQUEST_SUPPORTED},
@@ -97,8 +100,8 @@ static HgfsCapability hgfsServerCapabilities[] =
    {HGFS_OP_WRITE_WIN32_STREAM_V3, HGFS_REQUEST_WIN32_SUPPORTED},
    {HGFS_OP_CREATE_SESSION_V4,     HGFS_REQUEST_SUPPORTED},
    {HGFS_OP_DESTROY_SESSION_V4,    HGFS_REQUEST_SUPPORTED},
-   {HGFS_OP_READ_FAST_V4,          HGFS_REQUEST_SUPPORTED},
-   {HGFS_OP_WRITE_FAST_V4,         HGFS_REQUEST_SUPPORTED},
+   {HGFS_OP_READ_FAST_V4,          HGFS_REQUEST_NOT_SUPPORTED},
+   {HGFS_OP_WRITE_FAST_V4,         HGFS_REQUEST_NOT_SUPPORTED},
    {HGFS_OP_OPEN_V4,               HGFS_REQUEST_NOT_SUPPORTED},
    {HGFS_OP_DIRECTORY_READ_V4,     HGFS_REQUEST_NOT_SUPPORTED},
    {HGFS_OP_ENUMERATE_STREAMS_V4,  HGFS_REQUEST_NOT_SUPPORTED},
@@ -4779,23 +4782,22 @@ HgfsPackCreateSessionReply(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 {
    Bool result;
    HgfsReplyCreateSessionV4 *reply;
-   uint32 numCapabilities = ARRAYSIZE(hgfsServerCapabilities);
+   uint32 numCapabilities = session->numberOfCapabilities;
+   uint32 capabilitiesLen = numCapabilities * sizeof *session->hgfsSessionCapabilities;
 
    HGFS_ASSERT_PACK_PARAMS;
 
-   *payloadSize = offsetof(HgfsReplyCreateSessionV4, capabilities) +
-      sizeof hgfsServerCapabilities;
+   *payloadSize = offsetof(HgfsReplyCreateSessionV4, capabilities) + capabilitiesLen;
 
-   result = HgfsAllocInitReply(packet, packetHeader, *payloadSize,
-                               (void **)&reply, session);
+   result = HgfsAllocInitReply(packet, packetHeader, *payloadSize, (void **)&reply,
+                               session);
    if (result) {
       reply->sessionId = session->sessionId;
       reply->numCapabilities = numCapabilities;
       reply->maxPacketSize = session->maxPacketSize;
       reply->identityOffset = 0;
       reply->reserved = 0;
-      memcpy(reply->capabilities, hgfsServerCapabilities,
-             sizeof hgfsServerCapabilities);
+      memcpy(reply->capabilities, session->hgfsSessionCapabilities, capabilitiesLen);
    }
 
    return result;
@@ -4841,3 +4843,29 @@ HgfsPackDestorySessionReply(HgfsPacket *packet,        // IN/OUT: Hgfs Packet
 
    return result;
 }
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsServerGetDefaultCapabilities --
+ *
+ *    Returns list capabilities that are supported by all sessions.
+ *
+ * Results:
+ *    None
+ *
+ * Side effects:
+ *    None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+HgfsServerGetDefaultCapabilities(HgfsCapability *capabilities,  // OUT: capabilities
+                                 uint32 *numberOfCapabilities)  // OUT: number of items
+{
+   *numberOfCapabilities = ARRAYSIZE(hgfsDefaultCapabilityTable);
+   ASSERT(*numberOfCapabilities <= HGFS_OP_MAX);
+   memcpy(capabilities, hgfsDefaultCapabilityTable, sizeof hgfsDefaultCapabilityTable);
+}
index 52e911d19a51a7b6c39c1c6e2338e6d9853ec4a0..cf8ad23a047766a9f67f0a89ec2013dfac259ffc 100644 (file)
@@ -349,6 +349,7 @@ HgfsChannelGuestConnConnect(HgfsGuestConn *connData)  // IN: our connection data
    connData->channelCbTable.send = HgfsChannelGuestBdSend;
    result = connData->serverCbTable->connect(connData,
                                              &connData->channelCbTable,
+                                             0,
                                              &connData->serverSession);
    if (result) {
       HgfsChannelGuestConnGet(connData);
index 412722e779aa4ae7e9cdac56e53b455d1f1ebee6..da66e9589b625dc533024e4b66876958a19479a7 100644 (file)
@@ -111,6 +111,9 @@ typedef uint32 HgfsSendFlags;
 #define HGFS_SEND_CAN_DELAY         (1 << 0)
 #define HGFS_SEND_NO_COMPLETE       (1 << 1)
 
+// Channel capability flags
+#define HGFS_CHANNEL_SHARED_MEM     (1 << 0)
+#define HGFS_CHANNEL_ASYNC          (1 << 1)
 
 typedef Bool
 HgfsSessionSendFunc(void *opaqueSession,  // IN
@@ -127,7 +130,7 @@ typedef struct HgfsServerChannelCallbacks {
 }HgfsServerChannelCallbacks;
 
 typedef struct HgfsServerSessionCallbacks {
-   Bool (*connect)(void *, HgfsServerChannelCallbacks *, void **);
+   Bool (*connect)(void *, HgfsServerChannelCallbacks *, uint32 ,void **);
    void (*disconnect)(void *);
    void (*close)(void *);
    void (*receive)(HgfsPacket *packet, void *);