Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/programs/dxdiag/information.c
4389 views
1
/*
2
* DxDiag information collection
3
*
4
* Copyright 2011 Andrew Nguyen
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#define WIN32_LEAN_AND_MEAN
22
#include <windows.h>
23
#include <dxdiag.h>
24
25
#include "wine/debug.h"
26
#include "dxdiag_private.h"
27
28
WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);
29
30
struct property_list
31
{
32
const WCHAR *property_name;
33
WCHAR **output;
34
};
35
36
static BOOL property_to_string(IDxDiagContainer *container, const WCHAR *property, WCHAR **output)
37
{
38
VARIANT var;
39
HRESULT hr;
40
BOOL ret = FALSE;
41
42
VariantInit(&var);
43
44
hr = IDxDiagContainer_GetProp(container, property, &var);
45
if (SUCCEEDED(hr))
46
{
47
if (V_VT(&var) == VT_BSTR)
48
{
49
WCHAR *bstr = V_BSTR(&var);
50
51
*output = wcsdup(bstr);
52
ret = !!*output;
53
}
54
}
55
56
VariantClear(&var);
57
return ret;
58
}
59
60
static void free_system_information(struct dxdiag_information *dxdiag_info)
61
{
62
struct system_information *system_info = &dxdiag_info->system_info;
63
64
free(system_info->szTimeEnglish);
65
free(system_info->szTimeLocalized);
66
free(system_info->szMachineNameEnglish);
67
free(system_info->szOSExLongEnglish);
68
free(system_info->szOSExLocalized);
69
free(system_info->szLanguagesEnglish);
70
free(system_info->szLanguagesLocalized);
71
free(system_info->szSystemManufacturerEnglish);
72
free(system_info->szSystemModelEnglish);
73
free(system_info->szBIOSEnglish);
74
free(system_info->szProcessorEnglish);
75
free(system_info->szPhysicalMemoryEnglish);
76
free(system_info->szPageFileEnglish);
77
free(system_info->szPageFileLocalized);
78
free(system_info->szWindowsDir);
79
free(system_info->szDirectXVersionLongEnglish);
80
free(system_info->szSetupParamEnglish);
81
free(system_info->szDxDiagVersion);
82
}
83
84
static inline void fill_system_property_list(struct dxdiag_information *dxdiag_info, struct property_list *list)
85
{
86
struct system_information *system_info = &dxdiag_info->system_info;
87
88
list[0].property_name = L"szTimeEnglish";
89
list[0].output = &system_info->szTimeEnglish;
90
list[1].property_name = L"szTimeLocalized";
91
list[1].output = &system_info->szTimeLocalized;
92
list[2].property_name = L"szMachineNameEnglish";
93
list[2].output = &system_info->szMachineNameEnglish;
94
list[3].property_name = L"szOSExLongEnglish";
95
list[3].output = &system_info->szOSExLongEnglish;
96
list[4].property_name = L"szOSExLocalized";
97
list[4].output = &system_info->szOSExLocalized;
98
list[5].property_name = L"szLanguagesEnglish";
99
list[5].output = &system_info->szLanguagesEnglish;
100
list[6].property_name = L"szLanguagesLocalized";
101
list[6].output = &system_info->szLanguagesLocalized;
102
list[7].property_name = L"szSystemManufacturerEnglish";
103
list[7].output = &system_info->szSystemManufacturerEnglish;
104
list[8].property_name = L"szSystemModelEnglish";
105
list[8].output = &system_info->szSystemModelEnglish;
106
list[9].property_name = L"szBIOSEnglish";
107
list[9].output = &system_info->szBIOSEnglish;
108
list[10].property_name = L"szProcessorEnglish";
109
list[10].output = &system_info->szProcessorEnglish;
110
list[11].property_name = L"szPhysicalMemoryEnglish";
111
list[11].output = &system_info->szPhysicalMemoryEnglish;
112
list[12].property_name = L"szPageFileEnglish";
113
list[12].output = &system_info->szPageFileEnglish;
114
list[13].property_name = L"szPageFileLocalized";
115
list[13].output = &system_info->szPageFileLocalized;
116
list[14].property_name = L"szWindowsDir";
117
list[14].output = &system_info->szWindowsDir;
118
list[15].property_name = L"szDirectXVersionLongEnglish";
119
list[15].output = &system_info->szDirectXVersionLongEnglish;
120
list[16].property_name = L"szSetupParamEnglish";
121
list[16].output = &system_info->szSetupParamEnglish;
122
list[17].property_name = L"szDxDiagVersion";
123
list[17].output = &system_info->szDxDiagVersion;
124
}
125
126
static BOOL fill_system_information(IDxDiagContainer *container, struct dxdiag_information *dxdiag_info)
127
{
128
struct system_information *system_info = &dxdiag_info->system_info;
129
size_t i;
130
struct property_list property_list[18];
131
132
fill_system_property_list(dxdiag_info, property_list);
133
134
for (i = 0; i < ARRAY_SIZE(property_list); i++)
135
{
136
if (!property_to_string(container, property_list[i].property_name, property_list[i].output))
137
{
138
WINE_ERR("Failed to retrieve property %s\n", wine_dbgstr_w(property_list[i].property_name));
139
return FALSE;
140
}
141
}
142
143
#ifdef _WIN64
144
system_info->win64 = TRUE;
145
#else
146
system_info->win64 = FALSE;
147
#endif
148
149
return TRUE;
150
}
151
152
static const struct information_fillers
153
{
154
const WCHAR *child_container_name;
155
BOOL (*fill_function)(IDxDiagContainer *, struct dxdiag_information *);
156
void (*free_function)(struct dxdiag_information *);
157
} filler_list[] =
158
{
159
{L"DxDiag_SystemInfo", fill_system_information, free_system_information},
160
};
161
162
void free_dxdiag_information(struct dxdiag_information *system_info)
163
{
164
size_t i;
165
166
if (!system_info)
167
return;
168
169
for (i = 0; i < ARRAY_SIZE(filler_list); i++)
170
filler_list[i].free_function(system_info);
171
172
free(system_info);
173
}
174
175
struct dxdiag_information *collect_dxdiag_information(BOOL whql_check)
176
{
177
IDxDiagProvider *pddp = NULL;
178
IDxDiagContainer *root = NULL;
179
struct dxdiag_information *ret = NULL;
180
DXDIAG_INIT_PARAMS params = {sizeof(DXDIAG_INIT_PARAMS), DXDIAG_DX9_SDK_VERSION};
181
HRESULT hr;
182
size_t i;
183
184
/* Initialize the DxDiag COM instances. */
185
hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER,
186
&IID_IDxDiagProvider, (void **)&pddp);
187
if (FAILED(hr))
188
{
189
WINE_ERR("IDxDiagProvider instance creation failed with 0x%08lx\n", hr);
190
goto error;
191
}
192
193
params.bAllowWHQLChecks = whql_check;
194
hr = IDxDiagProvider_Initialize(pddp, &params);
195
if (FAILED(hr))
196
goto error;
197
198
hr = IDxDiagProvider_GetRootContainer(pddp, &root);
199
if (FAILED(hr))
200
goto error;
201
202
ret = calloc(1, sizeof(*ret));
203
if (!ret)
204
goto error;
205
206
for (i = 0; i < ARRAY_SIZE(filler_list); i++)
207
{
208
IDxDiagContainer *child;
209
BOOL success;
210
211
hr = IDxDiagContainer_GetChildContainer(root, filler_list[i].child_container_name, &child);
212
if (FAILED(hr))
213
goto error;
214
215
success = filler_list[i].fill_function(child, ret);
216
IDxDiagContainer_Release(child);
217
if (!success)
218
goto error;
219
}
220
221
IDxDiagContainer_Release(root);
222
IDxDiagProvider_Release(pddp);
223
return ret;
224
225
error:
226
free_dxdiag_information(ret);
227
if (root) IDxDiagContainer_Release(root);
228
if (pddp) IDxDiagProvider_Release(pddp);
229
return NULL;
230
}
231
232