/** * Try adjust the time using adjtime or similar. * * @returns true on success, false on failure. * * @param pDrift The time adjustment. */ static void VBoxServiceTimeSyncSet(PCRTTIMESPEC pDrift) { /* * Query the current time, adjust it by adding the drift and set it. */ RTTIMESPEC NewGuestTime; int rc = RTTimeSet(RTTimeSpecAdd(RTTimeNow(&NewGuestTime), pDrift)); if (RT_SUCCESS(rc)) { /* Succeeded - reset the error count and log the change. */ g_cTimeSyncErrors = 0; if (g_cVerbosity >= 1) { char sz[64]; RTTIME Time; VBoxServiceVerbose(1, "time set to %s\n", RTTimeToString(RTTimeExplode(&Time, &NewGuestTime), sz, sizeof(sz))); #ifdef DEBUG RTTIMESPEC Tmp; if (g_cVerbosity >= 3) VBoxServiceVerbose(3, " now %s\n", RTTimeToString(RTTimeExplode(&Time, RTTimeNow(&Tmp)), sz, sizeof(sz))); #endif } } else if (g_cTimeSyncErrors++ < 10) VBoxServiceError("VBoxServiceTimeSyncSet: RTTimeSet(%RDtimespec) failed: %Rrc\n", &NewGuestTime, rc); }
static void benchExecute() { SDL_Rect rect = { 0, 0, (Uint16)guGuestXRes, (Uint16)guGuestYRes }; RTTIMESPEC t1, t2; RTTimeNow(&t1); for (unsigned i=0; i<guLoop; i++) { #ifdef VBOX_OPENGL if (!gfOpenGL) { #endif /* SDL backend */ checkSDL("SDL_BlitSurface", SDL_BlitSurface(gSurfVRAM, &rect, gScreen, &rect)); if ((gScreen->flags & SDL_HWSURFACE) == 0) SDL_UpdateRect(gScreen, rect.x, rect.y, rect.w, rect.h); #ifdef VBOX_OPENGL } else { /* OpenGL backend */ glBindTexture(GL_TEXTURE_2D, gTexture); glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x); glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y); glPixelStorei(GL_UNPACK_ROW_LENGTH, gSurfVRAM->pitch / gSurfVRAM->format->BytesPerPixel); switch (gSurfVRAM->format->BitsPerPixel) { case 16: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect.w, rect.h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, gSurfVRAM->pixels); break; case 24: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect.w, rect.h, GL_BGR, GL_UNSIGNED_BYTE, gSurfVRAM->pixels); break; case 32: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect.w, rect.h, GL_BGRA, GL_UNSIGNED_BYTE, gSurfVRAM->pixels); break; default: RTPrintf("BitsPerPixel=%d?\n", gSurfVRAM->format->BitsPerPixel); return; } GLfloat tx = (GLfloat)((float)rect.w) / guTextureWidth; GLfloat ty = (GLfloat)((float)rect.h) / guTextureHeight; glBegin(GL_QUADS); glColor4f(1.0, 1.0, 1.0, 1.0); glTexCoord2f(0.0, 0.0); glVertex2i(rect.x, rect.y ); glTexCoord2f(0.0, ty); glVertex2i(rect.x, rect.y + rect.h); glTexCoord2f(tx, ty); glVertex2i(rect.x + rect.w, rect.y + rect.h); glTexCoord2f(tx, 0.0); glVertex2i(rect.x + rect.w, rect.y ); glEnd(); glFlush(); } #endif } RTTimeNow(&t2); int64_t ms = RTTimeSpecGetMilli(&t2) - RTTimeSpecGetMilli(&t1); printf(" %.1fms/frame\n", (double)ms / guLoop); }
/** * This tries to find the UTC offset for a given timespec. * * It does probably not take into account changes in daylight * saving over the years or similar stuff. * * @returns UTC offset in nanoseconds. * @param pTime The time. * @param fCurrentTime Whether the input is current time or not. * This is for avoid infinit recursion on errors in the fallback path. */ static int64_t rtTimeLocalUTCOffset(PCRTTIMESPEC pTime, bool fCurrentTime) { RTTIMESPEC Fallback; /* * Convert to time_t. */ int64_t i64UnixTime = RTTimeSpecGetSeconds(pTime); time_t UnixTime = i64UnixTime; if (UnixTime != i64UnixTime) return fCurrentTime ? 0 : rtTimeLocalUTCOffset(RTTimeNow(&Fallback), true); /* * Explode it as both local and uct time. */ struct tm TmLocal; if ( !localtime_r(&UnixTime, &TmLocal) || !TmLocal.tm_year) return fCurrentTime ? 0 : rtTimeLocalUTCOffset(RTTimeNow(&Fallback), true); struct tm TmUct; if (!gmtime_r(&UnixTime, &TmUct)) return fCurrentTime ? 0 : rtTimeLocalUTCOffset(RTTimeNow(&Fallback), true); /* * Calc the difference (if any). * We ASSUME that the difference is less that 24 hours. */ if ( TmLocal.tm_hour == TmUct.tm_hour && TmLocal.tm_min == TmUct.tm_min && TmLocal.tm_sec == TmUct.tm_sec && TmLocal.tm_mday == TmUct.tm_mday) return 0; int LocalSecs = TmLocal.tm_hour * 3600 + TmLocal.tm_min * 60 + TmLocal.tm_sec; int UctSecs = TmUct.tm_hour * 3600 + TmUct.tm_min * 60 + TmUct.tm_sec; if (TmLocal.tm_mday != TmUct.tm_mday) { if ( ( TmLocal.tm_mday > TmUct.tm_mday && TmUct.tm_mday != 1) || TmLocal.tm_mday == 1) LocalSecs += 24*60*60; else UctSecs += 24*60*60; } return (LocalSecs - UctSecs) * INT64_C(1000000000); }
HRESULT Guest::facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus) { ComAssertRet(enmFacility < INT32_MAX, E_INVALIDARG); HRESULT rc; RTTIMESPEC tsNow; RTTimeNow(&tsNow); FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)enmFacility); if (it != mData.mFacilityMap.end()) { AdditionsFacility *pFac = it->second; rc = pFac->update((AdditionsFacilityStatus_T)enmStatus, tsNow); } else { ComObjPtr<AdditionsFacility> pFacility; pFacility.createObject(); ComAssert(!pFacility.isNull()); rc = pFacility->init(this, (AdditionsFacilityType_T)enmFacility, (AdditionsFacilityStatus_T)enmStatus); if (SUCCEEDED(rc)) mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)enmFacility, pFacility)); } LogFlowFunc(("Returned with rc=%Rrc\n")); return rc; }
static int vbglR3DnDCreateDropDir(char* pszDropDir, size_t cbSize) { /* Validate input */ AssertPtrReturn(pszDropDir, VERR_INVALID_POINTER); AssertReturn(cbSize, VERR_INVALID_PARAMETER); /* Get the users document directory (usually $HOME/Documents). */ int rc = RTPathUserDocuments(pszDropDir, cbSize); if (RT_FAILURE(rc)) return rc; /* Append our base drop directory. */ rc = RTPathAppend(pszDropDir, cbSize, "VirtualBox Dropped Files"); if (RT_FAILURE(rc)) return rc; /* Create it when necessary. */ if (!RTDirExists(pszDropDir)) { rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU); if (RT_FAILURE(rc)) return rc; } /* The actually drop directory consist of the current time stamp and a * unique number when necessary. */ char pszTime[64]; RTTIMESPEC time; if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime))) return VERR_BUFFER_OVERFLOW; rc = RTPathAppend(pszDropDir, cbSize, pszTime); if (RT_FAILURE(rc)) return rc; /* Create it (only accessible by the current user) */ return RTDirCreateUniqueNumbered(pszDropDir, cbSize, RTFS_UNIX_IRWXU, 3, '-'); }
/** * Reports Guest Additions API and OS version. * * Called whenever the Additions issue a guest version report request or the VM * is reset. * * @param pInterface Pointer to this interface. * @param guestInfo Pointer to guest information structure. * @thread The emulation thread. */ DECLCALLBACK(void) vmmdevUpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo *guestInfo) { PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface); Assert(guestInfo); if (!guestInfo) return; Console *pConsole = pDrv->pVMMDev->getParent(); /* Store that information in IGuest */ Guest* guest = pConsole->getGuest(); Assert(guest); if (!guest) return; if (guestInfo->interfaceVersion != 0) { char version[16]; RTStrPrintf(version, sizeof(version), "%d", guestInfo->interfaceVersion); guest->setAdditionsInfo(Bstr(version), guestInfo->osType); /* * Tell the console interface about the event * so that it can notify its consumers. */ pConsole->onAdditionsStateChange(); if (guestInfo->interfaceVersion < VMMDEV_VERSION) pConsole->onAdditionsOutdated(); } else { /* * The guest additions was disabled because of a reset * or driver unload. */ guest->setAdditionsInfo(Bstr(), guestInfo->osType); /* Clear interface version + OS type. */ /** @todo Would be better if GuestImpl.cpp did all this in the above method call * while holding down the. */ guest->setAdditionsInfo2(0, "", 0, 0); /* Clear Guest Additions version. */ RTTIMESPEC TimeSpecTS; RTTimeNow(&TimeSpecTS); guest->setAdditionsStatus(VBoxGuestFacilityType_All, VBoxGuestFacilityStatus_Inactive, 0 /*fFlags*/, &TimeSpecTS); pConsole->onAdditionsStateChange(); } }
/** * Sets the supported features (and whether they are active or not). * * @param fCaps Guest capability bit mask (VMMDEV_GUEST_SUPPORTS_XXX). */ void Guest::i_setSupportedFeatures(uint32_t aCaps) { AutoCaller autoCaller(this); AssertComRCReturnVoid(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /** @todo A nit: The timestamp is wrong on saved state restore. Would be better * to move the graphics and seamless capability -> facility translation to * VMMDev so this could be saved. */ RTTIMESPEC TimeSpecTS; RTTimeNow(&TimeSpecTS); i_facilityUpdate(VBoxGuestFacilityType_Seamless, aCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive, 0 /*fFlags*/, &TimeSpecTS); /** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */ }
static char* rtS3DateHeader() { /* Date header entry */ RTTIMESPEC TimeSpec; RTTIME Time; RTTimeExplode(&Time, RTTimeNow(&TimeSpec)); static const char s_apszDayNms[7][4] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; static const char s_apszMonthNms[1+12][4] = { "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; char *pszDate; RTStrAPrintf(&pszDate, "Date: %s, %02u %s %04d %02u:%02u:%02u UTC", s_apszDayNms[Time.u8WeekDay], Time.u8MonthDay, s_apszMonthNms[Time.u8Month], Time.i32Year, Time.u8Hour, Time.u8Minute, Time.u8Second); return pszDate; }
/** * @interface_method_impl{VBOXSERVICE,pfnWorker} */ DECLCALLBACK(int) vgsvcTimeSyncWorker(bool volatile *pfShutdown) { RTTIME Time; char sz[64]; int rc = VINF_SUCCESS; /* * Tell the control thread that it can continue spawning services. */ RTThreadUserSignal(RTThreadSelf()); /* * The Work Loop. */ for (;;) { /* * Try get a reliable time reading. */ int cTries = 3; do { /* query it. */ RTTIMESPEC GuestNow0, GuestNow, HostNow; RTTimeNow(&GuestNow0); int rc2 = VbglR3GetHostTime(&HostNow); if (RT_FAILURE(rc2)) { if (g_cTimeSyncErrors++ < 10) VGSvcError("vgsvcTimeSyncWorker: VbglR3GetHostTime failed; rc2=%Rrc\n", rc2); break; } RTTimeNow(&GuestNow); /* calc latency and check if it's ok. */ RTTIMESPEC GuestElapsed = GuestNow; RTTimeSpecSub(&GuestElapsed, &GuestNow0); if ((uint32_t)RTTimeSpecGetMilli(&GuestElapsed) < g_TimeSyncMaxLatency) { /* * Set the time once after we were restored. * (Of course only if the drift is bigger than MinAdjust) */ uint32_t TimeSyncSetThreshold = g_TimeSyncSetThreshold; if (g_fTimeSyncSetOnRestore) { uint64_t idNewSession = g_idTimeSyncSession; VbglR3GetSessionId(&idNewSession); if (idNewSession != g_idTimeSyncSession) { VGSvcVerbose(3, "vgsvcTimeSyncWorker: The VM session ID changed, forcing resync.\n"); TimeSyncSetThreshold = 0; g_idTimeSyncSession = idNewSession; } } /* * Calculate the adjustment threshold and the current drift. */ uint32_t MinAdjust = RTTimeSpecGetMilli(&GuestElapsed) * g_TimeSyncLatencyFactor; if (MinAdjust < g_TimeSyncMinAdjust) MinAdjust = g_TimeSyncMinAdjust; RTTIMESPEC Drift = HostNow; RTTimeSpecSub(&Drift, &GuestNow); if (RTTimeSpecGetMilli(&Drift) < 0) MinAdjust += g_TimeSyncMinAdjust; /* extra buffer against moving time backwards. */ RTTIMESPEC AbsDrift = Drift; RTTimeSpecAbsolute(&AbsDrift); if (g_cVerbosity >= 3) { VGSvcVerbose(3, "vgsvcTimeSyncWorker: Host: %s (MinAdjust: %RU32 ms)\n", RTTimeToString(RTTimeExplode(&Time, &HostNow), sz, sizeof(sz)), MinAdjust); VGSvcVerbose(3, "vgsvcTimeSyncWorker: Guest: - %s => %RDtimespec drift\n", RTTimeToString(RTTimeExplode(&Time, &GuestNow), sz, sizeof(sz)), &Drift); } uint32_t AbsDriftMilli = RTTimeSpecGetMilli(&AbsDrift); if (AbsDriftMilli > MinAdjust) { /* * Ok, the drift is above the threshold. * * Try a gradual adjustment first, if that fails or the drift is * too big, fall back on just setting the time. */ if ( AbsDriftMilli > TimeSyncSetThreshold || g_fTimeSyncSetNext || !vgsvcTimeSyncAdjust(&Drift)) { vgsvcTimeSyncCancelAdjust(); vgsvcTimeSyncSet(&Drift); } } else vgsvcTimeSyncCancelAdjust(); break; } VGSvcVerbose(3, "vgsvcTimeSyncWorker: %RDtimespec: latency too high (%RDtimespec) sleeping 1s\n", GuestElapsed); RTThreadSleep(1000); } while (--cTries > 0); /* Clear the set-next/set-start flag. */ g_fTimeSyncSetNext = false; /* * Block for a while. * * The event semaphore takes care of ignoring interruptions and it * allows us to implement service wakeup later. */ if (*pfShutdown) break; int rc2 = RTSemEventMultiWait(g_TimeSyncEvent, g_TimeSyncInterval); if (*pfShutdown) break; if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2)) { VGSvcError("vgsvcTimeSyncWorker: RTSemEventMultiWait failed; rc2=%Rrc\n", rc2); rc = rc2; break; } } vgsvcTimeSyncCancelAdjust(); RTSemEventMultiDestroy(g_TimeSyncEvent); g_TimeSyncEvent = NIL_RTSEMEVENTMULTI; return rc; }
/** * Release logger callback. * * @return IPRT status code. * @param pLoggerRelease * @param enmPhase * @param pfnLog */ static void VBoxServiceLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog) { /* Some introductory information. */ static RTTIMESPEC s_TimeSpec; char szTmp[256]; if (enmPhase == RTLOGPHASE_BEGIN) RTTimeNow(&s_TimeSpec); RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp)); switch (enmPhase) { case RTLOGPHASE_BEGIN: { pfnLog(pLoggerRelease, "VBoxService %s r%s (verbosity: %d) %s (%s %s) release log\n" "Log opened %s\n", RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity, VBOX_BUILD_TARGET, __DATE__, __TIME__, szTmp); int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp); /* the package type is interesting for Linux distributions */ char szExecName[RTPATH_MAX]; char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); pfnLog(pLoggerRelease, "Executable: %s\n" "Process ID: %u\n" "Package type: %s" #ifdef VBOX_OSE " (OSE)" #endif "\n", pszExecName ? pszExecName : "unknown", RTProcSelf(), VBOX_PACKAGE_STRING); break; } case RTLOGPHASE_PREROTATE: pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp); break; case RTLOGPHASE_POSTROTATE: pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp); break; case RTLOGPHASE_END: pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp); break; default: /* nothing */ ; } }
static void vboxHeaderFooter(PRTLOGGER pReleaseLogger, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog) { /* some introductory information */ static RTTIMESPEC s_TimeSpec; char szTmp[256]; if (enmPhase == RTLOGPHASE_BEGIN) RTTimeNow(&s_TimeSpec); RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp)); switch (enmPhase) { case RTLOGPHASE_BEGIN: { bool fOldBuffered = RTLogSetBuffering(pReleaseLogger, true /*fBuffered*/); pfnLog(pReleaseLogger, "VirtualBox %s %s r%u %s (%s %s) release log\n" #ifdef VBOX_BLEEDING_EDGE "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n" #endif "Log opened %s\n", g_pszLogEntity, VBOX_VERSION_STRING, RTBldCfgRevision(), RTBldCfgTargetDotArch(), __DATE__, __TIME__, szTmp); int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "OS Product: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "OS Release: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "OS Version: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "OS Service Pack: %s\n", szTmp); vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_NAME, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "DMI Product Name: %s\n", szTmp); vrc = RTSystemQueryDmiString(RTSYSDMISTR_PRODUCT_VERSION, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pReleaseLogger, "DMI Product Version: %s\n", szTmp); uint64_t cbHostRam = 0, cbHostRamAvail = 0; vrc = RTSystemQueryTotalRam(&cbHostRam); if (RT_SUCCESS(vrc)) vrc = RTSystemQueryAvailableRam(&cbHostRamAvail); if (RT_SUCCESS(vrc)) pfnLog(pReleaseLogger, "Host RAM: %lluMB RAM, available: %lluMB\n", cbHostRam / _1M, cbHostRamAvail / _1M); /* the package type is interesting for Linux distributions */ char szExecName[RTPATH_MAX]; char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); pfnLog(pReleaseLogger, "Executable: %s\n" "Process ID: %u\n" "Package type: %s" #ifdef VBOX_OSE " (OSE)" #endif "\n", pszExecName ? pszExecName : "unknown", RTProcSelf(), VBOX_PACKAGE_STRING); RTLogSetBuffering(pReleaseLogger, fOldBuffered); break; } case RTLOGPHASE_PREROTATE: pfnLog(pReleaseLogger, "Log rotated - Log started %s\n", szTmp); break; case RTLOGPHASE_POSTROTATE: pfnLog(pReleaseLogger, "Log continuation - Log started %s\n", szTmp); break; case RTLOGPHASE_END: pfnLog(pReleaseLogger, "End of log file - Log started %s\n", szTmp); break; default: /* nothing */; } }
RTR3DECL(int) RTTarFileClose(RTTARFILE hFile) { /* Already closed? */ if (hFile == NIL_RTTARFILE) return VINF_SUCCESS; PRTTARFILEINTERNAL pFileInt = hFile; RTTARFILE_VALID_RETURN(pFileInt); int rc = VINF_SUCCESS; /* In write mode: */ if ((pFileInt->fOpenMode & (RTFILE_O_WRITE | RTFILE_O_READ)) == RTFILE_O_WRITE) { pFileInt->pTar->fFileOpenForWrite = false; do { /* If the user has called RTTarFileSetSize in the meantime, we have to make sure the file has the right size. */ if (pFileInt->cbSetSize > pFileInt->cbSize) { rc = rtTarAppendZeros(pFileInt, pFileInt->cbSetSize - pFileInt->cbSize); if (RT_FAILURE(rc)) break; } /* If the written size isn't 512 byte aligned, we need to fix this. */ RTTARRECORD record; RT_ZERO(record); uint64_t cbSizeAligned = RT_ALIGN(pFileInt->cbSize, sizeof(RTTARRECORD)); if (cbSizeAligned != pFileInt->cbSize) { /* Note the RTFile method. We didn't increase the cbSize or cbCurrentPos here. */ rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->offStart + sizeof(RTTARRECORD) + pFileInt->cbSize, &record, cbSizeAligned - pFileInt->cbSize, NULL); if (RT_FAILURE(rc)) break; } /* Create a header record for the file */ /* Todo: mode, gid, uid, mtime should be setable (or detected myself) */ RTTIMESPEC time; RTTimeNow(&time); rc = rtTarCreateHeaderRecord(&record, pFileInt->pszFilename, pFileInt->cbSize, 0, 0, 0600, RTTimeSpecGetSeconds(&time)); if (RT_FAILURE(rc)) break; /* Write this at the start of the file data */ rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->offStart, &record, sizeof(RTTARRECORD), NULL); if (RT_FAILURE(rc)) break; } while (0); } /* * Now cleanup and delete the handle. */ if (pFileInt->pszFilename) RTStrFree(pFileInt->pszFilename); if (pFileInt->hVfsIos != NIL_RTVFSIOSTREAM) { RTVfsIoStrmRelease(pFileInt->hVfsIos); pFileInt->hVfsIos = NIL_RTVFSIOSTREAM; } pFileInt->u32Magic = RTTARFILE_MAGIC_DEAD; RTMemFree(pFileInt); return rc; }
/** * Creates the default logger instance for a VBox process. * * @returns Pointer to the logger instance. */ RTDECL(PRTLOGGER) RTLogDefaultInit(void) { /* * Initialize the default logger instance. * Take care to do this once and not recursively. */ static volatile uint32_t fInitializing = 0; PRTLOGGER pLogger; int rc; if (g_pLogger || !ASMAtomicCmpXchgU32(&fInitializing, 1, 0)) return g_pLogger; #ifdef IN_RING3 /* * Assert the group definitions. */ #define ASSERT_LOG_GROUP(grp) ASSERT_LOG_GROUP2(LOG_GROUP_##grp, #grp) #define ASSERT_LOG_GROUP2(def, str) \ do { if (strcmp(g_apszGroups[def], str)) {printf("%s='%s' expects '%s'\n", #def, g_apszGroups[def], str); RTAssertDoPanic(); } } while (0) ASSERT_LOG_GROUP(DEFAULT); ASSERT_LOG_GROUP(AUDIO_MIXER); ASSERT_LOG_GROUP(AUDIO_MIXER_BUFFER); ASSERT_LOG_GROUP(CFGM); ASSERT_LOG_GROUP(CPUM); ASSERT_LOG_GROUP(CSAM); ASSERT_LOG_GROUP(DBGC); ASSERT_LOG_GROUP(DBGF); ASSERT_LOG_GROUP(DBGF_INFO); ASSERT_LOG_GROUP(DEV); ASSERT_LOG_GROUP(DEV_AC97); ASSERT_LOG_GROUP(DEV_ACPI); ASSERT_LOG_GROUP(DEV_APIC); ASSERT_LOG_GROUP(DEV_FDC); ASSERT_LOG_GROUP(DEV_HDA); ASSERT_LOG_GROUP(DEV_HDA_CODEC); ASSERT_LOG_GROUP(DEV_HPET); ASSERT_LOG_GROUP(DEV_IDE); ASSERT_LOG_GROUP(DEV_KBD); ASSERT_LOG_GROUP(DEV_LPC); ASSERT_LOG_GROUP(DEV_NE2000); ASSERT_LOG_GROUP(DEV_PC); ASSERT_LOG_GROUP(DEV_PC_ARCH); ASSERT_LOG_GROUP(DEV_PC_BIOS); ASSERT_LOG_GROUP(DEV_PCI); ASSERT_LOG_GROUP(DEV_PCNET); ASSERT_LOG_GROUP(DEV_PIC); ASSERT_LOG_GROUP(DEV_PIT); ASSERT_LOG_GROUP(DEV_RTC); ASSERT_LOG_GROUP(DEV_SB16); ASSERT_LOG_GROUP(DEV_SERIAL); ASSERT_LOG_GROUP(DEV_SMC); ASSERT_LOG_GROUP(DEV_VGA); ASSERT_LOG_GROUP(DEV_VMM); ASSERT_LOG_GROUP(DEV_VMM_STDERR); ASSERT_LOG_GROUP(DIS); ASSERT_LOG_GROUP(DRV); ASSERT_LOG_GROUP(DRV_ACPI); ASSERT_LOG_GROUP(DRV_AUDIO); ASSERT_LOG_GROUP(DRV_BLOCK); ASSERT_LOG_GROUP(DRV_FLOPPY); ASSERT_LOG_GROUP(DRV_HOST_AUDIO); ASSERT_LOG_GROUP(DRV_HOST_DVD); ASSERT_LOG_GROUP(DRV_HOST_FLOPPY); ASSERT_LOG_GROUP(DRV_ISO); ASSERT_LOG_GROUP(DRV_KBD_QUEUE); ASSERT_LOG_GROUP(DRV_MOUSE_QUEUE); ASSERT_LOG_GROUP(DRV_NAT); ASSERT_LOG_GROUP(DRV_RAW_IMAGE); ASSERT_LOG_GROUP(DRV_TUN); ASSERT_LOG_GROUP(DRV_USBPROXY); ASSERT_LOG_GROUP(DRV_VBOXHDD); ASSERT_LOG_GROUP(DRV_VRDE_AUDIO); ASSERT_LOG_GROUP(DRV_VSWITCH); ASSERT_LOG_GROUP(DRV_VUSB); ASSERT_LOG_GROUP(EM); ASSERT_LOG_GROUP(GUI); ASSERT_LOG_GROUP(HGCM); ASSERT_LOG_GROUP(HM); ASSERT_LOG_GROUP(IOM); ASSERT_LOG_GROUP(LWIP); ASSERT_LOG_GROUP(MAIN); ASSERT_LOG_GROUP(MM); ASSERT_LOG_GROUP(MM_HEAP); ASSERT_LOG_GROUP(MM_HYPER); ASSERT_LOG_GROUP(MM_HYPER_HEAP); ASSERT_LOG_GROUP(MM_PHYS); ASSERT_LOG_GROUP(MM_POOL); ASSERT_LOG_GROUP(NAT_SERVICE); ASSERT_LOG_GROUP(NET_SERVICE); ASSERT_LOG_GROUP(PATM); ASSERT_LOG_GROUP(PDM); ASSERT_LOG_GROUP(PDM_DEVICE); ASSERT_LOG_GROUP(PDM_DRIVER); ASSERT_LOG_GROUP(PDM_LDR); ASSERT_LOG_GROUP(PDM_QUEUE); ASSERT_LOG_GROUP(PGM); ASSERT_LOG_GROUP(PGM_POOL); ASSERT_LOG_GROUP(REM); ASSERT_LOG_GROUP(REM_DISAS); ASSERT_LOG_GROUP(REM_HANDLER); ASSERT_LOG_GROUP(REM_IOPORT); ASSERT_LOG_GROUP(REM_MMIO); ASSERT_LOG_GROUP(REM_PRINTF); ASSERT_LOG_GROUP(REM_RUN); ASSERT_LOG_GROUP(SELM); ASSERT_LOG_GROUP(SSM); ASSERT_LOG_GROUP(STAM); ASSERT_LOG_GROUP(SUP); ASSERT_LOG_GROUP(TM); ASSERT_LOG_GROUP(TRPM); ASSERT_LOG_GROUP(VM); ASSERT_LOG_GROUP(VMM); ASSERT_LOG_GROUP(VRDP); #undef ASSERT_LOG_GROUP #undef ASSERT_LOG_GROUP2 #endif /* IN_RING3 */ /* * Create the default logging instance. */ #ifdef IN_RING3 # ifndef IN_GUEST char szExecName[RTPATH_MAX]; if (!RTProcGetExecutablePath(szExecName, sizeof(szExecName))) strcpy(szExecName, "VBox"); RTTIMESPEC TimeSpec; RTTIME Time; RTTimeExplode(&Time, RTTimeNow(&TimeSpec)); rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, "./%04d-%02d-%02d-%02d-%02d-%02d.%03d-%s-%d.log", Time.i32Year, Time.u8Month, Time.u8MonthDay, Time.u8Hour, Time.u8Minute, Time.u8Second, Time.u32Nanosecond / 10000000, RTPathFilename(szExecName), RTProcSelf()); if (RT_SUCCESS(rc)) { /* * Write a log header. */ char szBuf[RTPATH_MAX]; RTTimeSpecToString(&TimeSpec, szBuf, sizeof(szBuf)); RTLogLoggerEx(pLogger, 0, ~0U, "Log created: %s\n", szBuf); RTLogLoggerEx(pLogger, 0, ~0U, "Executable: %s\n", szExecName); /* executable and arguments - tricky and all platform specific. */ # if defined(RT_OS_WINDOWS) RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %ls\n", GetCommandLineW()); # elif defined(RT_OS_SOLARIS) psinfo_t psi; char szArgFileBuf[80]; RTStrPrintf(szArgFileBuf, sizeof(szArgFileBuf), "/proc/%ld/psinfo", (long)getpid()); FILE* pFile = fopen(szArgFileBuf, "rb"); if (pFile) { if (fread(&psi, sizeof(psi), 1, pFile) == 1) { # if 0 /* 100% safe:*/ RTLogLoggerEx(pLogger, 0, ~0U, "Args: %s\n", psi.pr_psargs); # else /* probably safe: */ const char * const *argv = (const char * const *)psi.pr_argv; for (int iArg = 0; iArg < psi.pr_argc; iArg++) RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%d]: %s\n", iArg, argv[iArg]); # endif } fclose(pFile); } # elif defined(RT_OS_LINUX) FILE *pFile = fopen("/proc/self/cmdline", "r"); if (pFile) { /* braindead */ unsigned iArg = 0; int ch; bool fNew = true; while (!feof(pFile) && (ch = fgetc(pFile)) != EOF) { if (fNew) { RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%u]: ", iArg++); fNew = false; } if (ch) RTLogLoggerEx(pLogger, 0, ~0U, "%c", ch); else { RTLogLoggerEx(pLogger, 0, ~0U, "\n"); fNew = true; } } if (!fNew) RTLogLoggerEx(pLogger, 0, ~0U, "\n"); fclose(pFile); } # elif defined(RT_OS_HAIKU) team_info info; if (get_team_info(0, &info) == B_OK) { /* there is an info.argc, but no way to know arg boundaries */ RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %.64s\n", info.args); } # elif defined(RT_OS_FREEBSD) /* Retrieve the required length first */ int aiName[4]; aiName[0] = CTL_KERN; aiName[1] = KERN_PROC; aiName[2] = KERN_PROC_ARGS; /* Introduced in FreeBSD 4.0 */ aiName[3] = getpid(); size_t cchArgs = 0; int rcBSD = sysctl(aiName, RT_ELEMENTS(aiName), NULL, &cchArgs, NULL, 0); if (cchArgs > 0) { char *pszArgFileBuf = (char *)RTMemAllocZ(cchArgs + 1 /* Safety */); if (pszArgFileBuf) { /* Retrieve the argument list */ rcBSD = sysctl(aiName, RT_ELEMENTS(aiName), pszArgFileBuf, &cchArgs, NULL, 0); if (!rcBSD) { unsigned iArg = 0; size_t off = 0; while (off < cchArgs) { size_t cchArg = strlen(&pszArgFileBuf[off]); RTLogLoggerEx(pLogger, 0, ~0U, "Arg[%u]: %s\n", iArg, &pszArgFileBuf[off]); /* advance */ off += cchArg + 1; iArg++; } } RTMemFree(pszArgFileBuf); } } # elif defined(RT_OS_OS2) || defined(RT_OS_DARWIN) /* commandline? */ # else # error needs porting. # endif } # else /* IN_GUEST */ /* The user destination is backdoor logging. */ rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox.log"); # endif /* IN_GUEST */ #else /* IN_RING0 */ /* Some platforms has trouble allocating memory with interrupts and/or preemption disabled. Check and fail before we panic. */ # if defined(RT_OS_DARWIN) if ( !ASMIntAreEnabled() || !RTThreadPreemptIsEnabled(NIL_RTTHREAD)) return NULL; # endif # ifndef IN_GUEST rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, "VBox-ring0.log"); # else /* IN_GUEST */ rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox-ring0.log"); # endif /* IN_GUEST */ if (RT_SUCCESS(rc)) { /* * This is where you set your ring-0 logging preferences. * * On platforms which don't differ between debugger and kernel * log printing, STDOUT is gonna be a stub and the DEBUGGER * destination is the one doing all the work. On platforms * that do differ (like Darwin), STDOUT is the kernel log. */ # if defined(DEBUG_bird) /*RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3");*/ RTLogFlags(pLogger, "enabled unbuffered pid tid"); # ifndef IN_GUEST pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # endif # if defined(DEBUG_sandervl) && !defined(IN_GUEST) RTLogGroupSettings(pLogger, "+all"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER; # endif # if defined(DEBUG_ramshankar) /* Guest ring-0 as well */ RTLogGroupSettings(pLogger, "+all.e.l.f"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER; # endif # if defined(DEBUG_aleksey) /* Guest ring-0 as well */ //RTLogGroupSettings(pLogger, "net_flt_drv.e.l.f.l3.l4.l5 +net_adp_drv.e.l.f.l3.l4.l5"); RTLogGroupSettings(pLogger, "net_flt_drv.e.l.f.l3.l4.l5.l6"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # if defined(DEBUG_andy) /* Guest ring-0 as well */ RTLogGroupSettings(pLogger, "+all.e.l.f"); RTLogFlags(pLogger, "enabled unbuffered pid tid"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # if defined(DEBUG_misha) /* Guest ring-0 as well */ RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER; # endif # if defined(DEBUG_michael) && defined(IN_GUEST) RTLogGroupSettings(pLogger, "+vga.e.l.f"); RTLogFlags(pLogger, "enabled unbuffered"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif # if 0 /* vboxdrv logging - ATTENTION: this is what we're referring to guys! Change to '# if 1'. */ RTLogGroupSettings(pLogger, "all=~0 -default.l6.l5.l4.l3"); RTLogFlags(pLogger, "enabled unbuffered tid"); pLogger->fDestFlags |= RTLOGDEST_DEBUGGER | RTLOGDEST_STDOUT; # endif } #endif /* IN_RING0 */ return g_pLogger = RT_SUCCESS(rc) ? pLogger : NULL; }
int main() { RTTIMESPEC Now; RTTIMESPEC Ts1; RTTIMESPEC Ts2; RTTIME T1; RTTIME T2; #ifdef RTTIME_INCL_TIMEVAL struct timeval Tv1; struct timeval Tv2; struct timespec Tsp1; struct timespec Tsp2; #endif RTTEST hTest; int rc = RTTestInitAndCreate("tstRTTimeSpec", &hTest); if (rc) return rc; /* * Simple test with current time. */ RTTestSub(hTest, "Current time (UTC)"); CHECK_NZ(RTTimeNow(&Now)); CHECK_NZ(RTTimeExplode(&T1, &Now)); RTTestIPrintf(RTTESTLVL_ALWAYS, " %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1)); CHECK_NZ(RTTimeImplode(&Ts1, &T1)); if (!RTTimeSpecIsEqual(&Ts1, &Now)) RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now)); /* * Simple test with current local time. */ RTTestSub(hTest, "Current time (local)"); CHECK_NZ(RTTimeLocalNow(&Now)); CHECK_NZ(RTTimeExplode(&T1, &Now)); RTTestIPrintf(RTTESTLVL_ALWAYS, " %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1)); CHECK_NZ(RTTimeImplode(&Ts1, &T1)); if (!RTTimeSpecIsEqual(&Ts1, &Now)) RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now)); /* * Some simple tests with fixed dates (just checking for smoke). */ RTTestSub(hTest, "Smoke"); TEST_NS(INT64_C(0)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); TEST_NS(INT64_C(86400000000000)); CHECK_TIME(&T1, 1970,01,02, 00,00,00, 0, 2, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); TEST_NS(INT64_C(1)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); TEST_NS(INT64_C(-1)); CHECK_TIME(&T1, 1969,12,31, 23,59,59,999999999, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* * Test the limits. */ RTTestSub(hTest, "Extremes"); TEST_NS(INT64_MAX); TEST_NS(INT64_MIN); TEST_SEC(1095379198); CHECK_TIME(&T1, 2004, 9,16, 23,59,58, 0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); TEST_SEC(1095379199); CHECK_TIME(&T1, 2004, 9,16, 23,59,59, 0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); TEST_SEC(1095379200); CHECK_TIME(&T1, 2004, 9,17, 00,00,00, 0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); TEST_SEC(1095379201); CHECK_TIME(&T1, 2004, 9,17, 00,00,01, 0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); /* * Test normalization (UTC). */ RTTestSub(hTest, "Normalization (UTC)"); /* simple */ CHECK_NZ(RTTimeNow(&Now)); CHECK_NZ(RTTimeExplode(&T1, &Now)); T2 = T1; CHECK_NZ(RTTimeNormalize(&T1)); if (memcmp(&T1, &T2, sizeof(T1))) RTTestIFailed("simple normalization failed\n"); CHECK_NZ(RTTimeImplode(&Ts1, &T1)); CHECK_NZ(RTTimeSpecIsEqual(&Ts1, &Now)); /* a few partial dates. */ memset(&T1, 0, sizeof(T1)); SET_TIME( &T1, 1970,01,01, 00,00,00, 0, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1970,00,00, 00,00,00, 1, 1, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2007,12,06, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1968,01,30, 00,19,24, 5, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1968,01,30, 00,19,24, 5, 30, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 1969,01,31, 00, 9, 2, 7, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,01,31, 00, 9, 2, 7, 31, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,03,31, 00, 9, 2, 7, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,03,31, 00, 9, 2, 7, 90, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,31, 00,00,00, 9, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,31, 00,00,00, 9, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,30, 00,00,00, 30, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,30, 00,00,00, 30, 364, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 363, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,29, 00,00,00, 30, 363, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 362, 6, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,28, 00,00,00, 30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,27, 00,00,00, 30, 0, 5, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,27, 00,00,00, 30, 361, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 360, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,26, 00,00,00, 30, 360, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,25, 00,00,00, 12, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,25, 00,00,00, 12, 359, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,24, 00,00,00, 16, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,24, 00,00,00, 16, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* outside the year table range */ SET_TIME( &T1, 1200,01,30, 00,00,00, 2, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1200,01,30, 00,00,00, 2, 30, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 2555,11,29, 00,00,00, 2, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2555,11,29, 00,00,00, 2, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2555,00,00, 00,00,00, 3, 333, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2555,11,29, 00,00,00, 3, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* time overflow */ SET_TIME( &T1, 1969,12,30, 255,255,255, UINT32_MAX, 364, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1970,01, 9, 19,19,19,294967295, 9, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* date overflow */ SET_TIME( &T1, 2007,11,36, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2007,10,67, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2007,10,98, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2008,01,06, 02,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 2006,24,06, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2003,60,37, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2008,01,06, 02,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 2003,00,00, 02,15,23, 1,1801, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* * Conversions. */ #define CHECK_NSEC(Ts1, T2) \ do { \ RTTIMESPEC TsTmp; \ RTTESTI_CHECK_MSG( RTTimeSpecGetNano(&(Ts1)) == RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2))), \ ("line %d: %RI64, %RI64\n", __LINE__, \ RTTimeSpecGetNano(&(Ts1)), RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2)))) ); \ } while (0) RTTestSub(hTest, "Conversions, positive"); SET_TIME(&T1, 1980,01,01, 00,00,00, 0, 1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); RTTESTI_CHECK(RTTimeSpecSetDosSeconds(&Ts2, 0) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetDosSeconds(&Ts2) == 0); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1980,01,01, 00,00,00, 0, 1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); RTTESTI_CHECK(RTTimeSpecSetNtTime(&Ts2, INT64_C(119600064000000000)) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetNtTime(&Ts2) == INT64_C(119600064000000000)); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetSeconds(&Ts2, 1) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetSeconds(&Ts2) == 1); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetMilli(&Ts2, 1000) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetMilli(&Ts2) == 1000); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetMicro(&Ts2, 1000000) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000000); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetNano(&Ts2, 1000000000) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000000); CHECK_NSEC(Ts2, T1); #ifdef RTTIME_INCL_TIMEVAL SET_TIME(&T1, 1970,01,01, 00,00,01, 5000, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tv1.tv_sec = 1; Tv1.tv_usec = 5; RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000005); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2); RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec); #endif #ifdef RTTIME_INCL_TIMESPEC SET_TIME(&T1, 1970,01,01, 00,00,01, 5, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tsp1.tv_sec = 1; Tsp1.tv_nsec = 5; RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000005); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2); RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec); #endif RTTestSub(hTest, "Conversions, negative"); #ifdef RTTIME_INCL_TIMEVAL SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tv1.tv_sec = -2; Tv1.tv_usec = 999995; RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2); RTTESTI_CHECK_MSG(RTTimeSpecGetMicro(&Ts2) == -1000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2))); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2); RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec); #endif #ifdef RTTIME_INCL_TIMESPEC SET_TIME(&T1, 1969,12,31, 23,59,58,999999995, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tsp1.tv_sec = -2; Tsp1.tv_nsec = 999999995; RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2); RTTESTI_CHECK_MSG(RTTimeSpecGetNano(&Ts2) == -1000000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2))); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2); RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec); #endif /* * Summary */ return RTTestSummaryAndDestroy(hTest); }
/** * Gets the delta between UTC and local time. * * @code * RTTIMESPEC LocalTime; * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano()); * @endcode * * @returns Returns the nanosecond delta between UTC and local time. */ RTDECL(int64_t) RTTimeLocalDeltaNano(void) { RTTIMESPEC Time; return rtTimeLocalUTCOffset(RTTimeNow(&Time), true /* current time, skip fallback */); }
/** * Process the testcases found in the filter. * * @param pszFilter The filter (winnt) to pass to RTDirOpenFiltered for * selecting the testcases. * @param pszDir The directory we're processing. */ static void Process(const char *pszFilter, const char *pszDir) { /* * Open and enumerate the directory. */ PRTDIR pDir; int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT, 0); if (RT_SUCCESS(rc)) { for (;;) { RTDIRENTRY DirEntry; rc = RTDirRead(pDir, &DirEntry, NULL); if (RT_FAILURE(rc)) { if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; else RTPrintf("tstRunTestcases: reading '%s' -> %Rrc\n", pszFilter, rc); break; } /* * Construct the testcase name. */ char *pszTestcase; RTStrAPrintf(&pszTestcase, "%s/%s", pszDir, DirEntry.szName); if (!pszTestcase) { RTPrintf("tstRunTestcases: out of memory!\n"); rc = VERR_NO_MEMORY; break; } if (IsTestcaseIncluded(pszTestcase)) { /* * Execute the testcase. */ RTPrintf("*** %s: Executing...\n", pszTestcase); RTStrmFlush(g_pStdOut); const char *papszArgs[2]; papszArgs[0] = pszTestcase; papszArgs[1] = NULL; RTPROCESS Process; rc = RTProcCreate(pszTestcase, papszArgs, RTENV_DEFAULT, 0, &Process); if (RT_SUCCESS(rc)) { /* * Wait for the process and collect it's return code. * If it takes too long, we'll terminate it and continue. */ RTTIMESPEC Start; RTTimeNow(&Start); RTPROCSTATUS ProcStatus; for (;;) { rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); if (rc != VERR_PROCESS_RUNNING) break; RTTIMESPEC Now; if (RTTimeSpecGetMilli(RTTimeSpecSub(RTTimeNow(&Now), &Start)) > 120*1000 /* 1 min */) { RTPrintf("*** %s: FAILED - timed out. killing it.\n", pszTestcase); RTProcTerminate(Process); RTThreadSleep(100); RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); g_cFailures++; break; } RTThreadSleep(100); } /* * Examin the exit status. */ if (RT_SUCCESS(rc)) { if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL && ProcStatus.iStatus == 0) { RTPrintf("*** %s: PASSED\n", pszTestcase); g_cPasses++; } else { RTPrintf("*** %s: FAILED\n", pszTestcase); g_cFailures++; } } else if (rc != VERR_PROCESS_RUNNING) { RTPrintf("tstRunTestcases: %s: RTProcWait failed -> %Rrc\n", pszTestcase, rc); g_cFailures++; } } else { RTPrintf("tstRunTestcases: %s: failed to start -> %Rrc\n", pszTestcase, rc); g_cFailures++; } } else { RTPrintf("tstRunTestcases: %s: SKIPPED\n", pszTestcase); g_cSkipped++; } RTStrFree(pszTestcase); } /* enumeration loop */ RTDirClose(pDir); } else RTPrintf("tstRunTestcases: opening '%s' -> %Rrc\n", pszDir, rc); }
/** * Sets the general Guest Additions information like * API (interface) version and OS type. Gets called by * vmmdevUpdateGuestInfo. * * @param aInterfaceVersion * @param aOsType */ void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType) { RTTIMESPEC TimeSpecTS; RTTimeNow(&TimeSpecTS); AutoCaller autoCaller(this); AssertComRCReturnVoid(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* * Note: The Guest Additions API (interface) version is deprecated * and will not be used anymore! We might need it to at least report * something as version number if *really* ancient Guest Additions are * installed (without the guest version + revision properties having set). */ mData.mInterfaceVersion = aInterfaceVersion; /* * Older Additions rely on the Additions API version whether they * are assumed to be active or not. Since newer Additions do report * the Additions version *before* calling this function (by calling * VMMDevReportGuestInfo2, VMMDevReportGuestStatus, VMMDevReportGuestInfo, * in that order) we can tell apart old and new Additions here. Old * Additions never would set VMMDevReportGuestInfo2 (which set mData.mAdditionsVersion) * so they just rely on the aInterfaceVersion string (which gets set by * VMMDevReportGuestInfo). * * So only mark the Additions as being active (run level = system) when we * don't have the Additions version set. */ if (mData.mAdditionsVersionNew.isEmpty()) { if (aInterfaceVersion.isEmpty()) mData.mAdditionsRunLevel = AdditionsRunLevelType_None; else { mData.mAdditionsRunLevel = AdditionsRunLevelType_System; /* * To keep it compatible with the old Guest Additions behavior we need to set the * "graphics" (feature) facility to active as soon as we got the Guest Additions * interface version. */ facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active, 0 /*fFlags*/, &TimeSpecTS); } } /* * Older Additions didn't have this finer grained capability bit, * so enable it by default. Newer Additions will not enable this here * and use the setSupportedFeatures function instead. */ /** @todo r=bird: I don't get the above comment nor the code below... * One talks about capability bits, the one always does something to a facility. * Then there is the comment below it all, which is placed like it addresses the * mOSTypeId, but talks about something which doesn't remotely like mOSTypeId... * * Andy, could you please try clarify and make the comments shorter and more * coherent! Also, explain why this is important and what depends on it. * * PS. There is the VMMDEV_GUEST_SUPPORTS_GRAPHICS capability* report... It * should come in pretty quickly after this update, normally. */ facilityUpdate(VBoxGuestFacilityType_Graphics, facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver) ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive, 0 /*fFlags*/, &TimeSpecTS); /** @todo the timestamp isn't gonna be right here on saved state restore. */ /* * Note! There is a race going on between setting mAdditionsRunLevel and * mSupportsGraphics here and disabling/enabling it later according to * its real status when using new(er) Guest Additions. */ mData.mOSTypeId = Global::OSTypeId(aOsType); }
static int vboxInitLogging(const char *pszFilename, bool bGenNameSuffix) { PRTLOGGER loggerRelease; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; RTUINT fFlags = RTLOGFLAGS_PREFIX_TIME_PROG; #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) fFlags |= RTLOGFLAGS_USECRLF; #endif char szError[RTPATH_MAX + 128] = ""; const char * pszFilenameFmt; RTLOGDEST enmLogDest; if(pszFilename) { if(bGenNameSuffix) pszFilenameFmt = "%s.%ld.log"; else pszFilenameFmt = "%s"; enmLogDest = RTLOGDEST_FILE; } else { pszFilenameFmt = NULL; enmLogDest = RTLOGDEST_STDOUT; } int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, enmLogDest, NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, szError, sizeof(szError), pszFilenameFmt, pszFilename, RTTimeMilliTS()); if (RT_SUCCESS(vrc)) { /* some introductory information */ RTTIMESPEC timeSpec; char szTmp[256]; RTTimeSpecToString(RTTimeNow(&timeSpec), szTmp, sizeof(szTmp)); RTLogRelLogger(loggerRelease, 0, ~0U, "VBoxTestGL %s r%u %s (%s %s) release log\n" #ifdef VBOX_BLEEDING_EDGE "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n" #endif "Log opened %s\n", VBOX_VERSION_STRING, RTBldCfgRevision(), VBOX_BUILD_TARGET, __DATE__, __TIME__, szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) RTLogRelLogger(loggerRelease, 0, ~0U, "OS Product: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) RTLogRelLogger(loggerRelease, 0, ~0U, "OS Release: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) RTLogRelLogger(loggerRelease, 0, ~0U, "OS Version: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) RTLogRelLogger(loggerRelease, 0, ~0U, "OS Service Pack: %s\n", szTmp); // RTLogRelLogger(loggerRelease, 0, ~0U, "Host RAM: %uMB RAM, available: %uMB\n", // uHostRamMb, uHostRamAvailMb); /* the package type is interesting for Linux distributions */ char szExecName[RTPATH_MAX]; char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); RTLogRelLogger(loggerRelease, 0, ~0U, "Executable: %s\n" "Process ID: %u\n" "Package type: %s" #ifdef VBOX_OSE " (OSE)" #endif "\n", pszExecName ? pszExecName : "unknown", RTProcSelf(), VBOX_PACKAGE_STRING); /* register this logger as the release logger */ RTLogRelSetDefaultInstance(loggerRelease); return VINF_SUCCESS; } return vrc; }
/** * Records an VUSB event. * * @returns VBox status code. * @param hSniffer The sniffer instance. * @param pUrb The URB triggering the event. * @param enmEvent The type of event to record. */ DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent) { int rc = VINF_SUCCESS; PVUSBSNIFFERINT pThis = hSniffer; DumpFileEpb Epb; DumpFileUsbHeaderLnxMmapped UsbHdr; DumpFileUsbSetup UsbSetup; RTTIMESPEC TimeNow; uint64_t u64TimestampEvent; size_t cbUrbLength = 0; uint32_t cbDataLength = 0; uint32_t cbCapturedLength = sizeof(UsbHdr); uint32_t cIsocPkts = 0; uint8_t *pbData = NULL; RTTimeNow(&TimeNow); u64TimestampEvent = RTTimeSpecGetNano(&TimeNow); /* Start with the enhanced packet block. */ Epb.Hdr.u32BlockType = DUMPFILE_EPB_BLOCK_TYPE; Epb.Hdr.u32BlockTotalLength = 0; Epb.u32InterfaceId = 0; Epb.u32TimestampHigh = (u64TimestampEvent >> 32) & UINT32_C(0xffffffff); Epb.u32TimestampLow = u64TimestampEvent & UINT32_C(0xffffffff); UsbHdr.u64Id = (uint64_t)pUrb; /** @todo: check whether the pointer is a good ID. */ switch (enmEvent) { case VUSBSNIFFEREVENT_SUBMIT: UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_SUBMIT; cbUrbLength = pUrb->cbData; break; case VUSBSNIFFEREVENT_COMPLETE: UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_COMPLETE; cbUrbLength = pUrb->cbData; break; case VUSBSNIFFEREVENT_ERROR_SUBMIT: case VUSBSNIFFEREVENT_ERROR_COMPLETE: UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_ERROR; break; default: AssertMsgFailed(("Invalid event type %d\n", enmEvent)); } cbDataLength = cbUrbLength; pbData = &pUrb->abData[0]; switch (pUrb->enmType) { case VUSBXFERTYPE_ISOC: { int32_t i32ErrorCount = 0; UsbHdr.u8TransferType = 0; cIsocPkts = pUrb->cIsocPkts; for (unsigned i = 0; i < cIsocPkts; i++) if ( pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_OK && pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_NOT_ACCESSED) i32ErrorCount++; UsbHdr.u.IsoRec.i32ErrorCount = i32ErrorCount; UsbHdr.u.IsoRec.i32NumDesc = pUrb->cIsocPkts; cbCapturedLength += cIsocPkts * sizeof(DumpFileUsbIsoDesc); break; } case VUSBXFERTYPE_BULK: UsbHdr.u8TransferType = 3; break; case VUSBXFERTYPE_INTR: UsbHdr.u8TransferType = 1; break; case VUSBXFERTYPE_CTRL: case VUSBXFERTYPE_MSG: UsbHdr.u8TransferType = 2; break; default: AssertMsgFailed(("invalid transfer type %d\n", pUrb->enmType)); } if (pUrb->enmDir == VUSBDIRECTION_IN) { if (enmEvent == VUSBSNIFFEREVENT_SUBMIT) cbDataLength = 0; } else if (pUrb->enmDir == VUSBDIRECTION_OUT) { if ( enmEvent == VUSBSNIFFEREVENT_COMPLETE || pUrb->enmType == VUSBXFERTYPE_CTRL || pUrb->enmType == VUSBXFERTYPE_MSG) cbDataLength = 0; } else if (pUrb->enmDir == VUSBDIRECTION_SETUP) cbDataLength -= sizeof(VUSBSETUP); Epb.u32CapturedLen = cbCapturedLength + cbDataLength; Epb.u32PacketLen = cbCapturedLength + cbUrbLength; UsbHdr.u8EndpointNumber = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0x00); UsbHdr.u8DeviceAddress = pUrb->DstAddress; UsbHdr.u16BusId = 0; UsbHdr.u8DataFlag = cbDataLength ? 0 : 1; UsbHdr.u64TimestampSec = u64TimestampEvent / RT_NS_1SEC_64; UsbHdr.u32TimestampUSec = u64TimestampEvent / RT_NS_1US_64 - UsbHdr.u64TimestampSec * RT_US_1SEC; UsbHdr.i32Status = pUrb->enmStatus; UsbHdr.u32UrbLength = cbUrbLength; UsbHdr.u32DataLength = cbDataLength + cIsocPkts * sizeof(DumpFileUsbIsoDesc); UsbHdr.i32Interval = 0; UsbHdr.i32StartFrame = 0; UsbHdr.u32XferFlags = 0; UsbHdr.u32NumDesc = cIsocPkts; if ( (pUrb->enmType == VUSBXFERTYPE_MSG || pUrb->enmType == VUSBXFERTYPE_CTRL) && enmEvent == VUSBSNIFFEREVENT_SUBMIT) { PVUSBSETUP pSetup = (PVUSBSETUP)pUrb->abData; UsbHdr.u.UsbSetup.bmRequestType = pSetup->bmRequestType; UsbHdr.u.UsbSetup.bRequest = pSetup->bRequest; UsbHdr.u.UsbSetup.wValue = pSetup->wValue; UsbHdr.u.UsbSetup.wIndex = pSetup->wIndex; UsbHdr.u.UsbSetup.wLength = pSetup->wLength; UsbHdr.u8SetupFlag = 0; } else UsbHdr.u8SetupFlag = '-'; /* Follow usbmon source here. */ /* Write the packet to the capture file. */ rc = RTSemFastMutexRequest(pThis->hMtx); if (RT_SUCCESS(rc)) { rc = vusbSnifferBlockNew(pThis, &Epb.Hdr, sizeof(Epb)); if (RT_SUCCESS(rc)) rc = vusbSnifferBlockAddData(pThis, &UsbHdr, sizeof(UsbHdr)); /* Add Isochronous descriptors now. */ for (unsigned i = 0; i < cIsocPkts && RT_SUCCESS(rc); i++) { DumpFileUsbIsoDesc IsoDesc; IsoDesc.i32Status = pUrb->aIsocPkts[i].enmStatus; IsoDesc.u32Offset = pUrb->aIsocPkts[i].off; IsoDesc.u32Len = pUrb->aIsocPkts[i].cb; rc = vusbSnifferBlockAddData(pThis, &IsoDesc, sizeof(IsoDesc)); } /* Record data. */ if ( RT_SUCCESS(rc) && cbDataLength) rc = vusbSnifferBlockAddData(pThis, pbData, cbDataLength); if (RT_SUCCESS(rc)) rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0); if (RT_SUCCESS(rc)) rc = vusbSnifferBlockCommit(pThis); RTSemFastMutexRelease(pThis->hMtx); } return rc; }