Changeset 71406 in vbox
- Timestamp:
- Mar 20, 2018 2:44:24 PM (7 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r71314 r71406 686 686 /** The session's friendly name. Optional. */ 687 687 Utf8Str mName; 688 /** The session's unique ID. Used to encode 689 * a context ID. */ 688 /** The session's unique ID. Used to encode a context ID. */ 690 689 uint32_t mID; 691 690 /** Flag indicating if this is an internal session … … 907 906 GuestWaitEventPayload(uint32_t uTypePayload, 908 907 const void *pvPayload, uint32_t cbPayload) 909 { 908 : uType(0), 909 cbData(0), 910 pvData(NULL) 911 { 912 int rc = copyFrom(uTypePayload, pvPayload, cbPayload); 913 if (RT_FAILURE(rc)) 914 throw rc; 915 } 916 917 virtual ~GuestWaitEventPayload(void) 918 { 919 Clear(); 920 } 921 922 GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that) 923 { 924 CopyFromDeep(that); 925 return *this; 926 } 927 928 public: 929 930 void Clear(void) 931 { 932 if (pvData) 933 { 934 Assert(cbData); 935 RTMemFree(pvData); 936 cbData = 0; 937 pvData = NULL; 938 } 939 uType = 0; 940 } 941 942 int CopyFromDeep(const GuestWaitEventPayload &payload) 943 { 944 return copyFrom(payload.uType, payload.pvData, payload.cbData); 945 } 946 947 const void* Raw(void) const { return pvData; } 948 949 size_t Size(void) const { return cbData; } 950 951 uint32_t Type(void) const { return uType; } 952 953 void* MutableRaw(void) { return pvData; } 954 955 Utf8Str ToString(void) 956 { 957 const char *pszStr = (const char *)pvData; 958 size_t cbStr = cbData; 959 960 if (RT_FAILURE(RTStrValidateEncodingEx(pszStr, cbStr, 961 RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED | RTSTR_VALIDATE_ENCODING_EXACT_LENGTH))) 962 { 963 AssertFailed(); 964 return ""; 965 } 966 967 return Utf8Str(pszStr, cbStr); 968 } 969 970 protected: 971 972 int copyFrom(uint32_t uTypePayload, const void *pvPayload, uint32_t cbPayload) 973 { 974 if (cbPayload > _64K) /* Paranoia. */ 975 return VERR_TOO_MUCH_DATA; 976 977 Clear(); 978 979 int rc = VINF_SUCCESS; 980 910 981 if (cbPayload) 911 982 { … … 918 989 cbData = cbPayload; 919 990 } 920 else /* Throw IPRT error. */921 throwVERR_NO_MEMORY;991 else 992 rc = VERR_NO_MEMORY; 922 993 } 923 994 else … … 928 999 cbData = 0; 929 1000 } 930 }931 932 virtual ~GuestWaitEventPayload(void)933 {934 Clear();935 }936 937 GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that)938 {939 CopyFromDeep(that);940 return *this;941 }942 943 public:944 945 void Clear(void)946 {947 if (pvData)948 {949 RTMemFree(pvData);950 cbData = 0;951 pvData = NULL;952 }953 uType = 0;954 }955 956 int CopyFromDeep(const GuestWaitEventPayload &payload)957 {958 Clear();959 960 int rc = VINF_SUCCESS;961 if (payload.cbData)962 {963 Assert(payload.cbData);964 pvData = RTMemAlloc(payload.cbData);965 if (pvData)966 {967 memcpy(pvData, payload.pvData, payload.cbData);968 cbData = payload.cbData;969 uType = payload.uType;970 }971 else972 rc = VERR_NO_MEMORY;973 }974 1001 975 1002 return rc; 976 }977 978 const void* Raw(void) const { return pvData; }979 980 size_t Size(void) const { return cbData; }981 982 uint32_t Type(void) const { return uType; }983 984 void* MutableRaw(void) { return pvData; }985 986 Utf8Str ToString(void)987 {988 const char *pszStr = (const char *)pvData;989 size_t cbStr = cbData;990 991 if (!RTStrValidateEncodingEx(pszStr, cbStr,992 RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED | RTSTR_VALIDATE_ENCODING_EXACT_LENGTH))993 return "";994 995 return Utf8Str(pszStr, cbStr);996 1003 } 997 1004 … … 1003 1010 uint32_t cbData; 1004 1011 /** Pointer to actual payload data. */ 1005 void *pvData;1012 void *pvData; 1006 1013 }; 1007 1014 … … 1114 1121 int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID); 1115 1122 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent); 1116 int registerWaitEvent (uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);1123 int registerWaitEventEx(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent); 1117 1124 int unregisterWaitEvent(GuestWaitEvent *pEvent); 1118 1125 int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent); -
trunk/src/VBox/Main/include/GuestDirectoryImpl.h
r71250 r71406 37 37 DECLARE_EMPTY_CTOR_DTOR(GuestDirectory) 38 38 39 int init(Console *pConsole, GuestSession *pSession, ULONG uDirID, const GuestDirectoryOpenInfo &openInfo);39 int init(Console *pConsole, GuestSession *pSession, ULONG aObjectID, const GuestDirectoryOpenInfo &openInfo); 40 40 void uninit(void); 41 41 … … 79 79 /** The directory's open info. */ 80 80 GuestDirectoryOpenInfo mOpenInfo; 81 /** The directory's ID. */82 uint32_t mID;83 81 /** The process tool instance to use. */ 84 82 GuestProcessTool mProcessTool; -
trunk/src/VBox/Main/include/GuestFileImpl.h
r69500 r71406 123 123 /** The file's initial size on open. */ 124 124 uint64_t mInitialSize; 125 /** The file's ID. */126 uint32_t mID;127 125 /** The current file status. */ 128 126 FileStatus_T mStatus; -
trunk/src/VBox/Main/include/GuestImpl.h
r69500 r71406 5 5 6 6 /* 7 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 202 202 #ifdef VBOX_WITH_GUEST_CONTROL 203 203 GuestSessions mGuestSessions; 204 uint32_t mNextSessionID;205 204 #endif 206 205 } mData; -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r71301 r71406 40 40 DECLARE_EMPTY_CTOR_DTOR(GuestProcess) 41 41 42 int init(Console *aConsole, GuestSession *aSession, ULONG a ProcessID,42 int init(Console *aConsole, GuestSession *aSession, ULONG aObjectID, 43 43 const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv); 44 44 void uninit(void); … … 147 147 /** Exit code if process has been terminated. */ 148 148 LONG mExitCode; 149 /** PID reported from the guest. */ 149 /** PID reported from the guest. 150 * Note: This is *not* the internal object ID! */ 150 151 ULONG mPID; 151 152 /** The current process status. */ -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r71345 r71406 30 30 31 31 #include <iprt/isofs.h> /* For UpdateAdditions. */ 32 33 #include <deque> 32 34 33 35 class Guest; … … 493 495 typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses; 494 496 497 /** Guest session object type enumeration. */ 498 enum SESSIONOBJECTTYPE 499 { 500 /** Anonymous object. */ 501 SESSIONOBJECTTYPE_ANONYMOUS = 0, 502 /** Session object. */ 503 SESSIONOBJECTTYPE_SESSION = 1, 504 /** Directory object. */ 505 SESSIONOBJECTTYPE_DIRECTORY = 2, 506 /** File object. */ 507 SESSIONOBJECTTYPE_FILE = 3, 508 /** Process object. */ 509 SESSIONOBJECTTYPE_PROCESS = 4, 510 /** The usual 32-bit hack. */ 511 SESSIONOBJECTTYPE_32BIT_HACK = 0x7fffffff 512 }; 513 514 struct SessionObject 515 { 516 /** Creation timestamp (in ms). */ 517 uint64_t tsCreatedMs; 518 /** The object type. */ 519 SESSIONOBJECTTYPE enmType; 520 }; 521 522 /** Map containing all objects bound to a guest session. 523 * The key specifies the (global) context ID. */ 524 typedef std::map <uint32_t, SessionObject> SessionObjects; 525 /** Queue containing context IDs which are no longer in use. 526 * Useful for quickly retrieving a new, unused context ID. */ 527 typedef std::deque <uint32_t> SessionObjectsFree; 528 495 529 public: 496 530 /** @name Public internal methods. 497 531 * @todo r=bird: Most of these are public for no real reason... 498 532 * @{ */ 499 int i_copyToGuestCreateDir(const com::Utf8Str &aDestination, uint32_t fFlags, int *pGuestRc);500 533 int i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc); 501 534 inline bool i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir); 502 int i_directory RemoveFromList(GuestDirectory *pDirectory);535 int i_directoryUnregister(GuestDirectory *pDirectory); 503 536 int i_directoryRemove(const Utf8Str &strPath, uint32_t uFlags, int *pGuestRc); 504 537 int i_directoryCreate(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, int *pGuestRc); 505 int i_objectCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,506 Utf8Str &strName, int *pGuestRc);507 538 int i_directoryOpen(const GuestDirectoryOpenInfo &openInfo, 508 539 ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc); 509 540 int i_directoryQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc); 510 int i_dispatchToDirectory(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);511 int i_dispatchToFile(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);512 541 int i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb); 513 int i_dispatchToProcess(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);514 542 int i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb); 515 543 inline bool i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile); 516 int i_file RemoveFromList(GuestFile *pFile);544 int i_fileUnregister(GuestFile *pFile); 517 545 int i_fileRemove(const Utf8Str &strPath, int *pGuestRc); 518 546 int i_fileOpen(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pGuestRc); 519 547 int i_fileQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc); 520 548 int i_fileQuerySize(const Utf8Str &strPath, bool fFollowSymlinks, int64_t *pllSize, int *pGuestRc); 549 int i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory, 550 Utf8Str &strName, int *pGuestRc); 521 551 int i_fsQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc); 522 552 const GuestCredentials &i_getCredentials(void); … … 533 563 Guest *i_getParent(void) { return mParent; } 534 564 uint32_t i_getProtocolVersion(void) { return mData.mProtocolVersion; } 565 int i_objectRegister(SESSIONOBJECTTYPE enmType, uint32_t *puObjectID); 566 int i_objectRegisterEx(SESSIONOBJECTTYPE enmType, uint32_t fFlags, uint32_t *puObjectID); 567 int i_objectUnregister(uint32_t uObjectID); 535 568 int i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *pGuestRc); 536 569 int i_pathUserDocuments(Utf8Str &strPath, int *prcGuest); 537 570 int i_pathUserHome(Utf8Str &strPath, int *prcGuest); 538 int i_process RemoveFromList(GuestProcess *pProcess);571 int i_processUnregister(GuestProcess *pProcess); 539 572 int i_processCreateEx(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress); 540 573 inline bool i_processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess); … … 571 604 /** The session's startup info. */ 572 605 GuestSessionStartupInfo mSession; 606 /** The session's object ID. 607 * Needed for registering wait events which are bound directly to this session. */ 608 uint32_t mObjectID; 573 609 /** The session's current status. */ 574 610 GuestSessionStatus_T mStatus; … … 586 622 /** Process objects bound to this session. */ 587 623 SessionProcesses mProcesses; 624 /** Map of registered session objects (files, directories, ...). */ 625 SessionObjects mObjects; 626 /** Queue of object IDs which are not used anymore (free list). 627 * Acts as a "free list" for the mObjects map. */ 628 SessionObjectsFree mObjectsFree; 588 629 /** Guest control protocol version to be used. 589 630 * Guest Additions < VBox 4.3 have version 1, … … 592 633 /** Session timeout (in ms). */ 593 634 uint32_t mTimeout; 594 /** Total number of session objects (processes,595 * files, ...). */596 uint32_t mNumObjects;597 635 /** The last returned session status 598 636 * returned from the guest side. */ … … 611 649 , mFiles(rThat.mFiles) 612 650 , mProcesses(rThat.mProcesses) 651 , mObjects(rThat.mObjects) 652 , mObjectsFree(rThat.mObjectsFree) 613 653 , mProtocolVersion(rThat.mProtocolVersion) 614 654 , mTimeout(rThat.mTimeout) 615 , mNumObjects(rThat.mNumObjects)616 655 , mRC(rThat.mRC) 617 656 { } -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r71349 r71406 80 80 * changes to the object state. 81 81 */ 82 LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n", 83 pvExtension, u32Function, pvData, cbData)); 82 Log2Func(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n", 83 pvExtension, u32Function, pvData, cbData)); 84 84 85 ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension); 85 86 Assert(!pGuest.isNull()); … … 93 94 */ 94 95 if (cbData != sizeof(VBOXGUESTCTRLHOSTCALLBACK)) 95 return VERR_NOT_SUPPORTED; 96 PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData; 96 { 97 AssertMsgFailed(("Guest control host callback data has wrong size (expected %zu, got %zu)\n", 98 sizeof(VBOXGUESTCTRLHOSTCALLBACK), cbData)); 99 return VINF_SUCCESS; /* Never return any errors back to the guest here. */ 100 } 101 102 const PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData; 97 103 AssertPtr(pSvcCb); 98 104 99 if ( !pSvcCb->mParms) /* At least context ID must be present. */100 return VERR_INVALID_PARAMETER;101 102 uint32_t uContextID;103 int rc = pSvcCb->mpaParms[0].getUInt32(&uContextID);104 AssertMsgRCReturn(rc, ("Unable to extract callback context ID, pvData=%p\n", pSvcCb), rc);105 #ifdef DEBUG 106 LogFlowFunc(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32\n",107 uContextID,108 VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID), 109 VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID),110 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID)));111 #endif 112 113 VBOXGUESTCTRLHOSTCBCTX ctxCb = { u32Function, uContextID };114 rc = pGuest->i_dispatchToSession(&ctxCb, pSvcCb);115 116 LogFlowFunc(("Returning rc=%Rrc\n", rc));117 return rc;105 if (pSvcCb->mParms) /* At least context ID must be present. */ 106 { 107 uint32_t uContextID; 108 int rc = pSvcCb->mpaParms[0].getUInt32(&uContextID); 109 AssertMsgRCReturn(rc, ("Unable to extract callback context ID, pvData=%p\n", pSvcCb), 110 VINF_SUCCESS /* Never return any errors back to the guest here */); 111 112 VBOXGUESTCTRLHOSTCBCTX ctxCb = { u32Function, uContextID }; 113 rc = pGuest->i_dispatchToSession(&ctxCb, pSvcCb); 114 115 Log2Func(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32, rc=%Rrc\n", 116 uContextID, 117 VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID), 118 VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID), 119 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID), rc)); 120 } 121 122 /* Never return any errors back to the guest here. */ 123 return VINF_SUCCESS; 118 124 } 119 125 … … 128 134 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 129 135 130 LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n", 131 pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol)); 136 Log2Func(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n", pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol)); 132 137 133 138 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 134 139 135 uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID); 136 #ifdef DEBUG 137 LogFlowFunc(("uSessionID=%RU32 (%zu total)\n", 138 uSessionID, mData.mGuestSessions.size())); 139 #endif 140 GuestSessions::const_iterator itSession 141 = mData.mGuestSessions.find(uSessionID); 140 const uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID); 141 142 Log2Func(("uSessionID=%RU32 (%zu total)\n", uSessionID, mData.mGuestSessions.size())); 143 144 GuestSessions::const_iterator itSession = mData.mGuestSessions.find(uSessionID); 142 145 143 146 int rc; … … 188 191 break; 189 192 193 /* Process stuff. */ 190 194 case GUEST_EXEC_STATUS: 191 195 case GUEST_EXEC_OUTPUT: 192 196 case GUEST_EXEC_INPUT_STATUS: 193 197 case GUEST_EXEC_IO_NOTIFY: 194 rc = pSession->i_dispatchTo Process(pCtxCb, pSvcCb);198 rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb); 195 199 break; 196 200 201 /* File stuff. */ 197 202 case GUEST_FILE_NOTIFY: 198 rc = pSession->i_dispatchTo File(pCtxCb, pSvcCb);203 rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb); 199 204 break; 200 205 206 /* Session stuff. */ 201 207 case GUEST_SESSION_NOTIFY: 202 208 rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb); … … 204 210 205 211 default: 206 /*207 * Try processing generic messages which might208 * (or might not) supported by certain objects.209 * If the message either is not found or supported210 * by the approprirate object, try handling it211 * in this session object.212 */213 212 rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb); 214 if ( rc == VERR_NOT_FOUND215 || rc == VERR_NOT_SUPPORTED)216 {217 alock.acquire();218 219 rc = pSession->dispatchGeneric(pCtxCb, pSvcCb);220 }221 #ifndef DEBUG_andy222 if (rc == VERR_NOT_IMPLEMENTED)223 AssertMsgFailed(("Received not handled function %RU32\n", pCtxCb->uFunction));224 #endif225 213 break; 226 214 } -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r71326 r71406 681 681 } 682 682 683 /** 684 * Handles generic messages not bound to a specific object type. 685 * 686 * @return VBox status code. VERR_NOT_FOUND if no handler has been found or VERR_NOT_SUPPORTED 687 * if this class does not support the specified callback. 688 * @param pCtxCb Host callback context. 689 * @param pSvcCb Service callback data. 690 */ 683 691 int GuestBase::dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 684 692 { … … 692 700 try 693 701 { 694 LogFlowFunc(("uFunc=%RU32, cParms=%RU32\n", 695 pCtxCb->uFunction, pSvcCb->mParms)); 702 Log2Func(("uFunc=%RU32, cParms=%RU32\n", pCtxCb->uFunction, pSvcCb->mParms)); 696 703 697 704 switch (pCtxCb->uFunction) … … 716 723 GuestWaitEventPayload evPayload(dataCb.uType, dataCb.pvPayload, dataCb.cbPayload); 717 724 vrc = signalWaitEventInternal(pCtxCb, dataCb.rc, &evPayload); 718 if (vrc == VERR_NOT_FOUND)719 vrc = VINF_SUCCESS;720 725 } 721 726 else … … 766 771 } 767 772 768 int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, 769 GuestWaitEvent **ppEvent) 773 /** 774 * Registers (creates) a new wait event based on a given session and object ID. 775 * 776 * From those IDs an unique context ID (CID) will be built, which only can be 777 * around once at a time. 778 * 779 * @returns IPRT status code. VERR_ALREADY_EXISTS if an event with the given session 780 * and object ID already has been registered. 781 * 782 * @param uSessionID Session ID to register wait event for. 783 * @param uObjectID Object ID to register wait event for. 784 * @param ppEvent Pointer to registered (created) wait event on success. 785 * Must be destroyed with unregisterWaitEvent(). 786 */ 787 int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent) 770 788 { 771 789 GuestEventTypes eventTypesEmpty; 772 return registerWaitEvent(uSessionID, uObjectID, eventTypesEmpty, ppEvent); 773 } 774 775 /** 776 * Registers (creates) a new wait event based on a given session and object ID. 790 return registerWaitEventEx(uSessionID, uObjectID, eventTypesEmpty, ppEvent); 791 } 792 793 /** 794 * Registers (creates) a new wait event based on a given session, object ID 795 * and a list of event types to wait for. 777 796 * 778 797 * From those IDs an unique context ID (CID) will be built, which only can be … … 788 807 * Must be destroyed with unregisterWaitEvent(). 789 808 */ 790 int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, 791 const GuestEventTypes &lstEvents, 792 GuestWaitEvent **ppEvent) 809 int GuestBase::registerWaitEventEx(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, 810 GuestWaitEvent **ppEvent) 793 811 { 794 812 AssertPtrReturn(ppEvent, VERR_INVALID_POINTER); … … 1107 1125 { 1108 1126 AssertPtr(mSession); 1109 return GuestBase::registerWaitEvent (mSession->i_getId(), mObjectID, lstEvents, ppEvent);1127 return GuestBase::registerWaitEventEx(mSession->i_getId(), mObjectID, lstEvents, ppEvent); 1110 1128 } 1111 1129 -
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r71302 r71406 58 58 ///////////////////////////////////////////////////////////////////////////// 59 59 60 int GuestDirectory::init(Console *pConsole, GuestSession *pSession, 61 ULONG uDirID, const GuestDirectoryOpenInfo &openInfo) 62 { 63 LogFlowThisFunc(("pConsole=%p, pSession=%p, uDirID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n", 64 pConsole, pSession, uDirID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(), 65 openInfo.mFlags)); 60 int GuestDirectory::init(Console *pConsole, GuestSession *pSession, ULONG aObjectID, const GuestDirectoryOpenInfo &openInfo) 61 { 62 LogFlowThisFunc(("pConsole=%p, pSession=%p, aObjectID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n", 63 pConsole, pSession, aObjectID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(), openInfo.mFlags)); 66 64 67 65 AssertPtrReturn(pConsole, VERR_INVALID_POINTER); … … 72 70 AssertReturn(autoInitSpan.isOk(), E_FAIL); 73 71 74 int vrc = bindToSession(pConsole, pSession, uDirID /* Object ID */);72 int vrc = bindToSession(pConsole, pSession, aObjectID); 75 73 if (RT_SUCCESS(vrc)) 76 74 { 77 mSession = pSession;78 79 mData.mID = uDirID; 75 mSession = pSession; 76 mObjectID = aObjectID; 77 80 78 mData.mOpenInfo = openInfo; 81 79 } … … 262 260 263 261 AssertPtr(mSession); 264 int rc2 = mSession->i_directory RemoveFromList(this);262 int rc2 = mSession->i_directoryUnregister(this); 265 263 if (RT_SUCCESS(rc)) 266 264 rc = rc2; -
trunk/src/VBox/Main/src-client/GuestFileImpl.cpp
r71299 r71406 135 135 * @param pConsole Pointer to console object. 136 136 * @param pSession Pointer to session object. 137 * @param uFileID Host-based file ID (part of the context ID).137 * @param aObjectID The object's ID. 138 138 * @param openInfo File opening information. 139 139 */ 140 140 int GuestFile::init(Console *pConsole, GuestSession *pSession, 141 ULONG uFileID, const GuestFileOpenInfo &openInfo)142 { 143 LogFlowThisFunc(("pConsole=%p, pSession=%p, uFileID=%RU32, strPath=%s\n",144 pConsole, pSession, uFileID, openInfo.mFileName.c_str()));141 ULONG aObjectID, const GuestFileOpenInfo &openInfo) 142 { 143 LogFlowThisFunc(("pConsole=%p, pSession=%p, aObjectID=%RU32, strPath=%s\n", 144 pConsole, pSession, aObjectID, openInfo.mFileName.c_str())); 145 145 146 146 AssertPtrReturn(pConsole, VERR_INVALID_POINTER); … … 151 151 AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED); 152 152 153 int vrc = bindToSession(pConsole, pSession, uFileID /* Object ID */);153 int vrc = bindToSession(pConsole, pSession, aObjectID); 154 154 if (RT_SUCCESS(vrc)) 155 155 { 156 156 mSession = pSession; 157 157 158 mData.mID = uFileID;159 158 mData.mInitialSize = 0; 160 159 mData.mStatus = FileStatus_Undefined; … … 278 277 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 279 278 280 *aId = m Data.mID;279 *aId = mObjectID; 281 280 282 281 return S_OK; … … 381 380 int i = 0; 382 381 paParms[i++].setUInt32(pEvent->ContextID()); 383 paParms[i++].setUInt32(m Data.mID /* Guest file ID */);382 paParms[i++].setUInt32(mObjectID /* Guest file ID */); 384 383 385 384 vrc = sendCommand(HOST_FILE_CLOSE, i, paParms); … … 453 452 AssertRC(rc2); 454 453 455 rc2 = signalWaitEventInternal(pCbCtx, 456 rcGuest, NULL /* pPayload */); 454 rc2 = signalWaitEventInternal(pCbCtx, rcGuest, NULL /* pPayload */); 457 455 AssertRC(rc2); 458 456 … … 476 474 pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle); 477 475 478 AssertMsg(m Data.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),479 ("File ID %RU32 does not match context ID %RU32\n", mData.mID,476 AssertMsg(mObjectID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID), 477 ("File ID %RU32 does not match object ID %RU32\n", mObjectID, 480 478 VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID))); 481 479 … … 687 685 vrc = sendCommand(HOST_FILE_OPEN, i, paParms); 688 686 if (RT_SUCCESS(vrc)) 689 vrc = i_waitForStatusChange(pEvent, uTimeoutMS, 690 NULL /* FileStatus */, prcGuest); 687 vrc = i_waitForStatusChange(pEvent, uTimeoutMS, NULL /* FileStatus */, prcGuest); 691 688 692 689 unregisterWaitEvent(pEvent); … … 730 727 int i = 0; 731 728 paParms[i++].setUInt32(pEvent->ContextID()); 732 paParms[i++].setUInt32(m Data.mID /* File handle */);729 paParms[i++].setUInt32(mObjectID /* File handle */); 733 730 paParms[i++].setUInt32(uSize /* Size (in bytes) to read */); 734 731 … … 785 782 int i = 0; 786 783 paParms[i++].setUInt32(pEvent->ContextID()); 787 paParms[i++].setUInt32(m Data.mID /* File handle */);784 paParms[i++].setUInt32(mObjectID /* File handle */); 788 785 paParms[i++].setUInt64(uOffset /* Offset (in bytes) to start reading */); 789 786 paParms[i++].setUInt32(uSize /* Size (in bytes) to read */); … … 842 839 int i = 0; 843 840 paParms[i++].setUInt32(pEvent->ContextID()); 844 paParms[i++].setUInt32(m Data.mID /* File handle */);841 paParms[i++].setUInt32(mObjectID /* File handle */); 845 842 paParms[i++].setUInt32(eSeekType /* Seek method */); 846 843 /** @todo uint64_t vs. int64_t! */ … … 1091 1088 int i = 0; 1092 1089 paParms[i++].setUInt32(pEvent->ContextID()); 1093 paParms[i++].setUInt32(m Data.mID /* File handle */);1090 paParms[i++].setUInt32(mObjectID /* File handle */); 1094 1091 paParms[i++].setUInt32(cbData /* Size (in bytes) to write */); 1095 1092 paParms[i++].setPointer(pvData, cbData); … … 1150 1147 int i = 0; 1151 1148 paParms[i++].setUInt32(pEvent->ContextID()); 1152 paParms[i++].setUInt32(m Data.mID /* File handle */);1149 paParms[i++].setUInt32(mObjectID /* File handle */); 1153 1150 paParms[i++].setUInt64(uOffset /* Offset where to starting writing */); 1154 1151 paParms[i++].setUInt32(cbData /* Size (in bytes) to write */); … … 1189 1186 1190 1187 AssertPtr(mSession); 1191 int rc2 = mSession->i_file RemoveFromList(this);1188 int rc2 = mSession->i_fileUnregister(this); 1192 1189 if (RT_SUCCESS(rc)) 1193 1190 rc = rc2; -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r71349 r71406 178 178 ///////////////////////////////////////////////////////////////////////////// 179 179 180 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG a ProcessID,180 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aObjectID, 181 181 const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv) 182 182 { 183 LogFlowThisFunc(("aConsole=%p, aSession=%p, a ProcessID=%RU32pBaseEnv=%p\n",184 aConsole, aSession, a ProcessID, pBaseEnv));183 LogFlowThisFunc(("aConsole=%p, aSession=%p, aObjectID=%RU32, pBaseEnv=%p\n", 184 aConsole, aSession, aObjectID, pBaseEnv)); 185 185 186 186 AssertPtrReturn(aConsole, VERR_INVALID_POINTER); … … 193 193 HRESULT hr; 194 194 195 int vrc = bindToSession(aConsole, aSession, a ProcessID /* Object ID */);195 int vrc = bindToSession(aConsole, aSession, aObjectID); 196 196 if (RT_SUCCESS(vrc)) 197 197 { … … 293 293 } 294 294 295 AssertPtr(mSession); 296 mSession->i_processUnregister(this); 297 295 298 baseUninit(); 296 299 297 LogFlowThisFunc(("Returning rc=%Rrc, rcGuest=%Rrc\n", 298 vrc, rcGuest)); 300 LogFlowThisFunc(("Returning rc=%Rrc, rcGuest=%Rrc\n", vrc, rcGuest)); 299 301 RT_NOREF_PV(vrc); 300 302 } … … 337 339 } 338 340 else 339 hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by the guest additions"));341 hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by installed Guest Additions")); 340 342 LogFlowThisFuncLeave(); 341 343 return hrc; … … 1804 1806 1805 1807 int rcGuest; 1806 int vrc = i_terminateProcess(30 * 1000 /* Timeout in ms */, 1807 &rcGuest); 1808 int vrc = i_terminateProcess(30 * 1000 /* Timeout in ms */, &rcGuest); 1808 1809 if (RT_FAILURE(vrc)) 1809 1810 { … … 1831 1832 * still can hold references to it. */ 1832 1833 AssertPtr(mSession); 1833 int rc2 = mSession->i_process RemoveFromList(this);1834 int rc2 = mSession->i_processUnregister(this); 1834 1835 if (RT_SUCCESS(vrc)) 1835 1836 vrc = rc2; … … 1952 1953 GuestProcessTool::~GuestProcessTool(void) 1953 1954 { 1954 terminate(30 * 1000, NULL /* prcGuest */); 1955 if (!pProcess.isNull()) 1956 { 1957 /* Terminate (and unregister) process. */ 1958 pProcess->uninit(); 1959 1960 /* Release reference. */ 1961 pProcess.setNull(); 1962 } 1955 1963 } 1956 1964 … … 2439 2447 LogFlowThisFuncEnter(); 2440 2448 2441 int rc = VINF_SUCCESS;2449 int rc; 2442 2450 if (!pProcess.isNull()) 2443 {2444 2451 rc = pProcess->i_terminateProcess(uTimeoutMS, prcGuest); 2445 pProcess.setNull();2446 }2447 2452 else 2448 2453 rc = VERR_NOT_FOUND; -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r71349 r71406 208 208 mData.mSession.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS; 209 209 210 /* Copy over session credentials. */ 210 211 /** @todo Use an overloaded copy operator. Later. */ 211 212 mData.mCredentials.mUser = guestCreds.mUser; … … 216 217 mData.mRC = VINF_SUCCESS; 217 218 mData.mStatus = GuestSessionStatus_Undefined; 218 mData.mNumObjects = 0;219 219 mData.mpBaseEnvironment = NULL; 220 int rc = mData.mEnvironmentChanges.initChangeRecord(); 220 221 /* 222 * Register an object for the session itself to clearly 223 * distinguish callbacks which are for this session directly, or for 224 * objects (like files, directories, ...) which are bound to this session. 225 */ 226 int rc = i_objectRegister(SESSIONOBJECTTYPE_SESSION, &mData.mObjectID); 221 227 if (RT_SUCCESS(rc)) 222 228 { 223 rc = RTCritSectInit(&mWaitEventCritSect); 224 AssertRC(rc); 225 } 229 rc = mData.mEnvironmentChanges.initChangeRecord(); 230 if (RT_SUCCESS(rc)) 231 { 232 rc = RTCritSectInit(&mWaitEventCritSect); 233 AssertRC(rc); 234 } 235 } 236 226 237 if (RT_SUCCESS(rc)) 227 238 rc = i_determineProtocolVersion(); 239 228 240 if (RT_SUCCESS(rc)) 229 241 { … … 298 310 itDirs != mData.mDirectories.end(); ++itDirs) 299 311 { 300 Assert(mData.mNumObjects);301 mData.mNumObjects--;302 312 itDirs->second->i_onRemove(); 303 313 itDirs->second->uninit(); … … 310 320 itFiles != mData.mFiles.end(); ++itFiles) 311 321 { 312 Assert(mData.mNumObjects);313 mData.mNumObjects--;314 322 itFiles->second->i_onRemove(); 315 323 itFiles->second->uninit(); … … 322 330 itProcs != mData.mProcesses.end(); ++itProcs) 323 331 { 324 Assert(mData.mNumObjects);325 mData.mNumObjects--;326 332 itProcs->second->i_onRemove(); 327 333 itProcs->second->uninit(); … … 329 335 mData.mProcesses.clear(); 330 336 337 /* Unregister the session's object ID. */ 338 i_objectUnregister(mData.mObjectID); 339 340 mData.mObjects.clear(); 341 mData.mObjectsFree.clear(); 342 331 343 mData.mEnvironmentChanges.reset(); 332 344 … … 336 348 mData.mpBaseEnvironment = NULL; 337 349 } 338 339 AssertMsg(mData.mNumObjects == 0,340 ("mNumObjects=%RU32 when it should be 0\n", mData.mNumObjects));341 350 342 351 /* Unitialize our local listener. */ … … 698 707 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 699 708 700 vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 701 eventTypes, &pEvent); 709 vrc = registerWaitEventEx(mData.mSession.mID, mData.mObjectID, eventTypes, &pEvent); 702 710 } 703 711 catch (std::bad_alloc) … … 815 823 } 816 824 817 int GuestSession::i_directoryRemoveFromList(GuestDirectory *pDirectory) 825 /** 826 * Unregisters a directory object from a session. 827 * 828 * @return VBox status code. VERR_NOT_FOUND if the directory is not registered (anymore). 829 * @param pDirectory Directory object to unregister from session. 830 */ 831 int GuestSession::i_directoryUnregister(GuestDirectory *pDirectory) 818 832 { 819 833 AssertPtrReturn(pDirectory, VERR_INVALID_POINTER); 820 834 835 LogFlowThisFunc(("pDirectory=%p\n", pDirectory)); 836 821 837 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 822 838 823 int rc = VERR_NOT_FOUND; 824 825 SessionDirectories::iterator itDirs = mData.mDirectories.begin(); 826 while (itDirs != mData.mDirectories.end()) 827 { 828 if (pDirectory == itDirs->second) 829 { 830 /* Make sure to consume the pointer before the one of the 831 * iterator gets released. */ 832 ComObjPtr<GuestDirectory> pDir = pDirectory; 833 834 Bstr strName; 835 HRESULT hr = itDirs->second->COMGETTER(DirectoryName)(strName.asOutParam()); 836 ComAssertComRC(hr); 837 838 Assert(mData.mDirectories.size()); 839 Assert(mData.mNumObjects); 840 LogFlowFunc(("Removing directory \"%s\" (Session: %RU32) (now total %zu processes, %RU32 objects)\n", 841 Utf8Str(strName).c_str(), mData.mSession.mID, mData.mDirectories.size() - 1, mData.mNumObjects - 1)); 842 843 rc = pDirectory->i_onRemove(); 844 mData.mDirectories.erase(itDirs); 845 mData.mNumObjects--; 846 847 pDir.setNull(); 848 break; 849 } 850 851 ++itDirs; 852 } 839 const uint32_t uObjectID = pDirectory->getObjectID(); 840 841 LogFlowFunc(("Removing directory (objectID=%RU32) ...\n", uObjectID)); 842 843 int rc = i_objectUnregister(uObjectID); 844 if (RT_FAILURE(rc)) 845 return rc; 846 847 SessionDirectories::iterator itDirs = mData.mDirectories.find(uObjectID); 848 AssertReturn(itDirs != mData.mDirectories.end(), VERR_NOT_FOUND); 849 850 /* Make sure to consume the pointer before the one of the iterator gets released. */ 851 ComObjPtr<GuestDirectory> pDirConsumed = pDirectory; 852 853 LogFlowFunc(("Removing directory ID=%RU32 (session %RU32, now total %zu directories)\n", 854 uObjectID, mData.mSession.mID, mData.mDirectories.size())); 855 856 rc = pDirConsumed->i_onRemove(); 857 AssertRCReturn(rc, rc); 858 859 mData.mDirectories.erase(itDirs); 860 861 alock.release(); /* Release lock before firing off event. */ 862 863 // fireGuestDirectoryRegisteredEvent(mEventSource, this /* Session */, pDirConsumed, false /* Process unregistered */); 864 865 pDirConsumed.setNull(); 853 866 854 867 LogFlowFuncLeaveRC(rc); … … 866 879 867 880 GuestWaitEvent *pEvent = NULL; 868 int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 869 &pEvent); 881 int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent); 870 882 if (RT_FAILURE(vrc)) 871 883 return vrc; … … 896 908 } 897 909 898 int GuestSession::i_ objectCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath,899 bool fDirectory, Utf8Str &strName,int *prcGuest)910 int GuestSession::i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory, Utf8Str &strName, 911 int *prcGuest) 900 912 { 901 913 AssertPtrReturn(prcGuest, VERR_INVALID_POINTER); … … 931 943 int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS; 932 944 GuestCtrlStreamObjects stdOut; 933 int vrc = GuestProcessTool::runEx(this, procInfo, 934 &stdOut, 1 /* cStrmOutObjects */, 935 &vrcGuest); 945 int vrc = GuestProcessTool::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest); 936 946 if (!GuestProcess::i_isGuestError(vrc)) 937 947 { … … 971 981 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 972 982 973 int rc = VERR_GSTCTL_MAX_OBJECTS_REACHED; 974 if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS) 975 return rc; 976 977 /* Create a new (host-based) directory ID and assign it. */ 978 uint32_t uNewDirID = 0; 979 ULONG uTries = 0; 980 981 for (;;) 982 { 983 /* Is the directory ID already used? */ 984 if (!i_directoryExists(uNewDirID, NULL /* pDirectory */)) 985 { 986 /* Callback with context ID was not found. This means 987 * we can use this context ID for our new callback we want 988 * to add below. */ 989 rc = VINF_SUCCESS; 990 break; 991 } 992 uNewDirID++; 993 if (uNewDirID == VBOX_GUESTCTRL_MAX_OBJECTS) 994 uNewDirID = 0; 995 996 if (++uTries == UINT32_MAX) 997 break; /* Don't try too hard. */ 998 } 999 983 /* Register a new object ID. */ 984 uint32_t uObjectID; 985 int rc = i_objectRegister(SESSIONOBJECTTYPE_DIRECTORY, &uObjectID); 1000 986 if (RT_FAILURE(rc)) 1001 987 return rc; … … 1009 995 AssertPtr(pConsole); 1010 996 1011 int vrc = pDirectory->init(pConsole, this /* Parent */, 1012 uNewDirID, openInfo); 997 int vrc = pDirectory->init(pConsole, this /* Parent */, uObjectID, openInfo); 1013 998 if (RT_FAILURE(vrc)) 1014 999 return vrc; … … 1024 1009 { 1025 1010 /* Add the created directory to our map. */ 1026 mData.mDirectories[uNewDirID] = pDirectory; 1027 mData.mNumObjects++; 1028 Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS); 1029 1030 LogFlowFunc(("Added new guest directory \"%s\" (Session: %RU32) (now total %zu dirs, %RU32 objects)\n", 1031 openInfo.mPath.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects)); 1011 mData.mDirectories[uObjectID] = pDirectory; 1012 1013 LogFlowFunc(("Added new guest directory \"%s\" (Session: %RU32) (now total %zu directories)\n", 1014 openInfo.mPath.c_str(), mData.mSession.mID, mData.mDirectories.size())); 1032 1015 1033 1016 alock.release(); /* Release lock before firing off event. */ … … 1051 1034 } 1052 1035 1053 int GuestSession::i_dispatchToDirectory(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 1036 /** 1037 * Dispatches a host callback to its corresponding object. 1038 * 1039 * @return VBox status code. VERR_NOT_FOUND if no corresponding object was found. 1040 * @param pCtxCb Host callback context. 1041 * @param pSvcCb Service callback data. 1042 */ 1043 int GuestSession::i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 1054 1044 { 1055 1045 LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb)); … … 1058 1048 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 1059 1049 1060 if (pSvcCb->mParms < 3)1061 return VERR_INVALID_PARAMETER;1062 1063 1050 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1064 1051 1065 uint32_t uDirID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID); 1066 #ifdef DEBUG 1067 LogFlowFunc(("uDirID=%RU32 (%zu total)\n", 1068 uDirID, mData.mFiles.size())); 1069 #endif 1070 int rc; 1071 SessionDirectories::const_iterator itDir 1072 = mData.mDirectories.find(uDirID); 1073 if (itDir != mData.mDirectories.end()) 1074 { 1075 ComObjPtr<GuestDirectory> pDirectory(itDir->second); 1076 Assert(!pDirectory.isNull()); 1077 1078 alock.release(); 1079 1080 rc = pDirectory->i_callbackDispatcher(pCtxCb, pSvcCb); 1081 } 1082 else 1083 rc = VERR_NOT_FOUND; 1084 1085 LogFlowFuncLeaveRC(rc); 1086 return rc; 1087 } 1088 1089 int GuestSession::i_dispatchToFile(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 1090 { 1091 LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb)); 1092 1093 AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER); 1094 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 1095 1096 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1097 1098 uint32_t uFileID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID); 1099 #ifdef DEBUG 1100 LogFlowFunc(("uFileID=%RU32 (%zu total)\n", 1101 uFileID, mData.mFiles.size())); 1102 #endif 1103 int rc; 1104 SessionFiles::const_iterator itFile 1105 = mData.mFiles.find(uFileID); 1106 if (itFile != mData.mFiles.end()) 1107 { 1108 ComObjPtr<GuestFile> pFile(itFile->second); 1109 Assert(!pFile.isNull()); 1110 1111 alock.release(); 1112 1113 rc = pFile->i_callbackDispatcher(pCtxCb, pSvcCb); 1114 } 1115 else 1116 rc = VERR_NOT_FOUND; 1117 1118 LogFlowFuncLeaveRC(rc); 1119 return rc; 1120 } 1121 1122 int GuestSession::i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 1123 { 1124 LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb)); 1125 1126 AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER); 1127 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); 1128 1129 int rc; 1130 uint32_t uObjectID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID); 1131 1132 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1133 1134 /* Since we don't know which type the object is, we need to through all 1135 * all objects. */ 1136 /** @todo Speed this up by adding an object type to the callback context! */ 1137 SessionProcesses::const_iterator itProc = mData.mProcesses.find(uObjectID); 1138 if (itProc == mData.mProcesses.end()) 1139 { 1140 SessionFiles::const_iterator itFile = mData.mFiles.find(uObjectID); 1141 if (itFile != mData.mFiles.end()) 1052 const uint32_t uObjectID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID); 1053 1054 int rc = VERR_NOT_FOUND; 1055 1056 SessionObjects::const_iterator itObjs = mData.mObjects.find(uObjectID); 1057 1058 if (itObjs == mData.mObjects.end()) 1059 return rc; 1060 1061 /* Set protocol version so that pSvcCb can be interpreted right. */ 1062 pCtxCb->uProtocol = mData.mProtocolVersion; 1063 1064 switch (itObjs->second.enmType) 1065 { 1066 case SESSIONOBJECTTYPE_ANONYMOUS: 1067 rc = VERR_NOT_SUPPORTED; 1068 break; 1069 1070 case SESSIONOBJECTTYPE_SESSION: 1142 1071 { 1143 1072 alock.release(); 1144 1073 1145 rc = i_dispatchToFile(pCtxCb, pSvcCb); 1146 } 1147 else 1074 rc = i_dispatchToThis(pCtxCb, pSvcCb); 1075 break; 1076 } 1077 case SESSIONOBJECTTYPE_DIRECTORY: 1148 1078 { 1149 1079 SessionDirectories::const_iterator itDir = mData.mDirectories.find(uObjectID); 1150 1080 if (itDir != mData.mDirectories.end()) 1151 1081 { 1082 ComObjPtr<GuestDirectory> pDirectory(itDir->second); 1083 Assert(!pDirectory.isNull()); 1084 1152 1085 alock.release(); 1153 1086 1154 rc = i_dispatchToDirectory(pCtxCb, pSvcCb);1087 rc = pDirectory->i_callbackDispatcher(pCtxCb, pSvcCb); 1155 1088 } 1156 else 1157 rc = VERR_NOT_FOUND; 1158 } 1159 } 1160 else 1161 { 1162 alock.release(); 1163 1164 rc = i_dispatchToProcess(pCtxCb, pSvcCb); 1089 break; 1090 } 1091 case SESSIONOBJECTTYPE_FILE: 1092 { 1093 SessionFiles::const_iterator itFile = mData.mFiles.find(uObjectID); 1094 if (itFile != mData.mFiles.end()) 1095 { 1096 ComObjPtr<GuestFile> pFile(itFile->second); 1097 Assert(!pFile.isNull()); 1098 1099 alock.release(); 1100 1101 rc = pFile->i_callbackDispatcher(pCtxCb, pSvcCb); 1102 } 1103 break; 1104 } 1105 case SESSIONOBJECTTYPE_PROCESS: 1106 { 1107 SessionProcesses::const_iterator itProc = mData.mProcesses.find(uObjectID); 1108 if (itProc != mData.mProcesses.end()) 1109 { 1110 ComObjPtr<GuestProcess> pProcess(itProc->second); 1111 Assert(!pProcess.isNull()); 1112 1113 alock.release(); 1114 1115 rc = pProcess->i_callbackDispatcher(pCtxCb, pSvcCb); 1116 } 1117 break; 1118 } 1119 default: 1120 AssertFailed(); 1121 break; 1165 1122 } 1166 1123 … … 1169 1126 } 1170 1127 1171 int GuestSession::i_dispatchToProcess(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)1172 {1173 LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));1174 1175 AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);1176 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);1177 1178 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);1179 1180 uint32_t uProcessID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);1181 #ifdef DEBUG1182 LogFlowFunc(("uProcessID=%RU32 (%zu total)\n",1183 uProcessID, mData.mProcesses.size()));1184 #endif1185 int rc;1186 SessionProcesses::const_iterator itProc1187 = mData.mProcesses.find(uProcessID);1188 if (itProc != mData.mProcesses.end())1189 {1190 #ifdef DEBUG_andy1191 ULONG cRefs = itProc->second->AddRef();1192 Assert(cRefs >= 2);1193 LogFlowFunc(("pProcess=%p, cRefs=%RU32\n", &itProc->second, cRefs - 1));1194 itProc->second->Release();1195 #endif1196 ComObjPtr<GuestProcess> pProcess(itProc->second);1197 Assert(!pProcess.isNull());1198 1199 /* Set protocol version so that pSvcCb can1200 * be interpreted right. */1201 pCtxCb->uProtocol = mData.mProtocolVersion;1202 1203 alock.release();1204 rc = pProcess->i_callbackDispatcher(pCtxCb, pSvcCb);1205 }1206 else1207 rc = VERR_NOT_FOUND;1208 1209 LogFlowFuncLeaveRC(rc);1210 return rc;1211 }1212 1213 1128 int GuestSession::i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) 1214 1129 { … … 1218 1133 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1219 1134 1220 #ifdef DEBUG1221 1135 LogFlowThisFunc(("sessionID=%RU32, CID=%RU32, uFunction=%RU32, pSvcCb=%p\n", 1222 1136 mData.mSession.mID, pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb)); 1223 #endif1224 1225 1137 int rc; 1226 1138 switch (pCbCtx->uFunction) … … 1238 1150 1239 1151 default: 1240 /* Silently skip unknown callbacks. */ 1241 rc = VERR_NOT_SUPPORTED; 1152 rc = dispatchGeneric(pCbCtx, pSvcCb); 1242 1153 break; 1243 1154 } … … 1259 1170 } 1260 1171 1261 int GuestSession::i_fileRemoveFromList(GuestFile *pFile) 1262 { 1172 /** 1173 * Unregisters a file object from a session. 1174 * 1175 * @return VBox status code. VERR_NOT_FOUND if the file is not registered (anymore). 1176 * @param pFile File object to unregister from session. 1177 */ 1178 int GuestSession::i_fileUnregister(GuestFile *pFile) 1179 { 1180 AssertPtrReturn(pFile, VERR_INVALID_POINTER); 1181 1182 LogFlowThisFunc(("pFile=%p\n", pFile)); 1183 1263 1184 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1264 1185 1265 int rc = VERR_NOT_FOUND; 1266 1267 SessionFiles::iterator itFiles = mData.mFiles.begin(); 1268 while (itFiles != mData.mFiles.end()) 1269 { 1270 if (pFile == itFiles->second) 1271 { 1272 /* Make sure to consume the pointer before the one of thfe 1273 * iterator gets released. */ 1274 ComObjPtr<GuestFile> pCurFile = pFile; 1275 1276 Bstr strName; 1277 HRESULT hr = pCurFile->COMGETTER(FileName)(strName.asOutParam()); 1278 ComAssertComRC(hr); 1279 1280 Assert(mData.mNumObjects); 1281 LogFlowThisFunc(("Removing guest file \"%s\" (Session: %RU32) (now total %zu files, %RU32 objects)\n", 1282 Utf8Str(strName).c_str(), mData.mSession.mID, mData.mFiles.size() - 1, mData.mNumObjects - 1)); 1283 1284 rc = pFile->i_onRemove(); 1285 mData.mFiles.erase(itFiles); 1286 mData.mNumObjects--; 1287 1288 alock.release(); /* Release lock before firing off event. */ 1289 1290 fireGuestFileRegisteredEvent(mEventSource, this, pCurFile, 1291 false /* Unregistered */); 1292 pCurFile.setNull(); 1293 break; 1294 } 1295 1296 ++itFiles; 1297 } 1186 const uint32_t uObjectID = pFile->getObjectID(); 1187 1188 LogFlowFunc(("Removing file (objectID=%RU32) ...\n", uObjectID)); 1189 1190 int rc = i_objectUnregister(uObjectID); 1191 if (RT_FAILURE(rc)) 1192 return rc; 1193 1194 SessionFiles::iterator itFiles = mData.mFiles.find(uObjectID); 1195 AssertReturn(itFiles != mData.mFiles.end(), VERR_NOT_FOUND); 1196 1197 /* Make sure to consume the pointer before the one of the iterator gets released. */ 1198 ComObjPtr<GuestFile> pFileConsumed = pFile; 1199 1200 LogFlowFunc(("Removing file ID=%RU32 (session %RU32, now total %zu files)\n", 1201 pFileConsumed->getObjectID(), mData.mSession.mID, mData.mFiles.size())); 1202 1203 rc = pFileConsumed->i_onRemove(); 1204 AssertRCReturn(rc, rc); 1205 1206 mData.mFiles.erase(itFiles); 1207 1208 alock.release(); /* Release lock before firing off event. */ 1209 1210 fireGuestFileRegisteredEvent(mEventSource, this, pFileConsumed, false /* Unregistered */); 1211 1212 pFileConsumed.setNull(); 1298 1213 1299 1214 LogFlowFuncLeaveRC(rc); … … 1341 1256 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1342 1257 1343 /* Guest Additions < 4.3 don't support handling 1344 guest files, skip. */ 1258 /* Guest Additions < 4.3 don't support handling guest files, skip. */ 1345 1259 if (mData.mProtocolVersion < 2) 1346 1260 { 1347 LogFlowThisFunc(("Installed Guest Additions don't support handling guest files, skipping\n")); 1348 return VERR_NOT_SUPPORTED; 1349 } 1350 1351 int rc = VERR_GSTCTL_MAX_OBJECTS_REACHED; 1352 if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS) 1353 return rc; 1354 1355 /* Create a new (host-based) file ID and assign it. */ 1356 uint32_t uNewFileID = 0; 1357 ULONG uTries = 0; 1358 1359 for (;;) 1360 { 1361 /* Is the file ID already used? */ 1362 if (!i_fileExists(uNewFileID, NULL /* pFile */)) 1363 { 1364 /* Callback with context ID was not found. This means 1365 * we can use this context ID for our new callback we want 1366 * to add below. */ 1367 rc = VINF_SUCCESS; 1368 break; 1369 } 1370 uNewFileID++; 1371 if (uNewFileID == VBOX_GUESTCTRL_MAX_OBJECTS) 1372 uNewFileID = 0; 1373 1374 if (++uTries == UINT32_MAX) 1375 break; /* Don't try too hard. */ 1376 } 1377 1261 if (prcGuest) 1262 *prcGuest = VERR_NOT_SUPPORTED; 1263 return VERR_GSTCTL_GUEST_ERROR; 1264 } 1265 1266 /* Register a new object ID. */ 1267 uint32_t uObjectID; 1268 int rc = i_objectRegister(SESSIONOBJECTTYPE_FILE, &uObjectID); 1378 1269 if (RT_FAILURE(rc)) 1379 1270 return rc; … … 1387 1278 AssertPtr(pConsole); 1388 1279 1389 rc = pFile->init(pConsole, this /* GuestSession */, 1390 uNewFileID, openInfo); 1280 rc = pFile->init(pConsole, this /* GuestSession */, uObjectID, openInfo); 1391 1281 if (RT_FAILURE(rc)) 1392 1282 return rc; … … 1402 1292 { 1403 1293 /* Add the created file to our vector. */ 1404 mData.mFiles[uNewFileID] = pFile; 1405 mData.mNumObjects++; 1406 Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS); 1407 1408 LogFlowFunc(("Added new guest file \"%s\" (Session: %RU32) (now total %zu files, %RU32 objects)\n", 1409 openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects)); 1294 mData.mFiles[uObjectID] = pFile; 1295 1296 LogFlowFunc(("Added new guest file \"%s\" (Session: %RU32) (now total %zu files)\n", 1297 openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size())); 1410 1298 1411 1299 alock.release(); /* Release lock before firing off event. */ 1412 1300 1413 fireGuestFileRegisteredEvent(mEventSource, this, pFile, 1414 true /* Registered */); 1301 fireGuestFileRegisteredEvent(mEventSource, this, pFile, true /* Registered */); 1415 1302 } 1416 1303 catch (std::bad_alloc &) … … 1756 1643 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 1757 1644 1758 vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 1759 eventTypes, &pEvent); 1645 vrc = registerWaitEventEx(mData.mSession.mID, mData.mObjectID, eventTypes, &pEvent); 1760 1646 } 1761 1647 catch (std::bad_alloc) … … 1869 1755 } 1870 1756 1757 /** 1758 * Registers an object to a session. 1759 * 1760 * @return VBox status code. 1761 * @param enmType Session object type to register. 1762 * @param puObjectID Returns registered object ID on success. Optional. 1763 */ 1764 int GuestSession::i_objectRegister(SESSIONOBJECTTYPE enmType, uint32_t *puObjectID) 1765 { 1766 return i_objectRegisterEx(enmType, 0 /* fFlags */, puObjectID); 1767 } 1768 1769 /** 1770 * Registers an object to a session, extended version. 1771 * 1772 * @return VBox status code. VERR_GSTCTL_MAX_OBJECTS_REACHED if the maximum of concurrent objects is reached. 1773 * @param enmType Session object type to register. 1774 * @param fFlags Registration flags. Not used yet and must be 0. 1775 * @param puObjectID Returns registered object ID on success. Optional. 1776 */ 1777 int GuestSession::i_objectRegisterEx(SESSIONOBJECTTYPE enmType, uint32_t fFlags, uint32_t *puObjectID) 1778 { 1779 RT_NOREF(fFlags); 1780 AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); 1781 1782 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1783 1784 int rc = VINF_SUCCESS; 1785 1786 uint32_t uObjectID; 1787 1788 if (mData.mObjects.size() < VBOX_GUESTCTRL_MAX_OBJECTS - 1 /* Minus 1 for the session itself */) 1789 { 1790 SessionObjects::reverse_iterator itRend = mData.mObjects.rbegin(); 1791 if (itRend != mData.mObjects.rend()) 1792 uObjectID = itRend->first + 1; /* Last key plus 1. */ 1793 else 1794 uObjectID = 0; 1795 } 1796 else 1797 { 1798 /* Utilize our "free list" to get the next free object ID in the map. */ 1799 if (mData.mObjectsFree.size()) 1800 { 1801 /* Always re-use the oldest object ID to avoid trouble. */ 1802 uObjectID = mData.mObjectsFree.front(); 1803 mData.mObjectsFree.pop_front(); 1804 } 1805 else 1806 rc = VERR_GSTCTL_MAX_OBJECTS_REACHED; 1807 } 1808 1809 Log2Func(("enmType=%RU32, fFlags=%RU32 -> uObjectID=%RU32 (%zu objects, %zu on free list), rc=%Rrc\n", 1810 enmType, fFlags, uObjectID, mData.mObjects.size(), mData.mObjectsFree.size(), rc)); 1811 1812 if (RT_SUCCESS(rc)) 1813 { 1814 mData.mObjects[uObjectID].enmType = enmType; 1815 mData.mObjects[uObjectID].tsCreatedMs = RTTimeMilliTS(); 1816 1817 if (puObjectID) 1818 *puObjectID = uObjectID; 1819 } 1820 1821 return rc; 1822 } 1823 1824 /** 1825 * Unregisters a formerly registered object from a session. 1826 * 1827 * @return VBox status code. VERR_NOT_FOUND if object to unregister was not found. 1828 * @param uObjectID Object ID to unregister. 1829 */ 1830 int GuestSession::i_objectUnregister(uint32_t uObjectID) 1831 { 1832 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1833 1834 SessionObjects::const_iterator itObj = mData.mObjects.find(uObjectID); 1835 if (itObj != mData.mObjects.end()) 1836 { 1837 Log2Func(("uObjectID=%RU32 (now %zu objects in free list)\n", uObjectID, mData.mObjectsFree.size())); 1838 1839 /* Note: Do not remove object from object list (mData.mObjects) here, as we continue operating 1840 * on the free list (mData.mObjectsFree) if we reached the object list's maximum. */ 1841 1842 mData.mObjectsFree.push_back(uObjectID); 1843 Assert(mData.mObjectsFree.size() <= VBOX_GUESTCTRL_MAX_OBJECTS); 1844 return VINF_SUCCESS; 1845 } 1846 1847 AssertFailed(); 1848 return VERR_NOT_FOUND; 1849 } 1850 1871 1851 int GuestSession::i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *prcGuest) 1872 1852 { … … 1879 1859 1880 1860 GuestWaitEvent *pEvent = NULL; 1881 int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 1882 &pEvent); 1861 int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent); 1883 1862 if (RT_FAILURE(vrc)) 1884 1863 return vrc; … … 1926 1905 1927 1906 GuestWaitEvent *pEvent = NULL; 1928 int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, &pEvent);1907 int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent); 1929 1908 if (RT_FAILURE(vrc)) 1930 1909 return vrc; … … 1976 1955 1977 1956 GuestWaitEvent *pEvent = NULL; 1978 int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, &pEvent);1957 int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent); 1979 1958 if (RT_FAILURE(vrc)) 1980 1959 return vrc; … … 2011 1990 } 2012 1991 2013 int GuestSession::i_processRemoveFromList(GuestProcess *pProcess) 1992 /** 1993 * Unregisters a process object from a session. 1994 * 1995 * @return VBox status code. VERR_NOT_FOUND if the process is not registered (anymore). 1996 * @param pProcess Process object to unregister from session. 1997 */ 1998 int GuestSession::i_processUnregister(GuestProcess *pProcess) 2014 1999 { 2015 2000 AssertPtrReturn(pProcess, VERR_INVALID_POINTER); … … 2019 2004 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2020 2005 2021 int rc = VERR_NOT_FOUND; 2022 2023 ULONG uPID; 2024 HRESULT hr = pProcess->COMGETTER(PID)(&uPID); 2006 const uint32_t uObjectID = pProcess->getObjectID(); 2007 2008 LogFlowFunc(("Removing process (objectID=%RU32) ...\n", uObjectID)); 2009 2010 int rc = i_objectUnregister(uObjectID); 2011 if (RT_FAILURE(rc)) 2012 return rc; 2013 2014 SessionProcesses::iterator itProcs = mData.mProcesses.find(uObjectID); 2015 AssertReturn(itProcs != mData.mProcesses.end(), VERR_NOT_FOUND); 2016 2017 /* Make sure to consume the pointer before the one of the iterator gets released. */ 2018 ComObjPtr<GuestProcess> pProc = pProcess; 2019 2020 uint32_t uPID; 2021 HRESULT hr = pProc->COMGETTER(PID)(&uPID); 2025 2022 ComAssertComRC(hr); 2026 2023 2027 LogFlowFunc(("Removing process (PID=%RU32) ...\n", uPID)); 2028 2029 SessionProcesses::iterator itProcs = mData.mProcesses.begin(); 2030 while (itProcs != mData.mProcesses.end()) 2031 { 2032 if (pProcess == itProcs->second) 2033 { 2034 #ifdef DEBUG_andy 2035 ULONG cRefs = pProcess->AddRef(); 2036 Assert(cRefs >= 2); 2037 LogFlowFunc(("pProcess=%p, cRefs=%RU32\n", pProcess, cRefs - 1)); 2038 pProcess->Release(); 2039 #endif 2040 /* Make sure to consume the pointer before the one of the 2041 * iterator gets released. */ 2042 ComObjPtr<GuestProcess> pProc = pProcess; 2043 2044 hr = pProc->COMGETTER(PID)(&uPID); 2045 ComAssertComRC(hr); 2046 2047 Assert(mData.mProcesses.size()); 2048 Assert(mData.mNumObjects); 2049 LogFlowFunc(("Removing process ID=%RU32 (Session: %RU32), guest PID=%RU32 (now total %zu processes, %RU32 objects)\n", 2050 pProcess->getObjectID(), mData.mSession.mID, uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1)); 2051 2052 rc = pProcess->i_onRemove(); 2053 mData.mProcesses.erase(itProcs); 2054 mData.mNumObjects--; 2055 2056 alock.release(); /* Release lock before firing off event. */ 2057 2058 fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProc, 2059 uPID, false /* Process unregistered */); 2060 pProc.setNull(); 2061 break; 2062 } 2063 2064 ++itProcs; 2065 } 2024 LogFlowFunc(("Removing process ID=%RU32 (session %RU32, guest PID %RU32, now total %zu processes)\n", 2025 uObjectID, mData.mSession.mID, uPID, mData.mProcesses.size())); 2026 2027 rc = pProcess->i_onRemove(); 2028 AssertRCReturn(rc, rc); 2029 2030 mData.mProcesses.erase(itProcs); 2031 2032 alock.release(); /* Release lock before firing off event. */ 2033 2034 fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProc, uPID, false /* Process unregistered */); 2035 2036 pProc.setNull(); 2066 2037 2067 2038 LogFlowFuncLeaveRC(rc); … … 2129 2100 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2130 2101 2131 int rc = VERR_GSTCTL_MAX_OBJECTS_REACHED; 2132 if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS) 2133 return rc; 2134 2135 /* Create a new (host-based) process ID and assign it. */ 2136 uint32_t uNewProcessID = 0; 2137 ULONG uTries = 0; 2138 2139 for (;;) 2140 { 2141 /* Is the context ID already used? */ 2142 if (!i_processExists(uNewProcessID, NULL /* pProcess */)) 2143 { 2144 /* Callback with context ID was not found. This means 2145 * we can use this context ID for our new callback we want 2146 * to add below. */ 2147 rc = VINF_SUCCESS; 2148 break; 2149 } 2150 uNewProcessID++; 2151 if (uNewProcessID == VBOX_GUESTCTRL_MAX_OBJECTS) 2152 uNewProcessID = 0; 2153 2154 if (++uTries == VBOX_GUESTCTRL_MAX_OBJECTS) 2155 break; /* Don't try too hard. */ 2156 } 2157 2102 /* Register a new object ID. */ 2103 uint32_t uObjectID; 2104 int rc = i_objectRegister(SESSIONOBJECTTYPE_PROCESS, &uObjectID); 2158 2105 if (RT_FAILURE(rc)) 2159 2106 return rc; … … 2164 2111 return VERR_COM_UNEXPECTED; 2165 2112 2166 rc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */, 2167 uNewProcessID,procInfo, mData.mpBaseEnvironment);2113 rc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */, uObjectID, 2114 procInfo, mData.mpBaseEnvironment); 2168 2115 if (RT_FAILURE(rc)) 2169 2116 return rc; … … 2172 2119 try 2173 2120 { 2174 mData.mProcesses[uNewProcessID] = pProcess; 2175 mData.mNumObjects++; 2176 Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS); 2177 2178 LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %zu processes, %RU32 objects)\n", 2179 mData.mSession.mID, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects)); 2121 mData.mProcesses[uObjectID] = pProcess; 2122 2123 LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %zu processes)\n", 2124 mData.mSession.mID, uObjectID, mData.mProcesses.size())); 2180 2125 2181 2126 alock.release(); /* Release lock before firing off event. */ 2182 2127 2183 fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProcess, 2184 0 /* PID */, true /* Process registered */); 2128 fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProcess, 0 /* PID */, true /* Process registered */); 2185 2129 } 2186 2130 catch (std::bad_alloc &) … … 2474 2418 eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged); 2475 2419 2476 vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, 2477 eventTypes, &pEvent); 2420 vrc = registerWaitEventEx(mData.mSession.mID, mData.mObjectID, eventTypes, &pEvent); 2478 2421 } 2479 2422 catch (std::bad_alloc) … … 2999 2942 3000 2943 int rcGuest; 3001 int rc = i_ objectCreateTemp(aTemplateName, aPath, true /* Directory */, aDirectory, &rcGuest);2944 int rc = i_fsCreateTemp(aTemplateName, aPath, true /* Directory */, aDirectory, &rcGuest); 3002 2945 if (!RT_SUCCESS(rc)) 3003 2946 {
Note:
See TracChangeset
for help on using the changeset viewer.