VirtualBox

Changeset 42808 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 14, 2012 2:01:11 PM (12 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r42711 r42808  
    6060using namespace com;
    6161
    62 #undef VBOX_WITH_GUEST_CONTROL2
    63 
    6462/**
    6563 * IVirtualBoxCallback implementation for handling the GuestControlCallback in
     
    7775    }
    7876
    79 #ifndef VBOX_WITH_GUEST_CONTROL2
    80     ComPtr<IGuest> pGuest;
    81 #else
    8277    ComPtr<IGuestSession> pGuestSession;
    83 #endif
    8478    bool fVerbose;
    8579    bool fDryRun;
    8680    bool fHostToGuest;
    87 #ifndef VBOX_WITH_GUEST_CONTROL2
    88     Utf8Str strUsername;
    89     Utf8Str strPassword;
    90 #endif
    9181} COPYCONTEXT, *PCOPYCONTEXT;
    9282
     
    311301}
    312302
    313 #ifndef VBOX_WITH_GUEST_CONTROL2
    314 /**
    315  * Translates a process status to a human readable
    316  * string.
    317  */
    318 static const char *ctrlExecProcessStatusToText(ExecuteProcessStatus_T enmStatus)
    319 {
    320     switch (enmStatus)
    321     {
    322         case ExecuteProcessStatus_Started:
    323             return "started";
    324         case ExecuteProcessStatus_TerminatedNormally:
    325             return "successfully terminated";
    326         case ExecuteProcessStatus_TerminatedSignal:
    327             return "terminated by signal";
    328         case ExecuteProcessStatus_TerminatedAbnormally:
    329             return "abnormally aborted";
    330         case ExecuteProcessStatus_TimedOutKilled:
    331             return "timed out";
    332         case ExecuteProcessStatus_TimedOutAbnormally:
    333             return "timed out, hanging";
    334         case ExecuteProcessStatus_Down:
    335             return "killed";
    336         case ExecuteProcessStatus_Error:
    337             return "error";
    338         default:
    339             break;
    340     }
    341     return "unknown";
    342 }
    343 
    344 static int ctrlExecProcessStatusToExitCode(ExecuteProcessStatus_T enmStatus, ULONG uExitCode)
    345 {
    346     int vrc = EXITCODEEXEC_SUCCESS;
    347     switch (enmStatus)
    348     {
    349         case ExecuteProcessStatus_Started:
    350             vrc = EXITCODEEXEC_SUCCESS;
    351             break;
    352         case ExecuteProcessStatus_TerminatedNormally:
    353             vrc = !uExitCode ? EXITCODEEXEC_SUCCESS : EXITCODEEXEC_CODE;
    354             break;
    355         case ExecuteProcessStatus_TerminatedSignal:
    356             vrc = EXITCODEEXEC_TERM_SIGNAL;
    357             break;
    358         case ExecuteProcessStatus_TerminatedAbnormally:
    359             vrc = EXITCODEEXEC_TERM_ABEND;
    360             break;
    361         case ExecuteProcessStatus_TimedOutKilled:
    362             vrc = EXITCODEEXEC_TIMEOUT;
    363             break;
    364         case ExecuteProcessStatus_TimedOutAbnormally:
    365             vrc = EXITCODEEXEC_TIMEOUT;
    366             break;
    367         case ExecuteProcessStatus_Down:
    368             /* Service/OS is stopping, process was killed, so
    369              * not exactly an error of the started process ... */
    370             vrc = EXITCODEEXEC_DOWN;
    371             break;
    372         case ExecuteProcessStatus_Error:
    373             vrc = EXITCODEEXEC_FAILED;
    374             break;
    375         default:
    376             AssertMsgFailed(("Unknown exit code (%u) from guest process returned!\n", enmStatus));
    377             break;
    378     }
    379     return vrc;
    380 }
    381 #else
    382303/**
    383304 * Translates a process status to a human readable
     
    462383    return vrc;
    463384}
    464 #endif
    465385
    466386static int ctrlPrintError(com::ErrorInfo &errorInfo)
     
    480400        return VERR_GENERAL_FAILURE; /** @todo */
    481401    }
    482     AssertMsgFailedReturn(("Object has indicated no error (%Rrc)!?\n", errorInfo.getResultCode()),
     402    AssertMsgFailedReturn(("Object has indicated no error (%Rhrc)!?\n", errorInfo.getResultCode()),
    483403                          VERR_INVALID_PARAMETER);
    484404}
     
    582502}
    583503
    584 #ifndef VBOX_WITH_GUEST_CONTROL2
    585 /**
    586  * Prints the desired guest output to a stream.
    587  *
    588  * @return  IPRT status code.
    589  * @param   pGuest          Pointer to IGuest interface.
    590  * @param   uPID            PID of guest process to get the output from.
    591  * @param   fOutputFlags    Output flags of type ProcessOutputFlag.
    592  * @param   cMsTimeout      Timeout value (in ms) to wait for output.
    593  */
    594 static int ctrlExecPrintOutput(IGuest *pGuest, ULONG uPID,
    595                                PRTSTREAM pStrmOutput, uint32_t fOutputFlags,
    596                                RTMSINTERVAL cMsTimeout)
    597 {
    598     AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
    599     AssertReturn(uPID, VERR_INVALID_PARAMETER);
    600     AssertPtrReturn(pStrmOutput, VERR_INVALID_POINTER);
    601 
    602     SafeArray<BYTE> aOutputData;
    603     ULONG cbOutputData = 0;
    604 
    605     int vrc = VINF_SUCCESS;
    606     HRESULT rc = pGuest->GetProcessOutput(uPID, fOutputFlags,
    607                                           cMsTimeout,
    608                                           _64K, ComSafeArrayAsOutParam(aOutputData));
    609     if (FAILED(rc))
    610     {
    611         vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
    612         cbOutputData = 0;
    613     }
    614     else
    615     {
    616         cbOutputData = aOutputData.size();
    617         if (cbOutputData > 0)
    618         {
    619             BYTE *pBuf = aOutputData.raw();
    620             AssertPtr(pBuf);
    621             pBuf[cbOutputData - 1] = 0; /* Properly terminate buffer. */
    622 
    623             /** @todo r=bird: Use a VFS I/O stream filter for doing this, it's a
    624             *        generic problem and the new VFS APIs will handle it more
    625             *        transparently. (requires writing dos2unix/unix2dos filters ofc) */
    626 
    627             /*
    628              * If aOutputData is text data from the guest process' stdout or stderr,
    629              * it has a platform dependent line ending. So standardize on
    630              * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
    631              * Windows. Otherwise we end up with CR/CR/LF on Windows.
    632              */
    633 
    634             char *pszBufUTF8;
    635             vrc = RTStrCurrentCPToUtf8(&pszBufUTF8, (const char*)aOutputData.raw());
    636             if (RT_SUCCESS(vrc))
    637             {
    638                 cbOutputData = strlen(pszBufUTF8);
    639 
    640                 ULONG cbOutputDataPrint = cbOutputData;
    641                 for (char *s = pszBufUTF8, *d = s;
    642                      s - pszBufUTF8 < (ssize_t)cbOutputData;
    643                      s++, d++)
    644                 {
    645                     if (*s == '\r')
    646                     {
    647                         /* skip over CR, adjust destination */
    648                         d--;
    649                         cbOutputDataPrint--;
    650                     }
    651                     else if (s != d)
    652                         *d = *s;
    653                 }
    654 
    655                 vrc = RTStrmWrite(pStrmOutput, pszBufUTF8, cbOutputDataPrint);
    656                 if (RT_FAILURE(vrc))
    657                     RTMsgError("Unable to write output, rc=%Rrc\n", vrc);
    658 
    659                 RTStrFree(pszBufUTF8);
    660             }
    661             else
    662                 RTMsgError("Unable to convert output, rc=%Rrc\n", vrc);
    663         }
    664     }
    665 
    666     return vrc;
    667 }
    668 #else
    669504/**
    670505 * Prints the desired guest output to a stream.
     
    684519
    685520    SafeArray<BYTE> aOutputData;
    686     HRESULT rc = pProcess->Read(uHandle, _64K, 1 /* timeout */,
     521    HRESULT rc = pProcess->Read(uHandle, _64K, 30 * 1000 /* 30s timeout. */,
    687522                                ComSafeArrayAsOutParam(aOutputData));
    688523    if (FAILED(rc))
     
    698533    return vrc;
    699534}
    700 #endif
    701535
    702536/**
     
    713547        return RT_INDEFINITE_WAIT;
    714548
    715     uint64_t u64ElapsedMs = RTTimeMilliTS() - u64StartMs;
     549    uint32_t u64ElapsedMs = RTTimeMilliTS() - u64StartMs;
    716550    if (u64ElapsedMs >= cMsTimeout)
    717551        return 0;
     
    754588
    755589    Utf8Str                 strCmd;
    756 #ifndef VBOX_WITH_GUEST_CONTROL2
    757     uint32_t                fExecFlags      = ExecuteProcessFlag_None;
    758 #else
    759     com::SafeArray<ProcessCreateFlag_T> aCreateFlags;
     590    com::SafeArray<ProcessCreateFlag_T>  aCreateFlags;
    760591    com::SafeArray<ProcessWaitForFlag_T> aWaitFlags;
    761 #endif
    762     com::SafeArray<IN_BSTR> args;
    763     com::SafeArray<IN_BSTR> env;
    764     Utf8Str                 strUsername;
    765     Utf8Str                 strPassword;
    766     Utf8Str                 strDomain;
    767     RTMSINTERVAL            cMsTimeout      = 0;
    768     OUTPUTTYPE              eOutputType     = OUTPUTTYPE_UNDEFINED;
    769     bool                    fWaitForExit    = false;
    770     bool                    fVerbose        = false;
    771 
    772     int                     vrc             = VINF_SUCCESS;
     592    com::SafeArray<IN_BSTR>              args;
     593    com::SafeArray<IN_BSTR>              env;
     594    Utf8Str                              strUsername;
     595    Utf8Str                              strPassword;
     596    Utf8Str                              strDomain;
     597    RTMSINTERVAL                         cMsTimeout      = 0;
     598    OUTPUTTYPE                           eOutputType     = OUTPUTTYPE_UNDEFINED;
     599    bool                                 fWaitForExit    = false;
     600    bool                                 fVerbose        = false;
     601    int                                  vrc             = VINF_SUCCESS;
     602
     603    /* Wait for process start in any case. This is useful for scripting VBoxManage
     604     * when relying on its overall exit code. */
     605    aWaitFlags.push_back(ProcessWaitForFlag_Start);
     606
    773607    while (   (ch = RTGetOpt(&GetState, &ValueUnion))
    774608           && RT_SUCCESS(vrc))
     
    799633
    800634            case GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES:
    801 #ifndef VBOX_WITH_GUEST_CONTROL2
    802                 fExecFlags |= ExecuteProcessFlag_IgnoreOrphanedProcesses;
    803 #else
    804635                aCreateFlags.push_back(ProcessCreateFlag_IgnoreOrphanedProcesses);
    805 #endif
    806636                break;
    807637
    808638            case GETOPTDEF_EXEC_NO_PROFILE:
    809 #ifndef VBOX_WITH_GUEST_CONTROL2
    810                 fExecFlags |= ExecuteProcessFlag_NoProfile;
    811 #else
    812639                aCreateFlags.push_back(ProcessCreateFlag_NoProfile);
    813 #endif
    814640                break;
    815641
     
    855681
    856682            case GETOPTDEF_EXEC_WAITFOREXIT:
    857 #ifndef VBOX_WITH_GUEST_CONTROL2
    858 #else
    859683                aWaitFlags.push_back(ProcessWaitForFlag_Terminate);
    860 #endif
    861684                fWaitForExit = true;
    862685                break;
    863686
    864687            case GETOPTDEF_EXEC_WAITFORSTDOUT:
    865 #ifndef VBOX_WITH_GUEST_CONTROL2
    866                 fExecFlags |= ExecuteProcessFlag_WaitForStdOut;
    867 #else
    868688                aCreateFlags.push_back(ProcessCreateFlag_WaitForStdOut);
    869689                aWaitFlags.push_back(ProcessWaitForFlag_StdOut);
    870 #endif
    871690                fWaitForExit = true;
    872691                break;
    873692
    874693            case GETOPTDEF_EXEC_WAITFORSTDERR:
    875 #ifndef VBOX_WITH_GUEST_CONTROL2
    876                 fExecFlags |= ExecuteProcessFlag_WaitForStdErr;
    877 #else
    878694                aCreateFlags.push_back(ProcessCreateFlag_WaitForStdErr);
    879695                aWaitFlags.push_back(ProcessWaitForFlag_StdErr);
    880 #endif
    881696                fWaitForExit = true;
    882697                break;
     
    918733    }
    919734
    920 #ifndef VBOX_WITH_GUEST_CONTROL2
    921     /* Get current time stamp to later calculate rest of timeout left. */
    922     uint64_t u64StartMS = RTTimeMilliTS();
    923 
    924     /*
    925      * Execute the process.
    926      */
    927     ComPtr<IProgress> pProgress;
    928     ULONG uPID = 0;
    929     rc = pGuest->ExecuteProcess(Bstr(strCmd).raw(),
    930                                fExecFlags,
    931                                ComSafeArrayAsInParam(args),
    932                                ComSafeArrayAsInParam(env),
    933                                Bstr(strUsername).raw(),
    934                                Bstr(strPassword).raw(),
    935                                cMsTimeout,
    936                                &uPID,
    937                                pProgress.asOutParam());
    938     if (FAILED(rc))
    939     {
    940         ctrlPrintError(pGuest, COM_IIDOF(IGuest));
    941         return RTEXITCODE_FAILURE;
    942     }
    943 
    944     if (fVerbose)
    945         RTPrintf("Process '%s' (PID: %u) started\n", strCmd.c_str(), uPID);
    946     if (fWaitForExit)
    947     {
    948         if (fVerbose)
    949         {
    950             if (cMsTimeout) /* Wait with a certain timeout. */
    951             {
    952                 /* Calculate timeout value left after process has been started.  */
    953                 uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS;
    954                 /* Is timeout still bigger than current difference? */
    955                 if (cMsTimeout > u64Elapsed)
    956                     RTPrintf("Waiting for process to exit (%ums left) ...\n", cMsTimeout - u64Elapsed);
    957                 else
    958                     RTPrintf("No time left to wait for process!\n"); /** @todo a bit misleading ... */
    959             }
    960             else /* Wait forever. */
    961                 RTPrintf("Waiting for process to exit ...\n");
    962         }
    963 
    964         /* Setup signal handling if cancelable. */
    965         ASSERT(pProgress);
    966         bool fCanceledAlready = false;
    967         BOOL fCancelable;
    968         HRESULT hrc = pProgress->COMGETTER(Cancelable)(&fCancelable);
    969         if (FAILED(hrc))
    970             fCancelable = FALSE;
    971         if (fCancelable)
    972             ctrlSignalHandlerInstall();
    973 
    974         vrc = RTStrmSetMode(g_pStdOut, 1 /* Binary mode */, -1 /* Code set, unchanged */);
    975         if (RT_FAILURE(vrc))
    976             RTMsgError("Unable to set stdout's binary mode, rc=%Rrc\n", vrc);
    977 
    978         PRTSTREAM pStream = g_pStdOut; /* StdOut by default. */
    979         AssertPtr(pStream);
    980 
    981         /* Wait for process to exit ... */
    982         BOOL fCompleted    = FALSE;
    983         BOOL fCanceled     = FALSE;
    984         while (   SUCCEEDED(pProgress->COMGETTER(Completed(&fCompleted)))
    985                && !fCompleted)
    986         {
    987             /* Do we need to output stuff? */
    988             RTMSINTERVAL cMsTimeLeft;
    989             if (fExecFlags & ExecuteProcessFlag_WaitForStdOut)
    990             {
    991                 cMsTimeLeft = ctrlExecGetRemainingTime(u64StartMS, cMsTimeout);
    992                 if (cMsTimeLeft)
    993                     vrc = ctrlExecPrintOutput(pGuest, uPID,
    994                                               pStream, ProcessOutputFlag_None /* StdOut */,
    995                                               cMsTimeLeft == RT_INDEFINITE_WAIT ? 0 : cMsTimeLeft);
    996             }
    997 
    998             if (fExecFlags & ExecuteProcessFlag_WaitForStdErr)
    999             {
    1000                 cMsTimeLeft = ctrlExecGetRemainingTime(u64StartMS, cMsTimeout);
    1001                 if (cMsTimeLeft)
    1002                     vrc = ctrlExecPrintOutput(pGuest, uPID,
    1003                                               pStream, ProcessOutputFlag_StdErr /* StdErr */,
    1004                                               cMsTimeLeft == RT_INDEFINITE_WAIT ? 0 : cMsTimeLeft);
    1005             }
    1006 
    1007             /* Process async cancelation */
    1008             if (g_fGuestCtrlCanceled && !fCanceledAlready)
    1009             {
    1010                 hrc = pProgress->Cancel();
    1011                 if (SUCCEEDED(hrc))
    1012                     fCanceledAlready = TRUE;
    1013                 else
    1014                     g_fGuestCtrlCanceled = false;
    1015             }
    1016 
    1017             /* Progress canceled by Main API? */
    1018             if (   SUCCEEDED(pProgress->COMGETTER(Canceled(&fCanceled)))
    1019                 && fCanceled)
    1020                 break;
    1021 
    1022             /* Did we run out of time? */
    1023             if (   cMsTimeout
    1024                 && RTTimeMilliTS() - u64StartMS > cMsTimeout)
    1025             {
    1026                 pProgress->Cancel();
    1027                 break;
    1028             }
    1029         } /* while */
    1030 
    1031         /* Undo signal handling */
    1032         if (fCancelable)
    1033             ctrlSignalHandlerUninstall();
    1034 
    1035         /* Report status back to the user. */
    1036         if (fCanceled)
    1037         {
    1038             if (fVerbose)
    1039                 RTPrintf("Process execution canceled!\n");
    1040             return EXITCODEEXEC_CANCELED;
    1041         }
    1042         else if (   fCompleted
    1043                  && SUCCEEDED(rc)) /* The GetProcessOutput rc. */
    1044         {
    1045             LONG iRc;
    1046             CHECK_ERROR_RET(pProgress, COMGETTER(ResultCode)(&iRc), rc);
    1047             if (FAILED(iRc))
    1048                 vrc = ctrlPrintProgressError(pProgress);
    1049             else
    1050             {
    1051                 ExecuteProcessStatus_T retStatus;
    1052                 ULONG uRetExitCode, uRetFlags;
    1053                 rc = pGuest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
    1054                 if (SUCCEEDED(rc))
    1055                 {
    1056                     if (fVerbose)
    1057                         RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, retStatus, ctrlExecProcessStatusToText(retStatus), uRetFlags);
    1058                     return ctrlExecProcessStatusToExitCode(retStatus, uRetExitCode);
    1059                 }
    1060                 else
    1061                 {
    1062                     ctrlPrintError(pGuest, COM_IIDOF(IGuest));
    1063                     return RTEXITCODE_FAILURE;
    1064                 }
    1065             }
    1066         }
    1067         else
    1068         {
    1069             if (fVerbose)
    1070                 RTPrintf("Process execution aborted!\n");
    1071             return EXITCODEEXEC_TERM_ABEND;
    1072         }
    1073     }
    1074 #else
    1075735    ComPtr<IGuestSession> pGuestSession;
    1076736    rc = pGuest->CreateSession(Bstr(strUsername).raw(),
    1077737                               Bstr(strPassword).raw(),
    1078738                               Bstr(strDomain).raw(),
    1079                                Bstr("guest exec").raw(),
     739                               Bstr("VBoxManage Guest Control Exec").raw(),
    1080740                               pGuestSession.asOutParam());
    1081741    if (FAILED(rc))
     
    1103763        return RTEXITCODE_FAILURE;
    1104764    }
    1105     ULONG uPID = 0;
    1106     rc = pProcess->COMGETTER(PID)(&uPID);
    1107     if (FAILED(rc))
    1108     {
    1109         ctrlPrintError(pProcess, COM_IIDOF(IProcess));
    1110         return RTEXITCODE_FAILURE;
    1111     }
    1112 
    1113     if (fVerbose)
    1114         RTPrintf("Process '%s' (PID: %u) started\n", strCmd.c_str(), uPID);
    1115765
    1116766    if (fWaitForExit)
     
    1143793        /* Wait for process to exit ... */
    1144794        RTMSINTERVAL cMsTimeLeft = 1;
     795        bool fReadStdOut, fReadStdErr;
     796        fReadStdOut = fReadStdErr = false;
    1145797        bool fCompleted = false;
    1146798        while (!fCompleted && cMsTimeLeft != 0)
     
    1155807            }
    1156808
     809#ifdef DEBUG
     810            if (fVerbose)
     811                RTPrintf("rc=%Rrc, waitResult=%ld\n", rc, waitResult);
     812#endif
    1157813            switch (waitResult)
    1158814            {
     815                case ProcessWaitResult_Start:
     816                {
     817                    if (fVerbose)
     818                    {
     819                        ULONG uPID = 0;
     820                        rc = pProcess->COMGETTER(PID)(&uPID);
     821                        if (FAILED(rc))
     822                        {
     823                            ctrlPrintError(pProcess, COM_IIDOF(IProcess));
     824                            return RTEXITCODE_FAILURE;
     825                        }
     826                        RTPrintf("Process '%s' (PID: %u) started\n", strCmd.c_str(), uPID);
     827                    }
     828                    break;
     829                }
    1159830                case ProcessWaitResult_StdOut:
    1160                     /* Do we need to fetch stdout data? */
    1161                     vrc = ctrlExecPrintOutput(pProcess, g_pStdOut, 1 /* StdOut */);
     831                    fReadStdOut = true;
    1162832                    break;
    1163                 case ProcessWaitResult_StdErr:
    1164                     /* Do we need to fetch stderr data? */
    1165                     vrc = ctrlExecPrintOutput(pProcess, g_pStdErr, 2 /* StdErr */);
     833               case ProcessWaitResult_StdErr:
     834                    fReadStdErr = true;
    1166835                    break;
    1167836                case ProcessWaitResult_Terminate:
     
    1169838                    fCompleted = true;
    1170839                    break;
     840               case ProcessWaitResult_Any:
     841                   fReadStdOut = fReadStdErr = true;
     842                   break;
    1171843                default:
    1172844                    /* Ignore all other results, let the timeout expire */;
    1173             }
     845                    break;
     846            }
     847
     848            if (fReadStdOut) /* Do we need to fetch stdout data? */
     849            {
     850                vrc = ctrlExecPrintOutput(pProcess, g_pStdOut, 1 /* StdOut */);
     851                fReadStdOut = false;
     852            }
     853
     854            if (fReadStdErr) /* Do we need to fetch stdout data? */
     855            {
     856                vrc = ctrlExecPrintOutput(pProcess, g_pStdErr, 2 /* StdErr */);
     857                fReadStdErr = false;
     858            }
     859
     860            if (RT_FAILURE(vrc))
     861                break;
     862
    1174863        } /* while */
    1175864
     
    1202891        }
    1203892    }
    1204 #endif
    1205893
    1206894    return RT_FAILURE(vrc) || FAILED(rc) ? RTEXITCODE_FAILURE : RTEXITCODE_SUCCESS;
     
    1233921    PCOPYCONTEXT pContext = new COPYCONTEXT();
    1234922    AssertPtrReturn(pContext, VERR_NO_MEMORY); /**< @todo r=klaus cannot happen with new */
    1235 #ifndef VBOX_WITH_GUEST_CONTROL2
    1236     NOREF(strDomain);
    1237     NOREF(strSessionName);
    1238     pContext->pGuest = pGuest;
    1239 
    1240     pContext->strUsername = strUsername;
    1241     pContext->strPassword = strPassword;
    1242 #else
    1243923    ComPtr<IGuestSession> pGuestSession;
    1244924    HRESULT rc = pGuest->CreateSession(Bstr(strUsername).raw(),
     
    1250930        return ctrlPrintError(pGuest, COM_IIDOF(IGuest));
    1251931
    1252 #endif
    1253 
    1254932    pContext->fVerbose = fVerbose;
    1255933    pContext->fDryRun = fDryRun;
    1256934    pContext->fHostToGuest = fHostToGuest;
     935    pContext->pGuestSession = pGuestSession;
    1257936
    1258937    *ppContext = pContext;
     
    1270949    if (pContext)
    1271950    {
    1272 #ifndef VBOX_WITH_GUEST_CONTROL2
    1273 #else
    1274951        if (pContext->pGuestSession)
    1275952            pContext->pGuestSession->Close();
    1276 #endif
    1277953        delete pContext;
    1278954    }
     
    14461122    if (pContext->fHostToGuest) /* We want to create directories on the guest. */
    14471123    {
    1448 #ifndef VBOX_WITH_GUEST_CONTROL2
    1449         HRESULT rc = pContext->pGuest->DirectoryCreate(Bstr(pszDir).raw(),
    1450                                                        Bstr(pContext->strUsername).raw(), Bstr(pContext->strPassword).raw(),
    1451                                                        0700, DirectoryCreateFlag_Parents);
    1452         if (FAILED(rc))
    1453             vrc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    1454 #else
    1455         ComPtr<IGuestDirectory> pDirectory;
    14561124        SafeArray<DirectoryCreateFlag_T> dirCreateFlags;
    14571125        dirCreateFlags.push_back(DirectoryCreateFlag_Parents);
    14581126        HRESULT rc = pContext->pGuestSession->DirectoryCreate(Bstr(pszDir).raw(),
    1459                                                               0700, ComSafeArrayAsInParam(dirCreateFlags), pDirectory.asOutParam());
     1127                                                              0700, ComSafeArrayAsInParam(dirCreateFlags));
    14601128        if (FAILED(rc))
    14611129            vrc = ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
    1462         if (!pDirectory.isNull())
    1463             pDirectory->Close();
    1464 #endif
    14651130    }
    14661131    else /* ... or on the host. */
     
    14951160    {
    14961161        BOOL fDirExists = FALSE;
    1497 #ifndef VBOX_WITH_GUEST_CONTROL2
    1498         /** @todo Replace with DirectoryExists as soon as API is in place. */
    1499         HRESULT rc = pContext->pGuest->FileExists(Bstr(pszDir).raw(),
    1500                                                   Bstr(pContext->strUsername).raw(),
    1501                                                   Bstr(pContext->strPassword).raw(), &fDirExists);
    1502         if (FAILED(rc))
    1503             vrc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    1504         else
    1505             *fExists = fDirExists ? true : false;
    1506 #else
    15071162        HRESULT rc = pContext->pGuestSession->DirectoryExists(Bstr(pszDir).raw(), &fDirExists);
    15081163        if (FAILED(rc))
     
    15101165        else
    15111166            *fExists = fDirExists ? true : false;
    1512 #endif
    15131167    }
    15141168    else
     
    15731227    {
    15741228        BOOL fFileExists = FALSE;
    1575 #ifndef VBOX_WITH_GUEST_CONTROL2
    1576         HRESULT rc = pContext->pGuest->FileExists(Bstr(pszFile).raw(),
    1577                                                   Bstr(pContext->strUsername).raw(),
    1578                                                   Bstr(pContext->strPassword).raw(), &fFileExists);
    1579         if (FAILED(rc))
    1580             vrc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    1581         else
    1582             *fExists = fFileExists ? true : false;
    1583 #else
    15841229        HRESULT rc = pContext->pGuestSession->FileExists(Bstr(pszFile).raw(), &fFileExists);
    15851230        if (FAILED(rc))
     
    15871232        else
    15881233            *fExists = fFileExists ? true : false;
    1589 #endif
    15901234    }
    15911235    else
     
    16581302    if (pContext->fHostToGuest)
    16591303    {
    1660 #ifndef VBOX_WITH_GUEST_CONTROL2
    1661         Assert(!fFlags);
    1662         rc = pContext->pGuest->CopyToGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
    1663                                            Bstr(pContext->strUsername).raw(), Bstr(pContext->strPassword).raw(),
    1664                                            fFlags, pProgress.asOutParam());
    1665 #else
    16661304        SafeArray<CopyFileFlag_T> copyFlags;
    16671305        rc = pContext->pGuestSession->CopyTo(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
     
    16691307
    16701308                                             pProgress.asOutParam());
    1671 #endif
    16721309    }
    16731310    else
    16741311    {
    1675 #ifndef VBOX_WITH_GUEST_CONTROL2
    1676         Assert(!fFlags);
    1677         rc = pContext->pGuest->CopyFromGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
    1678                                              Bstr(pContext->strUsername).raw(), Bstr(pContext->strPassword).raw(),
    1679                                              fFlags, pProgress.asOutParam());
    1680 #else
    16811312        SafeArray<CopyFileFlag_T> copyFlags;
    16821313        rc = pContext->pGuestSession->CopyFrom(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
    16831314                                               ComSafeArrayAsInParam(copyFlags),
    16841315                                               pProgress.asOutParam());
    1685 #endif
    16861316    }
    16871317
    16881318    if (FAILED(rc))
    16891319    {
    1690 #ifndef VBOX_WITH_GUEST_CONTROL2
    1691         vrc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    1692 #else
    16931320        vrc = ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
    1694 #endif
    16951321    }
    16961322    else
     
    19141540     * target or not. */
    19151541    bool fDirCreated = false;
    1916 
    1917 #ifndef VBOX_WITH_GUEST_CONTROL2
    1918     ULONG uDirHandle;
    1919     HRESULT rc = pContext->pGuest->DirectoryOpen(Bstr(szCurDir).raw(), Bstr(pszFilter).raw(),
    1920                                                  DirectoryOpenFlag_None /* No flags supported yet. */,
    1921                                                  Bstr(pContext->strUsername).raw(), Bstr(pContext->strPassword).raw(),
    1922                                                  &uDirHandle);
    1923     if (FAILED(rc))
    1924         return ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    1925     ComPtr<IGuestDirEntry> dirEntry;
    1926 #else
    19271542    SafeArray<DirectoryOpenFlag_T> dirOpenFlags; /* No flags supported yet. */
    19281543    ComPtr<IGuestDirectory> pDirectory;
     
    19331548        return ctrlPrintError(pContext->pGuestSession, COM_IIDOF(IGuestSession));
    19341549    ComPtr<IFsObjInfo> dirEntry;
    1935 #endif
    19361550    while (true)
    19371551    {
    1938 #ifndef VBOX_WITH_GUEST_CONTROL2
    1939         rc = pContext->pGuest->DirectoryRead(uDirHandle, dirEntry.asOutParam());
    1940 #else
    19411552        rc = pDirectory->Read(dirEntry.asOutParam());
    1942 #endif
    19431553        if (FAILED(rc))
    19441554            break;
    19451555
    1946 #ifndef VBOX_WITH_GUEST_CONTROL2
    1947         GuestDirEntryType_T enmType;
    1948 #else
    19491556        FsObjType_T enmType;
    1950 #endif
    19511557        dirEntry->COMGETTER(Type)(&enmType);
    19521558
     
    19561562        switch (enmType)
    19571563        {
    1958 #ifndef VBOX_WITH_GUEST_CONTROL2
    1959             case GuestDirEntryType_Directory:
    1960 #else
    19611564            case FsObjType_Directory:
    1962 #endif
    19631565            {
    19641566                Assert(!strName.isEmpty());
     
    19991601            }
    20001602
    2001 #ifndef VBOX_WITH_GUEST_CONTROL2
    2002             case GuestDirEntryType_Symlink:
    2003 #else
    20041603            case FsObjType_Symlink:
    2005 #endif
    20061604                if (   (fFlags & CopyFileFlag_Recursive)
    20071605                    && (fFlags & CopyFileFlag_FollowLinks))
     
    20121610                    break;
    20131611
    2014 #ifndef VBOX_WITH_GUEST_CONTROL2
    2015             case GuestDirEntryType_File:
    2016 #else
    20171612            case FsObjType_File:
    2018 #endif
    20191613            {
    20201614                Assert(!strName.isEmpty());
     
    20921686
    20931687            default:
    2094 #ifndef VBOX_WITH_GUEST_CONTROL2
    2095                 vrc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    2096 #else
    20971688                vrc = ctrlPrintError(pDirectory, COM_IIDOF(IGuestDirectory));
    2098 #endif
    2099                 break;
    2100         }
    2101     }
    2102 
    2103 #ifndef VBOX_WITH_GUEST_CONTROL2
    2104     HRESULT rc2 = pContext->pGuest->DirectoryClose(uDirHandle);
    2105 #else
     1689                break;
     1690        }
     1691    }
     1692
    21061693    HRESULT rc2 = pDirectory->Close();
    2107 #endif
    21081694    if (FAILED(rc2))
    21091695    {
    2110 #ifndef VBOX_WITH_GUEST_CONTROL2
    2111         int vrc2 = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
    2112 #else
    21131696        int vrc2 = ctrlPrintError(pDirectory, COM_IIDOF(IGuestDirectory));
    2114 #endif
    21151697        if (RT_SUCCESS(vrc))
    21161698            vrc = vrc2;
     
    23441926    PCOPYCONTEXT pContext;
    23451927    vrc = ctrlCopyContextCreate(guest, fVerbose, fDryRun, fHostToGuest,
    2346                                 strUsername.c_str(), strPassword.c_str(),
    2347                                 strDomain.c_str(), "guest copy", &pContext);
     1928                                strUsername, strPassword, strDomain,
     1929                                "VBoxManage Guest Control Copy", &pContext);
    23481930    if (RT_FAILURE(vrc))
    23491931    {
     
    24792061}
    24802062
    2481 static int handleCtrlCreateDirectory(ComPtr<IGuest> guest, HandlerArg *pArg)
     2063static int handleCtrlCreateDirectory(ComPtr<IGuest> pGuest, HandlerArg *pArg)
    24822064{
    24832065    AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
     
    25092091    Utf8Str strPassword;
    25102092    Utf8Str strDomain;
    2511     uint32_t fFlags = DirectoryCreateFlag_None;
     2093    SafeArray<DirectoryCreateFlag_T> dirCreateFlags;
    25122094    uint32_t fDirMode = 0; /* Default mode. */
    25132095    bool fVerbose = false;
     
    25252107
    25262108            case 'P': /* Create parents */
    2527                 fFlags |= DirectoryCreateFlag_Parents;
     2109                dirCreateFlags.push_back(DirectoryCreateFlag_Parents);
    25282110                break;
    25292111
     
    25772159        RTPrintf("Creating %u directories ...\n", cDirs);
    25782160
     2161    ComPtr<IGuestSession> pGuestSession;
     2162    hrc = pGuest->CreateSession(Bstr(strUsername).raw(),
     2163                                Bstr(strPassword).raw(),
     2164                                Bstr(strDomain).raw(),
     2165                                Bstr("VBoxManage Guest Control MkDir").raw(),
     2166                                pGuestSession.asOutParam());
     2167    if (FAILED(hrc))
     2168        return ctrlPrintError(pGuest, COM_IIDOF(IGuest));
     2169
    25792170    DESTDIRMAPITER it = mapDirs.begin();
    25802171    while (it != mapDirs.end())
     
    25832174            RTPrintf("Creating directory \"%s\" ...\n", it->first.c_str());
    25842175
    2585         hrc = guest->DirectoryCreate(Bstr(it->first).raw(),
    2586                                      Bstr(strUsername).raw(), Bstr(strPassword).raw(),
    2587                                      fDirMode, fFlags);
     2176        hrc = pGuestSession->DirectoryCreate(Bstr(it->first).raw(), fDirMode, ComSafeArrayAsInParam(dirCreateFlags));
    25882177        if (FAILED(hrc))
    25892178        {
    2590             ctrlPrintError(guest, COM_IIDOF(IGuest)); /* Return code ignored, save original rc. */
     2179            ctrlPrintError(pGuest, COM_IIDOF(IGuestSession)); /* Return code ignored, save original rc. */
    25912180            break;
    25922181        }
     
    25952184    }
    25962185
     2186    if (!pGuestSession.isNull())
     2187        pGuestSession->Close();
     2188
    25972189    return FAILED(hrc) ? RTEXITCODE_FAILURE : RTEXITCODE_SUCCESS;
    25982190}
    25992191
    2600 static int handleCtrlStat(ComPtr<IGuest> guest, HandlerArg *pArg)
     2192static int handleCtrlStat(ComPtr<IGuest> pGuest, HandlerArg *pArg)
    26012193{
    26022194    AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
     
    26832275        return errorSyntax(USAGE_GUESTCONTROL, "No user name specified!");
    26842276
     2277    ComPtr<IGuestSession> pGuestSession;
     2278    HRESULT hrc = pGuest->CreateSession(Bstr(strUsername).raw(),
     2279                                        Bstr(strPassword).raw(),
     2280                                        Bstr(strDomain).raw(),
     2281                                        Bstr("VBoxManage Guest Control Stat").raw(),
     2282                                        pGuestSession.asOutParam());
     2283    if (FAILED(hrc))
     2284        return ctrlPrintError(pGuest, COM_IIDOF(IGuest));
     2285
    26852286    /*
    26862287     * Create the directories.
    26872288     */
    2688     HRESULT hrc = S_OK;
    26892289    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
    26902290    DESTDIRMAPITER it = mapObjs.begin();
     
    26942294            RTPrintf("Checking for element \"%s\" ...\n", it->first.c_str());
    26952295
    2696         BOOL fExists;
    2697         hrc = guest->FileExists(Bstr(it->first).raw(),
    2698                                 Bstr(strUsername).raw(), Bstr(strPassword).raw(),
    2699                                 &fExists);
     2296        ComPtr<IGuestFsObjInfo> pFsObjInfo;
     2297        hrc = pGuestSession->FileQueryInfo(Bstr(it->first).raw(), pFsObjInfo.asOutParam());
    27002298        if (FAILED(hrc))
    2701         {
    2702             ctrlPrintError(guest, COM_IIDOF(IGuest)); /* Return code ignored, save original rc. */
    2703             rcExit = RTEXITCODE_FAILURE;
    2704         }
    2705         else
    2706         {
    2707             /** @todo: Output vbox_stat's stdout output to get more information about
    2708              *         what happened. */
    2709 
     2299            hrc = pGuestSession->DirectoryQueryInfo(Bstr(it->first).raw(), pFsObjInfo.asOutParam());
     2300
     2301        if (FAILED(hrc))
     2302        {
    27102303            /* If there's at least one element which does not exist on the guest,
    27112304             * drop out with exitcode 1. */
    2712             if (!fExists)
    2713             {
    2714                 if (fVerbose)
    2715                     RTPrintf("Cannot stat for element \"%s\": No such file or directory\n",
    2716                              it->first.c_str());
    2717                 rcExit = RTEXITCODE_FAILURE;
    2718             }
     2305            if (fVerbose)
     2306                RTPrintf("Cannot stat for element \"%s\": No such element\n",
     2307                         it->first.c_str());
     2308            rcExit = RTEXITCODE_FAILURE;
     2309        }
     2310        else
     2311        {
     2312            FsObjType_T objType;
     2313            hrc = pFsObjInfo->COMGETTER(Type)(&objType);
     2314            if (FAILED(hrc))
     2315                return ctrlPrintError(pGuest, COM_IIDOF(IGuestFsObjInfo));
     2316            switch (objType)
     2317            {
     2318                case FsObjType_File:
     2319                    RTPrintf("Element \"%s\" found: Is a file\n", it->first.c_str());
     2320                    break;
     2321
     2322                case FsObjType_Directory:
     2323                    RTPrintf("Element \"%s\" found: Is a directory\n", it->first.c_str());
     2324                    break;
     2325
     2326                case FsObjType_Symlink:
     2327                    RTPrintf("Element \"%s\" found: Is a symlink\n", it->first.c_str());
     2328                    break;
     2329
     2330                default:
     2331                    RTPrintf("Element \"%s\" found, type unknown (%ld)\n", it->first.c_str(), objType);
     2332                    break;
     2333            }
     2334
     2335            /** @todo: Show more information about this element. */
    27192336        }
    27202337
    27212338        it++;
    27222339    }
     2340
     2341    if (!pGuestSession.isNull())
     2342        pGuestSession->Close();
    27232343
    27242344    return rcExit;
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42783 r42808  
    195195    STDMETHOD(CopyFrom)(IN_BSTR aSource, IN_BSTR aDest, ComSafeArrayIn(CopyFileFlag_T, aFlags), IProgress **aProgress);
    196196    STDMETHOD(CopyTo)(IN_BSTR aSource, IN_BSTR aDest, ComSafeArrayIn(CopyFileFlag_T, aFlags), IProgress **aProgress);
    197     STDMETHOD(DirectoryCreate)(IN_BSTR aPath, ULONG aMode, ComSafeArrayIn(DirectoryCreateFlag_T, aFlags), IGuestDirectory **aDirectory);
     197    STDMETHOD(DirectoryCreate)(IN_BSTR aPath, ULONG aMode, ComSafeArrayIn(DirectoryCreateFlag_T, aFlags));
    198198    STDMETHOD(DirectoryCreateTemp)(IN_BSTR aTemplate, ULONG aMode, IN_BSTR aPath, BOOL aSecure, BSTR *aDirectory);
    199199    STDMETHOD(DirectoryExists)(IN_BSTR aPath, BOOL *aExists);
     
    245245     * @{ */
    246246    int                     directoryClose(ComObjPtr<GuestDirectory> pDirectory);
    247     int                     directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory);
     247    int                     directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags);
    248248    int                     objectCreateTempInternal(Utf8Str strTemplate,
    249249                                                     Utf8Str strPath,
     
    252252                                                     int *prc);
    253253    int                     directoryOpenInternal(const Utf8Str &strPath, const Utf8Str &strFilter, uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory);
     254    int                     directoryQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData);
    254255    int                     dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
    255256    int                     fileClose(ComObjPtr<GuestFile> pFile);
     
    259260    int                     fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData);
    260261    int                     fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize);
     262    int                     fsQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData);
    261263    const GuestCredentials &getCredentials(void);
    262264    const GuestEnvironment &getEnvironment(void);
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42787 r42808  
    3838
    3939
     40/*
     41 * If the following define is enabled the Guest Additions update code also
     42 * checks for locations which were not supposed to happen due to not resolving
     43 * environment variables in VBoxService toolbox arguments. So a file copied
     44 * to "%TEMP%\foo.exe" became "C:\Windows\EMPfoo.exe".
     45 */
    4046#define VBOX_SERVICE_ENVARG_BUG
    4147
     
    14221428}
    14231429
    1424 int GuestSession::directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, ComObjPtr<GuestDirectory> &pDirectory)
     1430int GuestSession::directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags)
    14251431{
    14261432    LogFlowThisFunc(("strPath=%s, uMode=%x, uFlags=%x\n",
     
    14761482    }
    14771483
    1478     if (RT_FAILURE(rc))
    1479         return rc;
    1480 
    1481     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    1482 
    1483     /* Create the directory object. */
    1484     HRESULT hr = pDirectory.createObject();
    1485     if (FAILED(hr))
    1486         return VERR_COM_UNEXPECTED;
    1487 
    1488     /* Note: There will be a race between creating and getting/initing the directory
    1489              object here. */
    1490     rc = pDirectory->init(this /* Parent */, strPath);
    1491     if (RT_FAILURE(rc))
    1492         return rc;
    1493 
    1494     /* Add the created directory to our vector. */
    1495     mData.mDirectories.push_back(pDirectory);
    1496 
    1497     LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n",
    1498                  strPath.c_str(), mData.mId));
     1484    LogFlowFuncLeaveRC(rc);
     1485    return rc;
     1486}
     1487
     1488int GuestSession::directoryQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData)
     1489{
     1490    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
     1491
     1492    int rc = fsQueryInfoInternal(strPath, objData);
     1493    if (RT_SUCCESS(rc))
     1494    {
     1495        rc = objData.mType == FsObjType_Directory
     1496           ? VINF_SUCCESS : VERR_NOT_A_DIRECTORY;
     1497    }
    14991498
    15001499    LogFlowFuncLeaveRC(rc);
     
    17951794}
    17961795
    1797 /* Note: Will work on directories and others, too. */
    17981796int GuestSession::fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData)
     1797{
     1798    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
     1799
     1800    int rc = fsQueryInfoInternal(strPath, objData);
     1801    if (RT_SUCCESS(rc))
     1802    {
     1803        rc = objData.mType == FsObjType_File
     1804           ? VINF_SUCCESS : VERR_NOT_A_FILE;
     1805    }
     1806
     1807    LogFlowFuncLeaveRC(rc);
     1808    return rc;
     1809}
     1810
     1811int GuestSession::fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize)
     1812{
     1813    AssertPtrReturn(pllSize, VERR_INVALID_POINTER);
     1814
     1815    GuestFsObjData objData;
     1816    int rc = fileQueryInfoInternal(strPath, objData);
     1817    if (RT_SUCCESS(rc))
     1818    {
     1819        if (objData.mType == FsObjType_File)
     1820            *pllSize = objData.mObjectSize;
     1821        else
     1822            rc = VERR_NOT_A_FILE;
     1823    }
     1824
     1825    return rc;
     1826}
     1827
     1828int GuestSession::fsQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData)
    17991829{
    18001830    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
     
    18681898}
    18691899
    1870 int GuestSession::fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize)
    1871 {
    1872     AssertPtrReturn(pllSize, VERR_INVALID_POINTER);
    1873 
    1874     GuestFsObjData objData;
    1875     int rc = fileQueryInfoInternal(strPath, objData);
    1876     if (RT_SUCCESS(rc))
    1877     {
    1878         if (objData.mType == FsObjType_File)
    1879             *pllSize = objData.mObjectSize;
    1880         else
    1881             rc = VERR_NOT_A_FILE;
    1882     }
    1883 
    1884     return rc;
    1885 }
    1886 
    18871900const GuestCredentials& GuestSession::getCredentials(void)
    18881901{
     
    22382251
    22392252STDMETHODIMP GuestSession::DirectoryCreate(IN_BSTR aPath, ULONG aMode,
    2240                                            ComSafeArrayIn(DirectoryCreateFlag_T, aFlags), IGuestDirectory **aDirectory)
     2253                                           ComSafeArrayIn(DirectoryCreateFlag_T, aFlags))
    22412254{
    22422255#ifndef VBOX_WITH_GUEST_CONTROL
     
    22472260    if (RT_UNLIKELY((aPath) == NULL || *(aPath) == '\0'))
    22482261        return setError(E_INVALIDARG, tr("No directory to create specified"));
    2249     /* aDirectory is optional. */
    22502262
    22512263    AutoCaller autoCaller(this);
     
    22692281
    22702282    ComObjPtr <GuestDirectory> pDirectory;
    2271     int rc = directoryCreateInternal(Utf8Str(aPath), (uint32_t)aMode, fFlags, pDirectory);
    2272     if (RT_SUCCESS(rc))
    2273     {
    2274         if (aDirectory)
    2275         {
    2276             /* Return directory object to the caller. */
    2277             hr = pDirectory.queryInterfaceTo(aDirectory);
    2278         }
    2279         else
    2280         {
    2281             rc = directoryClose(pDirectory);
    2282             if (RT_FAILURE(rc))
    2283                 hr = setError(VBOX_E_IPRT_ERROR, tr("Unable to close directory object, rc=%Rrc"), rc);
    2284         }
    2285     }
    2286     else
     2283    int rc = directoryCreateInternal(Utf8Str(aPath), (uint32_t)aMode, fFlags);
     2284    if (RT_FAILURE(rc))
    22872285    {
    22882286        switch (rc)
     
    24622460    LogFlowThisFuncEnter();
    24632461
    2464     AutoCaller autoCaller(this);
    2465     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    2466 
    2467     ReturnComNotImplemented();
     2462    if (RT_UNLIKELY((aPath) == NULL || *(aPath) == '\0'))
     2463        return setError(E_INVALIDARG, tr("No directory to query information for specified"));
     2464    CheckComArgOutPointerValid(aInfo);
     2465
     2466    AutoCaller autoCaller(this);
     2467    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     2468
     2469    HRESULT hr = S_OK;
     2470
     2471    GuestFsObjData objData;
     2472    int rc = directoryQueryInfoInternal(Utf8Str(aPath), objData);
     2473    if (RT_SUCCESS(rc))
     2474    {
     2475        if (objData.mType == FsObjType_Directory)
     2476        {
     2477            ComObjPtr<GuestFsObjInfo> pFsObjInfo;
     2478            hr = pFsObjInfo.createObject();
     2479            if (FAILED(hr))
     2480                return VERR_COM_UNEXPECTED;
     2481
     2482            rc = pFsObjInfo->init(objData);
     2483            if (RT_SUCCESS(rc))
     2484                hr = pFsObjInfo.queryInterfaceTo(aInfo);
     2485        }
     2486    }
     2487
     2488    if (RT_FAILURE(rc))
     2489    {
     2490        switch (rc)
     2491        {
     2492            /** @todo Add more errors here! */
     2493
     2494            case VERR_NOT_A_DIRECTORY:
     2495                hr = setError(VBOX_E_IPRT_ERROR, tr("Element exists but is not a directory"));
     2496                break;
     2497
     2498            default:
     2499                hr = setError(VBOX_E_IPRT_ERROR, tr("Querying directory information failed: %Rrc"), rc);
     2500                break;
     2501        }
     2502    }
     2503
     2504    return hr;
    24682505#endif /* VBOX_WITH_GUEST_CONTROL */
    24692506}
     
    27532790    LogFlowThisFuncEnter();
    27542791
    2755     AutoCaller autoCaller(this);
    2756     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    2757 
    2758     ReturnComNotImplemented();
     2792    if (RT_UNLIKELY((aPath) == NULL || *(aPath) == '\0'))
     2793        return setError(E_INVALIDARG, tr("No file to query information for specified"));
     2794    CheckComArgOutPointerValid(aInfo);
     2795
     2796    AutoCaller autoCaller(this);
     2797    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     2798
     2799    HRESULT hr = S_OK;
     2800
     2801    GuestFsObjData objData;
     2802    int rc = fileQueryInfoInternal(Utf8Str(aPath), objData);
     2803    if (RT_SUCCESS(rc))
     2804    {
     2805        ComObjPtr<GuestFsObjInfo> pFsObjInfo;
     2806        hr = pFsObjInfo.createObject();
     2807        if (FAILED(hr))
     2808            return VERR_COM_UNEXPECTED;
     2809
     2810        rc = pFsObjInfo->init(objData);
     2811        if (RT_SUCCESS(rc))
     2812            hr = pFsObjInfo.queryInterfaceTo(aInfo);
     2813    }
     2814
     2815    if (RT_FAILURE(rc))
     2816    {
     2817        switch (rc)
     2818        {
     2819            /** @todo Add more errors here! */
     2820
     2821            case VERR_NOT_A_FILE:
     2822                hr = setError(VBOX_E_IPRT_ERROR, tr("Element exists but is not a file"));
     2823                break;
     2824
     2825            default:
     2826               hr = setError(VBOX_E_IPRT_ERROR, tr("Querying file information failed: %Rrc"), rc);
     2827               break;
     2828        }
     2829    }
     2830
     2831    return hr;
    27592832#endif /* VBOX_WITH_GUEST_CONTROL */
    27602833}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette