summarylogtreecommitdiffstats
path: root/wbemprox_query_v2.patch
blob: d58bcaa8b1a86312f24bda4d5c0d6ef971fbe59f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 13f708f..ddb8d7d 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -2927,7 +2927,7 @@ static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres )
     ReleaseDC( NULL, hdc );
     return ret;
 }
-static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
+static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC1 *desc )
 {
     static const WCHAR fmtW[] =
         {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X',
@@ -2940,14 +2940,93 @@ static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
     return ret;
 }

+/* some games like to continuously ask for the video controller
+   since dxgi is expensive, cache results for subsequent calls */
+static IDXGIFactory1 *factory = NULL;
+static IDXGIAdapter1 *adapter = NULL;
+static struct record_videocontroller *static_rec = NULL;
+
+static void cache_videocontroller(struct record_videocontroller *rec)
+{
+    if (!(static_rec = heap_alloc(sizeof(struct record_videocontroller))))
+        return;
+
+    static_rec->adapter_dactype       = heap_strdupW( rec->adapter_dactype );
+    static_rec->adapter_ram           = rec->adapter_ram;
+    static_rec->availability          = rec->availability;
+    static_rec->caption               = heap_strdupW( rec->caption );
+    static_rec->current_bitsperpixel  = rec->current_bitsperpixel;
+    static_rec->current_horizontalres = rec->current_horizontalres;
+    static_rec->current_refreshrate   = rec->current_refreshrate;
+    static_rec->current_scanmode      = rec->current_scanmode;
+    static_rec->current_verticalres   = rec->current_verticalres;
+    static_rec->description           = heap_strdupW( rec->description );
+    static_rec->device_id             = heap_strdupW( rec->device_id );
+    static_rec->driverversion         = heap_strdupW( rec->driverversion );
+    static_rec->name                  = heap_strdupW( rec->name );
+    static_rec->pnpdevice_id          = heap_strdupW( rec->pnpdevice_id );
+    static_rec->videoarchitecture     = rec->videoarchitecture;
+    static_rec->videomemorytype       = rec->videomemorytype;
+    static_rec->videoprocessor        = heap_strdupW( rec->videoprocessor );
+}
+
+static void videocontroller_from_cache(struct record_videocontroller *rec)
+{
+    rec->adapter_dactype       = heap_strdupW( static_rec->adapter_dactype );
+    rec->adapter_ram           = static_rec->adapter_ram;
+    rec->availability          = 3; /* Running or Full Power */
+    rec->caption               = heap_strdupW( static_rec->caption );
+    rec->current_bitsperpixel  = static_rec->current_bitsperpixel;
+    rec->current_horizontalres = static_rec->current_horizontalres;
+    rec->current_refreshrate   = 0; /* default refresh rate */
+    rec->current_scanmode      = 2; /* Unknown */
+    rec->current_verticalres   = static_rec->current_verticalres;
+    rec->description           = heap_strdupW( static_rec->description );
+    rec->device_id             = heap_strdupW( static_rec->device_id );
+    rec->driverversion         = heap_strdupW( static_rec->driverversion );
+    rec->name                  = heap_strdupW( static_rec->name );
+    rec->pnpdevice_id          = heap_strdupW( static_rec->pnpdevice_id );
+    rec->videoarchitecture     = 2; /* Unknown */
+    rec->videomemorytype       = 2; /* Unknown */
+    rec->videoprocessor        = heap_strdupW( static_rec->videoprocessor );
+}
+
+void free_videocontroller_cache()
+{
+    if (!static_rec)
+        return;
+
+    heap_free(static_rec->adapter_dactype);
+    heap_free(static_rec->caption);
+    heap_free(static_rec->description);
+    heap_free(static_rec->device_id);
+    heap_free(static_rec->driverversion);
+    heap_free(static_rec->name);
+    heap_free(static_rec->pnpdevice_id);
+    heap_free(static_rec->videoprocessor);
+
+    heap_free(static_rec);
+    static_rec = NULL;
+
+    if (factory)
+    {
+        IDXGIFactory1_Release( factory );
+        factory = NULL;
+    }
+
+    if (adapter)
+    {
+        IDXGIAdapter1_Release( adapter );
+        adapter = NULL;
+    }
+}
+
 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
 {
     static const WCHAR fmtW[] = {'%','u',' ','x',' ','%','u',' ','x',' ','%','I','6','4','u',' ','c','o','l','o','r','s',0};
     struct record_videocontroller *rec;
     HRESULT hr;
-    IDXGIFactory *factory = NULL;
-    IDXGIAdapter *adapter = NULL;
-    DXGI_ADAPTER_DESC desc;
+    DXGI_ADAPTER_DESC1 desc;
     UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
     const WCHAR *name = videocontroller_deviceidW;
     enum fill_status status = FILL_STATUS_UNFILTERED;
@@ -2955,14 +3034,24 @@ static enum fill_status fill_videocontroller( struct table *table, const struct

     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;

+    rec = (struct record_videocontroller *)table->data;
+    if (static_rec && factory && IDXGIFactory1_IsCurrent(factory))
+    {
+        TRACE("using cached data at %p\n", static_rec);
+        videocontroller_from_cache(rec);
+        goto done_cached;
+    }
+
+    free_videocontroller_cache();
+
     memset (&desc, 0, sizeof(desc));
-    hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
+    hr = CreateDXGIFactory1( &IID_IDXGIFactory, (void **)&factory );
     if (FAILED(hr)) goto done;

-    hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
+    hr = IDXGIFactory1_EnumAdapters1( factory, 0, &adapter );
     if (FAILED(hr)) goto done;

-    hr = IDXGIAdapter_GetDesc( adapter, &desc );
+    hr = IDXGIAdapter1_GetDesc1( adapter, &desc );
     if (SUCCEEDED(hr))
     {
         vidmem = desc.DedicatedVideoMemory;
@@ -2970,7 +3059,6 @@ static enum fill_status fill_videocontroller( struct table *table, const struct
     }

 done:
-    rec = (struct record_videocontroller *)table->data;
     rec->adapter_dactype       = videocontroller_dactypeW;
     rec->adapter_ram           = vidmem;
     rec->availability          = 3; /* Running or Full Power */
@@ -2990,14 +3078,15 @@ done:
     wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel );
     rec->videomodedescription  = heap_strdupW( mode );
     rec->videoprocessor        = heap_strdupW( name );
+    cache_videocontroller(rec);
+
+done_cached:
     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
     else row++;

     TRACE("created %u rows\n", row);
     table->num_rows = row;

-    if (adapter) IDXGIAdapter_Release( adapter );
-    if (factory) IDXGIFactory_Release( factory );
     return status;
 }