ntoskrnl.exe: Implement NtBuildNumber.
[wine.git] / dlls / wbemprox / builtin.c
blobd2b7dc116f5f5299d0ae655d998ed59262c24167
1 /*
2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
23 #include "config.h"
24 #include <stdarg.h>
25 #include <fcntl.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #ifdef HAVE_ARPA_INET_H
30 # include <arpa/inet.h>
31 #endif
33 #include "ntstatus.h"
34 #define WIN32_NO_STATUS
35 #include "windef.h"
36 #include "winbase.h"
37 #ifdef __MINGW32__
38 # include "winsock2.h"
39 # include "ws2tcpip.h"
40 # define WS_AF_INET AF_INET
41 # define WS_AF_UNSPEC AF_UNSPEC
42 # define WS_NI_MAXHOST NI_MAXHOST
43 # define WS_NI_NAMEREQD NI_NAMEREQD
44 #else
45 # define USE_WS_PREFIX
46 # include "winsock2.h"
47 # include "ws2tcpip.h"
48 #endif
49 #include "initguid.h"
50 #include "wbemcli.h"
51 #include "wbemprov.h"
52 #include "iphlpapi.h"
53 #include "netioapi.h"
54 #include "tlhelp32.h"
55 #include "d3d10.h"
56 #include "winternl.h"
57 #include "winioctl.h"
58 #include "winsvc.h"
59 #include "winver.h"
60 #include "sddl.h"
61 #include "ntsecapi.h"
62 #include "winspool.h"
63 #include "setupapi.h"
65 #include "wine/debug.h"
66 #include "wbemprox_private.h"
68 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
70 static const WCHAR class_baseboardW[] =
71 {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0};
72 static const WCHAR class_biosW[] =
73 {'W','i','n','3','2','_','B','I','O','S',0};
74 static const WCHAR class_cdromdriveW[] =
75 {'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0};
76 static const WCHAR class_compsysW[] =
77 {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
78 static const WCHAR class_compsysproductW[] =
79 {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m','P','r','o','d','u','c','t',0};
80 static const WCHAR class_datafileW[] =
81 {'C','I','M','_','D','a','t','a','F','i','l','e',0};
82 static const WCHAR class_desktopmonitorW[] =
83 {'W','i','n','3','2','_','D','e','s','k','t','o','p','M','o','n','i','t','o','r',0};
84 static const WCHAR class_directoryW[] =
85 {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0};
86 static const WCHAR class_diskdriveW[] =
87 {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0};
88 static const WCHAR class_diskpartitionW[] =
89 {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0};
90 static const WCHAR class_ip4routetableW[] =
91 {'W','i','n','3','2','_','I','P','4','R','o','u','t','e','T','a','b','l','e',0};
92 static const WCHAR class_logicaldiskW[] =
93 {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0};
94 static const WCHAR class_logicaldisk2W[] =
95 {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0};
96 static const WCHAR class_networkadapterW[] =
97 {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0};
98 static const WCHAR class_networkadapterconfigW[] =
99 {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',
100 'C','o','n','f','i','g','u','r','a','t','i','o','n',0};
101 static const WCHAR class_osW[] =
102 {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
103 static const WCHAR class_paramsW[] =
104 {'_','_','P','A','R','A','M','E','T','E','R','S',0};
105 static const WCHAR class_physicalmediaW[] =
106 {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0};
107 static const WCHAR class_physicalmemoryW[] =
108 {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
109 static const WCHAR class_pnpentityW[] =
110 {'W','i','n','3','2','_','P','n','P','E','n','t','i','t','y',0};
111 static const WCHAR class_printerW[] =
112 {'W','i','n','3','2','_','P','r','i','n','t','e','r',0};
113 static const WCHAR class_process_getowner_outW[] =
114 {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W',
115 'N','E','R','_','O','U','T',0};
116 static const WCHAR class_processorW[] =
117 {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0};
118 static const WCHAR class_processor2W[] =
119 {'C','I','M','_','P','r','o','c','e','s','s','o','r',0};
120 static const WCHAR class_qualifiersW[] =
121 {'_','_','Q','U','A','L','I','F','I','E','R','S',0};
122 static const WCHAR class_sidW[] =
123 {'W','i','n','3','2','_','S','I','D',0};
124 static const WCHAR class_sounddeviceW[] =
125 {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0};
126 static const WCHAR class_systemenclosureW[] =
127 {'W','i','n','3','2','_','S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0};
128 static const WCHAR class_videocontrollerW[] =
129 {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0};
131 static const WCHAR prop_accountnameW[] =
132 {'A','c','c','o','u','n','t','N','a','m','e',0};
133 static const WCHAR prop_acceptpauseW[] =
134 {'A','c','c','e','p','t','P','a','u','s','e',0};
135 static const WCHAR prop_acceptstopW[] =
136 {'A','c','c','e','p','t','S','t','o','p',0};
137 static const WCHAR prop_accessmaskW[] =
138 {'A','c','c','e','s','s','M','a','s','k',0};
139 static const WCHAR prop_adapterdactypeW[] =
140 {'A','d','a','p','t','e','r','D','A','C','T','y','p','e',0};
141 static const WCHAR prop_adapterramW[] =
142 {'A','d','a','p','t','e','r','R','A','M',0};
143 static const WCHAR prop_adaptertypeW[] =
144 {'A','d','a','p','t','e','r','T','y','p','e',0};
145 static const WCHAR prop_adaptertypeidW[] =
146 {'A','d','a','p','t','e','r','T','y','p','e','I','D',0};
147 static const WCHAR prop_addresswidthW[] =
148 {'A','d','d','r','e','s','s','W','i','d','t','h',0};
149 static const WCHAR prop_architectureW[] =
150 {'A','r','c','h','i','t','e','c','t','u','r','e',0};
151 static const WCHAR prop_attributesW[] =
152 {'A','t','t','r','i','b','u','t','e','s',0};
153 static const WCHAR prop_availabilityW[] =
154 {'A','v','a','i','l','a','b','i','l','i','t','y',0};
155 static const WCHAR prop_binaryrepresentationW[] =
156 {'B','i','n','a','r','y','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
157 static const WCHAR prop_bootableW[] =
158 {'B','o','o','t','a','b','l','e',0};
159 static const WCHAR prop_bootpartitionW[] =
160 {'B','o','o','t','P','a','r','t','i','t','i','o','n',0};
161 static const WCHAR prop_buildnumberW[] =
162 {'B','u','i','l','d','N','u','m','b','e','r',0};
163 static const WCHAR prop_capacityW[] =
164 {'C','a','p','a','c','i','t','y',0};
165 static const WCHAR prop_captionW[] =
166 {'C','a','p','t','i','o','n',0};
167 static const WCHAR prop_chassistypesW[] =
168 {'C','h','a','s','s','i','s','T','y','p','e','s',0};
169 static const WCHAR prop_classW[] =
170 {'C','l','a','s','s',0};
171 static const WCHAR prop_codesetW[] =
172 {'C','o','d','e','S','e','t',0};
173 static const WCHAR prop_commandlineW[] =
174 {'C','o','m','m','a','n','d','L','i','n','e',0};
175 static const WCHAR prop_configmanagererrorcodeW[] =
176 {'C','o','n','f','i','g','M','a','n','a','g','e','r','E','r','r','o','r','C','o','d','e',0};
177 static const WCHAR prop_countrycodeW[] =
178 {'C','o','u','n','t','r','y','C','o','d','e',0};
179 static const WCHAR prop_cpustatusW[] =
180 {'C','p','u','S','t','a','t','u','s',0};
181 static const WCHAR prop_csdversionW[] =
182 {'C','S','D','V','e','r','s','i','o','n',0};
183 static const WCHAR prop_currentbitsperpixelW[] =
184 {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0};
185 static const WCHAR prop_currentclockspeedW[] =
186 {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0};
187 static const WCHAR prop_currenthorizontalresW[] =
188 {'C','u','r','r','e','n','t','H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
189 static const WCHAR prop_currentrefreshrateW[] =
190 {'C','u','r','r','e','n','t','R','e','f','r','e','s','h','R','a','t','e',0};
191 static const WCHAR prop_currentscanmodeW[] =
192 {'C','u','r','r','e','n','t','S','c','a','n','M','o','d','e',0};
193 static const WCHAR prop_currentverticalresW[] =
194 {'C','u','r','r','e','n','t','V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0};
195 static const WCHAR prop_datawidthW[] =
196 {'D','a','t','a','W','i','d','t','h',0};
197 static const WCHAR prop_defaultipgatewayW[] =
198 {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0};
199 static const WCHAR prop_defaultvalueW[] =
200 {'D','e','f','a','u','l','t','V','a','l','u','e',0};
201 static const WCHAR prop_descriptionW[] =
202 {'D','e','s','c','r','i','p','t','i','o','n',0};
203 static const WCHAR prop_destinationW[] =
204 {'D','e','s','t','i','n','a','t','i','o','n',0};
205 static const WCHAR prop_deviceidW[] =
206 {'D','e','v','i','c','e','I','d',0};
207 static const WCHAR prop_dhcpenabledW[] =
208 {'D','H','C','P','E','n','a','b','l','e','d',0};
209 static const WCHAR prop_directionW[] =
210 {'D','i','r','e','c','t','i','o','n',0};
211 static const WCHAR prop_displaynameW[] =
212 {'D','i','s','p','l','a','y','N','a','m','e',0};
213 static const WCHAR prop_diskindexW[] =
214 {'D','i','s','k','I','n','d','e','x',0};
215 static const WCHAR prop_dnshostnameW[] =
216 {'D','N','S','H','o','s','t','N','a','m','e',0};
217 static const WCHAR prop_dnsserversearchorderW[] =
218 {'D','N','S','S','e','r','v','e','r','S','e','a','r','c','h','O','r','d','e','r',0};
219 static const WCHAR prop_domainW[] =
220 {'D','o','m','a','i','n',0};
221 static const WCHAR prop_domainroleW[] =
222 {'D','o','m','a','i','n','R','o','l','e',0};
223 static const WCHAR prop_driveW[] =
224 {'D','r','i','v','e',0};
225 static const WCHAR prop_driverdateW[] =
226 {'D','r','i','v','e','r','D','a','t','e',0};
227 static const WCHAR prop_drivernameW[] =
228 {'D','r','i','v','e','r','N','a','m','e',0};
229 static const WCHAR prop_driverversionW[] =
230 {'D','r','i','v','e','r','V','e','r','s','i','o','n',0};
231 static const WCHAR prop_drivetypeW[] =
232 {'D','r','i','v','e','T','y','p','e',0};
233 static const WCHAR prop_familyW[] =
234 {'F','a','m','i','l','y',0};
235 static const WCHAR prop_filesystemW[] =
236 {'F','i','l','e','S','y','s','t','e','m',0};
237 static const WCHAR prop_flavorW[] =
238 {'F','l','a','v','o','r',0};
239 static const WCHAR prop_freespaceW[] =
240 {'F','r','e','e','S','p','a','c','e',0};
241 static const WCHAR prop_freephysicalmemoryW[] =
242 {'F','r','e','e','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
243 static const WCHAR prop_handleW[] =
244 {'H','a','n','d','l','e',0};
245 static const WCHAR prop_horizontalresolutionW[] =
246 {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
247 static const WCHAR prop_idW[] =
248 {'I','D',0};
249 static const WCHAR prop_identificationcodeW[] =
250 {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0};
251 static const WCHAR prop_identifyingnumberW[] =
252 {'I','d','e','n','t','i','f','y','i','n','g','N','u','m','b','e','r',0};
253 static const WCHAR prop_indexW[] =
254 {'I','n','d','e','x',0};
255 static const WCHAR prop_installdateW[] =
256 {'I','n','s','t','a','l','l','D','a','t','e',0};
257 static const WCHAR prop_installeddisplaydriversW[]=
258 {'I','n','s','t','a','l','l','e','d','D','i','s','p','l','a','y','D','r','i','v','e','r','s',0};
259 static const WCHAR prop_interfaceindexW[] =
260 {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0};
261 static const WCHAR prop_interfacetypeW[] =
262 {'I','n','t','e','r','f','a','c','e','T','y','p','e',0};
263 static const WCHAR prop_intvalueW[] =
264 {'I','n','t','e','g','e','r','V','a','l','u','e',0};
265 static const WCHAR prop_ipaddressW[] =
266 {'I','P','A','d','d','r','e','s','s',0};
267 static const WCHAR prop_ipconnectionmetricW[] =
268 {'I','P','C','o','n','n','e','c','t','i','o','n','M','e','t','r','i','c',0};
269 static const WCHAR prop_ipenabledW[] =
270 {'I','P','E','n','a','b','l','e','d',0};
271 static const WCHAR prop_ipsubnet[] =
272 {'I','P','S','u','b','n','e','t',0};
273 static const WCHAR prop_lastbootuptimeW[] =
274 {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0};
275 static const WCHAR prop_levelW[] =
276 {'L','e','v','e','l',0};
277 static const WCHAR prop_localW[] =
278 {'L','o','c','a','l',0};
279 static const WCHAR prop_localdatetimeW[] =
280 {'L','o','c','a','l','D','a','t','e','T','i','m','e',0};
281 static const WCHAR prop_localeW[] =
282 {'L','o','c','a','l','e',0};
283 static const WCHAR prop_locationW[] =
284 {'L','o','c','a','t','i','o','n',0};
285 static const WCHAR prop_lockpresentW[] =
286 {'L','o','c','k','P','r','e','s','e','n','t',0};
287 static const WCHAR prop_macaddressW[] =
288 {'M','A','C','A','d','d','r','e','s','s',0};
289 static const WCHAR prop_manufacturerW[] =
290 {'M','a','n','u','f','a','c','t','u','r','e','r',0};
291 static const WCHAR prop_maxclockspeedW[] =
292 {'M','a','x','C','l','o','c','k','S','p','e','e','d',0};
293 static const WCHAR prop_mediatypeW[] =
294 {'M','e','d','i','a','T','y','p','e',0};
295 static const WCHAR prop_memberW[] =
296 {'M','e','m','b','e','r',0};
297 static const WCHAR prop_memorytypeW[] =
298 {'M','e','m','o','r','y','T','y','p','e',0};
299 static const WCHAR prop_methodW[] =
300 {'M','e','t','h','o','d',0};
301 static const WCHAR prop_modelW[] =
302 {'M','o','d','e','l',0};
303 static const WCHAR prop_netconnectionstatusW[] =
304 {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0};
305 static const WCHAR prop_networkW[] =
306 {'N','e','t','w','o','r','k',0};
307 static const WCHAR prop_nexthopW[] =
308 {'N','e','x','t','H','o','p',0};
309 static const WCHAR prop_numcoresW[] =
310 {'N','u','m','b','e','r','O','f','C','o','r','e','s',0};
311 static const WCHAR prop_numlogicalprocessorsW[] =
312 {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
313 static const WCHAR prop_numprocessorsW[] =
314 {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
315 static const WCHAR prop_osarchitectureW[] =
316 {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0};
317 static const WCHAR prop_oslanguageW[] =
318 {'O','S','L','a','n','g','u','a','g','e',0};
319 static const WCHAR prop_osproductsuiteW[] =
320 {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0};
321 static const WCHAR prop_ostypeW[] =
322 {'O','S','T','y','p','e',0};
323 static const WCHAR prop_parameterW[] =
324 {'P','a','r','a','m','e','t','e','r',0};
325 static const WCHAR prop_physicaladapterW[] =
326 {'P','h','y','s','i','c','a','l','A','d','a','p','t','e','r',0};
327 static const WCHAR prop_pixelsperxlogicalinchW[] =
328 {'P','i','x','e','l','s','P','e','r','X','L','o','g','i','c','a','l','I','n','c','h',0};
329 static const WCHAR prop_pnpdeviceidW[] =
330 {'P','N','P','D','e','v','i','c','e','I','D',0};
331 static const WCHAR prop_portnameW[] =
332 {'P','o','r','t','N','a','m','e',0};
333 static const WCHAR prop_pprocessidW[] =
334 {'P','a','r','e','n','t','P','r','o','c','e','s','s','I','D',0};
335 static const WCHAR prop_primaryW[] =
336 {'P','r','i','m','a','r','y',0};
337 static const WCHAR prop_processidW[] =
338 {'P','r','o','c','e','s','s','I','D',0};
339 static const WCHAR prop_processoridW[] =
340 {'P','r','o','c','e','s','s','o','r','I','d',0};
341 static const WCHAR prop_processortypeW[] =
342 {'P','r','o','c','e','s','s','o','r','T','y','p','e',0};
343 static const WCHAR prop_productW[] =
344 {'P','r','o','d','u','c','t',0};
345 static const WCHAR prop_productnameW[] =
346 {'P','r','o','d','u','c','t','N','a','m','e',0};
347 static const WCHAR prop_referenceddomainnameW[] =
348 {'R','e','f','e','r','e','n','c','e','d','D','o','m','a','i','n','N','a','m','e',0};
349 static const WCHAR prop_releasedateW[] =
350 {'R','e','l','e','a','s','e','D','a','t','e',0};
351 static const WCHAR prop_revisionW[] =
352 {'R','e','v','i','s','i','o','n',0};
353 static const WCHAR prop_serialnumberW[] =
354 {'S','e','r','i','a','l','N','u','m','b','e','r',0};
355 static const WCHAR prop_servicepackmajorW[] =
356 {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0};
357 static const WCHAR prop_servicepackminorW[] =
358 {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0};
359 static const WCHAR prop_servicetypeW[] =
360 {'S','e','r','v','i','c','e','T','y','p','e',0};
361 static const WCHAR prop_settingidW[] =
362 {'S','e','t','t','i','n','g','I','D',0};
363 static const WCHAR prop_skunumberW[] =
364 {'S','K','U','N','u','m','b','e','r',0};
365 static const WCHAR prop_smbiosbiosversionW[] =
366 {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0};
367 static const WCHAR prop_smbiosmajorversionW[] =
368 {'S','M','B','I','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0};
369 static const WCHAR prop_smbiosminorversionW[] =
370 {'S','M','B','I','O','S','M','i','n','o','r','V','e','r','s','i','o','n',0};
371 static const WCHAR prop_startmodeW[] =
372 {'S','t','a','r','t','M','o','d','e',0};
373 static const WCHAR prop_sidW[] =
374 {'S','I','D',0};
375 static const WCHAR prop_sidlengthW[] =
376 {'S','i','d','L','e','n','g','t','h',0};
377 static const WCHAR prop_sizeW[] =
378 {'S','i','z','e',0};
379 static const WCHAR prop_speedW[] =
380 {'S','p','e','e','d',0};
381 static const WCHAR prop_startingoffsetW[] =
382 {'S','t','a','r','t','i','n','g','O','f','f','s','e','t',0};
383 static const WCHAR prop_stateW[] =
384 {'S','t','a','t','e',0};
385 static const WCHAR prop_statusW[] =
386 {'S','t','a','t','u','s',0};
387 static const WCHAR prop_statusinfoW[] =
388 {'S','t','a','t','u','s','I','n','f','o',0};
389 static const WCHAR prop_strvalueW[] =
390 {'S','t','r','i','n','g','V','a','l','u','e',0};
391 static const WCHAR prop_suitemaskW[] =
392 {'S','u','i','t','e','M','a','s','k',0};
393 static const WCHAR prop_systemdirectoryW[] =
394 {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0};
395 static const WCHAR prop_systemnameW[] =
396 {'S','y','s','t','e','m','N','a','m','e',0};
397 static const WCHAR prop_tagW[] =
398 {'T','a','g',0};
399 static const WCHAR prop_threadcountW[] =
400 {'T','h','r','e','a','d','C','o','u','n','t',0};
401 static const WCHAR prop_totalphysicalmemoryW[] =
402 {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
403 static const WCHAR prop_totalvirtualmemorysizeW[] =
404 {'T','o','t','a','l','V','i','r','t','u','a','l','M','e','m','o','r','y','S','i','z','e',0};
405 static const WCHAR prop_totalvisiblememorysizeW[] =
406 {'T','o','t','a','l','V','i','s','i','b','l','e','M','e','m','o','r','y','S','i','z','e',0};
407 static const WCHAR prop_typeW[] =
408 {'T','y','p','e',0};
409 static const WCHAR prop_uniqueidW[] =
410 {'U','n','i','q','u','e','I','d',0};
411 static const WCHAR prop_usernameW[] =
412 {'U','s','e','r','N','a','m','e',0};
413 static const WCHAR prop_uuidW[] =
414 {'U','U','I','D',0};
415 static const WCHAR prop_varianttypeW[] =
416 {'V','a','r','i','a','n','t','T','y','p','e',0};
417 static const WCHAR prop_vendorW[] =
418 {'V','e','n','d','o','r',0};
419 static const WCHAR prop_versionW[] =
420 {'V','e','r','s','i','o','n',0};
421 static const WCHAR prop_videoarchitectureW[] =
422 {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0};
423 static const WCHAR prop_videomemorytypeW[] =
424 {'V','i','d','e','o','M','e','m','o','r','y','T','y','p','e',0};
425 static const WCHAR prop_videomodedescriptionW[] =
426 {'V','i','d','e','o','M','o','d','e','D','e','s','c','r','i','p','t','i','o','n',0};
427 static const WCHAR prop_videoprocessorW[] =
428 {'V','i','d','e','o','P','r','o','c','e','s','s','o','r',0};
429 static const WCHAR prop_volumenameW[] =
430 {'V','o','l','u','m','e','N','a','m','e',0};
431 static const WCHAR prop_volumeserialnumberW[] =
432 {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0};
433 static const WCHAR prop_workingsetsizeW[] =
434 {'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0};
436 /* column definitions must be kept in sync with record structures below */
437 static const struct column col_baseboard[] =
439 { prop_manufacturerW, CIM_STRING },
440 { prop_modelW, CIM_STRING },
441 { prop_nameW, CIM_STRING },
442 { prop_productW, CIM_STRING },
443 { prop_serialnumberW, CIM_STRING },
444 { prop_tagW, CIM_STRING|COL_FLAG_KEY },
445 { prop_versionW, CIM_STRING }
447 static const struct column col_bios[] =
449 { prop_descriptionW, CIM_STRING },
450 { prop_identificationcodeW, CIM_STRING },
451 { prop_manufacturerW, CIM_STRING },
452 { prop_nameW, CIM_STRING },
453 { prop_releasedateW, CIM_DATETIME },
454 { prop_serialnumberW, CIM_STRING },
455 { prop_smbiosbiosversionW, CIM_STRING },
456 { prop_smbiosmajorversionW, CIM_UINT16, VT_I4 },
457 { prop_smbiosminorversionW, CIM_UINT16, VT_I4 },
458 { prop_versionW, CIM_STRING|COL_FLAG_KEY }
460 static const struct column col_cdromdrive[] =
462 { prop_deviceidW, CIM_STRING|COL_FLAG_KEY },
463 { prop_driveW, CIM_STRING|COL_FLAG_DYNAMIC },
464 { prop_mediatypeW, CIM_STRING },
465 { prop_nameW, CIM_STRING },
466 { prop_pnpdeviceidW, CIM_STRING }
468 static const struct column col_compsys[] =
470 { prop_descriptionW, CIM_STRING },
471 { prop_domainW, CIM_STRING },
472 { prop_domainroleW, CIM_UINT16, VT_I4 },
473 { prop_manufacturerW, CIM_STRING },
474 { prop_modelW, CIM_STRING },
475 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
476 { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
477 { prop_numprocessorsW, CIM_UINT32, VT_I4 },
478 { prop_totalphysicalmemoryW, CIM_UINT64 },
479 { prop_usernameW, CIM_STRING|COL_FLAG_DYNAMIC }
481 static const struct column col_compsysproduct[] =
483 { prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY },
484 { prop_nameW, CIM_STRING|COL_FLAG_KEY },
485 { prop_skunumberW, CIM_STRING },
486 { prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC },
487 { prop_vendorW, CIM_STRING },
488 { prop_versionW, CIM_STRING|COL_FLAG_KEY }
490 static const struct column col_datafile[] =
492 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
493 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
495 static const struct column col_desktopmonitor[] =
497 { prop_pixelsperxlogicalinchW, CIM_UINT32 }
499 static const struct column col_directory[] =
501 { prop_accessmaskW, CIM_UINT32 },
502 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
504 static const struct column col_diskdrive[] =
506 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
507 { prop_indexW, CIM_UINT32, VT_I4 },
508 { prop_interfacetypeW, CIM_STRING },
509 { prop_manufacturerW, CIM_STRING },
510 { prop_mediatypeW, CIM_STRING },
511 { prop_modelW, CIM_STRING },
512 { prop_pnpdeviceidW, CIM_STRING },
513 { prop_serialnumberW, CIM_STRING },
514 { prop_sizeW, CIM_UINT64 }
516 static const struct column col_diskpartition[] =
518 { prop_bootableW, CIM_BOOLEAN },
519 { prop_bootpartitionW, CIM_BOOLEAN },
520 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
521 { prop_diskindexW, CIM_UINT32, VT_I4 },
522 { prop_indexW, CIM_UINT32, VT_I4 },
523 { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC },
524 { prop_sizeW, CIM_UINT64 },
525 { prop_startingoffsetW, CIM_UINT64 },
526 { prop_typeW, CIM_STRING|COL_FLAG_DYNAMIC }
528 static const struct column col_ip4routetable[] =
530 { prop_destinationW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
531 { prop_interfaceindexW, CIM_SINT32|COL_FLAG_KEY },
532 { prop_nexthopW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
534 static const struct column col_logicaldisk[] =
536 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
537 { prop_drivetypeW, CIM_UINT32, VT_I4 },
538 { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC },
539 { prop_freespaceW, CIM_UINT64 },
540 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
541 { prop_sizeW, CIM_UINT64 },
542 { prop_volumenameW, CIM_STRING|COL_FLAG_DYNAMIC },
543 { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC }
545 static const struct column col_networkadapter[] =
547 { prop_adaptertypeW, CIM_STRING },
548 { prop_adaptertypeidW, CIM_UINT16, VT_I4 },
549 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
550 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
551 { prop_indexW, CIM_UINT32, VT_I4 },
552 { prop_interfaceindexW, CIM_UINT32, VT_I4 },
553 { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC },
554 { prop_manufacturerW, CIM_STRING },
555 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
556 { prop_netconnectionstatusW, CIM_UINT16, VT_I4 },
557 { prop_physicaladapterW, CIM_BOOLEAN },
558 { prop_pnpdeviceidW, CIM_STRING },
559 { prop_speedW, CIM_UINT64 }
561 static const struct column col_networkadapterconfig[] =
563 { prop_defaultipgatewayW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
564 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
565 { prop_dhcpenabledW, CIM_BOOLEAN },
566 { prop_dnshostnameW, CIM_STRING|COL_FLAG_DYNAMIC },
567 { prop_dnsserversearchorderW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
568 { prop_indexW, CIM_UINT32|COL_FLAG_KEY, VT_I4 },
569 { prop_ipaddressW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
570 { prop_ipconnectionmetricW, CIM_UINT32, VT_I4 },
571 { prop_ipenabledW, CIM_BOOLEAN },
572 { prop_ipsubnet, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
573 { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC },
574 { prop_settingidW, CIM_STRING|COL_FLAG_DYNAMIC }
576 static const struct column col_os[] =
578 { prop_buildnumberW, CIM_STRING|COL_FLAG_DYNAMIC },
579 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
580 { prop_codesetW, CIM_STRING|COL_FLAG_DYNAMIC },
581 { prop_countrycodeW, CIM_STRING|COL_FLAG_DYNAMIC },
582 { prop_csdversionW, CIM_STRING|COL_FLAG_DYNAMIC },
583 { prop_freephysicalmemoryW, CIM_UINT64 },
584 { prop_installdateW, CIM_DATETIME },
585 { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC },
586 { prop_localdatetimeW, CIM_DATETIME|COL_FLAG_DYNAMIC },
587 { prop_localeW, CIM_STRING|COL_FLAG_DYNAMIC },
588 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
589 { prop_osarchitectureW, CIM_STRING },
590 { prop_oslanguageW, CIM_UINT32, VT_I4 },
591 { prop_osproductsuiteW, CIM_UINT32, VT_I4 },
592 { prop_ostypeW, CIM_UINT16, VT_I4 },
593 { prop_primaryW, CIM_BOOLEAN },
594 { prop_serialnumberW, CIM_STRING },
595 { prop_servicepackmajorW, CIM_UINT16, VT_I4 },
596 { prop_servicepackminorW, CIM_UINT16, VT_I4 },
597 { prop_suitemaskW, CIM_UINT32, VT_I4 },
598 { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC },
599 { prop_totalvirtualmemorysizeW, CIM_UINT64 },
600 { prop_totalvisiblememorysizeW, CIM_UINT64 },
601 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
603 static const struct column col_param[] =
605 { prop_classW, CIM_STRING },
606 { prop_methodW, CIM_STRING },
607 { prop_directionW, CIM_SINT32 },
608 { prop_parameterW, CIM_STRING },
609 { prop_typeW, CIM_UINT32 },
610 { prop_varianttypeW, CIM_UINT32 },
611 { prop_defaultvalueW, CIM_UINT32 }
613 static const struct column col_physicalmedia[] =
615 { prop_serialnumberW, CIM_STRING },
616 { prop_tagW, CIM_STRING }
618 static const struct column col_physicalmemory[] =
620 { prop_capacityW, CIM_UINT64 },
621 { prop_memorytypeW, CIM_UINT16, VT_I4 }
623 static const struct column col_pnpentity[] =
625 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC },
627 static const struct column col_printer[] =
629 { prop_attributesW, CIM_UINT32 },
630 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
631 { prop_drivernameW, CIM_STRING|COL_FLAG_DYNAMIC },
632 { prop_horizontalresolutionW, CIM_UINT32 },
633 { prop_localW, CIM_BOOLEAN },
634 { prop_locationW, CIM_STRING|COL_FLAG_DYNAMIC },
635 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
636 { prop_networkW, CIM_BOOLEAN },
637 { prop_portnameW, CIM_STRING|COL_FLAG_DYNAMIC },
639 static const struct column col_process[] =
641 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
642 { prop_commandlineW, CIM_STRING|COL_FLAG_DYNAMIC },
643 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
644 { prop_handleW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
645 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
646 { prop_pprocessidW, CIM_UINT32, VT_I4 },
647 { prop_processidW, CIM_UINT32, VT_I4 },
648 { prop_threadcountW, CIM_UINT32, VT_I4 },
649 { prop_workingsetsizeW, CIM_UINT64 },
650 /* methods */
651 { method_getownerW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
653 static const struct column col_processor[] =
655 { prop_addresswidthW, CIM_UINT16, VT_I4 },
656 { prop_architectureW, CIM_UINT16, VT_I4 },
657 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
658 { prop_cpustatusW, CIM_UINT16 },
659 { prop_currentclockspeedW, CIM_UINT32, VT_I4 },
660 { prop_datawidthW, CIM_UINT16, VT_I4 },
661 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
662 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
663 { prop_familyW, CIM_UINT16, VT_I4 },
664 { prop_levelW, CIM_UINT16, VT_I4 },
665 { prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
666 { prop_maxclockspeedW, CIM_UINT32, VT_I4 },
667 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
668 { prop_numcoresW, CIM_UINT32, VT_I4 },
669 { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
670 { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC },
671 { prop_processortypeW, CIM_UINT16, VT_I4 },
672 { prop_revisionW, CIM_UINT16, VT_I4 },
673 { prop_uniqueidW, CIM_STRING },
674 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
676 static const struct column col_qualifier[] =
678 { prop_classW, CIM_STRING },
679 { prop_memberW, CIM_STRING },
680 { prop_typeW, CIM_UINT32 },
681 { prop_flavorW, CIM_SINT32 },
682 { prop_nameW, CIM_STRING },
683 { prop_intvalueW, CIM_SINT32 },
684 { prop_strvalueW, CIM_STRING }
686 static const struct column col_service[] =
688 { prop_acceptpauseW, CIM_BOOLEAN },
689 { prop_acceptstopW, CIM_BOOLEAN },
690 { prop_displaynameW, CIM_STRING|COL_FLAG_DYNAMIC },
691 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
692 { prop_processidW, CIM_UINT32 },
693 { prop_servicetypeW, CIM_STRING },
694 { prop_startmodeW, CIM_STRING },
695 { prop_stateW, CIM_STRING },
696 { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC },
697 /* methods */
698 { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
699 { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
700 { method_startserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
701 { method_stopserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
703 static const struct column col_sid[] =
705 { prop_accountnameW, CIM_STRING|COL_FLAG_DYNAMIC },
706 { prop_binaryrepresentationW, CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
707 { prop_referenceddomainnameW, CIM_STRING|COL_FLAG_DYNAMIC },
708 { prop_sidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
709 { prop_sidlengthW, CIM_UINT32 }
711 static const struct column col_sounddevice[] =
713 { prop_nameW, CIM_STRING },
714 { prop_productnameW, CIM_STRING },
715 { prop_statusinfoW, CIM_UINT16, VT_I4 }
717 static const struct column col_stdregprov[] =
719 { method_createkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
720 { method_enumkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
721 { method_enumvaluesW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
722 { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
724 static const struct column col_systemenclosure[] =
726 { prop_captionW, CIM_STRING },
727 { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY },
728 { prop_descriptionW, CIM_STRING },
729 { prop_lockpresentW, CIM_BOOLEAN },
730 { prop_manufacturerW, CIM_STRING },
731 { prop_nameW, CIM_STRING },
732 { prop_tagW, CIM_STRING },
734 static const struct column col_systemsecurity[] =
736 { method_getsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
737 { method_setsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
739 static const struct column col_videocontroller[] =
741 { prop_adapterdactypeW, CIM_STRING },
742 { prop_adapterramW, CIM_UINT32, VT_I4 },
743 { prop_availabilityW, CIM_UINT16 },
744 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
745 { prop_configmanagererrorcodeW, CIM_UINT32, VT_I4 },
746 { prop_currentbitsperpixelW, CIM_UINT32, VT_I4 },
747 { prop_currenthorizontalresW, CIM_UINT32, VT_I4 },
748 { prop_currentrefreshrateW, CIM_UINT32, VT_I4 },
749 { prop_currentscanmodeW, CIM_UINT16, VT_I4 },
750 { prop_currentverticalresW, CIM_UINT32, VT_I4 },
751 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
752 { prop_deviceidW, CIM_STRING|COL_FLAG_KEY },
753 { prop_driverdateW, CIM_DATETIME },
754 { prop_driverversionW, CIM_STRING },
755 { prop_installeddisplaydriversW,CIM_STRING },
756 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
757 { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC },
758 { prop_statusW, CIM_STRING },
759 { prop_videoarchitectureW, CIM_UINT16, VT_I4 },
760 { prop_videomemorytypeW, CIM_UINT16, VT_I4 },
761 { prop_videomodedescriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
762 { prop_videoprocessorW, CIM_STRING|COL_FLAG_DYNAMIC },
765 static const WCHAR baseboard_manufacturerW[] =
766 {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0};
767 static const WCHAR baseboard_serialnumberW[] =
768 {'N','o','n','e',0};
769 static const WCHAR baseboard_tagW[] =
770 {'B','a','s','e',' ','B','o','a','r','d',0};
771 static const WCHAR baseboard_versionW[] =
772 {'1','.','0',0};
773 static const WCHAR bios_descriptionW[] =
774 {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0};
775 static const WCHAR bios_manufacturerW[] =
776 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
777 static const WCHAR bios_nameW[] =
778 {'W','I','N','E',' ','B','I','O','S',0};
779 static const WCHAR bios_releasedateW[] =
780 {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
781 static const WCHAR bios_serialnumberW[] =
782 {'0',0};
783 static const WCHAR bios_smbiosbiosversionW[] =
784 {'W','i','n','e',0};
785 static const WCHAR bios_versionW[] =
786 {'W','I','N','E',' ',' ',' ','-',' ','1',0};
787 static const WCHAR cdromdrive_mediatypeW[] =
788 {'C','D','-','R','O','M',0};
789 static const WCHAR cdromdrive_nameW[] =
790 {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0};
791 static const WCHAR cdromdrive_pnpdeviceidW[]=
792 {'I','D','E','\\','C','D','R','O','M','W','I','N','E','_','C','D','-','R','O','M',
793 '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_',
794 '_','_','_','_','_','_','_','1','.','0','_','_','_','_','_','\\','5','&','3','A','2',
795 'A','5','8','5','4','&','0','&','1','.','0','.','0',0};
796 static const WCHAR compsys_descriptionW[] =
797 {'A','T','/','A','T',' ','C','O','M','P','A','T','I','B','L','E',0};
798 static const WCHAR compsys_domainW[] =
799 {'W','O','R','K','G','R','O','U','P',0};
800 static const WCHAR compsys_manufacturerW[] =
801 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
802 static const WCHAR compsys_modelW[] =
803 {'W','i','n','e',0};
804 static const WCHAR compsysproduct_identifyingnumberW[] =
805 {'0',0};
806 static const WCHAR compsysproduct_nameW[] =
807 {'W','i','n','e',0};
808 static const WCHAR compsysproduct_uuidW[] =
809 {'d','e','a','d','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-',
810 'd','e','a','d','d','e','a','d','d','e','a','d',0};
811 static const WCHAR compsysproduct_vendorW[] =
812 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
813 static const WCHAR compsysproduct_versionW[] =
814 {'1','.','0',0};
815 static const WCHAR diskdrive_interfacetypeW[] =
816 {'I','D','E',0};
817 static const WCHAR diskdrive_manufacturerW[] =
818 {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0};
819 static const WCHAR diskdrive_mediatype_fixedW[] =
820 {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0};
821 static const WCHAR diskdrive_mediatype_removableW[] =
822 {'R','e','m','o','v','a','b','l','e',' ','m','e','d','i','a',0};
823 static const WCHAR diskdrive_modelW[] =
824 {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0};
825 static const WCHAR diskdrive_pnpdeviceidW[] =
826 {'I','D','E','\\','D','i','s','k','\\','V','E','N','_','W','I','N','E',0};
827 static const WCHAR diskdrive_serialW[] =
828 {'W','I','N','E','H','D','I','S','K',0};
829 static const WCHAR networkadapter_pnpdeviceidW[]=
830 {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&',
831 'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\',
832 '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0};
833 static const WCHAR os_32bitW[] =
834 {'3','2','-','b','i','t',0};
835 static const WCHAR os_64bitW[] =
836 {'6','4','-','b','i','t',0};
837 static const WCHAR os_installdateW[] =
838 {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
839 static const WCHAR os_serialnumberW[] =
840 {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0};
841 static const WCHAR physicalmedia_tagW[] =
842 {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0};
843 static const WCHAR sounddevice_productnameW[] =
844 {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
845 static const WCHAR systemenclosure_systemenclosureW[] =
846 {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',0};
847 static const WCHAR systemenclosure_tagW[] =
848 {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',' ','0',0};
849 static const WCHAR systemenclosure_manufacturerW[] =
850 {'W','i','n','e',0};
851 static const WCHAR videocontroller_dactypeW[] =
852 {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0};
853 static const WCHAR videocontroller_deviceidW[] =
854 {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0};
855 static const WCHAR videocontroller_driverdateW[] =
856 {'2','0','1','7','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
857 static const WCHAR videocontroller_driverversionW[] =
858 {'1','.','0',0};
859 static const WCHAR videocontroller_statusW[] =
860 {'O','K',0};
862 #include "pshpack1.h"
863 struct record_baseboard
865 const WCHAR *manufacturer;
866 const WCHAR *model;
867 const WCHAR *name;
868 const WCHAR *product;
869 const WCHAR *serialnumber;
870 const WCHAR *tag;
871 const WCHAR *version;
873 struct record_bios
875 const WCHAR *description;
876 const WCHAR *identificationcode;
877 const WCHAR *manufacturer;
878 const WCHAR *name;
879 const WCHAR *releasedate;
880 const WCHAR *serialnumber;
881 const WCHAR *smbiosbiosversion;
882 UINT16 smbiosmajorversion;
883 UINT16 smbiosminorversion;
884 const WCHAR *version;
886 struct record_cdromdrive
888 const WCHAR *device_id;
889 const WCHAR *drive;
890 const WCHAR *mediatype;
891 const WCHAR *name;
892 const WCHAR *pnpdevice_id;
894 struct record_computersystem
896 const WCHAR *description;
897 const WCHAR *domain;
898 UINT16 domainrole;
899 const WCHAR *manufacturer;
900 const WCHAR *model;
901 const WCHAR *name;
902 UINT32 num_logical_processors;
903 UINT32 num_processors;
904 UINT64 total_physical_memory;
905 const WCHAR *username;
907 struct record_computersystemproduct
909 const WCHAR *identifyingnumber;
910 const WCHAR *name;
911 const WCHAR *skunumber;
912 const WCHAR *uuid;
913 const WCHAR *vendor;
914 const WCHAR *version;
916 struct record_datafile
918 const WCHAR *name;
919 const WCHAR *version;
921 struct record_desktopmonitor
923 UINT32 pixelsperxlogicalinch;
925 struct record_directory
927 UINT32 accessmask;
928 const WCHAR *name;
930 struct record_diskdrive
932 const WCHAR *device_id;
933 UINT32 index;
934 const WCHAR *interfacetype;
935 const WCHAR *manufacturer;
936 const WCHAR *mediatype;
937 const WCHAR *model;
938 const WCHAR *pnpdevice_id;
939 const WCHAR *serialnumber;
940 UINT64 size;
942 struct record_diskpartition
944 int bootable;
945 int bootpartition;
946 const WCHAR *device_id;
947 UINT32 diskindex;
948 UINT32 index;
949 const WCHAR *pnpdevice_id;
950 UINT64 size;
951 UINT64 startingoffset;
952 const WCHAR *type;
954 struct record_ip4routetable
956 const WCHAR *destination;
957 INT32 interfaceindex;
958 const WCHAR *nexthop;
960 struct record_logicaldisk
962 const WCHAR *device_id;
963 UINT32 drivetype;
964 const WCHAR *filesystem;
965 UINT64 freespace;
966 const WCHAR *name;
967 UINT64 size;
968 const WCHAR *volumename;
969 const WCHAR *volumeserialnumber;
971 struct record_networkadapter
973 const WCHAR *adaptertype;
974 UINT16 adaptertypeid;
975 const WCHAR *description;
976 const WCHAR *device_id;
977 UINT32 index;
978 UINT32 interface_index;
979 const WCHAR *mac_address;
980 const WCHAR *manufacturer;
981 const WCHAR *name;
982 UINT16 netconnection_status;
983 int physicaladapter;
984 const WCHAR *pnpdevice_id;
985 UINT64 speed;
987 struct record_networkadapterconfig
989 const struct array *defaultipgateway;
990 const WCHAR *description;
991 int dhcpenabled;
992 const WCHAR *dnshostname;
993 const struct array *dnsserversearchorder;
994 UINT32 index;
995 const struct array *ipaddress;
996 UINT32 ipconnectionmetric;
997 int ipenabled;
998 const struct array *ipsubnet;
999 const WCHAR *mac_address;
1000 const WCHAR *settingid;
1002 struct record_operatingsystem
1004 const WCHAR *buildnumber;
1005 const WCHAR *caption;
1006 const WCHAR *codeset;
1007 const WCHAR *countrycode;
1008 const WCHAR *csdversion;
1009 UINT64 freephysicalmemory;
1010 const WCHAR *installdate;
1011 const WCHAR *lastbootuptime;
1012 const WCHAR *localdatetime;
1013 const WCHAR *locale;
1014 const WCHAR *name;
1015 const WCHAR *osarchitecture;
1016 UINT32 oslanguage;
1017 UINT32 osproductsuite;
1018 UINT16 ostype;
1019 int primary;
1020 const WCHAR *serialnumber;
1021 UINT16 servicepackmajor;
1022 UINT16 servicepackminor;
1023 UINT32 suitemask;
1024 const WCHAR *systemdirectory;
1025 UINT64 totalvirtualmemorysize;
1026 UINT64 totalvisiblememorysize;
1027 const WCHAR *version;
1029 struct record_param
1031 const WCHAR *class;
1032 const WCHAR *method;
1033 INT32 direction;
1034 const WCHAR *parameter;
1035 UINT32 type;
1036 UINT32 varianttype;
1037 UINT32 defaultvalue;
1039 struct record_physicalmedia
1041 const WCHAR *serialnumber;
1042 const WCHAR *tag;
1044 struct record_physicalmemory
1046 UINT64 capacity;
1047 UINT16 memorytype;
1049 struct record_pnpentity
1051 const WCHAR *device_id;
1053 struct record_printer
1055 UINT32 attributes;
1056 const WCHAR *device_id;
1057 const WCHAR *drivername;
1058 UINT32 horizontalresolution;
1059 int local;
1060 const WCHAR *location;
1061 const WCHAR *name;
1062 int network;
1063 const WCHAR *portname;
1065 struct record_process
1067 const WCHAR *caption;
1068 const WCHAR *commandline;
1069 const WCHAR *description;
1070 const WCHAR *handle;
1071 const WCHAR *name;
1072 UINT32 pprocess_id;
1073 UINT32 process_id;
1074 UINT32 thread_count;
1075 UINT64 workingsetsize;
1076 /* methods */
1077 class_method *get_owner;
1079 struct record_processor
1081 UINT16 addresswidth;
1082 UINT16 architecture;
1083 const WCHAR *caption;
1084 UINT16 cpu_status;
1085 UINT32 currentclockspeed;
1086 UINT16 datawidth;
1087 const WCHAR *description;
1088 const WCHAR *device_id;
1089 UINT16 family;
1090 UINT16 level;
1091 const WCHAR *manufacturer;
1092 UINT32 maxclockspeed;
1093 const WCHAR *name;
1094 UINT32 num_cores;
1095 UINT32 num_logical_processors;
1096 const WCHAR *processor_id;
1097 UINT16 processortype;
1098 UINT16 revision;
1099 const WCHAR *unique_id;
1100 const WCHAR *version;
1102 struct record_qualifier
1104 const WCHAR *class;
1105 const WCHAR *member;
1106 UINT32 type;
1107 INT32 flavor;
1108 const WCHAR *name;
1109 INT32 intvalue;
1110 const WCHAR *strvalue;
1112 struct record_service
1114 int accept_pause;
1115 int accept_stop;
1116 const WCHAR *displayname;
1117 const WCHAR *name;
1118 UINT32 process_id;
1119 const WCHAR *servicetype;
1120 const WCHAR *startmode;
1121 const WCHAR *state;
1122 const WCHAR *systemname;
1123 /* methods */
1124 class_method *pause_service;
1125 class_method *resume_service;
1126 class_method *start_service;
1127 class_method *stop_service;
1129 struct record_sid
1131 const WCHAR *accountname;
1132 const struct array *binaryrepresentation;
1133 const WCHAR *referenceddomainname;
1134 const WCHAR *sid;
1135 UINT32 sidlength;
1137 struct record_sounddevice
1139 const WCHAR *name;
1140 const WCHAR *productname;
1141 UINT16 statusinfo;
1143 struct record_stdregprov
1145 class_method *createkey;
1146 class_method *enumkey;
1147 class_method *enumvalues;
1148 class_method *getstringvalue;
1150 struct record_systemsecurity
1152 class_method *getsd;
1153 class_method *setsd;
1155 struct record_systemenclosure
1157 const WCHAR *caption;
1158 const struct array *chassistypes;
1159 const WCHAR *description;
1160 int lockpresent;
1161 const WCHAR *manufacturer;
1162 const WCHAR *name;
1163 const WCHAR *tag;
1165 struct record_videocontroller
1167 const WCHAR *adapter_dactype;
1168 UINT32 adapter_ram;
1169 UINT16 availability;
1170 const WCHAR *caption;
1171 UINT32 config_errorcode;
1172 UINT32 current_bitsperpixel;
1173 UINT32 current_horizontalres;
1174 UINT32 current_refreshrate;
1175 UINT16 current_scanmode;
1176 UINT32 current_verticalres;
1177 const WCHAR *description;
1178 const WCHAR *device_id;
1179 const WCHAR *driverdate;
1180 const WCHAR *driverversion;
1181 const WCHAR *installeddriver;
1182 const WCHAR *name;
1183 const WCHAR *pnpdevice_id;
1184 const WCHAR *status;
1185 UINT16 videoarchitecture;
1186 UINT16 videomemorytype;
1187 const WCHAR *videomodedescription;
1188 const WCHAR *videoprocessor;
1190 #include "poppack.h"
1192 static const struct record_baseboard data_baseboard[] =
1194 { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW }
1196 static const struct record_bios data_bios[] =
1198 { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW,
1199 bios_smbiosbiosversionW, 1, 0, bios_versionW }
1201 static const struct record_param data_param[] =
1203 { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1204 { class_processW, method_getownerW, -1, param_userW, CIM_STRING },
1205 { class_processW, method_getownerW, -1, param_domainW, CIM_STRING },
1206 { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1207 { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1208 { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1209 { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1210 { class_stdregprovW, method_createkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1211 { class_stdregprovW, method_createkeyW, 1, param_subkeynameW, CIM_STRING },
1212 { class_stdregprovW, method_createkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1213 { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1214 { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING },
1215 { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1216 { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
1217 { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1218 { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING },
1219 { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1220 { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
1221 { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY },
1222 { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1223 { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING },
1224 { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING },
1225 { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1226 { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING },
1227 { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1228 { class_systemsecurityW, method_getsdW, -1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
1229 { class_systemsecurityW, method_setsdW, 1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
1230 { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1233 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1234 WBEM_FLAVOR_ORIGIN_PROPAGATED)
1236 static const struct record_physicalmedia data_physicalmedia[] =
1238 { diskdrive_serialW, physicalmedia_tagW }
1240 static const struct record_qualifier data_qualifier[] =
1242 { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 },
1243 { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 }
1245 static const struct record_sounddevice data_sounddevice[] =
1247 { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
1249 static const struct record_stdregprov data_stdregprov[] =
1251 { reg_create_key, reg_enum_key, reg_enum_values, reg_get_stringvalue }
1253 static UINT16 systemenclosure_chassistypes[] =
1257 static const struct array systemenclosure_chassistypes_array =
1259 ARRAY_SIZE(systemenclosure_chassistypes),
1260 &systemenclosure_chassistypes
1262 static const struct record_systemenclosure data_systemenclosure[] =
1265 systemenclosure_systemenclosureW,
1266 &systemenclosure_chassistypes_array,
1267 systemenclosure_systemenclosureW,
1268 FALSE,
1269 systemenclosure_manufacturerW,
1270 systemenclosure_systemenclosureW,
1271 systemenclosure_tagW,
1274 static const struct record_systemsecurity data_systemsecurity[] =
1276 { security_get_sd, security_set_sd }
1279 /* check if row matches condition and update status */
1280 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
1282 LONGLONG val;
1283 UINT type;
1285 if (!cond)
1287 *status = FILL_STATUS_UNFILTERED;
1288 return TRUE;
1290 if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1292 *status = FILL_STATUS_FAILED;
1293 return FALSE;
1295 *status = FILL_STATUS_FILTERED;
1296 return val != 0;
1299 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
1301 if (!table->num_rows_allocated)
1303 if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE;
1304 table->num_rows_allocated = row_count;
1305 return TRUE;
1307 if (row_count > table->num_rows_allocated)
1309 BYTE *data;
1310 UINT count = max( row_count, table->num_rows_allocated * 2 );
1311 if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE;
1312 table->data = data;
1313 table->num_rows_allocated = count;
1315 return TRUE;
1318 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1320 static const WCHAR fmtW[] = {'%','c',':',0};
1321 WCHAR drive[3], root[] = {'A',':','\\',0};
1322 struct record_cdromdrive *rec;
1323 UINT i, row = 0, offset = 0;
1324 DWORD drives = GetLogicalDrives();
1325 enum fill_status status = FILL_STATUS_UNFILTERED;
1327 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1329 for (i = 0; i < 26; i++)
1331 if (drives & (1 << i))
1333 root[0] = 'A' + i;
1334 if (GetDriveTypeW( root ) != DRIVE_CDROM)
1335 continue;
1337 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1339 rec = (struct record_cdromdrive *)(table->data + offset);
1340 rec->device_id = cdromdrive_pnpdeviceidW;
1341 sprintfW( drive, fmtW, 'A' + i );
1342 rec->drive = heap_strdupW( drive );
1343 rec->mediatype = cdromdrive_mediatypeW;
1344 rec->name = cdromdrive_nameW;
1345 rec->pnpdevice_id = cdromdrive_pnpdeviceidW;
1346 if (!match_row( table, row, cond, &status ))
1348 free_row_values( table, row );
1349 continue;
1351 offset += sizeof(*rec);
1352 row++;
1355 TRACE("created %u rows\n", row);
1356 table->num_rows = row;
1357 return status;
1360 static UINT get_processor_count(void)
1362 SYSTEM_BASIC_INFORMATION info;
1364 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1365 return info.NumberOfProcessors;
1368 static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
1370 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
1371 UINT core_relation_count = 0, package_relation_count = 0;
1372 NTSTATUS status;
1373 ULONG len, offset = 0;
1374 BOOL smt_enabled = FALSE;
1375 DWORD all;
1377 if (num_packages) *num_packages = 1;
1378 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
1379 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1381 if (!(buf = heap_alloc( len ))) return get_processor_count();
1382 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
1383 if (status != STATUS_SUCCESS)
1385 heap_free( buf );
1386 return get_processor_count();
1389 while (offset < len)
1391 entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
1393 if (entry->Relationship == RelationProcessorCore)
1395 core_relation_count++;
1396 if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
1398 else if (entry->Relationship == RelationProcessorPackage)
1400 package_relation_count++;
1402 offset += entry->Size;
1405 heap_free( buf );
1406 if (num_physical) *num_physical = core_relation_count;
1407 if (num_packages) *num_packages = package_relation_count;
1408 return smt_enabled ? core_relation_count * 2 : core_relation_count;
1411 static UINT64 get_total_physical_memory(void)
1413 MEMORYSTATUSEX status;
1415 status.dwLength = sizeof(status);
1416 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1417 return status.ullTotalPhys;
1420 static UINT64 get_available_physical_memory(void)
1422 MEMORYSTATUSEX status;
1424 status.dwLength = sizeof(status);
1425 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1426 return status.ullAvailPhys;
1429 static WCHAR *get_computername(void)
1431 WCHAR *ret;
1432 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1434 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1435 GetComputerNameW( ret, &size );
1436 return ret;
1439 static WCHAR *get_username(void)
1441 WCHAR *ret;
1442 DWORD compsize, usersize;
1443 DWORD size;
1445 compsize = 0;
1446 GetComputerNameW( NULL, &compsize );
1447 usersize = 0;
1448 GetUserNameW( NULL, &usersize );
1449 size = compsize + usersize; /* two null terminators account for the \ */
1450 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1451 GetComputerNameW( ret, &compsize );
1452 ret[compsize] = '\\';
1453 GetUserNameW( ret + compsize + 1, &usersize );
1454 return ret;
1457 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1459 struct record_computersystem *rec;
1460 enum fill_status status = FILL_STATUS_UNFILTERED;
1461 UINT row = 0;
1463 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1465 rec = (struct record_computersystem *)table->data;
1466 rec->description = compsys_descriptionW;
1467 rec->domain = compsys_domainW;
1468 rec->domainrole = 0; /* standalone workstation */
1469 rec->manufacturer = compsys_manufacturerW;
1470 rec->model = compsys_modelW;
1471 rec->name = get_computername();
1472 rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
1473 rec->total_physical_memory = get_total_physical_memory();
1474 rec->username = get_username();
1475 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1476 else row++;
1478 TRACE("created %u rows\n", row);
1479 table->num_rows = row;
1480 return status;
1483 static WCHAR *get_compsysproduct_uuid(void)
1485 #ifdef __APPLE__
1486 unsigned char uuid[16];
1487 const struct timespec timeout = {1, 0};
1488 if (!gethostuuid( uuid, &timeout ))
1490 static const WCHAR fmtW[] =
1491 {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
1492 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
1493 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0};
1494 WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) );
1495 if (!ret) return NULL;
1496 sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
1497 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] );
1498 return ret;
1500 #endif
1501 #ifdef __linux__
1502 int file;
1503 if ((file = open( "/var/lib/dbus/machine-id", O_RDONLY )) != -1)
1505 unsigned char buf[32];
1506 if (read( file, buf, sizeof(buf) ) == sizeof(buf))
1508 unsigned int i, j;
1509 WCHAR *ret, *p;
1511 close( file );
1512 if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL;
1513 for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] );
1514 p[8] = '-';
1515 for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] );
1516 p[13] = '-';
1517 for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] );
1518 p[18] = '-';
1519 for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] );
1520 p[23] = '-';
1521 for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] );
1522 ret[i] = 0;
1523 return ret;
1525 close( file );
1527 #endif
1528 return heap_strdupW( compsysproduct_uuidW );
1531 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1533 struct record_computersystemproduct *rec;
1534 enum fill_status status = FILL_STATUS_UNFILTERED;
1535 UINT row = 0;
1537 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1539 rec = (struct record_computersystemproduct *)table->data;
1540 rec->identifyingnumber = compsysproduct_identifyingnumberW;
1541 rec->name = compsysproduct_nameW;
1542 rec->skunumber = NULL;
1543 rec->uuid = get_compsysproduct_uuid();
1544 rec->vendor = compsysproduct_vendorW;
1545 rec->version = compsysproduct_versionW;
1546 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1547 else row++;
1549 TRACE("created %u rows\n", row);
1550 table->num_rows = row;
1551 return status;
1554 struct dirstack
1556 WCHAR **dirs;
1557 UINT *len_dirs;
1558 UINT num_dirs;
1559 UINT num_allocated;
1562 static struct dirstack *alloc_dirstack( UINT size )
1564 struct dirstack *dirstack;
1566 if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL;
1567 if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size )))
1569 heap_free( dirstack );
1570 return NULL;
1572 if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size )))
1574 heap_free( dirstack->dirs );
1575 heap_free( dirstack );
1576 return NULL;
1578 dirstack->num_dirs = 0;
1579 dirstack->num_allocated = size;
1580 return dirstack;
1583 static void clear_dirstack( struct dirstack *dirstack )
1585 UINT i;
1586 for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] );
1587 dirstack->num_dirs = 0;
1590 static void free_dirstack( struct dirstack *dirstack )
1592 clear_dirstack( dirstack );
1593 heap_free( dirstack->dirs );
1594 heap_free( dirstack->len_dirs );
1595 heap_free( dirstack );
1598 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1600 UINT size, i = dirstack->num_dirs;
1602 if (!dir) return FALSE;
1604 if (i == dirstack->num_allocated)
1606 WCHAR **tmp;
1607 UINT *len_tmp;
1609 size = dirstack->num_allocated * 2;
1610 if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1611 dirstack->dirs = tmp;
1612 if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1613 dirstack->len_dirs = len_tmp;
1614 dirstack->num_allocated = size;
1616 dirstack->dirs[i] = dir;
1617 dirstack->len_dirs[i] = len;
1618 dirstack->num_dirs++;
1619 return TRUE;
1622 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1624 if (!dirstack->num_dirs)
1626 *len = 0;
1627 return NULL;
1629 dirstack->num_dirs--;
1630 *len = dirstack->len_dirs[dirstack->num_dirs];
1631 return dirstack->dirs[dirstack->num_dirs];
1634 static const WCHAR *peek_dir( struct dirstack *dirstack )
1636 if (!dirstack->num_dirs) return NULL;
1637 return dirstack->dirs[dirstack->num_dirs - 1];
1640 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1642 UINT i = 0;
1643 WCHAR *ret;
1645 if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1646 ret[i++] = drive;
1647 ret[i++] = ':';
1648 ret[i++] = '\\';
1649 if (path && len)
1651 memcpy( ret + i, path, len * sizeof(WCHAR) );
1652 i += len;
1653 ret[i++] = '\\';
1655 ret[i++] = '*';
1656 ret[i] = 0;
1657 return ret;
1660 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1662 UINT i = 0, len = 0;
1663 const WCHAR *p;
1664 WCHAR *ret;
1666 for (p = path; *p; p++)
1668 if (*p == '\\') len += 2;
1669 else len++;
1671 if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1672 ret[i++] = drive;
1673 ret[i++] = ':';
1674 ret[i++] = '\\';
1675 ret[i++] = '\\';
1676 for (p = path; *p; p++)
1678 if (*p != '\\') ret[i++] = *p;
1679 else
1681 ret[i++] = '\\';
1682 ret[i++] = '\\';
1685 ret[i] = 0;
1686 return ret;
1689 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1691 const WCHAR *p = path, *start;
1692 UINT len, i;
1693 WCHAR *ret;
1695 if (!isalphaW( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1696 start = path + 4;
1697 len = strlenW( start );
1698 p = start + len - 1;
1699 if (*p == '\\') return NULL;
1701 while (p >= start && *p != '\\') { len--; p--; };
1702 while (p >= start && *p == '\\') { len--; p--; };
1704 if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1705 for (i = 0, p = start; p < start + len; p++)
1707 if (p[0] == '\\' && p[1] == '\\')
1709 ret[i++] = '\\';
1710 p++;
1712 else ret[i++] = *p;
1714 ret[i] = 0;
1715 *ret_len = i;
1716 return ret;
1719 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1721 UINT i;
1722 for (i = 0; i < dirstack->num_dirs; i++) if (!strcmpW( dirstack->dirs[i], path )) return TRUE;
1723 return FALSE;
1726 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1727 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1729 const struct expr *left, *right;
1731 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1733 left = cond->u.expr.left;
1734 right = cond->u.expr.right;
1735 if (cond->u.expr.op == OP_EQ)
1737 UINT len;
1738 WCHAR *path;
1739 const WCHAR *str = NULL;
1741 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1742 !strcmpW( left->u.propval->name, prop_nameW ) &&
1743 toupperW( right->u.sval[0] ) == toupperW( root ))
1745 str = right->u.sval;
1747 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1748 !strcmpW( right->u.propval->name, prop_nameW ) &&
1749 toupperW( left->u.sval[0] ) == toupperW( root ))
1751 str = left->u.sval;
1753 if (str && (path = build_dirname( str, &len )))
1755 if (seen_dir( dirstack, path ))
1757 heap_free( path );
1758 return ++*count;
1760 else if (push_dir( dirstack, path, len )) return ++*count;
1761 heap_free( path );
1762 return *count = 0;
1765 else if (cond->u.expr.op == OP_OR)
1767 UINT left_count = 0, right_count = 0;
1769 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
1770 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
1771 return *count += left_count + right_count;
1773 return *count = 0;
1776 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
1778 UINT len_path = 0, len_segment = strlenW( segment );
1779 WCHAR *ret;
1781 *len = 0;
1782 if (path) len_path = strlenW( path );
1783 if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
1784 if (path && len_path)
1786 memcpy( ret, path, len_path * sizeof(WCHAR) );
1787 ret[len_path] = '\\';
1788 *len += len_path + 1;
1790 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
1791 *len += len_segment;
1792 ret[*len] = 0;
1793 return ret;
1796 static WCHAR *get_file_version( const WCHAR *filename )
1798 static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
1799 VS_FIXEDFILEINFO *info;
1800 DWORD size;
1801 void *block;
1802 WCHAR *ret;
1804 if (!(ret = heap_alloc( (4 * 5 + ARRAY_SIZE( fmtW )) * sizeof(WCHAR) ))) return NULL;
1805 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size )))
1807 heap_free( ret );
1808 return NULL;
1810 if (!GetFileVersionInfoW( filename, 0, size, block ) ||
1811 !VerQueryValueW( block, slashW, (void **)&info, &size ))
1813 heap_free( block );
1814 heap_free( ret );
1815 return NULL;
1817 sprintfW( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
1818 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
1819 heap_free( block );
1820 return ret;
1823 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
1825 static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
1826 struct record_datafile *rec;
1827 UINT i, len, row = 0, offset = 0, num_expected_rows;
1828 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
1829 DWORD drives = GetLogicalDrives();
1830 WIN32_FIND_DATAW data;
1831 HANDLE handle;
1832 struct dirstack *dirstack;
1833 enum fill_status status = FILL_STATUS_UNFILTERED;
1835 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
1837 dirstack = alloc_dirstack(2);
1839 for (i = 0; i < 26; i++)
1841 if (!(drives & (1 << i))) continue;
1843 root[0] = 'A' + i;
1844 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1846 num_expected_rows = 0;
1847 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1849 for (;;)
1851 heap_free( glob );
1852 heap_free( path );
1853 path = pop_dir( dirstack, &len );
1854 if (!(glob = build_glob( root[0], path, len )))
1856 status = FILL_STATUS_FAILED;
1857 goto done;
1859 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1863 if (!resize_table( table, row + 1, sizeof(*rec) ))
1865 status = FILL_STATUS_FAILED;
1866 FindClose( handle );
1867 goto done;
1869 if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue;
1870 new_path = append_path( path, data.cFileName, &len );
1872 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1874 if (push_dir( dirstack, new_path, len )) continue;
1875 heap_free( new_path );
1876 FindClose( handle );
1877 status = FILL_STATUS_FAILED;
1878 goto done;
1880 rec = (struct record_datafile *)(table->data + offset);
1881 rec->name = build_name( root[0], new_path );
1882 rec->version = get_file_version( rec->name );
1883 if (!match_row( table, row, cond, &status ))
1885 free_row_values( table, row );
1886 continue;
1888 else if (num_expected_rows && row == num_expected_rows - 1)
1890 row++;
1891 FindClose( handle );
1892 status = FILL_STATUS_FILTERED;
1893 goto done;
1895 offset += sizeof(*rec);
1896 row++;
1898 while (FindNextFileW( handle, &data ));
1899 FindClose( handle );
1901 if (!peek_dir( dirstack )) break;
1905 done:
1906 free_dirstack( dirstack );
1907 heap_free( glob );
1908 heap_free( path );
1910 TRACE("created %u rows\n", row);
1911 table->num_rows = row;
1912 return status;
1915 static UINT32 get_pixelsperxlogicalinch(void)
1917 HDC hdc = GetDC( NULL );
1918 UINT32 ret;
1920 if (!hdc) return 96;
1921 ret = GetDeviceCaps( hdc, LOGPIXELSX );
1922 ReleaseDC( NULL, hdc );
1923 return ret;
1926 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
1928 struct record_desktopmonitor *rec;
1929 enum fill_status status = FILL_STATUS_UNFILTERED;
1930 UINT row = 0;
1932 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1934 rec = (struct record_desktopmonitor *)table->data;
1935 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
1937 if (match_row( table, row, cond, &status )) row++;
1939 TRACE("created %u rows\n", row);
1940 table->num_rows = row;
1941 return status;
1944 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
1946 static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
1947 struct record_directory *rec;
1948 UINT i, len, row = 0, offset = 0, num_expected_rows;
1949 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
1950 DWORD drives = GetLogicalDrives();
1951 WIN32_FIND_DATAW data;
1952 HANDLE handle;
1953 struct dirstack *dirstack;
1954 enum fill_status status = FILL_STATUS_UNFILTERED;
1956 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
1958 dirstack = alloc_dirstack(2);
1960 for (i = 0; i < 26; i++)
1962 if (!(drives & (1 << i))) continue;
1964 root[0] = 'A' + i;
1965 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1967 num_expected_rows = 0;
1968 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1970 for (;;)
1972 heap_free( glob );
1973 heap_free( path );
1974 path = pop_dir( dirstack, &len );
1975 if (!(glob = build_glob( root[0], path, len )))
1977 status = FILL_STATUS_FAILED;
1978 goto done;
1980 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1984 if (!resize_table( table, row + 1, sizeof(*rec) ))
1986 FindClose( handle );
1987 status = FILL_STATUS_FAILED;
1988 goto done;
1990 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
1991 !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW ))
1992 continue;
1994 new_path = append_path( path, data.cFileName, &len );
1995 if (!(push_dir( dirstack, new_path, len )))
1997 heap_free( new_path );
1998 FindClose( handle );
1999 status = FILL_STATUS_FAILED;
2000 goto done;
2002 rec = (struct record_directory *)(table->data + offset);
2003 rec->accessmask = FILE_ALL_ACCESS;
2004 rec->name = build_name( root[0], new_path );
2005 if (!match_row( table, row, cond, &status ))
2007 free_row_values( table, row );
2008 continue;
2010 else if (num_expected_rows && row == num_expected_rows - 1)
2012 row++;
2013 FindClose( handle );
2014 status = FILL_STATUS_FILTERED;
2015 goto done;
2017 offset += sizeof(*rec);
2018 row++;
2020 while (FindNextFileW( handle, &data ));
2021 FindClose( handle );
2023 if (!peek_dir( dirstack )) break;
2027 done:
2028 free_dirstack( dirstack );
2029 heap_free( glob );
2030 heap_free( path );
2032 TRACE("created %u rows\n", row);
2033 table->num_rows = row;
2034 return status;
2037 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
2039 WCHAR root[] = {'\\','\\','.','\\','A',':',0};
2040 ULARGE_INTEGER free;
2041 DISK_GEOMETRY_EX info;
2042 HANDLE handle;
2043 DWORD bytes_returned;
2045 free.QuadPart = 512 * 1024 * 1024;
2046 GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
2048 root[4] = dir[0];
2049 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2050 if (handle != INVALID_HANDLE_VALUE)
2052 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
2053 *disksize = info.DiskSize.QuadPart;
2054 CloseHandle( handle );
2056 return free.QuadPart;
2059 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
2061 static const WCHAR fmtW[] =
2062 {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','%','u',0};
2063 WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = {'A',':','\\',0};
2064 struct record_diskdrive *rec;
2065 UINT i, row = 0, offset = 0, index = 0, type;
2066 UINT64 size = 1024 * 1024 * 1024;
2067 DWORD drives = GetLogicalDrives();
2068 enum fill_status status = FILL_STATUS_UNFILTERED;
2070 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
2072 for (i = 0; i < 26; i++)
2074 if (drives & (1 << i))
2076 root[0] = 'A' + i;
2077 type = GetDriveTypeW( root );
2078 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2079 continue;
2081 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2083 rec = (struct record_diskdrive *)(table->data + offset);
2084 sprintfW( device_id, fmtW, index );
2085 rec->device_id = heap_strdupW( device_id );
2086 rec->index = index;
2087 rec->interfacetype = diskdrive_interfacetypeW;
2088 rec->manufacturer = diskdrive_manufacturerW;
2089 if (type == DRIVE_FIXED)
2090 rec->mediatype = diskdrive_mediatype_fixedW;
2091 else
2092 rec->mediatype = diskdrive_mediatype_removableW;
2093 rec->model = diskdrive_modelW;
2094 rec->pnpdevice_id = diskdrive_pnpdeviceidW;
2095 rec->serialnumber = diskdrive_serialW;
2096 get_freespace( root, &size );
2097 rec->size = size;
2098 if (!match_row( table, row, cond, &status ))
2100 free_row_values( table, row );
2101 continue;
2103 offset += sizeof(*rec);
2104 index++;
2105 row++;
2108 TRACE("created %u rows\n", row);
2109 table->num_rows = row;
2110 return status;
2113 static WCHAR *get_filesystem( const WCHAR *root )
2115 static const WCHAR ntfsW[] = {'N','T','F','S',0};
2116 WCHAR buffer[MAX_PATH + 1];
2118 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
2119 return heap_strdupW( buffer );
2120 return heap_strdupW( ntfsW );
2123 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2125 static const WCHAR fmtW[] =
2126 {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0};
2127 WCHAR device_id[32], root[] = {'A',':','\\',0};
2128 struct record_diskpartition *rec;
2129 UINT i, row = 0, offset = 0, type, index = 0;
2130 UINT64 size = 1024 * 1024 * 1024;
2131 DWORD drives = GetLogicalDrives();
2132 enum fill_status status = FILL_STATUS_UNFILTERED;
2134 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2136 for (i = 0; i < 26; i++)
2138 if (drives & (1 << i))
2140 root[0] = 'A' + i;
2141 type = GetDriveTypeW( root );
2142 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2143 continue;
2145 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2147 rec = (struct record_diskpartition *)(table->data + offset);
2148 rec->bootable = (i == 2) ? -1 : 0;
2149 rec->bootpartition = (i == 2) ? -1 : 0;
2150 sprintfW( device_id, fmtW, index );
2151 rec->device_id = heap_strdupW( device_id );
2152 rec->diskindex = index;
2153 rec->index = 0;
2154 rec->pnpdevice_id = heap_strdupW( device_id );
2155 get_freespace( root, &size );
2156 rec->size = size;
2157 rec->startingoffset = 0;
2158 rec->type = get_filesystem( root );
2159 if (!match_row( table, row, cond, &status ))
2161 free_row_values( table, row );
2162 continue;
2164 offset += sizeof(*rec);
2165 row++;
2166 index++;
2169 TRACE("created %u rows\n", row);
2170 table->num_rows = row;
2171 return status;
2174 static WCHAR *get_ip4_string( DWORD addr )
2176 static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
2177 WCHAR *ret;
2179 if (!(ret = heap_alloc( sizeof("ddd.ddd.ddd.ddd") * sizeof(WCHAR) ))) return NULL;
2180 sprintfW( ret, fmtW, (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2181 return ret;
2184 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2186 struct record_ip4routetable *rec;
2187 UINT i, row = 0, offset = 0, size = 0;
2188 MIB_IPFORWARDTABLE *forwards;
2189 enum fill_status status = FILL_STATUS_UNFILTERED;
2191 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2192 if (!(forwards = heap_alloc( size ))) return FILL_STATUS_FAILED;
2193 if (GetIpForwardTable( forwards, &size, TRUE ))
2195 heap_free( forwards );
2196 return FILL_STATUS_FAILED;
2198 if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) ))
2200 heap_free( forwards );
2201 return FILL_STATUS_FAILED;
2204 for (i = 0; i < forwards->dwNumEntries; i++)
2206 rec = (struct record_ip4routetable *)(table->data + offset);
2208 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2209 rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2210 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2212 if (!match_row( table, row, cond, &status ))
2214 free_row_values( table, row );
2215 continue;
2217 offset += sizeof(*rec);
2218 row++;
2220 TRACE("created %u rows\n", row);
2221 table->num_rows = row;
2223 heap_free( forwards );
2224 return status;
2227 static WCHAR *get_volumename( const WCHAR *root )
2229 WCHAR buf[MAX_PATH + 1] = {0};
2230 GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 );
2231 return heap_strdupW( buf );
2233 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2235 static const WCHAR fmtW[] = {'%','0','8','X',0};
2236 DWORD serial = 0;
2237 WCHAR buffer[9];
2239 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2240 sprintfW( buffer, fmtW, serial );
2241 return heap_strdupW( buffer );
2244 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2246 static const WCHAR fmtW[] = {'%','c',':',0};
2247 WCHAR device_id[3], root[] = {'A',':','\\',0};
2248 struct record_logicaldisk *rec;
2249 UINT i, row = 0, offset = 0, type;
2250 UINT64 size = 1024 * 1024 * 1024;
2251 DWORD drives = GetLogicalDrives();
2252 enum fill_status status = FILL_STATUS_UNFILTERED;
2254 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2256 for (i = 0; i < 26; i++)
2258 if (drives & (1 << i))
2260 root[0] = 'A' + i;
2261 type = GetDriveTypeW( root );
2262 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2263 continue;
2265 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2267 rec = (struct record_logicaldisk *)(table->data + offset);
2268 sprintfW( device_id, fmtW, 'A' + i );
2269 rec->device_id = heap_strdupW( device_id );
2270 rec->drivetype = type;
2271 rec->filesystem = get_filesystem( root );
2272 rec->freespace = get_freespace( root, &size );
2273 rec->name = heap_strdupW( device_id );
2274 rec->size = size;
2275 rec->volumename = get_volumename( root );
2276 rec->volumeserialnumber = get_volumeserialnumber( root );
2277 if (!match_row( table, row, cond, &status ))
2279 free_row_values( table, row );
2280 continue;
2282 offset += sizeof(*rec);
2283 row++;
2286 TRACE("created %u rows\n", row);
2287 table->num_rows = row;
2288 return status;
2291 static UINT16 get_connection_status( IF_OPER_STATUS status )
2293 switch (status)
2295 case IfOperStatusDown:
2296 return 0; /* Disconnected */
2297 case IfOperStatusUp:
2298 return 2; /* Connected */
2299 default:
2300 ERR("unhandled status %u\n", status);
2301 break;
2303 return 0;
2305 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2307 static const WCHAR fmtW[] =
2308 {'%','0','2','x',':','%','0','2','x',':','%','0','2','x',':',
2309 '%','0','2','x',':','%','0','2','x',':','%','0','2','x',0};
2310 WCHAR *ret;
2312 if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL;
2313 sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2314 return ret;
2316 static const WCHAR *get_adaptertype( DWORD type, int *id, int *physical )
2318 static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0};
2319 static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0};
2320 static const WCHAR firewireW[] = {'1','3','9','4',0};
2321 static const WCHAR tunnelW[] = {'T','u','n','n','e','l',0};
2323 switch (type)
2325 case IF_TYPE_ETHERNET_CSMACD:
2326 *id = 0;
2327 *physical = -1;
2328 return ethernetW;
2329 case IF_TYPE_IEEE80211:
2330 *id = 9;
2331 *physical = -1;
2332 return wirelessW;
2333 case IF_TYPE_IEEE1394:
2334 *id = 13;
2335 *physical = -1;
2336 return firewireW;
2337 case IF_TYPE_TUNNEL:
2338 *id = 15;
2339 *physical = 0;
2340 return tunnelW;
2341 default:
2342 *id = -1;
2343 *physical = 0;
2344 return NULL;
2348 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2350 static const WCHAR fmtW[] = {'%','u',0};
2351 WCHAR device_id[11];
2352 struct record_networkadapter *rec;
2353 IP_ADAPTER_ADDRESSES *aa, *buffer;
2354 UINT row = 0, offset = 0, count = 0;
2355 DWORD size = 0, ret;
2356 int adaptertypeid, physical;
2357 enum fill_status status = FILL_STATUS_UNFILTERED;
2359 ret = GetAdaptersAddresses( WS_AF_UNSPEC, 0, NULL, NULL, &size );
2360 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2362 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2363 if (GetAdaptersAddresses( WS_AF_UNSPEC, 0, NULL, buffer, &size ))
2365 heap_free( buffer );
2366 return FILL_STATUS_FAILED;
2368 for (aa = buffer; aa; aa = aa->Next)
2370 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2372 if (!resize_table( table, count, sizeof(*rec) ))
2374 heap_free( buffer );
2375 return FILL_STATUS_FAILED;
2377 for (aa = buffer; aa; aa = aa->Next)
2379 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2381 rec = (struct record_networkadapter *)(table->data + offset);
2382 sprintfW( device_id, fmtW, aa->u.s.IfIndex );
2383 rec->adaptertype = get_adaptertype( aa->IfType, &adaptertypeid, &physical );
2384 rec->adaptertypeid = adaptertypeid;
2385 rec->description = heap_strdupW( aa->Description );
2386 rec->device_id = heap_strdupW( device_id );
2387 rec->index = aa->u.s.IfIndex;
2388 rec->interface_index = aa->u.s.IfIndex;
2389 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2390 rec->manufacturer = compsys_manufacturerW;
2391 rec->name = heap_strdupW( aa->FriendlyName );
2392 rec->netconnection_status = get_connection_status( aa->OperStatus );
2393 rec->physicaladapter = physical;
2394 rec->pnpdevice_id = networkadapter_pnpdeviceidW;
2395 rec->speed = 1000000;
2396 if (!match_row( table, row, cond, &status ))
2398 free_row_values( table, row );
2399 continue;
2401 offset += sizeof(*rec);
2402 row++;
2404 TRACE("created %u rows\n", row);
2405 table->num_rows = row;
2407 heap_free( buffer );
2408 return status;
2411 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2413 const SOCKET_ADDRESS *sa = &addr->Address;
2414 WCHAR buf[WS_NI_MAXHOST];
2416 if (!addr) return NULL;
2417 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL,
2418 0, WS_NI_NAMEREQD )) return NULL;
2419 return heap_strdupW( buf );
2421 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2423 IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2424 struct array *ret;
2425 ULONG buflen, i = 0, count = 0;
2426 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2428 if (!list) return NULL;
2429 for (gateway = list; gateway; gateway = gateway->Next) count++;
2431 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2432 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2434 heap_free( ret );
2435 return NULL;
2437 for (gateway = list; gateway; gateway = gateway->Next)
2439 buflen = ARRAY_SIZE( buf );
2440 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2441 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2443 for (; i > 0; i--) heap_free( ptr[i - 1] );
2444 heap_free( ptr );
2445 heap_free( ret );
2446 return NULL;
2449 ret->count = count;
2450 ret->ptr = ptr;
2451 return ret;
2453 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2455 IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2456 struct array *ret;
2457 ULONG buflen, i = 0, count = 0;
2458 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2460 if (!list) return NULL;
2461 for (server = list; server; server = server->Next) count++;
2463 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2464 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2466 heap_free( ret );
2467 return NULL;
2469 for (server = list; server; server = server->Next)
2471 buflen = ARRAY_SIZE( buf );
2472 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2473 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2475 for (; i > 0; i--) heap_free( ptr[i - 1] );
2476 heap_free( ptr );
2477 heap_free( ret );
2478 return NULL;
2480 if ((p = strrchrW( ptr[i - 1], ':' ))) *p = 0;
2482 ret->count = count;
2483 ret->ptr = ptr;
2484 return ret;
2486 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2488 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2489 struct array *ret;
2490 ULONG buflen, i = 0, count = 0;
2491 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2493 if (!list) return NULL;
2494 for (address = list; address; address = address->Next) count++;
2496 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2497 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2499 heap_free( ret );
2500 return NULL;
2502 for (address = list; address; address = address->Next)
2504 buflen = ARRAY_SIZE( buf );
2505 if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength,
2506 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2508 for (; i > 0; i--) heap_free( ptr[i - 1] );
2509 heap_free( ptr );
2510 heap_free( ret );
2511 return NULL;
2514 ret->count = count;
2515 ret->ptr = ptr;
2516 return ret;
2518 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2520 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2521 struct array *ret;
2522 ULONG i = 0, count = 0;
2523 WCHAR **ptr;
2525 if (!list) return NULL;
2526 for (address = list; address; address = address->Next) count++;
2528 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2529 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2531 heap_free( ret );
2532 return NULL;
2534 for (address = list; address; address = address->Next)
2536 if (address->Address.lpSockaddr->sa_family == WS_AF_INET)
2538 WCHAR buf[INET_ADDRSTRLEN];
2539 SOCKADDR_IN addr;
2540 ULONG buflen = ARRAY_SIZE( buf );
2542 memset( &addr, 0, sizeof(addr) );
2543 addr.sin_family = WS_AF_INET;
2544 if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
2545 || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
2546 ptr[i] = NULL;
2547 else
2548 ptr[i] = heap_strdupW( buf );
2550 else
2552 static const WCHAR fmtW[] = {'%','u',0};
2553 WCHAR buf[11];
2555 sprintfW(buf, fmtW, address->OnLinkPrefixLength);
2556 ptr[i] = heap_strdupW( buf );
2558 if (!ptr[i++])
2560 for (; i > 0; i--) heap_free( ptr[i - 1] );
2561 heap_free( ptr );
2562 heap_free( ret );
2563 return NULL;
2566 ret->count = count;
2567 ret->ptr = ptr;
2568 return ret;
2570 static WCHAR *get_settingid( UINT32 index )
2572 GUID guid;
2573 WCHAR *ret, *str;
2574 memset( &guid, 0, sizeof(guid) );
2575 guid.Data1 = index;
2576 UuidToStringW( &guid, &str );
2577 ret = heap_strdupW( str );
2578 RpcStringFreeW( &str );
2579 return ret;
2582 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
2584 struct record_networkadapterconfig *rec;
2585 IP_ADAPTER_ADDRESSES *aa, *buffer;
2586 UINT row = 0, offset = 0, count = 0;
2587 DWORD size = 0, ret;
2588 enum fill_status status = FILL_STATUS_UNFILTERED;
2590 ret = GetAdaptersAddresses( WS_AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size );
2591 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2593 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2594 if (GetAdaptersAddresses( WS_AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size ))
2596 heap_free( buffer );
2597 return FILL_STATUS_FAILED;
2599 for (aa = buffer; aa; aa = aa->Next)
2601 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2603 if (!resize_table( table, count, sizeof(*rec) ))
2605 heap_free( buffer );
2606 return FILL_STATUS_FAILED;
2608 for (aa = buffer; aa; aa = aa->Next)
2610 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2612 rec = (struct record_networkadapterconfig *)(table->data + offset);
2613 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress );
2614 rec->description = heap_strdupW( aa->Description );
2615 rec->dhcpenabled = -1;
2616 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress );
2617 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress );
2618 rec->index = aa->u.s.IfIndex;
2619 rec->ipaddress = get_ipaddress( aa->FirstUnicastAddress );
2620 rec->ipconnectionmetric = 20;
2621 rec->ipenabled = -1;
2622 rec->ipsubnet = get_ipsubnet( aa->FirstUnicastAddress );
2623 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2624 rec->settingid = get_settingid( rec->index );
2625 if (!match_row( table, row, cond, &status ))
2627 free_row_values( table, row );
2628 continue;
2630 offset += sizeof(*rec);
2631 row++;
2633 TRACE("created %u rows\n", row);
2634 table->num_rows = row;
2636 heap_free( buffer );
2637 return status;
2640 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
2642 struct record_physicalmemory *rec;
2643 enum fill_status status = FILL_STATUS_UNFILTERED;
2644 UINT row = 0;
2646 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2648 rec = (struct record_physicalmemory *)table->data;
2649 rec->capacity = get_total_physical_memory();
2650 rec->memorytype = 9; /* RAM */
2651 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2652 else row++;
2654 TRACE("created %u rows\n", row);
2655 table->num_rows = row;
2656 return status;
2659 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond )
2661 struct record_pnpentity *rec;
2662 enum fill_status status = FILL_STATUS_UNFILTERED;
2663 HDEVINFO device_info_set;
2664 SP_DEVINFO_DATA devinfo = {0};
2665 DWORD idx;
2667 device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT );
2669 devinfo.cbSize = sizeof(devinfo);
2671 idx = 0;
2672 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
2674 /* noop */
2677 resize_table( table, idx, sizeof(*rec) );
2678 table->num_rows = 0;
2679 rec = (struct record_pnpentity *)table->data;
2681 idx = 0;
2682 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
2684 WCHAR device_id[MAX_PATH];
2685 if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
2686 ARRAY_SIZE(device_id), NULL ))
2688 rec->device_id = heap_strdupW( device_id );
2690 table->num_rows++;
2691 if (!match_row( table, table->num_rows - 1, cond, &status ))
2693 free_row_values( table, table->num_rows - 1 );
2694 table->num_rows--;
2696 else
2697 rec++;
2701 SetupDiDestroyDeviceInfoList( device_info_set );
2703 return status;
2706 static enum fill_status fill_printer( struct table *table, const struct expr *cond )
2708 static const WCHAR fmtW[] = {'P','r','i','n','t','e','r','%','d',0};
2709 struct record_printer *rec;
2710 enum fill_status status = FILL_STATUS_UNFILTERED;
2711 PRINTER_INFO_2W *info;
2712 DWORD i, offset = 0, count = 0, size = 0, num_rows = 0;
2713 WCHAR id[20];
2715 EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
2716 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2718 if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED;
2719 if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
2721 heap_free( info );
2722 return FILL_STATUS_FAILED;
2724 if (!resize_table( table, count, sizeof(*rec) ))
2726 heap_free( info );
2727 return FILL_STATUS_FAILED;
2730 for (i = 0; i < count; i++)
2732 rec = (struct record_printer *)(table->data + offset);
2733 rec->attributes = info[i].Attributes;
2734 sprintfW( id, fmtW, i );
2735 rec->device_id = heap_strdupW( id );
2736 rec->drivername = heap_strdupW( info[i].pDriverName );
2737 rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality;
2738 rec->local = -1;
2739 rec->location = heap_strdupW( info[i].pLocation );
2740 rec->name = heap_strdupW( info[i].pPrinterName );
2741 rec->network = 0;
2742 rec->portname = heap_strdupW( info[i].pPortName );
2743 if (!match_row( table, i, cond, &status ))
2745 free_row_values( table, i );
2746 continue;
2748 offset += sizeof(*rec);
2749 num_rows++;
2751 TRACE("created %u rows\n", num_rows);
2752 table->num_rows = num_rows;
2754 heap_free( info );
2755 return status;
2758 static WCHAR *get_cmdline( DWORD process_id )
2760 if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() );
2761 return NULL; /* FIXME handle different process case */
2764 static enum fill_status fill_process( struct table *table, const struct expr *cond )
2766 static const WCHAR fmtW[] = {'%','u',0};
2767 WCHAR handle[11];
2768 struct record_process *rec;
2769 PROCESSENTRY32W entry;
2770 HANDLE snap;
2771 enum fill_status status = FILL_STATUS_FAILED;
2772 UINT row = 0, offset = 0;
2774 snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
2775 if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
2777 entry.dwSize = sizeof(entry);
2778 if (!Process32FirstW( snap, &entry )) goto done;
2779 if (!resize_table( table, 8, sizeof(*rec) )) goto done;
2783 if (!resize_table( table, row + 1, sizeof(*rec) )) goto done;
2785 rec = (struct record_process *)(table->data + offset);
2786 rec->caption = heap_strdupW( entry.szExeFile );
2787 rec->commandline = get_cmdline( entry.th32ProcessID );
2788 rec->description = heap_strdupW( entry.szExeFile );
2789 sprintfW( handle, fmtW, entry.th32ProcessID );
2790 rec->handle = heap_strdupW( handle );
2791 rec->name = heap_strdupW( entry.szExeFile );
2792 rec->process_id = entry.th32ProcessID;
2793 rec->pprocess_id = entry.th32ParentProcessID;
2794 rec->thread_count = entry.cntThreads;
2795 rec->workingsetsize = 0;
2796 rec->get_owner = process_get_owner;
2797 if (!match_row( table, row, cond, &status ))
2799 free_row_values( table, row );
2800 continue;
2802 offset += sizeof(*rec);
2803 row++;
2804 } while (Process32NextW( snap, &entry ));
2806 TRACE("created %u rows\n", row);
2807 table->num_rows = row;
2808 status = FILL_STATUS_UNFILTERED;
2810 done:
2811 CloseHandle( snap );
2812 return status;
2815 extern void do_cpuid( unsigned int ax, unsigned int *p );
2816 #if defined(_MSC_VER)
2817 void do_cpuid( unsigned int ax, unsigned int *p )
2819 __cpuid( p, ax );
2821 #elif defined(__i386__)
2822 __ASM_GLOBAL_FUNC( do_cpuid,
2823 "pushl %esi\n\t"
2824 "pushl %ebx\n\t"
2825 "movl 12(%esp),%eax\n\t"
2826 "movl 16(%esp),%esi\n\t"
2827 "cpuid\n\t"
2828 "movl %eax,(%esi)\n\t"
2829 "movl %ebx,4(%esi)\n\t"
2830 "movl %ecx,8(%esi)\n\t"
2831 "movl %edx,12(%esi)\n\t"
2832 "popl %ebx\n\t"
2833 "popl %esi\n\t"
2834 "ret" )
2835 #elif defined(__x86_64__)
2836 __ASM_GLOBAL_FUNC( do_cpuid,
2837 "pushq %rbx\n\t"
2838 "movl %edi,%eax\n\t"
2839 "cpuid\n\t"
2840 "movl %eax,(%rsi)\n\t"
2841 "movl %ebx,4(%rsi)\n\t"
2842 "movl %ecx,8(%rsi)\n\t"
2843 "movl %edx,12(%rsi)\n\t"
2844 "popq %rbx\n\t"
2845 "ret" )
2846 #else
2847 void do_cpuid( unsigned int ax, unsigned int *p )
2849 FIXME("\n");
2851 #endif
2853 static unsigned int get_processor_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
2855 unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
2857 model = (reg0 & (0x0f << 4)) >> 4;
2858 if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
2859 if (family)
2861 *family = family_id;
2862 if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
2864 *stepping = reg0 & 0x0f;
2865 return model;
2867 static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
2869 unsigned int i;
2870 unsigned char *p = (unsigned char *)regs;
2872 for (i = 0; i < len; i++) { buffer[i] = *p++; }
2873 buffer[i] = 0;
2875 static void get_processor_manufacturer( WCHAR *manufacturer )
2877 unsigned int tmp, regs[4] = {0, 0, 0, 0};
2879 do_cpuid( 0, regs );
2880 tmp = regs[2]; /* swap edx and ecx */
2881 regs[2] = regs[3];
2882 regs[3] = tmp;
2884 regs_to_str( regs + 1, 12, manufacturer );
2886 static const WCHAR *get_osarchitecture(void)
2888 SYSTEM_INFO info;
2889 GetNativeSystemInfo( &info );
2890 if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW;
2891 return os_32bitW;
2893 static void get_processor_caption( WCHAR *caption )
2895 static const WCHAR fmtW[] =
2896 {'%','s',' ','F','a','m','i','l','y',' ','%','u',' ',
2897 'M','o','d','e','l',' ','%','u',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
2898 static const WCHAR x86W[] = {'x','8','6',0};
2899 static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0};
2900 static const WCHAR amd64W[] = {'A','M','D','6','4',0};
2901 static const WCHAR authenticamdW[] = {'A','u','t','h','e','n','t','i','c','A','M','D',0};
2902 const WCHAR *arch;
2903 WCHAR manufacturer[13];
2904 unsigned int regs[4] = {0, 0, 0, 0}, family, model, stepping;
2906 get_processor_manufacturer( manufacturer );
2907 if (get_osarchitecture() == os_32bitW) arch = x86W;
2908 else if (!strcmpW( manufacturer, authenticamdW )) arch = amd64W;
2909 else arch = intel64W;
2911 do_cpuid( 1, regs );
2913 model = get_processor_model( regs[0], &stepping, &family );
2914 sprintfW( caption, fmtW, arch, family, model, stepping );
2916 static void get_processor_version( WCHAR *version )
2918 static const WCHAR fmtW[] =
2919 {'M','o','d','e','l',' ','%','u',',',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
2920 unsigned int regs[4] = {0, 0, 0, 0}, model, stepping;
2922 do_cpuid( 1, regs );
2924 model = get_processor_model( regs[0], &stepping, NULL );
2925 sprintfW( version, fmtW, model, stepping );
2927 static UINT16 get_processor_revision(void)
2929 unsigned int regs[4] = {0, 0, 0, 0};
2930 do_cpuid( 1, regs );
2931 return regs[0];
2933 static void get_processor_id( WCHAR *processor_id )
2935 static const WCHAR fmtW[] = {'%','0','8','X','%','0','8','X',0};
2936 unsigned int regs[4] = {0, 0, 0, 0};
2938 do_cpuid( 1, regs );
2939 sprintfW( processor_id, fmtW, regs[3], regs[0] );
2941 static void get_processor_name( WCHAR *name )
2943 unsigned int regs[4] = {0, 0, 0, 0};
2944 int i;
2946 do_cpuid( 0x80000000, regs );
2947 if (regs[0] >= 0x80000004)
2949 do_cpuid( 0x80000002, regs );
2950 regs_to_str( regs, 16, name );
2951 do_cpuid( 0x80000003, regs );
2952 regs_to_str( regs, 16, name + 16 );
2953 do_cpuid( 0x80000004, regs );
2954 regs_to_str( regs, 16, name + 32 );
2956 for (i = strlenW(name) - 1; i >= 0 && name[i] == ' '; i--) name[i] = 0;
2958 static UINT get_processor_currentclockspeed( UINT index )
2960 PROCESSOR_POWER_INFORMATION *info;
2961 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
2962 NTSTATUS status;
2964 if ((info = heap_alloc( size )))
2966 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
2967 if (!status) ret = info[index].CurrentMhz;
2968 heap_free( info );
2970 return ret;
2972 static UINT get_processor_maxclockspeed( UINT index )
2974 PROCESSOR_POWER_INFORMATION *info;
2975 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
2976 NTSTATUS status;
2978 if ((info = heap_alloc( size )))
2980 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
2981 if (!status) ret = info[index].MaxMhz;
2982 heap_free( info );
2984 return ret;
2987 static enum fill_status fill_processor( struct table *table, const struct expr *cond )
2989 static const WCHAR fmtW[] = {'C','P','U','%','u',0};
2990 WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
2991 struct record_processor *rec;
2992 UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
2993 enum fill_status status = FILL_STATUS_UNFILTERED;
2995 num_logical = get_logical_processor_count( &num_physical, &num_packages );
2997 if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
2999 get_processor_caption( caption );
3000 get_processor_id( processor_id );
3001 get_processor_manufacturer( manufacturer );
3002 get_processor_name( name );
3003 get_processor_version( version );
3005 for (i = 0; i < num_packages; i++)
3007 rec = (struct record_processor *)(table->data + offset);
3008 rec->addresswidth = get_osarchitecture() == os_32bitW ? 32 : 64;
3009 rec->architecture = get_osarchitecture() == os_32bitW ? 0 : 9;
3010 rec->caption = heap_strdupW( caption );
3011 rec->cpu_status = 1; /* CPU Enabled */
3012 rec->currentclockspeed = get_processor_currentclockspeed( i );
3013 rec->datawidth = get_osarchitecture() == os_32bitW ? 32 : 64;
3014 rec->description = heap_strdupW( caption );
3015 sprintfW( device_id, fmtW, i );
3016 rec->device_id = heap_strdupW( device_id );
3017 rec->family = 2; /* Unknown */
3018 rec->level = 15;
3019 rec->manufacturer = heap_strdupW( manufacturer );
3020 rec->maxclockspeed = get_processor_maxclockspeed( i );
3021 rec->name = heap_strdupW( name );
3022 rec->num_cores = num_physical / num_packages;
3023 rec->num_logical_processors = num_logical / num_packages;
3024 rec->processor_id = heap_strdupW( processor_id );
3025 rec->processortype = 3; /* central processor */
3026 rec->revision = get_processor_revision();
3027 rec->unique_id = NULL;
3028 rec->version = heap_strdupW( version );
3029 if (!match_row( table, i, cond, &status ))
3031 free_row_values( table, i );
3032 continue;
3034 offset += sizeof(*rec);
3035 num_rows++;
3038 TRACE("created %u rows\n", num_rows);
3039 table->num_rows = num_rows;
3040 return status;
3043 static WCHAR *get_lastbootuptime(void)
3045 static const WCHAR fmtW[] =
3046 {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u',
3047 '.','%','0','6','u','+','0','0','0',0};
3048 SYSTEM_TIMEOFDAY_INFORMATION ti;
3049 TIME_FIELDS tf;
3050 WCHAR *ret;
3052 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3054 NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
3055 RtlTimeToTimeFields( &ti.liKeBootTime, &tf );
3056 sprintfW( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 );
3057 return ret;
3059 static WCHAR *get_localdatetime(void)
3061 static const WCHAR fmtW[] =
3062 {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u',
3063 '.','%','0','6','u','%','+','0','3','d',0};
3064 TIME_ZONE_INFORMATION tzi;
3065 SYSTEMTIME st;
3066 WCHAR *ret;
3067 DWORD Status;
3068 LONG Bias;
3070 Status = GetTimeZoneInformation(&tzi);
3072 if(Status == TIME_ZONE_ID_INVALID) return NULL;
3073 Bias = tzi.Bias;
3074 if(Status == TIME_ZONE_ID_DAYLIGHT)
3075 Bias+= tzi.DaylightBias;
3076 else
3077 Bias+= tzi.StandardBias;
3078 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3080 GetLocalTime(&st);
3081 sprintfW( ret, fmtW, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000, -Bias);
3082 return ret;
3084 static WCHAR *get_systemdirectory(void)
3086 void *redir;
3087 WCHAR *ret;
3089 if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL;
3090 Wow64DisableWow64FsRedirection( &redir );
3091 GetSystemDirectoryW( ret, MAX_PATH );
3092 Wow64RevertWow64FsRedirection( redir );
3093 return ret;
3095 static WCHAR *get_codeset(void)
3097 static const WCHAR fmtW[] = {'%','u',0};
3098 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3099 if (ret) sprintfW( ret, fmtW, GetACP() );
3100 return ret;
3102 static WCHAR *get_countrycode(void)
3104 WCHAR *ret = heap_alloc( 6 * sizeof(WCHAR) );
3105 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 );
3106 return ret;
3108 static WCHAR *get_locale(void)
3110 WCHAR *ret = heap_alloc( 5 * sizeof(WCHAR) );
3111 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 );
3112 return ret;
3114 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
3116 static const WCHAR fmtW[] = {'%','u',0};
3117 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3118 if (ret) sprintfW( ret, fmtW, ver->dwBuildNumber );
3119 return ret;
3121 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
3123 static const WCHAR windowsW[] =
3124 {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' '};
3125 static const WCHAR win2000W[] =
3126 {'2','0','0','0',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
3127 static const WCHAR win2003W[] =
3128 {'S','e','r','v','e','r',' ','2','0','0','3',' ','S','t','a','n','d','a','r','d',' ','E','d','i','t','i','o','n',0};
3129 static const WCHAR winxpW[] =
3130 {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
3131 static const WCHAR winxp64W[] =
3132 {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',' ','x','6','4',' ','E','d','i','t','i','o','n',0};
3133 static const WCHAR vistaW[] =
3134 {'V','i','s','t','a',' ','U','l','t','i','m','a','t','e',0};
3135 static const WCHAR win2008W[] =
3136 {'S','e','r','v','e','r',' ','2','0','0','8',' ','S','t','a','n','d','a','r','d',0};
3137 static const WCHAR win7W[] =
3138 {'7',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
3139 static const WCHAR win2008r2W[] =
3140 {'S','e','r','v','e','r',' ','2','0','0','8',' ','R','2',' ','S','t','a','n','d','a','r','d',0};
3141 static const WCHAR win8W[] =
3142 {'8',' ','P','r','o',0};
3143 static const WCHAR win81W[] =
3144 {'8','.','1',' ','P','r','o',0};
3145 static const WCHAR win10W[] =
3146 {'1','0',' ','P','r','o',0};
3147 int len = ARRAY_SIZE( windowsW );
3148 WCHAR *ret;
3150 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL;
3151 memcpy( ret, windowsW, sizeof(windowsW) );
3152 if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) );
3153 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win8W, sizeof(win8W) );
3154 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win81W, sizeof(win81W) );
3155 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1)
3157 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) );
3158 else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) );
3160 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0)
3162 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) );
3163 else memcpy( ret + len, win2008W, sizeof(win2008W) );
3165 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2)
3167 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) );
3168 else memcpy( ret + len, win2003W, sizeof(win2003W) );
3170 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) );
3171 else memcpy( ret + len, win2000W, sizeof(win2000W) );
3172 return ret;
3174 static WCHAR *get_osname( const WCHAR *caption )
3176 static const WCHAR partitionW[] =
3177 {'|','C',':','\\','W','I','N','D','O','W','S','|','\\','D','e','v','i','c','e','\\',
3178 'H','a','r','d','d','i','s','k','0','\\','P','a','r','t','i','t','i','o','n','1',0};
3179 int len = strlenW( caption );
3180 WCHAR *ret;
3182 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
3183 memcpy( ret, caption, len * sizeof(WCHAR) );
3184 memcpy( ret + len, partitionW, sizeof(partitionW) );
3185 return ret;
3187 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
3189 static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u',0};
3190 WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) );
3191 if (ret) sprintfW( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
3192 return ret;
3195 static enum fill_status fill_os( struct table *table, const struct expr *cond )
3197 struct record_operatingsystem *rec;
3198 enum fill_status status = FILL_STATUS_UNFILTERED;
3199 OSVERSIONINFOEXW ver;
3200 UINT row = 0;
3202 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3204 ver.dwOSVersionInfoSize = sizeof(ver);
3205 GetVersionExW( (OSVERSIONINFOW *)&ver );
3207 rec = (struct record_operatingsystem *)table->data;
3208 rec->buildnumber = get_osbuildnumber( &ver );
3209 rec->caption = get_oscaption( &ver );
3210 rec->codeset = get_codeset();
3211 rec->countrycode = get_countrycode();
3212 rec->csdversion = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL;
3213 rec->freephysicalmemory = get_available_physical_memory() / 1024;
3214 rec->installdate = os_installdateW;
3215 rec->lastbootuptime = get_lastbootuptime();
3216 rec->localdatetime = get_localdatetime();
3217 rec->locale = get_locale();
3218 rec->name = get_osname( rec->caption );
3219 rec->osarchitecture = get_osarchitecture();
3220 rec->oslanguage = GetSystemDefaultLangID();
3221 rec->osproductsuite = 2461140; /* Windows XP Professional */
3222 rec->ostype = 18; /* WINNT */
3223 rec->primary = -1;
3224 rec->serialnumber = os_serialnumberW;
3225 rec->servicepackmajor = ver.wServicePackMajor;
3226 rec->servicepackminor = ver.wServicePackMinor;
3227 rec->suitemask = 272; /* Single User + Terminal */
3228 rec->systemdirectory = get_systemdirectory();
3229 rec->totalvirtualmemorysize = get_total_physical_memory() / 1024;
3230 rec->totalvisiblememorysize = rec->totalvirtualmemorysize;
3231 rec->version = get_osversion( &ver );
3232 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3233 else row++;
3235 TRACE("created %u rows\n", row);
3236 table->num_rows = row;
3237 return status;
3240 static const WCHAR *get_service_type( DWORD type )
3242 static const WCHAR filesystem_driverW[] =
3243 {'F','i','l','e',' ','S','y','s','t','e','m',' ','D','r','i','v','e','r',0};
3244 static const WCHAR kernel_driverW[] =
3245 {'K','e','r','n','e','l',' ','D','r','i','v','e','r',0};
3246 static const WCHAR own_processW[] =
3247 {'O','w','n',' ','P','r','o','c','e','s','s',0};
3248 static const WCHAR share_processW[] =
3249 {'S','h','a','r','e',' ','P','r','o','c','e','s','s',0};
3251 if (type & SERVICE_KERNEL_DRIVER) return kernel_driverW;
3252 else if (type & SERVICE_FILE_SYSTEM_DRIVER) return filesystem_driverW;
3253 else if (type & SERVICE_WIN32_OWN_PROCESS) return own_processW;
3254 else if (type & SERVICE_WIN32_SHARE_PROCESS) return share_processW;
3255 else ERR("unhandled type 0x%08x\n", type);
3256 return NULL;
3258 static const WCHAR *get_service_state( DWORD state )
3260 static const WCHAR runningW[] =
3261 {'R','u','n','n','i','n','g',0};
3262 static const WCHAR start_pendingW[] =
3263 {'S','t','a','r','t',' ','P','e','n','d','i','n','g',0};
3264 static const WCHAR stop_pendingW[] =
3265 {'S','t','o','p',' ','P','e','n','d','i','n','g',0};
3266 static const WCHAR stoppedW[] =
3267 {'S','t','o','p','p','e','d',0};
3268 static const WCHAR unknownW[] =
3269 {'U','n','k','n','o','w','n',0};
3271 switch (state)
3273 case SERVICE_STOPPED: return stoppedW;
3274 case SERVICE_START_PENDING: return start_pendingW;
3275 case SERVICE_STOP_PENDING: return stop_pendingW;
3276 case SERVICE_RUNNING: return runningW;
3277 default:
3278 ERR("unknown state %u\n", state);
3279 return unknownW;
3282 static const WCHAR *get_service_startmode( DWORD mode )
3284 static const WCHAR bootW[] = {'B','o','o','t',0};
3285 static const WCHAR systemW[] = {'S','y','s','t','e','m',0};
3286 static const WCHAR autoW[] = {'A','u','t','o',0};
3287 static const WCHAR manualW[] = {'M','a','n','u','a','l',0};
3288 static const WCHAR disabledW[] = {'D','i','s','a','b','l','e','d',0};
3289 static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',0};
3291 switch (mode)
3293 case SERVICE_BOOT_START: return bootW;
3294 case SERVICE_SYSTEM_START: return systemW;
3295 case SERVICE_AUTO_START: return autoW;
3296 case SERVICE_DEMAND_START: return manualW;
3297 case SERVICE_DISABLED: return disabledW;
3298 default:
3299 ERR("unknown mode 0x%x\n", mode);
3300 return unknownW;
3303 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
3305 QUERY_SERVICE_CONFIGW *config = NULL;
3306 SC_HANDLE service;
3307 DWORD size;
3309 if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL;
3310 QueryServiceConfigW( service, NULL, 0, &size );
3311 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
3312 if (!(config = heap_alloc( size ))) goto done;
3313 if (QueryServiceConfigW( service, config, size, &size )) goto done;
3314 heap_free( config );
3315 config = NULL;
3317 done:
3318 CloseServiceHandle( service );
3319 return config;
3322 static enum fill_status fill_service( struct table *table, const struct expr *cond )
3324 struct record_service *rec;
3325 SC_HANDLE manager;
3326 ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL;
3327 SERVICE_STATUS_PROCESS *status;
3328 WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
3329 DWORD len = ARRAY_SIZE( sysnameW );
3330 UINT i, row = 0, offset = 0, size = 256, needed, count;
3331 enum fill_status fill_status = FILL_STATUS_FAILED;
3332 BOOL ret;
3334 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED;
3335 if (!(services = heap_alloc( size ))) goto done;
3337 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3338 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3339 &count, NULL, NULL );
3340 if (!ret)
3342 if (GetLastError() != ERROR_MORE_DATA) goto done;
3343 size = needed;
3344 if (!(tmp = heap_realloc( services, size ))) goto done;
3345 services = tmp;
3346 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3347 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3348 &count, NULL, NULL );
3349 if (!ret) goto done;
3351 if (!resize_table( table, count, sizeof(*rec) )) goto done;
3353 GetComputerNameW( sysnameW, &len );
3354 fill_status = FILL_STATUS_UNFILTERED;
3356 for (i = 0; i < count; i++)
3358 QUERY_SERVICE_CONFIGW *config;
3360 if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue;
3362 status = &services[i].ServiceStatusProcess;
3363 rec = (struct record_service *)(table->data + offset);
3364 rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0;
3365 rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0;
3366 rec->displayname = heap_strdupW( services[i].lpDisplayName );
3367 rec->name = heap_strdupW( services[i].lpServiceName );
3368 rec->process_id = status->dwProcessId;
3369 rec->servicetype = get_service_type( status->dwServiceType );
3370 rec->startmode = get_service_startmode( config->dwStartType );
3371 rec->state = get_service_state( status->dwCurrentState );
3372 rec->systemname = heap_strdupW( sysnameW );
3373 rec->pause_service = service_pause_service;
3374 rec->resume_service = service_resume_service;
3375 rec->start_service = service_start_service;
3376 rec->stop_service = service_stop_service;
3377 heap_free( config );
3378 if (!match_row( table, row, cond, &fill_status ))
3380 free_row_values( table, row );
3381 continue;
3383 offset += sizeof(*rec);
3384 row++;
3387 TRACE("created %u rows\n", row);
3388 table->num_rows = row;
3390 done:
3391 CloseServiceHandle( manager );
3392 heap_free( services );
3393 return fill_status;
3396 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
3398 if (!name || !name->Name.Buffer) return NULL;
3399 return heap_strdupW( name->Name.Buffer );
3401 static struct array *get_binaryrepresentation( PSID sid, UINT len )
3403 struct array *array = heap_alloc( sizeof(struct array) );
3404 if (array)
3406 UINT8 *ret = heap_alloc( len );
3407 if (ret)
3409 memcpy( ret, sid, len );
3410 array->count = len;
3411 array->ptr = ret;
3412 return array;
3414 heap_free( array );
3416 return NULL;
3418 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
3420 if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL;
3421 return heap_strdupW( domain->Domains->Name.Buffer );
3423 static const WCHAR *find_sid_str( const struct expr *cond )
3425 const struct expr *left, *right;
3426 const WCHAR *ret = NULL;
3428 if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL;
3430 left = cond->u.expr.left;
3431 right = cond->u.expr.right;
3432 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !strcmpiW( left->u.propval->name, prop_sidW ))
3434 ret = right->u.sval;
3436 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !strcmpiW( right->u.propval->name, prop_sidW ))
3438 ret = left->u.sval;
3440 return ret;
3443 static enum fill_status fill_sid( struct table *table, const struct expr *cond )
3445 PSID sid;
3446 LSA_REFERENCED_DOMAIN_LIST *domain;
3447 LSA_TRANSLATED_NAME *name;
3448 LSA_HANDLE handle;
3449 LSA_OBJECT_ATTRIBUTES attrs;
3450 const WCHAR *str;
3451 struct record_sid *rec;
3452 UINT len;
3454 if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED;
3455 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3457 if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED;
3458 len = GetLengthSid( sid );
3460 memset( &attrs, 0, sizeof(attrs) );
3461 attrs.Length = sizeof(attrs);
3462 if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ))
3464 LocalFree( sid );
3465 return FILL_STATUS_FAILED;
3467 if (LsaLookupSids( handle, 1, &sid, &domain, &name ))
3469 LocalFree( sid );
3470 LsaClose( handle );
3471 return FILL_STATUS_FAILED;
3474 rec = (struct record_sid *)table->data;
3475 rec->accountname = get_accountname( name );
3476 rec->binaryrepresentation = get_binaryrepresentation( sid, len );
3477 rec->referenceddomainname = get_referenceddomainname( domain );
3478 rec->sid = heap_strdupW( str );
3479 rec->sidlength = len;
3481 TRACE("created 1 row\n");
3482 table->num_rows = 1;
3484 LsaFreeMemory( domain );
3485 LsaFreeMemory( name );
3486 LocalFree( sid );
3487 LsaClose( handle );
3488 return FILL_STATUS_FILTERED;
3491 static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres )
3493 HDC hdc = GetDC( NULL );
3494 UINT32 ret;
3496 if (!hdc) return 32;
3497 ret = GetDeviceCaps( hdc, BITSPIXEL );
3498 *hres = GetDeviceCaps( hdc, HORZRES );
3499 *vres = GetDeviceCaps( hdc, VERTRES );
3500 ReleaseDC( NULL, hdc );
3501 return ret;
3503 static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
3505 static const WCHAR fmtW[] =
3506 {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X',
3507 '&','S','U','B','S','Y','S','_','%','0','8','X','&','R','E','V','_','%','0','2','X','\\',
3508 '0','&','D','E','A','D','B','E','E','F','&','0','&','D','E','A','D',0};
3509 WCHAR *ret;
3511 if (!(ret = heap_alloc( sizeof(fmtW) + 2 * sizeof(WCHAR) ))) return NULL;
3512 sprintfW( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
3513 return ret;
3516 #define HW_VENDOR_AMD 0x1002
3517 #define HW_VENDOR_NVIDIA 0x10de
3518 #define HW_VENDOR_VMWARE 0x15ad
3519 #define HW_VENDOR_INTEL 0x8086
3521 static const WCHAR *get_installeddriver( UINT vendorid )
3523 static const WCHAR driver_amdW[] = {'a','t','i','c','f','x','3','2','.','d','l','l',0};
3524 static const WCHAR driver_intelW[] = {'i','g','d','u','m','d','i','m','3','2','.','d','l','l',0};
3525 static const WCHAR driver_nvidiaW[] = {'n','v','d','3','d','u','m','.','d','l','l',0};
3526 static const WCHAR driver_wineW[] = {'w','i','n','e','.','d','l','l',0};
3528 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
3530 if (vendorid == HW_VENDOR_AMD)
3531 return driver_amdW;
3532 else if (vendorid == HW_VENDOR_NVIDIA)
3533 return driver_nvidiaW;
3534 else if (vendorid == HW_VENDOR_INTEL)
3535 return driver_intelW;
3536 return driver_wineW;
3539 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
3541 static const WCHAR fmtW[] = {'%','u',' ','x',' ','%','u',' ','x',' ','%','I','6','4','u',' ','c','o','l','o','r','s',0};
3542 struct record_videocontroller *rec;
3543 HRESULT hr;
3544 IDXGIFactory *factory = NULL;
3545 IDXGIAdapter *adapter = NULL;
3546 DXGI_ADAPTER_DESC desc;
3547 UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
3548 const WCHAR *name = videocontroller_deviceidW;
3549 enum fill_status status = FILL_STATUS_UNFILTERED;
3550 WCHAR mode[44];
3552 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3554 memset (&desc, 0, sizeof(desc));
3555 hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
3556 if (FAILED(hr)) goto done;
3558 hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
3559 if (FAILED(hr)) goto done;
3561 hr = IDXGIAdapter_GetDesc( adapter, &desc );
3562 if (SUCCEEDED(hr))
3564 vidmem = desc.DedicatedVideoMemory;
3565 name = desc.Description;
3568 done:
3569 rec = (struct record_videocontroller *)table->data;
3570 rec->adapter_dactype = videocontroller_dactypeW;
3571 rec->adapter_ram = vidmem;
3572 rec->availability = 3; /* Running or Full Power */
3573 rec->config_errorcode = 0; /* no error */
3574 rec->caption = heap_strdupW( name );
3575 rec->current_bitsperpixel = get_bits_per_pixel( &hres, &vres );
3576 rec->current_horizontalres = hres;
3577 rec->current_refreshrate = 0; /* default refresh rate */
3578 rec->current_scanmode = 2; /* Unknown */
3579 rec->current_verticalres = vres;
3580 rec->description = heap_strdupW( name );
3581 rec->device_id = videocontroller_deviceidW;
3582 rec->driverdate = videocontroller_driverdateW;
3583 rec->driverversion = videocontroller_driverversionW;
3584 rec->installeddriver = get_installeddriver( desc.VendorId );
3585 rec->name = heap_strdupW( name );
3586 rec->pnpdevice_id = get_pnpdeviceid( &desc );
3587 rec->status = videocontroller_statusW;
3588 rec->videoarchitecture = 2; /* Unknown */
3589 rec->videomemorytype = 2; /* Unknown */
3590 wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel );
3591 rec->videomodedescription = heap_strdupW( mode );
3592 rec->videoprocessor = heap_strdupW( name );
3593 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3594 else row++;
3596 TRACE("created %u rows\n", row);
3597 table->num_rows = row;
3599 if (adapter) IDXGIAdapter_Release( adapter );
3600 if (factory) IDXGIFactory_Release( factory );
3601 return status;
3604 static struct table builtin_classes[] =
3606 { class_baseboardW, ARRAY_SIZE(col_baseboard), col_baseboard, ARRAY_SIZE(data_baseboard), 0, (BYTE *)data_baseboard },
3607 { class_biosW, ARRAY_SIZE(col_bios), col_bios, ARRAY_SIZE(data_bios), 0, (BYTE *)data_bios },
3608 { class_cdromdriveW, ARRAY_SIZE(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive },
3609 { class_compsysW, ARRAY_SIZE(col_compsys), col_compsys, 0, 0, NULL, fill_compsys },
3610 { class_compsysproductW, ARRAY_SIZE(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct },
3611 { class_datafileW, ARRAY_SIZE(col_datafile), col_datafile, 0, 0, NULL, fill_datafile },
3612 { class_desktopmonitorW, ARRAY_SIZE(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor },
3613 { class_directoryW, ARRAY_SIZE(col_directory), col_directory, 0, 0, NULL, fill_directory },
3614 { class_diskdriveW, ARRAY_SIZE(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive },
3615 { class_diskpartitionW, ARRAY_SIZE(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition },
3616 { class_ip4routetableW, ARRAY_SIZE(col_ip4routetable), col_ip4routetable, 0, 0, NULL, fill_ip4routetable },
3617 { class_logicaldiskW, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
3618 { class_logicaldisk2W, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
3619 { class_networkadapterW, ARRAY_SIZE(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter },
3620 { class_networkadapterconfigW, ARRAY_SIZE(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, fill_networkadapterconfig },
3621 { class_osW, ARRAY_SIZE(col_os), col_os, 0, 0, NULL, fill_os },
3622 { class_paramsW, ARRAY_SIZE(col_param), col_param, ARRAY_SIZE(data_param), 0, (BYTE *)data_param },
3623 { class_physicalmediaW, ARRAY_SIZE(col_physicalmedia), col_physicalmedia, ARRAY_SIZE(data_physicalmedia), 0, (BYTE *)data_physicalmedia },
3624 { class_physicalmemoryW, ARRAY_SIZE(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory },
3625 { class_pnpentityW, ARRAY_SIZE(col_pnpentity), col_pnpentity, 0, 0, NULL, fill_pnpentity },
3626 { class_printerW, ARRAY_SIZE(col_printer), col_printer, 0, 0, NULL, fill_printer },
3627 { class_processW, ARRAY_SIZE(col_process), col_process, 0, 0, NULL, fill_process },
3628 { class_processorW, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
3629 { class_processor2W, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
3630 { class_qualifiersW, ARRAY_SIZE(col_qualifier), col_qualifier, ARRAY_SIZE(data_qualifier), 0, (BYTE *)data_qualifier },
3631 { class_serviceW, ARRAY_SIZE(col_service), col_service, 0, 0, NULL, fill_service },
3632 { class_sidW, ARRAY_SIZE(col_sid), col_sid, 0, 0, NULL, fill_sid },
3633 { class_sounddeviceW, ARRAY_SIZE(col_sounddevice), col_sounddevice, ARRAY_SIZE(data_sounddevice), 0, (BYTE *)data_sounddevice },
3634 { class_stdregprovW, ARRAY_SIZE(col_stdregprov), col_stdregprov, ARRAY_SIZE(data_stdregprov), 0, (BYTE *)data_stdregprov },
3635 { class_systemsecurityW, ARRAY_SIZE(col_systemsecurity), col_systemsecurity, ARRAY_SIZE(data_systemsecurity), 0, (BYTE *)data_systemsecurity },
3636 { class_systemenclosureW, ARRAY_SIZE(col_systemenclosure), col_systemenclosure, ARRAY_SIZE(data_systemenclosure), 0, (BYTE *)data_systemenclosure },
3637 { class_videocontrollerW, ARRAY_SIZE(col_videocontroller), col_videocontroller, 0, 0, NULL, fill_videocontroller }
3640 void init_table_list( void )
3642 static struct list tables = LIST_INIT( tables );
3643 UINT i;
3645 for (i = 0; i < ARRAY_SIZE(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry );
3646 table_list = &tables;