| | 40 | #include <iprt/ctype.h> |
|---|
| | 41 | |
|---|
| | 42 | |
|---|
| | 43 | /******************************************************************************* |
|---|
| | 44 | * Structures and Typedefs * |
|---|
| | 45 | *******************************************************************************/ |
|---|
| | 46 | /** |
|---|
| | 47 | * Windows OS type as determined by rtSystemWinOSType(). |
|---|
| | 48 | */ |
|---|
| | 49 | typedef enum RTWINOSTYPE |
|---|
| | 50 | { |
|---|
| | 51 | kRTWinOSType_UNKNOWN = 0, |
|---|
| | 52 | kRTWinOSType_9XFIRST = 1, |
|---|
| | 53 | kRTWinOSType_95 = kRTWinOSType_9XFIRST, |
|---|
| | 54 | kRTWinOSType_95SP1, |
|---|
| | 55 | kRTWinOSType_95OSR2, |
|---|
| | 56 | kRTWinOSType_98, |
|---|
| | 57 | kRTWinOSType_98SP1, |
|---|
| | 58 | kRTWinOSType_98SE, |
|---|
| | 59 | kRTWinOSType_ME, |
|---|
| | 60 | kRTWinOSType_9XLAST = 99, |
|---|
| | 61 | kRTWinOSType_NTFIRST = 100, |
|---|
| | 62 | kRTWinOSType_NT31 = kRTWinOSType_NTFIRST, |
|---|
| | 63 | kRTWinOSType_NT351, |
|---|
| | 64 | kRTWinOSType_NT4, |
|---|
| | 65 | kRTWinOSType_2K, |
|---|
| | 66 | kRTWinOSType_XP, |
|---|
| | 67 | kRTWinOSType_2003, |
|---|
| | 68 | kRTWinOSType_VISTA, |
|---|
| | 69 | kRTWinOSType_NT_UNKNOWN = 199, |
|---|
| | 70 | kRTWinOSType_NT_LAST = kRTWinOSType_UNKNOWN |
|---|
| | 71 | } RTWINOSTYPE; |
|---|
| | 72 | |
|---|
| | 73 | /** |
|---|
| | 74 | * These are the PRODUCT_* defines found in the Vista Platform SDK and returned |
|---|
| | 75 | * by GetProductInfo(). |
|---|
| | 76 | * |
|---|
| | 77 | * We define them ourselves because we don't necessarily have any Vista PSDK around. |
|---|
| | 78 | */ |
|---|
| | 79 | typedef enum RTWINPRODTYPE |
|---|
| | 80 | { |
|---|
| | 81 | kRTWinProdType_UNDEFINED = 0x00000000, ///< An unknown product |
|---|
| | 82 | kRTWinProdType_BUSINESS = 0x00000006, ///< Business Edition |
|---|
| | 83 | kRTWinProdType_BUSINESS_N = 0x00000010, ///< Business Edition |
|---|
| | 84 | kRTWinProdType_CLUSTER_SERVER = 0x00000012, ///< Cluster Server Edition |
|---|
| | 85 | kRTWinProdType_DATACENTER_SERVER = 0x00000008, ///< Server Datacenter Edition (full installation) |
|---|
| | 86 | kRTWinProdType_DATACENTER_SERVER_CORE = 0x0000000C, ///< Server Datacenter Edition (core installation) |
|---|
| | 87 | kRTWinProdType_ENTERPRISE = 0x00000004, ///< Enterprise Edition |
|---|
| | 88 | kRTWinProdType_ENTERPRISE_N = 0x0000001B, ///< Enterprise Edition |
|---|
| | 89 | kRTWinProdType_ENTERPRISE_SERVER = 0x0000000A, ///< Server Enterprise Edition (full installation) |
|---|
| | 90 | kRTWinProdType_ENTERPRISE_SERVER_CORE = 0x0000000E, ///< Server Enterprise Edition (core installation) |
|---|
| | 91 | kRTWinProdType_ENTERPRISE_SERVER_IA64 = 0x0000000F, ///< Server Enterprise Edition for Itanium-based Systems |
|---|
| | 92 | kRTWinProdType_HOME_BASIC = 0x00000002, ///< Home Basic Edition |
|---|
| | 93 | kRTWinProdType_HOME_BASIC_N = 0x00000005, ///< Home Basic Edition |
|---|
| | 94 | kRTWinProdType_HOME_PREMIUM = 0x00000003, ///< Home Premium Edition |
|---|
| | 95 | kRTWinProdType_HOME_PREMIUM_N = 0x0000001A, ///< Home Premium Edition |
|---|
| | 96 | kRTWinProdType_HOME_SERVER = 0x00000013, ///< Home Server Edition |
|---|
| | 97 | kRTWinProdType_SERVER_FOR_SMALLBUSINESS = 0x00000018, ///< Server for Small Business Edition |
|---|
| | 98 | kRTWinProdType_SMALLBUSINESS_SERVER = 0x00000009, ///< Small Business Server |
|---|
| | 99 | kRTWinProdType_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019, ///< Small Business Server Premium Edition |
|---|
| | 100 | kRTWinProdType_STANDARD_SERVER = 0x00000007, ///< Server Standard Edition (full installation) |
|---|
| | 101 | kRTWinProdType_STANDARD_SERVER_CORE = 0x0000000D, ///< Server Standard Edition (core installation) |
|---|
| | 102 | kRTWinProdType_STARTER = 0x0000000B, ///< Starter Edition |
|---|
| | 103 | kRTWinProdType_STORAGE_ENTERPRISE_SERVER = 0x00000017, ///< Storage Server Enterprise Edition |
|---|
| | 104 | kRTWinProdType_STORAGE_EXPRESS_SERVER = 0x00000014, ///< Storage Server Express Edition |
|---|
| | 105 | kRTWinProdType_STORAGE_STANDARD_SERVER = 0x00000015, ///< Storage Server Standard Edition |
|---|
| | 106 | kRTWinProdType_STORAGE_WORKGROUP_SERVER = 0x00000016, ///< Storage Server Workgroup Edition |
|---|
| | 107 | kRTWinProdType_ULTIMATE = 0x00000001, ///< Ultimate Edition |
|---|
| | 108 | kRTWinProdType_ULTIMATE_N = 0x0000001C, ///< Ultimate Edition |
|---|
| | 109 | kRTWinProdType_WEB_SERVER = 0x00000011, ///< Web Server Edition (full) |
|---|
| | 110 | kRTWinProdType_WEB_SERVER_CORE = 0x0000001D ///< Web Server Edition (core) |
|---|
| | 111 | } RTWINPRODTYPE; |
|---|
| | 112 | |
|---|
| | 113 | |
|---|
| | 114 | /** |
|---|
| | 115 | * Translates OSVERSIONINOFEX into a Windows OS type. |
|---|
| | 116 | * |
|---|
| | 117 | * @returns The Windows OS type. |
|---|
| | 118 | * @param pOSInfoEx The OS info returned by Windows. |
|---|
| | 119 | * |
|---|
| | 120 | * @remarks This table has been assembled from Usenet postings, personal |
|---|
| | 121 | * observations, and reading other people's code. Please feel |
|---|
| | 122 | * free to add to it or correct it. |
|---|
| | 123 | * <pre> |
|---|
| | 124 | dwPlatFormID dwMajorVersion dwMinorVersion dwBuildNumber |
|---|
| | 125 | 95 1 4 0 950 |
|---|
| | 126 | 95 SP1 1 4 0 >950 && <=1080 |
|---|
| | 127 | 95 OSR2 1 4 <10 >1080 |
|---|
| | 128 | 98 1 4 10 1998 |
|---|
| | 129 | 98 SP1 1 4 10 >1998 && <2183 |
|---|
| | 130 | 98 SE 1 4 10 >=2183 |
|---|
| | 131 | ME 1 4 90 3000 |
|---|
| | 132 | |
|---|
| | 133 | NT 3.51 2 3 51 1057 |
|---|
| | 134 | NT 4 2 4 0 1381 |
|---|
| | 135 | 2000 2 5 0 2195 |
|---|
| | 136 | XP 2 5 1 2600 |
|---|
| | 137 | 2003 2 5 2 3790 |
|---|
| | 138 | Vista 2 6 0 |
|---|
| | 139 | |
|---|
| | 140 | CE 1.0 3 1 0 |
|---|
| | 141 | CE 2.0 3 2 0 |
|---|
| | 142 | CE 2.1 3 2 1 |
|---|
| | 143 | CE 3.0 3 3 0 |
|---|
| | 144 | </pre> |
|---|
| | 145 | */ |
|---|
| | 146 | static RTWINOSTYPE rtSystemWinOSType(OSVERSIONINFOEX const *pOSInfoEx) |
|---|
| | 147 | { |
|---|
| | 148 | RTWINOSTYPE enmVer = kRTWinOSType_UNKNOWN; |
|---|
| | 149 | DWORD const dwPlatformId = pOSInfoEx->dwPlatformId; |
|---|
| | 150 | DWORD const dwMinorVersion = pOSInfoEx->dwMinorVersion; |
|---|
| | 151 | DWORD const dwMajorVersion = pOSInfoEx->dwMajorVersion; |
|---|
| | 152 | DWORD const dwBuildNumber = pOSInfoEx->dwBuildNumber & 0xFFFF; /* Win 9x needs this. */ |
|---|
| | 153 | |
|---|
| | 154 | if ( dwPlatformId == VER_PLATFORM_WIN32_WINDOWS |
|---|
| | 155 | && dwMajorVersion == 4) |
|---|
| | 156 | { |
|---|
| | 157 | if ( dwMinorVersion < 10 |
|---|
| | 158 | && dwBuildNumber == 950) |
|---|
| | 159 | enmVer = kRTWinOSType_95; |
|---|
| | 160 | else if ( dwMinorVersion < 10 |
|---|
| | 161 | && dwBuildNumber > 950 |
|---|
| | 162 | && dwBuildNumber <= 1080) |
|---|
| | 163 | enmVer = kRTWinOSType_95SP1; |
|---|
| | 164 | else if ( dwMinorVersion < 10 |
|---|
| | 165 | && dwBuildNumber > 1080) |
|---|
| | 166 | enmVer = kRTWinOSType_95OSR2; |
|---|
| | 167 | else if ( dwMinorVersion == 10 |
|---|
| | 168 | && dwBuildNumber == 1998) |
|---|
| | 169 | enmVer = kRTWinOSType_98; |
|---|
| | 170 | else if ( dwMinorVersion == 10 |
|---|
| | 171 | && dwBuildNumber > 1998 |
|---|
| | 172 | && dwBuildNumber < 2183) |
|---|
| | 173 | enmVer = kRTWinOSType_98SP1; |
|---|
| | 174 | else if ( dwMinorVersion == 10 |
|---|
| | 175 | && dwBuildNumber >= 2183) |
|---|
| | 176 | enmVer = kRTWinOSType_98SE; |
|---|
| | 177 | else if (dwMinorVersion == 90) |
|---|
| | 178 | enmVer = kRTWinOSType_ME; |
|---|
| | 179 | } |
|---|
| | 180 | else if (dwPlatformId == VER_PLATFORM_WIN32_NT) |
|---|
| | 181 | { |
|---|
| | 182 | if ( dwMajorVersion == 3 |
|---|
| | 183 | && dwMinorVersion == 51) |
|---|
| | 184 | enmVer = kRTWinOSType_NT351; |
|---|
| | 185 | else if ( dwMajorVersion == 4 |
|---|
| | 186 | && dwMinorVersion == 0) |
|---|
| | 187 | enmVer = kRTWinOSType_NT4; |
|---|
| | 188 | else if ( dwMajorVersion == 5 |
|---|
| | 189 | && dwMinorVersion == 0) |
|---|
| | 190 | enmVer = kRTWinOSType_2K; |
|---|
| | 191 | else if ( dwMajorVersion == 5 |
|---|
| | 192 | && dwMinorVersion == 1) |
|---|
| | 193 | enmVer = kRTWinOSType_XP; |
|---|
| | 194 | else if ( dwMajorVersion == 5 |
|---|
| | 195 | && dwMinorVersion == 2) |
|---|
| | 196 | enmVer = kRTWinOSType_2003; |
|---|
| | 197 | else if ( dwMajorVersion == 6 |
|---|
| | 198 | && dwMinorVersion == 0) |
|---|
| | 199 | enmVer = kRTWinOSType_VISTA; |
|---|
| | 200 | /** @todo check Windows Server 2008! */ |
|---|
| | 201 | else |
|---|
| | 202 | enmVer = kRTWinOSType_NT_UNKNOWN; |
|---|
| | 203 | } |
|---|
| | 204 | |
|---|
| | 205 | return enmVer; |
|---|
| | 206 | } |
|---|
| | 207 | |
|---|
| | 208 | |
|---|
| | 209 | /** |
|---|
| | 210 | * Wrapper around the GetProductInfo API. |
|---|
| | 211 | * |
|---|
| | 212 | * @returns The vista type. |
|---|
| | 213 | */ |
|---|
| | 214 | static RTWINPRODTYPE rtSystemWinGetProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion) |
|---|
| | 215 | { |
|---|
| | 216 | BOOL (WINAPI *pfnGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); |
|---|
| | 217 | pfnGetProductInfo = (BOOL (WINAPI *)(DWORD, DWORD, DWORD, DWORD, PDWORD))GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "GetProductInfo"); |
|---|
| | 218 | if (pfnGetProductInfo) |
|---|
| | 219 | { |
|---|
| | 220 | DWORD dwProductType = kRTWinProdType_UNDEFINED; |
|---|
| | 221 | if (pfnGetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, &dwProductType)) |
|---|
| | 222 | return (RTWINPRODTYPE)dwProductType; |
|---|
| | 223 | } |
|---|
| | 224 | return kRTWinProdType_UNDEFINED; |
|---|
| | 225 | } |
|---|
| | 226 | |
|---|
| | 227 | |
|---|
| | 228 | |
|---|
| | 229 | /** |
|---|
| | 230 | * Appends the product type if available. |
|---|
| | 231 | * |
|---|
| | 232 | * @param pszTmp The buffer. Assumes it's big enough. |
|---|
| | 233 | */ |
|---|
| | 234 | static void rtSystemWinAppendProductType(char *pszTmp) |
|---|
| | 235 | { |
|---|
| | 236 | RTWINPRODTYPE enmVistaType = rtSystemWinGetProductInfo(6, 0, 0, 0); |
|---|
| | 237 | switch (enmVistaType) |
|---|
| | 238 | { |
|---|
| | 239 | case kRTWinProdType_BUSINESS: strcat(pszTmp, " Business Edition"); break; |
|---|
| | 240 | case kRTWinProdType_BUSINESS_N: strcat(pszTmp, " Business Edition"); break; |
|---|
| | 241 | case kRTWinProdType_CLUSTER_SERVER: strcat(pszTmp, " Cluster Server Edition"); break; |
|---|
| | 242 | case kRTWinProdType_DATACENTER_SERVER: strcat(pszTmp, " Server Datacenter Edition (full installation)"); break; |
|---|
| | 243 | case kRTWinProdType_DATACENTER_SERVER_CORE: strcat(pszTmp, " Server Datacenter Edition (core installation)"); break; |
|---|
| | 244 | case kRTWinProdType_ENTERPRISE: strcat(pszTmp, " Enterprise Edition"); break; |
|---|
| | 245 | case kRTWinProdType_ENTERPRISE_N: strcat(pszTmp, " Enterprise Edition"); break; |
|---|
| | 246 | case kRTWinProdType_ENTERPRISE_SERVER: strcat(pszTmp, " Server Enterprise Edition (full installation)"); break; |
|---|
| | 247 | case kRTWinProdType_ENTERPRISE_SERVER_CORE: strcat(pszTmp, " Server Enterprise Edition (core installation)"); break; |
|---|
| | 248 | case kRTWinProdType_ENTERPRISE_SERVER_IA64: strcat(pszTmp, " Server Enterprise Edition for Itanium-based Systems"); break; |
|---|
| | 249 | case kRTWinProdType_HOME_BASIC: strcat(pszTmp, " Home Basic Edition"); break; |
|---|
| | 250 | case kRTWinProdType_HOME_BASIC_N: strcat(pszTmp, " Home Basic Edition"); break; |
|---|
| | 251 | case kRTWinProdType_HOME_PREMIUM: strcat(pszTmp, " Home Premium Edition"); break; |
|---|
| | 252 | case kRTWinProdType_HOME_PREMIUM_N: strcat(pszTmp, " Home Premium Edition"); break; |
|---|
| | 253 | case kRTWinProdType_HOME_SERVER: strcat(pszTmp, " Home Server Edition"); break; |
|---|
| | 254 | case kRTWinProdType_SERVER_FOR_SMALLBUSINESS: strcat(pszTmp, " Server for Small Business Edition"); break; |
|---|
| | 255 | case kRTWinProdType_SMALLBUSINESS_SERVER: strcat(pszTmp, " Small Business Server"); break; |
|---|
| | 256 | case kRTWinProdType_SMALLBUSINESS_SERVER_PREMIUM: strcat(pszTmp, " Small Business Server Premium Edition"); break; |
|---|
| | 257 | case kRTWinProdType_STANDARD_SERVER: strcat(pszTmp, " Server Standard Edition (full installation)"); break; |
|---|
| | 258 | case kRTWinProdType_STANDARD_SERVER_CORE: strcat(pszTmp, " Server Standard Edition (core installation)"); break; |
|---|
| | 259 | case kRTWinProdType_STARTER: strcat(pszTmp, " Starter Edition"); break; |
|---|
| | 260 | case kRTWinProdType_STORAGE_ENTERPRISE_SERVER: strcat(pszTmp, " Storage Server Enterprise Edition"); break; |
|---|
| | 261 | case kRTWinProdType_STORAGE_EXPRESS_SERVER: strcat(pszTmp, " Storage Server Express Edition"); break; |
|---|
| | 262 | case kRTWinProdType_STORAGE_STANDARD_SERVER: strcat(pszTmp, " Storage Server Standard Edition"); break; |
|---|
| | 263 | case kRTWinProdType_STORAGE_WORKGROUP_SERVER: strcat(pszTmp, " Storage Server Workgroup Edition"); break; |
|---|
| | 264 | case kRTWinProdType_ULTIMATE: strcat(pszTmp, " Ultimate Edition"); break; |
|---|
| | 265 | case kRTWinProdType_ULTIMATE_N: strcat(pszTmp, " Ultimate Edition"); break; |
|---|
| | 266 | case kRTWinProdType_WEB_SERVER: strcat(pszTmp, " Web Server Edition (full installation)"); break; |
|---|
| | 267 | case kRTWinProdType_WEB_SERVER_CORE: strcat(pszTmp, " Web Server Edition (core installation)"); break; |
|---|
| | 268 | case kRTWinProdType_UNDEFINED: break; |
|---|
| | 269 | } |
|---|
| | 270 | } |
|---|
| | 271 | |
|---|
| | 272 | |
|---|
| | 273 | /** |
|---|
| | 274 | * Services the RTSYSOSINFO_PRODUCT, RTSYSOSINFO_RELEASE |
|---|
| | 275 | * and RTSYSOSINFO_SERVICE_PACK requests. |
|---|
| | 276 | * |
|---|
| | 277 | * @returns See RTSystemQueryOSInfo. |
|---|
| | 278 | * @param enmInfo See RTSystemQueryOSInfo. |
|---|
| | 279 | * @param pszInfo See RTSystemQueryOSInfo. |
|---|
| | 280 | * @param cchInfo See RTSystemQueryOSInfo. |
|---|
| | 281 | */ |
|---|
| | 282 | static int rtSystemWinQueryOSVersion(RTSYSOSINFO enmInfo, char *pszInfo, size_t cchInfo) |
|---|
| | 283 | { |
|---|
| | 284 | int rc; |
|---|
| | 285 | |
|---|
| | 286 | /* |
|---|
| | 287 | * Make sure it's terminated correctly in case of error. |
|---|
| | 288 | */ |
|---|
| | 289 | *pszInfo = '\0'; |
|---|
| | 290 | |
|---|
| | 291 | /* |
|---|
| | 292 | * Query the Windows version. |
|---|
| | 293 | * |
|---|
| | 294 | * ASSUMES OSVERSIONINFOEX starts with the exact same layout as OSVERSIONINFO (safe). |
|---|
| | 295 | */ |
|---|
| | 296 | OSVERSIONINFOEX OSInfoEx; |
|---|
| | 297 | memset(&OSInfoEx, '\0', sizeof(OSInfoEx)); |
|---|
| | 298 | OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
|---|
| | 299 | if (!GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)) |
|---|
| | 300 | { |
|---|
| | 301 | DWORD err = GetLastError(); |
|---|
| | 302 | rc = RTErrConvertFromWin32(err); |
|---|
| | 303 | AssertMsgFailedReturn(("err=%d\n", err), rc == VERR_BUFFER_OVERFLOW ? VERR_INTERNAL_ERROR : rc); |
|---|
| | 304 | } |
|---|
| | 305 | |
|---|
| | 306 | /* Get extended version info for 2000 and later. */ |
|---|
| | 307 | if ( OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT |
|---|
| | 308 | && OSInfoEx.dwMajorVersion >= 5) |
|---|
| | 309 | { |
|---|
| | 310 | ZeroMemory(&OSInfoEx, sizeof(OSInfoEx)); |
|---|
| | 311 | OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); |
|---|
| | 312 | if (!GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)) |
|---|
| | 313 | { |
|---|
| | 314 | DWORD err = GetLastError(); |
|---|
| | 315 | rc = RTErrConvertFromWin32(err); |
|---|
| | 316 | AssertMsgFailedReturn(("err=%d\n", err), rc == VERR_BUFFER_OVERFLOW ? VERR_INTERNAL_ERROR : rc); |
|---|
| | 317 | } |
|---|
| | 318 | } |
|---|
| | 319 | |
|---|
| | 320 | /* |
|---|
| | 321 | * Service the request. |
|---|
| | 322 | */ |
|---|
| | 323 | char szTmp[512]; |
|---|
| | 324 | szTmp[0] = '\0'; |
|---|
| | 325 | rc = VINF_SUCCESS; |
|---|
| | 326 | switch (enmInfo) |
|---|
| | 327 | { |
|---|
| | 328 | /* |
|---|
| | 329 | * The product name. |
|---|
| | 330 | */ |
|---|
| | 331 | case RTSYSOSINFO_PRODUCT: |
|---|
| | 332 | { |
|---|
| | 333 | RTWINOSTYPE enmVer = rtSystemWinOSType(&OSInfoEx); |
|---|
| | 334 | switch (enmVer) |
|---|
| | 335 | { |
|---|
| | 336 | case kRTWinOSType_95: strcpy(szTmp, "Windows 95"); break; |
|---|
| | 337 | case kRTWinOSType_95SP1: strcpy(szTmp, "Windows 95 (Service Pack 1)"); break; |
|---|
| | 338 | case kRTWinOSType_95OSR2: strcpy(szTmp, "Windows 95 (OSR 2)"); break; |
|---|
| | 339 | case kRTWinOSType_98: strcpy(szTmp, "Windows 98"); break; |
|---|
| | 340 | case kRTWinOSType_98SP1: strcpy(szTmp, "Windows 98 (Service Pack 1)"); break; |
|---|
| | 341 | case kRTWinOSType_98SE: strcpy(szTmp, "Windows 98 (Second Edition)"); break; |
|---|
| | 342 | case kRTWinOSType_ME: strcpy(szTmp, "Windows Me"); break; |
|---|
| | 343 | case kRTWinOSType_NT351: strcpy(szTmp, "Windows NT 3.51"); break; |
|---|
| | 344 | case kRTWinOSType_NT4: strcpy(szTmp, "Windows NT 4.0"); break; |
|---|
| | 345 | case kRTWinOSType_2K: strcpy(szTmp, "Windows 2000"); break; |
|---|
| | 346 | case kRTWinOSType_XP: |
|---|
| | 347 | strcpy(szTmp, "Windows XP"); |
|---|
| | 348 | if (OSInfoEx.wSuiteMask & VER_SUITE_PERSONAL) |
|---|
| | 349 | strcat(szTmp, " Home"); |
|---|
| | 350 | if ( OSInfoEx.wProductType == VER_NT_WORKSTATION |
|---|
| | 351 | && !(OSInfoEx.wSuiteMask & VER_SUITE_PERSONAL)) |
|---|
| | 352 | strcat(szTmp, " Professional"); |
|---|
| | 353 | #if 0 /** @todo fixme */ |
|---|
| | 354 | if (GetSystemMetrics(SM_MEDIACENTER)) |
|---|
| | 355 | strcat(szTmp, " Media Center"); |
|---|
| | 356 | #endif |
|---|
| | 357 | break; |
|---|
| | 358 | |
|---|
| | 359 | case kRTWinOSType_2003: strcpy(szTmp, "Windows 2003"); break; |
|---|
| | 360 | case kRTWinOSType_VISTA: |
|---|
| | 361 | { |
|---|
| | 362 | strcpy(szTmp, "Windows Vista"); |
|---|
| | 363 | rtSystemWinAppendProductType(szTmp); |
|---|
| | 364 | break; |
|---|
| | 365 | } |
|---|
| | 366 | |
|---|
| | 367 | case kRTWinOSType_NT_UNKNOWN: |
|---|
| | 368 | RTStrPrintf(szTmp, sizeof(szTmp), "Unknown NT v%u.%u", OSInfoEx.dwMajorVersion, OSInfoEx.dwMinorVersion); |
|---|
| | 369 | break; |
|---|
| | 370 | |
|---|
| | 371 | default: |
|---|
| | 372 | AssertFailed(); |
|---|
| | 373 | case kRTWinOSType_UNKNOWN: |
|---|
| | 374 | RTStrPrintf(szTmp, sizeof(szTmp), "Unknown %d v%u.%u", OSInfoEx.dwPlatformId, OSInfoEx.dwMajorVersion, OSInfoEx.dwMinorVersion); |
|---|
| | 375 | break; |
|---|
| | 376 | } |
|---|
| | 377 | break; |
|---|
| | 378 | } |
|---|
| | 379 | |
|---|
| | 380 | /* |
|---|
| | 381 | * The release. |
|---|
| | 382 | */ |
|---|
| | 383 | case RTSYSOSINFO_RELEASE: |
|---|
| | 384 | { |
|---|
| | 385 | RTWINOSTYPE enmVer = rtSystemWinOSType(&OSInfoEx); |
|---|
| | 386 | RTStrPrintf(szTmp, sizeof(szTmp), "%u.%u.%u", OSInfoEx.dwMajorVersion, OSInfoEx.dwMinorVersion, OSInfoEx.dwBuildNumber); |
|---|
| | 387 | break; |
|---|
| | 388 | } |
|---|
| | 389 | |
|---|
| | 390 | |
|---|
| | 391 | /* |
|---|
| | 392 | * Get the service pack. |
|---|
| | 393 | */ |
|---|
| | 394 | case RTSYSOSINFO_SERVICE_PACK: |
|---|
| | 395 | { |
|---|
| | 396 | if (OSInfoEx.wServicePackMajor) |
|---|
| | 397 | { |
|---|
| | 398 | if (OSInfoEx.wServicePackMinor) |
|---|
| | 399 | RTStrPrintf(szTmp, sizeof(szTmp), "Service Pack %u.%u", (unsigned)OSInfoEx.wServicePackMajor, (unsigned)OSInfoEx.wServicePackMinor); |
|---|
| | 400 | else |
|---|
| | 401 | RTStrPrintf(szTmp, sizeof(szTmp), "Service Pack %u", (unsigned)OSInfoEx.wServicePackMajor); |
|---|
| | 402 | } |
|---|
| | 403 | else if (OSInfoEx.szCSDVersion[0]) |
|---|
| | 404 | { |
|---|
| | 405 | /* just copy the entire string. */ |
|---|
| | 406 | memcpy(szTmp, OSInfoEx.szCSDVersion, sizeof(OSInfoEx.szCSDVersion)); |
|---|
| | 407 | szTmp[sizeof(OSInfoEx.szCSDVersion)] = '\0'; |
|---|
| | 408 | AssertCompile(sizeof(szTmp) > sizeof(OSInfoEx.szCSDVersion)); |
|---|
| | 409 | } |
|---|
| | 410 | else |
|---|
| | 411 | { |
|---|
| | 412 | RTWINOSTYPE enmVer = rtSystemWinOSType(&OSInfoEx); |
|---|
| | 413 | switch (enmVer) |
|---|
| | 414 | { |
|---|
| | 415 | case kRTWinOSType_95SP1: strcpy(szTmp, "Service Pack 1"); break; |
|---|
| | 416 | case kRTWinOSType_98SP1: strcpy(szTmp, "Service Pack 1"); break; |
|---|
| | 417 | default: |
|---|
| | 418 | break; |
|---|
| | 419 | } |
|---|
| | 420 | } |
|---|
| | 421 | break; |
|---|
| | 422 | } |
|---|
| | 423 | |
|---|
| | 424 | default: |
|---|
| | 425 | AssertFatalFailed(); |
|---|
| | 426 | } |
|---|
| | 427 | |
|---|
| | 428 | /* |
|---|
| | 429 | * Copy the result to the return buffer. |
|---|
| | 430 | */ |
|---|
| | 431 | size_t cchTmp = strlen(szTmp); |
|---|
| | 432 | Assert(cchTmp < sizeof(szTmp)); |
|---|
| | 433 | if (cchTmp < cchInfo) |
|---|
| | 434 | memcpy(pszInfo, szTmp, cchTmp + 1); |
|---|
| | 435 | else |
|---|
| | 436 | { |
|---|
| | 437 | memcpy(pszInfo, szTmp, cchInfo - 1); |
|---|
| | 438 | pszInfo[cchInfo - 1] = '\0'; |
|---|
| | 439 | if (RT_SUCCESS(rc)) |
|---|
| | 440 | rc = VERR_BUFFER_OVERFLOW; |
|---|
| | 441 | } |
|---|
| | 442 | return VINF_SUCCESS; |
|---|
| | 443 | } |
|---|
| | 444 | |
|---|