RTDECL(int) RTSystemQueryOSInfo(RTSYSOSINFO enmInfo, char *pszInfo, size_t cchInfo) { /* * Quick validation. */ AssertReturn(enmInfo > RTSYSOSINFO_INVALID && enmInfo < RTSYSOSINFO_END, VERR_INVALID_PARAMETER); AssertPtrReturn(pszInfo, VERR_INVALID_POINTER); if (!cchInfo) return VERR_BUFFER_OVERFLOW; /* * Handle the request. */ switch (enmInfo) { case RTSYSOSINFO_PRODUCT: case RTSYSOSINFO_RELEASE: case RTSYSOSINFO_VERSION: { struct utsname UtsInfo; if (uname(&UtsInfo) < 0) return RTErrConvertFromErrno(errno); const char *pszSrc; switch (enmInfo) { case RTSYSOSINFO_PRODUCT: pszSrc = UtsInfo.sysname; break; case RTSYSOSINFO_RELEASE: pszSrc = UtsInfo.release; break; case RTSYSOSINFO_VERSION: pszSrc = UtsInfo.version; break; default: AssertFatalFailed(); /* screw gcc */ } size_t cch = strlen(pszSrc); if (cch < cchInfo) { memcpy(pszInfo, pszSrc, cch + 1); return VINF_SUCCESS; } memcpy(pszInfo, pszSrc, cchInfo - 1); pszInfo[cchInfo - 1] = '\0'; return VERR_BUFFER_OVERFLOW; } case RTSYSOSINFO_SERVICE_PACK: default: *pszInfo = '\0'; return VERR_NOT_SUPPORTED; } return VINF_SUCCESS; }
/** * Services the RTSYSOSINFO_PRODUCT, RTSYSOSINFO_RELEASE * and RTSYSOSINFO_SERVICE_PACK requests. * * @returns See RTSystemQueryOSInfo. * @param enmInfo See RTSystemQueryOSInfo. * @param pszInfo See RTSystemQueryOSInfo. * @param cchInfo See RTSystemQueryOSInfo. */ static int rtSystemWinQueryOSVersion(RTSYSOSINFO enmInfo, char *pszInfo, size_t cchInfo) { /* * Make sure it's terminated correctly in case of error. */ *pszInfo = '\0'; /* * Check that we got the windows version at init time. */ AssertReturn(g_WinOsInfoEx.dwOSVersionInfoSize, VERR_WRONG_ORDER); /* * Service the request. */ char szTmp[512]; szTmp[0] = '\0'; switch (enmInfo) { /* * The product name. */ case RTSYSOSINFO_PRODUCT: { switch (g_enmWinVer) { case kRTWinOSType_95: strcpy(szTmp, "Windows 95"); break; case kRTWinOSType_95SP1: strcpy(szTmp, "Windows 95 (Service Pack 1)"); break; case kRTWinOSType_95OSR2: strcpy(szTmp, "Windows 95 (OSR 2)"); break; case kRTWinOSType_98: strcpy(szTmp, "Windows 98"); break; case kRTWinOSType_98SP1: strcpy(szTmp, "Windows 98 (Service Pack 1)"); break; case kRTWinOSType_98SE: strcpy(szTmp, "Windows 98 (Second Edition)"); break; case kRTWinOSType_ME: strcpy(szTmp, "Windows Me"); break; case kRTWinOSType_NT351: strcpy(szTmp, "Windows NT 3.51"); break; case kRTWinOSType_NT4: strcpy(szTmp, "Windows NT 4.0"); break; case kRTWinOSType_2K: strcpy(szTmp, "Windows 2000"); break; case kRTWinOSType_XP: strcpy(szTmp, "Windows XP"); if (g_WinOsInfoEx.wSuiteMask & VER_SUITE_PERSONAL) strcat(szTmp, " Home"); if ( g_WinOsInfoEx.wProductType == VER_NT_WORKSTATION && !(g_WinOsInfoEx.wSuiteMask & VER_SUITE_PERSONAL)) strcat(szTmp, " Professional"); #if 0 /** @todo fixme */ if (GetSystemMetrics(SM_MEDIACENTER)) strcat(szTmp, " Media Center"); #endif break; case kRTWinOSType_2003: strcpy(szTmp, "Windows 2003"); break; case kRTWinOSType_VISTA: { strcpy(szTmp, "Windows Vista"); rtSystemWinAppendProductType(szTmp); break; } case kRTWinOSType_2008: strcpy(szTmp, "Windows 2008"); break; case kRTWinOSType_7: strcpy(szTmp, "Windows 7"); break; case kRTWinOSType_2008R2: strcpy(szTmp, "Windows 2008 R2"); break; case kRTWinOSType_8: strcpy(szTmp, "Windows 8"); break; case kRTWinOSType_2012: strcpy(szTmp, "Windows 2012"); break; case kRTWinOSType_81: strcpy(szTmp, "Windows 8.1"); break; case kRTWinOSType_2012R2: strcpy(szTmp, "Windows 2012 R2"); break; case kRTWinOSType_10: strcpy(szTmp, "Windows 10"); break; case kRTWinOSType_2016: strcpy(szTmp, "Windows 2016"); break; case kRTWinOSType_NT_UNKNOWN: RTStrPrintf(szTmp, sizeof(szTmp), "Unknown NT v%u.%u", g_WinOsInfoEx.dwMajorVersion, g_WinOsInfoEx.dwMinorVersion); break; default: AssertFailed(); case kRTWinOSType_UNKNOWN: RTStrPrintf(szTmp, sizeof(szTmp), "Unknown %d v%u.%u", g_WinOsInfoEx.dwPlatformId, g_WinOsInfoEx.dwMajorVersion, g_WinOsInfoEx.dwMinorVersion); break; } break; } /* * The release. */ case RTSYSOSINFO_RELEASE: { RTStrPrintf(szTmp, sizeof(szTmp), "%u.%u.%u", g_WinOsInfoEx.dwMajorVersion, g_WinOsInfoEx.dwMinorVersion, g_WinOsInfoEx.dwBuildNumber); break; } /* * Get the service pack. */ case RTSYSOSINFO_SERVICE_PACK: { if (g_WinOsInfoEx.wServicePackMajor) { if (g_WinOsInfoEx.wServicePackMinor) RTStrPrintf(szTmp, sizeof(szTmp), "%u.%u", (unsigned)g_WinOsInfoEx.wServicePackMajor, (unsigned)g_WinOsInfoEx.wServicePackMinor); else RTStrPrintf(szTmp, sizeof(szTmp), "%u", (unsigned)g_WinOsInfoEx.wServicePackMajor); } else if (g_WinOsInfoEx.szCSDVersion[0]) { /* just copy the entire string. */ char *pszTmp = szTmp; int rc = RTUtf16ToUtf8Ex(g_WinOsInfoEx.szCSDVersion, RT_ELEMENTS(g_WinOsInfoEx.szCSDVersion), &pszTmp, sizeof(szTmp), NULL); if (RT_SUCCESS(rc)) RTStrStripR(szTmp); else szTmp[0] = '\0'; AssertCompile(sizeof(szTmp) > sizeof(g_WinOsInfoEx.szCSDVersion)); } else { switch (g_enmWinVer) { case kRTWinOSType_95SP1: strcpy(szTmp, "1"); break; case kRTWinOSType_98SP1: strcpy(szTmp, "1"); break; default: break; } } break; } default: AssertFatalFailed(); } /* * Copy the result to the return buffer. */ size_t cchTmp = strlen(szTmp); Assert(cchTmp < sizeof(szTmp)); if (cchTmp < cchInfo) { memcpy(pszInfo, szTmp, cchTmp + 1); return VINF_SUCCESS; } memcpy(pszInfo, szTmp, cchInfo - 1); pszInfo[cchInfo - 1] = '\0'; return VERR_BUFFER_OVERFLOW; }