Changeset 50734 in vbox for trunk/src/VBox/Main
- Timestamp:
- Mar 10, 2014 1:54:03 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 92721
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp
r50724 r50734 204 204 HRESULT queryProgressTo(IProgress **ppProgress); 205 205 206 int writeToFile(const char *pszPath, size_t cbPath, void *pvData, size_t cbData, uint32_t fMode); 207 206 208 public: 207 209 … … 223 225 /** Dropped files directory on the host. */ 224 226 Utf8Str m_strDropDir; 227 /** The handle of the currently opened file being written to 228 * or read from. */ 229 RTFILE m_hFile; 230 Utf8Str m_strFile; 225 231 226 232 ComObjPtr<Guest> m_parent; … … 294 300 , m_cbDataCurrent(0) 295 301 , m_cbDataTotal(0) 302 , m_hFile(NIL_RTFILE) 296 303 , m_parent(pGuest) 297 304 { … … 303 310 { 304 311 reset(); 312 305 313 int rc = RTSemEventDestroy(m_EventSem); 306 314 AssertRC(rc); … … 346 354 break; 347 355 356 case VERR_NOT_FOUND: 357 /* Should not happen due to file locking on the guest, but anyway ... */ 358 strError += Utf8StrFmt(pGuest->tr("One or more guest files or directories selected for transferring to the host were not" 359 "found on the guest anymore. This can be the case if the guest files were moved and/or" 360 "altered while the drag'n drop operation was in progress.")); 361 break; 362 348 363 case VERR_SHARING_VIOLATION: 349 364 strError += Utf8StrFmt(pGuest->tr("One or more guest files or directories selected for transferring to the host were locked. " … … 367 382 void DnDGuestResponse::reset(void) 368 383 { 384 LogFlowThisFuncEnter(); 385 386 m_defAction = 0; 387 m_allActions = 0; 388 369 389 m_strDropDir = ""; 370 390 m_strFormat = ""; … … 375 395 m_pvData = NULL; 376 396 } 377 m_cbData = 0; 378 397 m_cbData = 0; 379 398 m_cbDataCurrent = 0; 380 399 m_cbDataTotal = 0; 400 401 if (m_hFile != NIL_RTFILE) 402 { 403 RTFileClose(m_hFile); 404 m_hFile = NIL_RTFILE; 405 } 406 m_strFile = ""; 381 407 } 382 408 … … 492 518 } 493 519 520 int DnDGuestResponse::writeToFile(const char *pszPath, size_t cbPath, 521 void *pvData, size_t cbData, uint32_t fMode) 522 { 523 /** @todo Support locking more than one file at a time! We 524 * might want to have a table in DnDGuestImpl which 525 * keeps those file pointers around, or extend the 526 * actual protocol for explicit open calls. 527 * 528 * For now we only keep one file open at a time, so if 529 * a client does alternating writes to different files 530 * this function will close the old and re-open the new 531 * file on every call. */ 532 int rc; 533 if ( m_hFile == NIL_RTFILE 534 || m_strFile != pszPath) 535 { 536 char *pszFile = RTPathJoinA(m_strDropDir.c_str(), pszPath); 537 if (pszFile) 538 { 539 RTFILE hFile; 540 /** @todo Respect fMode! */ 541 rc = RTFileOpen(&hFile, pszFile, 542 RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE 543 | RTFILE_O_WRITE | RTFILE_O_APPEND); 544 if (RT_SUCCESS(rc)) 545 { 546 LogFlowFunc(("Opening \"%s\" (fMode=0x%x) for writing ...\n", 547 pszFile, fMode)); 548 549 m_hFile = hFile; 550 m_strFile = pszPath; 551 } 552 553 RTStrFree(pszFile); 554 } 555 else 556 rc = VERR_NO_MEMORY; 557 } 558 else 559 rc = VINF_SUCCESS; 560 561 if (RT_SUCCESS(rc)) 562 { 563 rc = RTFileWrite(m_hFile, pvData, cbData, 564 NULL /* No partial writes */); 565 566 if (RT_SUCCESS(rc)) 567 rc = dataSetStatus(cbData); 568 } 569 570 return rc; 571 } 572 494 573 /////////////////////////////////////////////////////////////////////////////// 495 574 … … 719 798 720 799 DnDGuestResponse *pResp = d->response(); 721 /* This blocks until the request is answered (or timeout). */722 800 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 723 801 return S_OK; … … 783 861 784 862 DnDGuestResponse *pResp = d->response(); 785 /* This blocks until the request is answered (or timeout). */786 863 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 787 864 return S_OK; … … 813 890 814 891 DnDGuestResponse *pResp = d->response(); 815 /* This blocks until the request is answered (or timeout). */816 892 pResp->waitForGuestResponse(); 817 893 } … … 873 949 874 950 DnDGuestResponse *pResp = d->response(); 875 /* This blocks until the request is answered (or timeout). */876 951 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) 877 952 return S_OK; 878 953 879 /* Copy the response info*/954 /* Get the resulting action from the guest. */ 880 955 *pResultAction = d->toMainAction(pResp->defAction()); 956 957 LogFlowFunc(("resFormat=%s, resAction=%RU32\n", 958 pResp->format().c_str(), pResp->defAction())); 959 881 960 Bstr(pResp->format()).cloneTo(pstrFormat); 882 883 LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));884 961 } 885 962 catch (HRESULT hr2) … … 957 1034 paParms); 958 1035 959 /* This blocks until the request is answered (or timed out). */960 1036 DnDGuestResponse *pResp = d->response(); 961 1037 if (pResp->waitForGuestResponse() == VERR_TIMEOUT) … … 1167 1243 pszPath, cbPath, fMode)); 1168 1244 1169 /** @todo Add file locking between calls! */ 1170 int rc; 1171 char *pszFile = RTPathJoinA(pResp->dropDir().c_str(), pszPath); 1172 if (pszFile) 1173 { 1174 RTFILE hFile; 1175 rc = RTFileOpen(&hFile, pszFile, 1176 RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE | RTFILE_O_WRITE); 1177 if (RT_SUCCESS(rc)) 1178 { 1179 rc = RTFileWrite(hFile, pvData, cbData, 1180 NULL /* No partial writes */); 1181 RTFileClose(hFile); 1182 } 1183 RTStrFree(pszFile); 1184 } 1185 else 1186 rc = VERR_NO_MEMORY; 1187 1188 if (RT_SUCCESS(rc)) 1189 rc = pResp->dataSetStatus(cbData); 1245 int rc = pResp->writeToFile(pszPath, cbPath, pvData, cbData, fMode); 1190 1246 1191 1247 LogFlowFuncLeaveRC(rc);
Note:
See TracChangeset
for help on using the changeset viewer.