summarylogtreecommitdiffstats
path: root/wbemprox_query_v2.patch
blob: 5c55edfc4b8d0d8db27e404bcccfbccfda185c24 (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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 2ff3f50..1f97dc9 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -2824,7 +2824,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',
@@ -2837,14 +2837,92 @@ static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
     return ret;
 }
 
-static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
+/* 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 )
+{
     struct record_videocontroller *rec;
     HRESULT hr;
-    IDXGIFactory *factory = NULL;
-    IDXGIAdapter *adapter = NULL;
-    DXGI_ADAPTER_DESC desc;
+    DXGI_ADAPTER_DESC1 desc;
     UINT hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
     const WCHAR *name = videocontroller_deviceidW;
     enum fill_status status = FILL_STATUS_UNFILTERED;
@@ -2852,14 +2930,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;
@@ -2867,7 +2955,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 */
@@ -2885,14 +2972,15 @@ done:
     rec->videoarchitecture     = 2; /* Unknown */
     rec->videomemorytype       = 2; /* Unknown */
     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;
 }
 
diff --git a/dlls/wbemprox/main.c b/dlls/wbemprox/main.c
index e6ccd5c..feb489f 100644
--- a/dlls/wbemprox/main.c
+++ b/dlls/wbemprox/main.c
@@ -123,6 +123,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
             DisableThreadLibraryCalls(hinstDLL);
             init_table_list();
             break;
+        case DLL_PROCESS_DETACH:
+            free_videocontroller_cache();
+            break;
     }
 
     return TRUE;
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index ba25a02..de16fb7 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -186,6 +186,7 @@ void free_columns( struct column *, UINT ) DECLSPEC_HIDDEN;
 void free_row_values( const struct table *, UINT ) DECLSPEC_HIDDEN;
 void clear_table( struct table * ) DECLSPEC_HIDDEN;
 void free_table( struct table * ) DECLSPEC_HIDDEN;
+void free_videocontroller_cache(void) DECLSPEC_HIDDEN;
 UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN;
 HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG *, UINT * ) DECLSPEC_HIDDEN;
 HRESULT get_column_index( const struct table *, const WCHAR *, UINT * ) DECLSPEC_HIDDEN;