Changeset 98709 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Feb 24, 2023 8:49:40 AM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 156009
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r98667 r98709 47 47 48 48 #include <VBox/com/array.h> 49 #include <VBox/com/listeners.h> 49 50 #include <VBox/AssertGuest.h> 50 51 52 53 /** 54 * Internal listener class to serve events in an 55 * active manner, e.g. without polling delays. 56 */ 57 class GuestDirectoryListener 58 { 59 public: 60 61 GuestDirectoryListener(void) 62 { 63 } 64 65 virtual ~GuestDirectoryListener() 66 { 67 } 68 69 HRESULT init(GuestDirectory *pDir) 70 { 71 AssertPtrReturn(pDir, E_POINTER); 72 mDir = pDir; 73 return S_OK; 74 } 75 76 void uninit(void) 77 { 78 mDir = NULL; 79 } 80 81 STDMETHOD(HandleEvent)(VBoxEventType_T aType, IEvent *aEvent) 82 { 83 switch (aType) 84 { 85 case VBoxEventType_OnGuestDirectoryStateChanged: 86 RT_FALL_THROUGH(); 87 case VBoxEventType_OnGuestDirectoryRead: 88 { 89 AssertPtrReturn(mDir, E_POINTER); 90 int vrc2 = mDir->signalWaitEvent(aType, aEvent); 91 RT_NOREF(vrc2); 92 #ifdef DEBUG_andy 93 LogFlowFunc(("Signalling events of type=%RU32, dir=%p resulted in vrc=%Rrc\n", 94 aType, mDir, vrc2)); 95 #endif 96 break; 97 } 98 99 default: 100 AssertMsgFailed(("Unhandled event %RU32\n", aType)); 101 break; 102 } 103 104 return S_OK; 105 } 106 107 private: 108 109 /** Weak pointer to the guest directory object to listen for. */ 110 GuestDirectory *mDir; 111 }; 112 typedef ListenerImpl<GuestDirectoryListener, GuestDirectory *> GuestDirectoryListenerImpl; 113 114 VBOX_LISTENER_DECLARE(GuestDirectoryListenerImpl) 51 115 52 116 // constructor / destructor … … 98 162 if (FAILED(hr)) 99 163 vrc = VERR_COM_UNEXPECTED; 164 } 165 166 if (RT_SUCCESS(vrc)) 167 { 168 try 169 { 170 GuestDirectoryListener *pListener = new GuestDirectoryListener(); 171 ComObjPtr<GuestDirectoryListenerImpl> thisListener; 172 HRESULT hr = thisListener.createObject(); 173 if (SUCCEEDED(hr)) 174 hr = thisListener->init(pListener, this); 175 176 if (SUCCEEDED(hr)) 177 { 178 com::SafeArray <VBoxEventType_T> eventTypes; 179 eventTypes.push_back(VBoxEventType_OnGuestDirectoryStateChanged); 180 eventTypes.push_back(VBoxEventType_OnGuestDirectoryRead); 181 hr = mEventSource->RegisterListener(thisListener, 182 ComSafeArrayAsInParam(eventTypes), 183 TRUE /* Active listener */); 184 if (SUCCEEDED(hr)) 185 { 186 vrc = baseInit(); 187 if (RT_SUCCESS(vrc)) 188 { 189 mLocalListener = thisListener; 190 } 191 } 192 else 193 vrc = VERR_COM_UNEXPECTED; 194 } 195 else 196 vrc = VERR_COM_UNEXPECTED; 197 } 198 catch(std::bad_alloc &) 199 { 200 vrc = VERR_NO_MEMORY; 201 } 100 202 } 101 203 … … 194 296 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 195 297 196 LogFlowThisFunc(("strPath=%s, uContextID=%RU32, u Function=%RU32, pSvcCb=%p\n",298 LogFlowThisFunc(("strPath=%s, uContextID=%RU32, uMessage=%RU32, pSvcCb=%p\n", 197 299 mData.mOpenInfo.mPath.c_str(), pCbCtx->uContextID, pCbCtx->uMessage, pSvcCb)); 198 300 … … 248 350 } 249 351 352 if (RT_FAILURE(vrc)) 353 return vrc; 354 250 355 /* Prepare HGCM call. */ 251 356 VBOXHGCMSVCPARM paParms[8]; 252 357 int i = 0; 253 358 HGCMSvcSetU32(&paParms[i++], pEvent->ContextID()); 254 HGCMSvcSetPv(&paParms[i++], (void *)mData.mOpenInfo.mPath.c_str(), (ULONG)mData.mOpenInfo.mPath.length() + 1); 255 HGCMSvcSetPv(&paParms[i++], (void *)mData.mOpenInfo.mFilter.c_str(), (ULONG)mData.mOpenInfo.mFilter.length() + 1); 359 HGCMSvcSetStr(&paParms[i++], mData.mOpenInfo.mPath.c_str()); 256 360 HGCMSvcSetU32(&paParms[i++], mData.mOpenInfo.menmFilter); 257 361 HGCMSvcSetU32(&paParms[i++], mData.mOpenInfo.mFlags); … … 261 365 vrc = sendMessage(HOST_MSG_DIR_OPEN, i, paParms); 262 366 if (RT_SUCCESS(vrc)) 263 { 264 vrc = pEvent->Wait(30 * 1000); 265 if (RT_SUCCESS(vrc)) 266 { 267 } 268 } 367 vrc = i_waitForStatusChange(pEvent, 30 * 1000, NULL /* FileStatus */, pvrcGuest); 269 368 } 270 369 else … … 385 484 { 386 485 hrc = errorInfo->initEx(VBOX_E_GSTCTL_GUEST_ERROR, vrcGuest, 387 COM_IIDOF(IGuest File), getComponentName(),486 COM_IIDOF(IGuestDirectory), getComponentName(), 388 487 i_guestErrorToString(vrcGuest, mData.mOpenInfo.mPath.c_str())); 389 488 ComAssertComRCRet(hrc, VERR_COM_UNEXPECTED); … … 400 499 case GUEST_DIR_NOTIFYTYPE_OPEN: 401 500 { 501 AssertBreakStmt(pSvcCbData->mParms >= 4, vrc = VERR_INVALID_PARAMETER); 502 vrc = HGCMSvcGetU32(&pSvcCbData->mpaParms[idx++], &dataCb.u.open.uHandle /* Guest native file handle */); 503 AssertRCBreak(vrc); 402 504 vrc = i_setStatus(DirectoryStatus_Open, vrcGuest); 403 505 break; … … 417 519 ("type=%u\n", pSvcCbData->mpaParms[idx].type), 418 520 vrc = VERR_WRONG_PARAMETER_TYPE); 419 420 PGSTCTLFSOBJINFO pObjInfo; 421 uint32_t cbObjInfo; 422 vrc = HGCMSvcGetPv(&pSvcCbData->mpaParms[idx++], (void **)&pObjInfo, &cbObjInfo); 521 PGSTCTLDIRENTRYEX pEntry; 522 uint32_t cbEntry; 523 vrc = HGCMSvcGetPv(&pSvcCbData->mpaParms[idx++], (void **)&pEntry, &cbEntry); 423 524 AssertRCBreak(vrc); 424 AssertBreakStmt(cbObjInfo == sizeof(GSTCTLFSOBJINFO), VERR_INVALID_PARAMETER); 425 426 GuestFsObjData fsObjData(mData.mOpenInfo.mPath); 427 vrc = fsObjData.FromGuestFsObjInfo(pObjInfo); 525 AssertBreakStmt( cbEntry >= sizeof(GSTCTLDIRENTRYEX) 526 && cbEntry <= GSTCTL_DIRENTRY_MAX_SIZE, VERR_INVALID_PARAMETER); 527 dataCb.u.read.pEntry = (PGSTCTLDIRENTRYEX)RTMemDup(pEntry, cbEntry); 528 AssertPtrBreakStmt(dataCb.u.read.pEntry, vrc = VERR_NO_MEMORY); 529 dataCb.u.read.cbEntry = cbEntry; 530 531 char *pszUser; 532 uint32_t cbUser; 533 vrc = HGCMSvcGetStr(&pSvcCbData->mpaParms[idx++], &pszUser, &cbUser); 534 AssertRCBreak(vrc); 535 dataCb.u.read.pszUser = RTStrDup(pszUser); 536 AssertPtrBreakStmt(dataCb.u.read.pszUser, vrc = VERR_NO_MEMORY); 537 dataCb.u.read.cbUser = cbUser; 538 539 char *pszGroups; 540 uint32_t cbGroups; 541 vrc = HGCMSvcGetStr(&pSvcCbData->mpaParms[idx++], &pszGroups, &cbGroups); 542 AssertRCBreak(vrc); 543 dataCb.u.read.pszGroups = RTStrDup(pszGroups); 544 AssertPtrBreakStmt(dataCb.u.read.pszGroups, vrc = VERR_NO_MEMORY); 545 dataCb.u.read.cbGroups = cbGroups; 546 547 /** @todo ACLs not implemented yet. */ 548 549 GuestFsObjData fsObjData(dataCb.u.read.pEntry->szName); 550 vrc = fsObjData.FromGuestFsObjInfo(&dataCb.u.read.pEntry->Info); 428 551 AssertRCBreak(vrc); 429 552 ComObjPtr<GuestFsObjInfo> ptrFsObjInfo; 430 553 hrc = ptrFsObjInfo.createObject(); 431 ComAssertComRCBreak(hrc, VERR_COM_UNEXPECTED);554 ComAssertComRCBreak(hrc, vrc = VERR_COM_UNEXPECTED); 432 555 vrc = ptrFsObjInfo->init(fsObjData); 433 556 AssertRCBreak(vrc); 434 557 435 ::FireGuestDirectoryReadEvent(mEventSource, mSession, this, ptrFsObjInfo); 558 ::FireGuestDirectoryReadEvent(mEventSource, mSession, this, 559 dataCb.u.read.pEntry->szName, ptrFsObjInfo, dataCb.u.read.pszUser, dataCb.u.read.pszGroups); 436 560 break; 437 561 } … … 481 605 * 482 606 * @returns Error string. 483 * @param vrcGuest Guest fileerror to return string for.607 * @param vrcGuest Guest directory error to return string for. 484 608 * @param pcszWhat Hint of what was involved when the error occurred. 485 609 */ … … 550 674 if (mSession->i_getParent()->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS) 551 675 { 552 /// @todo To be implemented 553 vrc = VERR_NOT_IMPLEMENTED; 676 GuestWaitEvent *pEvent = NULL; 677 GuestEventTypes eventTypes; 678 try 679 { 680 eventTypes.push_back(VBoxEventType_OnGuestDirectoryStateChanged); 681 682 vrc = registerWaitEvent(eventTypes, &pEvent); 683 } 684 catch (std::bad_alloc &) 685 { 686 vrc = VERR_NO_MEMORY; 687 } 688 689 if (RT_FAILURE(vrc)) 690 return vrc; 691 692 /* Prepare HGCM call. */ 693 VBOXHGCMSVCPARM paParms[2]; 694 int i = 0; 695 HGCMSvcSetU32(&paParms[i++], pEvent->ContextID()); 696 HGCMSvcSetU32(&paParms[i++], mObjectID /* Guest directory handle */); 697 698 vrc = sendMessage(HOST_MSG_DIR_CLOSE, i, paParms); 699 if (RT_SUCCESS(vrc)) 700 { 701 vrc = pEvent->Wait(30 * 1000); 702 if (RT_SUCCESS(vrc)) 703 { 704 // Nothing to do here. 705 } 706 else if (pEvent->HasGuestError() && pvrcGuest) 707 *pvrcGuest = pEvent->GuestResult(); 708 } 554 709 } 555 710 else … … 595 750 596 751 int vrc; 752 int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS; 753 597 754 #ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS 598 755 if (mSession->i_getParent()->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS) 599 756 { 600 /// @todo To be implemented 601 RT_NOREF(objData, pvrcGuest); 602 vrc = 0; 757 GuestWaitEvent *pEvent = NULL; 758 GuestEventTypes eventTypes; 759 try 760 { 761 vrc = registerWaitEvent(eventTypes, &pEvent); 762 } 763 catch (std::bad_alloc &) 764 { 765 vrc = VERR_NO_MEMORY; 766 } 767 768 if (RT_FAILURE(vrc)) 769 return vrc; 770 771 /* Prepare HGCM call. */ 772 VBOXHGCMSVCPARM paParms[8]; 773 int i = 0; 774 HGCMSvcSetU32(&paParms[i++], pEvent->ContextID()); 775 HGCMSvcSetU32(&paParms[i++], mObjectID /* Guest directory handle */); 776 HGCMSvcSetU32(&paParms[i++], GSTCTL_DIRENTRY_MAX_SIZE); 777 HGCMSvcSetU32(&paParms[i++], GSTCTLFSOBJATTRADD_UNIX /* Implicit */); 778 HGCMSvcSetU32(&paParms[i++], GSTCTL_PATH_F_ON_LINK); 779 780 vrc = sendMessage(HOST_MSG_DIR_READ, i, paParms); 781 if (RT_SUCCESS(vrc)) 782 { 783 vrc = pEvent->Wait(30 * 1000); 784 if (RT_SUCCESS(vrc)) 785 { 786 PCALLBACKDATA_DIR_NOTIFY const pDirNotify = (PCALLBACKDATA_DIR_NOTIFY)pEvent->Payload().Raw(); 787 AssertPtrReturn(pDirNotify, VERR_INVALID_POINTER); 788 vrcGuest = (int)pDirNotify->rc; 789 if (RT_SUCCESS(vrcGuest)) 790 { 791 AssertReturn(pDirNotify->uType == GUEST_DIR_NOTIFYTYPE_READ, VERR_INVALID_PARAMETER); 792 AssertPtrReturn(pDirNotify->u.read.pEntry, VERR_INVALID_POINTER); 793 objData.Init(pDirNotify->u.read.pEntry->szName); 794 vrc = objData.FromGuestFsObjInfo(&pDirNotify->u.read.pEntry->Info, 795 pDirNotify->u.read.pszUser, pDirNotify->u.read.pszGroups); 796 RTMemFree(pDirNotify->u.read.pEntry); 797 RTStrFree(pDirNotify->u.read.pszUser); 798 RTStrFree(pDirNotify->u.read.pszGroups); 799 } 800 else 801 { 802 if (pvrcGuest) 803 *pvrcGuest = vrcGuest; 804 vrc = VERR_GSTCTL_GUEST_ERROR; 805 } 806 } 807 else if (pEvent->HasGuestError() && pvrcGuest) 808 *pvrcGuest = pEvent->GuestResult(); 809 } 603 810 } 604 811 else … … 813 1020 alock.release(); /* Release lock before firing off event. */ 814 1021 815 ::FireGuestDirectoryStateChangedEvent(mEventSource, mSession, this, enmStatus, errorInfo);1022 ::FireGuestDirectoryStateChangedEvent(mEventSource, mSession, this, mData.mStatus, errorInfo); 816 1023 } 817 1024 818 1025 return VINF_SUCCESS; 1026 } 1027 1028 /** 1029 * Waits for a guest directory status change. 1030 * 1031 * @note Similar code in GuestFile::i_waitForStatusChange(). 1032 * 1033 * @returns VBox status code. 1034 * @retval VERR_GSTCTL_GUEST_ERROR when an error from the guest side has been received. 1035 * @param pEvent Guest wait event to wait for. 1036 * @param uTimeoutMS Timeout (in ms) to wait. 1037 * @param penmStatus Where to return the directoy status on success. 1038 * @param prcGuest Where to return the guest error when VERR_GSTCTL_GUEST_ERROR was returned. 1039 */ 1040 int GuestDirectory::i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, 1041 DirectoryStatus_T *penmStatus, int *prcGuest) 1042 { 1043 AssertPtrReturn(pEvent, VERR_INVALID_POINTER); 1044 /* penmStatus is optional. */ 1045 1046 VBoxEventType_T evtType; 1047 ComPtr<IEvent> pIEvent; 1048 int vrc = waitForEvent(pEvent, uTimeoutMS, &evtType, pIEvent.asOutParam()); 1049 if (RT_SUCCESS(vrc)) 1050 { 1051 AssertReturn(evtType == VBoxEventType_OnGuestDirectoryStateChanged, VERR_WRONG_TYPE); 1052 ComPtr<IGuestDirectoryStateChangedEvent> pDirectoryEvent = pIEvent; 1053 AssertReturn(!pDirectoryEvent.isNull(), VERR_COM_UNEXPECTED); 1054 1055 HRESULT hr; 1056 if (penmStatus) 1057 { 1058 hr = pDirectoryEvent->COMGETTER(Status)(penmStatus); 1059 ComAssertComRC(hr); 1060 } 1061 1062 ComPtr<IVirtualBoxErrorInfo> errorInfo; 1063 hr = pDirectoryEvent->COMGETTER(Error)(errorInfo.asOutParam()); 1064 ComAssertComRC(hr); 1065 1066 LONG lGuestRc; 1067 hr = errorInfo->COMGETTER(ResultDetail)(&lGuestRc); 1068 ComAssertComRC(hr); 1069 1070 LogFlowThisFunc(("resultDetail=%RI32 (%Rrc)\n", lGuestRc, lGuestRc)); 1071 1072 if (RT_FAILURE((int)lGuestRc)) 1073 vrc = VERR_GSTCTL_GUEST_ERROR; 1074 1075 if (prcGuest) 1076 *prcGuest = (int)lGuestRc; 1077 } 1078 /* waitForEvent may also return VERR_GSTCTL_GUEST_ERROR like we do above, so make prcGuest is set. */ 1079 /** @todo Also see todo in GuestFile::i_waitForStatusChange(). */ 1080 else if (vrc == VERR_GSTCTL_GUEST_ERROR && prcGuest) 1081 *prcGuest = pEvent->GuestResult(); 1082 Assert(vrc != VERR_GSTCTL_GUEST_ERROR || !prcGuest || *prcGuest != (int)0xcccccccc); 1083 1084 return vrc; 819 1085 } 820 1086 -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r98667 r98709 1979 1979 return vrc; 1980 1980 1981 uint32_t const fFlags = fFollowSymlinks ? GSTCTL_ QUERYINFO_F_FOLLOW_LINK : GSTCTL_QUERYINFO_F_ON_LINK;1981 uint32_t const fFlags = fFollowSymlinks ? GSTCTL_PATH_F_FOLLOW_LINK : GSTCTL_PATH_F_ON_LINK; 1982 1982 1983 1983 /* Prepare HGCM call. */ … … 2271 2271 case GUEST_FS_NOTIFYTYPE_QUERY_INFO: 2272 2272 { 2273 AssertBreakStmt(pSvcCbData->mParms >= 7, VERR_INVALID_PARAMETER);2273 AssertBreakStmt(pSvcCbData->mParms >= 7, vrc = VERR_INVALID_PARAMETER); 2274 2274 PGSTCTLFSOBJINFO pObjInfo; 2275 2275 uint32_t cbObjInfo; 2276 2276 vrc = HGCMSvcGetPv(&pSvcCbData->mpaParms[3], (void **)&pObjInfo, &cbObjInfo); 2277 2277 AssertRCBreak(vrc); 2278 AssertBreakStmt(cbObjInfo == sizeof(GSTCTLFSOBJINFO), VERR_INVALID_PARAMETER);2278 AssertBreakStmt(cbObjInfo == sizeof(GSTCTLFSOBJINFO), vrc = VERR_INVALID_PARAMETER); 2279 2279 memcpy(&dataCb.u.QueryInfo.objInfo, pObjInfo, sizeof(GSTCTLFSOBJINFO)); 2280 2280
Note:
See TracChangeset
for help on using the changeset viewer.