This patch super-seeds my previous attempt ID 91173. This time I used do_cpuid from ntdll / wbemprox. If cpuid is not available, the default "Intel Pentium 4" string is used. I modified get_processor_name to remove leading white-spaces. I also updated the code for Identifier REG_SZ. This applies to 64bit wine only, as 32bit still reports x86.
From b2d44473592cfe2840912b30fb345a513bd58f7d Mon Sep 17 00:00:00 2001
From: Patrick Rudolph <s...@das-labor.org>
Date: Mon, 22 Oct 2012 20:46:58 +0200
Subject: wineboot: detect correct processor name and vendorID, using cpuid

---
 programs/wineboot/wineboot.c |  160 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 145 insertions(+), 15 deletions(-)

diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 0be773b..ae67516 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -159,6 +159,112 @@ done:
     return ret;
 }
 
+/* TODO: move do_cpuid and have_cpuid to a common header */
+static inline void do_cpuid( unsigned int ax, unsigned int *p )
+{
+#ifdef __i386__
+    __asm__("pushl %%ebx\n\t"
+                "cpuid\n\t"
+                "movl %%ebx, %%esi\n\t"
+                "popl %%ebx"
+                : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3])
+                :  "0" (ax));
+#endif
+}
+
+/* From xf86info havecpuid.c 1.11 */
+static inline int have_cpuid(void)
+{
+#ifdef __i386__
+	unsigned int f1, f2;
+	__asm__("pushfl\n\t"
+                "pushfl\n\t"
+                "popl %0\n\t"
+                "movl %0,%1\n\t"
+                "xorl %2,%0\n\t"
+                "pushl %0\n\t"
+                "popfl\n\t"
+                "pushfl\n\t"
+                "popl %0\n\t"
+                "popfl"
+                : "=&r" (f1), "=&r" (f2)
+                : "ir" (0x00200000));
+	return ((f1^f2) & 0x00200000) != 0;
+#else
+        return 0;
+#endif
+}
+
+/* helper for get_processor_* */
+static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
+{
+    unsigned int i;
+    unsigned char *p = (unsigned char *)regs;
+
+    for (i = 0; i < len; i++)
+    {
+        buffer[i] = *p++;
+    }
+    buffer[i] = 0;
+}
+
+static void get_processor_manufacturer( WCHAR *manufacturer )
+{
+#ifdef __i386__
+    unsigned int tmp, regs[4] = {0, 0, 0, 0};
+    static const WCHAR VenidIntelW[] = {'G','e','n','u','i','n','e','I','n','t','e','l',0};
+
+    if (!have_cpuid())
+    {
+        memcpy(manufacturer, VenidIntelW, sizeof(VenidIntelW));
+        return;
+    }
+
+    do_cpuid( 0, regs );
+    tmp = regs[2];      /* swap edx and ecx */
+    regs[2] = regs[3];
+    regs[3] = tmp;
+
+    regs_to_str( regs + 1, 12, manufacturer );
+#else
+    WINE_FIXME("non i386 CPUs aren't supported yet\n");
+#endif
+}
+
+static void get_processor_name( WCHAR *name )
+{
+#ifdef __i386__
+    unsigned int tmp, regs[4] = {0, 0, 0, 0};
+    static const WCHAR IntelCpuStringW[] = {'I','n','t','e','l','(','R',')',' ','P','e','n','t','i','u','m','(','R',')',' ','4',' ',
+                                            'C','P','U',' ','2','.','4',' ','G','H','z',0};
+    if (!have_cpuid())
+    {
+        memcpy(name, IntelCpuStringW, sizeof(IntelCpuStringW));
+        return;
+    }
+
+    do_cpuid( 0x80000000, regs );
+    if (regs[0] >= 0x80000004)
+    {
+        do_cpuid( 0x80000002, regs );
+        regs_to_str( regs, 16, name );
+        do_cpuid( 0x80000003, regs );
+        regs_to_str( regs, 16, name + 16 );
+        do_cpuid( 0x80000004, regs );
+        regs_to_str( regs, 16, name + 32 );
+
+        /* cut leading whitespace */
+        tmp = 0;
+        while(*(name+tmp) == (WCHAR)' ')
+            tmp++;
+        if(tmp < 48)
+            memmove(name,name+tmp,48-tmp);
+    }
+#else
+    WINE_FIXME("non i386 CPUs aren't supported yet\n");
+#endif
+}
+
 /* wrapper for RegSetValueExW */
 static DWORD set_reg_value( HKEY hkey, const WCHAR *name, const WCHAR *value )
 {
@@ -179,19 +285,22 @@ static void create_hardware_registry_keys(void)
     static const WCHAR SysidW[] = {'A','T',' ','c','o','m','p','a','t','i','b','l','e',0};
     static const WCHAR mhzKeyW[] = {'~','M','H','z',0};
     static const WCHAR VendorIdentifierW[] = {'V','e','n','d','o','r','I','d','e','n','t','i','f','i','e','r',0};
-    static const WCHAR VenidIntelW[] = {'G','e','n','u','i','n','e','I','n','t','e','l',0};
-    /* static const WCHAR VenidAMDW[] = {'A','u','t','h','e','n','t','i','c','A','M','D',0}; */
     static const WCHAR PercentDW[] = {'%','d',0};
-    static const WCHAR IntelCpuDescrW[] = {'x','8','6',' ','F','a','m','i','l','y',' ','%','d',' ','M','o','d','e','l',' ','%','d',
+    static const WCHAR CommonCpuDescrW[] = {'%','s',' ','F','a','m','i','l','y',' ','%','d',' ','M','o','d','e','l',' ','%','d',
                                            ' ','S','t','e','p','p','i','n','g',' ','%','d',0};
-    static const WCHAR IntelCpuStringW[] = {'I','n','t','e','l','(','R',')',' ','P','e','n','t','i','u','m','(','R',')',' ','4',' ',
-                                            'C','P','U',' ','2','.','4','0','G','H','z',0};
+    static const WCHAR x86W[]      = {'x','8','6',0};
+    static const WCHAR Intel64W[]     = {'I','n','t','e','l','6','4',0};
+    static const WCHAR AMD64W[]    = {'A','M','D','6','4',0};
+
+    static const WCHAR IntelW[]     = {'I','n','t','e','l',0};
+
     unsigned int i;
     HKEY hkey, system_key, cpu_key, fpu_key;
     SYSTEM_CPU_INFORMATION sci;
     PROCESSOR_POWER_INFORMATION* power_info;
     ULONG sizeof_power_info = sizeof(PROCESSOR_POWER_INFORMATION) * NtCurrentTeb()->Peb->NumberOfProcessors;
     WCHAR idW[60];
+    const WCHAR *arch;
 
     NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL );
 
@@ -201,9 +310,6 @@ static void create_hardware_registry_keys(void)
     if (NtPowerInformation( ProcessorInformation, NULL, 0, power_info, sizeof_power_info ))
         memset( power_info, 0, sizeof_power_info );
 
-    /*TODO: report 64bit processors properly*/
-    sprintfW( idW, IntelCpuDescrW, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
-
     if (RegCreateKeyExW( HKEY_LOCAL_MACHINE, SystemW, 0, NULL, REG_OPTION_VOLATILE,
                          KEY_ALL_ACCESS, NULL, &system_key, NULL ))
     {
@@ -222,21 +328,45 @@ static void create_hardware_registry_keys(void)
 
     for (i = 0; i < NtCurrentTeb()->Peb->NumberOfProcessors; i++)
     {
-        WCHAR numW[10];
+        /* ProcessorNameStringW has a maximum size of 48 */
+        WCHAR regvalW[48];
 
-        sprintfW( numW, PercentDW, i );
-        if (!RegCreateKeyExW( cpu_key, numW, 0, NULL, REG_OPTION_VOLATILE,
+        sprintfW( regvalW, PercentDW, i );
+        if (!RegCreateKeyExW( cpu_key, regvalW, 0, NULL, REG_OPTION_VOLATILE,
                               KEY_ALL_ACCESS, NULL, &hkey, NULL ))
         {
             RegSetValueExW( hkey, FeatureSetW, 0, REG_DWORD, (BYTE *)&sci.FeatureSet, sizeof(DWORD) );
+
+            get_processor_name( regvalW );
+            set_reg_value( hkey, ProcessorNameStringW, regvalW );
+
+            get_processor_manufacturer( regvalW );
+            set_reg_value( hkey, VendorIdentifierW, regvalW );
+
+            /* fill the Identifier REG_SZ with correct data */
+            switch(sci.Architecture)
+            {
+            case PROCESSOR_ARCHITECTURE_AMD64:
+                if(strstrW(regvalW,IntelW))
+                    arch = Intel64W;
+                else
+                    arch = AMD64W;
+                break;
+            case PROCESSOR_ARCHITECTURE_IA64:  arch = Intel64W; break;
+
+            default:
+            case PROCESSOR_ARCHITECTURE_INTEL: arch = x86W; break;
+            }
+
+            sprintfW( idW, CommonCpuDescrW, arch, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
+
             set_reg_value( hkey, IdentifierW, idW );
-            /*TODO; report amd's properly*/
-            set_reg_value( hkey, ProcessorNameStringW, IntelCpuStringW );
-            set_reg_value( hkey, VendorIdentifierW, VenidIntelW );
+
             RegSetValueExW( hkey, mhzKeyW, 0, REG_DWORD, (BYTE *)&power_info[i].MaxMhz, sizeof(DWORD) );
             RegCloseKey( hkey );
         }
-        if (!RegCreateKeyExW( fpu_key, numW, 0, NULL, REG_OPTION_VOLATILE,
+        sprintfW( regvalW, PercentDW, i );
+        if (!RegCreateKeyExW( fpu_key, regvalW, 0, NULL, REG_OPTION_VOLATILE,
                               KEY_ALL_ACCESS, NULL, &hkey, NULL ))
         {
             set_reg_value( hkey, IdentifierW, idW );
-- 
1.7.10.4



Reply via email to