diff options
author | Andreas Baumann <abaumann@yahoo.com> | 2014-12-04 15:08:40 +0100 |
---|---|---|
committer | Andreas Baumann <abaumann@yahoo.com> | 2014-12-04 15:08:40 +0100 |
commit | 5706fc4a77f6d30d5fefa627914d102a5bab8e0e (patch) | |
tree | 36e578dc7741f5eaa3fa390f85dac10c4a783bb2 /src | |
parent | 7836764be463d8a537e8a2db6003af1356c7ea37 (diff) | |
download | biruda-5706fc4a77f6d30d5fefa627914d102a5bab8e0e.tar.gz biruda-5706fc4a77f6d30d5fefa627914d102a5bab8e0e.tar.bz2 |
implemented system detection on Windows (CPE)
Diffstat (limited to 'src')
-rw-r--r-- | src/biruda.c | 12 | ||||
-rw-r--r-- | src/system.c | 159 |
2 files changed, 168 insertions, 3 deletions
diff --git a/src/biruda.c b/src/biruda.c index f4ff03a..0e0379c 100644 --- a/src/biruda.c +++ b/src/biruda.c @@ -22,6 +22,7 @@ #include "libdaemon/daemon.h" #endif +#include "system.h" #include "master.h" #include "worker.h" #include "coordinator.h" @@ -154,6 +155,17 @@ static int read_config( const char *filename, cfg_t **cfg ) static void print_config( struct gengetopt_args_info *args_info, cfg_t *cfg ) { + unsigned int nofCpus = system_available_cpus( ); + puts( "Environment:" ); + printf( " Number of CPUs: %d\n", nofCpus ); + char machine_arch[100]; + system_arch( machine_arch, sizeof( machine_arch ) ); + printf( " System architecture: %s\n", machine_arch ); + char os_name[100]; + system_os( os_name, sizeof( os_name ) ); + printf( " Operating system: %s\n", os_name ); + puts( "" ); + cfg_t *master_cfg = cfg_getnsec( cfg, "master", 0 ); unsigned int has_master = cfg_size( cfg, "master" ); if( has_master ) { 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" ); |