summaryrefslogtreecommitdiff
path: root/src/system.c
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2014-12-04 15:08:40 +0100
committerAndreas Baumann <abaumann@yahoo.com>2014-12-04 15:08:40 +0100
commit5706fc4a77f6d30d5fefa627914d102a5bab8e0e (patch)
tree36e578dc7741f5eaa3fa390f85dac10c4a783bb2 /src/system.c
parent7836764be463d8a537e8a2db6003af1356c7ea37 (diff)
downloadbiruda-5706fc4a77f6d30d5fefa627914d102a5bab8e0e.tar.gz
biruda-5706fc4a77f6d30d5fefa627914d102a5bab8e0e.tar.bz2
implemented system detection on Windows (CPE)
Diffstat (limited to 'src/system.c')
-rw-r--r--src/system.c159
1 files changed, 156 insertions, 3 deletions
diff --git a/src/system.c b/src/system.c
index 5a62242..aad9729 100644
--- a/src/system.c
+++ b/src/system.c
@@ -25,6 +25,7 @@ unsigned int system_available_cpus( void )
// operating specific cases
#ifdef _WIN32
SYSTEM_INFO info;
+ memset( &info, 0, sizeof( SYSTEM_INFO ) );
GetSystemInfo( &info );
return info.dwNumberOfProcessors;
#else
@@ -58,11 +59,163 @@ unsigned int system_available_cpus( void )
#endif // _WIN32
}
+static bool verifyVersion( const DWORD major, const DWORD minor )
+{
+ OSVERSIONINFOEX info;
+ memset( &info, 0, sizeof( OSVERSIONINFOEX ) );
+ info.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
+ info.dwMajorVersion = major;
+ info.dwMinorVersion = minor;
+ info.dwPlatformId = VER_PLATFORM_WIN32_NT; // all other have gone..
+
+ DWORDLONG condMask = 0;
+ VER_SET_CONDITION( condMask, VER_MAJORVERSION, VER_GREATER_EQUAL );
+ VER_SET_CONDITION( condMask, VER_MINORVERSION, VER_GREATER_EQUAL );
+ VER_SET_CONDITION( condMask, VER_PLATFORMID, VER_EQUAL );
+
+ const BOOL res = VerifyVersionInfo( &info, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, condMask );
+ if( !res ) {
+ if( GetLastError( ) == ERROR_OLD_WIN_VERSION ) {
+ return false;
+ } else {
+ fprintf( stderr, "VerifyVersionInfo( ) failed for %u.%u!\n",
+ major, minor );
+ return false;
+ }
+ }
+
+ return true;
+}
+
void system_os( char *name, size_t len )
{
#ifdef _WIN32
- /* TODO: test for Windows versions */
- snprintf( name, len, "cpe:/o:microsoft:windows:unknown" );
+ OSVERSIONINFOEX info;
+ memset( &info, 0, sizeof( OSVERSIONINFOEX ) );
+ info.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
+ if( !GetVersionEx( (LPOSVERSIONINFO)&info ) ) {
+ snprintf( name, len, "cpe:/o:microsoft:windows:unknown" );
+ return;
+ }
+
+ DWORD major = info.dwMajorVersion;
+ DWORD minor = info.dwMinorVersion;
+
+ // GetVersionEx "lies" to us since Windows 8.1, so verify real
+ // version with VerifyVersionInfo
+ for( DWORD nextMajor = major + 1; nextMajor < 20; nextMajor++ ) {
+ if( verifyVersion( nextMajor, 0 ) ) {
+ major = nextMajor;
+ break;
+ }
+ }
+
+ for( DWORD nextMinor = minor + 1; nextMinor < 20; nextMinor++ ) {
+ if( verifyVersion( major, nextMinor ) ) {
+ minor = nextMinor;
+ break;
+ }
+ }
+
+ switch( major ) {
+ case 6:
+ switch( minor ) {
+ case 3:
+ switch( info.wProductType ) {
+ case VER_NT_DOMAIN_CONTROLLER:
+ case VER_NT_SERVER:
+ snprintf( name, len, "cpe:/o:microsoft:windows_server_2012:r2" );
+ break;
+
+ case VER_NT_WORKSTATION:
+ snprintf( name, len, "cpe:/o:microsoft:windows_8.1" );
+ break;
+ }
+ break;
+
+ case 2:
+ switch( info.wProductType ) {
+ case VER_NT_DOMAIN_CONTROLLER:
+ case VER_NT_SERVER:
+ snprintf( name, len, "cpe:/o:microsoft:windows_server_2012" );
+ break;
+
+ case VER_NT_WORKSTATION:
+ snprintf( name, len, "cpe:/o:microsoft:windows_8" );
+ break;
+ }
+ break;
+
+ case 1:
+ switch( info.wProductType ) {
+ case VER_NT_DOMAIN_CONTROLLER:
+ case VER_NT_SERVER:
+ snprintf( name, len, "cpe:/o:microsoft:windows_server_2008:r2" );
+ break;
+
+ case VER_NT_WORKSTATION:
+ snprintf( name, len, "cpe:/o:microsoft:windows_7" );
+ break;
+ }
+ break;
+
+ case 0:
+ switch( info.wProductType ) {
+ case VER_NT_DOMAIN_CONTROLLER:
+ case VER_NT_SERVER:
+ snprintf( name, len, "cpe:/o:microsoft:windows_server_2008" );
+ break;
+
+ case VER_NT_WORKSTATION:
+ snprintf( name, len, "cpe:/o:microsoft:windows_vista" );
+ break;
+ }
+ break;
+
+ default:
+ snprintf( name, len, "cpe:/o:microsoft:windows" );
+ break;
+ }
+ break;
+
+ case 5:
+ switch( minor ) {
+ case 2:
+ switch( info.wProductType ) {
+ case VER_NT_DOMAIN_CONTROLLER:
+ case VER_NT_SERVER:
+ snprintf( name, len, "cpe:/o:microsoft:windows_server_2003" );
+ break;
+
+ case VER_NT_WORKSTATION:
+ snprintf( name, len, "cpe:/o:microsoft:windows" );
+ break;
+ }
+ break;
+
+ case 1:
+ switch( info.wProductType ) {
+ case VER_NT_DOMAIN_CONTROLLER:
+ case VER_NT_SERVER:
+ snprintf( name, len, "cpe:/o:microsoft:windows" );
+ break;
+
+ case VER_NT_WORKSTATION:
+ snprintf( name, len, "cpe:/o:microsoft:windows_xp" );
+ break;
+ }
+ break;
+
+ default:
+ snprintf( name, len, "cpe:/o:microsoft:windows" );
+ break;
+ }
+ break;
+
+ default:
+ snprintf( name, len, "cpe:/o:microsoft:windows" );
+ break;
+ }
#elif defined( linux ) || defined( __linux ) || defined( __linux__ )
/* new systemd-way on modern Linux systems */
FILE *f = fopen( "/etc/os-release", "r" );
@@ -154,8 +307,8 @@ void system_arch( char *name, size_t len )
{
#ifdef _WIN32
SYSTEM_INFO info;
+ memset( &info, 0, sizeof( SYSTEM_INFO ) );
GetSystemInfo( &info );
- printf( "%d\n", info.wProcessorArchitecture );
switch( info.wProcessorArchitecture ) {
case PROCESSOR_ARCHITECTURE_AMD64:
snprintf( name, len, "x86_64" );