int main(int argc, char *argv[]) { RTR3InitExe(argc, &argv, 0); int rc; RTPrintf("tstVD: TESTING...\n"); /* * Clean up potential leftovers from previous unsuccessful runs. */ RTFileDelete("tmpVDCreate.vdi"); if (!RTDirExists("tmp")) { rc = RTDirCreate("tmp", RTFS_UNIX_IRWXU, 0); if (RT_FAILURE(rc)) { RTPrintf("tstVD: Failed to create 'tmp' directory! rc=%Rrc\n", rc); g_cErrors++; } } #ifdef VDI_TEST rc = tstVDCreateShareDelete("VDI", "tmpVDCreate.vdi", 10 * _1M, VD_IMAGE_FLAGS_FIXED); if (RT_FAILURE(rc)) { RTPrintf("tstVD: VDI shareable test failed! rc=%Rrc\n", rc); g_cErrors++; } #endif /* VDI_TEST */ /* * Clean up any leftovers. */ RTFileDelete("tmpVDCreate.vdi"); rc = VDShutdown(); if (RT_FAILURE(rc)) { RTPrintf("tstVD: unloading backends failed! rc=%Rrc\n", rc); g_cErrors++; } /* * Summary */ if (!g_cErrors) RTPrintf("tstVD: SUCCESS\n"); else RTPrintf("tstVD: FAILURE - %d errors\n", g_cErrors); return !!g_cErrors; }
int main() { int rc = RTTestInitAndCreate("tstRTFileAio", &g_hTest); if (rc) return rc; /* Check if the API is available. */ RTTestSub(g_hTest, "RTFileAioGetLimits"); RTFILEAIOLIMITS AioLimits; RT_ZERO(AioLimits); RTTESTI_CHECK_RC(rc = RTFileAioGetLimits(&AioLimits), VINF_SUCCESS); if (RT_SUCCESS(rc)) { RTTestSub(g_hTest, "Write"); RTFILE hFile; RTTESTI_CHECK_RC(rc = RTFileOpen(&hFile, "tstFileAio#1.tst", RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE | RTFILE_O_ASYNC_IO), VINF_SUCCESS); if (RT_SUCCESS(rc)) { uint8_t *pbTestBuf = (uint8_t *)RTTestGuardedAllocTail(g_hTest, TSTFILEAIO_BUFFER_SIZE); for (unsigned i = 0; i < TSTFILEAIO_BUFFER_SIZE; i++) pbTestBuf[i] = i % 256; uint32_t cReqsMax = AioLimits.cReqsOutstandingMax < TSTFILEAIO_MAX_REQS_IN_FLIGHT ? AioLimits.cReqsOutstandingMax : TSTFILEAIO_MAX_REQS_IN_FLIGHT; /* Basic write test. */ RTTestIPrintf(RTTESTLVL_ALWAYS, "Preparing test file, this can take some time and needs quite a bit of harddisk space...\n"); tstFileAioTestReadWriteBasic(hFile, true /*fWrite*/, pbTestBuf, TSTFILEAIO_BUFFER_SIZE, 100*_1M, cReqsMax); /* Reopen the file before doing the next test. */ RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS); if (RTTestErrorCount(g_hTest) == 0) { RTTestSub(g_hTest, "Read/Write"); RTTESTI_CHECK_RC(rc = RTFileOpen(&hFile, "tstFileAio#1.tst", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_ASYNC_IO), VINF_SUCCESS); if (RT_SUCCESS(rc)) { tstFileAioTestReadWriteBasic(hFile, false /*fWrite*/, pbTestBuf, TSTFILEAIO_BUFFER_SIZE, 100*_1M, cReqsMax); RTFileClose(hFile); } } /* Cleanup */ RTFileDelete("tstFileAio#1.tst"); } } /* * Summary */ return RTTestSummaryAndDestroy(g_hTest); }
RTR3DECL(int) RTS3GetKey(RTS3 hS3, const char *pszBucketName, const char *pszKeyName, const char *pszFilename) { PRTS3INTERNAL pS3Int = hS3; RTS3_VALID_RETURN(pS3Int); /* Reset the CURL object to an defined state */ rtS3ReinitCurl(pS3Int); /* Open the file */ RTFILE hFile; int rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) return rc; char* pszUrl = rtS3Host(pszBucketName, pszKeyName, pS3Int->pszBaseUrl); curl_easy_setopt(pS3Int->pCurl, CURLOPT_URL, pszUrl); RTStrFree(pszUrl); /* Create the three basic header entries */ char *apszHead[3] = { rtS3HostHeader(pszBucketName, pS3Int->pszBaseUrl), /* Host entry */ rtS3DateHeader(), /* Date entry */ NULL /* Authorization entry */ }; /* Create the authorization header entry */ apszHead[RT_ELEMENTS(apszHead)-1] = rtS3CreateAuthHeader(pS3Int, "GET", pszBucketName, pszKeyName, apszHead, RT_ELEMENTS(apszHead)); /* Add all headers to curl */ struct curl_slist* pHeaders = NULL; /* Init to NULL is important */ for(size_t i=0; i < RT_ELEMENTS(apszHead); ++i) pHeaders = curl_slist_append(pHeaders, apszHead[i]); /* Pass our list of custom made headers */ curl_easy_setopt(pS3Int->pCurl, CURLOPT_HTTPHEADER, pHeaders); /* Set the callback which receive the content */ curl_easy_setopt(pS3Int->pCurl, CURLOPT_WRITEFUNCTION, rtS3WriteFileCallback); curl_easy_setopt(pS3Int->pCurl, CURLOPT_WRITEDATA, &hFile); /* Start the request */ rc = rtS3Perform(pS3Int); /* Regardless of the result, free all used resources first*/ curl_slist_free_all(pHeaders); for(size_t i=0; i < RT_ELEMENTS(apszHead); ++i) RTStrFree(apszHead[i]); /* Close the open file */ RTFileClose(hFile); /* If there was an error delete the newly created file */ if (RT_FAILURE(rc)) RTFileDelete(pszFilename); return rc; }
int main() { RTTEST hTest; int rc = RTTestInitAndCreate("tstRTFileAppend-1", &hTest); if (rc) return rc; RTTestBanner(hTest); tstFileAppend1(hTest); RTFileDelete("tstFileAppend-1.tst"); return RTTestSummaryAndDestroy(hTest); }
/** * Pushes the bytes from the input to the output stream, flushes the output * stream and closes both of them. * * On failure, we will delete the output file, if it's a file. The input file * may be deleted, if we're not told to keep it (--keep, --to-stdout). * * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE. * @param phVfsSrc The input stream. Set to NIL if closed. * @param pOpts The options. * @param phVfsDst The output stream. Set to NIL if closed. */ static RTEXITCODE gzipPushFlushAndClose(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsDst) { /* * Push bytes, flush and close the streams. */ RTEXITCODE rcExit = gzipPush(*phVfsSrc, *phVfsDst); RTVfsIoStrmRelease(*phVfsSrc); *phVfsSrc = NIL_RTVFSIOSTREAM; int rc = RTVfsIoStrmFlush(*phVfsDst); if (RT_FAILURE(rc) && rc != VERR_INVALID_PARAMETER) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to flush the output file: %Rrc", rc); RTVfsIoStrmRelease(*phVfsDst); *phVfsDst = NIL_RTVFSIOSTREAM; /* * Do the cleaning up, if needed. Remove the input file, if that's the * desire of the user, or remove the output file on failure. */ if (!pOpts->fStdOut) { if (rcExit == RTEXITCODE_SUCCESS) { if (!pOpts->fKeep) { rc = RTFileDelete(pOpts->pszInput); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to delete '%s': %Rrc", pOpts->pszInput, rc); } } else { rc = RTFileDelete(pOpts->szOutput); if (RT_FAILURE(rc)) RTMsgError("Failed to delete '%s': %Rrc", pOpts->szOutput, rc); } } return rcExit; }
/** * Close and remove an open PID File. * * @param pszPath The path to the PID File, * @param hFile The handle for the file. NIL_RTFILE is ignored as usual. */ VBGLR3DECL(void) VbglR3ClosePidFile(const char *pszPath, RTFILE hFile) { AssertPtrReturnVoid(pszPath); if (hFile != NIL_RTFILE) { #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) RTFileWriteAt(hFile, 0, "-1", 2, NULL); #else RTFileDelete(pszPath); #endif RTFileClose(hFile); } }
HRESULT VFSExplorer::i_deleteFS(TaskVFSExplorer *aTask) { LogFlowFuncEnter(); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; float fPercentStep = 100.0f / aTask->filenames.size(); try { char szPath[RTPATH_MAX]; std::list<Utf8Str>::const_iterator it; size_t i = 0; for (it = aTask->filenames.begin(); it != aTask->filenames.end(); ++it, ++i) { int vrc = RTPathJoin(szPath, sizeof(szPath), m->strPath.c_str(), (*it).c_str()); if (RT_FAILURE(vrc)) throw setError(E_FAIL, tr("Internal Error (%Rrc)"), vrc); vrc = RTFileDelete(szPath); if (RT_FAILURE(vrc)) throw setError(VBOX_E_FILE_ERROR, tr("Can't delete file '%s' (%Rrc)"), szPath, vrc); if (aTask->progress) aTask->progress->SetCurrentOperationProgress((ULONG)(fPercentStep * i)); } } catch(HRESULT aRC) { rc = aRC; } aTask->rc = rc; if (!aTask->progress.isNull()) aTask->progress->i_notifyComplete(rc); LogFlowFunc(("rc=%Rhrc\n", rc)); LogFlowFuncLeave(); return VINF_SUCCESS; }
int VDMemDiskWriteToFile(PVDMEMDISK pMemDisk, const char *pcszFilename) { int rc = VINF_SUCCESS; RTFILE hFile = NIL_RTFILE; LogFlowFunc(("pMemDisk=%#p pcszFilename=%s\n", pMemDisk, pcszFilename)); AssertPtrReturn(pMemDisk, VERR_INVALID_POINTER); AssertPtrReturn(pcszFilename, VERR_INVALID_POINTER); rc = RTFileOpen(&hFile, pcszFilename, RTFILE_O_DENY_NONE | RTFILE_O_CREATE | RTFILE_O_WRITE); if (RT_SUCCESS(rc)) { rc = RTAvlrU64DoWithAll(pMemDisk->pTreeSegments, true, vdMemDiskSegmentWriteToFile, &hFile); RTFileClose(hFile); if (RT_FAILURE(rc)) RTFileDelete(pcszFilename); } LogFlowFunc(("returns rc=%Rrc\n", rc)); return rc; }
RTDECL(int) RTFileMove(const char *pszSrc, const char *pszDst, unsigned fMove) { /* * Validate input. */ AssertMsgReturn(VALID_PTR(pszSrc), ("%p\n", pszSrc), VERR_INVALID_POINTER); AssertMsgReturn(VALID_PTR(pszDst), ("%p\n", pszDst), VERR_INVALID_POINTER); AssertMsgReturn(*pszSrc, ("%p\n", pszSrc), VERR_INVALID_PARAMETER); AssertMsgReturn(*pszDst, ("%p\n", pszDst), VERR_INVALID_PARAMETER); AssertMsgReturn(!(fMove & ~RTFILEMOVE_FLAGS_REPLACE), ("%#x\n", fMove), VERR_INVALID_PARAMETER); /* * Try RTFileRename first. */ Assert(RTPATHRENAME_FLAGS_REPLACE == RTFILEMOVE_FLAGS_REPLACE); unsigned fRename = fMove; int rc = RTFileRename(pszSrc, pszDst, fRename); if (rc == VERR_NOT_SAME_DEVICE) { const char *pszDelete = NULL; /* * The source and target are not on the same device, darn. * We'll try open both ends and perform a copy. */ RTFILE FileSrc; rc = RTFileOpen(&FileSrc, pszSrc, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN); if (RT_SUCCESS(rc)) { RTFILE FileDst; rc = RTFileOpen(&FileDst, pszDst, RTFILE_O_WRITE | RTFILE_O_DENY_ALL | RTFILE_O_CREATE_REPLACE); if (RT_SUCCESS(rc)) { rc = RTFileCopyByHandles(FileSrc, FileDst); if (RT_SUCCESS(rc)) pszDelete = pszSrc; else { pszDelete = pszDst; Log(("RTFileMove('%s', '%s', %#x): copy failed, rc=%Rrc\n", pszSrc, pszDst, fMove, rc)); } /* try delete without closing, and could perhaps avoid some trouble */ int rc2 = RTFileDelete(pszDelete); if (RT_SUCCESS(rc2)) pszDelete = NULL; RTFileClose(FileDst); } else Log(("RTFileMove('%s', '%s', %#x): failed to create destination, rc=%Rrc\n", pszSrc, pszDst, fMove, rc)); RTFileClose(FileSrc); } else Log(("RTFileMove('%s', '%s', %#x): failed to open source, rc=%Rrc\n", pszSrc, pszDst, fMove, rc)); /* if we failed to close it while open, close it now */ if (pszDelete) { int rc2 = RTFileDelete(pszDelete); if (RT_FAILURE(rc2)) Log(("RTFileMove('%s', '%s', %#x): failed to delete '%s', rc2=%Rrc (rc=%Rrc)\n", pszSrc, pszDst, fMove, pszDelete, rc2, rc)); } } LogFlow(("RTDirRename(%p:{%s}, %p:{%s}, %#x): returns %Rrc\n", pszSrc, pszSrc, pszDst, pszDst, fMove, rc)); return rc; }
static void tstObjectCreateTemp(const char *pszSubTest, const char *pszTemplate, bool fFile, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) { RTTestISub(pszSubTest); const char *pcszAPI = fFile ? "RTFileCreateTemp" : "RTDirCreateTemp"; /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); /* The test loop. */ unsigned i; for (i = 0; i < cTimes; i++) { int rc; char szName[RTPATH_MAX]; RTFMODE fModeFinal; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; rc = fFile ? RTFileCreateTemp(papszNames[i], fMode) : RTDirCreateTemp(papszNames[i], fMode); if (rc != VINF_SUCCESS) { RTTestIFailed("%s(%s, %#o) call #%u -> %Rrc\n", pcszAPI, szName, (int)fMode, i, rc); RTStrFree(papszNames[i]); papszNames[i] = NULL; break; } /* Check that the final permissions are not more permissive than * the ones requested (less permissive is fine, c.f. umask etc.). * I mask out the group as I am not sure how we deal with that on * Windows. */ RTTESTI_CHECK_RC_OK(rc = RTPathGetMode(papszNames[i], &fModeFinal)); if (RT_SUCCESS(rc)) { fModeFinal &= (RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXO); RTTESTI_CHECK_MSG((fModeFinal & ~fMode) == 0, ("%s: szName %s\nfModeFinal ~= %#o, expected %#o\n", pcszAPI, szName, fModeFinal, (int)fMode)); } RTTestIPrintf(RTTESTLVL_DEBUG, "%s: %s\n", pcszAPI, papszNames[i]); RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); if (!fSkipXCheck) RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); } /* cleanup */ while (i-- > 0) { if (fFile) RTTESTI_CHECK_RC(RTFileDelete(papszNames[i]), VINF_SUCCESS); else RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
void tstFileAppend1(RTTEST hTest) { /* * Open it write only and do some appending. * Checking that read fails and that the file position changes after the write. */ RTTestSub(hTest, "Basic 1"); RTFileDelete("tstFileAppend-1.tst"); RTFILE hFile = NIL_RTFILE; int rc = RTFileOpen(&hFile, "tstFileAppend-1.tst", RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_NONE | (0644 << RTFILE_O_CREATE_MODE_SHIFT) ); RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS); uint64_t offActual = 42; uint64_t off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 0 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTESTI_CHECK_RC(RTFileWrite(hFile, "0123456789", 10, NULL), VINF_SUCCESS); offActual = 99; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 10 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu after first write\n", offActual); size_t cb = 4; char szBuf[256]; rc = RTFileRead(hFile, szBuf, 1, &cb); RTTESTI_CHECK_MSG(rc == VERR_ACCESS_DENIED || rc == VERR_INVALID_HANDLE, ("rc=%Rrc\n", rc)); offActual = 999; off = 5; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_BEGIN, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 5 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS); /* * Open it write only and do some more appending. * Checking the initial position and that it changes after the write. */ RTTestSub(hTest, "Basic 2"); rc = RTFileOpen(&hFile, "tstFileAppend-1.tst", RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_OPEN | RTFILE_O_DENY_NONE ); RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS); offActual = 99; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 0 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu on 2nd open\n", offActual); RTTESTI_CHECK_RC(rc = RTFileWrite(hFile, "abcdefghij", 10, &cb), VINF_SUCCESS); offActual = 999; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 20 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu after 2nd write\n", offActual); RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS); /* * Open it read/write. * Check the initial position and read stuff. Then append some more and * check the new position and see that read returns 0/EOF. Finally, * do some seeking and read from a new position. */ RTTestSub(hTest, "Basic 3"); rc = RTFileOpen(&hFile, "tstFileAppend-1.tst", RTFILE_O_READWRITE | RTFILE_O_APPEND | RTFILE_O_OPEN | RTFILE_O_DENY_NONE ); RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS); offActual = 9; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 0 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu on 3rd open\n", offActual); cb = 99; RTTESTI_CHECK_RC(rc = RTFileRead(hFile, szBuf, 10, &cb), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || cb == 10); RTTESTI_CHECK_MSG(RT_FAILURE(rc) || !memcmp(szBuf, "0123456789", 10), ("read the wrong stuff: %.10s - expected 0123456789\n", szBuf)); offActual = 999; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 10 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu on 1st open\n", offActual); RTTESTI_CHECK_RC(RTFileWrite(hFile, "klmnopqrst", 10, NULL), VINF_SUCCESS); offActual = 9999; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 30 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu after 3rd write\n", offActual); RTTESTI_CHECK_RC(rc = RTFileRead(hFile, szBuf, 1, NULL), VERR_EOF); cb = 99; RTTESTI_CHECK_RC(rc = RTFileRead(hFile, szBuf, 1, &cb), VINF_SUCCESS); RTTESTI_CHECK(cb == 0); offActual = 99999; off = 15; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_BEGIN, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 15 || RT_FAILURE(rc), ("offActual=%llu", offActual)); if (RT_SUCCESS(rc) && offActual == 15) { RTTESTI_CHECK_RC(rc = RTFileRead(hFile, szBuf, 10, NULL), VINF_SUCCESS); RTTESTI_CHECK_MSG(RT_FAILURE(rc) || !memcmp(szBuf, "fghijklmno", 10), ("read the wrong stuff: %.10s - expected fghijklmno\n", szBuf)); offActual = 9999999; off = 0; RTTESTI_CHECK_RC(rc = RTFileSeek(hFile, off, RTFILE_SEEK_CURRENT, &offActual), VINF_SUCCESS); RTTESTI_CHECK_MSG(offActual == 25 || RT_FAILURE(rc), ("offActual=%llu", offActual)); RTTestIPrintf(RTTESTLVL_INFO, "off=%llu after 2nd read\n", offActual); } RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS); /* * Open it read only + append and check that we cannot write to it. */ RTTestSub(hTest, "Basic 4"); rc = RTFileOpen(&hFile, "tstFileAppend-1.tst", RTFILE_O_READ | RTFILE_O_APPEND | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); RTTESTI_CHECK_RC_RETV(rc, VINF_SUCCESS); rc = RTFileWrite(hFile, "pqrstuvwx", 10, &cb); RTTESTI_CHECK_MSG(rc == VERR_ACCESS_DENIED || rc == VERR_INVALID_HANDLE, ("rc=%Rrc\n", rc)); RTTESTI_CHECK_RC(RTFileClose(hFile), VINF_SUCCESS); RTTESTI_CHECK_RC(RTFileDelete("tstFileAppend-1.tst"), VINF_SUCCESS); }
static int tstVDOpenCreateWriteMerge(PVDSNAPTEST pTest) { int rc; PVBOXHDD pVD = NULL; VDGEOMETRY PCHS = { 0, 0, 0 }; VDGEOMETRY LCHS = { 0, 0, 0 }; PVDINTERFACE pVDIfs = NULL; VDINTERFACEERROR VDIfError; /** Buffer storing the random test pattern. */ uint8_t *pbTestPattern = NULL; /** Number of disk segments */ uint32_t cDiskSegments; /** Array of disk segments */ PVDDISKSEG paDiskSeg = NULL; unsigned cDiffs = 0; unsigned idDiff = 0; /* Diff ID counter for the filename */ /* Delete all images from a previous run. */ RTFileDelete(pTest->pcszBaseImage); for (unsigned i = 0; i < pTest->cIterations; i++) { char *pszDiffFilename = NULL; rc = RTStrAPrintf(&pszDiffFilename, "tstVDSnapDiff%u.%s", i, pTest->pcszDiffSuff); if (RT_SUCCESS(rc)) { if (RTFileExists(pszDiffFilename)) RTFileDelete(pszDiffFilename); RTStrFree(pszDiffFilename); } } /* Create the virtual disk test data */ pbTestPattern = (uint8_t *)RTMemAlloc(pTest->cbTestPattern); RTRandAdvBytes(g_hRand, pbTestPattern, pTest->cbTestPattern); cDiskSegments = RTRandAdvU32Ex(g_hRand, pTest->cDiskSegsMin, pTest->cDiskSegsMax); uint64_t cbDisk = 0; paDiskSeg = (PVDDISKSEG)RTMemAllocZ(cDiskSegments * sizeof(VDDISKSEG)); if (!paDiskSeg) { RTPrintf("Failed to allocate memory for random disk segments\n"); g_cErrors++; return VERR_NO_MEMORY; } for (unsigned i = 0; i < cDiskSegments; i++) { paDiskSeg[i].off = cbDisk; paDiskSeg[i].cbSeg = RT_ALIGN_64(RTRandAdvU64Ex(g_hRand, 512, pTest->cbTestPattern), 512); if (tstVDSnapIsTrue(pTest->uAllocatedBlocks)) paDiskSeg[i].pbData = pbTestPattern + RT_ALIGN_64(RTRandAdvU64Ex(g_hRand, 0, pTest->cbTestPattern - paDiskSeg[i].cbSeg - 512), 512); else paDiskSeg[i].pbData = NULL; /* Not allocated initially */ cbDisk += paDiskSeg[i].cbSeg; } RTPrintf("Disk size is %llu bytes\n", cbDisk); #define CHECK(str) \ do \ { \ RTPrintf("%s rc=%Rrc\n", str, rc); \ if (RT_FAILURE(rc)) \ { \ if (pbTestPattern) \ RTMemFree(pbTestPattern); \ if (paDiskSeg) \ RTMemFree(paDiskSeg); \ VDDestroy(pVD); \ g_cErrors++; \ return rc; \ } \ } while (0) #define CHECK_BREAK(str) \ do \ { \ RTPrintf("%s rc=%Rrc\n", str, rc); \ if (RT_FAILURE(rc)) \ { \ g_cErrors++; \ break; \ } \ } while (0) /* Create error interface. */ /* Create error interface. */ VDIfError.pfnError = tstVDError; VDIfError.pfnMessage = tstVDMessage; rc = VDInterfaceAdd(&VDIfError.Core, "tstVD_Error", VDINTERFACETYPE_ERROR, NULL, sizeof(VDINTERFACEERROR), &pVDIfs); AssertRC(rc); rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD); CHECK("VDCreate()"); rc = VDCreateBase(pVD, pTest->pcszBackend, pTest->pcszBaseImage, cbDisk, VD_IMAGE_FLAGS_NONE, "Test image", &PCHS, &LCHS, NULL, VD_OPEN_FLAGS_NORMAL, NULL, NULL); CHECK("VDCreateBase()"); bool fInit = true; uint32_t cIteration = 0; /* Do the real work now */ while ( RT_SUCCESS(rc) && cIteration < pTest->cIterations) { /* Write */ rc = tstVDSnapWrite(pVD, paDiskSeg, cDiskSegments, cbDisk, fInit); CHECK_BREAK("tstVDSnapWrite()"); fInit = false; /* Write returned, do we want to create a new diff or merge them? */ bool fCreate = cDiffs < pTest->cDiffsMinBeforeMerge ? true : tstVDSnapIsTrue(pTest->uCreateDiffChance); if (fCreate) { char *pszDiffFilename = NULL; RTStrAPrintf(&pszDiffFilename, "tstVDSnapDiff%u.%s", idDiff, pTest->pcszDiffSuff); CHECK("RTStrAPrintf()"); idDiff++; cDiffs++; rc = VDCreateDiff(pVD, pTest->pcszBackend, pszDiffFilename, VD_IMAGE_FLAGS_NONE, "Test diff image", NULL, NULL, VD_OPEN_FLAGS_NORMAL, NULL, NULL); CHECK_BREAK("VDCreateDiff()"); RTStrFree(pszDiffFilename); VDDumpImages(pVD); /* Change data */ tstVDSnapSegmentsDice(pTest, paDiskSeg, cDiskSegments, pbTestPattern, pTest->cbTestPattern); } else { uint32_t uStartMerge = RTRandAdvU32Ex(g_hRand, 1, cDiffs - 1); uint32_t uEndMerge = RTRandAdvU32Ex(g_hRand, uStartMerge + 1, cDiffs); RTPrintf("Merging %u diffs from %u to %u...\n", uEndMerge - uStartMerge, uStartMerge, uEndMerge); if (pTest->fForward) rc = VDMerge(pVD, uStartMerge, uEndMerge, NULL); else rc = VDMerge(pVD, uEndMerge, uStartMerge, NULL); CHECK_BREAK("VDMerge()"); cDiffs -= uEndMerge - uStartMerge; VDDumpImages(pVD); /* Go through the disk segments and reset pointers. */ for (uint32_t i = 0; i < cDiskSegments; i++) { if (paDiskSeg[i].pbDataDiff) { paDiskSeg[i].pbData = paDiskSeg[i].pbDataDiff; paDiskSeg[i].pbDataDiff = NULL; } } /* Now compare the result with our test pattern */ rc = tstVDSnapReadVerify(pVD, paDiskSeg, cDiskSegments, cbDisk); CHECK_BREAK("tstVDSnapReadVerify()"); } cIteration++; } VDDumpImages(pVD); VDDestroy(pVD); if (paDiskSeg) RTMemFree(paDiskSeg); if (pbTestPattern) RTMemFree(pbTestPattern); RTFileDelete(pTest->pcszBaseImage); for (unsigned i = 0; i < idDiff; i++) { char *pszDiffFilename = NULL; RTStrAPrintf(&pszDiffFilename, "tstVDSnapDiff%u.%s", i, pTest->pcszDiffSuff); RTFileDelete(pszDiffFilename); RTStrFree(pszDiffFilename); } #undef CHECK return rc; }
static int fileDeleteCallback(void * /* pvUser */, const char *pcszFilename) { DEBUG_PRINT_FLOW(); return RTFileDelete(pcszFilename); }
/** * Sets up a test file creating the I/O thread. * * @returns VBox status code. * @param pVM Pointer to the shared VM instance structure. * @param pTestFile Pointer to the uninitialized test file structure. * @param iTestId Unique test id. */ static int tstPDMACStressTestFileOpen(PVM pVM, PPDMACTESTFILE pTestFile, unsigned iTestId) { int rc = VERR_NO_MEMORY; /* Size is a multiple of 512 */ pTestFile->cbFileMax = RTRandU64Ex(FILE_SIZE_MIN, FILE_SIZE_MAX) & ~(511UL); pTestFile->cbFileCurr = 0; pTestFile->cbFileSegment = RTRandU32Ex(SEGMENT_SIZE_MIN, RT_MIN(pTestFile->cbFileMax, SEGMENT_SIZE_MAX)) & ~((size_t)511); Assert(pTestFile->cbFileMax >= pTestFile->cbFileSegment); /* Set up the segments array. */ pTestFile->cSegments = pTestFile->cbFileMax / pTestFile->cbFileSegment; pTestFile->cSegments += ((pTestFile->cbFileMax % pTestFile->cbFileSegment) > 0) ? 1 : 0; pTestFile->paSegs = (PPDMACTESTFILESEG)RTMemAllocZ(pTestFile->cSegments * sizeof(PDMACTESTFILESEG)); if (pTestFile->paSegs) { /* Init the segments */ for (unsigned i = 0; i < pTestFile->cSegments; i++) { PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[i]; pSeg->off = (RTFOFF)i * pTestFile->cbFileSegment; pSeg->cbSegment = pTestFile->cbFileSegment; /* Let the buffer point to a random position in the test pattern. */ uint32_t offTestPattern = RTRandU64Ex(0, g_cbTestPattern - pSeg->cbSegment); pSeg->pbData = g_pbTestPattern + offTestPattern; } /* Init task array. */ pTestFile->cTasksActiveMax = RTRandU32Ex(1, TASK_ACTIVE_MAX); pTestFile->paTasks = (PPDMACTESTFILETASK)RTMemAllocZ(pTestFile->cTasksActiveMax * sizeof(PDMACTESTFILETASK)); if (pTestFile->paTasks) { /* Create the template */ char szDesc[256]; RTStrPrintf(szDesc, sizeof(szDesc), "Template-%d", iTestId); rc = PDMR3AsyncCompletionTemplateCreateInternal(pVM, &pTestFile->pTemplate, tstPDMACStressTestFileTaskCompleted, pTestFile, szDesc); if (RT_SUCCESS(rc)) { /* Open the endpoint now. Because async completion endpoints cannot create files we have to do it before. */ char szFile[RTPATH_MAX]; RTStrPrintf(szFile, sizeof(szFile), "tstPDMAsyncCompletionStress-%d.tmp", iTestId); RTFILE FileTmp; rc = RTFileOpen(&FileTmp, szFile, RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_NONE); if (RT_SUCCESS(rc)) { RTFileClose(FileTmp); rc = PDMR3AsyncCompletionEpCreateForFile(&pTestFile->hEndpoint, szFile, 0, pTestFile->pTemplate); if (RT_SUCCESS(rc)) { char szThreadDesc[256]; pTestFile->fRunning = true; /* Create the thread creating the I/O for the given file. */ RTStrPrintf(szThreadDesc, sizeof(szThreadDesc), "PDMACThread-%d", iTestId); rc = PDMR3ThreadCreate(pVM, &pTestFile->hThread, pTestFile, tstPDMACTestFileThread, NULL, 0, RTTHREADTYPE_IO, szThreadDesc); if (RT_SUCCESS(rc)) { rc = PDMR3ThreadResume(pTestFile->hThread); AssertRC(rc); RTPrintf(TESTCASE ": Created test file %s cbFileMax=%llu cbFileSegment=%u cSegments=%u cTasksActiveMax=%u\n", szFile, pTestFile->cbFileMax, pTestFile->cbFileSegment, pTestFile->cSegments, pTestFile->cTasksActiveMax); return VINF_SUCCESS; } PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint); } RTFileDelete(szFile); } PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate); } RTMemFree(pTestFile->paTasks); } else rc = VERR_NO_MEMORY; RTMemFree(pTestFile->paSegs); } else rc = VERR_NO_MEMORY; RTPrintf(TESTCASE ": Opening test file with id %d failed rc=%Rrc\n", iTestId, rc); return rc; }
/** * Recursion worker for RTDirRemoveRecursive. * * @returns IPRT status code. * @param pszBuf The path buffer. Contains the abs path to the * directory to recurse into. Trailing slash. * @param cchDir The length of the directory we're cursing into, * including the trailing slash. * @param pDirEntry The dir entry buffer. (Shared to save stack.) * @param pObjInfo The object info buffer. (ditto) */ static int rtDirRemoveRecursiveSub(char *pszBuf, size_t cchDir, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo) { AssertReturn(RTPATH_IS_SLASH(pszBuf[cchDir - 1]), VERR_INTERNAL_ERROR_4); /* * Enumerate the directory content and dispose of it. */ PRTDIR pDir; int rc = RTDirOpen(&pDir, pszBuf); if (RT_FAILURE(rc)) return rc; while (RT_SUCCESS(rc = RTDirRead(pDir, pDirEntry, NULL))) { if ( pDirEntry->szName[0] != '.' || pDirEntry->cbName > 2 || ( pDirEntry->cbName == 2 && pDirEntry->szName[1] != '.') ) { /* Construct the full name of the entry. */ if (cchDir + pDirEntry->cbName + 1 /* dir slash */ >= RTPATH_MAX) { rc = VERR_FILENAME_TOO_LONG; break; } memcpy(&pszBuf[cchDir], pDirEntry->szName, pDirEntry->cbName + 1); /* Deal with the unknown type. */ if (pDirEntry->enmType == RTDIRENTRYTYPE_UNKNOWN) { rc = RTPathQueryInfoEx(pszBuf, pObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode)) pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY; else if (RT_SUCCESS(rc) && RTFS_IS_FILE(pObjInfo->Attr.fMode)) pDirEntry->enmType = RTDIRENTRYTYPE_FILE; else if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(pObjInfo->Attr.fMode)) pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK; } /* Try the delete the fs object. */ switch (pDirEntry->enmType) { case RTDIRENTRYTYPE_FILE: rc = RTFileDelete(pszBuf); break; case RTDIRENTRYTYPE_DIRECTORY: { size_t cchSubDir = cchDir + pDirEntry->cbName; pszBuf[cchSubDir++] = '/'; pszBuf[cchSubDir] = '\0'; rc = rtDirRemoveRecursiveSub(pszBuf, cchSubDir, pDirEntry, pObjInfo); if (RT_SUCCESS(rc)) { pszBuf[cchSubDir] = '\0'; rc = RTDirRemove(pszBuf); } break; } //case RTDIRENTRYTYPE_SYMLINK: // rc = RTSymlinkDelete(pszBuf, 0); // break; default: /** @todo not implemented yet. */ rc = VINF_SUCCESS; break; } if (RT_FAILURE(rc)) break; } } if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; RTDirClose(pDir); return rc; }
int main() { RTR3InitExeNoArguments(0); RTPrintf("tstFileLock: TESTING\n"); RTFILE File; int rc = RTFileOpen(&File, "tstLock.tst", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); RTPrintf("File open: rc=%Rrc\n", rc); if (RT_FAILURE(rc)) { if (rc != VERR_FILE_NOT_FOUND && rc != VERR_OPEN_FAILED) { RTPrintf("FATAL\n"); return 1; } rc = RTFileOpen(&File, "tstLock.tst", RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_NONE); RTPrintf("File create: rc=%Rrc\n", rc); if (RT_FAILURE(rc)) { RTPrintf("FATAL\n"); return 2; } fRun = true; } /* grow file a little */ rc = RTFileSetSize(File, fRun ? 2048 : 20480); RTPrintf("File size: rc=%Rrc\n", rc); int buf; /* read test. */ rc = RTFileRead(File, &buf, sizeof(buf), NULL); RTPrintf("Read: rc=%Rrc\n", rc); /* write test. */ rc = RTFileWrite(File, achTest1, strlen(achTest1), NULL); RTPrintf("Write: rc=%Rrc\n", rc); /* lock: read, non-blocking. */ rc = RTFileLock(File, RTFILE_LOCK_READ | RTFILE_LOCK_IMMEDIATELY, 0, _4G); RTPrintf("Lock: read, non-blocking, rc=%Rrc\n", rc); bool fl = RT_SUCCESS(rc); /* read test. */ rc = RTFileRead(File, &buf, sizeof(buf), NULL); RTPrintf("Read: rc=%Rrc\n", rc); /* write test. */ rc = RTFileWrite(File, achTest2, strlen(achTest2), NULL); RTPrintf("Write: rc=%Rrc\n", rc); RTPrintf("Lock test will change in three seconds\n"); for (int i = 0; i < 3; i++) { RTThreadSleep(1000); RTPrintf("."); } RTPrintf("\n"); /* change lock: write, non-blocking. */ rc = RTFileLock(File, RTFILE_LOCK_WRITE | RTFILE_LOCK_IMMEDIATELY, 0, _4G); RTPrintf("Change lock: write, non-blocking, rc=%Rrc\n", rc); RTPrintf("Test will unlock in three seconds\n"); for (int i = 0; i < 3; i++) { RTThreadSleep(1000); RTPrintf("."); } RTPrintf("\n"); /* remove lock. */ if (fl) { fl = false; rc = RTFileUnlock(File, 0, _4G); RTPrintf("Unlock: rc=%Rrc\n", rc); RTPrintf("Write test will lock in three seconds\n"); for (int i = 0; i < 3; i++) { RTThreadSleep(1000); RTPrintf("."); } RTPrintf("\n"); } /* lock: write, non-blocking. */ rc = RTFileLock(File, RTFILE_LOCK_WRITE | RTFILE_LOCK_IMMEDIATELY, 0, _4G); RTPrintf("Lock: write, non-blocking, rc=%Rrc\n", rc); fl = RT_SUCCESS(rc); /* grow file test */ rc = RTFileSetSize(File, fRun ? 2048 : 20480); RTPrintf("File size: rc=%Rrc\n", rc); /* read test. */ rc = RTFileRead(File, &buf, sizeof(buf), NULL); RTPrintf("Read: rc=%Rrc\n", rc); /* write test. */ rc = RTFileWrite(File, achTest3, strlen(achTest3), NULL); RTPrintf("Write: rc=%Rrc\n", rc); RTPrintf("Continuing to next test in three seconds\n"); for (int i = 0; i < 3; i++) { RTThreadSleep(1000); RTPrintf("."); } RTPrintf("\n"); RTFileClose(File); RTFileDelete("tstLock.tst"); RTPrintf("tstFileLock: I've no recollection of this testcase succeeding or not, sorry.\n"); return 0; }
RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, RTDIGESTTYPE enmDigestType, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser) { /* Validate input */ AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER); AssertPtrReturn(papszFiles, VERR_INVALID_POINTER); AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER); RTFILE file; int rc = RTFileOpen(&file, pszManifestFile, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL); if (RT_FAILURE(rc)) return rc; PRTMANIFESTTEST paFiles = 0; void *pvBuf = 0; do { paFiles = (PRTMANIFESTTEST)RTMemAllocZ(sizeof(RTMANIFESTTEST) * cFiles); if (!paFiles) { rc = VERR_NO_MEMORY; break; } RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 }; for (size_t i = 0; i < cFiles; ++i) { paFiles[i].pszTestFile = papszFiles[i]; /* Calculate the SHA1 digest of every file */ if (pfnProgressCallback) { callback.cCurrentFile = i; rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, rtSHAProgressCallback, &callback); } else rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, NULL, NULL); if (RT_FAILURE(rc)) break; } if (RT_SUCCESS(rc)) { size_t cbSize = 0; rc = RTManifestWriteFilesBuf(&pvBuf, &cbSize, enmDigestType, paFiles, cFiles); if (RT_FAILURE(rc)) break; rc = RTFileWrite(file, pvBuf, cbSize, 0); } }while (0); RTFileClose(file); /* Cleanup */ if (pvBuf) RTMemFree(pvBuf); if (paFiles) { for (size_t i = 0; i < cFiles; ++i) if (paFiles[i].pszTestDigest) RTStrFree((char*)paFiles[i].pszTestDigest); RTMemFree(paFiles); } /* Delete the manifest file on failure */ if (RT_FAILURE(rc)) RTFileDelete(pszManifestFile); return rc; }
/** * Modifies the autostart database. * * @returns VBox status code. * @param fAutostart Flag whether the autostart or autostop database is modified. * @param fAddVM Flag whether a VM is added or removed from the database. */ int AutostartDb::autostartModifyDb(bool fAutostart, bool fAddVM) { int rc = VINF_SUCCESS; char *pszUser = NULL; /* Check if the path is set. */ if (!m_pszAutostartDbPath) return VERR_PATH_NOT_FOUND; rc = RTProcQueryUsernameA(RTProcSelf(), &pszUser); if (RT_SUCCESS(rc)) { char *pszFile; uint64_t fOpen = RTFILE_O_DENY_ALL | RTFILE_O_READWRITE; RTFILE hAutostartFile; AssertPtr(pszUser); if (fAddVM) fOpen |= RTFILE_O_OPEN_CREATE; else fOpen |= RTFILE_O_OPEN; rc = RTStrAPrintf(&pszFile, "%s/%s.%s", m_pszAutostartDbPath, pszUser, fAutostart ? "start" : "stop"); if (RT_SUCCESS(rc)) { rc = RTFileOpen(&hAutostartFile, pszFile, fOpen); if (RT_SUCCESS(rc)) { uint64_t cbFile; /* * Files with more than 16 bytes are rejected because they just contain * a number of the amount of VMs with autostart configured, so they * should be really really small. Anything else is bogus. */ rc = RTFileGetSize(hAutostartFile, &cbFile); if ( RT_SUCCESS(rc) && cbFile <= 16) { char abBuf[16 + 1]; /* trailing \0 */ uint32_t cAutostartVms = 0; RT_ZERO(abBuf); /* Check if the file was just created. */ if (cbFile) { rc = RTFileRead(hAutostartFile, abBuf, cbFile, NULL); if (RT_SUCCESS(rc)) { rc = RTStrToUInt32Ex(abBuf, NULL, 10 /* uBase */, &cAutostartVms); if ( rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES) rc = VINF_SUCCESS; } } if (RT_SUCCESS(rc)) { size_t cbBuf; /* Modify VM counter and write back. */ if (fAddVM) cAutostartVms++; else cAutostartVms--; if (cAutostartVms > 0) { cbBuf = RTStrPrintf(abBuf, sizeof(abBuf), "%u", cAutostartVms); rc = RTFileSetSize(hAutostartFile, cbBuf); if (RT_SUCCESS(rc)) rc = RTFileWriteAt(hAutostartFile, 0, abBuf, cbBuf, NULL); } else { /* Just delete the file if there are no VMs left. */ RTFileClose(hAutostartFile); RTFileDelete(pszFile); hAutostartFile = NIL_RTFILE; } } } else if (RT_SUCCESS(rc)) rc = VERR_FILE_TOO_BIG; if (hAutostartFile != NIL_RTFILE) RTFileClose(hAutostartFile); } RTStrFree(pszFile); } RTStrFree(pszUser); } return rc; }
DECLHIDDEN(int) VUSBSnifferCreate(PVUSBSNIFFER phSniffer, uint32_t fFlags, const char *pszCaptureFilename, const char *pszDesc) { int rc = VINF_SUCCESS; PVUSBSNIFFERINT pThis = NULL; pThis = (PVUSBSNIFFERINT)RTMemAllocZ(sizeof(VUSBSNIFFERINT)); if (pThis) { pThis->hFile = NIL_RTFILE; pThis->cbBlockCur = 0; pThis->cbBlockMax = 0; pThis->pbBlockData = NULL; pThis->hMtx = NIL_RTSEMFASTMUTEX; rc = RTSemFastMutexCreate(&pThis->hMtx); if (RT_SUCCESS(rc)) { rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, RTFILE_O_DENY_NONE | RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ); if (RT_SUCCESS(rc)) { /* Write header and link type blocks. */ DumpFileShb Shb; Shb.Hdr.u32BlockType = DUMPFILE_SHB_BLOCK_TYPE; Shb.Hdr.u32BlockTotalLength = 0; /* Filled out by lower layer. */ Shb.u32ByteOrderMagic = DUMPFILE_SHB_BYTE_ORDER_MAGIC; Shb.u16VersionMajor = DUMPFILE_SHB_VERSION_MAJOR; Shb.u16VersionMinor = DUMPFILE_SHB_VERSION_MINOR; Shb.u64SectionLength = UINT64_C(0xffffffffffffffff); /* -1 */ /* Write the blocks. */ rc = vusbSnifferBlockNew(pThis, &Shb.Hdr, sizeof(Shb)); if (RT_SUCCESS(rc)) { const char *pszOpt = RTBldCfgTargetDotArch(); rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_HARDWARE, pszOpt, strlen(pszOpt) + 1); } if (RT_SUCCESS(rc)) { char szTmp[512]; size_t cbTmp = sizeof(szTmp); RT_ZERO(szTmp); /* Build the OS code. */ rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, cbTmp); if (RT_SUCCESS(rc)) { size_t cb = strlen(szTmp); szTmp[cb] = ' '; rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, &szTmp[cb + 1], cbTmp - (cb + 1)); if (RT_SUCCESS(rc)) { cb = strlen(szTmp); szTmp[cb] = ' '; rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, &szTmp[cb + 1], cbTmp - (cb + 1)); } } if (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW) rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_OS, szTmp, strlen(szTmp) + 1); else rc = VINF_SUCCESS; /* Skip OS code if building the string failed. */ } if (RT_SUCCESS(rc)) { /** @todo: Add product info. */ } if (RT_SUCCESS(rc)) rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0); if (RT_SUCCESS(rc)) rc = vusbSnifferBlockCommit(pThis); /* Write Interface descriptor block. */ if (RT_SUCCESS(rc)) { DumpFileIdb Idb; Idb.Hdr.u32BlockType = DUMPFILE_IDB_BLOCK_TYPE; Idb.Hdr.u32BlockTotalLength = 0; /* Filled out by lower layer. */ Idb.u16LinkType = DUMPFILE_IDB_LINK_TYPE_USB_LINUX_MMAPED; Idb.u16Reserved = 0; Idb.u32SnapLen = UINT32_C(0xffffffff); rc = vusbSnifferBlockNew(pThis, &Idb.Hdr, sizeof(Idb)); if (RT_SUCCESS(rc)) { uint8_t u8TsResolution = 9; /* Nano second resolution. */ /* Add timestamp resolution option. */ rc = vusbSnifferAddOption(pThis, DUMPFILE_IDB_OPTION_TS_RESOLUTION, &u8TsResolution, sizeof(u8TsResolution)); } if (RT_SUCCESS(rc)) rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0); if (RT_SUCCESS(rc)) rc = vusbSnifferBlockCommit(pThis); } if (RT_SUCCESS(rc)) { *phSniffer = pThis; return VINF_SUCCESS; } RTFileClose(pThis->hFile); pThis->hFile = NIL_RTFILE; RTFileDelete(pszCaptureFilename); } RTSemFastMutexDestroy(pThis->hMtx); pThis->hMtx = NIL_RTSEMFASTMUTEX; } RTMemFree(pThis); } else rc = VERR_NO_MEMORY; return rc; }
int main(int argc, char **argv) { RTEXITCODE rcExit = RTTestInitAndCreate("tstRTPrfIO", &g_hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; RTTestBanner(g_hTest); /* * Parse arguments */ static const RTGETOPTDEF s_aOptions[] = { { "--test-dir", 'd', RTGETOPT_REQ_STRING }, }; bool fFileOpenCloseTest = true; bool fFileWriteByteTest = true; bool fPathQueryInfoTest = true; //bool fFileTests = true; //bool fDirTests = true; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'd': g_pszTestDir = ValueUnion.psz; break; case 'V': RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "$Revision$\n"); return RTTestSummaryAndDestroy(g_hTest); case 'h': RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "usage: testname [-d <testdir>]\n"); return RTTestSummaryAndDestroy(g_hTest); default: RTTestFailed(g_hTest, "invalid argument"); RTGetOptPrintError(ch, &ValueUnion); return RTTestSummaryAndDestroy(g_hTest); } } /* * Set up and check the prerequisites. */ RTTESTI_CHECK_RC(RTPathJoin(g_szTestFile1, sizeof(g_szTestFile1), g_pszTestDir, "tstRTPrfIO-TestFile1"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szTestDir1, sizeof(g_szTestDir1), g_pszTestDir, "tstRTPrfIO-TestDir1"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingFile, sizeof(g_szNotExitingFile), g_pszTestDir, "tstRTPrfIO-nonexistent-file"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingDir, sizeof(g_szNotExitingDir), g_pszTestDir, "tstRTPrfIO-nonexistent-dir"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingDirFile, sizeof(g_szNotExitingDirFile), g_szNotExitingDir, "nonexistent-file"), VINF_SUCCESS); RTTESTI_CHECK(RTDirExists(g_pszTestDir)); if (RTPathExists(g_szTestDir1)) RTTestFailed(g_hTest, "The primary test directory (%s) already exist, please remove it", g_szTestDir1); if (RTPathExists(g_szTestFile1)) RTTestFailed(g_hTest, "The primary test file (%s) already exist, please remove it", g_szTestFile1); if (RTPathExists(g_szNotExitingFile)) RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingFile); if (RTPathExists(g_szNotExitingDir)) RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingDir); if (RTPathExists(g_szNotExitingDirFile)) RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingDirFile); /* * Do the testing. */ if (RTTestIErrorCount() == 0) { #if 1 if (fPathQueryInfoTest) benchmarkPathQueryInfo(); if (fFileOpenCloseTest) benchmarkFileOpenClose(); #endif if (fFileWriteByteTest) benchmarkFileWriteByte(); //if (fFileTests) // benchmarkFile(); //if (fDirTests) // benchmarkDir(); /* * Cleanup. */ RTFileDelete(g_szTestFile1); RTDirRemoveRecursive(g_szTestDir1, 0); RTTESTI_CHECK(RTDirExists(g_pszTestDir)); RTTESTI_CHECK(!RTPathExists(g_szTestDir1)); RTTESTI_CHECK(!RTPathExists(g_szTestFile1)); } return RTTestSummaryAndDestroy(g_hTest); }
int main() { int cErrors = 0; RTPrintf("tstFile: TESTING\n"); RTR3InitExeNoArguments(0); RTFILE File; int rc = RTFileOpen(&File, "tstFile#1.tst", RTFILE_O_READWRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) { RTPrintf("tstFile: FATAL ERROR - Failed to open file #1. rc=%Rrc\n", rc); return 1; } RTFOFF cbMax = -2; rc = RTFileGetMaxSizeEx(File, &cbMax); if (RT_FAILURE(rc)) { RTPrintf("tstFile: RTFileGetMaxSizeEx failed: %Rrc\n", rc); cErrors++; } else if (cbMax <= 0) { RTPrintf("tstFile: RTFileGetMaxSizeEx failed: cbMax=%RTfoff\n", cbMax); cErrors++; } else if (RTFileGetMaxSize(File) != cbMax) { RTPrintf("tstFile: RTFileGetMaxSize failed; returns %RTfoff instead of %RTfoff\n", RTFileGetMaxSize(File), cbMax); cErrors++; } else RTPrintf("Maximum file size is %RTfoff bytes.\n", cbMax); /* grow file beyond 2G */ rc = RTFileSetSize(File, _2G + _1M); if (RT_FAILURE(rc)) { RTPrintf("Failed to grow file #1 to 2.001GB. rc=%Rrc\n", rc); cErrors++; } else { uint64_t cb; rc = RTFileGetSize(File, &cb); if (RT_FAILURE(rc)) { RTPrintf("Failed to get file size of #1. rc=%Rrc\n", rc); cErrors++; } else if (cb != _2G + _1M) { RTPrintf("RTFileGetSize return %RX64 bytes, expected %RX64.\n", cb, _2G + _1M); cErrors++; } else RTPrintf("tstFile: cb=%RX64\n", cb); /* * Try some writes at the beginning of the file. */ uint64_t offFile = RTFileTell(File); if (offFile != 0) { RTPrintf("RTFileTell -> %#RX64, expected 0 (#1)\n", offFile); cErrors++; } static const char szTestBuf[] = "Sausages and bacon for breakfast again!"; size_t cbWritten = 0; while (cbWritten < sizeof(szTestBuf)) { size_t cbWrittenPart; rc = RTFileWrite(File, &szTestBuf[cbWritten], sizeof(szTestBuf) - cbWritten, &cbWrittenPart); if (RT_FAILURE(rc)) break; cbWritten += cbWrittenPart; } if (RT_FAILURE(rc)) { RTPrintf("Failed to write to file #1 at offset 0. rc=%Rrc\n", rc); cErrors++; } else { /* check that it was written correctly. */ rc = RTFileSeek(File, 0, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) { RTPrintf("Failed to seek offset 0 in file #1. rc=%Rrc\n", rc); cErrors++; } else { char szReadBuf[sizeof(szTestBuf)]; size_t cbRead = 0; while (cbRead < sizeof(szTestBuf)) { size_t cbReadPart; rc = RTFileRead(File, &szReadBuf[cbRead], sizeof(szTestBuf) - cbRead, &cbReadPart); if (RT_FAILURE(rc)) break; cbRead += cbReadPart; } if (RT_FAILURE(rc)) { RTPrintf("Failed to read from file #1 at offset 0. rc=%Rrc\n", rc); cErrors++; } else { if (!memcmp(szReadBuf, szTestBuf, sizeof(szTestBuf))) RTPrintf("tstFile: head write ok\n"); else { RTPrintf("Data read from file #1 at offset 0 differs from what we wrote there.\n"); cErrors++; } } } } /* * Try some writes at the end of the file. */ rc = RTFileSeek(File, _2G + _1M, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) { RTPrintf("Failed to seek to _2G + _1M in file #1. rc=%Rrc\n", rc); cErrors++; } else { offFile = RTFileTell(File); if (offFile != _2G + _1M) { RTPrintf("RTFileTell -> %#llx, expected %#llx (#2)\n", offFile, _2G + _1M); cErrors++; } else { cbWritten = 0; while (cbWritten < sizeof(szTestBuf)) { size_t cbWrittenPart; rc = RTFileWrite(File, &szTestBuf[cbWritten], sizeof(szTestBuf) - cbWritten, &cbWrittenPart); if (RT_FAILURE(rc)) break; cbWritten += cbWrittenPart; } if (RT_FAILURE(rc)) { RTPrintf("Failed to write to file #1 at offset 2G + 1M. rc=%Rrc\n", rc); cErrors++; } else { rc = RTFileSeek(File, offFile, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) { RTPrintf("Failed to seek offset %RX64 in file #1. rc=%Rrc\n", offFile, rc); cErrors++; } else { char szReadBuf[sizeof(szTestBuf)]; size_t cbRead = 0; while (cbRead < sizeof(szTestBuf)) { size_t cbReadPart; rc = RTFileRead(File, &szReadBuf[cbRead], sizeof(szTestBuf) - cbRead, &cbReadPart); if (RT_FAILURE(rc)) break; cbRead += cbReadPart; } if (RT_FAILURE(rc)) { RTPrintf("Failed to read from file #1 at offset 2G + 1M. rc=%Rrc\n", rc); cErrors++; } else { if (!memcmp(szReadBuf, szTestBuf, sizeof(szTestBuf))) RTPrintf("tstFile: tail write ok\n"); else { RTPrintf("Data read from file #1 at offset 2G + 1M differs from what we wrote there.\n"); cErrors++; } } } } } } /* * Some general seeking around. */ rc = RTFileSeek(File, _2G + 1, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) { RTPrintf("Failed to seek to _2G + 1 in file #1. rc=%Rrc\n", rc); cErrors++; } else { offFile = RTFileTell(File); if (offFile != _2G + 1) { RTPrintf("RTFileTell -> %#llx, expected %#llx (#3)\n", offFile, _2G + 1); cErrors++; } } /* seek end */ rc = RTFileSeek(File, 0, RTFILE_SEEK_END, NULL); if (RT_FAILURE(rc)) { RTPrintf("Failed to seek to end of file #1. rc=%Rrc\n", rc); cErrors++; } else { offFile = RTFileTell(File); if (offFile != _2G + _1M + sizeof(szTestBuf)) /* assuming tail write was ok. */ { RTPrintf("RTFileTell -> %#RX64, expected %#RX64 (#4)\n", offFile, _2G + _1M + sizeof(szTestBuf)); cErrors++; } } /* seek start */ rc = RTFileSeek(File, 0, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) { RTPrintf("Failed to seek to end of file #1. rc=%Rrc\n", rc); cErrors++; } else { offFile = RTFileTell(File); if (offFile != 0) { RTPrintf("RTFileTell -> %#llx, expected 0 (#5)\n", offFile); cErrors++; } } } /* * Cleanup. */ rc = RTFileClose(File); if (RT_FAILURE(rc)) { RTPrintf("Failed to close file #1. rc=%Rrc\n", rc); cErrors++; } rc = RTFileDelete("tstFile#1.tst"); if (RT_FAILURE(rc)) { RTPrintf("Failed to delete file #1. rc=%Rrc\n", rc); cErrors++; } /* * Summary */ if (cErrors == 0) RTPrintf("tstFile: SUCCESS\n"); else RTPrintf("tstFile: FAILURE - %d errors\n", cErrors); return !!cErrors; }
/** * Handles a file on the command line. * * @returns exit code. * @param pszFile The file to handle. * @param fStdOut Whether to output to standard output or not. * @param fForce Whether to output to or input from terminals. * @param phVfsStdOut Pointer to the standard out handle. * (input/output) */ static RTEXITCODE gzipDecompressFile(const char *pszFile, bool fStdOut, bool fForce, PRTVFSIOSTREAM phVfsStdOut) { /* * Open the specified input file. */ const char *pszError; RTVFSIOSTREAM hVfsIn; int rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsIn, &pszError); if (RT_FAILURE(rc)) { if (pszError && *pszError) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc:\n" " '%s'\n", " %*s^\n", rc, pszFile, pszError - pszFile, ""); return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc: '%s'", rc, pszFile); } /* * Output the output file. */ RTVFSIOSTREAM hVfsOut; char szFinal[RTPATH_MAX]; if (fStdOut) { if (*phVfsStdOut == NIL_RTVFSIOSTREAM) { rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, 0 /*fOpen*/, true /*fLeaveOpen*/, phVfsStdOut); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to set up standard out: %Rrc", rc); } hVfsOut = *phVfsStdOut; szFinal[0] = '\0'; } else { rc = RTStrCopy(szFinal, sizeof(szFinal), pszFile); /** @todo remove the extension? Or are we supposed * to get the org name from the gzip stream? */ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Decompressing to file is not implemented"); } /* * Do the decompressing, then flush and close the output stream (unless * it is stdout). */ RTEXITCODE rcExit = gzipDecompress(hVfsIn, hVfsOut); RTVfsIoStrmRelease(hVfsIn); rc = RTVfsIoStrmFlush(hVfsOut); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to flush the output file: %Rrc", rc); RTVfsIoStrmRelease(hVfsOut); /* * Remove the input file, if that's the desire of the caller, or * remove the output file on decompression failure. */ if (!fStdOut) { if (rcExit == RTEXITCODE_SUCCESS) { rc = RTFileDelete(pszFile); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileDelete failed with %rc: '%s'", rc, pszFile); } else { /* should we do this? */ rc = RTFileDelete(szFinal); if (RT_FAILURE(rc)) RTMsgError("RTFileDelete failed with %rc: '%s'", rc, pszFile); } } return rcExit; }
/** * Worker that removes a file. * * Currently used to delete both regular and special files. * * @returns IPRT status code, errors go via rtPathRmError. * @param pOpts The RM options. * @param pszPath The path to the file. * @param pObjInfo The FS object info for the file. */ static int rtPathRmOneFile(PRTPATHRMCMDOPTS pOpts, const char *pszPath, PRTFSOBJINFO pObjInfo) { int rc; if (pOpts->fVerbose) rtPathRmVerbose(pOpts, pszPath); /* * Wipe the file if requested and possible. */ if (pOpts->fSafeDelete && RTFS_IS_FILE(pObjInfo->Attr.fMode)) { /* Lazy init of the 0xff buffer. */ if (g_ab0xFF[0] != 0xff || g_ab0xFF[sizeof(g_ab0xFF) - 1] != 0xff) memset(g_ab0xFF, 0xff, sizeof(g_ab0xFF)); RTFILE hFile; rc = RTFileOpen(&hFile, pszPath, RTFILE_O_WRITE); if (RT_FAILURE(rc)) return rtPathRmError(pOpts, pszPath, rc, "Opening '%s' for overwriting: %Rrc\n", pszPath, rc); for (unsigned iPass = 0; iPass < 3; iPass++) { uint8_t const *pabFiller = iPass == 1 ? g_abZeros : g_ab0xFF; size_t const cbFiller = iPass == 1 ? sizeof(g_abZeros) : sizeof(g_ab0xFF); rc = RTFileSeek(hFile, 0, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) { rc = rtPathRmError(pOpts, pszPath, rc, "Error seeking to start of '%s': %Rrc\n", pszPath, rc); break; } for (RTFOFF cbLeft = pObjInfo->cbObject; cbLeft > 0; cbLeft -= cbFiller) { size_t cbToWrite = cbFiller; if (cbLeft < (RTFOFF)cbToWrite) cbToWrite = (size_t)cbLeft; rc = RTFileWrite(hFile, pabFiller, cbToWrite, NULL); if (RT_FAILURE(rc)) { rc = rtPathRmError(pOpts, pszPath, rc, "Error writing to '%s': %Rrc\n", pszPath, rc); break; } } } int rc2 = RTFileClose(hFile); if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) return rtPathRmError(pOpts, pszPath, rc2, "Closing '%s' failed: %Rrc\n", pszPath, rc); if (RT_FAILURE(rc)) return rc; } /* * Remove the file. */ rc = RTFileDelete(pszPath); if (RT_FAILURE(rc)) return rtPathRmError(pOpts, pszPath, rc, RTFS_IS_FILE(pObjInfo->Attr.fMode) ? "Error removing regular file '%s': %Rrc\n" : "Error removing special file '%s': %Rrc\n", pszPath, rc); return rc; }
static int vbglR3DnDHGProcessURIMessages(uint32_t uClientId, uint32_t *puScreenId, char *pszFormat, uint32_t cbFormat, uint32_t *pcbFormatRecv, void **ppvData, uint32_t cbData, size_t *pcbDataRecv) { /* Make a string list out of the uri data. */ RTCList<RTCString> uriList = RTCString(static_cast<char*>(*ppvData), *pcbDataRecv - 1).split("\r\n"); if (uriList.isEmpty()) return VINF_SUCCESS; uint32_t cbTmpData = _1M * 10; void *pvTmpData = RTMemAlloc(cbTmpData); if (!pvTmpData) return VERR_NO_MEMORY; /* Create and query the drop target directory. */ char pszDropDir[RTPATH_MAX]; int rc = vbglR3DnDCreateDropDir(pszDropDir, sizeof(pszDropDir)); if (RT_FAILURE(rc)) { RTMemFree(pvTmpData); return rc; } /* Patch the old drop data with the new drop directory, so the drop target * can find the files. */ RTCList<RTCString> guestUriList; for (size_t i = 0; i < uriList.size(); ++i) { const RTCString &strUri = uriList.at(i); /* Query the path component of a file URI. If this hasn't a * file scheme, null is returned. */ if (char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO)) { RTCString strFullPath = RTCString().printf("%s%c%s", pszDropDir, RTPATH_SLASH, pszFilePath); char *pszNewUri = RTUriFileCreate(strFullPath.c_str()); if (pszNewUri) { guestUriList.append(pszNewUri); RTStrFree(pszNewUri); } } else guestUriList.append(strUri); } /* Cleanup the old data and write the new data back to the event. */ RTMemFree(*ppvData); RTCString newData = RTCString::join(guestUriList, "\r\n") + "\r\n"; *ppvData = RTStrDupN(newData.c_str(), newData.length()); *pcbDataRecv = newData.length() + 1; /* Lists for holding created files & directories in the case of a * rollback. */ RTCList<RTCString> guestDirList; RTCList<RTCString> guestFileList; char pszPathname[RTPATH_MAX]; uint32_t cbPathname = 0; bool fLoop = true; do { uint32_t uNextMsg; uint32_t cNextParms; rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false); DO(("%Rrc - %d\n", rc , uNextMsg)); if (RT_SUCCESS(rc)) { switch(uNextMsg) { case DragAndDropSvc::HOST_DND_HG_SND_DIR: { uint32_t fMode = 0; rc = vbglR3DnDHGProcessSendDirMessage(uClientId, pszPathname, sizeof(pszPathname), &cbPathname, &fMode); if (RT_SUCCESS(rc)) { DO(("Got drop dir: %s - %o - %Rrc\n", pszPathname, fMode, rc)); char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname); rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0); if (!guestDirList.contains(pszNewDir)) guestDirList.append(pszNewDir); } break; } case DragAndDropSvc::HOST_DND_HG_SND_FILE: { uint32_t cbDataRecv; uint32_t fMode = 0; rc = vbglR3DnDHGProcessSendFileMessage(uClientId, pszPathname, sizeof(pszPathname), &cbPathname, pvTmpData, cbTmpData, &cbDataRecv, &fMode); if (RT_SUCCESS(rc)) { char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname); DO(("Got drop file: %s - %d - %o - %Rrc\n", pszPathname, cbDataRecv, fMode, rc)); RTFILE hFile; rc = RTFileOpen(&hFile, pszNewFile, RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE); if (RT_SUCCESS(rc)) { rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, NULL); if (RT_SUCCESS(rc)) { rc = RTFileWrite(hFile, pvTmpData, cbDataRecv, 0); /* Valid UNIX mode? */ if ( RT_SUCCESS(rc) && (fMode & RTFS_UNIX_MASK)) rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR); } RTFileClose(hFile); if (!guestFileList.contains(pszNewFile)) guestFileList.append(pszNewFile); } } break; } case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: { rc = vbglR3DnDHGProcessCancelMessage(uClientId); if (RT_SUCCESS(rc)) rc = VERR_CANCELLED; /* Break out of the loop. */ } default: fLoop = false; break; } } else { if (rc == VERR_NO_DATA) rc = VINF_SUCCESS; break; } }while(fLoop); RTMemFree(pvTmpData); /* Cleanup on failure or if the user has canceled. */ if (RT_FAILURE(rc)) { /* Remove any stuff created. */ for (size_t i = 0; i < guestFileList.size(); ++i) RTFileDelete(guestFileList.at(i).c_str()); for (size_t i = 0; i < guestDirList.size(); ++i) RTDirRemove(guestDirList.at(i).c_str()); RTDirRemove(pszDropDir); } return rc; }
/** * Does one free space wipe, using the given filename. * * @returns RTEXITCODE_SUCCESS on success, RTEXITCODE_FAILURE on failure (fully * bitched). * @param pszFilename The filename to use for wiping free space. Will be * replaced and afterwards deleted. * @param pvFiller The filler block buffer. * @param cbFiller The size of the filler block buffer. * @param cbMinLeftOpt When to stop wiping. */ static RTEXITCODE doOneFreeSpaceWipe(const char *pszFilename, void const *pvFiller, size_t cbFiller, uint64_t cbMinLeftOpt) { /* * Open the file. */ RTEXITCODE rcExit = RTEXITCODE_SUCCESS; RTFILE hFile = NIL_RTFILE; int rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_WRITE | RTFILE_O_DENY_NONE | RTFILE_O_CREATE_REPLACE | (0775 << RTFILE_O_CREATE_MODE_SHIFT)); if (RT_SUCCESS(rc)) { /* * Query the amount of available free space. Figure out which API we should use. */ RTFOFF cbTotal = 0; RTFOFF cbFree = 0; rc = RTFileQueryFsSizes(hFile, &cbTotal, &cbFree, NULL, NULL); bool const fFileHandleApiSupported = rc != VERR_NOT_SUPPORTED && rc != VERR_NOT_IMPLEMENTED; if (!fFileHandleApiSupported) rc = RTFsQuerySizes(pszFilename, &cbTotal, &cbFree, NULL, NULL); if (RT_SUCCESS(rc)) { RTPrintf("%s: %'9RTfoff MiB out of %'9RTfoff are free\n", pszFilename, cbFree / _1M, cbTotal / _1M); /* * Start filling up the free space, down to the last 32MB. */ uint64_t const nsStart = RTTimeNanoTS(); /* for speed calcs */ uint64_t nsStat = nsStart; /* for speed calcs */ uint64_t cbStatWritten = 0; /* for speed calcs */ RTFOFF const cbMinLeft = RT_MAX(cbMinLeftOpt, cbFiller * 2); RTFOFF cbLeftToWrite = cbFree - cbMinLeft; uint64_t cbWritten = 0; uint32_t iLoop = 0; while (cbLeftToWrite >= (RTFOFF)cbFiller) { rc = RTFileWrite(hFile, pvFiller, cbFiller, NULL); if (RT_FAILURE(rc)) { if (rc == VERR_DISK_FULL) RTPrintf("%s: Disk full after writing %'9RU64 MiB\n", pszFilename, cbWritten / _1M); else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Write error after %'RU64 bytes: %Rrc\n", pszFilename, cbWritten, rc); break; } /* Flush every now and then as we approach a completely full disk. */ if (cbLeftToWrite <= _1G && (iLoop & (cbLeftToWrite > _128M ? 15 : 3)) == 0) RTFileFlush(hFile); /* * Advance and maybe recheck the amount of free space. */ cbWritten += cbFiller; cbLeftToWrite -= (ssize_t)cbFiller; iLoop++; if ((iLoop & (16 - 1)) == 0 || cbLeftToWrite < _256M) { RTFOFF cbFreeUpdated; if (fFileHandleApiSupported) rc = RTFileQueryFsSizes(hFile, NULL, &cbFreeUpdated, NULL, NULL); else rc = RTFsQuerySizes(pszFilename, NULL, &cbFreeUpdated, NULL, NULL); if (RT_SUCCESS(rc)) { cbFree = cbFreeUpdated; cbLeftToWrite = cbFree - cbMinLeft; } else { rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Failed to query free space after %'RU64 bytes: %Rrc\n", pszFilename, cbWritten, rc); break; } if ((iLoop & (512 - 1)) == 0) { uint64_t const nsNow = RTTimeNanoTS(); uint64_t cNsInterval = nsNow - nsStat; uint64_t cbInterval = cbWritten - cbStatWritten; uint64_t cbIntervalPerSec = cbInterval ? (uint64_t)(cbInterval / (cNsInterval / (double)RT_NS_1SEC)) : 0; RTPrintf("%s: %'9RTfoff MiB out of %'9RTfoff are free after writing %'9RU64 MiB (%'5RU64 MiB/s)\n", pszFilename, cbFree / _1M, cbTotal / _1M, cbWritten / _1M, cbIntervalPerSec / _1M); nsStat = nsNow; cbStatWritten = cbWritten; } } } /* * Now flush the file and then reduce the size a little before closing * it so the system won't entirely run out of space. The flush should * ensure the data has actually hit the disk. */ rc = RTFileFlush(hFile); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Flush failed at %'RU64 bytes: %Rrc\n", pszFilename, cbWritten, rc); uint64_t cbReduced = cbWritten > _512M ? cbWritten - _512M : cbWritten / 2; rc = RTFileSetSize(hFile, cbReduced); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Failed to reduce file size from %'RU64 to %'RU64 bytes: %Rrc\n", pszFilename, cbWritten, cbReduced, rc); /* Issue a summary statements. */ uint64_t cNsElapsed = RTTimeNanoTS() - nsStart; uint64_t cbPerSec = cbWritten ? (uint64_t)(cbWritten / (cNsElapsed / (double)RT_NS_1SEC)) : 0; RTPrintf("%s: Wrote %'RU64 MiB in %'RU64 s, avg %'RU64 MiB/s.\n", pszFilename, cbWritten / _1M, cNsElapsed / RT_NS_1SEC, cbPerSec / _1M); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Initial free space query failed: %Rrc \n", pszFilename, rc); RTFileClose(hFile); /* * Delete the file. */ rc = RTFileDelete(pszFilename); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Delete failed: %Rrc !!\n", pszFilename, rc); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Open failed: %Rrc\n", pszFilename, rc); return rcExit; }