Changeset 37375 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jun 8, 2011 10:51:26 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 72150
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r37244 r37375 8114 8114 <desc>No flag set.</desc> 8115 8115 </const> 8116 8117 8116 <const name="WaitForProcessStartOnly" value="1"> 8118 8117 <desc>Only use the specified timeout value to wait for starting the guest process - the guest 8119 8118 process itself then uses an infinite timeout.</desc> 8120 8119 </const> 8121 8122 8120 <const name="IgnoreOrphanedProcesses" value="2"> 8123 8121 <desc>Do not report an error when executed processes are still alive when VBoxService or the guest OS is shutting down.</desc> 8124 8122 </const> 8125 8126 8123 <const name="Hidden" value="4"> 8127 8124 <desc>Don't show the started process according to the guest OS guidelines.</desc> … … 8136 8133 Guest process execution status. 8137 8134 </desc> 8138 8139 8135 <const name="Undefined" value="0"> 8140 8136 <desc>Process is in an undefined state.</desc> … … 8144 8140 <desc>Process has been started.</desc> 8145 8141 </const> 8146 8147 8142 <const name="TerminatedNormally" value="2"> 8148 8143 <desc>Process terminated normally.</desc> 8149 8144 </const> 8150 8151 8145 <const name="TerminatedSignal" value="3"> 8152 8146 <desc>Process terminated via signal.</desc> 8153 8147 </const> 8154 8155 8148 <const name="TerminatedAbnormally" value="4"> 8156 8149 <desc>Process terminated abnormally.</desc> 8157 8150 </const> 8158 8159 8151 <const name="TimedOutKilled" value="5"> 8160 8152 <desc>Process timed out and was killed.</desc> 8161 8153 </const> 8162 8163 8154 <const name="TimedOutAbnormally" value="6"> 8164 8155 <desc>Process timed out and was not killed successfully.</desc> 8165 8156 </const> 8166 8167 8157 <const name="Down" value="7"> 8168 8158 <desc>Service/OS is stopping, process was killed.</desc> 8169 8159 </const> 8170 8171 8160 <const name="Error" value="8"> 8172 8161 <desc>Something went wrong (error code in flags).</desc> … … 8181 8170 Guest process input flags. 8182 8171 </desc> 8183 8184 8172 <const name="None" value="0"> 8185 8173 <desc>No flag set.</desc> 8186 8174 </const> 8187 8188 8175 <const name="EndOfFile" value="1"> 8189 8176 <desc>End of file (input) reached.</desc> … … 8199 8186 type of output to retrieve. 8200 8187 </desc> 8201 8202 8188 <const name="None" value="0"> 8203 8189 <desc>No flags set. Get output from stdout.</desc> 8204 8190 </const> 8205 8206 8191 <const name="StdErr" value="1"> 8207 8192 <desc>Get output from stderr.</desc> … … 8217 8202 are implemented. 8218 8203 </desc> 8219 8220 8204 <const name="None" value="0"> 8221 8205 <desc>No flag set.</desc> 8222 8206 </const> 8223 8224 8207 <const name="Recursive" value="1"> 8225 8208 <desc>Copy directories recursively.</desc> 8226 8209 </const> 8227 8228 8210 <const name="Update" value="2"> 8229 8211 <desc>Only copy when the source file is newer than the destination file or when the destination file is missing.</desc> 8230 8212 </const> 8231 8232 8213 <const name="FollowLinks" value="4"> 8233 8214 <desc>Follow symbolic links.</desc> … … 8236 8217 8237 8218 <enum 8238 name=" CreateDirectoryFlag"8239 uuid=" 26ff5bdd-c81f-4304-857b-b8be5e3f9cd6"8240 >8219 name="DirectoryCreateFlag" 8220 uuid="bd721b0e-ced5-4f79-b368-249897c32a36" 8221 > 8241 8222 <desc> 8242 8223 Directory creation flags. 8243 8224 </desc> 8244 8245 8225 <const name="None" value="0"> 8246 8226 <desc>No flag set.</desc> 8247 8227 </const> 8248 8249 8228 <const name="Parents" value="1"> 8250 8229 <desc>No error if existing, make parent directories as needed.</desc> … … 8252 8231 </enum> 8253 8232 8233 <enum 8234 name="DirectoryOpenFlag" 8235 uuid="fc8f6203-0072-4f34-bd08-0b35e50bf071" 8236 > 8237 <desc> 8238 Directory open flags. 8239 </desc> 8240 <const name="None" value="0"> 8241 <desc>No flag set.</desc> 8242 </const> 8243 </enum> 8244 8245 <enum 8246 name="GuestDirEntryType" 8247 uuid="6d19d924-1b77-4fc8-b369-a3b2c85c8241" 8248 > 8249 <desc> 8250 Guest directory entry type. 8251 </desc> 8252 <const name="Unknown" value="0"> 8253 <desc>Unknown.</desc> 8254 </const> 8255 <const name="Directory" value="4"> 8256 <desc>Regular file.</desc> 8257 </const> 8258 <const name="File" value="10"> 8259 <desc>Regular file.</desc> 8260 </const> 8261 <const name="Symlink" value="12"> 8262 <desc>Symbolic link.</desc> 8263 </const> 8264 </enum> 8265 8266 <interface 8267 name="IGuestDirEntry" extends="$unknown" 8268 uuid="20a66efc-c2f6-4438-826f-38454c04369e" 8269 wsmap="struct" 8270 > 8271 <desc> 8272 Structure representing a directory entry on the guest OS. 8273 </desc> 8274 <attribute name="nodeId" type="long long" readonly="yes"> 8275 <desc>The unique identifier (within the guest's file system) of this file system object.</desc> 8276 </attribute> 8277 <attribute name="name" type="wstring" readonly="yes"> 8278 <desc>The filename.</desc> 8279 </attribute> 8280 <attribute name="type" type="GuestDirEntryType" readonly="yes"> 8281 <desc>The entry type.</desc> 8282 </attribute> 8283 </interface> 8284 8254 8285 <interface 8255 8286 name="IGuest" extends="$unknown" 8256 uuid="4 e78f7dd-8ca1-47e5-a344-5207f793df71"8287 uuid="44637074-a613-48cd-9b5d-77117f971529" 8257 8288 wsmap="managed" 8258 8289 > … … 8507 8538 </desc> 8508 8539 </param> 8509 <param name="data" type="octet" dir="return" safearray="yes">8540 <param name="data" type="octet" safearray="yes" dir="return"> 8510 8541 <desc> 8511 8542 Buffer for retrieving the actual output. A data size of 0 means end of file … … 8549 8580 </method> 8550 8581 8582 <method name="copyFromGuest"> 8583 <desc> 8584 Copies files/directories from guest to the host. 8585 8586 <result name="VBOX_E_IPRT_ERROR"> 8587 Error while copying. 8588 </result> 8589 8590 </desc> 8591 <param name="source" type="wstring" dir="in"> 8592 <desc> 8593 Source file on the guest to copy. 8594 </desc> 8595 </param> 8596 <param name="dest" type="wstring" dir="in"> 8597 <desc> 8598 Destination path on the host. 8599 </desc> 8600 </param> 8601 <param name="userName" type="wstring" dir="in"> 8602 <desc> 8603 User name under which the copy command will be executed; the 8604 user has to exist and have the appropriate rights to read from 8605 the source path. 8606 </desc> 8607 </param> 8608 <param name="password" type="wstring" dir="in"> 8609 <desc> 8610 Password of the user account specified. 8611 </desc> 8612 </param> 8613 <param name="flags" type="unsigned long" dir="in"> 8614 <desc> 8615 <link to="CopyFileFlag"/> flags. Not used at the moment and should be set to 0. 8616 </desc> 8617 </param> 8618 <param name="progress" type="IProgress" dir="return"> 8619 <desc>Progress object to track the operation completion.</desc> 8620 </param> 8621 </method> 8622 8551 8623 <method name="copyToGuest"> 8552 8624 <desc> … … 8590 8662 </method> 8591 8663 8592 <method name="createDirectory"> 8664 <method name="directoryClose"> 8665 <desc> 8666 Closes a formerly opened guest directory. 8667 8668 <result name="VBOX_E_IPRT_ERROR"> 8669 Error while closing directory. 8670 </result> 8671 8672 </desc> 8673 <param name="handle" type="unsigned long" dir="in"> 8674 <desc> 8675 Handle of opened directory to close. 8676 </desc> 8677 </param> 8678 </method> 8679 8680 <method name="directoryCreate"> 8593 8681 <desc> 8594 8682 Creates a directory on the guest. … … 8623 8711 <param name="flags" type="unsigned long" dir="in"> 8624 8712 <desc> 8625 <link to="CreateDirectoryFlag"/> flags. 8626 </desc> 8627 </param> 8628 <param name="progress" type="IProgress" dir="return"> 8629 <desc>Progress object to track the operation completion.</desc> 8713 <link to="DirectoryCreateFlag"/> flags. 8714 </desc> 8715 </param> 8716 </method> 8717 8718 <method name="directoryOpen"> 8719 <desc> 8720 Opens a directory on the guest. 8721 8722 <result name="VBOX_E_IPRT_ERROR"> 8723 Error while opening / reading directory. 8724 </result> 8725 8726 </desc> 8727 <param name="directory" type="wstring" dir="in"> 8728 <desc> 8729 Directory to read. 8730 </desc> 8731 </param> 8732 <param name="filter" type="wstring" dir="in"> 8733 <desc> 8734 Directory filter (DOS style wildcards). Set to empty 8735 string if no filter required. 8736 </desc> 8737 </param> 8738 <param name="flags" type="unsigned long" dir="in"> 8739 <desc> 8740 <link to="DirectoryOpenFlag"/> flags. 8741 </desc> 8742 </param> 8743 <param name="userName" type="wstring" dir="in"> 8744 <desc> 8745 User name under which the directory reading will be performed; the 8746 user has to exist and have the appropriate rights to access / read the 8747 desired directory. 8748 </desc> 8749 </param> 8750 <param name="password" type="wstring" dir="in"> 8751 <desc> 8752 Password of the user account specified. 8753 </desc> 8754 </param> 8755 <param name="handle" type="unsigned long" dir="out"> 8756 <desc> 8757 Handle of opened directory returned by openDirectory. 8758 </desc> 8759 </param> 8760 </method> 8761 8762 <method name="directoryRead"> 8763 <desc> 8764 Reads the next directory entry of an opened guest directory. 8765 8766 <result name="VBOX_E_IPRT_ERROR"> 8767 Error while opening / reading directory. 8768 </result> 8769 8770 </desc> 8771 <param name="handle" type="unsigned long" dir="in"> 8772 <desc> 8773 Handle of opened directory returned by openDirectory. 8774 </desc> 8775 </param> 8776 <param name="entry" type="IGuestDirEntry" dir="out"> 8777 <desc> 8778 Information about next directory entry on success. 8779 </desc> 8780 </param> 8781 </method> 8782 8783 <method name="fileExists"> 8784 <desc> 8785 Checks if the specified file name exists and is a regular file. 8786 8787 <result name="VBOX_E_IPRT_ERROR"> 8788 Error while looking up information. 8789 </result> 8790 8791 </desc> 8792 <param name="file" type="wstring" dir="in"> 8793 <desc> 8794 Full path of file to check. 8795 </desc> 8796 </param> 8797 <param name="userName" type="wstring" dir="in"> 8798 <desc> 8799 User name under which the lookup will be performed; the 8800 user has to exist and have the appropriate rights to access / read the 8801 desired directory. 8802 </desc> 8803 </param> 8804 <param name="password" type="wstring" dir="in"> 8805 <desc> 8806 Password of the user account specified. 8807 </desc> 8808 </param> 8809 <param name="exists" type="boolean" dir="out"> 8810 <desc> 8811 True if it's a regular file, false if it isn't (or doesn't exist). 8812 </desc> 8630 8813 </param> 8631 8814 </method> … … 8905 9088 this progress. This means sub-operation number, description, percent 8906 9089 and so on. 8907 9090 8908 9091 You have to take care on setting up at least the same count on 8909 9092 sub-operations in this progress object like there are in the other 8910 progress object. 9093 progress object. 8911 9094 8912 9095 If the other progress object supports cancel and this object gets any -
trunk/src/VBox/Main/include/GuestImpl.h
r36102 r37375 88 88 STDMETHOD(SetCredentials)(IN_BSTR aUserName, IN_BSTR aPassword, 89 89 IN_BSTR aDomain, BOOL aAllowInteractiveLogon); 90 // Process execution 90 91 STDMETHOD(ExecuteProcess)(IN_BSTR aCommand, ULONG aFlags, 91 92 ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment), … … 95 96 STDMETHOD(SetProcessInput)(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, ComSafeArrayIn(BYTE, aData), ULONG *aBytesWritten); 96 97 STDMETHOD(GetProcessStatus)(ULONG aPID, ULONG *aExitCode, ULONG *aFlags, ExecuteProcessStatus_T *aStatus); 98 // File copying 99 STDMETHOD(CopyFromGuest)(IN_BSTR aSource, IN_BSTR aDest, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aFlags, IProgress **aProgress); 97 100 STDMETHOD(CopyToGuest)(IN_BSTR aSource, IN_BSTR aDest, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aFlags, IProgress **aProgress); 98 STDMETHOD(CreateDirectory)(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aMode, ULONG aFlags, IProgress **aProgress); 101 // Directory handling 102 STDMETHOD(DirectoryClose)(ULONG aHandle); 103 STDMETHOD(DirectoryCreate)(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aMode, ULONG aFlags); 104 STDMETHOD(DirectoryOpen)(IN_BSTR aDirectory, IN_BSTR aFilter, 105 ULONG aFlags, IN_BSTR aUserName, IN_BSTR aPassword, ULONG *aHandle); 106 STDMETHOD(DirectoryRead)(ULONG aHandle, IGuestDirEntry **aDirEntry); 107 // File handling 108 STDMETHOD(FileExists)(IN_BSTR aFile, IN_BSTR aUserName, IN_BSTR aPassword, BOOL *aExists); 109 // Misc stuff 99 110 STDMETHOD(InternalGetStatistics)(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle, 100 111 ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache, … … 107 118 IN_BSTR aUserName, IN_BSTR aPassword, 108 119 ULONG aTimeoutMS, ULONG *aPID, IProgress **aProgress, int *pRC); 109 HRESULT createDirectoryInternal(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword,110 ULONG aMode, ULONG aFlags, IProgress **aProgress,int *pRC);120 HRESULT directoryCreateInternal(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, 121 ULONG aMode, ULONG aFlags, int *pRC); 111 122 void setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType); 112 123 void setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision); … … 131 142 // Internal tasks. 132 143 struct TaskGuest; /* Worker thread helper. */ 133 HRESULT taskCopyFile(TaskGuest *aTask); 144 HRESULT taskCopyFileToGuest(TaskGuest *aTask); 145 HRESULT taskCopyFileFromGuest(TaskGuest *aTask); 134 146 HRESULT taskUpdateGuestAdditions(TaskGuest *aTask); 135 147 -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r36887 r37375 45 45 enum TaskType 46 46 { 47 /** Copies a file to the guest. */ 48 CopyFile = 50, 47 /** Copies a file from host to the guest. */ 48 CopyFileToGuest = 50, 49 /** Copies a file from guest to the host. */ 50 CopyFileFromGuest = 55, 49 51 50 52 /** Update Guest Additions by directly copying the required installer … … 60 62 rc(S_OK) 61 63 {} 62 ~TaskGuest() {}64 virtual ~TaskGuest() {} 63 65 64 66 int startThread(); … … 110 112 { 111 113 #ifdef VBOX_WITH_GUEST_CONTROL 112 case TaskGuest::CopyFile: 113 { 114 rc = pGuest->taskCopyFile(task.get()); 114 case TaskGuest::CopyFileToGuest: 115 { 116 rc = pGuest->taskCopyFileToGuest(task.get()); 117 break; 118 } 119 case TaskGuest::CopyFileFromGuest: 120 { 121 rc = pGuest->taskCopyFileFromGuest(task.get()); 115 122 break; 116 123 } … … 182 189 183 190 #ifdef VBOX_WITH_GUEST_CONTROL 184 HRESULT Guest::taskCopyFile (TaskGuest *aTask)191 HRESULT Guest::taskCopyFileToGuest(TaskGuest *aTask) 185 192 { 186 193 LogFlowFuncEnter(); … … 458 465 } 459 466 467 HRESULT Guest::taskCopyFileFromGuest(TaskGuest *aTask) 468 { 469 LogFlowFuncEnter(); 470 471 AutoCaller autoCaller(this); 472 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 473 474 /* 475 * Do *not* take a write lock here since we don't (and won't) 476 * touch any class-specific data (of IGuest) here - only the member functions 477 * which get called here can do that. 478 */ 479 480 HRESULT rc = S_OK; 481 482 try 483 { 484 Guest *pGuest = aTask->pGuest; 485 AssertPtr(pGuest); 486 487 488 489 #if 0 490 /* Does our source file exist? */ 491 if (!RTFileExists(aTask->strSource.c_str())) 492 { 493 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 494 Guest::tr("Source file \"%s\" does not exist, or is not a file"), 495 aTask->strSource.c_str()); 496 } 497 else 498 { 499 RTFILE fileSource; 500 int vrc = RTFileOpen(&fileSource, aTask->strSource.c_str(), 501 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE); 502 if (RT_FAILURE(vrc)) 503 { 504 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 505 Guest::tr("Could not open source file \"%s\" for reading (%Rrc)"), 506 aTask->strSource.c_str(), vrc); 507 } 508 else 509 { 510 uint64_t cbSize; 511 vrc = RTFileGetSize(fileSource, &cbSize); 512 if (RT_FAILURE(vrc)) 513 { 514 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 515 Guest::tr("Could not query file size of \"%s\" (%Rrc)"), 516 aTask->strSource.c_str(), vrc); 517 } 518 else 519 { 520 com::SafeArray<IN_BSTR> args; 521 com::SafeArray<IN_BSTR> env; 522 523 /* 524 * Prepare tool command line. 525 */ 526 char szOutput[RTPATH_MAX]; 527 if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", aTask->strDest.c_str()) <= sizeof(szOutput) - 1) 528 { 529 /* 530 * Normalize path slashes, based on the detected guest. 531 */ 532 Utf8Str osType = mData.mOSTypeId; 533 if ( osType.contains("Microsoft", Utf8Str::CaseInsensitive) 534 || osType.contains("Windows", Utf8Str::CaseInsensitive)) 535 { 536 /* We have a Windows guest. */ 537 RTPathChangeToDosSlashes(szOutput, true /* Force conversion. */); 538 } 539 else /* ... or something which isn't from Redmond ... */ 540 { 541 RTPathChangeToUnixSlashes(szOutput, true /* Force conversion. */); 542 } 543 544 args.push_back(Bstr(szOutput).raw()); /* We want to write a file ... */ 545 } 546 else 547 { 548 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 549 Guest::tr("Error preparing command line")); 550 } 551 552 ComPtr<IProgress> execProgress; 553 ULONG uPID; 554 if (SUCCEEDED(rc)) 555 { 556 LogRel(("Copying file \"%s\" to guest \"%s\" (%u bytes) ...\n", 557 aTask->strSource.c_str(), aTask->strDest.c_str(), cbSize)); 558 /* 559 * Okay, since we gathered all stuff we need until now to start the 560 * actual copying, start the guest part now. 561 */ 562 rc = pGuest->ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(), 563 ExecuteProcessFlag_Hidden 564 | ExecuteProcessFlag_WaitForProcessStartOnly, 565 ComSafeArrayAsInParam(args), 566 ComSafeArrayAsInParam(env), 567 Bstr(aTask->strUserName).raw(), 568 Bstr(aTask->strPassword).raw(), 569 5 * 1000 /* Wait 5s for getting the process started. */, 570 &uPID, execProgress.asOutParam()); 571 if (FAILED(rc)) 572 rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest); 573 } 574 575 if (SUCCEEDED(rc)) 576 { 577 BOOL fCompleted = FALSE; 578 BOOL fCanceled = FALSE; 579 580 size_t cbToRead = cbSize; 581 size_t cbTransfered = 0; 582 size_t cbRead; 583 SafeArray<BYTE> aInputData(_64K); 584 while ( SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted))) 585 && !fCompleted) 586 { 587 if (!cbToRead) 588 cbRead = 0; 589 else 590 { 591 vrc = RTFileRead(fileSource, (uint8_t*)aInputData.raw(), 592 RT_MIN(cbToRead, _64K), &cbRead); 593 /* 594 * Some other error occured? There might be a chance that RTFileRead 595 * could not resolve/map the native error code to an IPRT code, so just 596 * print a generic error. 597 */ 598 if (RT_FAILURE(vrc)) 599 { 600 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 601 Guest::tr("Could not read from file \"%s\" (%Rrc)"), 602 aTask->strSource.c_str(), vrc); 603 break; 604 } 605 } 606 607 /* Resize buffer to reflect amount we just have read. 608 * Size 0 is allowed! */ 609 aInputData.resize(cbRead); 610 611 ULONG uFlags = ProcessInputFlag_None; 612 /* Did we reach the end of the content we want to transfer (last chunk)? */ 613 if ( (cbRead < _64K) 614 /* Did we reach the last block which is exactly _64K? */ 615 || (cbToRead - cbRead == 0) 616 /* ... or does the user want to cancel? */ 617 || ( SUCCEEDED(aTask->progress->COMGETTER(Canceled(&fCanceled))) 618 && fCanceled) 619 ) 620 { 621 uFlags |= ProcessInputFlag_EndOfFile; 622 } 623 624 /* Transfer the current chunk ... */ 625 ULONG uBytesWritten; 626 rc = pGuest->SetProcessInput(uPID, uFlags, 627 10 * 1000 /* Wait 10s for getting the input data transfered. */, 628 ComSafeArrayAsInParam(aInputData), &uBytesWritten); 629 if (FAILED(rc)) 630 { 631 rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest); 632 break; 633 } 634 635 Assert(cbRead <= cbToRead); 636 Assert(cbToRead >= cbRead); 637 cbToRead -= cbRead; 638 639 cbTransfered += uBytesWritten; 640 Assert(cbTransfered <= cbSize); 641 aTask->progress->SetCurrentOperationProgress(cbTransfered / (cbSize / 100.0)); 642 643 /* End of file reached? */ 644 if (cbToRead == 0) 645 break; 646 647 /* Did the user cancel the operation above? */ 648 if (fCanceled) 649 break; 650 651 /* Progress canceled by Main API? */ 652 if ( SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled))) 653 && fCanceled) 654 { 655 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 656 Guest::tr("Copy operation of file \"%s\" was canceled on guest side"), 657 aTask->strSource.c_str()); 658 break; 659 } 660 } 661 662 if (SUCCEEDED(rc)) 663 { 664 /* 665 * If we got here this means the started process either was completed, 666 * canceled or we simply got all stuff transferred. 667 */ 668 ExecuteProcessStatus_T retStatus; 669 ULONG uRetExitCode; 670 rc = pGuest->waitForProcessStatusChange(uPID, &retStatus, &uRetExitCode, 10 * 1000 /* 10s timeout. */); 671 if (FAILED(rc)) 672 { 673 rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest); 674 } 675 else 676 { 677 if ( uRetExitCode != 0 678 || retStatus != ExecuteProcessStatus_TerminatedNormally) 679 { 680 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 681 Guest::tr("Guest reported error %u while copying file \"%s\" to \"%s\""), 682 uRetExitCode, aTask->strSource.c_str(), aTask->strDest.c_str()); 683 } 684 } 685 } 686 687 if (SUCCEEDED(rc)) 688 { 689 if (fCanceled) 690 { 691 /* 692 * In order to make the progress object to behave nicely, we also have to 693 * notify the object with a complete event when it's canceled. 694 */ 695 aTask->progress->notifyComplete(VBOX_E_IPRT_ERROR, 696 COM_IIDOF(IGuest), 697 Guest::getStaticComponentName(), 698 Guest::tr("Copying file \"%s\" canceled"), aTask->strSource.c_str()); 699 } 700 else 701 { 702 /* 703 * Even if we succeeded until here make sure to check whether we really transfered 704 * everything. 705 */ 706 if ( cbSize > 0 707 && cbTransfered == 0) 708 { 709 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 710 * to the destination -> access denied. */ 711 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 712 Guest::tr("Access denied when copying file \"%s\" to \"%s\""), 713 aTask->strSource.c_str(), aTask->strDest.c_str()); 714 } 715 else if (cbTransfered < cbSize) 716 { 717 /* If we did not copy all let the user know. */ 718 rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress, 719 Guest::tr("Copying file \"%s\" failed (%u/%u bytes transfered)"), 720 aTask->strSource.c_str(), cbTransfered, cbSize); 721 } 722 else /* Yay, all went fine! */ 723 aTask->progress->notifyComplete(S_OK); 724 } 725 } 726 } 727 } 728 RTFileClose(fileSource); 729 } 730 } 731 #endif 732 } 733 catch (HRESULT aRC) 734 { 735 rc = aRC; 736 } 737 738 /* Clean up */ 739 aTask->rc = rc; 740 741 LogFlowFunc(("rc=%Rhrc\n", rc)); 742 LogFlowFuncLeave(); 743 744 return VINF_SUCCESS; 745 } 746 460 747 HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask) 461 748 { … … 945 1232 AssertPtr(pCBData); 946 1233 AssertReturn(sizeof(CALLBACKDATACLIENTDISCONNECTED) == cbParms, VERR_INVALID_PARAMETER); 947 AssertReturn(CALLBACKDATAMAGIC CLIENTDISCONNECTED == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);1234 AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 948 1235 949 1236 rc = pGuest->notifyCtrlClientDisconnected(u32Function, pCBData); … … 958 1245 AssertPtr(pCBData); 959 1246 AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbParms, VERR_INVALID_PARAMETER); 960 AssertReturn(CALLBACKDATAMAGIC EXECSTATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);1247 AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 961 1248 962 1249 rc = pGuest->notifyCtrlExecStatus(u32Function, pCBData); … … 971 1258 AssertPtr(pCBData); 972 1259 AssertReturn(sizeof(CALLBACKDATAEXECOUT) == cbParms, VERR_INVALID_PARAMETER); 973 AssertReturn(CALLBACKDATAMAGIC EXECOUT == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);1260 AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 974 1261 975 1262 rc = pGuest->notifyCtrlExecOut(u32Function, pCBData); … … 984 1271 AssertPtr(pCBData); 985 1272 AssertReturn(sizeof(CALLBACKDATAEXECINSTATUS) == cbParms, VERR_INVALID_PARAMETER); 986 AssertReturn(CALLBACKDATAMAGIC EXECINSTATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);1273 AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER); 987 1274 988 1275 rc = pGuest->notifyCtrlExecInStatus(u32Function, pCBData); … … 1636 1923 paParms[i++].setUInt32(aTimeoutMS); 1637 1924 1638 VMMDev * vmmDev;1925 VMMDev *pVMMDev = NULL; 1639 1926 { 1640 1927 /* Make sure mParent is valid, so set the read lock while using. … … 1645 1932 /* Forward the information to the VMM device. */ 1646 1933 AssertPtr(mParent); 1647 vmmDev = mParent->getVMMDev();1934 pVMMDev = mParent->getVMMDev(); 1648 1935 } 1649 1936 1650 if ( vmmDev)1937 if (pVMMDev) 1651 1938 { 1652 1939 LogFlowFunc(("hgcmHostCall numParms=%d\n", i)); 1653 vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,1940 vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD, 1654 1941 i, paParms); 1655 1942 } … … 1917 2204 1918 2205 { 1919 VMMDev * vmmDev;2206 VMMDev *pVMMDev = NULL; 1920 2207 { 1921 2208 /* Make sure mParent is valid, so set the read lock while using. … … 1926 2213 /* Forward the information to the VMM device. */ 1927 2214 AssertPtr(mParent); 1928 vmmDev = mParent->getVMMDev();2215 pVMMDev = mParent->getVMMDev(); 1929 2216 } 1930 2217 1931 if ( vmmDev)2218 if (pVMMDev) 1932 2219 { 1933 2220 LogFlowFunc(("hgcmHostCall numParms=%d\n", i)); 1934 vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_SET_INPUT,2221 vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_SET_INPUT, 1935 2222 i, paParms); 1936 2223 } … … 2093 2380 2094 2381 { 2095 VMMDev * vmmDev;2382 VMMDev *pVMMDev = NULL; 2096 2383 { 2097 2384 /* Make sure mParent is valid, so set the read lock while using. … … 2102 2389 /* Forward the information to the VMM device. */ 2103 2390 AssertPtr(mParent); 2104 vmmDev = mParent->getVMMDev();2391 pVMMDev = mParent->getVMMDev(); 2105 2392 } 2106 2393 2107 if ( vmmDev)2394 if (pVMMDev) 2108 2395 { 2109 2396 LogFlowFunc(("hgcmHostCall numParms=%d\n", i)); 2110 vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_GET_OUTPUT,2397 vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_GET_OUTPUT, 2111 2398 i, paParms); 2112 2399 } … … 2268 2555 } 2269 2556 2270 STDMETHODIMP Guest::Copy ToGuest(IN_BSTR aSource, IN_BSTR aDest,2271 IN_BSTR aUserName, IN_BSTR aPassword,2272 ULONG aFlags, IProgress **aProgress)2557 STDMETHODIMP Guest::CopyFromGuest(IN_BSTR aSource, IN_BSTR aDest, 2558 IN_BSTR aUserName, IN_BSTR aPassword, 2559 ULONG aFlags, IProgress **aProgress) 2273 2560 { 2274 2561 #ifndef VBOX_WITH_GUEST_CONTROL … … 2306 2593 2307 2594 rc = progress->init(static_cast<IGuest*>(this), 2308 Bstr(tr("Copying file ")).raw(),2595 Bstr(tr("Copying file from guest to host")).raw(), 2309 2596 TRUE /* aCancelable */); 2310 2597 if (FAILED(rc)) throw rc; 2311 2598 2312 2599 /* Initialize our worker task. */ 2313 TaskGuest *pTask = new TaskGuest(TaskGuest::CopyFile, this, progress); 2600 TaskGuest *pTask = new TaskGuest(TaskGuest::CopyFileFromGuest, this, progress); 2601 AssertPtr(pTask); 2602 std::auto_ptr<TaskGuest> task(pTask); 2603 2604 /* Assign data - aSource is the source file on the guest, 2605 * aDest reflects the full path on the host. */ 2606 task->strSource = (Utf8Str(aSource)); 2607 task->strDest = (Utf8Str(aDest)); 2608 task->strUserName = (Utf8Str(aUserName)); 2609 task->strPassword = (Utf8Str(aPassword)); 2610 task->uFlags = aFlags; 2611 2612 rc = task->startThread(); 2613 if (FAILED(rc)) throw rc; 2614 2615 /* Don't destruct on success. */ 2616 task.release(); 2617 } 2618 catch (HRESULT aRC) 2619 { 2620 rc = aRC; 2621 } 2622 2623 if (SUCCEEDED(rc)) 2624 { 2625 /* Return progress to the caller. */ 2626 progress.queryInterfaceTo(aProgress); 2627 } 2628 return rc; 2629 #endif /* VBOX_WITH_GUEST_CONTROL */ 2630 } 2631 2632 STDMETHODIMP Guest::CopyToGuest(IN_BSTR aSource, IN_BSTR aDest, 2633 IN_BSTR aUserName, IN_BSTR aPassword, 2634 ULONG aFlags, IProgress **aProgress) 2635 { 2636 #ifndef VBOX_WITH_GUEST_CONTROL 2637 ReturnComNotImplemented(); 2638 #else /* VBOX_WITH_GUEST_CONTROL */ 2639 CheckComArgStrNotEmptyOrNull(aSource); 2640 CheckComArgStrNotEmptyOrNull(aDest); 2641 CheckComArgStrNotEmptyOrNull(aUserName); 2642 CheckComArgStrNotEmptyOrNull(aPassword); 2643 CheckComArgOutPointerValid(aProgress); 2644 2645 AutoCaller autoCaller(this); 2646 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2647 2648 /* Validate flags. */ 2649 if (aFlags != CopyFileFlag_None) 2650 { 2651 if ( !(aFlags & CopyFileFlag_Recursive) 2652 && !(aFlags & CopyFileFlag_Update) 2653 && !(aFlags & CopyFileFlag_FollowLinks)) 2654 { 2655 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); 2656 } 2657 } 2658 2659 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 2660 2661 HRESULT rc = S_OK; 2662 2663 ComObjPtr<Progress> progress; 2664 try 2665 { 2666 /* Create the progress object. */ 2667 progress.createObject(); 2668 2669 rc = progress->init(static_cast<IGuest*>(this), 2670 Bstr(tr("Copying file from host to guest")).raw(), 2671 TRUE /* aCancelable */); 2672 if (FAILED(rc)) throw rc; 2673 2674 /* Initialize our worker task. */ 2675 TaskGuest *pTask = new TaskGuest(TaskGuest::CopyFileToGuest, this, progress); 2314 2676 AssertPtr(pTask); 2315 2677 std::auto_ptr<TaskGuest> task(pTask); … … 2343 2705 } 2344 2706 2345 STDMETHODIMP Guest::CreateDirectory(IN_BSTR aDirectory, 2707 STDMETHODIMP Guest::DirectoryClose(ULONG aHandle) 2708 { 2709 #ifndef VBOX_WITH_GUEST_CONTROL 2710 ReturnComNotImplemented(); 2711 #else /* VBOX_WITH_GUEST_CONTROL */ 2712 using namespace guestControl; 2713 2714 return VBOX_E_NOT_SUPPORTED; 2715 #endif 2716 } 2717 2718 STDMETHODIMP Guest::DirectoryCreate(IN_BSTR aDirectory, 2346 2719 IN_BSTR aUserName, IN_BSTR aPassword, 2347 ULONG aMode, ULONG aFlags, 2348 IProgress **aProgress) 2720 ULONG aMode, ULONG aFlags) 2349 2721 { 2350 2722 #ifndef VBOX_WITH_GUEST_CONTROL … … 2362 2734 Utf8Str(aDirectory).c_str(), Utf8Str(aUserName).c_str())); 2363 2735 2364 return createDirectoryInternal(aDirectory,2736 return directoryCreateInternal(aDirectory, 2365 2737 aUserName, aPassword, 2366 aMode, aFlags, aProgress,NULL /* rc */);2738 aMode, aFlags, NULL /* rc */); 2367 2739 #endif 2368 2740 } 2369 2741 2370 HRESULT Guest:: createDirectoryInternal(IN_BSTR aDirectory,2742 HRESULT Guest::directoryCreateInternal(IN_BSTR aDirectory, 2371 2743 IN_BSTR aUserName, IN_BSTR aPassword, 2372 ULONG aMode, ULONG aFlags, 2373 IProgress **aProgress, int *pRC) 2744 ULONG aMode, ULONG aFlags, int *pRC) 2374 2745 { 2375 2746 #ifndef VBOX_WITH_GUEST_CONTROL … … 2379 2750 2380 2751 CheckComArgStrNotEmptyOrNull(aDirectory); 2381 CheckComArgOutPointerValid(aProgress);2382 2752 2383 2753 AutoCaller autoCaller(this); … … 2385 2755 2386 2756 /* Validate flags. */ 2387 if (aFlags != CreateDirectoryFlag_None)2388 { 2389 if (!(aFlags & CreateDirectoryFlag_Parents))2757 if (aFlags != DirectoryCreateFlag_None) 2758 { 2759 if (!(aFlags & DirectoryCreateFlag_Parents)) 2390 2760 { 2391 2761 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); 2392 2762 } 2393 2763 } 2394 2395 /**2396 * @todo We return a progress object because we maybe later want to2397 * process more than one directory (or somewhat lengthly operations)2398 * that require having a progress object provided to the caller.2399 */2400 2764 2401 2765 HRESULT rc = S_OK; … … 2412 2776 * Prepare tool command line. 2413 2777 */ 2414 if (aFlags & CreateDirectoryFlag_Parents)2778 if (aFlags & DirectoryCreateFlag_Parents) 2415 2779 args.push_back(Bstr("--parents").raw()); /* We also want to create the parent directories. */ 2416 2780 if (aMode > 0) … … 2444 2808 { 2445 2809 /* Wait for process to exit ... */ 2810 rc = progressExec->WaitForCompletion(-1); 2811 if (FAILED(rc)) return rc; 2812 2446 2813 BOOL fCompleted = FALSE; 2447 2814 BOOL fCanceled = FALSE; 2448 2449 while ( SUCCEEDED(progressExec->COMGETTER(Completed(&fCompleted))) 2450 && !fCompleted) 2451 { 2452 /* Progress canceled by Main API? */ 2453 if ( SUCCEEDED(progressExec->COMGETTER(Canceled(&fCanceled))) 2454 && fCanceled) 2455 { 2456 break; 2457 } 2458 } 2459 2460 ComObjPtr<Progress> progressCreate; 2461 rc = progressCreate.createObject(); 2462 if (SUCCEEDED(rc)) 2463 { 2464 rc = progressCreate->init(static_cast<IGuest*>(this), 2465 Bstr(tr("Creating directory")).raw(), 2466 TRUE); 2467 } 2468 if (FAILED(rc)) return rc; 2815 progressExec->COMGETTER(Completed)(&fCompleted); 2816 if (!fCompleted) 2817 progressExec->COMGETTER(Canceled)(&fCanceled); 2469 2818 2470 2819 if (fCompleted) … … 2478 2827 { 2479 2828 rc = setError(VBOX_E_IPRT_ERROR, 2480 tr("Error %u while creating directory"), uRetExitCode);2829 tr("Error %u while creating guest directory"), uRetExitCode); 2481 2830 } 2482 2831 } … … 2484 2833 else if (fCanceled) 2485 2834 rc = setError(VBOX_E_IPRT_ERROR, 2486 tr("Directory creation was aborted"));2835 tr("Guest directory creation was aborted")); 2487 2836 else 2488 AssertReleaseMsgFailed(("Directory creation neither completed nor canceled!?")); 2489 2490 if (SUCCEEDED(rc)) 2491 progressCreate->notifyComplete(S_OK); 2492 else 2493 progressCreate->notifyComplete(VBOX_E_IPRT_ERROR, 2494 COM_IIDOF(IGuest), 2495 Guest::getStaticComponentName(), 2496 Guest::tr("Error while executing creation command")); 2497 2498 /* Return the progress to the caller. */ 2499 progressCreate.queryInterfaceTo(aProgress); 2837 AssertReleaseMsgFailed(("Guest directory creation neither completed nor canceled!?")); 2500 2838 } 2501 2839 } … … 2506 2844 return rc; 2507 2845 #endif /* VBOX_WITH_GUEST_CONTROL */ 2846 } 2847 2848 STDMETHODIMP Guest::DirectoryOpen(IN_BSTR aDirectory, IN_BSTR aFilter, 2849 ULONG aFlags, IN_BSTR aUserName, IN_BSTR aPassword, 2850 ULONG *aHandle) 2851 { 2852 #ifndef VBOX_WITH_GUEST_CONTROL 2853 ReturnComNotImplemented(); 2854 #else /* VBOX_WITH_GUEST_CONTROL */ 2855 using namespace guestControl; 2856 2857 CheckComArgStrNotEmptyOrNull(aDirectory); 2858 CheckComArgStrNotEmptyOrNull(aUserName); 2859 CheckComArgStrNotEmptyOrNull(aPassword); 2860 CheckComArgNotNull(aHandle); 2861 2862 AutoCaller autoCaller(this); 2863 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2864 2865 /* Validate flags. */ 2866 if (aFlags != DirectoryOpenFlag_None) 2867 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); 2868 2869 HRESULT rc = S_OK; 2870 try 2871 { 2872 Utf8Str Utf8Dir(aDirectory); 2873 Utf8Str UtfFilter(aFilter); 2874 Utf8Str Utf8UserName(aUserName); 2875 Utf8Str Utf8Password(aPassword); 2876 2877 /* 2878 * Create progress object. 2879 * This progress object, compared to the one in executeProgress() above 2880 * is only local and is used to determine whether the operation finished 2881 * or got canceled. 2882 */ 2883 ComObjPtr <Progress> progress; 2884 rc = progress.createObject(); 2885 if (SUCCEEDED(rc)) 2886 { 2887 rc = progress->init(static_cast<IGuest*>(this), 2888 Bstr(tr("Getting output of process")).raw(), 2889 TRUE /* Cancelable */); 2890 } 2891 if (FAILED(rc)) return rc; 2892 2893 PCALLBACKDATADIROPEN pData = (PCALLBACKDATADIROPEN)RTMemAlloc(sizeof(CALLBACKDATADIROPEN)); 2894 AssertReturn(pData, VBOX_E_IPRT_ERROR); 2895 RT_ZERO(*pData); 2896 uint32_t uContextID = addCtrlCallbackContext(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START, 2897 pData, sizeof(CALLBACKDATADIROPEN), progress); 2898 Assert(uContextID > 0); 2899 2900 VBOXHGCMSVCPARM paParms[8]; 2901 int i = 0; 2902 paParms[i++].setUInt32(uContextID); 2903 paParms[i++].setPointer((void*)Utf8Dir.c_str(), (uint32_t)Utf8Dir.length() + 1); 2904 paParms[i++].setPointer((void*)UtfFilter.c_str(), (uint32_t)UtfFilter.length() + 1); 2905 paParms[i++].setUInt32(0 /* Flags, none set yet */); 2906 paParms[i++].setPointer((void*)Utf8UserName.c_str(), (uint32_t)Utf8UserName.length() + 1); 2907 paParms[i++].setPointer((void*)Utf8Password.c_str(), (uint32_t)Utf8Password.length() + 1); 2908 2909 int vrc = VINF_SUCCESS; 2910 { 2911 VMMDev *pVMMDev = NULL; 2912 { 2913 /* Make sure mParent is valid, so set the read lock while using. 2914 * Do not keep this lock while doing the actual call, because in the meanwhile 2915 * another thread could request a write lock which would be a bad idea ... */ 2916 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 2917 2918 /* Forward the information to the VMM device. */ 2919 AssertPtr(mParent); 2920 pVMMDev = mParent->getVMMDev(); 2921 } 2922 2923 if (pVMMDev) 2924 { 2925 LogFlowFunc(("hgcmHostCall numParms=%d\n", i)); 2926 vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_DIR_OPEN, 2927 i, paParms); 2928 } 2929 } 2930 2931 if (RT_SUCCESS(vrc)) 2932 { 2933 /* 2934 * Wait for the HGCM low level callback until the process 2935 * has been started (or something went wrong). This is necessary to 2936 * get the PID. 2937 */ 2938 CallbackMapIter it = getCtrlCallbackContextByID(uContextID); 2939 Assert(it != mCallbackMap.end()); 2940 ComAssert(!it->second.pProgress.isNull()); 2941 2942 BOOL fCanceled = FALSE; 2943 2944 /* Wait until operation completed. */ 2945 rc = it->second.pProgress->WaitForCompletion(10 * 1000); 2946 if (FAILED(rc)) throw rc; 2947 2948 /* Was the operation canceled by one of the parties? */ 2949 rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled); 2950 if (FAILED(rc)) throw rc; 2951 2952 if (!fCanceled) 2953 { 2954 BOOL fCompleted; 2955 if ( SUCCEEDED(it->second.pProgress->COMGETTER(Completed)(&fCompleted)) 2956 && fCompleted) 2957 { 2958 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 2959 2960 /* Did we get some output? */ 2961 pData = (PCALLBACKDATADIROPEN)it->second.pvData; 2962 Assert(it->second.cbData == sizeof(PCALLBACKDATADIROPEN)); 2963 AssertPtr(pData); 2964 } 2965 else /* If callback not called within time ... well, that's a timeout! */ 2966 vrc = VERR_TIMEOUT; 2967 } 2968 else /* Operation was canceled. */ 2969 { 2970 vrc = VERR_CANCELLED; 2971 } 2972 2973 if (RT_FAILURE(vrc)) 2974 { 2975 if (vrc == VERR_NO_DATA) 2976 { 2977 /* If there was no output data then this is no error we want 2978 * to report to COM. The caller just gets back a size of 0 (zero). */ 2979 rc = S_OK; 2980 } 2981 else if (vrc == VERR_TIMEOUT) 2982 { 2983 rc = setError(VBOX_E_IPRT_ERROR, 2984 tr("The guest did not output within time")); 2985 } 2986 else if (vrc == VERR_CANCELLED) 2987 { 2988 rc = setError(VBOX_E_IPRT_ERROR, 2989 tr("The output operation was canceled")); 2990 } 2991 else 2992 { 2993 rc = setError(E_UNEXPECTED, 2994 tr("The service call failed with error %Rrc"), vrc); 2995 } 2996 } 2997 2998 { 2999 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3000 /* Destroy locally used progress object. */ 3001 destroyCtrlCallbackContext(it); 3002 } 3003 } 3004 else /* HGCM operation failed. */ 3005 rc = setError(E_UNEXPECTED, 3006 tr("The HGCM call failed with error %Rrc"), vrc); 3007 3008 /* Cleanup. */ 3009 progress->uninit(); 3010 progress.setNull(); 3011 } 3012 catch (std::bad_alloc &) 3013 { 3014 rc = E_OUTOFMEMORY; 3015 } 3016 return rc; 3017 #endif 3018 } 3019 3020 STDMETHODIMP Guest::DirectoryRead(ULONG aHandle, IGuestDirEntry **aDirEntry) 3021 { 3022 #ifndef VBOX_WITH_GUEST_CONTROL 3023 ReturnComNotImplemented(); 3024 #else /* VBOX_WITH_GUEST_CONTROL */ 3025 using namespace guestControl; 3026 3027 return VBOX_E_NOT_SUPPORTED; 3028 #endif 3029 } 3030 3031 STDMETHODIMP Guest::FileExists(IN_BSTR aFile, IN_BSTR aUserName, IN_BSTR aPassword, BOOL *aExists) 3032 { 3033 #ifndef VBOX_WITH_GUEST_CONTROL 3034 ReturnComNotImplemented(); 3035 #else /* VBOX_WITH_GUEST_CONTROL */ 3036 using namespace guestControl; 3037 3038 return VBOX_E_NOT_SUPPORTED; 3039 #endif 2508 3040 } 2509 3041 … … 2570 3102 #endif /* VBOX_WITH_GUEST_CONTROL */ 2571 3103 } 3104
Note:
See TracChangeset
for help on using the changeset viewer.