/*++ >>> This code is released to the public domain. No warranty whatsoever is provided. Use it at your own risk. <<< Module Name: version.c Abstract: Determine the Windows version number running and set the errorlevel appropriately. Intended for use with batch scripts. Author: Scott Gasch (scott@gasch.org) 22 Aug 2002 Revision History: --*/ #include #include #include // // This code _should_ run on win9x/ME or any version of NT. Note: I have // not personally tested it on 9x/ME though. It prints out a message on // stdout about which version of the windows operating system is running // and sets the errorlevel to one of the values below accordingly. Might // be useful in your CMD/BAT script... // #define EXIT_WIN95 (1) #define EXIT_WIN98 (2) #define EXIT_WINME (3) #define EXIT_CONSUMER_OTHER (4) #define EXIT_NT351 (5) #define EXIT_NT3OTHER (6) #define EXIT_NT4 (7) #define EXIT_NT4OTHER (8) #define EXIT_WIN2K (9) #define EXIT_WINXP (10) #define EXIT_WIN_SERVER_2003 (11) #define EXIT_NT5OTHER (12) #define EXIT_VISTA (13) #define EXIT_UNKNOWN (14) CHAR *g_szWindowsNames[] = { "Not Used", "Windows95", "Windows98", "WindowsME", "Unknown Consumer Windows Release", "Windows NT", "Unknown Windows NT", "Windows NT", "Unknown Windows NT", "Windows 2000", "WindowsXP", "Windows Server 2003", "Unknown Windows NT", "Longhorn Prerelease", "Unknown Operating System" }; typedef BOOL (*FUNCTION_PTR)(OSVERSIONINFO *); BOOL TryWinNT(DWORD *pdwMajor, DWORD *pdwMinor, DWORD *pdwPlatform) /*++ Routine description: GetVersionEx is not present on downlevel versions of Windows. Deal with this by using LoadLibrary/GetProcAddress. Parameters: DWORD *pdwMajor, DWORD *pdwMinor, DWORD *pdwPlatform Return value: BOOL --*/ { FUNCTION_PTR p; BOOL fRet = FALSE; HMODULE h = NULL; OSVERSIONINFOEXA osvi; h = LoadLibraryA("kernel32.dll"); if (NULL == h) { fprintf(stderr, "Failed to load kernel32.dll, error=%u.\n", GetLastError()); goto end; } p = (FUNCTION_PTR)GetProcAddress(h, "GetVersionExA"); if (NULL == p) { fprintf(stderr, "GetProcAddress for GetVersionEx failed, error=%u.\n", GetLastError()); goto end; } ZeroMemory(&osvi, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(osvi); fRet = (*p)((OSVERSIONINFO *)&osvi); if (FALSE == fRet) { fprintf(stderr, "GetVersionEx failed, error=%u.\n", GetLastError()); goto end; } *pdwMajor = osvi.dwMajorVersion; *pdwMinor = osvi.dwMinorVersion; *pdwPlatform = osvi.dwPlatformId; end: if (NULL != h) { FreeLibrary(h); } return(fRet); } int __cdecl main(void) /*++ Routine description: Program entry point. Parameters: void Return value: int __cdecl --*/ { DWORD dwMajor, dwMinor, dwPlatform; DWORD dwVersion; int iRet = EXIT_UNKNOWN; // // This call should be available on all versions of Windows // dwVersion = GetVersion(); if ((dwVersion & 0x80000000) || (FALSE == TryWinNT(&dwMajor, &dwMinor, &dwPlatform))) { dwMajor = (DWORD)(LOBYTE(LOWORD(dwVersion))); dwMinor = (DWORD)(HIBYTE(LOWORD(dwVersion))); dwPlatform = VER_PLATFORM_WIN32_WINDOWS; } // // Parse results // if (dwPlatform == VER_PLATFORM_WIN32_NT) { switch(dwMajor) { case 3: iRet = EXIT_NT3OTHER; if (51 == dwMinor) { iRet = EXIT_NT351; } goto end; case 4: iRet = EXIT_NT4OTHER; if (0 == dwMinor) { iRet = EXIT_NT4; } goto end; case 5: iRet = EXIT_NT5OTHER; if (0 == dwMinor) { iRet = EXIT_WIN2K; } else if (1 == dwMinor) { iRet = EXIT_WINXP; } else if (2 == dwMinor) { iRet = EXIT_WIN_SERVER_2003; } goto end; case 6: iRet = EXIT_VISTA; goto end; default: goto end; } } else if (dwPlatform == VER_PLATFORM_WIN32_WINDOWS) { switch(dwMajor) { case 4: iRet = EXIT_CONSUMER_OTHER; if (0 == dwMinor) { iRet = EXIT_WIN95; } else if (10 == dwMinor) { iRet = EXIT_WIN98; } else if (90 == dwMinor) { iRet = EXIT_WINME; } goto end; default: goto end; } } end: printf("%s %u.%u -- errorlevel is %d\n", g_szWindowsNames[iRet], dwMajor, dwMinor, iRet); exit(iRet); }