3232
3333#include <windows.h>
3434#include <windowsx.h>
35+ #include <assert.h>
3536#include <stdlib.h>
3637#include <stdio.h>
3738#include <string.h>
@@ -813,16 +814,63 @@ void set_loglevel(DWORD menu_cmd)
813814 wdi_set_log_level (log_level );
814815}
815816
816- BOOL is_x64 (void )
817+ static __inline USHORT get_application_arch (void )
817818{
818- BOOL ret = FALSE;
819- // Detect if we're running a 32 or 64 bit system
820- if (sizeof (uintptr_t ) < 8 ) {
821- IsWow64Process (GetCurrentProcess (), & ret );
822- } else {
823- ret = TRUE;
819+ #if defined(_M_AMD64 )
820+ return IMAGE_FILE_MACHINE_AMD64 ;
821+ #elif defined(_M_IX86 )
822+ return IMAGE_FILE_MACHINE_I386 ;
823+ #elif defined(_M_ARM64 )
824+ return IMAGE_FILE_MACHINE_ARM64 ;
825+ #elif defined(_M_ARM )
826+ return IMAGE_FILE_MACHINE_ARM ;
827+ #else
828+ return IMAGE_FILE_MACHINE_UNKNOWN ;
829+ #endif
830+ }
831+
832+ static __inline const char * get_arch_name (USHORT uArch )
833+ {
834+ switch (uArch ) {
835+ case IMAGE_FILE_MACHINE_AMD64 :
836+ return "x64" ;
837+ case IMAGE_FILE_MACHINE_I386 :
838+ return "x86" ;
839+ case IMAGE_FILE_MACHINE_ARM64 :
840+ return "arm64" ;
841+ case IMAGE_FILE_MACHINE_ARM :
842+ return "arm" ;
843+ default :
844+ return "unknown" ;
824845 }
825- return ret ;
846+ }
847+
848+ // Detect the underlying platform arch.
849+ static USHORT get_platform_arch (void )
850+ {
851+ BOOL is_64bit = FALSE, is_wow64 = FALSE;
852+ USHORT ProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN , NativeMachine = IMAGE_FILE_MACHINE_UNKNOWN ;
853+
854+ PF_TYPE_DECL (WINAPI , BOOL , IsWow64Process2 , (HANDLE , USHORT * , USHORT * ));
855+ PF_INIT (IsWow64Process2 , Kernel32 );
856+
857+ if ((pfIsWow64Process2 == NULL ) ||
858+ !pfIsWow64Process2 (GetCurrentProcess (), & ProcessMachine , & NativeMachine )) {
859+ // Assume same arch as the app
860+ NativeMachine = get_application_arch ();
861+ // Fix the Arch if we have a 32-bit app running under WOW64
862+ if ((sizeof (uintptr_t ) < 8 ) && IsWow64Process (GetCurrentProcess (), & is_wow64 ) && is_wow64 ) {
863+ if (NativeMachine == IMAGE_FILE_MACHINE_I386 )
864+ NativeMachine = IMAGE_FILE_MACHINE_AMD64 ;
865+ else if (NativeMachine == IMAGE_FILE_MACHINE_ARM )
866+ NativeMachine = IMAGE_FILE_MACHINE_ARM64 ;
867+ else // I sure wanna be made aware of this scenario...
868+ assert (FALSE);
869+ }
870+ dprintf ("Note: Underlying Windows architecture was guessed and may be incorrect..." );
871+ }
872+
873+ return NativeMachine ;
826874}
827875
828876static const char * get_edition (DWORD ProductType )
@@ -913,10 +961,18 @@ static const char* get_edition(DWORD ProductType)
913961 case 0x000000A5 : return "Pro for Education N" ;
914962 case 0x000000AB : return "Enterprise G" ; // I swear Microsoft are just making up editions...
915963 case 0x000000AC : return "Enterprise G N" ;
964+ case 0x000000B2 : return "Cloud" ;
965+ case 0x000000B3 : return "Cloud N" ;
916966 case 0x000000B6 : return "Home OS" ;
917- case 0x000000B7 : return "Cloud E" ;
918- case 0x000000B8 : return "Cloud E N" ;
967+ case 0x000000B7 : case 0x000000CB : return "Cloud E" ;
968+ case 0x000000B9 : return "IoT OS" ;
969+ case 0x000000BA : case 0x000000CA : return "Cloud E N" ;
970+ case 0x000000BB : return "IoT Edge OS" ;
971+ case 0x000000BC : return "IoT Enterprise" ;
919972 case 0x000000BD : return "Lite" ;
973+ case 0x000000BF : return "IoT Enterprise S" ;
974+ case 0x000000C0 : case 0x000000C2 : case 0x000000C3 : case 0x000000C4 : case 0x000000C5 : case 0x000000C6 : return "XBox" ;
975+ case 0x000000C7 : case 0x000000C8 : case 0x00000196 : case 0x00000197 : case 0x00000198 : return "Azure Server" ;
920976 case 0xABCDABCD : return "(Unlicensed)" ;
921977 default :
922978 static_sprintf (unknown_edition_str , "(Unknown Edition 0x%02X)" , (uint32_t )ProductType );
@@ -931,8 +987,8 @@ int get_windows_version(char* WindowsVersionStr, size_t WindowsVersionStrSize)
931987{
932988 OSVERSIONINFOEXA vi , vi2 ;
933989 DWORD dwProductType ;
934- const char * w = 0 ;
935- const char * w64 = "32 bit" ;
990+ const char * w = NULL ;
991+ const char * arch_name ;
936992 char * vptr ;
937993 size_t vlen ;
938994 unsigned major , minor ;
@@ -1023,22 +1079,21 @@ int get_windows_version(char* WindowsVersionStr, size_t WindowsVersionStrSize)
10231079 }
10241080 }
10251081
1026- if (is_x64 ())
1027- w64 = "64-bit" ;
1082+ arch_name = get_arch_name (get_platform_arch ());
10281083
10291084 GetProductInfo (vi .dwMajorVersion , vi .dwMinorVersion , vi .wServicePackMajor , vi .wServicePackMinor , & dwProductType );
10301085 vptr = & WindowsVersionStr [sizeof ("Windows " ) - 1 ];
10311086 vlen = WindowsVersionStrSize - sizeof ("Windows " ) - 1 ;
10321087 if (!w )
10331088 safe_sprintf (vptr , vlen , "%s %u.%u %s" , (vi .dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??" ),
1034- (unsigned )vi .dwMajorVersion , (unsigned )vi .dwMinorVersion , w64 );
1089+ (unsigned )vi .dwMajorVersion , (unsigned )vi .dwMinorVersion , arch_name );
10351090 else if (vi .wServicePackMinor )
1036- safe_sprintf (vptr , vlen , "%s SP%u.%u %s" , w , vi .wServicePackMajor , vi .wServicePackMinor , w64 );
1091+ safe_sprintf (vptr , vlen , "%s SP%u.%u %s" , w , vi .wServicePackMajor , vi .wServicePackMinor , arch_name );
10371092 else if (vi .wServicePackMajor )
1038- safe_sprintf (vptr , vlen , "%s SP%u %s" , w , vi .wServicePackMajor , w64 );
1093+ safe_sprintf (vptr , vlen , "%s SP%u %s" , w , vi .wServicePackMajor , arch_name );
10391094 else
10401095 safe_sprintf (vptr , vlen , "%s%s%s, %s" ,
1041- w , (dwProductType != PRODUCT_UNDEFINED ) ? " " : "" , get_edition (dwProductType ), w64 );
1096+ w , (dwProductType != PRODUCT_UNDEFINED ) ? " " : "" , get_edition (dwProductType ), arch_name );
10421097
10431098 // Add the build number (including UBR if available) for Windows 8.0 and later
10441099 nWindowsBuildNumber = vi .dwBuildNumber ;
0 commit comments