Alright; I'll drop a comment on the dev mailing list as well, once I'm done here. Which is, oh hey, right now; here's a patch that includes fixes for recursive copy host to guest (as well as the previously posted patch for guest to host).
Code: Select all
--- src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp (original code)
+++ src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp (working copy)
@@ -1776,11 +1776,13 @@
if (fOnGuest)
{
BOOL fDirExists = FALSE;
+ /* This function is bugged - it always returns an error if the directory does not exist. */
HRESULT rc = pContext->pCmdCtx->pGuestSession->DirectoryExists(Bstr(pszDir).raw(), &fDirExists);
- if (FAILED(rc))
+ *fExists = fDirExists ? true : false;
+ /* If it set fDirExists and returned an error, then we want to error. Otherwise, we
+ * need to return success with fExists set to false. */
+ if(fDirExists && FAILED(rc))
vrc = ctrlPrintError(pContext->pCmdCtx->pGuestSession, COM_IIDOF(IGuestSession));
- else
- *fExists = fDirExists ? true : false;
}
else
*fExists = RTDirExists(pszDir);
@@ -1983,9 +1985,15 @@
if (pContext->pCmdCtx->fVerbose)
RTPrintf("Processing host directory: %s\n", szCurDir);
- /* Flag indicating whether the current directory was created on the
- * target or not. */
- bool fDirCreated = false;
+ /* Always create directory, otherwise we'll fail to copy empty directories. */
+ char *pszDestDir;
+ vrc = ctrlCopyTranslatePath(pszSource, szCurDir,
+ pszDest, &pszDestDir);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = ctrlCopyDirCreate(pContext, pszDestDir);
+ RTStrFree(pszDestDir);
+ }
/*
* Open directory without a filter - RTDirOpenFiltered unfortunately
@@ -2072,36 +2080,19 @@
if (pContext->pCmdCtx->fVerbose)
RTPrintf("File: %s\n", DirEntry.szName);
- if (!fDirCreated)
+ char *pszFileSource = RTPathJoinA(szCurDir, DirEntry.szName);
+ if (pszFileSource)
{
- char *pszDestDir;
- vrc = ctrlCopyTranslatePath(pszSource, szCurDir,
- pszDest, &pszDestDir);
+ char *pszFileDest;
+ vrc = ctrlCopyTranslatePath(pszSource, pszFileSource,
+ pszDest, &pszFileDest);
if (RT_SUCCESS(vrc))
{
- vrc = ctrlCopyDirCreate(pContext, pszDestDir);
- RTStrFree(pszDestDir);
-
- fDirCreated = true;
- }
- }
-
- if (RT_SUCCESS(vrc))
- {
- char *pszFileSource = RTPathJoinA(szCurDir, DirEntry.szName);
- if (pszFileSource)
- {
- char *pszFileDest;
- vrc = ctrlCopyTranslatePath(pszSource, pszFileSource,
- pszDest, &pszFileDest);
- if (RT_SUCCESS(vrc))
- {
- vrc = ctrlCopyFileToDest(pContext, pszFileSource,
- pszFileDest, 0 /* Flags */);
- RTStrFree(pszFileDest);
- }
- RTStrFree(pszFileSource);
+ vrc = ctrlCopyFileToDest(pContext, pszFileSource,
+ pszFileDest, 0 /* Flags */);
+ RTStrFree(pszFileDest);
}
+ RTStrFree(pszFileSource);
}
break;
}
@@ -2155,9 +2146,18 @@
if (pContext->pCmdCtx->fVerbose)
RTPrintf("Processing guest directory: %s\n", szCurDir);
- /* Flag indicating whether the current directory was created on the
- * target or not. */
- bool fDirCreated = false;
+ /* Create directory here, otherwise we will fail to copy empty directories. */
+ char *pszDestDir;
+ vrc = ctrlCopyTranslatePath(pszSource, szCurDir,
+ pszDest, &pszDestDir);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = ctrlCopyDirCreate(pContext, pszDestDir);
+ RTStrFree(pszDestDir);
+ }
+ if (RT_FAILURE(vrc))
+ return vrc;
+
SafeArray<DirectoryOpenFlag_T> dirOpenFlags; /* No flags supported yet. */
ComPtr<IGuestDirectory> pDirectory;
HRESULT rc = pContext->pCmdCtx->pGuestSession->DirectoryOpen(Bstr(szCurDir).raw(), Bstr(pszFilter).raw(),
@@ -2242,39 +2242,22 @@
if (pContext->pCmdCtx->fVerbose)
RTPrintf("File: %s\n", strFile.c_str());
- if (!fDirCreated)
+ char *pszFileSource = RTPathJoinA(szCurDir, strFile.c_str());
+ if (pszFileSource)
{
- char *pszDestDir;
- vrc = ctrlCopyTranslatePath(pszSource, szCurDir,
- pszDest, &pszDestDir);
+ char *pszFileDest;
+ vrc = ctrlCopyTranslatePath(pszSource, pszFileSource,
+ pszDest, &pszFileDest);
if (RT_SUCCESS(vrc))
{
- vrc = ctrlCopyDirCreate(pContext, pszDestDir);
- RTStrFree(pszDestDir);
-
- fDirCreated = true;
+ vrc = ctrlCopyFileToDest(pContext, pszFileSource,
+ pszFileDest, 0 /* Flags */);
+ RTStrFree(pszFileDest);
}
+ RTStrFree(pszFileSource);
}
-
- if (RT_SUCCESS(vrc))
- {
- char *pszFileSource = RTPathJoinA(szCurDir, strFile.c_str());
- if (pszFileSource)
- {
- char *pszFileDest;
- vrc = ctrlCopyTranslatePath(pszSource, pszFileSource,
- pszDest, &pszFileDest);
- if (RT_SUCCESS(vrc))
- {
- vrc = ctrlCopyFileToDest(pContext, pszFileSource,
- pszFileDest, 0 /* Flags */);
- RTStrFree(pszFileDest);
- }
- RTStrFree(pszFileSource);
- }
- else
- vrc = VERR_NO_MEMORY;
- }
+ else
+ vrc = VERR_NO_MEMORY;
break;
}
@@ -2293,6 +2276,7 @@
switch (rc)
{
case E_ABORT: /* No more directory entries left to process. */
+ case VBOX_E_OBJECT_NOT_FOUND: /* Also indicates no more entries to process. */
break;
case VBOX_E_FILE_ERROR: /* Current entry cannot be accessed to
Edit: For some reason, the forum inserts four spaces in front of every line in the code block above, when you copy it directly. This breaks just applying the diff as is. If you want to get the actual raw text out with proper formatting, I suggest clicking the button to quote this post, and then copying from there.