885
934
*-----------------------------------------------------------------------------
936
* HgfsHandle2FileNameMode --
938
* Given an OS handle/fd, return information needed for directory
939
* notification package: relative to the root share file name and
940
* shared folder notification handle.
943
* TRUE if the node was found.
949
*-----------------------------------------------------------------------------
953
HgfsHandle2NotifyInfo(HgfsHandle handle, // IN: Hgfs file handle
954
HgfsSessionInfo *session, // IN: Session info
955
char **fileName, // OUT: UTF8 file name
956
size_t *fileNameSize, // OUT: UTF8 file name size
957
HgfsSharedFolderHandle *folderHandle) // OUT: shared folder handle
960
HgfsFileNode *existingFileNode;
964
ASSERT(fileName != NULL && fileNameSize != NULL);
965
MXUser_AcquireExclLock(session->nodeArrayLock);
967
existingFileNode = HgfsHandle2FileNode(handle, session);
968
if (NULL != existingFileNode) {
969
nameSize = existingFileNode->utf8NameLen - existingFileNode->shareInfo.rootDirLen;
970
name = Util_SafeMalloc(nameSize + 1);
971
*folderHandle = existingFileNode->shareInfo.handle;
972
memcpy(name, existingFileNode->utf8Name, nameSize);
973
name[nameSize] = '\0';
975
*fileNameSize = nameSize;
979
MXUser_ReleaseExclLock(session->nodeArrayLock);
986
*-----------------------------------------------------------------------------
887
988
* HgfsFileHasServerLock --
889
990
* Check if the file with the given name is already opened with a server
2887
3025
*-----------------------------------------------------------------------------
3027
* HgfsServerCleanupDeletedFolders --
3029
* This function iterates through all shared folders and removes all
3030
* deleted shared folders, removes them from notification package and
3031
* from the folders list.
3039
*-----------------------------------------------------------------------------
3043
HgfsServerCleanupDeletedFolders(void)
3045
DblLnkLst_Links *link, *nextElem;
3047
MXUser_AcquireExclLock(gHgfsSharedFoldersLock);
3048
DblLnkLst_ForEachSafe(link, nextElem, &gHgfsSharedFoldersList) {
3049
HgfsSharedFolderProperties *folder =
3050
DblLnkLst_Container(link, HgfsSharedFolderProperties, links);
3051
if (folder->markedForDeletion) {
3052
if (!HgfsNotify_RemoveSharedFolder(folder->notificationHandle)) {
3053
LOG(4, ("Problem removing %d shared folder handle\n",
3054
folder->notificationHandle));
3056
DblLnkLst_Unlink1(link);
3060
MXUser_ReleaseExclLock(gHgfsSharedFoldersLock);
3065
*-----------------------------------------------------------------------------
3067
* HgfsServer_RegisterSharedFolder --
3069
* This is a callback function which is invoked by hgfsServerManagement
3070
* for every shared folder when something changed in shared folders
3071
* configuration. The function iterates through the list of existing
3072
* shared folders trying to locate an entry with the shareName. If the
3073
* entry is found the function returns corresponding handle. Otherwise
3074
* it creates a new entry and assigns a new handle to it.
3076
* Currently there is no notification that a shared folder has been
3077
* deleted. The only way to find out that a shred folder is deleted
3078
* is to notice that it is not enumerated any more. Thus an explicit
3079
* "end of list" notification is needed. "sharedFolder == NULL" notifies
3080
* that enumeration is completed which allows to delete all shared
3081
* folders that were not mentioned during current enumeration.
3084
* HgfsSharedFolderHandle for the entry.
3087
* May add an entry to known shared folders list.
3089
*-----------------------------------------------------------------------------
3092
HgfsSharedFolderHandle
3093
HgfsServer_RegisterSharedFolder(const char *shareName, // IN: shared folder name
3094
const char *sharePath, // IN: shared folder path
3095
Bool addFolder) // IN: add or remove folder
3097
DblLnkLst_Links *link, *nextElem;
3098
HgfsSharedFolderHandle result = HGFS_INVALID_FOLDER_HANDLE;
3100
if (!gHgfsDirNotifyActive) {
3101
return HGFS_INVALID_FOLDER_HANDLE;
3104
if (NULL == shareName) {
3106
* The function is invoked with shareName NULL when all shares has been
3108
* Need to delete all shared folders that were marked for deletion.
3110
HgfsServerCleanupDeletedFolders();
3111
return HGFS_INVALID_FOLDER_HANDLE;
3114
MXUser_AcquireExclLock(gHgfsSharedFoldersLock);
3116
DblLnkLst_ForEachSafe(link, nextElem, &gHgfsSharedFoldersList) {
3117
HgfsSharedFolderProperties *folder =
3118
DblLnkLst_Container(link, HgfsSharedFolderProperties, links);
3119
if (strcmp(folder->name, shareName) == 0) {
3120
result = folder->notificationHandle;
3121
folder->markedForDeletion = !addFolder;
3125
if (addFolder && HGFS_INVALID_FOLDER_HANDLE == result) {
3126
result = HgfsNotify_AddSharedFolder(sharePath, shareName);
3127
if (HGFS_INVALID_FOLDER_HANDLE != result) {
3128
HgfsSharedFolderProperties *folder =
3129
(HgfsSharedFolderProperties *)Util_SafeMalloc(sizeof *folder);
3130
folder->notificationHandle = result;
3131
folder->name = Util_SafeStrdup(shareName);
3132
folder->markedForDeletion = FALSE;
3133
DblLnkLst_Init(&folder->links);
3134
DblLnkLst_LinkLast(&gHgfsSharedFoldersList, &folder->links);
3137
MXUser_ReleaseExclLock(gHgfsSharedFoldersLock);
3143
*-----------------------------------------------------------------------------
3145
* HgfsServerGetShareHandle --
3147
* The function returns shared folder notification handle for the specified
3151
* HgfsSharedFolderHandle that corresponds to the shared folder.
3156
*-----------------------------------------------------------------------------
3159
static HgfsSharedFolderHandle
3160
HgfsServerGetShareHandle(const char *shareName) // IN: name of the shared folder
3162
DblLnkLst_Links *link;
3163
HgfsSharedFolderHandle result = HGFS_INVALID_FOLDER_HANDLE;
3165
if (!gHgfsDirNotifyActive) {
3166
return HGFS_INVALID_FOLDER_HANDLE;
3169
MXUser_AcquireExclLock(gHgfsSharedFoldersLock);
3171
DblLnkLst_ForEach(link, &gHgfsSharedFoldersList) {
3172
HgfsSharedFolderProperties *folder =
3173
DblLnkLst_Container(link, HgfsSharedFolderProperties, links);
3174
if (strcmp(folder->name, shareName) == 0) {
3175
result = folder->notificationHandle;
3179
MXUser_ReleaseExclLock(gHgfsSharedFoldersLock);
3185
*-----------------------------------------------------------------------------
3187
* HgfsServerGetShareName --
3189
* Get the share name for a shared folder handle by looking at the
3190
* requested handle, finding the matching share (if any), and returning
3194
* An Bool value indicating if the result is returned.
3199
*-----------------------------------------------------------------------------
3203
HgfsServerGetShareName(HgfsSharedFolderHandle sharedFolder, // IN: Notify handle
3204
size_t *shareNameLen, // OUT: Name length
3205
char **shareName) // OUT: Share name
3207
Bool result = FALSE;
3208
DblLnkLst_Links *link;
3210
if (!gHgfsDirNotifyActive) {
3214
MXUser_AcquireExclLock(gHgfsSharedFoldersLock);
3216
DblLnkLst_ForEach(link, &gHgfsSharedFoldersList) {
3217
HgfsSharedFolderProperties *folder =
3218
DblLnkLst_Container(link, HgfsSharedFolderProperties, links);
3219
if (folder->notificationHandle == sharedFolder) {
3220
*shareName = Util_SafeStrdup(folder->name);
3222
*shareNameLen = strlen(*shareName);
3226
MXUser_ReleaseExclLock(gHgfsSharedFoldersLock);
3232
*-----------------------------------------------------------------------------
2889
3234
* HgfsServer_InitState --
2891
3236
* Initialize the global server state
2911
3258
maxCachedOpenNodes = Config_GetLong(MAX_CACHED_FILENODES,
2912
3259
"hgfs.fdCache.maxNodes");
2915
if (Config_GetBool(FALSE, "hgfs.alwaysUseHostTime")) {
2916
alwaysUseHostTime = TRUE;
2922
hgfsStaticSession.session = NULL;
2923
hgfsStaticSession.bufferOut = NULL;
2924
hgfsStaticSession.bufferOutLen = 0;
2927
if (HgfsNotify_Init() == 0) {
2928
hgfsChangeNotificationSupported = TRUE;
2931
if (!HgfsServerPlatformInit()) {
2932
LOG(4, ("Could not initialize server platform specific \n"));
2937
*callbackTable = &hgfsServerSessionCBTable;
3261
alwaysUseHostTime = Config_GetBool(FALSE, "hgfs.alwaysUseHostTime");
3264
* Initialize the globals for handling the active shared folders.
3267
gHgfsAsyncLock = NULL;
3268
gHgfsAsyncVar = NULL;
3269
Atomic_Write(&gHgfsAsyncCounter, 0);
3271
DblLnkLst_Init(&gHgfsSharedFoldersList);
3272
gHgfsSharedFoldersLock = MXUser_CreateExclLock("sharedFoldersLock",
3273
RANK_hgfsSharedFolders);
3274
if (NULL != gHgfsSharedFoldersLock) {
3275
gHgfsAsyncLock = MXUser_CreateExclLock("asyncLock",
3276
RANK_hgfsSharedFolders);
3277
if (NULL != gHgfsAsyncLock) {
3278
gHgfsAsyncVar = MXUser_CreateCondVarExclLock(gHgfsAsyncLock);
3279
if (NULL != gHgfsAsyncVar) {
3280
if (!HgfsServerPlatformInit()) {
3281
LOG(4, ("Could not initialize server platform specific \n"));
3285
LOG(4, ("%s: Could not create async counter cond var.\n",
3290
LOG(4, ("%s: Could not create async counter mutex.\n", __FUNCTION__));
3294
LOG(4, ("%s: Could not create shared folders mutex.\n", __FUNCTION__));
3299
*callbackTable = &hgfsServerSessionCBTable;
3300
if (Config_GetBool(TRUE, "isolation.tools.hgfs.notify.enable")) {
3301
gHgfsDirNotifyActive = HgfsNotify_Init() == HGFS_STATUS_SUCCESS;
3303
gHgfsInitialized = TRUE;
3305
HgfsServer_ExitState(); // Cleanup partially initialized state
3005
3385
*-----------------------------------------------------------------------------
3387
* HgfsServerSetSessionCapability --
3389
* Sets session capability for a specific operation code.
3392
* TRUE is the capability for the operation has been changed.
3393
* FALSE if the operation is not represented in the capabilities array.
3398
*-----------------------------------------------------------------------------
3402
HgfsServerSetSessionCapability(HgfsOp op, // IN: operation code
3403
uint32 flags, // IN: flags that describe level of support
3404
HgfsSessionInfo *session) // INOUT: session to update
3407
Bool result = FALSE;
3409
for ( i = 0; i < ARRAYSIZE(session->hgfsSessionCapabilities); i++) {
3410
if (session->hgfsSessionCapabilities[i].op == op) {
3411
session->hgfsSessionCapabilities[i].flags = flags;
3415
LOG(4, ("%s: Setting capabilitiy flags %x for op code %d %s\n",
3416
__FUNCTION__, flags, op, result ? "succeeded" : "failed"));
3423
*-----------------------------------------------------------------------------
3425
* HgfsServerEnumerateSharedFolders --
3427
* Enumerates all exisitng shared folders and registers shared folders with
3428
* directory notification package.
3436
*-----------------------------------------------------------------------------
3440
HgfsServerEnumerateSharedFolders(void)
3443
Bool success = FALSE;
3445
state = HgfsServerPolicy_GetSharesInit();
3446
if (NULL != state) {
3450
char const *shareName;
3453
success = HgfsServerPolicy_GetShares(state, &shareName, &len, &done);
3454
if (success && !done) {
3455
HgfsSharedFolderHandle handle;
3456
char const *sharePath;
3457
size_t sharePathLen;
3458
HgfsNameStatus nameStatus;
3460
nameStatus = HgfsServerPolicy_GetSharePath(shareName, len,
3461
HGFS_OPEN_MODE_READ_ONLY,
3462
&sharePathLen, &sharePath);
3463
if (HGFS_NAME_STATUS_COMPLETE == nameStatus) {
3464
handle = HgfsServer_RegisterSharedFolder(shareName, sharePath,
3466
success = handle != HGFS_INVALID_FOLDER_HANDLE;
3469
} while (!done && success);
3471
HgfsServerPolicy_GetSharesCleanup(state);
3478
*-----------------------------------------------------------------------------
3007
3480
* HgfsServerSessionConnect --
3009
3482
* Initialize a new client session.
3115
3593
session->channelCbTable = channelCbTable;
3116
3594
Atomic_Write(&session->refCount, 0);
3596
/* Get common to all sessions capabiities. */
3597
HgfsServerGetDefaultCapabilities(session->hgfsSessionCapabilities,
3598
&session->numberOfCapabilities);
3118
3600
/* Give our session a reference to hold while we are open. */
3119
3601
HgfsServerSessionGet(session);
3120
3602
*sessionData = session;
3604
if (channelCapabililies & HGFS_CHANNEL_SHARED_MEM) {
3605
HgfsServerSetSessionCapability(HGFS_OP_READ_FAST_V4,
3606
HGFS_REQUEST_SUPPORTED, session);
3607
HgfsServerSetSessionCapability(HGFS_OP_WRITE_FAST_V4,
3608
HGFS_REQUEST_SUPPORTED, session);
3609
if (gHgfsDirNotifyActive) {
3610
if (HgfsServerEnumerateSharedFolders()) {
3611
HgfsServerSetSessionCapability(HGFS_OP_SET_WATCH_V4,
3612
HGFS_REQUEST_SUPPORTED, session);
3613
HgfsServerSetSessionCapability(HGFS_OP_REMOVE_WATCH_V4,
3614
HGFS_REQUEST_SUPPORTED, session);
3615
session->activeNotification = TRUE;
3617
HgfsServerSetSessionCapability(HGFS_OP_SET_WATCH_V4,
3618
HGFS_REQUEST_NOT_SUPPORTED, session);
3619
HgfsServerSetSessionCapability(HGFS_OP_REMOVE_WATCH_V4,
3620
HGFS_REQUEST_NOT_SUPPORTED, session);
3319
*----------------------------------------------------------------------------
3321
* HgfsServer_ProcessPacket --
3323
* Process packet not associated with any session.
3325
* This function is used in the HGFS server inside Tools.
3327
* Create an internal session if not already created, and process the packet.
3335
*----------------------------------------------------------------------------
3339
HgfsServer_ProcessPacket(char const *packetIn, // IN: incoming packet
3340
char *packetOut, // OUT: outgoing packet
3341
size_t *packetLen) // IN/OUT: packet length
3348
if (*packetLen == 0) {
3353
* Create the session if not already created.
3354
* This session is destroyed in HgfsServer_ExitState.
3357
if (hgfsStaticSession.session == NULL) {
3358
if (!HgfsServerSessionConnect(NULL, NULL,
3359
(void **)&hgfsStaticSession.session)) {
3365
/* Mark the session as internal. */
3366
hgfsStaticSession.session->type = HGFS_SESSION_TYPE_INTERNAL;
3369
memset(&packet, 0, sizeof packet);
3370
packet.iov[0].va = (void *)packetIn;
3371
packet.iov[0].len = *packetLen;
3372
packet.iovCount = 1;
3373
packet.metaPacket = (void *)packetIn;
3374
packet.metaPacketSize = *packetLen;
3375
packet.replyPacket = packetOut;
3376
packet.replyPacketSize = HGFS_LARGE_PACKET_MAX;
3377
packet.supportsAsync = FALSE;
3379
HgfsServerSessionReceive(&packet,
3380
hgfsStaticSession.session);
3383
* At this point, all the HGFS ops send reply synchronously. So
3384
* we should have the reply by now.
3385
* XXX This should change if any async replies are expected.
3388
ASSERT(hgfsStaticSession.bufferOut);
3390
*packetLen = hgfsStaticSession.bufferOutLen;
3392
HgfsServerSessionSendComplete(&packet,
3393
hgfsStaticSession.session);
3394
hgfsStaticSession.bufferOut = NULL;
3400
3825
*----------------------------------------------------------------------------
3429
3854
*----------------------------------------------------------------------------
3856
* HgfsServer_Quiesce --
3858
* The function is called when VM is about to take a snapshot and
3859
* when creation of the snapshot completed. When the freeze is TRUE the
3860
* function quiesces all asynchronous and background activity to prevent
3861
* interactions with snapshots and waits until there is no such activity.
3862
* When freeze is FALSE the function restarts background activity that
3863
* has been suspended previously.
3871
*----------------------------------------------------------------------------
3875
HgfsServer_Quiesce(Bool freeze) // IN:
3877
if (!gHgfsInitialized) {
3882
/* Suspend background activity. */
3883
if (gHgfsDirNotifyActive) {
3884
HgfsNotify_Suspend();
3886
/* Wait for outstanding asynchronous requests to complete. */
3887
MXUser_AcquireExclLock(gHgfsAsyncLock);
3888
while (Atomic_Read(&gHgfsAsyncCounter)) {
3889
MXUser_WaitCondVarExclLock(gHgfsAsyncLock, gHgfsAsyncVar);
3891
MXUser_ReleaseExclLock(gHgfsAsyncLock);
3893
/* Resume background activity. */
3894
if (gHgfsDirNotifyActive) {
3895
HgfsNotify_Resume();
3902
*----------------------------------------------------------------------------
3904
* HgfsNotifyPacketSent --
3906
* Decrements counter of outstanding asynchronous packets
3907
* and signal conditional variable when the counter
3911
* TRUE on success, FALSE on error.
3916
*----------------------------------------------------------------------------
3920
HgfsNotifyPacketSent(void)
3922
if (Atomic_FetchAndDec(&gHgfsAsyncCounter) == 1) {
3923
MXUser_AcquireExclLock(gHgfsAsyncLock);
3924
MXUser_BroadcastCondVar(gHgfsAsyncVar);
3925
MXUser_ReleaseExclLock(gHgfsAsyncLock);
3931
*----------------------------------------------------------------------------
3431
3933
* HgfsPacketSend --
3433
3935
* Send the packet.
5921
6426
*-----------------------------------------------------------------------------
6428
* HgfsServerSetDirWatchByHandle --
6430
* Sets directory notification watch request using directory handle.
6438
*-----------------------------------------------------------------------------
6441
static HgfsInternalStatus
6442
HgfsServerSetDirWatchByHandle(HgfsInputParam *input, // IN: Input params
6443
HgfsHandle dir, // IN: directory handle
6444
uint32 events, // IN: event types to report
6445
Bool watchTree, // IN: recursive watch
6446
HgfsSubscriberHandle *watchId) // OUT: watch id
6448
HgfsInternalStatus status;
6449
char *fileName = NULL;
6450
size_t fileNameSize;
6451
HgfsSharedFolderHandle sharedFolder = HGFS_INVALID_FOLDER_HANDLE;
6453
ASSERT(watchId != NULL);
6455
if (HgfsHandle2NotifyInfo(dir, input->session, &fileName, &fileNameSize,
6457
*watchId = HgfsNotify_AddSubscriber(sharedFolder, fileName, events, watchTree,
6458
Hgfs_NotificationCallback, input->session);
6459
status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL :
6462
status = HGFS_ERROR_INTERNAL;
6470
*-----------------------------------------------------------------------------
6472
* HgfsServerSetDirWatchByName --
6474
* Sets directory notification watch request using directory name.
6482
*-----------------------------------------------------------------------------
6485
static HgfsInternalStatus
6486
HgfsServerSetDirWatchByName(HgfsInputParam *input, // IN: Input params
6487
char *cpName, // IN: directory name
6488
uint32 cpNameSize, // IN: directory name length
6489
uint32 caseFlags, // IN: case flags
6490
uint32 events, // IN: event types to report
6491
Bool watchTree, // IN: recursive watch
6492
HgfsSubscriberHandle *watchId) // OUT: watch id
6494
HgfsInternalStatus status;
6495
HgfsNameStatus nameStatus;
6496
char *utf8Name = NULL;
6498
HgfsShareInfo shareInfo;
6499
HgfsSharedFolderHandle sharedFolder = HGFS_INVALID_FOLDER_HANDLE;
6501
ASSERT(cpName != NULL);
6502
ASSERT(watchId != NULL);
6504
nameStatus = HgfsServerGetShareInfo(cpName, cpNameSize, caseFlags, &shareInfo,
6505
&utf8Name, &utf8NameLen);
6506
if (HGFS_NAME_STATUS_COMPLETE == nameStatus) {
6507
char const *inEnd = cpName + cpNameSize;
6513
* Get first component.
6515
len = CPName_GetComponent(cpName, inEnd, (char const **) &next);
6517
LOG(4, ("%s: get first component failed\n", __FUNCTION__));
6518
nameStatus = HGFS_NAME_STATUS_FAILURE;
6519
} else if (0 == len) {
6520
/* See if we are dealing with the base of the namespace */
6521
nameStatus = HGFS_NAME_STATUS_INCOMPLETE_BASE;
6523
sharedFolder = HgfsServerGetShareHandle(cpName);
6526
if (HGFS_NAME_STATUS_COMPLETE == nameStatus &&
6527
HGFS_INVALID_FOLDER_HANDLE != sharedFolder) {
6528
if (cpNameSize > len + 1) {
6529
size_t nameSize = cpNameSize - len - 1;
6530
char tempBuf[HGFS_PATH_MAX];
6531
char *tempPtr = tempBuf;
6532
size_t tempSize = sizeof tempBuf;
6534
nameStatus = CPName_ConvertFrom((char const **) &next, &nameSize,
6535
&tempSize, &tempPtr);
6536
if (HGFS_NAME_STATUS_COMPLETE == nameStatus) {
6537
*watchId = HgfsNotify_AddSubscriber(sharedFolder, tempBuf, events,
6538
watchTree, Hgfs_NotificationCallback,
6540
status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ?
6541
HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS;
6543
LOG(4, ("%s: Conversion to platform specific name failed\n",
6545
status = HgfsPlatformConvertFromNameStatus(nameStatus);
6548
*watchId = HgfsNotify_AddSubscriber(sharedFolder, "", events, watchTree,
6549
Hgfs_NotificationCallback,
6551
status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL :
6554
} else if (HGFS_NAME_STATUS_INCOMPLETE_BASE == nameStatus) {
6555
LOG(4, ("%s: Notification for root share is not supported yet\n",
6557
status = HGFS_ERROR_INVALID_PARAMETER;
6559
LOG(4, ("%s: file not found.\n", __FUNCTION__));
6560
status = HgfsPlatformConvertFromNameStatus(nameStatus);
6563
LOG(4, ("%s: file not found.\n", __FUNCTION__));
6564
status = HgfsPlatformConvertFromNameStatus(nameStatus);
6572
*-----------------------------------------------------------------------------
6574
* HgfsServerSetDirNotifyWatch --
6576
* Handle a set directory notification watch request.
6584
*-----------------------------------------------------------------------------
6588
HgfsServerSetDirNotifyWatch(HgfsInputParam *input) // IN: Input params
6592
HgfsInternalStatus status;
6595
size_t replyPayloadSize = 0;
6598
HgfsSubscriberHandle watchId = HGFS_INVALID_SUBSCRIBER_HANDLE;
6601
HGFS_ASSERT_INPUT(input);
6604
* If the active session does not support directory change notification - bail out
6605
* with an error immediately. Otherwise setting watch may succeed but no notification
6606
* will be delivered when a change occurs.
6608
if (!input->session->activeNotification) {
6609
HgfsServerCompleteRequest(HGFS_ERROR_PROTOCOL, 0, input);
6613
if (HgfsUnpackSetWatchRequest(input->payload, input->payloadSize, input->op,
6614
&useHandle, &cpName, &cpNameSize, &flags, &events,
6615
&dir, &caseFlags)) {
6616
Bool watchTree = 0 != (flags & HGFS_NOTIFY_FLAG_WATCH_TREE);
6618
status = HgfsServerSetDirWatchByHandle(input, dir, events, watchTree, &watchId);
6620
status = HgfsServerSetDirWatchByName(input, cpName, cpNameSize, caseFlags,
6621
events, watchTree, &watchId);
6623
if (HGFS_ERROR_SUCCESS == status) {
6624
if (!HgfsPackSetWatchReply(input->packet, input->metaPacket, input->op,
6625
watchId, &replyPayloadSize, input->session)) {
6626
status = HGFS_ERROR_INTERNAL;
6630
status = HGFS_ERROR_PROTOCOL;
6633
HgfsServerCompleteRequest(status, replyPayloadSize, input);
6638
*-----------------------------------------------------------------------------
6640
* HgfsServerRemoveDirNotifyWatch --
6642
* Handle a remove directory notification watch request.
6650
*-----------------------------------------------------------------------------
6654
HgfsServerRemoveDirNotifyWatch(HgfsInputParam *input) // IN: Input params
6656
HgfsSubscriberHandle watchId;
6657
HgfsInternalStatus status;
6658
size_t replyPayloadSize = 0;
6660
HGFS_ASSERT_INPUT(input);
6662
if (HgfsUnpackRemoveWatchRequest(input->payload, input->payloadSize, input->op,
6664
if (HgfsNotify_RemoveSubscriber(watchId)) {
6665
status = HGFS_ERROR_SUCCESS;
6667
status = HGFS_ERROR_INTERNAL;
6670
status = HGFS_ERROR_PROTOCOL;
6672
if (HGFS_ERROR_SUCCESS == status) {
6673
if (!HgfsPackRemoveWatchReply(input->packet, input->metaPacket, input->op,
6674
&replyPayloadSize, input->session)) {
6675
status = HGFS_ERROR_INTERNAL;
6679
HgfsServerCompleteRequest(status, replyPayloadSize, input);
6684
*-----------------------------------------------------------------------------
5923
6686
* HgfsServerGetattr --
5925
6688
* Handle a Getattr request.
6836
Hgfs_NotificationCallback(HgfsSharedFolderHandle sharedFolder,
6837
HgfsSubscriberHandle subscriber,
7627
Hgfs_NotificationCallback(HgfsSharedFolderHandle sharedFolder, // IN: shared folder
7628
HgfsSubscriberHandle subscriber, // IN: subsciber
7629
char* fileName, // IN: name of the file
7630
uint32 mask, // IN: event type
7631
struct HgfsSessionInfo *session) // IN: session info
6842
LOG(4, ("%s: notification for folder: %d index: %d file name %s "
6843
"(new name %s) mask %x\n", __FUNCTION__, sharedFolder,
6844
(int)subscriber, name, (newName == NULL) ? "" : newName,
7636
size_t shareNameLen;
7637
HgfsHeader *packetHeader;
7640
if (HgfsServerGetShareName(sharedFolder, &shareNameLen, &shareName)) {
7642
sizeNeeded = HgfsPackCalculateNotificationSize(shareName, fileName);
7644
packetHeader = Util_SafeCalloc(1, sizeNeeded);
7645
packet = Util_SafeCalloc(1, sizeof *packet);
7646
packet->guestInitiated = FALSE;
7647
packet->metaPacketSize = sizeNeeded;
7648
packet->metaPacket = packetHeader;
7649
packet->dataPacketIsAllocated = TRUE;
7651
if (mask & HGFS_NOTIFY_EVENTS_DROPPED) {
7652
flags |= HGFS_NOTIFY_FLAG_OVERFLOW;
7655
HgfsPackChangeNotificationRequest(packetHeader, subscriber, shareName, fileName, mask,
7656
flags, session, &sizeNeeded);
7657
if (!HgfsPacketSend(packet, (char *)packetHeader, sizeNeeded, session, 0)) {
7658
LOG(4, ("%s: failed to send notification to the host\n", __FUNCTION__));
7661
LOG(4, ("%s: notification for folder: %d index: %d file name %s "
7662
" mask %x\n", __FUNCTION__, sharedFolder,
7663
(int)subscriber, fileName, mask));
7666
LOG(4, ("%s: failed to find shared folder for a handle %x\n",
7667
__FUNCTION__, sharedFolder));