Changeset 38395 in vbox for trunk/src/VBox/Main/src-client/GuestCtrlImplDir.cpp
- Timestamp:
- Aug 10, 2011 11:48:29 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73430
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestCtrlImplDir.cpp
r38290 r38395 138 138 * 139 139 * @return IPRT status code. 140 * @param puHandle Pointer where the handle gets stored to. 140 * @param puHandle Pointer where the handle gets stored to. Optional. 141 141 * @param uPID PID of guest process running the associated "vbox_ls". 142 * @param pszDirectoryDirectory the handle is assigned to.143 * @param pszFilterDirectory filter. Optional.142 * @param aDirectory Directory the handle is assigned to. 143 * @param aFilter Directory filter. Optional. 144 144 * @param uFlags Directory open flags. 145 145 * 146 146 */ 147 147 int Guest::directoryCreateHandle(ULONG *puHandle, ULONG uPID, 148 const char *pszDirectory, const char *pszFilter, ULONG uFlags) 149 { 150 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 151 AssertPtrReturn(pszDirectory, VERR_INVALID_POINTER); 152 /* pszFilter is optional. */ 148 IN_BSTR aDirectory, IN_BSTR aFilter, ULONG uFlags) 149 { 150 AssertReturn(uPID, VERR_INVALID_PARAMETER); 151 CheckComArgStrNotEmptyOrNull(aDirectory); 152 /* aFilter is optional. */ 153 /* uFlags are optional. */ 153 154 154 155 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); … … 160 161 uint32_t uHandleTry = ASMAtomicIncU32(&mNextDirectoryID); 161 162 GuestDirectoryMapIter it = mGuestDirectoryMap.find(uHandleTry); 162 if (it == mGuestDirectoryMap.end()) 163 { 163 if (it == mGuestDirectoryMap.end()) /* We found a free slot ... */ 164 { 165 mGuestDirectoryMap[uHandleTry].mDirectory = aDirectory; 166 mGuestDirectoryMap[uHandleTry].mFilter = aFilter; 167 mGuestDirectoryMap[uHandleTry].mPID = uPID; 168 mGuestDirectoryMap[uHandleTry].mFlags = uFlags; 169 Assert(mGuestDirectoryMap.size()); 170 164 171 rc = VINF_SUCCESS; 165 if (!RTStrAPrintf(&mGuestDirectoryMap[uHandleTry].mpszDirectory, pszDirectory)) 166 rc = VERR_NO_MEMORY; 167 else 168 { 169 /* Filter is optional. */ 170 if (pszFilter) 171 { 172 if (!RTStrAPrintf(&mGuestDirectoryMap[uHandleTry].mpszFilter, pszFilter)) 173 rc = VERR_NO_MEMORY; 174 } 175 176 if (RT_SUCCESS(rc)) 177 { 178 mGuestDirectoryMap[uHandleTry].mPID = uPID; 179 mGuestDirectoryMap[uHandleTry].mFlags = uFlags; 180 *puHandle = uHandleTry; 181 182 break; 183 } 184 } 185 186 if (RT_FAILURE(rc)) 187 break; 188 189 Assert(mGuestDirectoryMap.size()); 172 173 if (puHandle) 174 *puHandle = uHandleTry; 175 break; 190 176 } 191 177 } … … 208 194 if (it != mGuestDirectoryMap.end()) 209 195 { 210 RTStrFree(it->second.mpszDirectory);211 RTStrFree(it->second.mpszFilter);212 213 196 /* Destroy raw guest stream buffer - not used 214 197 * anymore. */ … … 220 203 } 221 204 205 STDMETHODIMP Guest::DirectoryExists(IN_BSTR aDirectory, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists) 206 { 207 #ifndef VBOX_WITH_GUEST_CONTROL 208 ReturnComNotImplemented(); 209 #else /* VBOX_WITH_GUEST_CONTROL */ 210 using namespace guestControl; 211 212 CheckComArgStrNotEmptyOrNull(aDirectory); 213 214 /* Do not allow anonymous executions (with system rights). */ 215 if (RT_UNLIKELY((aUsername) == NULL || *(aUsername) == '\0')) 216 return setError(E_INVALIDARG, tr("No user name specified")); 217 218 return directoryExistsInternal(aDirectory, 219 aUsername, aPassword, aExists); 220 #endif 221 } 222 223 #ifdef VBOX_WITH_GUEST_CONTROL 224 HRESULT Guest::directoryExistsInternal(IN_BSTR aDirectory, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists) 225 { 226 using namespace guestControl; 227 228 CheckComArgStrNotEmptyOrNull(aDirectory); 229 230 AutoCaller autoCaller(this); 231 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 232 233 RTFSOBJINFO objInfo; 234 int rc; 235 HRESULT hr = directoryQueryInfoInternal(aDirectory, 236 aUsername, aPassword, 237 &objInfo, RTFSOBJATTRADD_NOTHING, &rc); 238 if (SUCCEEDED(hr)) 239 { 240 switch (rc) 241 { 242 case VINF_SUCCESS: 243 *aExists = TRUE; 244 break; 245 246 case VERR_FILE_NOT_FOUND: 247 *aExists = FALSE; 248 break; 249 250 case VERR_NOT_FOUND: 251 rc = setError(VBOX_E_IPRT_ERROR, 252 Guest::tr("Unable to query directory existence")); 253 break; 254 255 default: 256 AssertReleaseMsgFailed(("directoryExistsInternal: Unknown return value (%Rrc)\n", rc)); 257 break; 258 } 259 } 260 return hr; 261 } 262 #endif 263 222 264 /** 223 265 * Gets the associated PID from a directory handle. 224 266 * 225 * @return uint32_t Associated PID, 0 if handle not found/invalid.226 * @param uHandle Directory handle to get PID for.267 * @return uint32_t Associated PID, 0 if handle not found/invalid. 268 * @param uHandle Directory handle to get PID for. 227 269 */ 228 270 uint32_t Guest::directoryGetPID(uint32_t uHandle) … … 237 279 } 238 280 281 /** 282 * Returns the next directory entry of an open guest directory. 283 * Returns VERR_NO_MORE_FILES if no more entries available. 284 * 285 * @return IPRT status code. 286 * @param uHandle Directory handle to get entry for. 287 * @param streamBlock Reference that receives the next stream block data. 288 */ 239 289 int Guest::directoryGetNextEntry(uint32_t uHandle, GuestProcessStreamBlock &streamBlock) 240 290 { 241 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 291 // LOCK DOES NOT WORK HERE!? 292 //AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 242 293 243 294 GuestDirectoryMapIter it = mGuestDirectoryMap.find(uHandle); 244 295 if (it != mGuestDirectoryMap.end()) 245 296 { 246 HRESULT hr = executeStreamCollectBlock(it->second.mPID, 247 it->second.mStream, streamBlock); 248 if (FAILED(hr)) 249 return VERR_INVALID_PARAMETER; /** @todo Find better rc! */ 250 251 return VINF_SUCCESS; 297 return executeStreamGetNextBlock(it->second.mPID, 298 it->second.mStream, streamBlock); 252 299 } 253 300 … … 259 306 * or not. 260 307 * 261 * @return bool True if handle exists, false if not.262 * @param uHandle Directory handle to check.308 * @return bool True if handle exists, false if not. 309 * @param uHandle Directory handle to check. 263 310 */ 264 311 bool Guest::directoryHandleExists(uint32_t uHandle) … … 315 362 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); 316 363 317 HRESULT rc= S_OK;364 HRESULT hr = S_OK; 318 365 try 319 366 { … … 354 401 355 402 ULONG uPID; 356 rc = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_LS).raw(), Bstr("Opening directory").raw(), 403 /** @todo Don't wait for tool to finish! Might take a lot of time! */ 404 hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_LS).raw(), Bstr("Opening directory").raw(), 357 405 ComSafeArrayAsInParam(args), 358 406 ComSafeArrayAsInParam(env), 359 407 aUsername, aPassword, 360 408 NULL /* Progress */, &uPID); 361 if (SUCCEEDED( rc))409 if (SUCCEEDED(hr)) 362 410 { 363 411 /* Assign new directory handle ID. */ 364 int vrc = directoryCreateHandle(aHandle, uPID, 365 Utf8Directory.c_str(), 366 Utf8Filter.isEmpty() ? NULL : Utf8Filter.c_str(), 367 aFlags); 368 if (RT_FAILURE(vrc)) 369 rc = setError(VBOX_E_IPRT_ERROR, 412 ULONG uHandleNew; 413 int vrc = directoryCreateHandle(&uHandleNew, uPID, 414 aDirectory, aFilter, aFlags); 415 if (RT_SUCCESS(vrc)) 416 { 417 *aHandle = uHandleNew; 418 } 419 else 420 hr = setError(VBOX_E_IPRT_ERROR, 370 421 tr("Unable to create guest directory handle (%Rrc)"), vrc); 371 422 } … … 373 424 catch (std::bad_alloc &) 374 425 { 375 rc = E_OUTOFMEMORY; 376 } 377 return rc; 426 hr = E_OUTOFMEMORY; 427 } 428 return hr; 429 } 430 431 HRESULT Guest::directoryQueryInfoInternal(IN_BSTR aDirectory, 432 IN_BSTR aUsername, IN_BSTR aPassword, 433 PRTFSOBJINFO aObjInfo, RTFSOBJATTRADD enmAddAttribs, 434 int *pRC) 435 { 436 using namespace guestControl; 437 438 /** @todo Search directory cache first? */ 439 440 CheckComArgStrNotEmptyOrNull(aDirectory); 441 /* aUsername is optional. */ 442 /* aPassword is optional. */ 443 /* aObjInfo is optional. */ 444 445 AutoCaller autoCaller(this); 446 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 447 448 HRESULT hr = S_OK; 449 try 450 { 451 Utf8Str Utf8Dir(aDirectory); 452 Utf8Str Utf8Username(aUsername); 453 Utf8Str Utf8Password(aPassword); 454 455 com::SafeArray<IN_BSTR> args; 456 com::SafeArray<IN_BSTR> env; 457 458 /* 459 * Prepare tool command line. 460 */ 461 462 /* We need to get output which is machine-readable in form 463 * of "key=value\0..key=value\0\0". */ 464 args.push_back(Bstr("--machinereadable").raw()); 465 466 /* Only the actual file name to chekc is needed for now. */ 467 args.push_back(Bstr(Utf8Dir).raw()); 468 469 /* 470 * Execute guest process. 471 */ 472 ULONG uPID; 473 hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_STAT).raw(), Bstr("Querying directory information").raw(), 474 ComSafeArrayAsInParam(args), 475 ComSafeArrayAsInParam(env), 476 aUsername, aPassword, 477 NULL /* Progress */, &uPID); 478 if (SUCCEEDED(hr)) 479 { 480 GuestCtrlStreamObjects streamObjs; 481 hr = executeStreamParse(uPID, streamObjs); 482 if (SUCCEEDED(hr)) 483 { 484 int rc = VINF_SUCCESS; 485 486 GuestProcessStreamBlock *pBlock = streamObjs[0]; 487 AssertPtr(pBlock); 488 const char *pszFsType = pBlock->GetString("ftype"); 489 if (!pszFsType) /* Attribute missing? */ 490 rc = VERR_NOT_FOUND; 491 if ( RT_SUCCESS(rc) 492 && strcmp(pszFsType, "d")) /* Directory? */ 493 { 494 rc = VERR_FILE_NOT_FOUND; 495 } 496 if ( RT_SUCCESS(rc) 497 && aObjInfo) /* Do we want object details? */ 498 { 499 hr = executeStreamQueryFsObjInfo(aDirectory, pBlock, 500 aObjInfo, enmAddAttribs); 501 } 502 503 executeStreamFree(streamObjs); 504 505 if (pRC) 506 *pRC = rc; 507 } 508 } 509 } 510 catch (std::bad_alloc &) 511 { 512 hr = E_OUTOFMEMORY; 513 } 514 return hr; 378 515 } 379 516 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 391 528 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 392 529 393 HRESULT rc= S_OK;530 HRESULT hr = S_OK; 394 531 try 395 532 { 396 533 GuestProcessStreamBlock streamBlock; 397 int vrc = directoryGetNextEntry(aHandle, streamBlock);398 if (RT_SUCCESS( vrc))534 int rc = directoryGetNextEntry(aHandle, streamBlock); 535 if (RT_SUCCESS(rc)) 399 536 { 400 537 ComObjPtr <GuestDirEntry> pDirEntry; 401 rc= pDirEntry.createObject();402 ComAssertComRC( rc);403 404 rc= pDirEntry->init(this, streamBlock);405 if (SUCCEEDED( rc))538 hr = pDirEntry.createObject(); 539 ComAssertComRC(hr); 540 541 hr = pDirEntry->init(this, streamBlock); 542 if (SUCCEEDED(hr)) 406 543 { 407 544 pDirEntry.queryInterfaceTo(aDirEntry); 408 545 } 409 546 else 410 rc= setError(VBOX_E_IPRT_ERROR,547 hr = setError(VBOX_E_IPRT_ERROR, 411 548 Guest::tr("Unable to init guest directory entry")); 412 549 } 550 else if (rc == VERR_NO_MORE_FILES) 551 { 552 /* No more directory entries to read. */ 553 hr = E_ABORT; /** @todo Find/define a better rc! */ 554 } 413 555 else 414 rc= setError(VBOX_E_IPRT_ERROR,415 Guest::tr(" Directory handle is invalid"));556 hr = setError(VBOX_E_IPRT_ERROR, 557 Guest::tr("Failed getting next directory entry (%Rrc)"), rc); 416 558 } 417 559 catch (std::bad_alloc &) 418 560 { 419 rc= E_OUTOFMEMORY;420 } 421 return rc;422 #endif 423 } 424 561 hr = E_OUTOFMEMORY; 562 } 563 return hr; 564 #endif 565 } 566
Note:
See TracChangeset
for help on using the changeset viewer.