- Timestamp:
- Aug 8, 2012 8:07:09 AM (12 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r42657 r42673 9329 9329 <enum 9330 9330 name="DirectoryOpenFlag" 9331 uuid=" fc8f6203-0072-4f34-bd08-0b35e50bf071"9331 uuid="5138837a-8fd2-4194-a1b0-08f7bc3949d0" 9332 9332 > 9333 9333 <desc> … … 9336 9336 <const name="None" value="0"> 9337 9337 <desc>No flag set.</desc> 9338 </const> 9339 <const name="NoSymlinks" value="1"> 9340 <desc>Don't allow symbolic links as part of the path.</desc> 9338 9341 </const> 9339 9342 </enum> … … 9381 9384 <interface 9382 9385 name="IGuestSession" extends="$unknown" 9383 uuid=" 9233c0b5-8f0d-48b2-9b90-b730880f1e35"9386 uuid="45aca317-55d7-4b6c-bbec-d053289118b9" 9384 9387 wsmap="managed" 9385 9388 > … … 9582 9585 <desc>TODO</desc> 9583 9586 </param> 9584 <param name="flags" type=" wstring" dir="in">9587 <param name="flags" type="DirectoryOpenFlag" dir="in" safearray="yes"> 9585 9588 <desc>TODO</desc> 9586 9589 </param> … … 10233 10236 <interface 10234 10237 name="IDirectory" extends="$unknown" 10235 uuid=" e55ab5e5-4feb-452b-86ed-59cff4c581a3"10238 uuid="1b70dd03-26d7-483a-8877-89bbb0f87b70" 10236 10239 wsmap="managed" 10237 10240 > … … 10249 10252 </attribute> 10250 10253 10251 <method name="read"> 10254 <attribute name="filter" type="wstring" readonly="yes"> 10255 <desc> 10256 The open filter. 10257 <note> 10258 TODO 10259 </note> 10260 </desc> 10261 </attribute> 10262 10263 <method name="close"> 10252 10264 <desc> 10253 10265 TODO … … 10255 10267 <result name="VBOX_E_NOT_SUPPORTED"> 10256 10268 TODO 10269 </result> 10270 </desc> 10271 </method> 10272 10273 <method name="read"> 10274 <desc> 10275 TODO 10276 10277 <result name="VBOX_E_OBJECT_NOT_FOUND"> 10278 End of directory listing reached. 10257 10279 </result> 10258 10280 </desc> … … 10472 10494 <interface 10473 10495 name="IFsObjInfo" extends="$unknown" 10474 uuid="4 925335b-9aa6-4870-bda3-8edb09fb602c"10496 uuid="4047ba30-7006-4966-ae86-94164e5e20eb" 10475 10497 wsmap="managed" 10476 10498 > … … 10519 10541 </desc> 10520 10542 </attribute> 10521 <attribute name="fileAtt tributes" type="wstring" readonly="yes">10543 <attribute name="fileAttributes" type="wstring" readonly="yes"> 10522 10544 <desc> 10523 10545 TODO -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42643 r42673 275 275 { 276 276 /** Helper function to extract the data from 277 * a guest stream block. */ 278 int From(const GuestProcessStreamBlock &strmBlk); 277 * a certin VBoxService tool's guest stream block. */ 278 int FromLs(const GuestProcessStreamBlock &strmBlk); 279 int FromStat(const GuestProcessStreamBlock &strmBlk); 279 280 280 281 int64_t mAccessTime; … … 365 366 public: 366 367 367 void Clear( );368 void Clear(void); 368 369 369 370 #ifdef DEBUG 370 void Dump ();371 void DumpToLog(void) const; 371 372 #endif 372 373 … … 382 383 383 384 uint32_t GetUInt32(const char *pszKey) const; 385 386 bool IsEmpty(void) { return m_mapPairs.empty(); } 384 387 385 388 int SetValue(const char *pszKey, const char *pszValue); -
trunk/src/VBox/Main/include/GuestDirectoryImpl.h
r42525 r42673 21 21 22 22 #include "VirtualBoxBase.h" 23 #include "GuestCtrlImplPrivate.h" 23 24 25 class GuestProcess; 24 26 class GuestSession; 25 27 … … 43 45 DECLARE_EMPTY_CTOR_DTOR(GuestDirectory) 44 46 45 int init(GuestSession *aSession, const Utf8Str &strPath );47 int init(GuestSession *aSession, const Utf8Str &strPath, const Utf8Str &strFilter = "", uint32_t uFlags = 0); 46 48 void uninit(void); 47 49 HRESULT FinalConstruct(void); … … 52 54 * @{ */ 53 55 STDMETHOD(COMGETTER(DirectoryName))(BSTR *aName); 54 56 STDMETHOD(COMGETTER(Filter))(BSTR *aFilter); 57 STDMETHOD(Close)(void); 55 58 STDMETHOD(Read)(IFsObjInfo **aInfo); 56 59 /** @} */ … … 63 66 private: 64 67 68 /** @name Private internal methods. 69 * @{ */ 70 int parseData(GuestProcessStreamBlock &streamBlock); 71 /** @} */ 72 65 73 struct Data 66 74 { 67 GuestSession *mParent; 68 Utf8Str mName; 69 ComPtr<IGuestFsObjInfo> mFsObjInfo; 75 GuestSession *mParent; 76 Utf8Str mName; 77 Utf8Str mFilter; 78 uint32_t mFlags; 79 /** The stdout stream object which contains all 80 * read out data for parsing. Must be persisent 81 * between several read() calls. */ 82 GuestProcessStream mStream; 83 /** The guest process which is responsible for 84 * getting the stdout stream. */ 85 ComObjPtr<GuestProcess> mProcess; 70 86 } mData; 71 87 }; -
trunk/src/VBox/Main/include/GuestFsObjInfoImpl.h
r42530 r42673 42 42 DECLARE_EMPTY_CTOR_DTOR(GuestFsObjInfo) 43 43 44 HRESULT init(void);44 int init(const GuestFsObjData &objData); 45 45 void uninit(void); 46 46 HRESULT FinalConstruct(void); … … 55 55 STDMETHOD(COMGETTER(ChangeTime))(LONG64 *aChangeTime); 56 56 STDMETHOD(COMGETTER(DeviceNumber))(ULONG *aDeviceNumber); 57 STDMETHOD(COMGETTER(FileAttr s))(BSTR *aFileAttrs);58 STDMETHOD(COMGETTER(GenerationI D))(ULONG *aGenerationID);57 STDMETHOD(COMGETTER(FileAttributes))(BSTR *aFileAttrs); 58 STDMETHOD(COMGETTER(GenerationId))(ULONG *aGenerationId); 59 59 STDMETHOD(COMGETTER(GID))(ULONG *aGID); 60 60 STDMETHOD(COMGETTER(GroupName))(BSTR *aGroupName); … … 62 62 STDMETHOD(COMGETTER(ModificationTime))(LONG64 *aModificationTime); 63 63 STDMETHOD(COMGETTER(Name))(BSTR *aName); 64 STDMETHOD(COMGETTER(NodeI D))(LONG64 *aNodeID);65 STDMETHOD(COMGETTER(NodeI DDevice))(ULONG *aNodeIDDevice);66 STDMETHOD(COMGETTER(ObjectSize))( ULONG*aObjectSize);64 STDMETHOD(COMGETTER(NodeId))(LONG64 *aNodeId); 65 STDMETHOD(COMGETTER(NodeIdDevice))(ULONG *aNodeIdDevice); 66 STDMETHOD(COMGETTER(ObjectSize))(LONG64 *aObjectSize); 67 67 STDMETHOD(COMGETTER(Type))(FsObjType_T *aType); 68 68 STDMETHOD(COMGETTER(UID))(ULONG *aUID); -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r42634 r42673 74 74 int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData); 75 75 inline bool callbackExists(uint32_t uContextID); 76 inline int checkPID(uint32_t uPID); 76 77 void close(void); 77 78 bool isReady(void); … … 83 84 int terminateProcess(void); 84 85 int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult); 86 int waitForStart(uint32_t uTimeoutMS); 85 87 int writeData(uint32_t uHandle, uint32_t uFlags, void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten); 86 88 /** @} */ -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r42657 r42673 157 157 STDMETHOD(DirectoryCreateTemp)(IN_BSTR aTemplate, ULONG aMode, IN_BSTR aName, IGuestDirectory **aDirectory); 158 158 STDMETHOD(DirectoryExists)(IN_BSTR aPath, BOOL *aExists); 159 STDMETHOD(DirectoryOpen)(IN_BSTR aPath, IN_BSTR aFilter, IN_BSTR aFlags, IGuestDirectory **aDirectory);159 STDMETHOD(DirectoryOpen)(IN_BSTR aPath, IN_BSTR aFilter, ComSafeArrayIn(DirectoryOpenFlag_T, aFlags), IGuestDirectory **aDirectory); 160 160 STDMETHOD(DirectoryQueryInfo)(IN_BSTR aPath, IGuestFsObjInfo **aInfo); 161 161 STDMETHOD(DirectoryRemove)(IN_BSTR aPath); … … 205 205 int directoryClose(ComObjPtr<GuestDirectory> pDirectory); 206 206 int directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory); 207 int directoryOpenInternal(const Utf8Str &strPath, const Utf8Str &strFilter, uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory); 207 208 int dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData); 208 209 int fileClose(ComObjPtr<GuestFile> pFile); -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r42634 r42673 736 736 int rc = VINF_SUCCESS; 737 737 if (fDispatch) 738 { 738 739 rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms); 739 740 #ifdef VBOX_WITH_GUEST_CONTROL_LEGACY 741 if (RT_SUCCESS(rc)) 742 return rc; 740 if (RT_SUCCESS(rc)) 741 return rc; 742 } 743 744 #ifdef DEBUG 745 /* @todo Don't use legacy stuff in debug mode. Remove for final! */ 746 return rc; 747 #endif 743 748 744 749 /* Legacy handling. */ … … 794 799 break; 795 800 } 796 #endif /* VBOX_WITH_GUEST_CONTROL_LEGACY */797 801 798 802 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Main/src-client/GuestCtrlImplDir.cpp
r41222 r42673 593 593 { 594 594 #ifdef DEBUG 595 streamBlock.Dump ();595 streamBlock.DumpToLog(); 596 596 #endif 597 597 hr = VBOX_E_FILE_ERROR; -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42634 r42673 581 581 } 582 582 583 int GuestFsObjData::From(const GuestProcessStreamBlock &strmBlk) 584 { 583 int GuestFsObjData::FromLs(const GuestProcessStreamBlock &strmBlk) 584 { 585 LogFlowFuncEnter(("\n")); 586 585 587 int rc = VINF_SUCCESS; 586 588 587 589 try 588 590 { 591 #ifdef DEBUG 592 strmBlk.DumpToLog(); 593 #endif 594 /* Object name. */ 595 mName = strmBlk.GetString("name"); 596 if (mName.isEmpty()) throw VERR_NOT_FOUND; 597 /* Type. */ 589 598 Utf8Str strType(strmBlk.GetString("ftype")); 590 599 if (strType.equalsIgnoreCase("-")) … … 595 604 else 596 605 mType = FsObjType_Undefined; 597 606 /* Object size. */ 598 607 rc = strmBlk.GetInt64Ex("st_size", &mObjectSize); 599 608 if (RT_FAILURE(rc)) throw rc; 600 601 /** @todo Add complete GuestFsObjData info! */ 609 /** @todo Add complete ls info! */ 602 610 } 603 611 catch (int rc2) … … 606 614 } 607 615 616 LogFlowFuncLeaveRC(rc); 617 return rc; 618 } 619 620 int GuestFsObjData::FromStat(const GuestProcessStreamBlock &strmBlk) 621 { 622 LogFlowFuncEnter(("\n")); 623 624 int rc = VINF_SUCCESS; 625 626 try 627 { 628 #ifdef DEBUG 629 strmBlk.DumpToLog(); 630 #endif 631 /* Node ID. */ 632 rc = strmBlk.GetInt64Ex("node_id", &mNodeID); 633 if (RT_FAILURE(rc)) throw rc; 634 /* Object name. */ 635 mName = strmBlk.GetString("name"); 636 if (mName.isEmpty()) throw VERR_NOT_FOUND; 637 /* Type. */ 638 Utf8Str strType(strmBlk.GetString("ftype")); 639 if (strType.equalsIgnoreCase("-")) 640 mType = FsObjType_File; 641 else if (strType.equalsIgnoreCase("d")) 642 mType = FsObjType_Directory; 643 /** @todo Add more types! */ 644 else 645 mType = FsObjType_Undefined; 646 /* Object size. */ 647 rc = strmBlk.GetInt64Ex("st_size", &mObjectSize); 648 if (RT_FAILURE(rc)) throw rc; 649 /** @todo Add complete stat info! */ 650 } 651 catch (int rc2) 652 { 653 rc = rc2; 654 } 655 656 LogFlowFuncLeaveRC(rc); 608 657 return rc; 609 658 } … … 650 699 651 700 #ifdef DEBUG 652 void GuestProcessStreamBlock::Dump (void)701 void GuestProcessStreamBlock::DumpToLog(void) const 653 702 { 654 703 LogFlowFunc(("Dumping contents of stream block=0x%p (%ld items):\n", -
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r42525 r42673 22 22 *******************************************************************************/ 23 23 #include "GuestDirectoryImpl.h" 24 #include "GuestSessionImpl.h" 24 25 #include "GuestCtrlImplPrivate.h" 25 26 … … 52 53 ///////////////////////////////////////////////////////////////////////////// 53 54 54 int GuestDirectory::init(GuestSession *aSession, const Utf8Str &strPath) 55 { 55 int GuestDirectory::init(GuestSession *aSession, 56 const Utf8Str &strPath, const Utf8Str &strFilter /*= ""*/, uint32_t uFlags /*= 0*/) 57 { 58 LogFlowThisFunc(("strPath=%s, strFilter=%s, uFlags=%x\n", 59 strPath.c_str(), strFilter.c_str(), uFlags)); 60 56 61 /* Enclose the state transition NotReady->InInit->Ready. */ 57 62 AutoInitSpan autoInitSpan(this); … … 59 64 60 65 mData.mParent = aSession; 61 mData.mName = strPath; 62 63 /* Confirm a successful initialization when it's the case. */ 64 autoInitSpan.setSucceeded(); 65 66 return VINF_SUCCESS; 66 mData.mName = strPath; 67 mData.mFilter = strFilter; 68 mData.mFlags = uFlags; 69 70 /* Start the directory process on the guest. */ 71 GuestProcessStartupInfo procInfo; 72 procInfo.mName = Utf8StrFmt(tr("Reading directory \"%s\"", strPath.c_str())); 73 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_LS); 74 procInfo.mTimeoutMS = 0; /* No timeout. */ 75 procInfo.mFlags = ProcessCreateFlag_Hidden | ProcessCreateFlag_WaitForStdOut; 76 77 procInfo.mArguments.push_back(Utf8Str("--machinereadable")); 78 /* We want the long output format which contains all the object details. */ 79 procInfo.mArguments.push_back(Utf8Str("-l")); 80 #if 0 /* Flags are not supported yet. */ 81 if (uFlags & DirectoryOpenFlag_NoSymlinks) 82 procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */ 83 #endif 84 /** @todo Recursion support? */ 85 procInfo.mArguments.push_back(strPath); /* The directory we want to open. */ 86 87 /* 88 * Start the process asynchronously and keep it around so that we can use 89 * it later in subsequent read() calls. 90 */ 91 int rc = mData.mParent->processCreateExInteral(procInfo, mData.mProcess); 92 if (RT_SUCCESS(rc)) 93 rc = mData.mProcess->startProcessAsync(); 94 95 LogFlowThisFunc(("rc=%Rrc\n", rc)); 96 97 if (RT_SUCCESS(rc)) 98 { 99 /* Confirm a successful initialization when it's the case. */ 100 autoInitSpan.setSucceeded(); 101 return rc; 102 } 103 104 autoInitSpan.setFailed(); 105 return rc; 67 106 } 68 107 … … 79 118 if (autoUninitSpan.uninitDone()) 80 119 return; 120 121 if (!mData.mProcess.isNull()) 122 mData.mProcess->uninit(); 81 123 } 82 124 … … 100 142 } 101 143 144 STDMETHODIMP GuestDirectory::COMGETTER(Filter)(BSTR *aFilter) 145 { 146 LogFlowThisFuncEnter(); 147 148 CheckComArgOutPointerValid(aFilter); 149 150 AutoCaller autoCaller(this); 151 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 152 153 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 154 155 mData.mFilter.cloneTo(aFilter); 156 157 return S_OK; 158 } 159 160 // private methods 161 ///////////////////////////////////////////////////////////////////////////// 162 163 int GuestDirectory::parseData(GuestProcessStreamBlock &streamBlock) 164 { 165 LogFlowThisFunc(("cbStream=%RU32\n", mData.mStream.GetSize())); 166 167 int rc; 168 do 169 { 170 /* Try parsing the data to see if the current block is complete. */ 171 rc = mData.mStream.ParseBlock(streamBlock); 172 if (streamBlock.GetCount()) 173 break; 174 175 } while (RT_SUCCESS(rc)); 176 177 LogFlowFuncLeaveRC(rc); 178 return rc; 179 } 180 181 102 182 // implementation of public methods 103 183 ///////////////////////////////////////////////////////////////////////////// 104 184 105 STDMETHODIMP GuestDirectory:: Read(IFsObjInfo **aInfo)185 STDMETHODIMP GuestDirectory::Close(void) 106 186 { 107 187 #ifndef VBOX_WITH_GUEST_CONTROL 108 188 ReturnComNotImplemented(); 109 189 #else 190 LogFlowThisFuncEnter(); 191 192 uninit(); 193 194 return S_OK; 195 #endif /* VBOX_WITH_GUEST_CONTROL */ 196 } 197 198 STDMETHODIMP GuestDirectory::Read(IFsObjInfo **aInfo) 199 { 200 #ifndef VBOX_WITH_GUEST_CONTROL 201 ReturnComNotImplemented(); 202 #else 203 LogFlowThisFuncEnter(); 204 110 205 AutoCaller autoCaller(this); 111 206 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 112 207 113 ReturnComNotImplemented(); 208 ComObjPtr<GuestProcess> pProcess = mData.mProcess; 209 Assert(!pProcess.isNull()); 210 211 HRESULT hr = S_OK; 212 213 int rc; 214 GuestProcessStreamBlock streamBlock; 215 216 /** @todo Make use of exceptions! */ 217 218 try 219 { 220 GuestFsObjData objData; 221 222 AutoWriteLock rlock(this COMMA_LOCKVAL_SRC_POS); 223 224 rc = parseData(streamBlock); 225 if ( RT_FAILURE(rc) 226 || streamBlock.IsEmpty()) /* More data needed. */ 227 { 228 rlock.release(); 229 230 rc = pProcess->waitForStart(30 * 1000 /* Timeout */); 231 if (RT_FAILURE(rc)) 232 return setError(VBOX_E_IPRT_ERROR, 233 tr("Could not start reading directory \"%s\": %Rrc"), 234 mData.mName.c_str(), rc); 235 BYTE byBuf[_64K]; 236 size_t cbRead = 0; 237 238 /** @todo Merge with GuestSession::queryFileInfoInternal. */ 239 for (;;) 240 { 241 GuestProcessWaitResult waitRes; 242 rc = pProcess->waitFor( ProcessWaitForFlag_Terminate 243 | ProcessWaitForFlag_StdOut, 244 30 * 1000 /* Timeout */, waitRes); 245 if ( RT_FAILURE(rc) 246 || waitRes.mResult == ProcessWaitResult_Terminate 247 || waitRes.mResult == ProcessWaitResult_Error 248 || waitRes.mResult == ProcessWaitResult_Timeout) 249 { 250 break; 251 } 252 253 rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 254 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), 255 &cbRead); 256 if (RT_FAILURE(rc)) 257 break; 258 259 if (cbRead) 260 { 261 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 262 263 rc = mData.mStream.AddData(byBuf, cbRead); 264 if (RT_FAILURE(rc)) 265 break; 266 267 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n", 268 rc, cbRead, mData.mStream.GetSize())); 269 270 rc = parseData(streamBlock); 271 if (RT_SUCCESS(rc)) 272 { 273 /* Parsing the current stream block succeeded so 274 * we don't need more at the moment. */ 275 break; 276 } 277 } 278 } 279 280 LogFlowThisFunc(("Reading done with rc=%Rrc, cbRead=%RU64, cbStream=%RU32\n", 281 rc, cbRead, mData.mStream.GetSize())); 282 283 if (RT_SUCCESS(rc)) 284 { 285 rc = parseData(streamBlock); 286 if (rc == VERR_NO_DATA) /* Since this is the last parsing call, this is ok. */ 287 rc = VINF_SUCCESS; 288 } 289 290 /* 291 * Note: The guest process can still be around to serve the next 292 * upcoming stream block next time. 293 */ 294 if (RT_SUCCESS(rc)) 295 { 296 /** @todo Move into common function. */ 297 ProcessStatus_T procStatus = ProcessStatus_Undefined; 298 LONG exitCode = 0; 299 300 HRESULT hr = pProcess->COMGETTER(Status(&procStatus)); 301 ComAssertComRC(hr); 302 hr = pProcess->COMGETTER(ExitCode(&exitCode)); 303 ComAssertComRC(hr); 304 305 if ( ( procStatus != ProcessStatus_Started 306 && procStatus != ProcessStatus_Paused 307 && procStatus != ProcessStatus_Terminating 308 ) 309 && exitCode != 0) 310 { 311 return setError(VBOX_E_IPRT_ERROR, 312 tr("Reading directory \"%s\" failed: Unable to read / access denied"), 313 mData.mName.c_str(), exitCode); /**@todo Add stringify methods! */ 314 } 315 } 316 } 317 318 if (RT_SUCCESS(rc)) 319 { 320 if (streamBlock.GetCount()) /* Did we get content? */ 321 { 322 rc = objData.FromLs(streamBlock); 323 if (RT_FAILURE(rc)) 324 return setError(VBOX_E_IPRT_ERROR, 325 tr("Reading directory \"%s\" failed: Path not found"), 326 mData.mName.c_str()); 327 328 /* Create the object. */ 329 ComObjPtr<GuestFsObjInfo> pFsObjInfo; 330 HRESULT hr = pFsObjInfo.createObject(); 331 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 332 333 rc = pFsObjInfo->init(objData); 334 if (RT_FAILURE(rc)) throw rc; 335 336 /* Return info object to the caller. */ 337 hr = pFsObjInfo.queryInterfaceTo(aInfo); 338 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 339 } 340 else 341 { 342 /* Nothing to read anymore. Tell the caller. */ 343 hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""), 344 mData.mName.c_str()); 345 } 346 } 347 } 348 catch (int rc2) 349 { 350 rc = rc2; 351 } 352 353 if (RT_FAILURE(rc)) /** @todo Add more errors here. */ 354 hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"), 355 mData.mName.c_str(), rc); 356 357 LogFlowFuncLeaveRC(rc); 358 return hr; 114 359 #endif /* VBOX_WITH_GUEST_CONTROL */ 115 360 } -
trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp
r42478 r42673 52 52 ///////////////////////////////////////////////////////////////////////////// 53 53 54 HRESULT GuestFsObjInfo::init(void) 55 { 56 return S_OK; 54 int GuestFsObjInfo::init(const GuestFsObjData &objData) 55 { 56 LogFlowThisFuncEnter(); 57 58 /* Enclose the state transition NotReady->InInit->Ready. */ 59 AutoInitSpan autoInitSpan(this); 60 AssertReturn(autoInitSpan.isOk(), E_FAIL); 61 62 mData = objData; 63 64 /* Confirm a successful initialization when it's the case. */ 65 autoInitSpan.setSucceeded(); 66 67 return VINF_SUCCESS; 57 68 } 58 69 … … 82 93 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 83 94 84 ReturnComNotImplemented(); 95 CheckComArgOutPointerValid(aAccessTime); 96 97 *aAccessTime = mData.mAccessTime; 98 99 return S_OK; 85 100 #endif /* VBOX_WITH_GUEST_CONTROL */ 86 101 } … … 94 109 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 95 110 96 ReturnComNotImplemented(); 111 CheckComArgOutPointerValid(aAllocatedSize); 112 113 *aAllocatedSize = mData.mAllocatedSize; 114 115 return S_OK; 97 116 #endif /* VBOX_WITH_GUEST_CONTROL */ 98 117 } … … 106 125 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 107 126 108 ReturnComNotImplemented(); 127 CheckComArgOutPointerValid(aBirthTime); 128 129 *aBirthTime = mData.mBirthTime; 130 131 return S_OK; 109 132 #endif /* VBOX_WITH_GUEST_CONTROL */ 110 133 } … … 118 141 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 119 142 120 ReturnComNotImplemented(); 143 CheckComArgOutPointerValid(aChangeTime); 144 145 *aChangeTime = mData.mChangeTime; 146 147 return S_OK; 121 148 #endif /* VBOX_WITH_GUEST_CONTROL */ 122 149 } … … 130 157 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 131 158 132 ReturnComNotImplemented(); 133 #endif /* VBOX_WITH_GUEST_CONTROL */ 134 } 135 136 STDMETHODIMP GuestFsObjInfo::COMGETTER(FileAttrs)(BSTR *aFileAttrs) 137 { 138 #ifndef VBOX_WITH_GUEST_CONTROL 139 ReturnComNotImplemented(); 140 #else 141 AutoCaller autoCaller(this); 142 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 143 144 ReturnComNotImplemented(); 145 #endif /* VBOX_WITH_GUEST_CONTROL */ 146 } 147 148 STDMETHODIMP GuestFsObjInfo::COMGETTER(GenerationID)(ULONG *aGenerationID) 149 { 150 #ifndef VBOX_WITH_GUEST_CONTROL 151 ReturnComNotImplemented(); 152 #else 153 AutoCaller autoCaller(this); 154 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 155 156 ReturnComNotImplemented(); 159 CheckComArgOutPointerValid(aDeviceNumber); 160 161 *aDeviceNumber = mData.mDeviceNumber; 162 163 return S_OK; 164 #endif /* VBOX_WITH_GUEST_CONTROL */ 165 } 166 167 STDMETHODIMP GuestFsObjInfo::COMGETTER(FileAttributes)(BSTR *aAttributes) 168 { 169 #ifndef VBOX_WITH_GUEST_CONTROL 170 ReturnComNotImplemented(); 171 #else 172 AutoCaller autoCaller(this); 173 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 174 175 CheckComArgOutPointerValid(aAttributes); 176 177 mData.mFileAttrs.cloneTo(aAttributes); 178 179 return S_OK; 180 #endif /* VBOX_WITH_GUEST_CONTROL */ 181 } 182 183 STDMETHODIMP GuestFsObjInfo::COMGETTER(GenerationId)(ULONG *aGenerationId) 184 { 185 #ifndef VBOX_WITH_GUEST_CONTROL 186 ReturnComNotImplemented(); 187 #else 188 AutoCaller autoCaller(this); 189 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 190 191 CheckComArgOutPointerValid(aGenerationId); 192 193 *aGenerationId = mData.mGenerationID; 194 195 return S_OK; 157 196 #endif /* VBOX_WITH_GUEST_CONTROL */ 158 197 } … … 166 205 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 167 206 168 ReturnComNotImplemented(); 207 CheckComArgOutPointerValid(aGID); 208 209 *aGID = mData.mGID; 210 211 return S_OK; 169 212 #endif /* VBOX_WITH_GUEST_CONTROL */ 170 213 } … … 178 221 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 179 222 180 ReturnComNotImplemented(); 223 CheckComArgOutPointerValid(aGroupName); 224 225 mData.mGroupName.cloneTo(aGroupName); 226 227 return S_OK; 181 228 #endif /* VBOX_WITH_GUEST_CONTROL */ 182 229 } … … 190 237 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 191 238 192 ReturnComNotImplemented(); 239 CheckComArgOutPointerValid(aHardLinks); 240 241 *aHardLinks = mData.mNumHardLinks; 242 243 return S_OK; 193 244 #endif /* VBOX_WITH_GUEST_CONTROL */ 194 245 } … … 202 253 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 203 254 204 ReturnComNotImplemented(); 255 CheckComArgOutPointerValid(aModificationTime); 256 257 *aModificationTime = mData.mModificationTime; 258 259 return S_OK; 205 260 #endif /* VBOX_WITH_GUEST_CONTROL */ 206 261 } … … 214 269 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 215 270 216 ReturnComNotImplemented(); 217 #endif /* VBOX_WITH_GUEST_CONTROL */ 218 } 219 220 STDMETHODIMP GuestFsObjInfo::COMGETTER(NodeID)(LONG64 *aNodeID) 221 { 222 #ifndef VBOX_WITH_GUEST_CONTROL 223 ReturnComNotImplemented(); 224 #else 225 AutoCaller autoCaller(this); 226 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 227 228 ReturnComNotImplemented(); 229 #endif /* VBOX_WITH_GUEST_CONTROL */ 230 } 231 232 STDMETHODIMP GuestFsObjInfo::COMGETTER(NodeIDDevice)(ULONG *aNodeIDDevice) 233 { 234 #ifndef VBOX_WITH_GUEST_CONTROL 235 ReturnComNotImplemented(); 236 #else 237 AutoCaller autoCaller(this); 238 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 239 240 ReturnComNotImplemented(); 241 #endif /* VBOX_WITH_GUEST_CONTROL */ 242 } 243 244 STDMETHODIMP GuestFsObjInfo::COMGETTER(ObjectSize)(ULONG *aObjectSize) 245 { 246 #ifndef VBOX_WITH_GUEST_CONTROL 247 ReturnComNotImplemented(); 248 #else 249 AutoCaller autoCaller(this); 250 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 251 252 ReturnComNotImplemented(); 271 CheckComArgOutPointerValid(aName); 272 273 mData.mName.cloneTo(aName); 274 275 return S_OK; 276 #endif /* VBOX_WITH_GUEST_CONTROL */ 277 } 278 279 STDMETHODIMP GuestFsObjInfo::COMGETTER(NodeId)(LONG64 *aNodeId) 280 { 281 #ifndef VBOX_WITH_GUEST_CONTROL 282 ReturnComNotImplemented(); 283 #else 284 AutoCaller autoCaller(this); 285 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 286 287 CheckComArgOutPointerValid(aNodeId); 288 289 *aNodeId = mData.mNodeID; 290 291 return S_OK; 292 #endif /* VBOX_WITH_GUEST_CONTROL */ 293 } 294 295 STDMETHODIMP GuestFsObjInfo::COMGETTER(NodeIdDevice)(ULONG *aNodeIdDevice) 296 { 297 #ifndef VBOX_WITH_GUEST_CONTROL 298 ReturnComNotImplemented(); 299 #else 300 AutoCaller autoCaller(this); 301 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 302 303 CheckComArgOutPointerValid(aNodeIdDevice); 304 305 *aNodeIdDevice = mData.mNodeIDDevice; 306 307 return S_OK; 308 #endif /* VBOX_WITH_GUEST_CONTROL */ 309 } 310 311 STDMETHODIMP GuestFsObjInfo::COMGETTER(ObjectSize)(LONG64 *aObjectSize) 312 { 313 #ifndef VBOX_WITH_GUEST_CONTROL 314 ReturnComNotImplemented(); 315 #else 316 AutoCaller autoCaller(this); 317 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 318 319 CheckComArgOutPointerValid(aObjectSize); 320 321 *aObjectSize = mData.mObjectSize; 322 323 return S_OK; 253 324 #endif /* VBOX_WITH_GUEST_CONTROL */ 254 325 } … … 262 333 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 263 334 264 ReturnComNotImplemented(); 335 CheckComArgOutPointerValid(aType); 336 337 *aType = mData.mType; 338 339 return S_OK; 265 340 #endif /* VBOX_WITH_GUEST_CONTROL */ 266 341 } … … 274 349 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 275 350 276 ReturnComNotImplemented(); 351 CheckComArgOutPointerValid(aUID); 352 353 *aUID = mData.mUID; 354 355 return S_OK; 277 356 #endif /* VBOX_WITH_GUEST_CONTROL */ 278 357 } … … 286 365 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 287 366 288 ReturnComNotImplemented(); 367 CheckComArgOutPointerValid(aUserFlags); 368 369 *aUserFlags = mData.mUserFlags; 370 371 return S_OK; 289 372 #endif /* VBOX_WITH_GUEST_CONTROL */ 290 373 } … … 298 381 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 299 382 300 ReturnComNotImplemented(); 383 CheckComArgOutPointerValid(aUserName); 384 385 mData.mUserName.cloneTo(aUserName); 386 387 return S_OK; 301 388 #endif /* VBOX_WITH_GUEST_CONTROL */ 302 389 } … … 310 397 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 311 398 312 ReturnComNotImplemented(); 313 #endif /* VBOX_WITH_GUEST_CONTROL */ 314 } 315 399 CheckComArgOutPointerValid(aACL); 400 401 mData.mACL.cloneTo(aACL); 402 403 return S_OK; 404 #endif /* VBOX_WITH_GUEST_CONTROL */ 405 } 406 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42634 r42673 498 498 } 499 499 500 /** 501 * Checks if the current assigned PID matches another PID (from a callback). 502 * 503 * In protocol v1 we don't have the possibility to terminate/kill 504 * processes so it can happen that a formerly start process A 505 * (which has the context ID 0 (session=0, process=0, count=0) will 506 * send a delayed message to the host if this process has already 507 * been discarded there and the same context ID was reused by 508 * a process B. Process B in turn then has a different guest PID. 509 * 510 * @return IPRT status code. 511 * @param uPID PID to check. 512 */ 513 inline int GuestProcess::checkPID(uint32_t uPID) 514 { 515 /* Was there a PID assigned yet? */ 516 if (mData.mPID) 517 { 518 /* 519 520 */ 521 if (mData.mParent->getProtocolVersion() < 2) 522 { 523 /* Simply ignore the stale requests. */ 524 return (mData.mPID == uPID) 525 ? VINF_SUCCESS : VERR_NOT_FOUND; 526 } 527 /* This should never happen! */ 528 AssertReleaseMsg(mData.mPID == uPID, ("Unterminated guest process (PID %RU32) sent data to a newly started process (PID %RU32)\n", 529 uPID, mData.mPID)); 530 } 531 532 return VINF_SUCCESS; 533 } 534 535 /* Do not hold any locks here because the lock validator will be unhappy 536 * when being in uninit(). */ 537 void GuestProcess::close(void) 538 { 539 LogFlowThisFuncEnter(); 540 541 uninit(); 542 543 LogFlowThisFuncLeave(); 544 } 545 500 546 inline bool GuestProcess::isAlive(void) 501 547 { … … 503 549 || mData.mStatus == ProcessStatus_Paused 504 550 || mData.mStatus == ProcessStatus_Terminating); 505 }506 507 /* Do not hold any locks here because the lock validator will be unhappy508 * when being in uninit(). */509 void GuestProcess::close(void)510 {511 LogFlowThisFuncEnter();512 513 uninit();514 515 LogFlowThisFuncLeave();516 551 } 517 552 … … 565 600 mData.mPID, pData->u32Status, pData->u32Flags, pData->cbProcessed, pCallback, pData)); 566 601 567 int rc = VINF_SUCCESS; 602 int rc = checkPID(pData->u32PID); 603 if (RT_FAILURE(rc)) 604 return rc; 568 605 569 606 /* First, signal callback in every case (if available). */ … … 607 644 pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData)); 608 645 609 int rc = VINF_SUCCESS; 610 611 /* Get data from the callback payload. */ 612 if (mData.mPID) 613 Assert(mData.mPID == pData->u32PID); 646 int rc = checkPID(pData->u32PID); 647 if (RT_FAILURE(rc)) 648 return rc; 614 649 615 650 BOOL fSignal = FALSE; … … 791 826 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData)); 792 827 793 /* Copy data into callback (if any). */ 794 int rc = VINF_SUCCESS; 828 int rc = checkPID(pData->u32PID); 829 if (RT_FAILURE(rc)) 830 return rc; 795 831 796 832 /* First, signal callback in every case (if available). */ … … 1229 1265 case ProcessStatus_Down: 1230 1266 waitRes.mResult = ProcessWaitResult_Terminate; 1267 waitRes.mRC = mData.mRC; 1231 1268 break; 1232 1269 … … 1234 1271 case ProcessStatus_TimedOutAbnormally: 1235 1272 waitRes.mResult = ProcessWaitResult_Timeout; 1273 waitRes.mRC = mData.mRC; 1236 1274 break; 1237 1275 … … 1271 1309 break; 1272 1310 1311 case ProcessStatus_TimedOutKilled: 1312 case ProcessStatus_TimedOutAbnormally: 1313 waitRes.mResult = ProcessWaitResult_Timeout; 1314 waitRes.mRC = mData.mRC; 1315 break; 1316 1273 1317 case ProcessStatus_Undefined: 1274 1318 case ProcessStatus_Starting: … … 1310 1354 1311 1355 mData.mWaitCount--; 1356 1357 LogFlowFuncLeaveRC(rc); 1358 return rc; 1359 } 1360 1361 int GuestProcess::waitForStart(uint32_t uTimeoutMS) 1362 { 1363 LogFlowThisFunc(("uTimeoutMS=%RU32\n", uTimeoutMS)); 1364 1365 int rc = VINF_SUCCESS; 1366 1367 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 1368 if (mData.mStatus != ProcessStatus_Started) 1369 { 1370 alock.release(); 1371 1372 GuestProcessWaitResult waitRes; 1373 int rc = waitFor(ProcessWaitForFlag_Start, uTimeoutMS, waitRes); 1374 if ( RT_FAILURE(rc) 1375 || ( waitRes.mResult == ProcessWaitResult_Start 1376 && waitRes.mResult == ProcessWaitResult_Any 1377 ) 1378 ) 1379 { 1380 if (RT_SUCCESS(rc)) 1381 rc = waitRes.mRC; 1382 } 1383 } 1312 1384 1313 1385 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r42657 r42673 1092 1092 } 1093 1093 1094 int GuestSession::directoryOpenInternal(const Utf8Str &strPath, const Utf8Str &strFilter, 1095 uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory) 1096 { 1097 LogFlowThisFunc(("strPath=%s, strPath=%s, uFlags=%x\n", 1098 strPath.c_str(), strFilter.c_str(), uFlags)); 1099 int rc; 1100 1101 try 1102 { 1103 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1104 1105 /* Create the directory object. */ 1106 HRESULT hr = pDirectory.createObject(); 1107 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1108 1109 rc = pDirectory->init(this /* Parent */, 1110 strPath, strFilter, uFlags); 1111 if (RT_FAILURE(rc)) throw rc; 1112 1113 /* Add the created directory to our vector. */ 1114 mData.mDirectories.push_back(pDirectory); 1115 1116 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 1117 strPath.c_str(), mData.mId)); 1118 } 1119 catch (int rc2) 1120 { 1121 rc = rc2; 1122 } 1123 1124 LogFlowFuncLeaveRC(rc); 1125 return rc; 1126 } 1127 1094 1128 int GuestSession::dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData) 1095 1129 { … … 1198 1232 size_t cbRead = 0; 1199 1233 1234 /** @todo Merge with GuestDirectory::read. */ 1200 1235 for (;;) 1201 1236 { … … 1234 1269 if (RT_SUCCESS(rc)) 1235 1270 { 1236 rc = objData.From (streamBlock);1271 rc = objData.FromStat(streamBlock); 1237 1272 } 1238 1273 else … … 1818 1853 } 1819 1854 1820 STDMETHODIMP GuestSession::DirectoryOpen(IN_BSTR aPath, IN_BSTR aFilter, IN_BSTR aFlags, IGuestDirectory **aDirectory) 1821 { 1822 #ifndef VBOX_WITH_GUEST_CONTROL 1823 ReturnComNotImplemented(); 1824 #else 1825 LogFlowThisFuncEnter(); 1826 1827 AutoCaller autoCaller(this); 1828 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1829 1830 ReturnComNotImplemented(); 1855 STDMETHODIMP GuestSession::DirectoryOpen(IN_BSTR aPath, IN_BSTR aFilter, ComSafeArrayIn(DirectoryOpenFlag_T, aFlags), IGuestDirectory **aDirectory) 1856 { 1857 #ifndef VBOX_WITH_GUEST_CONTROL 1858 ReturnComNotImplemented(); 1859 #else 1860 LogFlowThisFuncEnter(); 1861 1862 if (RT_UNLIKELY((aPath) == NULL || *(aPath) == '\0')) 1863 return setError(E_INVALIDARG, tr("No directory to open specified")); 1864 if (RT_UNLIKELY((aFilter) != NULL && *(aFilter) != '\0')) 1865 return setError(E_INVALIDARG, tr("Directory filters not implemented yet")); 1866 1867 CheckComArgOutPointerValid(aDirectory); 1868 1869 AutoCaller autoCaller(this); 1870 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1871 1872 uint32_t fFlags = DirectoryOpenFlag_None; 1873 if (aFlags) 1874 { 1875 com::SafeArray<DirectoryOpenFlag_T> flags(ComSafeArrayInArg(aFlags)); 1876 for (size_t i = 0; i < flags.size(); i++) 1877 fFlags |= flags[i]; 1878 1879 if (fFlags) 1880 return setError(E_INVALIDARG, tr("Open flags (%#x) not implemented yet"), fFlags); 1881 } 1882 1883 HRESULT hr = S_OK; 1884 1885 ComObjPtr <GuestDirectory> pDirectory; 1886 int rc = directoryOpenInternal(Utf8Str(aPath), Utf8Str(aFilter), fFlags, pDirectory); 1887 if (RT_SUCCESS(rc)) 1888 { 1889 if (aDirectory) 1890 { 1891 /* Return directory object to the caller. */ 1892 hr = pDirectory.queryInterfaceTo(aDirectory); 1893 } 1894 else 1895 { 1896 rc = directoryClose(pDirectory); 1897 if (RT_FAILURE(rc)) 1898 hr = setError(VBOX_E_IPRT_ERROR, tr("Unable to close directory object, rc=%Rrc"), rc); 1899 } 1900 } 1901 else 1902 { 1903 switch (rc) 1904 { 1905 case VERR_INVALID_PARAMETER: 1906 hr = setError(VBOX_E_IPRT_ERROR, tr("Opening directory failed: Invalid parameters given")); 1907 break; 1908 1909 case VERR_BROKEN_PIPE: 1910 hr = setError(VBOX_E_IPRT_ERROR, tr("Opening directory failed: Unexpectedly aborted")); 1911 break; 1912 1913 default: 1914 hr = setError(VBOX_E_IPRT_ERROR, tr("Opening directory failed: %Rrc"), rc); 1915 break; 1916 } 1917 } 1918 1919 return hr; 1831 1920 #endif /* VBOX_WITH_GUEST_CONTROL */ 1832 1921 } … … 2103 2192 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU32, cbStreamOut=%RU32\n", 2104 2193 rc, cbRead, streamOut.GetSize())); 2105 } 2194 } 2106 2195 2107 2196 if (RT_FAILURE(rc))
Note:
See TracChangeset
for help on using the changeset viewer.