From f731547eed5aef1cfcddc58a4da1e714ddd47d1f Mon Sep 17 00:00:00 2001
From: Erich Hoover <ehoover@ubuntu.(none)>
Date: Sun, 14 Jun 2009 17:04:59 -0600
Subject: Report manufacturer video driver based on OS version.

---
 dlls/wined3d/directx.c    |   49 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/wined3d/wined3d_gl.h |    1 +
 2 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 05443fc..10f17fa 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1729,7 +1729,10 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad
 
     /* Return the information requested */
     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
-    strcpy(pIdentifier->Driver, This->adapters[Adapter].driver);
+    if(This->adapters[Adapter].gl_info.driver_filename)
+        strcpy(pIdentifier->Driver, This->adapters[Adapter].gl_info.driver_filename);
+    else /* Copy default description "Display" */
+        strcpy(pIdentifier->Driver, This->adapters[Adapter].driver);
     if(This->adapters[Adapter].gl_info.driver_description)
         strcpy(pIdentifier->Description, This->adapters[Adapter].gl_info.driver_description);
     else /* Copy default description "Direct3D HAL" */
@@ -4028,6 +4031,31 @@ static const struct driver_version_information driver_version_table[] = {
     /* TODO: Add information about legacy ATI hardware, Intel and other cards */
 };
 
+/* Certain applications (Fallout 3) crash if we do not report the correct manufacturer 
+ * driver filename.  These filenames are also OS version dependent.
+ *
+ * If a manufacturer is not found in this table, "Display" is reported
+ */
+struct driver_os_version {
+    DWORD major;
+    DWORD minor;
+};
+struct driver_filename_information {
+    WORD vendor;                        /* reported PCI card vendor ID  */
+    struct driver_os_version version;   /* OS version information  */
+    const char *filename;               /* Description of the card e.g. NVIDIA RIVA TNT */
+};
+
+#define OSVER_FALLBACK {0, 0}
+static const struct driver_filename_information driver_filename_table[] = {
+    {VENDOR_NVIDIA, {5, 1} /* WINXP */, "nv4_disp.dll"},
+    {VENDOR_NVIDIA, OSVER_FALLBACK,     "nv4_disp.dll"},
+    {VENDOR_ATI,    {5, 1} /* WINXP */, "atiumdag.dll"},
+    {VENDOR_ATI,    OSVER_FALLBACK,     "atiumdag.dll"},
+    {VENDOR_INTEL,  {5, 1} /* WINXP */, "igdumd32.dll"},
+    {VENDOR_INTEL,  OSVER_FALLBACK,     "igdumd32.dll"}
+};
+
 static BOOL match_ati_r300_to_500(const WineD3D_GL_Info *gl_info) {
     if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
     if(gl_info->gl_card == CARD_ATI_RADEON_9500) return TRUE;
@@ -4228,6 +4256,7 @@ struct driver_quirk quirk_table[] = {
 };
 
 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
+    OSVERSIONINFOA osvi;
     unsigned int i;
 
     for(i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); i++) {
@@ -4253,6 +4282,24 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) {
             break;
         }
     }
+
+    /* Fixup the driver filename */
+    ZeroMemory(&osvi, sizeof(OSVERSIONINFOA));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+    gl_info->driver_filename = NULL;
+    if(GetVersionExA(&osvi)) {
+        for(i = 0; i < (sizeof(driver_filename_table) / sizeof(driver_filename_table[0])); i++) {
+            if(gl_info->gl_vendor == driver_filename_table[i].vendor &&
+               ((driver_filename_table[i].version.major == osvi.dwMajorVersion &&
+                driver_filename_table[i].version.minor == osvi.dwMinorVersion) ||
+               (driver_filename_table[i].version.major == 0 &&
+                driver_filename_table[i].version.minor == 0)))
+            {
+                gl_info->driver_filename = driver_filename_table[i].filename;
+                break;
+            }
+        }
+    }
 }
 
 static void WINE_GLAPI invalid_func(const void *data)
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index aa59893..54b0c4b 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -3947,6 +3947,7 @@ typedef struct _WineD3D_GL_Info {
   UINT   vidmem;
   DWORD  driver_version;
   DWORD  driver_version_hipart;
+  const char *driver_filename;
   CHAR   driver_description[255];
   CHAR   gl_renderer[255];
   /**
-- 
1.5.4.3

