From: VMware, Inc <> Date: Mon, 21 Nov 2011 22:57:41 +0000 (-0800) Subject: Implement separate HgfsSessions for Transport layer and Sessions layer. X-Git-Tag: 2011.11.20-535097~71 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=48df7f3f3fb334e151c4d236b0c79f9efb1cb6f5;p=thirdparty%2Fopen-vm-tools.git Implement separate HgfsSessions for Transport layer and Sessions layer. To make the hgFileCopy more robust, we have decided to implement separate sessions in the transport layer and the session layer. I implemented a list of sessions in the transport layer. Moved the necessary attributes from HgfsTransportSessionInfo to HgfsSessionInfo. Modified all the necessary server connect|disconnect|receive|... functions to handle the packets properly. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index 0a89e5b17..787a4b15f 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -222,6 +222,11 @@ typedef struct HgfsSharedFolderProperties { Bool markedForDeletion; } HgfsSharedFolderProperties; +static void HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession, + HgfsSessionInfo *sessionInfo); + +static void HgfsServerTransportAddSessionToList(HgfsTransportSessionInfo *transportSession, + HgfsSessionInfo *sessionInfo); /* * Limit payload to 16M + header. * This limit ensures that list of shared pages fits into VMCI datagram. @@ -231,6 +236,9 @@ typedef struct HgfsSharedFolderProperties { /* Local functions. */ +static Bool HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, + uint32 channelCapabilities, + HgfsSessionInfo **sessionData); static void HgfsInvalidateSessionObjects(DblLnkLst_Links *shares, HgfsSessionInfo *session); static Bool HgfsAddToCacheInternal(HgfsHandle handle, @@ -361,12 +369,75 @@ static void HgfsServerSessionPut(HgfsSessionInfo *session) // IN: session context { ASSERT(session); + if (Atomic_FetchAndDec(&session->refCount) == 1) { HgfsServerExitSessionInternal(session); } } +/* + *---------------------------------------------------------------------------- + * + * HgfsServerTransportSessionGet -- + * + * Increment transport session reference count. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------------- + */ + +void +HgfsServerTransportSessionGet(HgfsTransportSessionInfo *transportSession) // IN: session context +{ + ASSERT(transportSession); + Atomic_Inc(&transportSession->refCount); +} + + +/* + *---------------------------------------------------------------------------- + * + * HgfsServerTransportSessionPut -- + * + * Decrement transport session reference count. + * + * Free session info data if no reference. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------------- + */ + +static void +HgfsServerTransportSessionPut(HgfsTransportSessionInfo *transportSession) // IN: transport session context +{ + ASSERT(transportSession); + if (Atomic_FetchAndDec(&transportSession->refCount) == 1) { + DblLnkLst_Links *curr, *next; + + MXUser_AcquireExclLock(transportSession->sessionArrayLock); + + DblLnkLst_ForEachSafe(curr, next, &transportSession->sessionArray) { + HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); + HgfsServerTransportRemoveSessionFromList(transportSession, session); + HgfsServerSessionPut(session); + } + + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); + } +} + + /* *----------------------------------------------------------------------------- * @@ -2861,7 +2932,7 @@ HgfsServerCompleteRequest(HgfsInternalStatus status, // IN: Status of the requ replySize = sizeof *header + replyPayloadSize; replyPacketSize = replySize; header = HSPU_GetReplyPacket(input->packet, &replyPacketSize, - input->session); + input->transportSession); packetOut = (char *)header; ASSERT_DEVEL(header && (replySize <= replyPacketSize)); @@ -2882,7 +2953,7 @@ HgfsServerCompleteRequest(HgfsInternalStatus status, // IN: Status of the requ } replyPacketSize = replySize; reply = HSPU_GetReplyPacket(input->packet, &replyPacketSize, - input->session); + input->transportSession); packetOut = (char *)reply; ASSERT_DEVEL(reply && (replySize <= replyPacketSize)); @@ -2892,12 +2963,13 @@ HgfsServerCompleteRequest(HgfsInternalStatus status, // IN: Status of the requ } } if (!HgfsPacketSend(input->packet, packetOut, replySize, - input->session, 0)) { + input->transportSession, 0)) { /* Send failed. Drop the reply. */ LOG(4, ("Error sending reply\n")); } HgfsServerSessionPut(input->session); + HgfsServerTransportSessionPut(input->transportSession); free(input); } @@ -2925,7 +2997,7 @@ HgfsServerProcessRequest(void *context) if (!input->metaPacket) { input->metaPacket = HSPU_GetMetaPacket(input->packet, &input->metaPacketSize, - input->session); + input->transportSession); } input->payload = (char *)input->metaPacket + input->payloadOffset; @@ -2968,24 +3040,24 @@ static void HgfsServerSessionReceive(HgfsPacket *packet, // IN: Hgfs Packet void *clientData) // IN: session info { - HgfsSessionInfo *session = (HgfsSessionInfo *)clientData; + HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; HgfsInternalStatus status; HgfsInputParam *input = NULL; - ASSERT(session); + ASSERT(transportSession); - if (session->state == HGFS_SESSION_STATE_CLOSED) { + if (transportSession->state == HGFS_SESSION_STATE_CLOSED) { LOG(4, ("%s: %d: Received packet after disconnected.\n", __FUNCTION__, __LINE__)); return; } - HgfsServerSessionGet(session); + HgfsServerTransportSessionGet(transportSession); - if (!HgfsParseRequest(packet, session, &input, &status)) { + if (!HgfsParseRequest(packet, transportSession, &input, &status)) { LOG(4, ("%s: %d: Can't generate any response for the guest, just exit.\n ", __FUNCTION__, __LINE__)); - HgfsServerSessionPut(session); + HgfsServerTransportSessionPut(transportSession); return; } @@ -3008,7 +3080,7 @@ HgfsServerSessionReceive(HgfsPacket *packet, // IN: Hgfs Packet * Asynchronous processing is supported by the transport. * We can release mappings here and reacquire when needed. */ - HSPU_PutMetaPacket(packet, session); + HSPU_PutMetaPacket(packet, transportSession); input->metaPacket = NULL; Atomic_Inc(&gHgfsAsyncCounter); @@ -3048,6 +3120,111 @@ HgfsServerSessionReceive(HgfsPacket *packet, // IN: Hgfs Packet } +/* + *----------------------------------------------------------------------------- + * + * HgfsServerTransportGetSessionInfo -- + * + * Scans the list of sessions and return the session with the specified + * session id. + * + * Results: + * A valid pointer to HgfsSessionInfo if there is a session with the + * specified session id. NULL, otherwise. + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +HgfsSessionInfo * +HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession, // IN: transport session info + uint64 sessionId) // IN: session id +{ + DblLnkLst_Links *curr; + HgfsSessionInfo *session = NULL; + + ASSERT(transportSession); + + MXUser_AcquireExclLock(transportSession->sessionArrayLock); + + DblLnkLst_ForEach(curr, &transportSession->sessionArray) { + session = DblLnkLst_Container(curr, HgfsSessionInfo, links); + if (session->sessionId == sessionId) { + HgfsServerSessionGet(session); + break; + } + session = NULL; + } + + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); + + return session; +} + + +/* + *----------------------------------------------------------------------------- + * + * HgfsServerTransportRemoveSessionFromList -- + * + * Unlinks the specified session info from the list. + * + * Note: The caller must acquire the sessionArrayLock in transportSession + * before calling this function. + * + * Results: + * None + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +void +HgfsServerTransportRemoveSessionFromList(HgfsTransportSessionInfo *transportSession, // IN: transport session info + HgfsSessionInfo *session) // IN: session info +{ + ASSERT(transportSession); + ASSERT(session); + + DblLnkLst_Unlink1(&session->links); + HgfsServerSessionPut(session); +} + + +/* + *----------------------------------------------------------------------------- + * + * HgfsServerTransportAddSessionToList -- + * + * Links the specified session info to the list. + * + * Results: + * None + * + * Side effects: + * None + * + *----------------------------------------------------------------------------- + */ + +void +HgfsServerTransportAddSessionToList(HgfsTransportSessionInfo *transportSession, // IN: transport session info + HgfsSessionInfo *session) // IN: session info +{ + ASSERT(transportSession); + ASSERT(session); + + MXUser_AcquireExclLock(transportSession->sessionArrayLock); + DblLnkLst_LinkLast(&transportSession->sessionArray, &session->links); + HgfsServerSessionGet(session); + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); +} + + /* *----------------------------------------------------------------------------- * @@ -3508,6 +3685,79 @@ HgfsServerEnumerateSharedFolders(void) * * Initialize a new client session. * + * Allocate HgfsTransportSessionInfo and initialize it. + * + * Results: + * TRUE on success, FALSE otherwise. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static Bool +HgfsServerSessionConnect(void *transportData, // IN: transport session context + HgfsServerChannelCallbacks *channelCbTable, // IN: Channel callbacks + uint32 channelCapabilities, // IN: channel capabilities + void **transportSessionData) // OUT: server session context +{ + HgfsTransportSessionInfo *transportSession; + HgfsSessionInfo *defaultSession; + + ASSERT(transportSessionData); + + LOG(4, ("%s: initting.\n", __FUNCTION__)); + + transportSession = Util_SafeCalloc(1, sizeof *transportSession); + transportSession->transportData = transportData; + transportSession->channelCbTable = channelCbTable; + transportSession->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4; + transportSession->type = HGFS_SESSION_TYPE_REGULAR; + transportSession->state = HGFS_SESSION_STATE_OPEN; + transportSession->channelCapabilities = channelCapabilities; + + transportSession->sessionArrayLock = + MXUser_CreateExclLock("HgfsSessionArrayLock", + RANK_hgfsSessionArrayLock); + if (transportSession->sessionArrayLock == NULL) { + LOG(4, ("%s: Could not create session sync mutex.\n", __FUNCTION__)); + free(transportSession); + return FALSE; + } + + DblLnkLst_Init(&transportSession->sessionArray); + + if (!HgfsServerAllocateSession(transportSession, + channelCapabilities, + &defaultSession)) { + MXUser_DestroyExclLock(transportSession->sessionArrayLock); + free(transportSession); + return FALSE; + } + + defaultSession->type = HGFS_SESSION_TYPE_INTERNAL; + HgfsServerTransportAddSessionToList(transportSession, defaultSession); + + transportSession->defaultSessionId = defaultSession->sessionId; + + Atomic_Write(&transportSession->refCount, 0); + + /* Give our session a reference to hold while we are open. */ + HgfsServerTransportSessionGet(transportSession); + + *transportSessionData = transportSession; + return TRUE; +} + + +/* + *----------------------------------------------------------------------------- + * + * HgfsServerAllocateSession -- + * + * Initialize a new Hgfs session. + * * Allocate HgfsSessionInfo and initialize it. Create the nodeArray and * searchArray for the session. * @@ -3521,17 +3771,16 @@ HgfsServerEnumerateSharedFolders(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 +HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN: + uint32 channelCapabilities, // IN: + HgfsSessionInfo **sessionData) // OUT: { int i; - HgfsSessionInfo *session = Util_SafeMalloc(sizeof *session); + HgfsSessionInfo *session; - ASSERT(sessionData); + ASSERT(transportSession); - LOG(4, ("%s: initting.\n", __FUNCTION__)); + session = Util_SafeCalloc(1, sizeof *session); /* * Initialize all our locks first as these can fail. @@ -3540,9 +3789,8 @@ HgfsServerSessionConnect(void *transportData, // IN: tra session->fileIOLock = MXUser_CreateExclLock("HgfsFileIOLock", RANK_hgfsFileIOLock); if (session->fileIOLock == NULL) { - free(session); LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__)); - + free(session); return FALSE; } @@ -3550,9 +3798,8 @@ HgfsServerSessionConnect(void *transportData, // IN: tra RANK_hgfsNodeArrayLock); if (session->nodeArrayLock == NULL) { MXUser_DestroyExclLock(session->fileIOLock); - free(session); LOG(4, ("%s: Could not create node array sync mutex.\n", __FUNCTION__)); - + free(session); return FALSE; } @@ -3561,16 +3808,20 @@ HgfsServerSessionConnect(void *transportData, // IN: tra if (session->searchArrayLock == NULL) { MXUser_DestroyExclLock(session->fileIOLock); MXUser_DestroyExclLock(session->nodeArrayLock); - free(session); LOG(4, ("%s: Could not create search array sync mutex.\n", __FUNCTION__)); - + free(session); return FALSE; } session->sessionId = HgfsGenerateSessionId(); + session->type = HGFS_SESSION_TYPE_REGULAR; + session->state = HGFS_SESSION_STATE_OPEN; + DblLnkLst_Init(&session->links); session->maxPacketSize = MAX_SERVER_PACKET_SIZE_V4; session->activeNotification = FALSE; + session->transportSession = transportSession; + /* * Initialize the node handling components. */ @@ -3598,6 +3849,11 @@ HgfsServerSessionConnect(void *transportData, // IN: tra /* Initialize search freelist. */ DblLnkLst_Init(&session->searchFreeList); + Atomic_Write(&session->refCount, 0); + + /* Give our session a reference to hold while we are open. */ + HgfsServerSessionGet(session); + /* Allocate array of searches and add them to free list. */ session->numSearches = NUM_SEARCHES; session->searchArray = Util_SafeCalloc(session->numSearches, @@ -3610,25 +3866,11 @@ HgfsServerSessionConnect(void *transportData, // IN: tra &session->searchArray[i].links); } - /* - * Initialize the general session stuff. - */ - - session->type = HGFS_SESSION_TYPE_REGULAR; - session->state = HGFS_SESSION_STATE_OPEN; - session->transportData = transportData; - 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) { + if (channelCapabilities & HGFS_CHANNEL_SHARED_MEM) { HgfsServerSetSessionCapability(HGFS_OP_READ_FAST_V4, HGFS_REQUEST_SUPPORTED, session); HgfsServerSetSessionCapability(HGFS_OP_WRITE_FAST_V4, @@ -3651,6 +3893,8 @@ HgfsServerSessionConnect(void *transportData, // IN: tra HGFS_REQUEST_SUPPORTED, session); } + *sessionData = session; + return TRUE; } @@ -3658,7 +3902,7 @@ HgfsServerSessionConnect(void *transportData, // IN: tra /* *----------------------------------------------------------------------------- * - * HgfsServerSessionDisconnect -- + * HgfsDisconnectSessionInt -- * * Disconnect a client session. * @@ -3676,9 +3920,8 @@ HgfsServerSessionConnect(void *transportData, // IN: tra */ static void -HgfsServerSessionDisconnect(void *clientData) // IN: session context +HgfsDisconnectSessionInt(HgfsSessionInfo *session) // IN: session context { - HgfsSessionInfo *session = (HgfsSessionInfo *)clientData; ASSERT(session); ASSERT(session->nodeArray); @@ -3686,8 +3929,48 @@ HgfsServerSessionDisconnect(void *clientData) // IN: session context if (session->activeNotification) { HgfsNotify_CleanupSession(session); } +} - session->state = HGFS_SESSION_STATE_CLOSED; + +/* + *----------------------------------------------------------------------------- + * + * HgfsServerSessionDisconnect -- + * + * Disconnect a client session. + * + * Mark the session as closed as we are in the process of teardown + * of the session. No more new requests should be processed. We would + * start draining any outstanding pending operations at this point. + * + * Results: + * None. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static void +HgfsServerSessionDisconnect(void *clientData) // IN: session context +{ + HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; + DblLnkLst_Links *curr, *next; + + ASSERT(transportSession); + + MXUser_AcquireExclLock(transportSession->sessionArrayLock); + + DblLnkLst_ForEachSafe(curr, next, &transportSession->sessionArray) { + HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); + + HgfsDisconnectSessionInt(session); + } + + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); + + transportSession->state = HGFS_SESSION_STATE_CLOSED; } @@ -3713,16 +3996,13 @@ HgfsServerSessionDisconnect(void *clientData) // IN: session context static void HgfsServerSessionClose(void *clientData) // IN: session context { - HgfsSessionInfo *session = (HgfsSessionInfo *)clientData; - - ASSERT(session); - ASSERT(session->nodeArray); - ASSERT(session->searchArray); + HgfsTransportSessionInfo *transportSession = (HgfsTransportSessionInfo *)clientData; - ASSERT(session->state == HGFS_SESSION_STATE_CLOSED); + ASSERT(transportSession); + ASSERT(transportSession->state == HGFS_SESSION_STATE_CLOSED); /* Remove, typically, the last reference, will teardown everything. */ - HgfsServerSessionPut(session); + HgfsServerTransportSessionPut(transportSession); } @@ -3797,6 +4077,7 @@ HgfsServerExitSessionInternal(HgfsSessionInfo *session) // IN: session contex MXUser_DestroyExclLock(session->nodeArrayLock); MXUser_DestroyExclLock(session->searchArrayLock); MXUser_DestroyExclLock(session->fileIOLock); + free(session); } @@ -3864,19 +4145,20 @@ HgfsServer_SetHandleCounter(uint32 newHandleCounter) * Side effects: * Frees the packet buffer. * - *---------------------------------------------------------------------------- + *--------------------------------------------------------------------------- */ void HgfsServerSessionSendComplete(HgfsPacket *packet, // IN/OUT: Hgfs packet void *clientData) // IN: session info { - HgfsSessionInfo *session = (HgfsSessionInfo *)clientData; + HgfsTransportSessionInfo *transportSession = + (HgfsTransportSessionInfo *)clientData; if (packet->guestInitiated) { - HSPU_PutMetaPacket(packet, session); - HSPU_PutReplyPacket(packet, session); - HSPU_PutDataPacketBuf(packet, session); + HSPU_PutMetaPacket(packet, transportSession); + HSPU_PutReplyPacket(packet, transportSession); + HSPU_PutDataPacketBuf(packet, transportSession); } else { free(packet->metaPacket); free(packet); @@ -3981,19 +4263,19 @@ Bool HgfsPacketSend(HgfsPacket *packet, // IN/OUT: Hgfs Packet char *packetOut, // IN: output buffer size_t packetOutLen, // IN: packet size - HgfsSessionInfo *session, // IN: session info + HgfsTransportSessionInfo *transportSession, // IN: session info HgfsSendFlags flags) // IN: flags for how to process { Bool result = FALSE; Bool notificationNeeded = packet->guestInitiated && packet->processedAsync; ASSERT(packet); - ASSERT(session); + ASSERT(transportSession); - if (session->state == HGFS_SESSION_STATE_OPEN) { + if (transportSession->state == HGFS_SESSION_STATE_OPEN) { packet->replyPacketSize = packetOutLen; - ASSERT(session->type == HGFS_SESSION_TYPE_REGULAR); - result = session->channelCbTable->send(session->transportData, + ASSERT(transportSession->type == HGFS_SESSION_TYPE_REGULAR); + result = transportSession->channelCbTable->send(transportSession->transportData, packet, packetOut, packetOutLen, flags); } @@ -4146,11 +4428,23 @@ HgfsInvalidateSessionObjects(DblLnkLst_Links *shares, // IN: List of new shares void HgfsServerSessionInvalidateObjects(void *clientData, // IN: - DblLnkLst_Links *shares) // IN: List of new shares + DblLnkLst_Links *shares) // IN: List of new shares { - HgfsSessionInfo *session = (HgfsSessionInfo *)clientData; + HgfsTransportSessionInfo *transportSession = + (HgfsTransportSessionInfo *)clientData; + DblLnkLst_Links *curr; + + ASSERT(transportSession); + MXUser_AcquireExclLock(transportSession->sessionArrayLock); - HgfsInvalidateSessionObjects(shares, session); + DblLnkLst_ForEach(curr, &transportSession->sessionArray) { + HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); + HgfsServerSessionGet(session); + HgfsInvalidateSessionObjects(shares, session); + HgfsServerSessionPut(session); + } + + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); } @@ -5206,7 +5500,7 @@ HgfsAllocInitReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet headerSize = sizeof(HgfsReply); } replyPacketSize = headerSize + payloadSize; - reply = HSPU_GetReplyPacket(packet, &replyPacketSize, session); + reply = HSPU_GetReplyPacket(packet, &replyPacketSize, session->transportSession); if (reply && (replyPacketSize >= headerSize + payloadSize)) { memset(reply, 0, headerSize + payloadSize); @@ -5273,7 +5567,7 @@ HgfsServerRead(HgfsInputParam *input) // IN: Input params payload = &reply->payload[0]; } else { payload = HSPU_GetDataPacketBuf(input->packet, BUF_WRITEABLE, - input->session); + input->transportSession); } if (payload) { status = HgfsPlatformReadFile(file, input->session, offset, @@ -7689,7 +7983,7 @@ HgfsServerSearchRead(HgfsInputParam *input) // IN: Input params if (inlineDataSize == 0) { info.replyPayload = HSPU_GetDataPacketBuf(input->packet, BUF_WRITEABLE, - input->session); + input->transportSession); } else { info.replyPayload = (char *)info.reply + baseReplySize; } @@ -7793,20 +8087,23 @@ HgfsServerCreateSession(HgfsInputParam *input) // IN: Input params if (HgfsUnpackCreateSessionRequest(input->payload, input->payloadSize, input->op, &info)) { + HgfsSessionInfo *session; LOG(4, ("%s: create session\n", __FUNCTION__)); + + if (!HgfsServerAllocateSession(input->transportSession, + input->transportSession->channelCapabilities, + &session)) { + status = HGFS_ERROR_NOT_ENOUGH_MEMORY; + goto abort; + } else { + HgfsServerTransportAddSessionToList(input->transportSession, session); + } + if (info.maxPacketSize < input->session->maxPacketSize) { input->session->maxPacketSize = info.maxPacketSize; } if (HgfsPackCreateSessionReply(input->packet, input->metaPacket, - &replyPayloadSize, input->session)) { - - /* - * XXX - TO BE RESTORED on session support implementation - * completion. - */ -#if defined HGFS_SESSION_SUPPORT - HgfsServerSessionGet(input->session); -#endif + &replyPayloadSize, session)) { status = HGFS_ERROR_SUCCESS; } else { status = HGFS_ERROR_INTERNAL; @@ -7815,6 +8112,7 @@ HgfsServerCreateSession(HgfsInputParam *input) // IN: Input params status = HGFS_ERROR_PROTOCOL; } +abort: HgfsServerCompleteRequest(status, replyPayloadSize, input); } @@ -7838,16 +8136,41 @@ HgfsServerCreateSession(HgfsInputParam *input) // IN: Input params static void HgfsServerDestroySession(HgfsInputParam *input) // IN: Input params { + HgfsTransportSessionInfo *transportSession; + HgfsSessionInfo *session; + HGFS_ASSERT_INPUT(input); - HgfsServerCompleteRequest(HGFS_ERROR_SUCCESS, 0, input); + transportSession = input->transportSession; + session = input->session; + + if ((session->sessionId == transportSession->defaultSessionId) || + (session->type != HGFS_SESSION_TYPE_REGULAR)) { + + /* + * In each transport session, there will be a default session. This + * default session should be in opened state till the end of the + * transport session. If we receive a destroy session request for + * default session, then we are receiving the requests for a malformed + * client. Return an error. + */ + HgfsServerCompleteRequest(HGFS_STATUS_PROTOCOL_ERROR, 0, input); + return; + } + + session->state = HGFS_SESSION_STATE_CLOSED; + /* - * XXX - TO BE RESTORED on session support implementation - * completion. - */ -#if defined HGFS_SESSION_SUPPORT - HgfsServerSessionPut(input->session); -#endif + * Remove the session from the list. By doing that, the refcount of + * the session will be decremented. Later, we will be invoking + * HgfsServerCompleteRequest which will decrement the session's + * refcount and cleanup the session + */ + MXUser_AcquireExclLock(transportSession->sessionArrayLock); + HgfsServerTransportRemoveSessionFromList(transportSession, session); + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); + HgfsServerCompleteRequest(HGFS_ERROR_SUCCESS, 0, input); + HgfsServerSessionPut(session); } @@ -8000,7 +8323,7 @@ Hgfs_NotificationCallback(HgfsSharedFolderHandle sharedFolder, // IN: shared fol HgfsPackChangeNotificationRequest(packetHeader, subscriber, shareName, fileName, mask, flags, session, &sizeNeeded); - if (!HgfsPacketSend(packet, (char *)packetHeader, sizeNeeded, session, 0)) { + if (!HgfsPacketSend(packet, (char *)packetHeader, sizeNeeded, session->transportSession, 0)) { LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__)); } diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h index 79744a59d..1a6b9290f 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h +++ b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h @@ -278,15 +278,21 @@ typedef enum { HGFS_SESSION_TYPE_INTERNAL, /* This is a static session. */ } HgfsSessionInfoType; -/* HgfsTransportSessionState, used for session status. */ +/* HgfsSessionState, used for session status. */ typedef enum { HGFS_SESSION_STATE_OPEN, HGFS_SESSION_STATE_CLOSED, } HgfsSessionInfoState; -typedef struct HgfsSessionInfo { - /* Unique session id. */ - uint64 sessionId; +typedef struct HgfsTransportSessionInfo { + /* Default session id. */ + uint64 defaultSessionId; + + /* Lock to manipulate the list of sessions */ + MXUserExclLock *sessionArrayLock; + + /* List of sessions */ + DblLnkLst_Links sessionArray; /* Max packet size that is supported by both client and server. */ uint32 maxPacketSize; @@ -303,6 +309,30 @@ typedef struct HgfsSessionInfo { /* Function callbacks into Hgfs Channels. */ HgfsServerChannelCallbacks *channelCbTable; + Atomic_uint32 refCount; /* Reference count for session. */ + + uint32 channelCapabilities; +} HgfsTransportSessionInfo; + +typedef struct HgfsSessionInfo { + + DblLnkLst_Links links; + + /* Unique session id. */ + uint64 sessionId; + + /* Max packet size that is supported by both client and server. */ + uint32 maxPacketSize; + + /* Transport session context. */ + HgfsTransportSessionInfo *transportSession; + + /* Current state of the session. */ + HgfsSessionInfoState state; + + /* Session is dynamic or internal. */ + HgfsSessionInfoType type; + /* Lock to ensure some fileIO requests are atomic for a handle. */ MXUserExclLock *fileIOLock; @@ -359,10 +389,8 @@ typedef struct HgfsSessionInfo { uint32 numberOfCapabilities; Bool activeNotification; - } HgfsSessionInfo; - /* * These structs represent information about file open requests, file * attributes, and directory creation requests. @@ -474,6 +502,7 @@ typedef struct HgfsInputParam { const char *metaPacket; size_t metaPacketSize; HgfsSessionInfo *session; + HgfsTransportSessionInfo *transportSession; HgfsPacket *packet; void const *payload; uint32 payloadOffset; @@ -568,7 +597,7 @@ HgfsServerSearchVirtualDir(HgfsGetNameFunc *getName, // IN: Name enumerator Bool HgfsParseRequest(HgfsPacket *packet, // IN: request packet - HgfsSessionInfo *session, // IN: current session + HgfsTransportSessionInfo *transportSession, // IN: current session HgfsInputParam **input, // OUT: request parameters HgfsInternalStatus *status); // OUT: error code @@ -1032,14 +1061,19 @@ HgfsPackAndSendPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t packetOutLen, // IN: Output packet size HgfsInternalStatus status, // IN: status HgfsHandle id, // IN: id of the request packet - HgfsSessionInfo *session, // IN: session info + HgfsTransportSessionInfo *transportSession, // IN: session info HgfsSendFlags flags); // IN: flags how to send +/* Get the session with a specific session id */ +HgfsSessionInfo * +HgfsServerTransportGetSessionInfo(HgfsTransportSessionInfo *transportSession, // IN: transport session info + uint64 sessionId); // IN: session id + Bool HgfsPacketSend(HgfsPacket *packet, // IN/OUT: Hgfs Packet char *packetOut, // IN: Output packet buffer size_t packetOutLen, // IN: Output packet size - HgfsSessionInfo *session, // IN: session info + HgfsTransportSessionInfo *transportSession, // IN: session info HgfsSendFlags flags); // IN: flags how to send Bool @@ -1163,8 +1197,6 @@ HgfsPlatformValidateOpen(HgfsFileOpenInfo *openInfo, // IN: Open info struct HgfsSessionInfo *session, // IN: Session info HgfsLocalId *localId, // OUT: Local unique file ID fileDesc *newHandle); // OUT: Handle to the file -void HgfsServerSessionGet(HgfsSessionInfo *session); // IN: session context - void * HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index of iov @@ -1172,21 +1204,21 @@ HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t bufSize, // IN: Size of buffer Bool *isAllocated, // OUT: Was buffer allocated ? MappingType mappingType, // IN: Readable/ Writeable ? - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void * HSPU_GetMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *metaPacketSize, // OUT: Size of metaPacket - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void * HSPU_GetDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet MappingType mappingType, // IN: Readable/ Writeable ? - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet @@ -1195,33 +1227,33 @@ HSPU_PutBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *bufSize, // IN: Size of the buffer Bool *isAllocated, // IN: Was buffer allocated ? MappingType mappingType, // IN: Readable/ Writeable ? - HgfsSessionInfo *session); // IN: Session info + HgfsTransportSessionInfo *transportSession); // IN: Session info void HSPU_PutDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_CopyBufToDataIovec(HgfsPacket *packet, // IN/OUT: Hgfs packet void *buf, // IN: Buffer to copy from uint32 bufSize, // IN: Size of buffer - HgfsSessionInfo *session);// IN: Session Info + HgfsTransportSessionInfo *transportSession);// IN: Session Info void HSPU_CopyBufToIovec(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index into iov void *buf, // IN: Buffer size_t bufSize, // IN: Size of buffer - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void * HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *replyPacketSize, //IN/OUT: Size of reply Packet - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info void HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session); // IN: Session Info + HgfsTransportSessionInfo *transportSession); // IN: Session Info #endif /* __HGFS_SERVER_INT_H__ */ diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c b/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c index b0e61511b..cf436a798 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c @@ -53,9 +53,9 @@ void * HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *replyPacketSize, // IN/OUT: Size of reply Packet - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { - ASSERT(session); + ASSERT(transportSession); if (packet->replyPacket) { /* * When we are transferring packets over backdoor, reply packet @@ -64,7 +64,7 @@ HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet LOG(4, ("Exising reply packet %s %Zu %Zu\n", __FUNCTION__, *replyPacketSize, packet->replyPacketSize)); ASSERT_DEVEL(*replyPacketSize <= packet->replyPacketSize); - } else if (session->channelCbTable && session->channelCbTable->getWriteVa) { + } else if (transportSession->channelCbTable && transportSession->channelCbTable->getWriteVa) { /* Can we write directly into guest memory ? */ ASSERT_DEVEL(packet->metaPacket); if (packet->metaPacket) { @@ -79,7 +79,7 @@ HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet packet->metaPacketSize, &packet->metaPacketIsAllocated, BUF_WRITEABLE, - session); + transportSession); /* * Really this can never happen, we would have caught bad physical address * during getMetaPacket. @@ -117,7 +117,7 @@ HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet void HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { if (packet->replyPacketIsAllocated) { LOG(10, ("%s Freeing reply packet", __FUNCTION__)); @@ -148,13 +148,13 @@ HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet void * HSPU_GetMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *metaPacketSize, // OUT: Size of metaPacket - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { *metaPacketSize = packet->metaPacketSize; return HSPU_GetBuf(packet, 0, &packet->metaPacket, packet->metaPacketSize, &packet->metaPacketIsAllocated, - BUF_READWRITEABLE, session); + BUF_READWRITEABLE, transportSession); } @@ -176,7 +176,7 @@ HSPU_GetMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet void * HSPU_GetDataPacketIov(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session, // IN: Session Info + HgfsTransportSessionInfo *transportSession, // IN: Session Info HgfsVaIov iov) // OUT: I/O vector { NOT_IMPLEMENTED(); @@ -204,12 +204,12 @@ HSPU_GetDataPacketIov(HgfsPacket *packet, // IN/OUT: Hgfs Packet void * HSPU_GetDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet MappingType mappingType, // IN: Writeable/Readable - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { packet->dataMappingType = mappingType; return HSPU_GetBuf(packet, packet->dataPacketIovIndex, &packet->dataPacket, packet->dataPacketSize, - &packet->dataPacketIsAllocated, mappingType, session); + &packet->dataPacketIsAllocated, mappingType, transportSession); } @@ -236,7 +236,7 @@ HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t bufSize, // IN: Size of buffer Bool *isAllocated, // OUT: Was buffer allocated ? MappingType mappingType, // IN: Readable/Writeable ? - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { uint32 iovCount; uint32 iovMapped = 0; @@ -251,16 +251,16 @@ HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet return NULL; } - if (!session->channelCbTable) { + if (!transportSession->channelCbTable) { return NULL; } if (mappingType == BUF_WRITEABLE || mappingType == BUF_READWRITEABLE) { - func = session->channelCbTable->getWriteVa; + func = transportSession->channelCbTable->getWriteVa; } else { ASSERT(mappingType == BUF_READABLE); - func = session->channelCbTable->getReadVa; + func = transportSession->channelCbTable->getReadVa; } /* Looks like we are in the middle of poweroff. */ @@ -329,7 +329,7 @@ HSPU_GetBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet freeMem: for (i = startIndex; i < iovCount; i++) { - session->channelCbTable->putVa(&packet->iov[i].token); + transportSession->channelCbTable->putVa(&packet->iov[i].token); packet->iov[i].va = NULL; } @@ -355,13 +355,13 @@ freeMem: void HSPU_PutMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { LOG(4, ("%s Hgfs Putting Meta packet\n", __FUNCTION__)); HSPU_PutBuf(packet, 0, &packet->metaPacket, &packet->metaPacketSize, &packet->metaPacketIsAllocated, - BUF_WRITEABLE, session); + BUF_WRITEABLE, transportSession); } @@ -405,14 +405,14 @@ HSPU_PutDataPacketIov() void HSPU_PutDataPacketBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { LOG(4, ("%s Hgfs Putting Data packet\n", __FUNCTION__)); HSPU_PutBuf(packet, packet->dataPacketIovIndex, &packet->dataPacket, &packet->dataPacketSize, &packet->dataPacketIsAllocated, - packet->dataMappingType, session); + packet->dataMappingType, transportSession); } @@ -438,23 +438,23 @@ HSPU_PutBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet size_t *bufSize, // IN: Size of the buffer Bool *isAllocated, // IN: Was buffer allocated ? MappingType mappingType, // IN: Readable / Writeable ? - HgfsSessionInfo *session) // IN: Session info + HgfsTransportSessionInfo *transportSession) // IN: Session info { uint32 iovCount = 0; int size = *bufSize; ASSERT(buf); - if (!session->channelCbTable) { + if (!transportSession->channelCbTable) { return; } - if (!session->channelCbTable->putVa || *buf == NULL) { + if (!transportSession->channelCbTable->putVa || *buf == NULL) { return; } if (*isAllocated) { if (mappingType == BUF_WRITEABLE) { - HSPU_CopyBufToIovec(packet, startIndex, *buf, *bufSize, session); + HSPU_CopyBufToIovec(packet, startIndex, *buf, *bufSize, transportSession); } LOG(10, ("%s: Hgfs Freeing buffer \n", __FUNCTION__)); free(*buf); @@ -464,7 +464,7 @@ HSPU_PutBuf(HgfsPacket *packet, // IN/OUT: Hgfs Packet iovCount < packet->iovCount && size > 0; iovCount++) { ASSERT_DEVEL(packet->iov[iovCount].token); - session->channelCbTable->putVa(&packet->iov[iovCount].token); + transportSession->channelCbTable->putVa(&packet->iov[iovCount].token); size -= packet->iov[iovCount].len; } LOG(10, ("%s: Hgfs bufSize = %d \n", __FUNCTION__, size)); @@ -493,9 +493,9 @@ void HSPU_CopyBufToMetaIovec(HgfsPacket *packet, // IN/OUT: Hgfs packet void *buf, // IN: Buffer to copy from size_t bufSize, // IN: Size of buffer - HgfsSessionInfo *session)// IN: Session Info + HgfsTransportSessionInfo *transportSession)// IN: Session Info { - HSPU_CopyBufToIovec(packet, 0, buf, bufSize, session); + HSPU_CopyBufToIovec(packet, 0, buf, bufSize, transportSession); } @@ -518,10 +518,10 @@ void HSPU_CopyBufToDataIovec(HgfsPacket *packet, // IN: Hgfs packet void *buf, // IN: Buffer to copy from uint32 bufSize, // IN: Size of buffer - HgfsSessionInfo *session) + HgfsTransportSessionInfo *transportSession) { HSPU_CopyBufToIovec(packet, packet->dataPacketIovIndex, buf, bufSize, - session); + transportSession); } @@ -545,7 +545,7 @@ HSPU_CopyBufToIovec(HgfsPacket *packet, // IN/OUT: Hgfs Packet uint32 startIndex, // IN: start index into iov void *buf, // IN: Contigous Buffer size_t bufSize, // IN: Size of buffer - HgfsSessionInfo *session) // IN: Session Info + HgfsTransportSessionInfo *transportSession) // IN: Session Info { uint32 iovCount; size_t remainingSize = bufSize; @@ -555,12 +555,12 @@ HSPU_CopyBufToIovec(HgfsPacket *packet, // IN/OUT: Hgfs Packet ASSERT(packet); ASSERT(buf); - if (!session->channelCbTable) { + if (!transportSession->channelCbTable) { return; } - ASSERT_DEVEL(session->channelCbTable->getWriteVa); - if (!session->channelCbTable->getWriteVa) { + ASSERT_DEVEL(transportSession->channelCbTable->getWriteVa); + if (!transportSession->channelCbTable->getWriteVa) { return; } @@ -575,13 +575,13 @@ HSPU_CopyBufToIovec(HgfsPacket *packet, // IN/OUT: Hgfs Packet ASSERT_DEVEL(packet->iov[iovCount].len <= (PAGE_SIZE - PAGE_OFFSET(packet->iov[iovCount].pa))); - packet->iov[iovCount].va = session->channelCbTable->getWriteVa(packet->iov[iovCount].pa, + packet->iov[iovCount].va = transportSession->channelCbTable->getWriteVa(packet->iov[iovCount].pa, packet->iov[iovCount].len, &packet->iov[iovCount].token); ASSERT_DEVEL(packet->iov[iovCount].va); if (packet->iov[iovCount].va != NULL) { memcpy(packet->iov[iovCount].va, (char *)buf + copiedAmount, copyAmount); - session->channelCbTable->putVa(&packet->iov[iovCount].token); + transportSession->channelCbTable->putVa(&packet->iov[iovCount].token); remainingSize -= copyAmount; copiedAmount += copyAmount; } else { diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c b/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c index 1a9f1c215..fe6c777ff 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServerParameters.c @@ -267,7 +267,7 @@ HgfsGetPayloadSize(char const *packetIn, // IN: request packet Bool HgfsParseRequest(HgfsPacket *packet, // IN: request packet - HgfsSessionInfo *session, // IN: current session + HgfsTransportSessionInfo *transportSession, // IN: current session HgfsInputParam **input, // OUT: request parameters HgfsInternalStatus *status) // OUT: error code { @@ -275,10 +275,13 @@ HgfsParseRequest(HgfsPacket *packet, // IN: request packet size_t packetSize; HgfsInternalStatus result = HGFS_ERROR_SUCCESS; HgfsInputParam *localInput; + HgfsSessionInfo *session = NULL; - request = (HgfsRequest *) HSPU_GetMetaPacket(packet, &packetSize, session); + request = (HgfsRequest *) HSPU_GetMetaPacket(packet, &packetSize, transportSession); ASSERT_DEVEL(request); + LOG(4, ("%s: Recieved a request with opcode %d.\n", __FUNCTION__, (int) request->op)); + if (!request) { /* * How can I return error back to the client, clearly the client is either broken or @@ -293,8 +296,9 @@ HgfsParseRequest(HgfsPacket *packet, // IN: request packet memset(localInput, 0, sizeof *localInput); localInput->metaPacket = (char *)request; localInput->metaPacketSize = packetSize; - localInput->session = session; + localInput->transportSession = transportSession; localInput->packet = packet; + localInput->session = NULL; /* * Error out if less than HgfsRequest size. @@ -329,15 +333,18 @@ HgfsParseRequest(HgfsPacket *packet, // IN: request packet localInput->id = header->requestId; if (packetSize >= offsetof(HgfsHeader, sessionId) + sizeof header->sessionId) { - if (header->sessionId != session->sessionId && - header->op != HGFS_OP_CREATE_SESSION_V4) { + if (header->op != HGFS_OP_CREATE_SESSION_V4) { + session = HgfsServerTransportGetSessionInfo(transportSession, + header->sessionId); + if (!session || session->state != HGFS_SESSION_STATE_OPEN) { LOG(4, ("%s: HGFS packet with invalid session id!\n", __FUNCTION__)); result = HGFS_ERROR_STALE_SESSION; + } } else if (packetSize < header->packetSize || header->packetSize < header->headerSize) { - LOG(4, ("%s: Malformed HGFS packet received - inconsistent header" - " and packet sizes!\n", __FUNCTION__)); - result = HGFS_ERROR_PROTOCOL; + LOG(4, ("%s: Malformed HGFS packet received - inconsistent header" + " and packet sizes!\n", __FUNCTION__)); + result = HGFS_ERROR_PROTOCOL; } } else { LOG(4, ("%s: Malformed HGFS packet received - header is too small!\n", @@ -359,6 +366,13 @@ HgfsParseRequest(HgfsPacket *packet, // IN: request packet LOG(4, ("%s: Malformed HGFS packet received!\n", __FUNCTION__)); } + if (!session) { + session = HgfsServerTransportGetSessionInfo(transportSession, + transportSession->defaultSessionId); + } + ASSERT(session); + + localInput->session = session; localInput->payloadOffset = (char *)localInput->payload - (char *)localInput->metaPacket; *status = result; @@ -4321,7 +4335,7 @@ HgfsUnpackWriteRequest(HgfsInputParam *input, // IN: Input params if (result) { *data = HSPU_GetDataPacketBuf(input->packet, BUF_READABLE, - input->session); + input->transportSession); if (NULL == *data) { LOG(4, ("%s: Failed to get data in guest memory\n", __FUNCTION__)); result = FALSE; diff --git a/open-vm-tools/lib/include/mutexRankLib.h b/open-vm-tools/lib/include/mutexRankLib.h index 3ce5541fb..2d5adb012 100644 --- a/open-vm-tools/lib/include/mutexRankLib.h +++ b/open-vm-tools/lib/include/mutexRankLib.h @@ -55,11 +55,12 @@ /* * hgfs locks */ -#define RANK_hgfsSharedFolders (RANK_libLockBase + 0x4003) -#define RANK_hgfsNotifyLock (RANK_libLockBase + 0x4005) -#define RANK_hgfsFileIOLock (RANK_libLockBase + 0x4010) -#define RANK_hgfsSearchArrayLock (RANK_libLockBase + 0x4020) -#define RANK_hgfsNodeArrayLock (RANK_libLockBase + 0x4030) +#define RANK_hgfsSessionArrayLock (RANK_libLockBase + 0x4010) +#define RANK_hgfsSharedFolders (RANK_libLockBase + 0x4030) +#define RANK_hgfsNotifyLock (RANK_libLockBase + 0x4040) +#define RANK_hgfsFileIOLock (RANK_libLockBase + 0x4050) +#define RANK_hgfsSearchArrayLock (RANK_libLockBase + 0x4060) +#define RANK_hgfsNodeArrayLock (RANK_libLockBase + 0x4070) /* * SLPv2 global lock