void fetchAllBuckets(RTS3 hS3) { /* Fetch all available buckets */ RTTestIPrintf(RTTESTLVL_ALWAYS, " List all buckets...\n"); char pszTitle[] = "RTS3GetBuckets"; RTS3SetProgressCallback(hS3, progress, pszTitle); PCRTS3BUCKETENTRY pBuckets = NULL; int rc = RTS3GetBuckets(hS3, &pBuckets); if (RT_SUCCESS(rc)) { if (pBuckets) { PCRTS3BUCKETENTRY pTmpBuckets = pBuckets; while (pBuckets) { RTTestIPrintf(RTTESTLVL_ALWAYS, " > %s, %s\n", pBuckets->pszName, pBuckets->pszCreationDate); pBuckets = pBuckets->pNext; } RTS3BucketsDestroy(pTmpBuckets); } else RTTestIPrintf(RTTESTLVL_ALWAYS, " > empty\n"); } else RTTestIFailed("RTS3GetBuckets -> %Rrc", rc); }
static void tstShowStats(RTSTRCACHE hStrCache) { size_t cbStrings; size_t cbChunks; size_t cbBigEntries; uint32_t cHashCollisions; uint32_t cHashCollisions2; uint32_t cHashInserts; uint32_t cRehashes; uint32_t cStrings = RTStrCacheGetStats(hStrCache, &cbStrings, &cbChunks, &cbBigEntries, &cHashCollisions, &cHashCollisions2, &cHashInserts, &cRehashes); if (cbStrings == UINT32_MAX) { RTTESTI_CHECK(!RTStrCacheIsRealImpl()); return; } RTTestIValue("Strings", cStrings, RTTESTUNIT_OCCURRENCES); RTTestIValue("Memory overhead", (uint64_t)(cbChunks + cbBigEntries - cbStrings) * 100 / cbStrings, RTTESTUNIT_PCT); if (cHashInserts > 0) { RTTestIValue("Collisions", (uint64_t)cHashCollisions * 100 / cHashInserts, RTTESTUNIT_PCT); RTTestIValue("Collisions2", (uint64_t)cHashCollisions2 * 100 / cHashInserts, RTTESTUNIT_PCT); } RTTestIPrintf(RTTESTLVL_ALWAYS, "cHashInserts=%u cHashCollisions=%u cHashCollisions2=%u cRehashes=%u\n", cHashInserts, cHashCollisions, cHashCollisions2, cRehashes); RTTestIPrintf(RTTESTLVL_ALWAYS, "cbChunks=%zu cbBigEntries=%zu cbStrings=%zu\n", cbChunks, cbBigEntries, cbStrings); }
void fetchAllKeys(RTS3 hS3, const char *pszBucketName) { /* Fetch all available keys of a specific bucket */ RTTestIPrintf(RTTESTLVL_ALWAYS, " List all keys of bucket '%s'...\n", pszBucketName); PCRTS3KEYENTRY pKeys = NULL; char pszTitle[] = "RTS3GetBucketKeys"; RTS3SetProgressCallback(hS3, progress, pszTitle); int rc = RTS3GetBucketKeys(hS3, pszBucketName, &pKeys); if (RT_SUCCESS(rc)) { if (pKeys) { PCRTS3KEYENTRY pTmpKeys = pKeys; while (pKeys) { RTTestIPrintf(RTTESTLVL_ALWAYS, " > %s, %s, %lu\n", pKeys->pszName, pKeys->pszLastModified, pKeys->cbFile); pKeys = pKeys->pNext; } RTS3KeysDestroy(pTmpKeys); } else RTTestIPrintf(RTTESTLVL_ALWAYS, " > empty\n"); } else RTTestIFailed("RTS3GetBucketKeys -> %Rrc", rc); }
static void test1(const char *pszSubTest, const char *pszFilename) { int rc; RTTestISub(pszSubTest); RTFILE hFile; rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN); if (RT_FAILURE(rc)) { if ( rc == VERR_ACCESS_DENIED || rc == VERR_PERMISSION_DENIED || rc == VERR_FILE_NOT_FOUND) { RTTestIPrintf(RTTESTLVL_ALWAYS, "Cannot access '%s', skipping.", pszFilename); return; } RTTESTI_CHECK_RC_RETV(RTFileOpen(&hFile, pszFilename, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN), VINF_SUCCESS); } uint64_t cbFile = UINT64_MAX - 42; RTTESTI_CHECK_RC(rc = RTFileGetSize(hFile, &cbFile), VINF_SUCCESS); if (RT_SUCCESS(rc)) { RTTESTI_CHECK(cbFile != UINT64_MAX - 42); RTTestIValue(pszSubTest, cbFile, RTTESTUNIT_BYTES); } RTFileClose(hFile); RTTestISubDone(); }
static void dotest(void) { RTDBGKRNLINFO hKrnlInfo; RTTESTI_CHECK_RC_RETV(RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0), VINF_SUCCESS); static const char * const s_apszSyms[] = { "ast_pending", "cpu_interrupt", "dtrace_register", "dtrace_suspend", "kext_alloc", "kext_free", "vm_map_protect" }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszSyms); i++) { void *pvValue = NULL; int rc = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, s_apszSyms[i], &pvValue); RTTestIPrintf(RTTESTLVL_ALWAYS, "%Rrc %p %s\n", rc, pvValue, s_apszSyms[i]); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTESTI_CHECK_RC(RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, s_apszSyms[i], NULL), VINF_SUCCESS); } RTTESTI_CHECK_RC(RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "no_such_symbol_name_really", NULL), VERR_SYMBOL_NOT_FOUND); RTTESTI_CHECK(RTR0DbgKrnlInfoRelease(hKrnlInfo) == 0); RTTESTI_CHECK(RTR0DbgKrnlInfoRelease(NIL_RTDBGKRNLINFO) == 0); }
static DECLCALLBACK(int) progress(unsigned uPercent, void *pvUser) { #ifdef TSTS3_SHOWPROGRESS RTTestIPrintf(RTTESTLVL_ALWAYS, " Progress for %s - %d%% done.\n", (char*)pvUser, (int)uPercent); #endif /* TSTS3_SHOWPROGRESS */ return VINF_SUCCESS; }
/** * Time constrained test with and unlimited N threads. */ static void tst3(uint32_t cThreads, uint32_t cbObject, int iMethod, uint32_t cSecs) { RTTestISubF("Benchmark - %u threads, %u bytes, %u secs, %s", cThreads, cbObject, cSecs, iMethod == 0 ? "RTMemCache" : "RTMemAlloc"); /* * Create a cache with unlimited space, a start semaphore and line up * the threads. */ RTTESTI_CHECK_RC_RETV(RTMemCacheCreate(&g_hMemCache, cbObject, 0 /*cbAlignment*/, UINT32_MAX, NULL, NULL, NULL, 0 /*fFlags*/), VINF_SUCCESS); RTSEMEVENTMULTI hEvt; RTTESTI_CHECK_RC_OK_RETV(RTSemEventMultiCreate(&hEvt)); TST3THREAD aThreads[64]; RTTESTI_CHECK_RETV(cThreads < RT_ELEMENTS(aThreads)); ASMAtomicWriteBool(&g_fTst3Stop, false); for (uint32_t i = 0; i < cThreads; i++) { aThreads[i].hThread = NIL_RTTHREAD; aThreads[i].cIterations = 0; aThreads[i].fUseCache = iMethod == 0; aThreads[i].cbObject = cbObject; aThreads[i].hEvt = hEvt; RTTESTI_CHECK_RC_OK_RETV(RTThreadCreateF(&aThreads[i].hThread, tst3Thread, &aThreads[i], 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tst3-%u", i)); } /* * Start the race. */ RTTimeNanoTS(); /* warmup */ uint64_t uStartTS = RTTimeNanoTS(); RTTESTI_CHECK_RC_OK_RETV(RTSemEventMultiSignal(hEvt)); RTThreadSleep(cSecs * 1000); ASMAtomicWriteBool(&g_fTst3Stop, true); for (uint32_t i = 0; i < cThreads; i++) RTTESTI_CHECK_RC_OK_RETV(RTThreadWait(aThreads[i].hThread, 60*1000, NULL)); uint64_t cElapsedNS = RTTimeNanoTS() - uStartTS; /* * Sum up the counts. */ uint64_t cIterations = 0; for (uint32_t i = 0; i < cThreads; i++) cIterations += aThreads[i].cIterations; RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second, %'llu ns on avg\n", (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS), cElapsedNS / cIterations); /* clean up */ RTTESTI_CHECK_RC(RTMemCacheDestroy(g_hMemCache), VINF_SUCCESS); RTTESTI_CHECK_RC_OK(RTSemEventMultiDestroy(hEvt)); }
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); }
void putKey(RTS3 hS3, const char *pszBucketName, const char *pszKeyName, const char *pszFilename) { /* Fetch the content of a key */ RTTestIPrintf(RTTESTLVL_ALWAYS, " Put '%s' into key '%s' in bucket '%s' ...\n", pszFilename, pszKeyName, pszBucketName); char pszTitle[] = "RTS3PutKey"; RTS3SetProgressCallback(hS3, progress, pszTitle); int rc = RTS3PutKey(hS3, pszBucketName, pszKeyName, pszFilename); if (RT_FAILURE(rc)) RTTestIFailed("RTS3PutKey -> %Rrc", rc); }
void createBucket(RTS3 hS3, const char *pszBucketName) { /* Create the bucket */ RTTestIPrintf(RTTESTLVL_ALWAYS, " Create bucket '%s'...\n", pszBucketName); char pszTitle[] = "RTS3CreateBucket"; RTS3SetProgressCallback(hS3, progress, pszTitle); int rc = RTS3CreateBucket(hS3, pszBucketName); if (RT_FAILURE(rc)) RTTestIFailed("RTS3CreateBucket -> %Rrc", rc); }
void deleteKey(RTS3 hS3, const char *pszBucketName, const char *pszKeyName) { /* Delete the key */ RTTestIPrintf(RTTESTLVL_ALWAYS, " Delete key '%s' in bucket '%s'...\n", pszKeyName, pszBucketName); char pszTitle[] = "RTS3DeleteKey"; RTS3SetProgressCallback(hS3, progress, pszTitle); int rc = RTS3DeleteKey(hS3, pszBucketName, pszKeyName); if (RT_FAILURE(rc)) RTTestIFailed("RTS3DeleteKey -> %Rrc", rc); }
static int tstRTFilesystem(RTTEST hTest, RTVFSFILE hVfsFile) { int rc = VINF_SUCCESS; RTVFS hVfs = NIL_RTVFS; RTTestSubF(hTest, "Create filesystem object"); rc = RTFilesystemVfsFromFile(hVfsFile, &hVfs); if (RT_FAILURE(rc)) { RTTestIFailed("RTFilesystemVfsFromFile -> %Rrc", rc); return rc; } /* Check all blocks. */ uint64_t off = 0; uint32_t cBlocksUsed = 0; uint32_t cBlocksUnused = 0; uint64_t cbFs = 0; rc = RTVfsFileGetSize(hVfsFile, &cbFs); if (RT_FAILURE(rc)) { RTTestIFailed("RTVfsFileGetSize -> %Rrc", rc); return rc; } while (off < cbFs) { bool fUsed = false; rc = RTVfsIsRangeInUse(hVfs, off, 1024, &fUsed); if (RT_FAILURE(rc)) { RTTestIFailed("RTVfsIsRangeInUse -> %Rrc", rc); break; } if (fUsed) cBlocksUsed++; else cBlocksUnused++; off += 1024; } if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_ALWAYS, "%u blocks used and %u blocks unused\n", cBlocksUsed, cBlocksUnused); RTVfsRelease(hVfs); return rc; }
static void tst1(size_t cTest, size_t cchDigits, char chSep) { RTTestISubF("tst #%u (digits: %u; sep: %c)", cTest, cchDigits, chSep ? chSep : ' '); /* We try to create max possible + one. */ size_t cTimes = 1; for (size_t i = 0; i < cchDigits; ++i) cTimes *= 10; /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); int rc = VERR_INTERNAL_ERROR; /* The test loop. */ size_t i; for (i = 0; i < cTimes; i++) { char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VINF_SUCCESS); if (RT_FAILURE(rc)) { RTTestIFailed("RTDirCreateUniqueNumbered(%s) call #%u -> %Rrc\n", szName, i, rc); break; } RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); } /* Try to create one more, which shouldn't be possible. */ if (RT_SUCCESS(rc)) { char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VERR_ALREADY_EXISTS); } /* cleanup */ while (i-- > 0) { RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
/** * Test automatic cleanup upon destruction. */ static void tst3(void) { RTTestISub("Destroy non-empty pool"); /* * Nothing freed. */ RTMEMPOOL hMemPool; RTTESTI_CHECK_RC_RETV(RTMemPoolCreate(&hMemPool, "test 3a"), VINF_SUCCESS); RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 10)); RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 20)); RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 40)); RTTESTI_CHECK_RETV(RTMemPoolAlloc(hMemPool, 80)); RTTESTI_CHECK_RC_RETV(RTMemPoolDestroy(hMemPool), VINF_SUCCESS); /* * Pseudo random freeing to test list maintenance. */ RTRAND hRand; RTTESTI_CHECK_RC_OK_RETV(RTRandAdvCreateParkMiller(&hRand)); for (uint32_t i = 0; i < 10; i++) { RTTESTI_CHECK_RC_RETV(RTMemPoolCreate(&hMemPool, "test 3b"), VINF_SUCCESS); void *apvHistory[256]; RT_ZERO(apvHistory); uint32_t cBlocks = 0; uint32_t j; for (j = 0; j < RT_ELEMENTS(apvHistory) - i * 7; j++) { RTTESTI_CHECK_RETV(apvHistory[j] = RTMemPoolAlloc(hMemPool, j)); memset(apvHistory[j], 'a', j); cBlocks++; if (RTRandAdvU32Ex(hRand, 0, 4) == 4) { uint32_t iFree = RTRandAdvU32Ex(hRand, 0, j); cBlocks -= apvHistory[iFree] != NULL; RTTESTI_CHECK_RETV(RTMemPoolRelease(hMemPool, apvHistory[iFree]) == 0); apvHistory[iFree] = NULL; } } RTTESTI_CHECK_RC_RETV(RTMemPoolDestroy(hMemPool), VINF_SUCCESS); RTTestIPrintf(RTTESTLVL_INFO, "cBlocks=%u j=%u\n", cBlocks, j); } RTRandAdvDestroy(hRand); }
static void testDisas(const char *pszSub, uint8_t const *pabInstrs, uintptr_t uEndPtr, DISCPUMODE enmDisCpuMode) { RTTestISub(pszSub); size_t const cbInstrs = uEndPtr - (uintptr_t)pabInstrs; for (size_t off = 0; off < cbInstrs;) { uint32_t const cErrBefore = RTTestIErrorCount(); uint32_t cb = 1; DISSTATE Dis; char szOutput[256] = {0}; int rc = DISInstrToStr(&pabInstrs[off], enmDisCpuMode, &Dis, &cb, szOutput, sizeof(szOutput)); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); RTTESTI_CHECK(cb == Dis.cbInstr); RTTESTI_CHECK(cb > 0); RTTESTI_CHECK(cb <= 16); RTStrStripR(szOutput); RTTESTI_CHECK(szOutput[0]); if (szOutput[0]) { char *pszBytes = strchr(szOutput, '['); RTTESTI_CHECK(pszBytes); if (pszBytes) { RTTESTI_CHECK(pszBytes[-1] == ' '); RTTESTI_CHECK(RT_C_IS_XDIGIT(pszBytes[1])); RTTESTI_CHECK(pszBytes[cb * 3] == ']'); RTTESTI_CHECK(pszBytes[cb * 3 + 1] == ' '); size_t cch = strlen(szOutput); RTTESTI_CHECK(szOutput[cch - 1] != ','); } } if (cErrBefore != RTTestIErrorCount()) RTTestIFailureDetails("rc=%Rrc, off=%#x (%u) cbInstr=%u enmDisCpuMode=%d\n", rc, off, Dis.cbInstr, enmDisCpuMode); RTTestIPrintf(RTTESTLVL_ALWAYS, "%s\n", szOutput); /* Check with size-only. */ uint32_t cbOnly = 1; DISSTATE DisOnly; rc = DISInstrWithPrefetchedBytes((uintptr_t)&pabInstrs[off], enmDisCpuMode, 0 /*fFilter - none */, Dis.abInstr, Dis.cbCachedInstr, NULL, NULL, &DisOnly, &cbOnly); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); RTTESTI_CHECK(cbOnly == DisOnly.cbInstr); RTTESTI_CHECK_MSG(cbOnly == cb, ("%#x vs %#x\n", cbOnly, cb)); off += cb; } }
static void testFile(const char *pszFilename) { size_t cbSrcActually = 0; void *pvSrc; size_t cbSrc; int rc = RTFileReadAll(pszFilename, &pvSrc, &cbSrc); RTTESTI_CHECK_RC_OK_RETV(rc); size_t cbDstActually = 0; size_t cbDst = RT_MAX(cbSrc * 8, _1M); void *pvDst = RTMemAllocZ(cbDst); rc = RTZipBlockDecompress(RTZIPTYPE_ZLIB, 0, pvSrc, cbSrc, &cbSrcActually, pvDst, cbDst, &cbDstActually); RTTestIPrintf(RTTESTLVL_ALWAYS, "cbSrc=%zu cbSrcActually=%zu cbDst=%zu cbDstActually=%zu rc=%Rrc\n", cbSrc, cbSrcActually, cbDst, cbDstActually, rc); RTTESTI_CHECK_RC_OK(rc); }
static void tstRTPipe3(void) { RTTestISub("Full write buffer"); RTPIPE hPipeR = (RTPIPE)999999; RTPIPE hPipeW = (RTPIPE)999999; RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS); static char s_abBuf[_256K]; int rc = VINF_SUCCESS; size_t cbTotal = 0; memset(s_abBuf, 0xff, sizeof(s_abBuf)); for (;;) { RTTESTI_CHECK(cbTotal < _1G); if (cbTotal > _1G) break; size_t cbWritten = _1G; rc = RTPipeWrite(hPipeW, s_abBuf, sizeof(s_abBuf), &cbWritten); RTTESTI_CHECK_MSG(rc == VINF_SUCCESS || rc == VINF_TRY_AGAIN, ("rc=%Rrc\n", rc)); if (rc != VINF_SUCCESS) break; cbTotal += cbWritten; } if (rc == VINF_TRY_AGAIN) { RTTestIPrintf(RTTESTLVL_ALWAYS, "cbTotal=%zu (%#zx)\n", cbTotal, cbTotal); RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 0), VERR_TIMEOUT); RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 1), VERR_TIMEOUT); size_t cbRead; RTTESTI_CHECK_RC(RTPipeRead(hPipeR, s_abBuf, RT_MIN(sizeof(s_abBuf), cbTotal) / 2, &cbRead), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 0), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 1), VINF_SUCCESS); size_t cbWritten = _1G; rc = RTPipeWrite(hPipeW, s_abBuf, sizeof(s_abBuf), &cbWritten); RTTESTI_CHECK(rc == VINF_SUCCESS); } RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS); }
static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck) { RTTestISub(pszSubTest); /* 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]; 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 = RTDirCreateTemp(papszNames[i]); if (rc != VINF_SUCCESS) { RTTestIFailed("RTDirCreateTemp(%s) call #%u -> %Rrc\n", szName, i, rc); RTStrFree(papszNames[i]); papszNames[i] = NULL; break; } RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("szName %s\nReturned %s\n", szName, papszNames[i])); if (!fSkipXCheck) RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("szName %s\nReturned %s\n", szName, papszNames[i])); } /* cleanup */ while (i-- > 0) { RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
void tst(int iFrom, int iTo, int iInc) { #ifdef VMM_R0_SWITCH_STACK int const cIterations = iFrom > iTo ? iFrom - iTo : iTo - iFrom; void *pvPrev = alloca(1); #endif RTR0PTR R0PtrSaved = g_Jmp.pvSavedStack; RT_ZERO(g_Jmp); g_Jmp.pvSavedStack = R0PtrSaved; memset((void *)g_Jmp.pvSavedStack, '\0', VMM_STACK_SIZE); g_cbFoo = 0; g_cJmps = 0; g_cbFooUsed = 0; for (int i = iFrom, iItr = 0; i != iTo; i += iInc, iItr++) { int rc = vmmR0CallRing3SetJmp(&g_Jmp, (PFNVMMR0SETJMP)tst2, (PVM)i, 0); RTTESTI_CHECK_MSG_RETV(rc == 0 || rc == 42, ("i=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x\n", i, rc, g_cbFoo, g_cbFooUsed)); #ifdef VMM_R0_SWITCH_STACK /* Make the stack pointer slide for the second half of the calls. */ if (iItr >= cIterations / 2) { /* Note! gcc does funny rounding up of alloca(). */ void *pv2 = alloca((i % 63) | 1); size_t cb2 = (uintptr_t)pvPrev - (uintptr_t)pv2; RTTESTI_CHECK_MSG(cb2 >= 16 && cb2 <= 128, ("cb2=%zu pv2=%p pvPrev=%p iAlloca=%d\n", cb2, pv2, pvPrev, iItr)); memset(pv2, 0xff, cb2); memset(pvPrev, 0xee, 1); pvPrev = pv2; } #endif } RTTESTI_CHECK_MSG_RETV(g_cJmps, ("No jumps!")); if (g_Jmp.cbUsedAvg || g_Jmp.cUsedTotal) RTTestIPrintf(RTTESTLVL_ALWAYS, "cbUsedAvg=%#x cbUsedMax=%#x cUsedTotal=%#llx\n", g_Jmp.cbUsedAvg, g_Jmp.cbUsedMax, g_Jmp.cUsedTotal); }
int main(int argc, char *argv[]) { /* * Init runtime. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstRTHeapSimple", &hTest); if (rc) return rc; RTTestBanner(hTest); /* * Create a heap. */ RTTestSub(hTest, "Basics"); static uint8_t s_abMem[128*1024]; RTHEAPSIMPLE Heap; RTTESTI_CHECK_RC(rc = RTHeapSimpleInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); /* * Try allocate. */ static struct TstHeapSimpleOps { size_t cb; unsigned uAlignment; void *pvAlloc; unsigned iFreeOrder; } s_aOps[] = { { 16, 0, NULL, 0 }, // 0 { 16, 4, NULL, 1 }, { 16, 8, NULL, 2 }, { 16, 16, NULL, 5 }, { 16, 32, NULL, 4 }, { 32, 0, NULL, 3 }, // 5 { 31, 0, NULL, 6 }, { 1024, 0, NULL, 8 }, { 1024, 32, NULL, 10 }, { 1024, 32, NULL, 12 }, { PAGE_SIZE, PAGE_SIZE, NULL, 13 }, // 10 { 1024, 32, NULL, 9 }, { PAGE_SIZE, 32, NULL, 11 }, { PAGE_SIZE, PAGE_SIZE, NULL, 14 }, { 16, 0, NULL, 15 }, { 9, 0, NULL, 7 }, // 15 { 16, 0, NULL, 7 }, { 36, 0, NULL, 7 }, { 16, 0, NULL, 7 }, { 12344, 0, NULL, 7 }, { 50, 0, NULL, 7 }, // 20 { 16, 0, NULL, 7 }, }; unsigned i; RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); /** @todo Add some detail info output with a signature identical to RTPrintf. */ size_t cbBefore = RTHeapSimpleGetFreeSize(Heap); static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* allocate */ for (i = 0; i < RT_ELEMENTS(s_aOps); i++) { s_aOps[i].pvAlloc = RTHeapSimpleAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment); RTTESTI_CHECK_MSG(s_aOps[i].pvAlloc, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i)); if (!s_aOps[i].pvAlloc) return RTTestSummaryAndDestroy(hTest); memset(s_aOps[i].pvAlloc, szFill[i], s_aOps[i].cb); RTTESTI_CHECK_MSG(RT_ALIGN_P(s_aOps[i].pvAlloc, (s_aOps[i].uAlignment ? s_aOps[i].uAlignment : 8)) == s_aOps[i].pvAlloc, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> %p\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i)); if (!s_aOps[i].pvAlloc) return RTTestSummaryAndDestroy(hTest); } /* free and allocate the same node again. */ for (i = 0; i < RT_ELEMENTS(s_aOps); i++) { if (!s_aOps[i].pvAlloc) continue; //RTPrintf("debug: i=%d pv=%#x cb=%#zx align=%#zx cbReal=%#zx\n", i, s_aOps[i].pvAlloc, // s_aOps[i].cb, s_aOps[i].uAlignment, RTHeapSimpleSize(Heap, s_aOps[i].pvAlloc)); size_t cbBeforeSub = RTHeapSimpleGetFreeSize(Heap); RTHeapSimpleFree(Heap, s_aOps[i].pvAlloc); size_t cbAfterSubFree = RTHeapSimpleGetFreeSize(Heap); void *pv; pv = RTHeapSimpleAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment); RTTESTI_CHECK_MSG(pv, ("RTHeapSimpleAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i)); if (!pv) return RTTestSummaryAndDestroy(hTest); //RTPrintf("debug: i=%d pv=%p cbReal=%#zx cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx \n", i, pv, RTHeapSimpleSize(Heap, pv), // cbBeforeSub, cbAfterSubFree, RTHeapSimpleGetFreeSize(Heap)); if (pv != s_aOps[i].pvAlloc) RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: Free+Alloc returned different address. new=%p old=%p i=%d\n", pv, s_aOps[i].pvAlloc, i); s_aOps[i].pvAlloc = pv; size_t cbAfterSubAlloc = RTHeapSimpleGetFreeSize(Heap); if (cbBeforeSub != cbAfterSubAlloc) { RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx. i=%d\n", cbBeforeSub, cbAfterSubFree, cbAfterSubAlloc, i); //return 1; - won't work correctly until we start creating free block instead of donating memory on alignment. } } /* make a copy of the heap and the to-be-freed list. */ static uint8_t s_abMemCopy[sizeof(s_abMem)]; memcpy(s_abMemCopy, s_abMem, sizeof(s_abMem)); uintptr_t offDelta = (uintptr_t)&s_abMemCopy[0] - (uintptr_t)&s_abMem[0]; RTHEAPSIMPLE hHeapCopy = (RTHEAPSIMPLE)((uintptr_t)Heap + offDelta); static struct TstHeapSimpleOps s_aOpsCopy[RT_ELEMENTS(s_aOps)]; memcpy(&s_aOpsCopy[0], &s_aOps[0], sizeof(s_aOps)); /* free it in a specific order. */ int cFreed = 0; for (i = 0; i < RT_ELEMENTS(s_aOps); i++) { unsigned j; for (j = 0; j < RT_ELEMENTS(s_aOps); j++) { if ( s_aOps[j].iFreeOrder != i || !s_aOps[j].pvAlloc) continue; //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(Heap), s_aOps[j].cb, s_aOps[j].pvAlloc); RTHeapSimpleFree(Heap, s_aOps[j].pvAlloc); s_aOps[j].pvAlloc = NULL; cFreed++; } } RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOps)); RTTestIPrintf(RTTESTLVL_ALWAYS, "i=done free=%d\n", RTHeapSimpleGetFreeSize(Heap)); /* check that we're back at the right amount of free memory. */ size_t cbAfter = RTHeapSimpleGetFreeSize(Heap); if (cbBefore != cbAfter) { RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: Either we've split out an alignment chunk at the start, or we've got\n" " an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter); RTHeapSimpleDump(Heap, (PFNRTHEAPSIMPLEPRINTF)RTPrintf); } /* relocate and free the bits in heap2 now. */ RTTestSub(hTest, "RTHeapSimpleRelocate"); rc = RTHeapSimpleRelocate(hHeapCopy, offDelta); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); if (RT_SUCCESS(rc)) { /* free it in a specific order. */ int cFreed2 = 0; for (i = 0; i < RT_ELEMENTS(s_aOpsCopy); i++) { unsigned j; for (j = 0; j < RT_ELEMENTS(s_aOpsCopy); j++) { if ( s_aOpsCopy[j].iFreeOrder != i || !s_aOpsCopy[j].pvAlloc) continue; //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapSimpleGetFreeSize(hHeapCopy), s_aOpsCopy[j].cb, s_aOpsCopy[j].pvAlloc); RTHeapSimpleFree(hHeapCopy, (uint8_t *)s_aOpsCopy[j].pvAlloc + offDelta); s_aOpsCopy[j].pvAlloc = NULL; cFreed2++; } } RTTESTI_CHECK(cFreed2 == RT_ELEMENTS(s_aOpsCopy)); /* check that we're back at the right amount of free memory. */ size_t cbAfterCopy = RTHeapSimpleGetFreeSize(hHeapCopy); RTTESTI_CHECK_MSG(cbAfterCopy == cbAfter, ("cbAfterCopy=%zu cbAfter=%zu\n", cbAfterCopy, cbAfter)); } return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char *argv[]) { /* * Init runtime. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstRTHeapOffset", &hTest); if (rc) return rc; RTTestBanner(hTest); /* * Create a heap. */ RTTestSub(hTest, "Basics"); static uint8_t s_abMem[128*1024]; RTHEAPOFFSET Heap; RTTESTI_CHECK_RC(rc = RTHeapOffsetInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); /* * Try allocate. */ static struct TstHeapOffsetOps { size_t cb; unsigned uAlignment; void *pvAlloc; unsigned iFreeOrder; } s_aOps[] = { { 16, 0, NULL, 0 }, // 0 { 16, 4, NULL, 1 }, { 16, 8, NULL, 2 }, { 16, 16, NULL, 5 }, { 16, 32, NULL, 4 }, { 32, 0, NULL, 3 }, // 5 { 31, 0, NULL, 6 }, { 1024, 0, NULL, 8 }, { 1024, 32, NULL, 10 }, { 1024, 32, NULL, 12 }, { PAGE_SIZE, PAGE_SIZE, NULL, 13 }, // 10 { 1024, 32, NULL, 9 }, { PAGE_SIZE, 32, NULL, 11 }, { PAGE_SIZE, PAGE_SIZE, NULL, 14 }, { 16, 0, NULL, 15 }, { 9, 0, NULL, 7 }, // 15 { 16, 0, NULL, 7 }, { 36, 0, NULL, 7 }, { 16, 0, NULL, 7 }, { 12344, 0, NULL, 7 }, { 50, 0, NULL, 7 }, // 20 { 16, 0, NULL, 7 }, }; uint32_t i; RTHeapOffsetDump(Heap, (PFNRTHEAPOFFSETPRINTF)RTPrintf); /** @todo Add some detail info output with a signature identical to RTPrintf. */ size_t cbBefore = RTHeapOffsetGetFreeSize(Heap); static char const s_szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* allocate */ for (i = 0; i < RT_ELEMENTS(s_aOps); i++) { s_aOps[i].pvAlloc = RTHeapOffsetAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment); RTTESTI_CHECK_MSG(s_aOps[i].pvAlloc, ("RTHeapOffsetAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i)); if (!s_aOps[i].pvAlloc) return RTTestSummaryAndDestroy(hTest); memset(s_aOps[i].pvAlloc, s_szFill[i], s_aOps[i].cb); RTTESTI_CHECK_MSG(RT_ALIGN_P(s_aOps[i].pvAlloc, (s_aOps[i].uAlignment ? s_aOps[i].uAlignment : 8)) == s_aOps[i].pvAlloc, ("RTHeapOffsetAlloc(%p, %#x, %#x,) -> %p\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i)); if (!s_aOps[i].pvAlloc) return RTTestSummaryAndDestroy(hTest); } /* free and allocate the same node again. */ for (i = 0; i < RT_ELEMENTS(s_aOps); i++) { if (!s_aOps[i].pvAlloc) continue; //RTPrintf("debug: i=%d pv=%#x cb=%#zx align=%#zx cbReal=%#zx\n", i, s_aOps[i].pvAlloc, // s_aOps[i].cb, s_aOps[i].uAlignment, RTHeapOffsetSize(Heap, s_aOps[i].pvAlloc)); size_t cbBeforeSub = RTHeapOffsetGetFreeSize(Heap); RTHeapOffsetFree(Heap, s_aOps[i].pvAlloc); size_t cbAfterSubFree = RTHeapOffsetGetFreeSize(Heap); void *pv; pv = RTHeapOffsetAlloc(Heap, s_aOps[i].cb, s_aOps[i].uAlignment); RTTESTI_CHECK_MSG(pv, ("RTHeapOffsetAlloc(%p, %#x, %#x,) -> NULL i=%d\n", (void *)Heap, s_aOps[i].cb, s_aOps[i].uAlignment, i)); if (!pv) return RTTestSummaryAndDestroy(hTest); //RTPrintf("debug: i=%d pv=%p cbReal=%#zx cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx \n", i, pv, RTHeapOffsetSize(Heap, pv), // cbBeforeSub, cbAfterSubFree, RTHeapOffsetGetFreeSize(Heap)); if (pv != s_aOps[i].pvAlloc) RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: Free+Alloc returned different address. new=%p old=%p i=%d\n", pv, s_aOps[i].pvAlloc, i); s_aOps[i].pvAlloc = pv; size_t cbAfterSubAlloc = RTHeapOffsetGetFreeSize(Heap); if (cbBeforeSub != cbAfterSubAlloc) { RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: cbBeforeSub=%#zx cbAfterSubFree=%#zx cbAfterSubAlloc=%#zx. i=%d\n", cbBeforeSub, cbAfterSubFree, cbAfterSubAlloc, i); //return 1; - won't work correctly until we start creating free block instead of donating memory on alignment. } } /* make a copy of the heap and the to-be-freed list. */ static uint8_t s_abMemCopy[sizeof(s_abMem)]; memcpy(s_abMemCopy, s_abMem, sizeof(s_abMem)); uintptr_t offDelta = (uintptr_t)&s_abMemCopy[0] - (uintptr_t)&s_abMem[0]; RTHEAPOFFSET hHeapCopy = (RTHEAPOFFSET)((uintptr_t)Heap + offDelta); static struct TstHeapOffsetOps s_aOpsCopy[RT_ELEMENTS(s_aOps)]; memcpy(&s_aOpsCopy[0], &s_aOps[0], sizeof(s_aOps)); /* free it in a specific order. */ int cFreed = 0; for (i = 0; i < RT_ELEMENTS(s_aOps); i++) { unsigned j; for (j = 0; j < RT_ELEMENTS(s_aOps); j++) { if ( s_aOps[j].iFreeOrder != i || !s_aOps[j].pvAlloc) continue; //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapOffsetGetFreeSize(Heap), s_aOps[j].cb, s_aOps[j].pvAlloc); RTHeapOffsetFree(Heap, s_aOps[j].pvAlloc); s_aOps[j].pvAlloc = NULL; cFreed++; } } RTTESTI_CHECK(cFreed == RT_ELEMENTS(s_aOps)); RTTestIPrintf(RTTESTLVL_ALWAYS, "i=done free=%d\n", RTHeapOffsetGetFreeSize(Heap)); /* check that we're back at the right amount of free memory. */ size_t cbAfter = RTHeapOffsetGetFreeSize(Heap); if (cbBefore != cbAfter) { RTTestIPrintf(RTTESTLVL_ALWAYS, "Warning: Either we've split out an alignment chunk at the start, or we've got\n" " an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter); RTHeapOffsetDump(Heap, (PFNRTHEAPOFFSETPRINTF)RTPrintf); } /* relocate and free the bits in heap2 now. */ RTTestSub(hTest, "Relocated Heap"); /* free it in a specific order. */ int cFreed2 = 0; for (i = 0; i < RT_ELEMENTS(s_aOpsCopy); i++) { unsigned j; for (j = 0; j < RT_ELEMENTS(s_aOpsCopy); j++) { if ( s_aOpsCopy[j].iFreeOrder != i || !s_aOpsCopy[j].pvAlloc) continue; //RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, RTHeapOffsetGetFreeSize(hHeapCopy), s_aOpsCopy[j].cb, s_aOpsCopy[j].pvAlloc); RTHeapOffsetFree(hHeapCopy, (uint8_t *)s_aOpsCopy[j].pvAlloc + offDelta); s_aOpsCopy[j].pvAlloc = NULL; cFreed2++; } } RTTESTI_CHECK(cFreed2 == RT_ELEMENTS(s_aOpsCopy)); /* check that we're back at the right amount of free memory. */ size_t cbAfterCopy = RTHeapOffsetGetFreeSize(hHeapCopy); RTTESTI_CHECK_MSG(cbAfterCopy == cbAfter, ("cbAfterCopy=%zu cbAfter=%zu\n", cbAfterCopy, cbAfter)); /* * Use random allocation pattern */ RTTestSub(hTest, "Random Test"); RTTESTI_CHECK_RC(rc = RTHeapOffsetInit(&Heap, &s_abMem[1], sizeof(s_abMem) - 1), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTRAND hRand; RTTESTI_CHECK_RC(rc = RTRandAdvCreateParkMiller(&hRand), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); #if 0 RTRandAdvSeed(hRand, 42); #else RTRandAdvSeed(hRand, RTTimeNanoTS()); #endif static struct { size_t cb; void *pv; } s_aHistory[1536]; RT_ZERO(s_aHistory); for (unsigned iTest = 0; iTest < 131072; iTest++) { i = RTRandAdvU32Ex(hRand, 0, RT_ELEMENTS(s_aHistory) - 1); if (!s_aHistory[i].pv) { uint32_t uAlignment = 1 << RTRandAdvU32Ex(hRand, 0, 7); s_aHistory[i].cb = RTRandAdvU32Ex(hRand, 9, 1024); s_aHistory[i].pv = RTHeapOffsetAlloc(Heap, s_aHistory[i].cb, uAlignment); if (!s_aHistory[i].pv) { s_aHistory[i].cb = 9; s_aHistory[i].pv = RTHeapOffsetAlloc(Heap, s_aHistory[i].cb, 0); } if (s_aHistory[i].pv) memset(s_aHistory[i].pv, 0xbb, s_aHistory[i].cb); } else { RTHeapOffsetFree(Heap, s_aHistory[i].pv); s_aHistory[i].pv = NULL; } if ((iTest % 7777) == 7776) { /* exhaust the heap */ for (i = 0; i < RT_ELEMENTS(s_aHistory) && RTHeapOffsetGetFreeSize(Heap) >= 256; i++) if (!s_aHistory[i].pv) { s_aHistory[i].cb = RTRandAdvU32Ex(hRand, 256, 16384); s_aHistory[i].pv = RTHeapOffsetAlloc(Heap, s_aHistory[i].cb, 0); } for (i = 0; i < RT_ELEMENTS(s_aHistory) && RTHeapOffsetGetFreeSize(Heap); i++) { if (!s_aHistory[i].pv) { s_aHistory[i].cb = 1; s_aHistory[i].pv = RTHeapOffsetAlloc(Heap, s_aHistory[i].cb, 1); } if (s_aHistory[i].pv) memset(s_aHistory[i].pv, 0x55, s_aHistory[i].cb); } RTTESTI_CHECK_MSG(RTHeapOffsetGetFreeSize(Heap) == 0, ("%zu\n", RTHeapOffsetGetFreeSize(Heap))); } else if ((iTest % 7777) == 1111) { /* free all */ for (i = 0; i < RT_ELEMENTS(s_aHistory); i++) { RTHeapOffsetFree(Heap, s_aHistory[i].pv); s_aHistory[i].pv = NULL; } size_t cbAfterRand = RTHeapOffsetGetFreeSize(Heap); RTTESTI_CHECK_MSG(cbAfterRand == cbAfter, ("cbAfterRand=%zu cbAfter=%zu\n", cbAfterRand, cbAfter)); } } /* free the rest. */ for (i = 0; i < RT_ELEMENTS(s_aHistory); i++) { RTHeapOffsetFree(Heap, s_aHistory[i].pv); s_aHistory[i].pv = NULL; } /* check that we're back at the right amount of free memory. */ size_t cbAfterRand = RTHeapOffsetGetFreeSize(Heap); RTTESTI_CHECK_MSG(cbAfterRand == cbAfter, ("cbAfterRand=%zu cbAfter=%zu\n", cbAfterRand, cbAfter)); return RTTestSummaryAndDestroy(hTest); }
int main() { RTTEST hTest; RTEXITCODE rcExit = RTTestInitAndCreate("tstRTMp-1", &hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; RTTestBanner(hTest); /* * Present and possible CPUs. */ RTCPUID cCpus = RTMpGetCount(); if (cCpus > 0) RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetCount -> %u\n", cCpus); else { RTTestIFailed("RTMpGetCount returned zero"); cCpus = 1; } RTCPUID cCoreCpus = RTMpGetCoreCount(); if (cCoreCpus > 0) RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetCoreCount -> %d\n", (int)cCoreCpus); else { RTTestIFailed("RTMpGetCoreCount returned zero"); cCoreCpus = 1; } RTTESTI_CHECK(cCoreCpus <= cCpus); RTCPUSET Set; PRTCPUSET pSet = RTMpGetSet(&Set); RTTESTI_CHECK(pSet == &Set); if (pSet == &Set) { RTTESTI_CHECK((RTCPUID)RTCpuSetCount(&Set) == cCpus); RTTestIPrintf(RTTESTLVL_ALWAYS, "Possible CPU mask:\n"); for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) { RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); if (RTCpuSetIsMemberByIndex(&Set, iCpu)) { RTTestIPrintf(RTTESTLVL_ALWAYS, "%2d - id %d: %u/%u MHz", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), RTMpGetMaxFrequency(idCpu)); if (RTMpIsCpuPresent(idCpu)) RTTestIPrintf(RTTESTLVL_ALWAYS, RTMpIsCpuOnline(idCpu) ? " online\n" : " offline\n"); else { if (!RTMpIsCpuOnline(idCpu)) RTTestIPrintf(RTTESTLVL_ALWAYS, " absent\n"); else { RTTestIPrintf(RTTESTLVL_ALWAYS, " online but absent!\n"); RTTestIFailed("Cpu with index %d is report as !RTIsCpuPresent while RTIsCpuOnline returns true!\n", iCpu); } } if (!RTMpIsCpuPossible(idCpu)) RTTestIFailed("Cpu with index %d is returned by RTCpuSet but not RTMpIsCpuPossible!\n", iCpu); } else if (RTMpIsCpuPossible(idCpu)) RTTestIFailed("Cpu with index %d is returned by RTMpIsCpuPossible but not RTCpuSet!\n", iCpu); else if (RTMpGetCurFrequency(idCpu) != 0) RTTestIFailed("RTMpGetCurFrequency(%d[idx=%d]) didn't return 0 as it should\n", (int)idCpu, iCpu); else if (RTMpGetMaxFrequency(idCpu) != 0) RTTestIFailed("RTMpGetMaxFrequency(%d[idx=%d]) didn't return 0 as it should\n", (int)idCpu, iCpu); } } else { RTCpuSetEmpty(&Set); RTCpuSetAdd(&Set, RTMpCpuIdFromSetIndex(0)); } /* * Online CPUs. */ RTCPUID cCpusOnline = RTMpGetOnlineCount(); if (cCpusOnline > 0) { if (cCpusOnline <= cCpus) RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); else { RTTestIFailed("RTMpGetOnlineCount -> %d, expected <= %d\n", (int)cCpusOnline, (int)cCpus); cCpusOnline = cCpus; } } else { RTTestIFailed("RTMpGetOnlineCount -> %d\n", (int)cCpusOnline); cCpusOnline = 1; } RTCPUID cCoresOnline = RTMpGetOnlineCoreCount(); if (cCoresOnline > 0) RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetOnlineCoreCount -> %d\n", (int)cCoresOnline); else { RTTestIFailed("RTMpGetOnlineCoreCount -> %d, expected <= %d\n", (int)cCoresOnline, (int)cCpusOnline); cCoresOnline = 1; } RTTESTI_CHECK(cCoresOnline <= cCpusOnline); RTCPUSET SetOnline; pSet = RTMpGetOnlineSet(&SetOnline); if (pSet == &SetOnline) { if (RTCpuSetCount(&SetOnline) <= 0) RTTestIFailed("RTMpGetOnlineSet returned an empty set!\n"); else if ((RTCPUID)RTCpuSetCount(&SetOnline) > cCpus) RTTestIFailed("RTMpGetOnlineSet returned a too high value; %d, expected <= %d\n", RTCpuSetCount(&SetOnline), cCpus); RTTestIPrintf(RTTESTLVL_ALWAYS, "Online CPU mask:\n"); for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) if (RTCpuSetIsMemberByIndex(&SetOnline, iCpu)) { RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); RTTestIPrintf(RTTESTLVL_ALWAYS, "%2d - id %d: %u/%u MHz %s\n", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), RTMpGetMaxFrequency(idCpu), RTMpIsCpuOnline(idCpu) ? "online" : "offline"); if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) RTTestIFailed("online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); } /* There isn't any sane way of testing RTMpIsCpuOnline really... :-/ */ } else RTTestIFailed("RTMpGetOnlineSet -> %p, expected %p\n", pSet, &Set); /* * Present CPUs. */ RTCPUID cCpusPresent = RTMpGetPresentCount(); if (cCpusPresent > 0) { if ( cCpusPresent <= cCpus && cCpusPresent >= cCpusOnline) RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetPresentCount -> %d\n", (int)cCpusPresent); else RTTestIFailed("RTMpGetPresentCount -> %d, expected <= %d and >= %d\n", (int)cCpusPresent, (int)cCpus, (int)cCpusOnline); } else { RTTestIFailed("RTMpGetPresentCount -> %d\n", (int)cCpusPresent); cCpusPresent = 1; } RTCPUSET SetPresent; pSet = RTMpGetPresentSet(&SetPresent); if (pSet == &SetPresent) { if (RTCpuSetCount(&SetPresent) <= 0) RTTestIFailed("RTMpGetPresentSet returned an empty set!\n"); else if ((RTCPUID)RTCpuSetCount(&SetPresent) != cCpusPresent) RTTestIFailed("RTMpGetPresentSet returned a bad value; %d, expected = %d\n", RTCpuSetCount(&SetPresent), cCpusPresent); RTTestIPrintf(RTTESTLVL_ALWAYS, "Present CPU mask:\n"); for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) if (RTCpuSetIsMemberByIndex(&SetPresent, iCpu)) { RTCPUID idCpu = RTMpCpuIdFromSetIndex(iCpu); RTTestIPrintf(RTTESTLVL_ALWAYS, "%2d - id %d: %u/%u MHz %s\n", iCpu, (int)idCpu, RTMpGetCurFrequency(idCpu), RTMpGetMaxFrequency(idCpu), RTMpIsCpuPresent(idCpu) ? "present" : "absent"); if (!RTCpuSetIsMemberByIndex(&Set, iCpu)) RTTestIFailed("online cpu with index %2d is not a member of the possible cpu set!\n", iCpu); } /* There isn't any sane way of testing RTMpIsCpuPresent really... :-/ */ } else RTTestIFailed("RTMpGetPresentSet -> %p, expected %p\n", pSet, &Set); /* Find an online cpu for the next test. */ RTCPUID idCpuOnline; for (idCpuOnline = 0; idCpuOnline < RTCPUSET_MAX_CPUS; idCpuOnline++) if (RTMpIsCpuOnline(idCpuOnline)) break; /* * Quick test of RTMpGetDescription. */ char szBuf[64]; int rc = RTMpGetDescription(idCpuOnline, &szBuf[0], sizeof(szBuf)); if (RT_SUCCESS(rc)) { RTTestIPrintf(RTTESTLVL_ALWAYS, "RTMpGetDescription -> '%s'\n", szBuf); size_t cch = strlen(szBuf); rc = RTMpGetDescription(idCpuOnline, &szBuf[0], cch); if (rc != VERR_BUFFER_OVERFLOW) RTTestIFailed("RTMpGetDescription -> %Rrc, expected VERR_BUFFER_OVERFLOW\n", rc); rc = RTMpGetDescription(idCpuOnline, &szBuf[0], cch + 1); if (RT_FAILURE(rc)) RTTestIFailed("RTMpGetDescription -> %Rrc, expected VINF_SUCCESS\n", rc); } else RTTestIFailed("RTMpGetDescription -> %Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); }
int main (int argc, char **argv) { #ifndef VBOX RTPrintf("tstSup: SKIPPED\n"); return 0; #else /* * Init. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstRTR0DbgKrnlInfo", &hTest); if (rc) return rc; RTTestBanner(hTest); uint8_t *pbPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE); if (!pbPage) { RTTestFailed(hTest, "RTTestGuardedAllocTail failed with rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); } PSUPDRVSESSION pSession; rc = SUPR3Init(&pSession); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); } char szPath[RTPATH_MAX]; rc = RTPathExecDir(szPath, sizeof(szPath)); if (RT_SUCCESS(rc)) rc = RTPathAppend(szPath, sizeof(szPath), "tstRTR0DbgKrnlInfo.r0"); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc); return RTTestSummaryAndDestroy(hTest); } void *pvImageBase; rc = SUPR3LoadServiceModule(szPath, "tstRTR0DbgKrnlInfo", "TSTR0DbgKrnlInfoSrvReqHandler", &pvImageBase); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc); return RTTestSummaryAndDestroy(hTest); } /* test request */ struct { SUPR0SERVICEREQHDR Hdr; char szMsg[256]; } Req; /* * Sanity checks. */ RTTestSub(hTest, "Sanity"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1, TSTRTR0DBGKRNLINFO_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg)); if (Req.szMsg[0] != '\0') return RTTestSummaryAndDestroy(hTest); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1, TSTRTR0DBGKRNLINFO_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg)); if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42"))) return RTTestSummaryAndDestroy(hTest); /* * Basic tests, bail out on failure. */ RTTestSub(hTest, "Basics"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1, TSTRTR0DBGKRNLINFO_BASIC, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); if (Req.szMsg[0] == '!') { RTTestIFailed("%s", &Req.szMsg[1]); return RTTestSummaryAndDestroy(hTest); } if (Req.szMsg[0]) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); /* * Done. */ return RTTestSummaryAndDestroy(hTest); #endif }
static void tstQueryVirtualMemory(void) { RTTestISub("NtQueryVirtualMemory"); uintptr_t cbAdvance = 0; uintptr_t uPtrWhere = 0; for (;;) { SIZE_T cbActual = 0; MEMORY_BASIC_INFORMATION MemInfo = { 0, 0, 0, 0, 0, 0, 0 }; NTSTATUS rcNt = NtQueryVirtualMemory(g_hProcess, (void const *)uPtrWhere, MemoryBasicInformation, &MemInfo, sizeof(MemInfo), &cbActual); if (!NT_SUCCESS(rcNt)) { RTTestIPrintf(RTTESTLVL_ALWAYS, "%p: rcNt=%#x\n", uPtrWhere, rcNt); break; } /* stringify the memory state. */ char szMemType[1024]; char szMemState[1024]; char szMemProt[1024]; char szAllocProt[1024]; if ( MemInfo.AllocationBase != NULL && MemInfo.AllocationBase == MemInfo.BaseAddress && MemInfo.Protect != MemInfo.AllocationProtect) RTTestIPrintf(RTTESTLVL_ALWAYS, "\n"); RTTestIPrintf(RTTESTLVL_ALWAYS, "%p-%p %-8s %-8s %-12s", MemInfo.BaseAddress, (uintptr_t)MemInfo.BaseAddress + MemInfo.RegionSize - 1, stringifyMemType(MemInfo.Type, szMemType, sizeof(szMemType)), stringifyMemState(MemInfo.State, szMemState, sizeof(szMemState)), stringifyMemProt(MemInfo.Protect, szMemProt, sizeof(szMemProt)) ); if ((uintptr_t)MemInfo.AllocationBase != 0) { if (MemInfo.AllocationBase != MemInfo.BaseAddress) RTTestIPrintf(RTTESTLVL_ALWAYS, " %p", MemInfo.AllocationBase); else RTTestIPrintf(RTTESTLVL_ALWAYS, " %s", stringifyMemProt(MemInfo.AllocationProtect, szAllocProt, sizeof(szAllocProt))); } RTTestIPrintf(RTTESTLVL_ALWAYS, "\n"); if ((uintptr_t)MemInfo.BaseAddress != uPtrWhere) RTTestIPrintf(RTTESTLVL_ALWAYS, " !Warning! Queried %p got BaseAddress=%p!\n", uPtrWhere, MemInfo.BaseAddress); /* Image or mapped, then try get a file name. */ if (MemInfo.Type == MEM_IMAGE || MemInfo.Type == MEM_MAPPED) { union { MEMORY_SECTION_NAME Core; WCHAR awcPadding[UNICODE_STRING_MAX_CHARS + (sizeof(UNICODE_STRING_MAX_CHARS) + 1) / sizeof(WCHAR)]; } uBuf; RT_ZERO(uBuf); uBuf.Core.SectionFileName.Length = UNICODE_STRING_MAX_CHARS * 2; uBuf.Core.SectionFileName.MaximumLength = UNICODE_STRING_MAX_CHARS * 2; uBuf.Core.SectionFileName.Buffer = &uBuf.Core.NameBuffer[0]; cbActual = 0; rcNt = NtQueryVirtualMemory(g_hProcess, (void const *)uPtrWhere, MemorySectionName, &uBuf, sizeof(uBuf), &cbActual); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, " %.*ls\n", uBuf.Core.SectionFileName.Length / 2, uBuf.Core.SectionFileName.Buffer); else { RTTestIPrintf(RTTESTLVL_ALWAYS, "%p: MemorySectionName - rcNt=%#x\n", uPtrWhere, rcNt); RTTESTI_CHECK(rcNt == STATUS_FILE_INVALID && MemInfo.Type == MEM_MAPPED); } } /* Advance. */ cbAdvance = MemInfo.RegionSize; //cbAdvance = 0; if (uPtrWhere + cbAdvance <= uPtrWhere) break; uPtrWhere += MemInfo.RegionSize; } }
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); }
int main() { RTTEST hTest; int rc = RTTestInitAndCreate("tstRTStrFormat", &hTest); if (rc) return rc; RTTestBanner(hTest); uint32_t u32 = 0x010; uint64_t u64 = 0x100; #define BUF_SIZE 120 char *pszBuf = (char *)RTTestGuardedAllocHead(hTest, BUF_SIZE); char *pszBuf2 = (char *)RTTestGuardedAllocHead(hTest, BUF_SIZE); RTTestSub(hTest, "Basics"); /* simple */ size_t cch = RTStrPrintf(pszBuf, BUF_SIZE, "u32=%d u64=%lld u64=%#llx", u32, u64, u64); if (strcmp(pszBuf, "u32=16 u64=256 u64=0x100")) { RTTestIFailed("error: '%s'\n" "wanted 'u32=16 u64=256 u64=0x100'\n", pszBuf); } /* just big. */ u64 = UINT64_C(0x7070605040302010); cch = RTStrPrintf(pszBuf, BUF_SIZE, "u64=%#llx 42=%d u64=%lld 42=%d", u64, 42, u64, 42); if (strcmp(pszBuf, "u64=0x7070605040302010 42=42 u64=8102081627430068240 42=42")) { RTTestIFailed("error: '%s'\n" "wanted 'u64=0x8070605040302010 42=42 u64=8102081627430068240 42=42'\n", pszBuf); RTTestIPrintf(RTTESTLVL_FAILURE, "%d\n", (int)(u64 % 10)); } /* huge and negative. */ u64 = UINT64_C(0x8070605040302010); cch = RTStrPrintf(pszBuf, BUF_SIZE, "u64=%#llx 42=%d u64=%llu 42=%d u64=%lld 42=%d", u64, 42, u64, 42, u64, 42); /* Not sure if this is the correct decimal representation... But both */ if (strcmp(pszBuf, "u64=0x8070605040302010 42=42 u64=9255003132036915216 42=42 u64=-9191740941672636400 42=42")) { RTTestIFailed("error: '%s'\n" "wanted 'u64=0x8070605040302010 42=42 u64=9255003132036915216 42=42 u64=-9191740941672636400 42=42'\n", pszBuf); RTTestIPrintf(RTTESTLVL_FAILURE, "%d\n", (int)(u64 % 10)); } /* 64-bit value bug. */ u64 = 0xa0000000; cch = RTStrPrintf(pszBuf, BUF_SIZE, "u64=%#llx 42=%d u64=%lld 42=%d", u64, 42, u64, 42); if (strcmp(pszBuf, "u64=0xa0000000 42=42 u64=2684354560 42=42")) RTTestIFailed("error: '%s'\n" "wanted 'u64=0xa0000000 42=42 u64=2684354560 42=42'\n", pszBuf); /* uuid */ RTUUID Uuid; RTUuidCreate(&Uuid); char szCorrect[RTUUID_STR_LENGTH]; RTUuidToStr(&Uuid, szCorrect, sizeof(szCorrect)); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%RTuuid", &Uuid); if (strcmp(pszBuf, szCorrect)) RTTestIFailed("error: '%s'\n" "expected: '%s'\n", pszBuf, szCorrect); /* * Nested */ RTTestSub(hTest, "Nested (%N)"); testNested(__LINE__, "42 2684354560 42 asdf 42", "42 %u 42 %s 42", 2684354560U, "asdf"); testNested(__LINE__, "", ""); /* * allocation */ RTTestSub(hTest, "RTStrAPrintf"); char *psz = (char *)~0; int cch2 = RTStrAPrintf(&psz, "Hey there! %s%s", "This is a test", "!"); if (cch2 < 0) RTTestIFailed("RTStrAPrintf failed, cch2=%d\n", cch2); else if (strcmp(psz, "Hey there! This is a test!")) RTTestIFailed("RTStrAPrintf failed\n" "got : '%s'\n" "wanted: 'Hey there! This is a test!'\n", psz); else if ((int)strlen(psz) != cch2) RTTestIFailed("RTStrAPrintf failed, cch2 == %d expected %u\n", cch2, strlen(psz)); RTStrFree(psz); #define CHECK42(fmt, arg, out) \ do { \ cch = RTStrPrintf(pszBuf, BUF_SIZE, fmt " 42=%d " fmt " 42=%d", arg, 42, arg, 42); \ if (strcmp(pszBuf, out " 42=42 " out " 42=42")) \ RTTestIFailed("at line %d: format '%s'\n" \ " output: '%s'\n" \ " wanted: '%s'\n", \ __LINE__, fmt, pszBuf, out " 42=42 " out " 42=42"); \ else if (cch != sizeof(out " 42=42 " out " 42=42") - 1) \ RTTestIFailed("at line %d: Invalid length %d returned, expected %u!\n", \ __LINE__, cch, sizeof(out " 42=42 " out " 42=42") - 1); \ } while (0) #define CHECKSTR(Correct) \ if (strcmp(pszBuf, Correct)) \ RTTestIFailed("error: '%s'\n" \ "expected: '%s'\n", pszBuf, Correct); \ /* * Runtime extensions. */ RTTestSub(hTest, "Runtime format types (%R*)"); CHECK42("%RGi", (RTGCINT)127, "127"); CHECK42("%RGi", (RTGCINT)-586589, "-586589"); CHECK42("%RGp", (RTGCPHYS)0x0000000044505045, "0000000044505045"); CHECK42("%RGp", ~(RTGCPHYS)0, "ffffffffffffffff"); CHECK42("%RGu", (RTGCUINT)586589, "586589"); CHECK42("%RGu", (RTGCUINT)1, "1"); CHECK42("%RGu", (RTGCUINT)3000000000U, "3000000000"); #if GC_ARCH_BITS == 32 CHECK42("%RGv", (RTGCUINTPTR)0, "00000000"); CHECK42("%RGv", ~(RTGCUINTPTR)0, "ffffffff"); CHECK42("%RGv", (RTGCUINTPTR)0x84342134, "84342134"); #else CHECK42("%RGv", (RTGCUINTPTR)0, "0000000000000000"); CHECK42("%RGv", ~(RTGCUINTPTR)0, "ffffffffffffffff"); CHECK42("%RGv", (RTGCUINTPTR)0x84342134, "0000000084342134"); #endif CHECK42("%RGx", (RTGCUINT)0x234, "234"); CHECK42("%RGx", (RTGCUINT)0xffffffff, "ffffffff"); CHECK42("%RRv", (RTRCUINTPTR)0, "00000000"); CHECK42("%RRv", ~(RTRCUINTPTR)0, "ffffffff"); CHECK42("%RRv", (RTRCUINTPTR)0x84342134, "84342134"); CHECK42("%RHi", (RTHCINT)127, "127"); CHECK42("%RHi", (RTHCINT)-586589, "-586589"); CHECK42("%RHp", (RTHCPHYS)0x0000000044505045, "0000000044505045"); CHECK42("%RHp", ~(RTHCPHYS)0, "ffffffffffffffff"); CHECK42("%RHu", (RTHCUINT)586589, "586589"); CHECK42("%RHu", (RTHCUINT)1, "1"); CHECK42("%RHu", (RTHCUINT)3000000000U, "3000000000"); if (sizeof(void*) == 8) { CHECK42("%RHv", (RTHCUINTPTR)0, "0000000000000000"); CHECK42("%RHv", ~(RTHCUINTPTR)0, "ffffffffffffffff"); CHECK42("%RHv", (RTHCUINTPTR)0x84342134, "0000000084342134"); } else { CHECK42("%RHv", (RTHCUINTPTR)0, "00000000"); CHECK42("%RHv", ~(RTHCUINTPTR)0, "ffffffff"); CHECK42("%RHv", (RTHCUINTPTR)0x84342134, "84342134"); } CHECK42("%RHx", (RTHCUINT)0x234, "234"); CHECK42("%RHx", (RTHCUINT)0xffffffff, "ffffffff"); CHECK42("%RI16", (int16_t)1, "1"); CHECK42("%RI16", (int16_t)-16384, "-16384"); CHECK42("%RI32", (int32_t)1123, "1123"); CHECK42("%RI32", (int32_t)-86596, "-86596"); CHECK42("%RI64", (int64_t)112345987345LL, "112345987345"); CHECK42("%RI64", (int64_t)-8659643985723459LL, "-8659643985723459"); CHECK42("%RI8", (int8_t)1, "1"); CHECK42("%RI8", (int8_t)-128, "-128"); CHECK42("%Rbn", "file.c", "file.c"); CHECK42("%Rbn", "foo/file.c", "file.c"); CHECK42("%Rbn", "/foo/file.c", "file.c"); CHECK42("%Rbn", "/dir/subdir/", "subdir/"); CHECK42("%Rfn", "function", "function"); CHECK42("%Rfn", "void function(void)", "function"); CHECK42("%RTfile", (RTFILE)127, "127"); CHECK42("%RTfile", (RTFILE)12341234, "12341234"); CHECK42("%RTfmode", (RTFMODE)0x123403, "00123403"); CHECK42("%RTfoff", (RTFOFF)12342312, "12342312"); CHECK42("%RTfoff", (RTFOFF)-123123123, "-123123123"); CHECK42("%RTfoff", (RTFOFF)858694596874568LL, "858694596874568"); RTFAR16 fp16; fp16.off = 0x34ff; fp16.sel = 0x0160; CHECK42("%RTfp16", fp16, "0160:34ff"); RTFAR32 fp32; fp32.off = 0xff094030; fp32.sel = 0x0168; CHECK42("%RTfp32", fp32, "0168:ff094030"); RTFAR64 fp64; fp64.off = 0xffff003401293487ULL; fp64.sel = 0x0ff8; CHECK42("%RTfp64", fp64, "0ff8:ffff003401293487"); fp64.off = 0x0; fp64.sel = 0x0; CHECK42("%RTfp64", fp64, "0000:0000000000000000"); CHECK42("%RTgid", (RTGID)-1, "-1"); CHECK42("%RTgid", (RTGID)1004, "1004"); CHECK42("%RTino", (RTINODE)0, "0000000000000000"); CHECK42("%RTino", (RTINODE)0x123412341324ULL, "0000123412341324"); CHECK42("%RTint", (RTINT)127, "127"); CHECK42("%RTint", (RTINT)-586589, "-586589"); CHECK42("%RTint", (RTINT)-23498723, "-23498723"); CHECK42("%RTiop", (RTIOPORT)0x3c4, "03c4"); CHECK42("%RTiop", (RTIOPORT)0xffff, "ffff"); RTMAC Mac; Mac.au8[0] = 0; Mac.au8[1] = 0x1b; Mac.au8[2] = 0x21; Mac.au8[3] = 0x0a; Mac.au8[4] = 0x1d; Mac.au8[5] = 0xd9; CHECK42("%RTmac", &Mac, "00:1b:21:0a:1d:d9"); Mac.au16[0] = 0xffff; Mac.au16[1] = 0xffff; Mac.au16[2] = 0xffff; CHECK42("%RTmac", &Mac, "ff:ff:ff:ff:ff:ff"); RTNETADDRIPV4 Ipv4Addr; Ipv4Addr.u = RT_H2N_U32_C(0xf040d003); CHECK42("%RTnaipv4", Ipv4Addr.u, "240.64.208.3"); Ipv4Addr.u = RT_H2N_U32_C(0xffffffff); CHECK42("%RTnaipv4", Ipv4Addr.u, "255.255.255.255"); RTNETADDRIPV6 Ipv6Addr; /* any */ memset(&Ipv6Addr, 0, sizeof(Ipv6Addr)); CHECK42("%RTnaipv6", &Ipv6Addr, "::"); /* loopback */ Ipv6Addr.au8[15] = 1; CHECK42("%RTnaipv6", &Ipv6Addr, "::1"); /* IPv4-compatible */ Ipv6Addr.au8[12] = 1; Ipv6Addr.au8[13] = 1; Ipv6Addr.au8[14] = 1; Ipv6Addr.au8[15] = 1; CHECK42("%RTnaipv6", &Ipv6Addr, "::1.1.1.1"); /* IPv4-mapped */ Ipv6Addr.au16[5] = RT_H2N_U16_C(0xffff); CHECK42("%RTnaipv6", &Ipv6Addr, "::ffff:1.1.1.1"); /* IPv4-translated */ Ipv6Addr.au16[4] = RT_H2N_U16_C(0xffff); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); CHECK42("%RTnaipv6", &Ipv6Addr, "::ffff:0:1.1.1.1"); /* single zero word is not abbreviated, leading zeroes are not printed */ Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); CHECK42("%RTnaipv6", &Ipv6Addr, "0:1:0:1:0:1:0:1"); /* longest run is abbreviated (here: at the beginning) */ Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0000); CHECK42("%RTnaipv6", &Ipv6Addr, "::1:0:0:1:0"); /* longest run is abbreviated (here: first) */ Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); CHECK42("%RTnaipv6", &Ipv6Addr, "1::1:0:0:1"); /* longest run is abbreviated (here: second) */ Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); CHECK42("%RTnaipv6", &Ipv6Addr, "1:0:0:1::1"); /* longest run is abbreviated (here: at the end) */ Ipv6Addr.au16[0] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0000); CHECK42("%RTnaipv6", &Ipv6Addr, "1:0:0:1::"); /* first of the two runs of equal length is abbreviated */ Ipv6Addr.au16[0] = RT_H2N_U16_C(0x2001); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0db8); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0001); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x0001); CHECK42("%RTnaipv6", &Ipv6Addr, "2001:db8::1:0:0:1"); Ipv6Addr.au16[0] = RT_H2N_U16_C(0x2001); Ipv6Addr.au16[1] = RT_H2N_U16_C(0x0db8); Ipv6Addr.au16[2] = RT_H2N_U16_C(0x85a3); Ipv6Addr.au16[3] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[4] = RT_H2N_U16_C(0x0000); Ipv6Addr.au16[5] = RT_H2N_U16_C(0x8a2e); Ipv6Addr.au16[6] = RT_H2N_U16_C(0x0370); Ipv6Addr.au16[7] = RT_H2N_U16_C(0x7334); CHECK42("%RTnaipv6", &Ipv6Addr, "2001:db8:85a3::8a2e:370:7334"); Ipv6Addr.au64[0] = UINT64_MAX; Ipv6Addr.au64[1] = UINT64_MAX; CHECK42("%RTnaipv6", &Ipv6Addr, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); RTNETADDR NetAddr; memset(&NetAddr, 0, sizeof(NetAddr)); /* plain IPv6 address if port is not specified */ NetAddr.enmType = RTNETADDRTYPE_IPV6; NetAddr.uAddr.au16[0] = RT_H2N_U16_C(0x0001); NetAddr.uAddr.au16[7] = RT_H2N_U16_C(0x0001); NetAddr.uPort = RTNETADDR_PORT_NA; CHECK42("%RTnaddr", &NetAddr, "1::1"); /* square brackets around IPv6 address if port is specified */ NetAddr.uPort = 1; CHECK42("%RTnaddr", &NetAddr, "[1::1]:1"); CHECK42("%RTproc", (RTPROCESS)0xffffff, "00ffffff"); CHECK42("%RTproc", (RTPROCESS)0x43455443, "43455443"); if (sizeof(RTUINTPTR) == 8) { CHECK42("%RTptr", (RTUINTPTR)0, "0000000000000000"); CHECK42("%RTptr", ~(RTUINTPTR)0, "ffffffffffffffff"); CHECK42("%RTptr", (RTUINTPTR)0x84342134, "0000000084342134"); } else { CHECK42("%RTptr", (RTUINTPTR)0, "00000000"); CHECK42("%RTptr", ~(RTUINTPTR)0, "ffffffff"); CHECK42("%RTptr", (RTUINTPTR)0x84342134, "84342134"); } if (sizeof(RTCCUINTREG) == 8) { CHECK42("%RTreg", (RTCCUINTREG)0, "0000000000000000"); CHECK42("%RTreg", ~(RTCCUINTREG)0, "ffffffffffffffff"); CHECK42("%RTreg", (RTCCUINTREG)0x84342134, "0000000084342134"); CHECK42("%RTreg", (RTCCUINTREG)0x23484342134ULL, "0000023484342134"); } else { CHECK42("%RTreg", (RTCCUINTREG)0, "00000000"); CHECK42("%RTreg", ~(RTCCUINTREG)0, "ffffffff"); CHECK42("%RTreg", (RTCCUINTREG)0x84342134, "84342134"); } CHECK42("%RTsel", (RTSEL)0x543, "0543"); CHECK42("%RTsel", (RTSEL)0xf8f8, "f8f8"); if (sizeof(RTSEMEVENT) == 8) { CHECK42("%RTsem", (RTSEMEVENT)0, "0000000000000000"); CHECK42("%RTsem", (RTSEMEVENT)0x23484342134ULL, "0000023484342134"); } else { CHECK42("%RTsem", (RTSEMEVENT)0, "00000000"); CHECK42("%RTsem", (RTSEMEVENT)0x84342134, "84342134"); } CHECK42("%RTsock", (RTSOCKET)12234, "12234"); CHECK42("%RTsock", (RTSOCKET)584854543, "584854543"); if (sizeof(RTTHREAD) == 8) { CHECK42("%RTthrd", (RTTHREAD)0, "0000000000000000"); CHECK42("%RTthrd", (RTTHREAD)~(uintptr_t)0, "ffffffffffffffff"); CHECK42("%RTthrd", (RTTHREAD)0x63484342134ULL, "0000063484342134"); } else { CHECK42("%RTthrd", (RTTHREAD)0, "00000000"); CHECK42("%RTthrd", (RTTHREAD)~(uintptr_t)0, "ffffffff"); CHECK42("%RTthrd", (RTTHREAD)0x54342134, "54342134"); } CHECK42("%RTuid", (RTUID)-2, "-2"); CHECK42("%RTuid", (RTUID)90344, "90344"); CHECK42("%RTuint", (RTUINT)584589, "584589"); CHECK42("%RTuint", (RTUINT)3, "3"); CHECK42("%RTuint", (RTUINT)2400000000U, "2400000000"); RTUuidCreate(&Uuid); RTUuidToStr(&Uuid, szCorrect, sizeof(szCorrect)); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%RTuuid", &Uuid); if (strcmp(pszBuf, szCorrect)) RTTestIFailed("error: '%s'\n" "expected: '%s'\n", pszBuf, szCorrect); CHECK42("%RTxint", (RTUINT)0x2345, "2345"); CHECK42("%RTxint", (RTUINT)0xffff8fff, "ffff8fff"); CHECK42("%RU16", (uint16_t)7, "7"); CHECK42("%RU16", (uint16_t)46384, "46384"); CHECK42("%RU32", (uint32_t)1123, "1123"); CHECK42("%RU32", (uint32_t)86596, "86596"); CHECK42("%4RU32", (uint32_t)42, " 42"); CHECK42("%04RU32", (uint32_t)42, "0042"); CHECK42("%.4RU32", (uint32_t)42, "0042"); CHECK42("%RU64", (uint64_t)112345987345ULL, "112345987345"); CHECK42("%RU64", (uint64_t)8659643985723459ULL, "8659643985723459"); CHECK42("%14RU64", (uint64_t)4, " 4"); CHECK42("%014RU64", (uint64_t)4, "00000000000004"); CHECK42("%.14RU64", (uint64_t)4, "00000000000004"); CHECK42("%RU8", (uint8_t)1, "1"); CHECK42("%RU8", (uint8_t)254, "254"); CHECK42("%RU8", 256, "0"); CHECK42("%RX16", (uint16_t)0x7, "7"); CHECK42("%RX16", 0x46384, "6384"); CHECK42("%RX32", (uint32_t)0x1123, "1123"); CHECK42("%RX32", (uint32_t)0x49939493, "49939493"); CHECK42("%RX64", UINT64_C(0x348734), "348734"); CHECK42("%RX64", UINT64_C(0x12312312312343f), "12312312312343f"); CHECK42("%5RX64", UINT64_C(0x42), " 42"); CHECK42("%05RX64", UINT64_C(0x42), "00042"); CHECK42("%.5RX64", UINT64_C(0x42), "00042"); CHECK42("%.05RX64", UINT64_C(0x42), "00042"); /* '0' is ignored */ CHECK42("%RX8", (uint8_t)1, "1"); CHECK42("%RX8", (uint8_t)0xff, "ff"); CHECK42("%RX8", 0x100, "0"); /* * Thousand separators. */ RTTestSub(hTest, "Thousand Separators (%'*)"); RTStrFormatNumber(pszBuf, 1, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("1"); memset(pszBuf, '!', BUF_SIZE); RTStrFormatNumber(pszBuf, 10, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("10"); memset(pszBuf, '!', BUF_SIZE); RTStrFormatNumber(pszBuf, 100, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("100"); memset(pszBuf, '!', BUF_SIZE); RTStrFormatNumber(pszBuf, 1000, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("1 000"); memset(pszBuf, '!', BUF_SIZE); RTStrFormatNumber(pszBuf, 10000, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("10 000"); memset(pszBuf, '!', BUF_SIZE); RTStrFormatNumber(pszBuf, 100000, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("100 000"); memset(pszBuf, '!', BUF_SIZE); RTStrFormatNumber(pszBuf, 1000000, 10, 0, 0, RTSTR_F_THOUSAND_SEP); CHECKSTR("1 000 000"); memset(pszBuf, '!', BUF_SIZE); CHECK42("%'u", 1, "1"); CHECK42("%'u", 10, "10"); CHECK42("%'u", 100, "100"); CHECK42("%'u", 1000, "1 000"); CHECK42("%'u", 10000, "10 000"); CHECK42("%'u", 100000, "100 000"); CHECK42("%'u", 1000000, "1 000 000"); CHECK42("%'RU64", _1T, "1 099 511 627 776"); CHECK42("%'RU64", _1E, "1 152 921 504 606 846 976"); /* * String formatting. */ RTTestSub(hTest, "String formatting (%s)"); // 0 1 2 3 4 5 6 7 // 0....5....0....5....0....5....0....5....0....5....0....5....0....5....0 cch = RTStrPrintf(pszBuf, BUF_SIZE, "%-10s %-30s %s", "cmd", "args", "description"); CHECKSTR("cmd args description"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%-10s %-30s %s", "cmd", "", "description"); CHECKSTR("cmd description"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%*s", 0, ""); CHECKSTR(""); /* automatic conversions. */ static RTUNICP s_usz1[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0 }; //assumes ascii. static RTUTF16 s_wsz1[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0 }; //assumes ascii. cch = RTStrPrintf(pszBuf, BUF_SIZE, "%ls", s_wsz1); CHECKSTR("hello world"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%Ls", s_usz1); CHECKSTR("hello world"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%.5ls", s_wsz1); CHECKSTR("hello"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%.5Ls", s_usz1); CHECKSTR("hello"); /* * Unicode string formatting. */ RTTestSub(hTest, "Unicode string formatting (%ls)"); static RTUTF16 s_wszEmpty[] = { 0 }; //assumes ascii. static RTUTF16 s_wszCmd[] = { 'c', 'm', 'd', 0 }; //assumes ascii. static RTUTF16 s_wszArgs[] = { 'a', 'r', 'g', 's', 0 }; //assumes ascii. static RTUTF16 s_wszDesc[] = { 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 0 }; //assumes ascii. // 0 1 2 3 4 5 6 7 // 0....5....0....5....0....5....0....5....0....5....0....5....0....5....0 cch = RTStrPrintf(pszBuf, BUF_SIZE, "%-10ls %-30ls %ls", s_wszCmd, s_wszArgs, s_wszDesc); CHECKSTR("cmd args description"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%-10ls %-30ls %ls", s_wszCmd, s_wszEmpty, s_wszDesc); CHECKSTR("cmd description"); #if 0 static RTUNICP s_usz2[] = { 0xc5, 0xc6, 0xf8, 0 }; static RTUTF16 s_wsz2[] = { 0xc5, 0xc6, 0xf8, 0 }; static char s_sz2[] = { 0xc5, 0xc6, 0xf8, 0 };///@todo multibyte tests. cch = RTStrPrintf(pszBuf, BUF_SIZE, "%ls", s_wsz2); CHECKSTR(s_sz2); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%Ls", s_usz2); CHECKSTR(s_sz2); #endif /* * Hex formatting. */ RTTestSub(hTest, "Hex dump formatting (%Rhx*)"); static uint8_t const s_abHex1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; cch = RTStrPrintf(pszBuf, BUF_SIZE, "%.1Rhxs", s_abHex1); CHECKSTR("00"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%.2Rhxs", s_abHex1); CHECKSTR("00 01"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%Rhxs", s_abHex1); CHECKSTR("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%.*Rhxs", sizeof(s_abHex1), s_abHex1); CHECKSTR("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%4.*Rhxs", sizeof(s_abHex1), s_abHex1); CHECKSTR("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%1.*Rhxs", sizeof(s_abHex1), s_abHex1); CHECKSTR("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%256.*Rhxs", sizeof(s_abHex1), s_abHex1); CHECKSTR("00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14"); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%4.8Rhxd", s_abHex1); RTStrPrintf(pszBuf2, BUF_SIZE, "%p 0000: 00 01 02 03 ....\n" "%p 0004: 04 05 06 07 ....", &s_abHex1[0], &s_abHex1[4]); CHECKSTR(pszBuf2); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%4.6Rhxd", s_abHex1); RTStrPrintf(pszBuf2, BUF_SIZE, "%p 0000: 00 01 02 03 ....\n" "%p 0004: 04 05 ..", &s_abHex1[0], &s_abHex1[4]); CHECKSTR(pszBuf2); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%.*Rhxd", sizeof(s_abHex1), s_abHex1); RTStrPrintf(pszBuf2, BUF_SIZE, "%p 0000: 00 01 02 03 04 05 06 07-08 09 0a 0b 0c 0d 0e 0f ................\n" "%p 0010: 10 11 12 13 14 ....." , &s_abHex1[0], &s_abHex1[0x10]); CHECKSTR(pszBuf2); /* * x86 register formatting. */ RTTestSub(hTest, "x86 register format types (%RAx86[*])"); CHECK42("%RAx86[cr0]", UINT64_C(0x80000011), "80000011{PE,ET,PG}"); CHECK42("%RAx86[cr0]", UINT64_C(0x80000001), "80000001{PE,PG}"); CHECK42("%RAx86[cr0]", UINT64_C(0x00000001), "00000001{PE}"); CHECK42("%RAx86[cr0]", UINT64_C(0x80000000), "80000000{PG}"); CHECK42("%RAx86[cr4]", UINT64_C(0x80000001), "80000001{VME,unkn=80000000}"); CHECK42("%#RAx86[cr4]", UINT64_C(0x80000001), "0x80000001{VME,unkn=0x80000000}"); /* * Custom types. */ RTTestSub(hTest, "Custom format types (%R[*])"); RTTESTI_CHECK_RC(RTStrFormatTypeRegister("type3", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type3", (void *)((uintptr_t)TstType + 3)), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3]", (void *)1); CHECKSTR("type3=1"); RTTESTI_CHECK_RC(RTStrFormatTypeRegister("type1", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type1", (void *)((uintptr_t)TstType + 1)), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1]", (void *)1, (void *)2); CHECKSTR("type3=1 type1=2"); RTTESTI_CHECK_RC(RTStrFormatTypeRegister("type4", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type4", (void *)((uintptr_t)TstType + 4)), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1] %R[type4]", (void *)1, (void *)2, (void *)3); CHECKSTR("type3=1 type1=2 type4=3"); RTTESTI_CHECK_RC(RTStrFormatTypeRegister("type2", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type2", (void *)((uintptr_t)TstType + 2)), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1] %R[type4] %R[type2]", (void *)1, (void *)2, (void *)3, (void *)4); CHECKSTR("type3=1 type1=2 type4=3 type2=4"); RTTESTI_CHECK_RC(RTStrFormatTypeRegister("type5", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type5", (void *)((uintptr_t)TstType + 5)), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1] %R[type4] %R[type2] %R[type5]", (void *)1, (void *)2, (void *)3, (void *)4, (void *)5); CHECKSTR("type3=1 type1=2 type4=3 type2=4 type5=5"); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type1", (void *)((uintptr_t)TstType + 1)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type2", (void *)((uintptr_t)TstType + 2)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type3", (void *)((uintptr_t)TstType + 3)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type4", (void *)((uintptr_t)TstType + 4)), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrFormatTypeSetUser("type5", (void *)((uintptr_t)TstType + 5)), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1] %R[type4] %R[type2] %R[type5]", (void *)10, (void *)20, (void *)30, (void *)40, (void *)50); CHECKSTR("type3=10 type1=20 type4=30 type2=40 type5=50"); RTTESTI_CHECK_RC(RTStrFormatTypeDeregister("type2"), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1] %R[type4] %R[type5]", (void *)10, (void *)20, (void *)30, (void *)40); CHECKSTR("type3=10 type1=20 type4=30 type5=40"); RTTESTI_CHECK_RC(RTStrFormatTypeDeregister("type5"), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1] %R[type4]", (void *)10, (void *)20, (void *)30); CHECKSTR("type3=10 type1=20 type4=30"); RTTESTI_CHECK_RC(RTStrFormatTypeDeregister("type4"), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3] %R[type1]", (void *)10, (void *)20); CHECKSTR("type3=10 type1=20"); RTTESTI_CHECK_RC(RTStrFormatTypeDeregister("type1"), VINF_SUCCESS); cch = RTStrPrintf(pszBuf, BUF_SIZE, "%R[type3]", (void *)10); CHECKSTR("type3=10"); RTTESTI_CHECK_RC(RTStrFormatTypeDeregister("type3"), VINF_SUCCESS); /* * Summarize and exit. */ return RTTestSummaryAndDestroy(hTest); }
int main() { RTTEST hTest; int rc = RTTestInitAndCreate("tstRTSystemQueryOsInfo", &hTest); if (rc) return rc; RTTestBanner(hTest); /* * Simple stuff. */ char szInfo[_4K]; rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szInfo, sizeof(szInfo)); RTTestIPrintf(RTTESTLVL_ALWAYS, "PRODUCT: \"%s\", rc=%Rrc\n", szInfo, rc); rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo)); RTTestIPrintf(RTTESTLVL_ALWAYS, "RELEASE: \"%s\", rc=%Rrc\n", szInfo, rc); rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szInfo, sizeof(szInfo)); RTTestIPrintf(RTTESTLVL_ALWAYS, "VERSION: \"%s\", rc=%Rrc\n", szInfo, rc); rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo)); RTTestIPrintf(RTTESTLVL_ALWAYS, "SERVICE_PACK: \"%s\", rc=%Rrc\n", szInfo, rc); uint64_t cbTotal; rc = RTSystemQueryTotalRam(&cbTotal); RTTestIPrintf(RTTESTLVL_ALWAYS, "Total RAM: %'RU64 Bytes (%RU64 KB, %RU64 MB)\n", cbTotal, cbTotal / _1K, cbTotal / _1M); uint64_t cbAvailable; rc = RTSystemQueryAvailableRam(&cbAvailable); RTTestIPrintf(RTTESTLVL_ALWAYS, "Available RAM: %'RU64 Bytes (%RU64 KB, %RU64 MB)\n", cbAvailable, cbAvailable / _1K, cbAvailable / _1M); /* * Check that unsupported stuff is terminated correctly. */ for (int i = RTSYSOSINFO_INVALID + 1; i < RTSYSOSINFO_END; i++) { memset(szInfo, ' ', sizeof(szInfo)); rc = RTSystemQueryOSInfo((RTSYSOSINFO)i, szInfo, sizeof(szInfo)); if ( rc == VERR_NOT_SUPPORTED && szInfo[0] != '\0') RTTestIFailed("level=%d; unterminated buffer on VERR_NOT_SUPPORTED\n", i); else if (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW) RTTESTI_CHECK(RTStrEnd(szInfo, sizeof(szInfo)) != NULL); else if (rc != VERR_NOT_SUPPORTED) RTTestIFailed("level=%d unexpected rc=%Rrc\n", i, rc); } /* * Check buffer overflow */ RTAssertSetQuiet(true); RTAssertSetMayPanic(false); for (int i = RTSYSDMISTR_INVALID + 1; i < RTSYSDMISTR_END; i++) { RTTESTI_CHECK_RC(RTSystemQueryDmiString((RTSYSDMISTR)i, szInfo, 0), VERR_INVALID_PARAMETER); /* Get the length of the info and check that we get overflow errors for everything less that it. */ rc = RTSystemQueryOSInfo((RTSYSOSINFO)i, szInfo, sizeof(szInfo)); if (RT_FAILURE(rc)) continue; size_t const cchInfo = strlen(szInfo); for (size_t cch = 1; cch < sizeof(szInfo) && cch < cchInfo; cch++) { memset(szInfo, 0x7f, sizeof(szInfo)); RTTESTI_CHECK_RC(RTSystemQueryOSInfo((RTSYSOSINFO)i, szInfo, cch), VERR_BUFFER_OVERFLOW); /* check the padding. */ for (size_t off = cch; off < sizeof(szInfo); off++) if (szInfo[off] != 0x7f) { RTTestIFailed("level=%d, rc=%Rrc, cch=%zu, off=%zu: Wrote too much!\n", i, rc, cch, off); break; } /* check for zero terminator. */ if (!RTStrEnd(szInfo, cch)) RTTestIFailed("level=%d, rc=%Rrc, cch=%zu: Buffer not terminated!\n", i, rc, cch); } /* Check that the exact length works. */ rc = RTSystemQueryOSInfo((RTSYSOSINFO)i, szInfo, cchInfo + 1); if (rc != VINF_SUCCESS) RTTestIFailed("level=%d: rc=%Rrc when specifying exactly right buffer length (%zu)\n", i, rc, cchInfo + 1); } return RTTestSummaryAndDestroy(hTest); }
static int tstRTDvmVolume(RTTEST hTest, PTSTRTDVMDISK pDisk, uint64_t cb, unsigned cNesting) { char szPrefix[100]; int rc = VINF_SUCCESS; RT_ZERO(szPrefix); if (cNesting < sizeof(szPrefix) - 1) { for (unsigned i = 0; i < cNesting; i++) szPrefix[i] = '\t'; } RTTestSubF(hTest, "Create DVM"); RTDVM hVolMgr; rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, 0, pDisk); if (RT_FAILURE(rc)) { RTTestIFailed("RTDvmCreate -> %Rrc", rc); return RTTestSummaryAndDestroy(hTest); } RTTestSubF(hTest, "Open volume map"); rc = RTDvmMapOpen(hVolMgr); if ( RT_FAILURE(rc) && rc != VERR_NOT_SUPPORTED) { RTTestIFailed("RTDvmOpen -> %Rrc", rc); return RTTestSummaryAndDestroy(hTest); } if (rc == VERR_NOT_SUPPORTED) return VINF_SUCCESS; RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Successfully opened map with format: %s.\n", szPrefix, RTDvmMapGetFormat(hVolMgr)); /* Dump all volumes. */ RTTestSubF(hTest, "Dump volumes"); uint32_t cVolume = 0; RTDVMVOLUME hVol; rc = RTDvmMapQueryFirstVolume(hVolMgr, &hVol); while (RT_SUCCESS(rc)) { char *pszVolName = NULL; RTDVMVOLTYPE enmVolType = RTDvmVolumeGetType(hVol); uint64_t fVolFlags = RTDvmVolumeGetFlags(hVol); RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume %u:\n", szPrefix, cVolume); RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume type %s\n", szPrefix, RTDvmVolumeTypeGetDescr(enmVolType)); RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume size %llu\n", szPrefix, RTDvmVolumeGetSize(hVol)); RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume flags %s %s\n\n", szPrefix, fVolFlags & DVMVOLUME_FLAGS_BOOTABLE ? "Bootable" : "", fVolFlags & DVMVOLUME_FLAGS_ACTIVE ? "Active" : ""); rc = RTDvmVolumeQueryName(hVol, &pszVolName); if (RT_SUCCESS(rc)) { RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume name %s.\n", szPrefix, pszVolName); RTStrFree(pszVolName); } else if (rc != VERR_NOT_SUPPORTED) RTTestIFailed("RTDvmVolumeQueryName -> %Rrc", rc); else rc = VINF_SUCCESS; /* * Query all volumes which might be inside this. * (think of MBR partitions with a bsdlabel inside) */ TSTRTDVMDISK Disk; Disk.fUseImage = false; Disk.hVol = hVol; rc = tstRTDvmVolume(hTest, &Disk, RTDvmVolumeGetSize(hVol), cNesting + 1); RTDVMVOLUME hVolNext; rc = RTDvmMapQueryNextVolume(hVolMgr, hVol, &hVolNext); RTDvmVolumeRelease(hVol); hVol = hVolNext; cVolume++; } RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Dumped %u volumes\n", szPrefix, cVolume); if ( rc == VERR_DVM_MAP_EMPTY || rc == VERR_DVM_MAP_NO_VOLUME) rc = VINF_SUCCESS; RTTESTI_CHECK(rc == VINF_SUCCESS); RTDvmRelease(hVolMgr); return rc; }
int main() { char szPath[RTPATH_MAX]; /* * Init RT+Test. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstRTPath", &hTest); if (rc) return rc; RTTestBanner(hTest); /* * RTPathExecDir, RTPathUserHome and RTProcGetExecutablePath. */ RTTestSub(hTest, "RTPathExecDir"); RTTESTI_CHECK_RC(rc = RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "ExecDir={%s}\n", szPath); RTTestSub(hTest, "RTProcGetExecutablePath"); if (RTProcGetExecutablePath(szPath, sizeof(szPath)) == szPath) RTTestIPrintf(RTTESTLVL_INFO, "ExecutableName={%s}\n", szPath); else RTTestIFailed("RTProcGetExecutablePath -> NULL"); RTTestSub(hTest, "RTPathUserHome"); RTTESTI_CHECK_RC(rc = RTPathUserHome(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "UserHome={%s}\n", szPath); RTTestSub(hTest, "RTPathUserDocuments"); RTTESTI_CHECK_RC(rc = RTPathUserDocuments(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "UserDocuments={%s}\n", szPath); RTTestSub(hTest, "RTPathTemp"); RTTESTI_CHECK_RC(rc = RTPathTemp(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "PathTemp={%s}\n", szPath); size_t cch = strlen(szPath); RTTESTI_CHECK_RC(RTPathTemp(szPath, cch), VERR_BUFFER_OVERFLOW); RTTESTI_CHECK_RC(RTPathTemp(szPath, cch+1), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathTemp(szPath, cch+2), VINF_SUCCESS); /* * RTPathAbsEx */ RTTestSub(hTest, "RTPathAbsEx"); static const struct { const char *pcszInputBase; const char *pcszInputPath; int rc; const char *pcszOutput; } s_aRTPathAbsExTests[] = { #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) { NULL, "", VERR_INVALID_PARAMETER, NULL }, { NULL, ".", VINF_SUCCESS, "%p" }, { NULL, "\\", VINF_SUCCESS, "%d\\" }, { NULL, "\\..", VINF_SUCCESS, "%d\\" }, { NULL, "/absolute/..", VINF_SUCCESS, "%d\\" }, { NULL, "/absolute\\\\../..", VINF_SUCCESS, "%d\\" }, { NULL, "/absolute//../path\\", VINF_SUCCESS, "%d\\path" }, { NULL, "/absolute/../../path", VINF_SUCCESS, "%d\\path" }, { NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p\\dir\\file.txt" }, { NULL, "\\data\\", VINF_SUCCESS, "%d\\data" }, { "relative_base/dir\\", "\\from_root", VINF_SUCCESS, "%d\\from_root" }, { "relative_base/dir/", "relative_also", VINF_SUCCESS, "%p\\relative_base\\dir\\relative_also" }, #else { NULL, "", VERR_INVALID_PARAMETER, NULL }, { NULL, ".", VINF_SUCCESS, "%p" }, { NULL, "/", VINF_SUCCESS, "/" }, { NULL, "/..", VINF_SUCCESS, "/" }, { NULL, "/absolute/..", VINF_SUCCESS, "/" }, { NULL, "/absolute\\\\../..", VINF_SUCCESS, "/" }, { NULL, "/absolute//../path/", VINF_SUCCESS, "/path" }, { NULL, "/absolute/../../path", VINF_SUCCESS, "/path" }, { NULL, "relative/../dir/./././file.txt", VINF_SUCCESS, "%p/dir/file.txt" }, { NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p/dir\\.\\.\\.\\file.txt" }, /* linux-specific */ { NULL, "/data/", VINF_SUCCESS, "/data" }, { "relative_base/dir/", "/from_root", VINF_SUCCESS, "/from_root" }, { "relative_base/dir/", "relative_also", VINF_SUCCESS, "%p/relative_base/dir/relative_also" }, #endif #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) { NULL, "C:\\", VINF_SUCCESS, "C:\\" }, { "C:\\", "..", VINF_SUCCESS, "C:\\" }, { "C:\\temp", "..", VINF_SUCCESS, "C:\\" }, { "C:\\VirtualBox/Machines", "..\\VirtualBox.xml", VINF_SUCCESS, "C:\\VirtualBox\\VirtualBox.xml" }, { "C:\\MustDie", "\\from_root/dir/..", VINF_SUCCESS, "C:\\from_root" }, { "C:\\temp", "D:\\data", VINF_SUCCESS, "D:\\data" }, { NULL, "\\\\server\\..\\share", VINF_SUCCESS, "\\\\server\\..\\share" /* kind of strange */ }, { NULL, "\\\\server/", VINF_SUCCESS, "\\\\server" }, { NULL, "\\\\", VINF_SUCCESS, "\\\\" }, { NULL, "\\\\\\something", VINF_SUCCESS, "\\\\\\something" /* kind of strange */ }, { "\\\\server\\share_as_base", "/from_root", VINF_SUCCESS, "\\\\server\\from_root" }, { "\\\\just_server", "/from_root", VINF_SUCCESS, "\\\\just_server\\from_root" }, { "\\\\server\\share_as_base", "relative\\data", VINF_SUCCESS, "\\\\server\\share_as_base\\relative\\data" }, { "base", "\\\\?\\UNC\\relative/edwef/..", VINF_SUCCESS, "\\\\?\\UNC\\relative" }, { "\\\\?\\UNC\\base", "/from_root", VERR_INVALID_NAME, NULL }, #else { "/temp", "..", VINF_SUCCESS, "/" }, { "/VirtualBox/Machines", "../VirtualBox.xml", VINF_SUCCESS, "/VirtualBox/VirtualBox.xml" }, { "/MustDie", "/from_root/dir/..", VINF_SUCCESS, "/from_root" }, { "\\temp", "\\data", VINF_SUCCESS, "%p/\\temp/\\data" }, #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_aRTPathAbsExTests); ++ i) { rc = RTPathAbsEx(s_aRTPathAbsExTests[i].pcszInputBase, s_aRTPathAbsExTests[i].pcszInputPath, szPath, sizeof(szPath)); if (rc != s_aRTPathAbsExTests[i].rc) { RTTestIFailed("unexpected result code!\n" " input base: '%s'\n" " input path: '%s'\n" " output: '%s'\n" " rc: %Rrc\n" " expected rc: %Rrc", s_aRTPathAbsExTests[i].pcszInputBase, s_aRTPathAbsExTests[i].pcszInputPath, szPath, rc, s_aRTPathAbsExTests[i].rc); continue; } char szTmp[RTPATH_MAX]; char *pszExpected = NULL; if (s_aRTPathAbsExTests[i].pcszOutput != NULL) { if (s_aRTPathAbsExTests[i].pcszOutput[0] == '%') { RTTESTI_CHECK_RC(rc = RTPathGetCurrent(szTmp, sizeof(szTmp)), VINF_SUCCESS); if (RT_FAILURE(rc)) break; pszExpected = szTmp; if (s_aRTPathAbsExTests[i].pcszOutput[1] == 'p') { cch = strlen(szTmp); if (cch + strlen(s_aRTPathAbsExTests[i].pcszOutput) - 2 <= sizeof(szTmp)) strcpy(szTmp + cch, s_aRTPathAbsExTests[i].pcszOutput + 2); } #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) else if (s_aRTPathAbsExTests[i].pcszOutput[1] == 'd') { if (2 + strlen(s_aRTPathAbsExTests[i].pcszOutput) - 2 <= sizeof(szTmp)) strcpy(szTmp + 2, s_aRTPathAbsExTests[i].pcszOutput + 2); } #endif } else { strcpy(szTmp, s_aRTPathAbsExTests[i].pcszOutput); pszExpected = szTmp; } if (strcmp(szPath, pszExpected)) { RTTestIFailed("Unexpected result\n" " input base: '%s'\n" " input path: '%s'\n" " output: '%s'\n" " expected: '%s'", s_aRTPathAbsExTests[i].pcszInputBase, s_aRTPathAbsExTests[i].pcszInputPath, szPath, s_aRTPathAbsExTests[i].pcszOutput); } } } /* * RTPathStripFilename */ RTTestSub(hTest, "RTPathStripFilename"); static const char *s_apszStripFilenameTests[] = { "/usr/include///", "/usr/include//", "/usr/include/", "/usr/include", "/usr/include", "/usr", "/usr", "/", "usr", ".", #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) "c:/windows", "c:/", "c:/", "c:/", "D:", "D:", "C:\\OS2\\DLLS", "C:\\OS2", #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszStripFilenameTests); i += 2) { const char *pszInput = s_apszStripFilenameTests[i]; const char *pszExpect = s_apszStripFilenameTests[i + 1]; strcpy(szPath, pszInput); RTPathStripFilename(szPath); if (strcmp(szPath, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, szPath, pszExpect); } } /* * RTPathAppend. */ RTTestSub(hTest, "RTPathAppend"); static const char *s_apszAppendTests[] = { /* base append result */ "/", "", "/", "", "/", "/", "/", "/", "/", "/x", "", "/x", "/x", "/", "/x/", "/", "x", "/x", "dir", "file", "dir/file", "dir", "/file", "dir/file", "dir", "//file", "dir/file", "dir", "///file", "dir/file", "dir/", "/file", "dir/file", "dir/", "//file", "dir/file", "dir/", "///file", "dir/file", "dir//", "file", "dir/file", "dir//", "/file", "dir/file", "dir//", "//file", "dir/file", "dir///", "///file", "dir/file", "/bin/testcase", "foo.r0", "/bin/testcase/foo.r0", #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) "/", "\\", "/", "\\", "/", "\\", "\\\\srv\\shr", "dir//", "\\\\srv\\shr/dir//", "\\\\srv\\shr", "dir//file", "\\\\srv\\shr/dir//file", "\\\\srv\\shr", "//dir//", "\\\\srv\\shr/dir//", "\\\\srv\\shr", "/\\dir//", "\\\\srv\\shr\\dir//", "\\\\", "not-srv/not-shr/file", "\\not-srv/not-shr/file", "C:", "autoexec.bat", "C:autoexec.bat", "C:", "/autoexec.bat", "C:/autoexec.bat", "C:", "\\autoexec.bat", "C:\\autoexec.bat", "C:\\", "/autoexec.bat", "C:\\autoexec.bat", "C:\\\\", "autoexec.bat", "C:\\autoexec.bat", "E:\\bin\\testcase", "foo.r0", "E:\\bin\\testcase/foo.r0", #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszAppendTests); i += 3) { const char *pszInput = s_apszAppendTests[i]; const char *pszAppend = s_apszAppendTests[i + 1]; const char *pszExpect = s_apszAppendTests[i + 2]; strcpy(szPath, pszInput); RTTESTI_CHECK_RC(rc = RTPathAppend(szPath, sizeof(szPath), pszAppend), VINF_SUCCESS); if (RT_FAILURE(rc)) continue; if (strcmp(szPath, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " append: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, pszAppend, szPath, pszExpect); } else { size_t const cchResult = strlen(szPath); strcpy(szPath, pszInput); RTTESTI_CHECK_RC(rc = RTPathAppend(szPath, cchResult + 2, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); strcpy(szPath, pszInput); RTTESTI_CHECK_RC(rc = RTPathAppend(szPath, cchResult + 1, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); if (strlen(pszInput) < cchResult) { strcpy(szPath, pszInput); RTTESTI_CHECK_RC(RTPathAppend(szPath, cchResult, pszAppend), VERR_BUFFER_OVERFLOW); } } } /* * RTPathJoin - reuse the append tests. */ RTTestSub(hTest, "RTPathJoin"); for (unsigned i = 0; i < RT_ELEMENTS(s_apszAppendTests); i += 3) { const char *pszInput = s_apszAppendTests[i]; const char *pszAppend = s_apszAppendTests[i + 1]; const char *pszExpect = s_apszAppendTests[i + 2]; memset(szPath, 'a', sizeof(szPath)); szPath[sizeof(szPath) - 1] = '\0'; RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, sizeof(szPath), pszInput, pszAppend), VINF_SUCCESS); if (RT_FAILURE(rc)) continue; if (strcmp(szPath, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " append: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, pszAppend, szPath, pszExpect); } else { size_t const cchResult = strlen(szPath); memset(szPath, 'a', sizeof(szPath)); szPath[sizeof(szPath) - 1] = '\0'; RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, cchResult + 2, pszInput, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); memset(szPath, 'a', sizeof(szPath)); szPath[sizeof(szPath) - 1] = '\0'; RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, cchResult + 1, pszInput, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, cchResult, pszInput, pszAppend), VERR_BUFFER_OVERFLOW); } } /* * RTPathJoinA - reuse the append tests. */ RTTestSub(hTest, "RTPathJoinA"); for (unsigned i = 0; i < RT_ELEMENTS(s_apszAppendTests); i += 3) { const char *pszInput = s_apszAppendTests[i]; const char *pszAppend = s_apszAppendTests[i + 1]; const char *pszExpect = s_apszAppendTests[i + 2]; char *pszPathDst; RTTESTI_CHECK(pszPathDst = RTPathJoinA(pszInput, pszAppend)); if (!pszPathDst) continue; if (strcmp(pszPathDst, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " append: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, pszAppend, pszPathDst, pszExpect); } RTStrFree(pszPathDst); } /* * RTPathStripTrailingSlash */ static const char *s_apszStripTrailingSlash[] = { /* input result */ "/", "/", "//", "/", "////////////////////", "/", "/tmp", "/tmp", "/tmp////////////////", "/tmp", "tmp", "tmp", "tmp////////////////", "tmp", "./", ".", #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) "////////////////////", "/", "D:", "D:", "D:/", "D:/", "D:\\", "D:\\", "D:\\/\\", "D:\\", "D:/\\/\\", "D:/", "C:/Temp", "D:/Temp", "C:/Temp/", "D:/Temp/", "C:/Temp\\/", "D:/Temp", #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszStripTrailingSlash); i += 2) { const char *pszInput = s_apszStripTrailingSlash[i]; const char *pszExpect = s_apszStripTrailingSlash[i + 1]; strcpy(szPath, pszInput); cch = RTPathStripTrailingSlash(szPath); if (strcmp(szPath, pszExpect)) RTTestIFailed("Unexpected result\n" " input: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, szPath, pszExpect); else RTTESTI_CHECK(cch == strlen(szPath)); } /* * RTPathCountComponents */ RTTestSub(hTest, "RTPathCountComponents"); RTTESTI_CHECK(RTPathCountComponents("") == 0); RTTESTI_CHECK(RTPathCountComponents("/") == 1); RTTESTI_CHECK(RTPathCountComponents("//") == 1); RTTESTI_CHECK(RTPathCountComponents("//////////////") == 1); RTTESTI_CHECK(RTPathCountComponents("//////////////bin") == 2); RTTESTI_CHECK(RTPathCountComponents("//////////////bin/") == 2); RTTESTI_CHECK(RTPathCountComponents("//////////////bin/////") == 2); RTTESTI_CHECK(RTPathCountComponents("..") == 1); RTTESTI_CHECK(RTPathCountComponents("../") == 1); RTTESTI_CHECK(RTPathCountComponents("../..") == 2); RTTESTI_CHECK(RTPathCountComponents("../../") == 2); #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) RTTESTI_CHECK(RTPathCountComponents("d:") == 1); RTTESTI_CHECK(RTPathCountComponents("d:/") == 1); RTTESTI_CHECK(RTPathCountComponents("d:/\\") == 1); RTTESTI_CHECK(RTPathCountComponents("d:\\") == 1); RTTESTI_CHECK(RTPathCountComponents("c:\\config.sys") == 2); RTTESTI_CHECK(RTPathCountComponents("c:\\windows") == 2); RTTESTI_CHECK(RTPathCountComponents("c:\\windows\\") == 2); RTTESTI_CHECK(RTPathCountComponents("c:\\windows\\system32") == 3); RTTESTI_CHECK(RTPathCountComponents("//./C$") == 1); RTTESTI_CHECK(RTPathCountComponents("\\\\.\\C$") == 1); RTTESTI_CHECK(RTPathCountComponents("/\\.\\C$") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share/") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\x") == 2); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\x\\y") == 3); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\x\\y\\") == 3); #endif /* * RTPathCopyComponents */ struct { const char *pszSrc; size_t cComponents; const char *pszResult; } s_aCopyComponents[] = { { "", 0, "" }, { "", 5, "" }, { "/", 0, "" }, { "/", 1, "/" }, { "/", 2, "/" }, { "/usr/bin/sed", 0, "" }, { "/usr/bin/sed", 1, "/" }, { "/usr/bin/sed", 2, "/usr/" }, { "/usr/bin/sed", 3, "/usr/bin/" }, { "/usr/bin/sed", 4, "/usr/bin/sed" }, { "/usr/bin/sed", 5, "/usr/bin/sed" }, { "/usr/bin/sed", 6, "/usr/bin/sed" }, { "/usr///bin/sed", 2, "/usr///" }, }; for (unsigned i = 0; i < RT_ELEMENTS(s_aCopyComponents); i++) { const char *pszInput = s_aCopyComponents[i].pszSrc; size_t cComponents = s_aCopyComponents[i].cComponents; const char *pszResult = s_aCopyComponents[i].pszResult; memset(szPath, 'a', sizeof(szPath)); rc = RTPathCopyComponents(szPath, sizeof(szPath), pszInput, cComponents); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); if (RT_SUCCESS(rc) && strcmp(szPath, pszResult)) RTTestIFailed("Unexpected result\n" " input: '%s' cComponents=%u\n" " output: '%s'\n" "expected: '%s'", pszInput, cComponents, szPath, pszResult); else if (RT_SUCCESS(rc)) { RTTESTI_CHECK_RC(RTPathCopyComponents(szPath, strlen(pszResult) + 1, pszInput, cComponents), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathCopyComponents(szPath, strlen(pszResult), pszInput, cComponents), VERR_BUFFER_OVERFLOW); } } /* * RTPathStripExt */ RTTestSub(hTest, "RTPathStripExt"); struct { const char *pszSrc; const char *pszResult; } s_aStripExt[] = { { "filename.ext", "filename" }, { "filename.ext1.ext2.ext3", "filename.ext1.ext2" }, { "filename..ext", "filename." }, { "filename.ext.", "filename.ext" }, /** @todo This is a bit weird/wrong, but not half as weird as the way Windows+OS/2 deals with a trailing dots. */ }; for (unsigned i = 0; i < RT_ELEMENTS(s_aStripExt); i++) { const char *pszInput = s_aStripExt[i].pszSrc; const char *pszResult = s_aStripExt[i].pszResult; strcpy(szPath, pszInput); RTPathStripExt(szPath); if (strcmp(szPath, pszResult)) RTTestIFailed("Unexpected result\n" " input: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, szPath, pszResult); } /* * RTPathCalcRelative */ RTTestSub(hTest, "RTPathCalcRelative"); struct { const char *pszFrom; const char *pszTo; int rc; const char *pszExpected; } s_aRelPath[] = { { "/home/test.ext", "/home/test2.ext", VINF_SUCCESS, "test2.ext"}, { "/dir/test.ext", "/dir/dir2/test2.ext", VINF_SUCCESS, "dir2/test2.ext"}, { "/dir/dir2/test.ext", "/dir/test2.ext", VINF_SUCCESS, "../test2.ext"}, { "/dir/dir2/test.ext", "/dir/dir3/test2.ext", VINF_SUCCESS, "../dir3/test2.ext"}, #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) { "\\\\server\\share\\test.ext", "\\\\server\\share2\\test2.ext", VERR_NOT_SUPPORTED, ""}, { "c:\\dir\\test.ext", "f:\\dir\\test.ext", VERR_NOT_SUPPORTED, ""} #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_aRelPath); i++) { const char *pszFrom = s_aRelPath[i].pszFrom; const char *pszTo = s_aRelPath[i].pszTo; rc = RTPathCalcRelative(szPath, sizeof(szPath), pszFrom, pszTo); if (rc != s_aRelPath[i].rc) RTTestIFailed("Unexpected return code\n" " got: %Rrc\n" "expected: %Rrc", rc, s_aRelPath[i].rc); else if ( RT_SUCCESS(rc) && strcmp(szPath, s_aRelPath[i].pszExpected)) RTTestIFailed("Unexpected result\n" " from: '%s'\n" " to: '%s'\n" " output: '%s'\n" "expected: '%s'", pszFrom, pszTo, szPath, s_aRelPath[i].pszExpected); } /* * Summary. */ return RTTestSummaryAndDestroy(hTest); }
static void tstQueryInformationProcess(void) { RTTestISub("NtQueryInformationProcess"); NTSTATUS rcNt; /* Basic info */ PROCESS_BASIC_INFORMATION BasicInfo; RT_ZERO(BasicInfo); DWORD cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), &cbActual); RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "BasicInfo:\n" " UniqueProcessId = %#x (%6d)\n" " InheritedFromUniqueProcessId = %#x (%6d)\n" " ExitStatus = %#x\n" " PebBaseAddress = %p\n" " AffinityMask = %#zx\n" " BasePriority = %#zx\n" , BasicInfo.UniqueProcessId, BasicInfo.UniqueProcessId, BasicInfo.InheritedFromUniqueProcessId, BasicInfo.InheritedFromUniqueProcessId, BasicInfo.ExitStatus, BasicInfo.PebBaseAddress, BasicInfo.AffinityMask, BasicInfo.BasePriority ); /* Debugger present? */ DWORD_PTR uPtr = ~(DWORD_PTR)0; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessDebugPort, &uPtr, sizeof(uPtr), &cbActual); RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessDebugPort: %p\n", uPtr); /* Debug object handle, whatever that is... */ uPtr = ~(DWORD_PTR)0; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessDebugObjectHandle, &uPtr, sizeof(uPtr), &cbActual); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessDebugObjectHandle: %p\n", uPtr); else if (rcNt == STATUS_PORT_NOT_SET) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessDebugObjectHandle: rcNt=%#x (STATUS_PORT_NOT_SET)\n", uPtr); else RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); /* 32-bit app on 64-bit host? */ uPtr = ~(DWORD_PTR)0; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessWow64Information, &uPtr, sizeof(uPtr), &cbActual); RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessWow64Information: %p\n", uPtr); /* Process image name (NT). */ struct { UNICODE_STRING UniStr; WCHAR awBuffer[UNICODE_STRING_MAX_CHARS]; } StrBuf; RT_ZERO(StrBuf); StrBuf.UniStr.Length = UNICODE_STRING_MAX_CHARS * 2; StrBuf.UniStr.MaximumLength = UNICODE_STRING_MAX_CHARS * 2; StrBuf.UniStr.Buffer = &StrBuf.awBuffer[0]; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessImageFileName, &StrBuf, sizeof(StrBuf), &cbActual); RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileName: len=%u\n %.*ls\n", StrBuf.UniStr.Length, StrBuf.UniStr.Length, StrBuf.UniStr.Buffer); /* Process image name (Win32) - Not available on Windows 2003. */ RT_ZERO(StrBuf); StrBuf.UniStr.Length = UNICODE_STRING_MAX_CHARS * 2; StrBuf.UniStr.MaximumLength = UNICODE_STRING_MAX_CHARS * 2; StrBuf.UniStr.Buffer = &StrBuf.awBuffer[0]; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessImageFileNameWin32, &StrBuf, sizeof(StrBuf), &cbActual); if (rcNt != STATUS_INVALID_INFO_CLASS) { RTTESTI_CHECK_MSG(NT_SUCCESS(rcNt), ("rcNt=%#x\n", rcNt)); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileNameWin32: len=%u\n %.*ls\n", StrBuf.UniStr.Length, StrBuf.UniStr.Length, StrBuf.UniStr.Buffer); } else RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileNameWin32: Not supported (STATUS_INVALID_INFO_CLASS).\n"); /* Process image mapping - Not available on Windows 2003. */ uPtr = ~(DWORD_PTR)0; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessImageFileMapping, &uPtr, sizeof(uPtr), &cbActual); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileMapping: %p\n", uPtr); else if (rcNt == STATUS_OBJECT_TYPE_MISMATCH) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileMapping: rcNt=%#x (STATUS_OBJECT_TYPE_MISMATCH)\n", rcNt); else if (rcNt == STATUS_INVALID_INFO_CLASS) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessImageFileMapping: Not supported (STATUS_INVALID_INFO_CLASS).\n"); else RTTestIFailed("ProcessImageFileMapping: rcNt=%#x\n", rcNt); /* Handles. Broken for 64-bit input. */ uint32_t u32 = UINT32_MAX; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessHandleCount, &u32, sizeof(u32), &cbActual); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessHandleCount: %#x (%d)\n", u32, u32); else RTTestIFailed("ProcessHandleCount: rcNt=%#x\n", rcNt); /* Execute flags. */ #if 0 /* fails... wrong process handle? */ u32 = ~(DWORD_PTR)0; cbActual = 0; rcNt = NtQueryInformationProcess(g_hProcess, ProcessExecuteFlags, &u32, sizeof(u32), &cbActual); if (NT_SUCCESS(rcNt)) RTTestIPrintf(RTTESTLVL_ALWAYS, "ProcessExecuteFlags: %#p\n", u32); else RTTestIFailed("ProcessExecuteFlags: rcNt=%#x\n", rcNt); #endif /** @todo ProcessImageInformation */ }