xref: /reactos/dll/win32/wbemprox/builtin.c (revision ac43fd2b)
1 /*
2  * Copyright 2012 Hans Leidekker for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #define COBJMACROS
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
22 
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
32 
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 #ifndef __REACTOS__
56 #include "d3d10.h"
57 #endif
58 #include "winternl.h"
59 #include "winioctl.h"
60 #include "winsvc.h"
61 #include "winver.h"
62 #include "sddl.h"
63 #include "ntsecapi.h"
64 #ifdef __REACTOS__
65 #include <wingdi.h>
66 #include <winreg.h>
67 #endif
68 #include "winspool.h"
69 #include "setupapi.h"
70 
71 #include "wine/debug.h"
72 #include "wbemprox_private.h"
73 
74 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
75 
76 static const WCHAR class_baseboardW[] =
77     {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0};
78 static const WCHAR class_biosW[] =
79     {'W','i','n','3','2','_','B','I','O','S',0};
80 static const WCHAR class_cdromdriveW[] =
81     {'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0};
82 static const WCHAR class_compsysW[] =
83     {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
84 static const WCHAR class_compsysproductW[] =
85     {'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};
86 static const WCHAR class_datafileW[] =
87     {'C','I','M','_','D','a','t','a','F','i','l','e',0};
88 static const WCHAR class_desktopmonitorW[] =
89     {'W','i','n','3','2','_','D','e','s','k','t','o','p','M','o','n','i','t','o','r',0};
90 static const WCHAR class_directoryW[] =
91     {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0};
92 static const WCHAR class_diskdriveW[] =
93     {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0};
94 static const WCHAR class_diskpartitionW[] =
95     {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0};
96 static const WCHAR class_ip4routetableW[] =
97     {'W','i','n','3','2','_','I','P','4','R','o','u','t','e','T','a','b','l','e',0};
98 static const WCHAR class_logicaldiskW[] =
99     {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0};
100 static const WCHAR class_logicaldisk2W[] =
101     {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0};
102 static const WCHAR class_networkadapterW[] =
103     {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0};
104 static const WCHAR class_networkadapterconfigW[] =
105     {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',
106      'C','o','n','f','i','g','u','r','a','t','i','o','n',0};
107 static const WCHAR class_osW[] =
108     {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
109 static const WCHAR class_paramsW[] =
110     {'_','_','P','A','R','A','M','E','T','E','R','S',0};
111 static const WCHAR class_physicalmediaW[] =
112     {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0};
113 static const WCHAR class_physicalmemoryW[] =
114     {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
115 static const WCHAR class_pnpentityW[] =
116     {'W','i','n','3','2','_','P','n','P','E','n','t','i','t','y',0};
117 static const WCHAR class_printerW[] =
118     {'W','i','n','3','2','_','P','r','i','n','t','e','r',0};
119 static const WCHAR class_process_getowner_outW[] =
120     {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W',
121      'N','E','R','_','O','U','T',0};
122 static const WCHAR class_processorW[] =
123     {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0};
124 static const WCHAR class_processor2W[] =
125     {'C','I','M','_','P','r','o','c','e','s','s','o','r',0};
126 static const WCHAR class_qualifiersW[] =
127     {'_','_','Q','U','A','L','I','F','I','E','R','S',0};
128 static const WCHAR class_sidW[] =
129     {'W','i','n','3','2','_','S','I','D',0};
130 static const WCHAR class_sounddeviceW[] =
131     {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0};
132 static const WCHAR class_systemenclosureW[] =
133     {'W','i','n','3','2','_','S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0};
134 #ifndef __REACTOS__
135 static const WCHAR class_videocontrollerW[] =
136     {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0};
137 #endif
138 
139 static const WCHAR prop_accountnameW[] =
140     {'A','c','c','o','u','n','t','N','a','m','e',0};
141 static const WCHAR prop_acceptpauseW[] =
142     {'A','c','c','e','p','t','P','a','u','s','e',0};
143 static const WCHAR prop_acceptstopW[] =
144     {'A','c','c','e','p','t','S','t','o','p',0};
145 static const WCHAR prop_accessmaskW[] =
146     {'A','c','c','e','s','s','M','a','s','k',0};
147 #ifndef __REACTOS__
148 static const WCHAR prop_adapterdactypeW[] =
149     {'A','d','a','p','t','e','r','D','A','C','T','y','p','e',0};
150 static const WCHAR prop_adapterramW[] =
151     {'A','d','a','p','t','e','r','R','A','M',0};
152 #endif
153 static const WCHAR prop_adaptertypeW[] =
154     {'A','d','a','p','t','e','r','T','y','p','e',0};
155 static const WCHAR prop_addresswidthW[] =
156     {'A','d','d','r','e','s','s','W','i','d','t','h',0};
157 static const WCHAR prop_architectureW[] =
158     {'A','r','c','h','i','t','e','c','t','u','r','e',0};
159 static const WCHAR prop_attributesW[] =
160     {'A','t','t','r','i','b','u','t','e','s',0};
161 #ifndef __REACTOS__
162 static const WCHAR prop_availabilityW[] =
163     {'A','v','a','i','l','a','b','i','l','i','t','y',0};
164 #endif
165 static const WCHAR prop_binaryrepresentationW[] =
166     {'B','i','n','a','r','y','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
167 static const WCHAR prop_bootableW[] =
168     {'B','o','o','t','a','b','l','e',0};
169 static const WCHAR prop_bootpartitionW[] =
170     {'B','o','o','t','P','a','r','t','i','t','i','o','n',0};
171 static const WCHAR prop_buildnumberW[] =
172     {'B','u','i','l','d','N','u','m','b','e','r',0};
173 static const WCHAR prop_capacityW[] =
174     {'C','a','p','a','c','i','t','y',0};
175 static const WCHAR prop_captionW[] =
176     {'C','a','p','t','i','o','n',0};
177 static const WCHAR prop_chassistypesW[] =
178     {'C','h','a','s','s','i','s','T','y','p','e','s',0};
179 static const WCHAR prop_classW[] =
180     {'C','l','a','s','s',0};
181 static const WCHAR prop_codesetW[] =
182     {'C','o','d','e','S','e','t',0};
183 static const WCHAR prop_commandlineW[] =
184     {'C','o','m','m','a','n','d','L','i','n','e',0};
185 static const WCHAR prop_configmanagererrorcodeW[] =
186     {'C','o','n','f','i','g','M','a','n','a','g','e','r','E','r','r','o','r','C','o','d','e',0};
187 static const WCHAR prop_countrycodeW[] =
188     {'C','o','u','n','t','r','y','C','o','d','e',0};
189 static const WCHAR prop_cpustatusW[] =
190     {'C','p','u','S','t','a','t','u','s',0};
191 static const WCHAR prop_csdversionW[] =
192     {'C','S','D','V','e','r','s','i','o','n',0};
193 #ifndef __REACTOS__
194 static const WCHAR prop_currentbitsperpixelW[] =
195     {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0};
196 #endif
197 static const WCHAR prop_currentclockspeedW[] =
198     {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0};
199 #ifndef __REACTOS__
200 static const WCHAR prop_currenthorizontalresW[] =
201     {'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};
202 static const WCHAR prop_currentrefreshrateW[] =
203     {'C','u','r','r','e','n','t','R','e','f','r','e','s','h','R','a','t','e',0};
204 static const WCHAR prop_currentscanmodeW[] =
205     {'C','u','r','r','e','n','t','S','c','a','n','M','o','d','e',0};
206 static const WCHAR prop_currentverticalresW[] =
207     {'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};
208 #endif
209 static const WCHAR prop_datawidthW[] =
210     {'D','a','t','a','W','i','d','t','h',0};
211 static const WCHAR prop_defaultipgatewayW[] =
212     {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0};
213 static const WCHAR prop_defaultvalueW[] =
214     {'D','e','f','a','u','l','t','V','a','l','u','e',0};
215 static const WCHAR prop_descriptionW[] =
216     {'D','e','s','c','r','i','p','t','i','o','n',0};
217 static const WCHAR prop_destinationW[] =
218     {'D','e','s','t','i','n','a','t','i','o','n',0};
219 static const WCHAR prop_deviceidW[] =
220     {'D','e','v','i','c','e','I','d',0};
221 static const WCHAR prop_dhcpenabledW[] =
222     {'D','H','C','P','E','n','a','b','l','e','d',0};
223 static const WCHAR prop_directionW[] =
224     {'D','i','r','e','c','t','i','o','n',0};
225 static const WCHAR prop_displaynameW[] =
226     {'D','i','s','p','l','a','y','N','a','m','e',0};
227 static const WCHAR prop_diskindexW[] =
228     {'D','i','s','k','I','n','d','e','x',0};
229 static const WCHAR prop_dnshostnameW[] =
230     {'D','N','S','H','o','s','t','N','a','m','e',0};
231 static const WCHAR prop_dnsserversearchorderW[] =
232     {'D','N','S','S','e','r','v','e','r','S','e','a','r','c','h','O','r','d','e','r',0};
233 static const WCHAR prop_domainW[] =
234     {'D','o','m','a','i','n',0};
235 static const WCHAR prop_domainroleW[] =
236     {'D','o','m','a','i','n','R','o','l','e',0};
237 static const WCHAR prop_driveW[] =
238     {'D','r','i','v','e',0};
239 static const WCHAR prop_driverdateW[] =
240     {'D','r','i','v','e','r','D','a','t','e',0};
241 static const WCHAR prop_drivernameW[] =
242     {'D','r','i','v','e','r','N','a','m','e',0};
243 #ifndef __REACTOS__
244 static const WCHAR prop_driverversionW[] =
245     {'D','r','i','v','e','r','V','e','r','s','i','o','n',0};
246 #endif
247 static const WCHAR prop_drivetypeW[] =
248     {'D','r','i','v','e','T','y','p','e',0};
249 static const WCHAR prop_familyW[] =
250     {'F','a','m','i','l','y',0};
251 static const WCHAR prop_filesystemW[] =
252     {'F','i','l','e','S','y','s','t','e','m',0};
253 static const WCHAR prop_flavorW[] =
254     {'F','l','a','v','o','r',0};
255 static const WCHAR prop_freespaceW[] =
256     {'F','r','e','e','S','p','a','c','e',0};
257 static const WCHAR prop_freephysicalmemoryW[] =
258     {'F','r','e','e','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
259 static const WCHAR prop_handleW[] =
260     {'H','a','n','d','l','e',0};
261 static const WCHAR prop_horizontalresolutionW[] =
262     {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
263 static const WCHAR prop_idW[] =
264     {'I','D',0};
265 static const WCHAR prop_identificationcodeW[] =
266     {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0};
267 static const WCHAR prop_identifyingnumberW[] =
268     {'I','d','e','n','t','i','f','y','i','n','g','N','u','m','b','e','r',0};
269 static const WCHAR prop_indexW[] =
270     {'I','n','d','e','x',0};
271 static const WCHAR prop_installdateW[] =
272     {'I','n','s','t','a','l','l','D','a','t','e',0};
273 static const WCHAR prop_installeddisplaydriversW[]=
274     {'I','n','s','t','a','l','l','e','d','D','i','s','p','l','a','y','D','r','i','v','e','r','s',0};
275 static const WCHAR prop_interfaceindexW[] =
276     {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0};
277 static const WCHAR prop_interfacetypeW[] =
278     {'I','n','t','e','r','f','a','c','e','T','y','p','e',0};
279 static const WCHAR prop_intvalueW[] =
280     {'I','n','t','e','g','e','r','V','a','l','u','e',0};
281 static const WCHAR prop_ipaddressW[] =
282     {'I','P','A','d','d','r','e','s','s',0};
283 static const WCHAR prop_ipconnectionmetricW[] =
284     {'I','P','C','o','n','n','e','c','t','i','o','n','M','e','t','r','i','c',0};
285 static const WCHAR prop_ipenabledW[] =
286     {'I','P','E','n','a','b','l','e','d',0};
287 static const WCHAR prop_ipsubnet[] =
288     {'I','P','S','u','b','n','e','t',0};
289 static const WCHAR prop_lastbootuptimeW[] =
290     {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0};
291 static const WCHAR prop_levelW[] =
292     {'L','e','v','e','l',0};
293 static const WCHAR prop_localW[] =
294     {'L','o','c','a','l',0};
295 static const WCHAR prop_localdatetimeW[] =
296     {'L','o','c','a','l','D','a','t','e','T','i','m','e',0};
297 static const WCHAR prop_localeW[] =
298     {'L','o','c','a','l','e',0};
299 static const WCHAR prop_locationW[] =
300     {'L','o','c','a','t','i','o','n',0};
301 static const WCHAR prop_lockpresentW[] =
302     {'L','o','c','k','P','r','e','s','e','n','t',0};
303 static const WCHAR prop_macaddressW[] =
304     {'M','A','C','A','d','d','r','e','s','s',0};
305 static const WCHAR prop_manufacturerW[] =
306     {'M','a','n','u','f','a','c','t','u','r','e','r',0};
307 static const WCHAR prop_maxclockspeedW[] =
308     {'M','a','x','C','l','o','c','k','S','p','e','e','d',0};
309 static const WCHAR prop_mediatypeW[] =
310     {'M','e','d','i','a','T','y','p','e',0};
311 static const WCHAR prop_memberW[] =
312     {'M','e','m','b','e','r',0};
313 static const WCHAR prop_memorytypeW[] =
314     {'M','e','m','o','r','y','T','y','p','e',0};
315 static const WCHAR prop_methodW[] =
316     {'M','e','t','h','o','d',0};
317 static const WCHAR prop_modelW[] =
318     {'M','o','d','e','l',0};
319 static const WCHAR prop_netconnectionstatusW[] =
320     {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0};
321 static const WCHAR prop_networkW[] =
322     {'N','e','t','w','o','r','k',0};
323 static const WCHAR prop_nexthopW[] =
324     {'N','e','x','t','H','o','p',0};
325 static const WCHAR prop_numcoresW[] =
326     {'N','u','m','b','e','r','O','f','C','o','r','e','s',0};
327 static const WCHAR prop_numlogicalprocessorsW[] =
328     {'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};
329 static const WCHAR prop_numprocessorsW[] =
330     {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
331 static const WCHAR prop_osarchitectureW[] =
332     {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0};
333 static const WCHAR prop_oslanguageW[] =
334     {'O','S','L','a','n','g','u','a','g','e',0};
335 static const WCHAR prop_osproductsuiteW[] =
336     {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0};
337 static const WCHAR prop_ostypeW[] =
338     {'O','S','T','y','p','e',0};
339 static const WCHAR prop_parameterW[] =
340     {'P','a','r','a','m','e','t','e','r',0};
341 static const WCHAR prop_physicaladapterW[] =
342     {'P','h','y','s','i','c','a','l','A','d','a','p','t','e','r',0};
343 static const WCHAR prop_pixelsperxlogicalinchW[] =
344     {'P','i','x','e','l','s','P','e','r','X','L','o','g','i','c','a','l','I','n','c','h',0};
345 static const WCHAR prop_pnpdeviceidW[] =
346     {'P','N','P','D','e','v','i','c','e','I','D',0};
347 static const WCHAR prop_portnameW[] =
348     {'P','o','r','t','N','a','m','e',0};
349 static const WCHAR prop_pprocessidW[] =
350     {'P','a','r','e','n','t','P','r','o','c','e','s','s','I','D',0};
351 static const WCHAR prop_primaryW[] =
352     {'P','r','i','m','a','r','y',0};
353 static const WCHAR prop_processidW[] =
354     {'P','r','o','c','e','s','s','I','D',0};
355 static const WCHAR prop_processoridW[] =
356     {'P','r','o','c','e','s','s','o','r','I','d',0};
357 static const WCHAR prop_processortypeW[] =
358     {'P','r','o','c','e','s','s','o','r','T','y','p','e',0};
359 static const WCHAR prop_productW[] =
360     {'P','r','o','d','u','c','t',0};
361 static const WCHAR prop_productnameW[] =
362     {'P','r','o','d','u','c','t','N','a','m','e',0};
363 static const WCHAR prop_referenceddomainnameW[] =
364     {'R','e','f','e','r','e','n','c','e','d','D','o','m','a','i','n','N','a','m','e',0};
365 static const WCHAR prop_releasedateW[] =
366     {'R','e','l','e','a','s','e','D','a','t','e',0};
367 static const WCHAR prop_revisionW[] =
368     {'R','e','v','i','s','i','o','n',0};
369 static const WCHAR prop_serialnumberW[] =
370     {'S','e','r','i','a','l','N','u','m','b','e','r',0};
371 static const WCHAR prop_servicepackmajorW[] =
372     {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0};
373 static const WCHAR prop_servicepackminorW[] =
374     {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0};
375 static const WCHAR prop_servicetypeW[] =
376     {'S','e','r','v','i','c','e','T','y','p','e',0};
377 static const WCHAR prop_settingidW[] =
378     {'S','e','t','t','i','n','g','I','D',0};
379 static const WCHAR prop_skunumberW[] =
380     {'S','K','U','N','u','m','b','e','r',0};
381 static const WCHAR prop_smbiosbiosversionW[] =
382     {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0};
383 static const WCHAR prop_smbiosmajorversionW[] =
384     {'S','M','B','I','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0};
385 static const WCHAR prop_smbiosminorversionW[] =
386     {'S','M','B','I','O','S','M','i','n','o','r','V','e','r','s','i','o','n',0};
387 static const WCHAR prop_startmodeW[] =
388     {'S','t','a','r','t','M','o','d','e',0};
389 static const WCHAR prop_sidW[] =
390     {'S','I','D',0};
391 static const WCHAR prop_sidlengthW[] =
392     {'S','i','d','L','e','n','g','t','h',0};
393 static const WCHAR prop_sizeW[] =
394     {'S','i','z','e',0};
395 static const WCHAR prop_speedW[] =
396     {'S','p','e','e','d',0};
397 static const WCHAR prop_startingoffsetW[] =
398     {'S','t','a','r','t','i','n','g','O','f','f','s','e','t',0};
399 static const WCHAR prop_stateW[] =
400     {'S','t','a','t','e',0};
401 static const WCHAR prop_statusW[] =
402     {'S','t','a','t','u','s',0};
403 static const WCHAR prop_statusinfoW[] =
404     {'S','t','a','t','u','s','I','n','f','o',0};
405 static const WCHAR prop_strvalueW[] =
406     {'S','t','r','i','n','g','V','a','l','u','e',0};
407 static const WCHAR prop_suitemaskW[] =
408     {'S','u','i','t','e','M','a','s','k',0};
409 static const WCHAR prop_systemdirectoryW[] =
410     {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0};
411 static const WCHAR prop_systemnameW[] =
412     {'S','y','s','t','e','m','N','a','m','e',0};
413 static const WCHAR prop_tagW[] =
414     {'T','a','g',0};
415 static const WCHAR prop_threadcountW[] =
416     {'T','h','r','e','a','d','C','o','u','n','t',0};
417 static const WCHAR prop_totalphysicalmemoryW[] =
418     {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
419 static const WCHAR prop_totalvirtualmemorysizeW[] =
420     {'T','o','t','a','l','V','i','r','t','u','a','l','M','e','m','o','r','y','S','i','z','e',0};
421 static const WCHAR prop_totalvisiblememorysizeW[] =
422     {'T','o','t','a','l','V','i','s','i','b','l','e','M','e','m','o','r','y','S','i','z','e',0};
423 static const WCHAR prop_typeW[] =
424     {'T','y','p','e',0};
425 static const WCHAR prop_uniqueidW[] =
426     {'U','n','i','q','u','e','I','d',0};
427 static const WCHAR prop_usernameW[] =
428     {'U','s','e','r','N','a','m','e',0};
429 static const WCHAR prop_uuidW[] =
430     {'U','U','I','D',0};
431 static const WCHAR prop_varianttypeW[] =
432     {'V','a','r','i','a','n','t','T','y','p','e',0};
433 static const WCHAR prop_vendorW[] =
434     {'V','e','n','d','o','r',0};
435 static const WCHAR prop_versionW[] =
436     {'V','e','r','s','i','o','n',0};
437 #ifndef __REACTOS__
438 static const WCHAR prop_videoarchitectureW[] =
439     {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0};
440 static const WCHAR prop_videomemorytypeW[] =
441     {'V','i','d','e','o','M','e','m','o','r','y','T','y','p','e',0};
442 static const WCHAR prop_videomodedescriptionW[] =
443     {'V','i','d','e','o','M','o','d','e','D','e','s','c','r','i','p','t','i','o','n',0};
444 static const WCHAR prop_videoprocessorW[] =
445     {'V','i','d','e','o','P','r','o','c','e','s','s','o','r',0};
446 #endif /* !__REACTOS__ */
447 static const WCHAR prop_volumenameW[] =
448     {'V','o','l','u','m','e','N','a','m','e',0};
449 static const WCHAR prop_volumeserialnumberW[] =
450     {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0};
451 static const WCHAR prop_workingsetsizeW[] =
452     {'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0};
453 
454 /* column definitions must be kept in sync with record structures below */
455 static const struct column col_baseboard[] =
456 {
457     { prop_manufacturerW,  CIM_STRING },
458     { prop_modelW,         CIM_STRING },
459     { prop_nameW,          CIM_STRING },
460     { prop_productW,       CIM_STRING },
461     { prop_serialnumberW,  CIM_STRING },
462     { prop_tagW,           CIM_STRING|COL_FLAG_KEY },
463     { prop_versionW,       CIM_STRING }
464 };
465 static const struct column col_bios[] =
466 {
467     { prop_descriptionW,        CIM_STRING },
468     { prop_identificationcodeW, CIM_STRING },
469     { prop_manufacturerW,       CIM_STRING },
470     { prop_nameW,               CIM_STRING },
471     { prop_releasedateW,        CIM_DATETIME },
472     { prop_serialnumberW,       CIM_STRING },
473     { prop_smbiosbiosversionW,  CIM_STRING },
474     { prop_smbiosmajorversionW, CIM_UINT16, VT_I4 },
475     { prop_smbiosminorversionW, CIM_UINT16, VT_I4 },
476     { prop_versionW,            CIM_STRING|COL_FLAG_KEY }
477 };
478 static const struct column col_cdromdrive[] =
479 {
480     { prop_deviceidW,    CIM_STRING|COL_FLAG_KEY },
481     { prop_driveW,       CIM_STRING|COL_FLAG_DYNAMIC },
482     { prop_mediatypeW,   CIM_STRING },
483     { prop_nameW,        CIM_STRING },
484     { prop_pnpdeviceidW, CIM_STRING }
485 };
486 static const struct column col_compsys[] =
487 {
488     { prop_descriptionW,          CIM_STRING },
489     { prop_domainW,               CIM_STRING },
490     { prop_domainroleW,           CIM_UINT16, VT_I4 },
491     { prop_manufacturerW,         CIM_STRING },
492     { prop_modelW,                CIM_STRING },
493     { prop_nameW,                 CIM_STRING|COL_FLAG_DYNAMIC },
494     { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
495     { prop_numprocessorsW,        CIM_UINT32, VT_I4 },
496     { prop_totalphysicalmemoryW,  CIM_UINT64 },
497     { prop_usernameW,             CIM_STRING|COL_FLAG_DYNAMIC }
498 };
499 static const struct column col_compsysproduct[] =
500 {
501     { prop_identifyingnumberW,  CIM_STRING|COL_FLAG_KEY },
502     { prop_nameW,               CIM_STRING|COL_FLAG_KEY },
503     { prop_skunumberW,          CIM_STRING },
504     { prop_uuidW,               CIM_STRING|COL_FLAG_DYNAMIC },
505     { prop_vendorW,             CIM_STRING },
506     { prop_versionW,            CIM_STRING|COL_FLAG_KEY }
507 };
508 static const struct column col_datafile[] =
509 {
510     { prop_nameW,    CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
511     { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
512 };
513 static const struct column col_desktopmonitor[] =
514 {
515     { prop_pixelsperxlogicalinchW, CIM_UINT32 }
516 };
517 static const struct column col_directory[] =
518 {
519     { prop_accessmaskW, CIM_UINT32 },
520     { prop_nameW,       CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
521 };
522 static const struct column col_diskdrive[] =
523 {
524     { prop_deviceidW,      CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
525     { prop_indexW,         CIM_UINT32, VT_I4 },
526     { prop_interfacetypeW, CIM_STRING },
527     { prop_manufacturerW,  CIM_STRING },
528     { prop_mediatypeW,     CIM_STRING },
529     { prop_modelW,         CIM_STRING },
530     { prop_pnpdeviceidW,   CIM_STRING },
531     { prop_serialnumberW,  CIM_STRING },
532     { prop_sizeW,          CIM_UINT64 }
533 };
534 static const struct column col_diskpartition[] =
535 {
536     { prop_bootableW,       CIM_BOOLEAN },
537     { prop_bootpartitionW,  CIM_BOOLEAN },
538     { prop_deviceidW,       CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
539     { prop_diskindexW,      CIM_UINT32, VT_I4 },
540     { prop_indexW,          CIM_UINT32, VT_I4 },
541     { prop_pnpdeviceidW,    CIM_STRING|COL_FLAG_DYNAMIC },
542     { prop_sizeW,           CIM_UINT64 },
543     { prop_startingoffsetW, CIM_UINT64 },
544     { prop_typeW,           CIM_STRING|COL_FLAG_DYNAMIC }
545 };
546 static const struct column col_ip4routetable[] =
547 {
548     { prop_destinationW,    CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
549     { prop_interfaceindexW, CIM_SINT32|COL_FLAG_KEY },
550     { prop_nexthopW,        CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
551 };
552 static const struct column col_logicaldisk[] =
553 {
554     { prop_deviceidW,           CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
555     { prop_drivetypeW,          CIM_UINT32, VT_I4 },
556     { prop_filesystemW,         CIM_STRING|COL_FLAG_DYNAMIC },
557     { prop_freespaceW,          CIM_UINT64 },
558     { prop_nameW,               CIM_STRING|COL_FLAG_DYNAMIC },
559     { prop_sizeW,               CIM_UINT64 },
560     { prop_volumenameW,         CIM_STRING|COL_FLAG_DYNAMIC },
561     { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC }
562 };
563 static const struct column col_networkadapter[] =
564 {
565     { prop_adaptertypeW,         CIM_STRING },
566     { prop_deviceidW,            CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
567     { prop_indexW,               CIM_UINT32, VT_I4 },
568     { prop_interfaceindexW,      CIM_UINT32, VT_I4 },
569     { prop_macaddressW,          CIM_STRING|COL_FLAG_DYNAMIC },
570     { prop_manufacturerW,        CIM_STRING },
571     { prop_nameW,                CIM_STRING|COL_FLAG_DYNAMIC },
572     { prop_netconnectionstatusW, CIM_UINT16, VT_I4 },
573     { prop_physicaladapterW,     CIM_BOOLEAN },
574     { prop_pnpdeviceidW,         CIM_STRING },
575     { prop_speedW,               CIM_UINT64 }
576 };
577 static const struct column col_networkadapterconfig[] =
578 {
579     { prop_defaultipgatewayW,     CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
580     { prop_descriptionW,          CIM_STRING|COL_FLAG_DYNAMIC },
581     { prop_dhcpenabledW,          CIM_BOOLEAN },
582     { prop_dnshostnameW,          CIM_STRING|COL_FLAG_DYNAMIC },
583     { prop_dnsserversearchorderW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
584     { prop_indexW,                CIM_UINT32|COL_FLAG_KEY, VT_I4 },
585     { prop_ipaddressW,            CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
586     { prop_ipconnectionmetricW,   CIM_UINT32, VT_I4 },
587     { prop_ipenabledW,            CIM_BOOLEAN },
588     { prop_ipsubnet,              CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
589     { prop_macaddressW,           CIM_STRING|COL_FLAG_DYNAMIC },
590     { prop_settingidW,            CIM_STRING|COL_FLAG_DYNAMIC }
591 };
592 static const struct column col_os[] =
593 {
594     { prop_buildnumberW,            CIM_STRING|COL_FLAG_DYNAMIC },
595     { prop_captionW,                CIM_STRING|COL_FLAG_DYNAMIC },
596     { prop_codesetW,                CIM_STRING|COL_FLAG_DYNAMIC },
597     { prop_countrycodeW,            CIM_STRING|COL_FLAG_DYNAMIC },
598     { prop_csdversionW,             CIM_STRING|COL_FLAG_DYNAMIC },
599     { prop_freephysicalmemoryW,     CIM_UINT64 },
600     { prop_installdateW,            CIM_DATETIME },
601     { prop_lastbootuptimeW,         CIM_DATETIME|COL_FLAG_DYNAMIC },
602     { prop_localdatetimeW,          CIM_DATETIME|COL_FLAG_DYNAMIC },
603     { prop_localeW,                 CIM_STRING|COL_FLAG_DYNAMIC },
604     { prop_nameW,                   CIM_STRING|COL_FLAG_DYNAMIC },
605     { prop_osarchitectureW,         CIM_STRING },
606     { prop_oslanguageW,             CIM_UINT32, VT_I4 },
607     { prop_osproductsuiteW,         CIM_UINT32, VT_I4 },
608     { prop_ostypeW,                 CIM_UINT16, VT_I4 },
609     { prop_primaryW,                CIM_BOOLEAN },
610     { prop_serialnumberW,           CIM_STRING },
611     { prop_servicepackmajorW,       CIM_UINT16, VT_I4 },
612     { prop_servicepackminorW,       CIM_UINT16, VT_I4 },
613     { prop_suitemaskW,              CIM_UINT32, VT_I4 },
614     { prop_systemdirectoryW,        CIM_STRING|COL_FLAG_DYNAMIC },
615     { prop_totalvirtualmemorysizeW, CIM_UINT64 },
616     { prop_totalvisiblememorysizeW, CIM_UINT64 },
617     { prop_versionW,                CIM_STRING|COL_FLAG_DYNAMIC }
618 };
619 static const struct column col_param[] =
620 {
621     { prop_classW,        CIM_STRING },
622     { prop_methodW,       CIM_STRING },
623     { prop_directionW,    CIM_SINT32 },
624     { prop_parameterW,    CIM_STRING },
625     { prop_typeW,         CIM_UINT32 },
626     { prop_varianttypeW,  CIM_UINT32 },
627     { prop_defaultvalueW, CIM_UINT32 }
628 };
629 static const struct column col_physicalmedia[] =
630 {
631     { prop_serialnumberW,       CIM_STRING },
632     { prop_tagW,                CIM_STRING }
633 };
634 static const struct column col_physicalmemory[] =
635 {
636     { prop_capacityW,   CIM_UINT64 },
637     { prop_memorytypeW, CIM_UINT16, VT_I4 }
638 };
639 static const struct column col_pnpentity[] =
640 {
641     { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC },
642 };
643 static const struct column col_printer[] =
644 {
645     { prop_attributesW,           CIM_UINT32 },
646     { prop_deviceidW,             CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
647     { prop_drivernameW,           CIM_STRING|COL_FLAG_DYNAMIC },
648     { prop_horizontalresolutionW, CIM_UINT32 },
649     { prop_localW,                CIM_BOOLEAN },
650     { prop_locationW,             CIM_STRING|COL_FLAG_DYNAMIC },
651     { prop_nameW,                 CIM_STRING|COL_FLAG_DYNAMIC },
652     { prop_networkW,              CIM_BOOLEAN },
653     { prop_portnameW,             CIM_STRING|COL_FLAG_DYNAMIC },
654 };
655 static const struct column col_process[] =
656 {
657     { prop_captionW,        CIM_STRING|COL_FLAG_DYNAMIC },
658     { prop_commandlineW,    CIM_STRING|COL_FLAG_DYNAMIC },
659     { prop_descriptionW,    CIM_STRING|COL_FLAG_DYNAMIC },
660     { prop_handleW,         CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
661     { prop_nameW,           CIM_STRING|COL_FLAG_DYNAMIC },
662     { prop_pprocessidW,     CIM_UINT32, VT_I4 },
663     { prop_processidW,      CIM_UINT32, VT_I4 },
664     { prop_threadcountW,    CIM_UINT32, VT_I4 },
665     { prop_workingsetsizeW, CIM_UINT64 },
666     /* methods */
667     { method_getownerW,     CIM_FLAG_ARRAY|COL_FLAG_METHOD }
668 };
669 static const struct column col_processor[] =
670 {
671     { prop_addresswidthW,         CIM_UINT16, VT_I4 },
672     { prop_architectureW,         CIM_UINT16, VT_I4 },
673     { prop_captionW,              CIM_STRING|COL_FLAG_DYNAMIC },
674     { prop_cpustatusW,            CIM_UINT16 },
675     { prop_currentclockspeedW,    CIM_UINT32, VT_I4 },
676     { prop_datawidthW,            CIM_UINT16, VT_I4 },
677     { prop_descriptionW,          CIM_STRING|COL_FLAG_DYNAMIC },
678     { prop_deviceidW,             CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
679     { prop_familyW,               CIM_UINT16, VT_I4 },
680     { prop_levelW,                CIM_UINT16, VT_I4 },
681     { prop_manufacturerW,         CIM_STRING|COL_FLAG_DYNAMIC },
682     { prop_maxclockspeedW,        CIM_UINT32, VT_I4 },
683     { prop_nameW,                 CIM_STRING|COL_FLAG_DYNAMIC },
684     { prop_numcoresW,             CIM_UINT32, VT_I4 },
685     { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
686     { prop_processoridW,          CIM_STRING|COL_FLAG_DYNAMIC },
687     { prop_processortypeW,        CIM_UINT16, VT_I4 },
688     { prop_revisionW,             CIM_UINT16, VT_I4 },
689     { prop_uniqueidW,             CIM_STRING },
690     { prop_versionW,              CIM_STRING|COL_FLAG_DYNAMIC }
691 };
692 static const struct column col_qualifier[] =
693 {
694     { prop_classW,    CIM_STRING },
695     { prop_memberW,   CIM_STRING },
696     { prop_typeW,     CIM_UINT32 },
697     { prop_flavorW,   CIM_SINT32 },
698     { prop_nameW,     CIM_STRING },
699     { prop_intvalueW, CIM_SINT32 },
700     { prop_strvalueW, CIM_STRING }
701 };
702 static const struct column col_service[] =
703 {
704     { prop_acceptpauseW,      CIM_BOOLEAN },
705     { prop_acceptstopW,       CIM_BOOLEAN },
706     { prop_displaynameW,      CIM_STRING|COL_FLAG_DYNAMIC },
707     { prop_nameW,             CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
708     { prop_processidW,        CIM_UINT32 },
709     { prop_servicetypeW,      CIM_STRING },
710     { prop_startmodeW,        CIM_STRING },
711     { prop_stateW,            CIM_STRING },
712     { prop_systemnameW,       CIM_STRING|COL_FLAG_DYNAMIC },
713     /* methods */
714     { method_pauseserviceW,   CIM_FLAG_ARRAY|COL_FLAG_METHOD },
715     { method_resumeserviceW,  CIM_FLAG_ARRAY|COL_FLAG_METHOD },
716     { method_startserviceW,   CIM_FLAG_ARRAY|COL_FLAG_METHOD },
717     { method_stopserviceW,    CIM_FLAG_ARRAY|COL_FLAG_METHOD }
718 };
719 static const struct column col_sid[] =
720 {
721     { prop_accountnameW,            CIM_STRING|COL_FLAG_DYNAMIC },
722     { prop_binaryrepresentationW,   CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
723     { prop_referenceddomainnameW,   CIM_STRING|COL_FLAG_DYNAMIC },
724     { prop_sidW,                    CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
725     { prop_sidlengthW,              CIM_UINT32 }
726 };
727 static const struct column col_sounddevice[] =
728 {
729     { prop_nameW,        CIM_STRING },
730     { prop_productnameW, CIM_STRING },
731     { prop_statusinfoW,  CIM_UINT16, VT_I4 }
732 };
733 static const struct column col_stdregprov[] =
734 {
735     { method_createkeyW,      CIM_FLAG_ARRAY|COL_FLAG_METHOD },
736     { method_enumkeyW,        CIM_FLAG_ARRAY|COL_FLAG_METHOD },
737     { method_enumvaluesW,     CIM_FLAG_ARRAY|COL_FLAG_METHOD },
738     { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
739 };
740 static const struct column col_systemenclosure[] =
741 {
742     { prop_captionW,      CIM_STRING },
743     { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY },
744     { prop_descriptionW,  CIM_STRING },
745     { prop_lockpresentW,  CIM_BOOLEAN },
746     { prop_manufacturerW, CIM_STRING },
747     { prop_nameW,         CIM_STRING },
748     { prop_tagW,          CIM_STRING },
749 };
750 static const struct column col_systemsecurity[] =
751 {
752     { method_getsdW,                    CIM_FLAG_ARRAY|COL_FLAG_METHOD },
753     { method_setsdW,                    CIM_FLAG_ARRAY|COL_FLAG_METHOD },
754 };
755 
756 #ifndef __REACTOS__
757 static const struct column col_videocontroller[] =
758 {
759     { prop_adapterdactypeW,         CIM_STRING },
760     { prop_adapterramW,             CIM_UINT32, VT_I4 },
761     { prop_availabilityW,           CIM_UINT16 },
762     { prop_captionW,                CIM_STRING|COL_FLAG_DYNAMIC },
763     { prop_configmanagererrorcodeW, CIM_UINT32, VT_I4 },
764     { prop_currentbitsperpixelW,    CIM_UINT32, VT_I4 },
765     { prop_currenthorizontalresW,   CIM_UINT32, VT_I4 },
766     { prop_currentrefreshrateW,     CIM_UINT32, VT_I4 },
767     { prop_currentscanmodeW,        CIM_UINT16, VT_I4 },
768     { prop_currentverticalresW,     CIM_UINT32, VT_I4 },
769     { prop_descriptionW,            CIM_STRING|COL_FLAG_DYNAMIC },
770     { prop_deviceidW,               CIM_STRING|COL_FLAG_KEY },
771     { prop_driverdateW,             CIM_DATETIME },
772     { prop_driverversionW,          CIM_STRING },
773     { prop_installeddisplaydriversW,CIM_STRING },
774     { prop_nameW,                   CIM_STRING|COL_FLAG_DYNAMIC },
775     { prop_pnpdeviceidW,            CIM_STRING|COL_FLAG_DYNAMIC },
776     { prop_statusW,                 CIM_STRING },
777     { prop_videoarchitectureW,      CIM_UINT16, VT_I4 },
778     { prop_videomemorytypeW,        CIM_UINT16, VT_I4 },
779     { prop_videomodedescriptionW,   CIM_STRING|COL_FLAG_DYNAMIC },
780     { prop_videoprocessorW,         CIM_STRING|COL_FLAG_DYNAMIC },
781 };
782 #endif
783 
784 static const WCHAR baseboard_manufacturerW[] =
785     {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0};
786 static const WCHAR baseboard_serialnumberW[] =
787     {'N','o','n','e',0};
788 static const WCHAR baseboard_tagW[] =
789     {'B','a','s','e',' ','B','o','a','r','d',0};
790 static const WCHAR baseboard_versionW[] =
791     {'1','.','0',0};
792 static const WCHAR bios_descriptionW[] =
793     {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0};
794 static const WCHAR bios_manufacturerW[] =
795     {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
796 static const WCHAR bios_nameW[] =
797     {'W','I','N','E',' ','B','I','O','S',0};
798 static const WCHAR bios_releasedateW[] =
799     {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
800 static const WCHAR bios_serialnumberW[] =
801     {'0',0};
802 static const WCHAR bios_smbiosbiosversionW[] =
803     {'W','i','n','e',0};
804 static const WCHAR bios_versionW[] =
805     {'W','I','N','E',' ',' ',' ','-',' ','1',0};
806 static const WCHAR cdromdrive_mediatypeW[] =
807     {'C','D','-','R','O','M',0};
808 static const WCHAR cdromdrive_nameW[] =
809     {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0};
810 static const WCHAR cdromdrive_pnpdeviceidW[]=
811     {'I','D','E','\\','C','D','R','O','M','W','I','N','E','_','C','D','-','R','O','M',
812      '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_',
813      '_','_','_','_','_','_','_','1','.','0','_','_','_','_','_','\\','5','&','3','A','2',
814      'A','5','8','5','4','&','0','&','1','.','0','.','0',0};
815 static const WCHAR compsys_descriptionW[] =
816     {'A','T','/','A','T',' ','C','O','M','P','A','T','I','B','L','E',0};
817 static const WCHAR compsys_domainW[] =
818     {'W','O','R','K','G','R','O','U','P',0};
819 static const WCHAR compsys_manufacturerW[] =
820     {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
821 static const WCHAR compsys_modelW[] =
822     {'W','i','n','e',0};
823 static const WCHAR compsysproduct_identifyingnumberW[] =
824     {'0',0};
825 static const WCHAR compsysproduct_nameW[] =
826     {'W','i','n','e',0};
827 static const WCHAR compsysproduct_uuidW[] =
828     {'d','e','a','d','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-',
829      'd','e','a','d','d','e','a','d','d','e','a','d',0};
830 static const WCHAR compsysproduct_vendorW[] =
831     {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
832 static const WCHAR compsysproduct_versionW[] =
833     {'1','.','0',0};
834 static const WCHAR diskdrive_interfacetypeW[] =
835     {'I','D','E',0};
836 static const WCHAR diskdrive_manufacturerW[] =
837     {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0};
838 static const WCHAR diskdrive_mediatype_fixedW[] =
839     {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0};
840 static const WCHAR diskdrive_mediatype_removableW[] =
841     {'R','e','m','o','v','a','b','l','e',' ','m','e','d','i','a',0};
842 static const WCHAR diskdrive_modelW[] =
843     {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0};
844 static const WCHAR diskdrive_pnpdeviceidW[] =
845     {'I','D','E','\\','D','i','s','k','\\','V','E','N','_','W','I','N','E',0};
846 static const WCHAR diskdrive_serialW[] =
847     {'W','I','N','E','H','D','I','S','K',0};
848 static const WCHAR networkadapter_pnpdeviceidW[]=
849     {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&',
850      'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\',
851      '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0};
852 static const WCHAR os_32bitW[] =
853     {'3','2','-','b','i','t',0};
854 static const WCHAR os_64bitW[] =
855     {'6','4','-','b','i','t',0};
856 static const WCHAR os_installdateW[] =
857     {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
858 static const WCHAR os_serialnumberW[] =
859     {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0};
860 static const WCHAR physicalmedia_tagW[] =
861     {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0};
862 static const WCHAR sounddevice_productnameW[] =
863     {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
864 static const WCHAR systemenclosure_systemenclosureW[] =
865     {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',0};
866 static const WCHAR systemenclosure_tagW[] =
867     {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',' ','0',0};
868 static const WCHAR systemenclosure_manufacturerW[] =
869     {'W','i','n','e',0};
870 #ifndef __REACTOS__
871 static const WCHAR videocontroller_dactypeW[] =
872     {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0};
873 static const WCHAR videocontroller_deviceidW[] =
874     {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0};
875 static const WCHAR videocontroller_driverdateW[] =
876     {'2','0','1','7','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
877 static const WCHAR videocontroller_driverversionW[] =
878     {'1','.','0',0};
879 static const WCHAR videocontroller_statusW[] =
880     {'O','K',0};
881 #endif
882 
883 #include "pshpack1.h"
884 struct record_baseboard
885 {
886     const WCHAR *manufacturer;
887     const WCHAR *model;
888     const WCHAR *name;
889     const WCHAR *product;
890     const WCHAR *serialnumber;
891     const WCHAR *tag;
892     const WCHAR *version;
893 };
894 struct record_bios
895 {
896     const WCHAR *description;
897     const WCHAR *identificationcode;
898     const WCHAR *manufacturer;
899     const WCHAR *name;
900     const WCHAR *releasedate;
901     const WCHAR *serialnumber;
902     const WCHAR *smbiosbiosversion;
903     UINT16       smbiosmajorversion;
904     UINT16       smbiosminorversion;
905     const WCHAR *version;
906 };
907 struct record_cdromdrive
908 {
909     const WCHAR *device_id;
910     const WCHAR *drive;
911     const WCHAR *mediatype;
912     const WCHAR *name;
913     const WCHAR *pnpdevice_id;
914 };
915 struct record_computersystem
916 {
917     const WCHAR *description;
918     const WCHAR *domain;
919     UINT16       domainrole;
920     const WCHAR *manufacturer;
921     const WCHAR *model;
922     const WCHAR *name;
923     UINT32       num_logical_processors;
924     UINT32       num_processors;
925     UINT64       total_physical_memory;
926     const WCHAR *username;
927 };
928 struct record_computersystemproduct
929 {
930     const WCHAR *identifyingnumber;
931     const WCHAR *name;
932     const WCHAR *skunumber;
933     const WCHAR *uuid;
934     const WCHAR *vendor;
935     const WCHAR *version;
936 };
937 struct record_datafile
938 {
939     const WCHAR *name;
940     const WCHAR *version;
941 };
942 struct record_desktopmonitor
943 {
944     UINT32       pixelsperxlogicalinch;
945 };
946 struct record_directory
947 {
948     UINT32       accessmask;
949     const WCHAR *name;
950 };
951 struct record_diskdrive
952 {
953     const WCHAR *device_id;
954     UINT32       index;
955     const WCHAR *interfacetype;
956     const WCHAR *manufacturer;
957     const WCHAR *mediatype;
958     const WCHAR *model;
959     const WCHAR *pnpdevice_id;
960     const WCHAR *serialnumber;
961     UINT64       size;
962 };
963 struct record_diskpartition
964 {
965     int          bootable;
966     int          bootpartition;
967     const WCHAR *device_id;
968     UINT32       diskindex;
969     UINT32       index;
970     const WCHAR *pnpdevice_id;
971     UINT64       size;
972     UINT64       startingoffset;
973     const WCHAR *type;
974 };
975 struct record_ip4routetable
976 {
977     const WCHAR *destination;
978     INT32        interfaceindex;
979     const WCHAR *nexthop;
980 };
981 struct record_logicaldisk
982 {
983     const WCHAR *device_id;
984     UINT32       drivetype;
985     const WCHAR *filesystem;
986     UINT64       freespace;
987     const WCHAR *name;
988     UINT64       size;
989     const WCHAR *volumename;
990     const WCHAR *volumeserialnumber;
991 };
992 struct record_networkadapter
993 {
994     const WCHAR *adaptertype;
995     const WCHAR *device_id;
996     UINT32       index;
997     UINT32       interface_index;
998     const WCHAR *mac_address;
999     const WCHAR *manufacturer;
1000     const WCHAR *name;
1001     UINT16       netconnection_status;
1002     int          physicaladapter;
1003     const WCHAR *pnpdevice_id;
1004     UINT64       speed;
1005 };
1006 struct record_networkadapterconfig
1007 {
1008     const struct array *defaultipgateway;
1009     const WCHAR        *description;
1010     int                 dhcpenabled;
1011     const WCHAR        *dnshostname;
1012     const struct array *dnsserversearchorder;
1013     UINT32              index;
1014     const struct array *ipaddress;
1015     UINT32              ipconnectionmetric;
1016     int                 ipenabled;
1017     const struct array *ipsubnet;
1018     const WCHAR        *mac_address;
1019     const WCHAR        *settingid;
1020 };
1021 struct record_operatingsystem
1022 {
1023     const WCHAR *buildnumber;
1024     const WCHAR *caption;
1025     const WCHAR *codeset;
1026     const WCHAR *countrycode;
1027     const WCHAR *csdversion;
1028     UINT64       freephysicalmemory;
1029     const WCHAR *installdate;
1030     const WCHAR *lastbootuptime;
1031     const WCHAR *localdatetime;
1032     const WCHAR *locale;
1033     const WCHAR *name;
1034     const WCHAR *osarchitecture;
1035     UINT32       oslanguage;
1036     UINT32       osproductsuite;
1037     UINT16       ostype;
1038     int          primary;
1039     const WCHAR *serialnumber;
1040     UINT16       servicepackmajor;
1041     UINT16       servicepackminor;
1042     UINT32       suitemask;
1043     const WCHAR *systemdirectory;
1044     UINT64       totalvirtualmemorysize;
1045     UINT64       totalvisiblememorysize;
1046     const WCHAR *version;
1047 };
1048 struct record_param
1049 {
1050     const WCHAR *class;
1051     const WCHAR *method;
1052     INT32        direction;
1053     const WCHAR *parameter;
1054     UINT32       type;
1055     UINT32       varianttype;
1056     UINT32       defaultvalue;
1057 };
1058 struct record_physicalmedia
1059 {
1060     const WCHAR *serialnumber;
1061     const WCHAR *tag;
1062 };
1063 struct record_physicalmemory
1064 {
1065     UINT64 capacity;
1066     UINT16 memorytype;
1067 };
1068 struct record_pnpentity
1069 {
1070     const WCHAR *device_id;
1071 };
1072 struct record_printer
1073 {
1074     UINT32       attributes;
1075     const WCHAR *device_id;
1076     const WCHAR *drivername;
1077     UINT32       horizontalresolution;
1078     int          local;
1079     const WCHAR *location;
1080     const WCHAR *name;
1081     int          network;
1082     const WCHAR *portname;
1083 };
1084 struct record_process
1085 {
1086     const WCHAR *caption;
1087     const WCHAR *commandline;
1088     const WCHAR *description;
1089     const WCHAR *handle;
1090     const WCHAR *name;
1091     UINT32       pprocess_id;
1092     UINT32       process_id;
1093     UINT32       thread_count;
1094     UINT64       workingsetsize;
1095     /* methods */
1096     class_method *get_owner;
1097 };
1098 struct record_processor
1099 {
1100     UINT16       addresswidth;
1101     UINT16       architecture;
1102     const WCHAR *caption;
1103     UINT16       cpu_status;
1104     UINT32       currentclockspeed;
1105     UINT16       datawidth;
1106     const WCHAR *description;
1107     const WCHAR *device_id;
1108     UINT16       family;
1109     UINT16       level;
1110     const WCHAR *manufacturer;
1111     UINT32       maxclockspeed;
1112     const WCHAR *name;
1113     UINT32       num_cores;
1114     UINT32       num_logical_processors;
1115     const WCHAR *processor_id;
1116     UINT16       processortype;
1117     UINT16       revision;
1118     const WCHAR *unique_id;
1119     const WCHAR *version;
1120 };
1121 struct record_qualifier
1122 {
1123     const WCHAR *class;
1124     const WCHAR *member;
1125     UINT32       type;
1126     INT32        flavor;
1127     const WCHAR *name;
1128     INT32        intvalue;
1129     const WCHAR *strvalue;
1130 };
1131 struct record_service
1132 {
1133     int          accept_pause;
1134     int          accept_stop;
1135     const WCHAR *displayname;
1136     const WCHAR *name;
1137     UINT32       process_id;
1138     const WCHAR *servicetype;
1139     const WCHAR *startmode;
1140     const WCHAR *state;
1141     const WCHAR *systemname;
1142     /* methods */
1143     class_method *pause_service;
1144     class_method *resume_service;
1145     class_method *start_service;
1146     class_method *stop_service;
1147 };
1148 struct record_sid
1149 {
1150     const WCHAR *accountname;
1151     const struct array *binaryrepresentation;
1152     const WCHAR *referenceddomainname;
1153     const WCHAR *sid;
1154     UINT32       sidlength;
1155 };
1156 struct record_sounddevice
1157 {
1158     const WCHAR *name;
1159     const WCHAR *productname;
1160     UINT16       statusinfo;
1161 };
1162 struct record_stdregprov
1163 {
1164     class_method *createkey;
1165     class_method *enumkey;
1166     class_method *enumvalues;
1167     class_method *getstringvalue;
1168 };
1169 struct record_systemsecurity
1170 {
1171     class_method *getsd;
1172     class_method *setsd;
1173 };
1174 struct record_systemenclosure
1175 {
1176     const WCHAR *caption;
1177     const struct array *chassistypes;
1178     const WCHAR *description;
1179     int         lockpresent;
1180     const WCHAR *manufacturer;
1181     const WCHAR *name;
1182     const WCHAR *tag;
1183 };
1184 struct record_videocontroller
1185 {
1186     const WCHAR *adapter_dactype;
1187     UINT32       adapter_ram;
1188     UINT16       availability;
1189     const WCHAR *caption;
1190     UINT32       config_errorcode;
1191     UINT32       current_bitsperpixel;
1192     UINT32       current_horizontalres;
1193     UINT32       current_refreshrate;
1194     UINT16       current_scanmode;
1195     UINT32       current_verticalres;
1196     const WCHAR *description;
1197     const WCHAR *device_id;
1198     const WCHAR *driverdate;
1199     const WCHAR *driverversion;
1200     const WCHAR *installeddriver;
1201     const WCHAR *name;
1202     const WCHAR *pnpdevice_id;
1203     const WCHAR *status;
1204     UINT16       videoarchitecture;
1205     UINT16       videomemorytype;
1206     const WCHAR *videomodedescription;
1207     const WCHAR *videoprocessor;
1208 };
1209 #include "poppack.h"
1210 
1211 static const struct record_baseboard data_baseboard[] =
1212 {
1213     { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW }
1214 };
1215 static const struct record_bios data_bios[] =
1216 {
1217     { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW,
1218       bios_smbiosbiosversionW, 1, 0, bios_versionW }
1219 };
1220 static const struct record_param data_param[] =
1221 {
1222     { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1223     { class_processW, method_getownerW, -1, param_userW, CIM_STRING },
1224     { class_processW, method_getownerW, -1, param_domainW, CIM_STRING },
1225     { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1226     { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1227     { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1228     { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1229     { class_stdregprovW, method_createkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1230     { class_stdregprovW, method_createkeyW, 1, param_subkeynameW, CIM_STRING },
1231     { class_stdregprovW, method_createkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1232     { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1233     { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING },
1234     { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1235     { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
1236     { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1237     { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING },
1238     { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1239     { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
1240     { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY },
1241     { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1242     { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING },
1243     { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING },
1244     { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1245     { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING },
1246     { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1247     { class_systemsecurityW, method_getsdW, -1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
1248     { class_systemsecurityW, method_setsdW, 1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
1249     { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1250 };
1251 
1252 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1253                    WBEM_FLAVOR_ORIGIN_PROPAGATED)
1254 
1255 static const struct record_physicalmedia data_physicalmedia[] =
1256 {
1257     { diskdrive_serialW, physicalmedia_tagW }
1258 };
1259 static const struct record_qualifier data_qualifier[] =
1260 {
1261     { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 },
1262     { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 }
1263 };
1264 static const struct record_sounddevice data_sounddevice[] =
1265 {
1266     { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
1267 };
1268 static const struct record_stdregprov data_stdregprov[] =
1269 {
1270     { reg_create_key, reg_enum_key, reg_enum_values, reg_get_stringvalue }
1271 };
1272 static UINT16 systemenclosure_chassistypes[] =
1273 {
1274     1,
1275 };
1276 static const struct array systemenclosure_chassistypes_array =
1277 {
1278     ARRAY_SIZE(systemenclosure_chassistypes),
1279     &systemenclosure_chassistypes
1280 };
1281 static const struct record_systemenclosure data_systemenclosure[] =
1282 {
1283     {
1284         systemenclosure_systemenclosureW,
1285         &systemenclosure_chassistypes_array,
1286         systemenclosure_systemenclosureW,
1287         FALSE,
1288         systemenclosure_manufacturerW,
1289         systemenclosure_systemenclosureW,
1290         systemenclosure_tagW,
1291     }
1292 };
1293 static const struct record_systemsecurity data_systemsecurity[] =
1294 {
1295     { security_get_sd, security_set_sd }
1296 };
1297 
1298 /* check if row matches condition and update status */
1299 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
1300 {
1301     LONGLONG val;
1302     UINT type;
1303 
1304     if (!cond)
1305     {
1306         *status = FILL_STATUS_UNFILTERED;
1307         return TRUE;
1308     }
1309     if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1310     {
1311         *status = FILL_STATUS_FAILED;
1312         return FALSE;
1313     }
1314     *status = FILL_STATUS_FILTERED;
1315     return val != 0;
1316 }
1317 
1318 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
1319 {
1320     if (!table->num_rows_allocated)
1321     {
1322         if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE;
1323         table->num_rows_allocated = row_count;
1324         return TRUE;
1325     }
1326     if (row_count > table->num_rows_allocated)
1327     {
1328         BYTE *data;
1329         UINT count = max( row_count, table->num_rows_allocated * 2 );
1330         if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE;
1331         table->data = data;
1332         table->num_rows_allocated = count;
1333     }
1334     return TRUE;
1335 }
1336 
1337 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1338 {
1339     static const WCHAR fmtW[] = {'%','c',':',0};
1340     WCHAR drive[3], root[] = {'A',':','\\',0};
1341     struct record_cdromdrive *rec;
1342     UINT i, row = 0, offset = 0;
1343     DWORD drives = GetLogicalDrives();
1344     enum fill_status status = FILL_STATUS_UNFILTERED;
1345 
1346     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1347 
1348     for (i = 0; i < 26; i++)
1349     {
1350         if (drives & (1 << i))
1351         {
1352             root[0] = 'A' + i;
1353             if (GetDriveTypeW( root ) != DRIVE_CDROM)
1354                 continue;
1355 
1356             if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1357 
1358             rec = (struct record_cdromdrive *)(table->data + offset);
1359             rec->device_id    = cdromdrive_pnpdeviceidW;
1360             sprintfW( drive, fmtW, 'A' + i );
1361             rec->drive        = heap_strdupW( drive );
1362             rec->mediatype    = cdromdrive_mediatypeW;
1363             rec->name         = cdromdrive_nameW;
1364             rec->pnpdevice_id = cdromdrive_pnpdeviceidW;
1365             if (!match_row( table, row, cond, &status ))
1366             {
1367                 free_row_values( table, row );
1368                 continue;
1369             }
1370             offset += sizeof(*rec);
1371             row++;
1372         }
1373     }
1374     TRACE("created %u rows\n", row);
1375     table->num_rows = row;
1376     return status;
1377 }
1378 
1379 static UINT get_processor_count(void)
1380 {
1381     SYSTEM_BASIC_INFORMATION info;
1382 
1383     if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1384     return info.NumberOfProcessors;
1385 }
1386 
1387 static UINT get_logical_processor_count( UINT *num_cores )
1388 {
1389     SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info;
1390     UINT i, j, count = 0;
1391     NTSTATUS status;
1392     ULONG len;
1393 
1394     if (num_cores) *num_cores = get_processor_count();
1395     status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len );
1396     if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1397 
1398     if (!(info = heap_alloc( len ))) return get_processor_count();
1399     status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len );
1400     if (status != STATUS_SUCCESS)
1401     {
1402         heap_free( info );
1403         return get_processor_count();
1404     }
1405     if (num_cores) *num_cores = 0;
1406     for (i = 0; i < len / sizeof(*info); i++)
1407     {
1408         if (info[i].Relationship == RelationProcessorCore)
1409         {
1410             for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++;
1411         }
1412         else if (info[i].Relationship == RelationProcessorPackage && num_cores)
1413         {
1414             for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) (*num_cores)++;
1415         }
1416     }
1417     heap_free( info );
1418     return count;
1419 }
1420 
1421 static UINT64 get_total_physical_memory(void)
1422 {
1423     MEMORYSTATUSEX status;
1424 
1425     status.dwLength = sizeof(status);
1426     if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1427     return status.ullTotalPhys;
1428 }
1429 
1430 static UINT64 get_available_physical_memory(void)
1431 {
1432     MEMORYSTATUSEX status;
1433 
1434     status.dwLength = sizeof(status);
1435     if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1436     return status.ullAvailPhys;
1437 }
1438 
1439 static WCHAR *get_computername(void)
1440 {
1441     WCHAR *ret;
1442     DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1443 
1444     if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1445     GetComputerNameW( ret, &size );
1446     return ret;
1447 }
1448 
1449 static WCHAR *get_username(void)
1450 {
1451     WCHAR *ret;
1452     DWORD compsize, usersize;
1453     DWORD size;
1454 
1455     compsize = 0;
1456     GetComputerNameW( NULL, &compsize );
1457     usersize = 0;
1458     GetUserNameW( NULL, &usersize );
1459     size = compsize + usersize; /* two null terminators account for the \ */
1460     if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1461     GetComputerNameW( ret, &compsize );
1462     ret[compsize] = '\\';
1463     GetUserNameW( ret + compsize + 1, &usersize );
1464     return ret;
1465 }
1466 
1467 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1468 {
1469     struct record_computersystem *rec;
1470     enum fill_status status = FILL_STATUS_UNFILTERED;
1471     UINT row = 0;
1472 
1473     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1474 
1475     rec = (struct record_computersystem *)table->data;
1476     rec->description            = compsys_descriptionW;
1477     rec->domain                 = compsys_domainW;
1478     rec->domainrole             = 0; /* standalone workstation */
1479     rec->manufacturer           = compsys_manufacturerW;
1480     rec->model                  = compsys_modelW;
1481     rec->name                   = get_computername();
1482     rec->num_logical_processors = get_logical_processor_count( NULL );
1483     rec->num_processors         = get_processor_count();
1484     rec->total_physical_memory  = get_total_physical_memory();
1485     rec->username               = get_username();
1486     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1487     else row++;
1488 
1489     TRACE("created %u rows\n", row);
1490     table->num_rows = row;
1491     return status;
1492 }
1493 
1494 static WCHAR *get_compsysproduct_uuid(void)
1495 {
1496 #ifdef __APPLE__
1497     unsigned char uuid[16];
1498     const struct timespec timeout = {1, 0};
1499     if (!gethostuuid( uuid, &timeout ))
1500     {
1501         static const WCHAR fmtW[] =
1502             {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
1503              '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
1504              '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0};
1505         WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) );
1506         if (!ret) return NULL;
1507         sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
1508                   uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] );
1509         return ret;
1510     }
1511 #endif
1512 #ifdef __linux__
1513     int file;
1514     if ((file = open( "/var/lib/dbus/machine-id", O_RDONLY )) != -1)
1515     {
1516         unsigned char buf[32];
1517         if (read( file, buf, sizeof(buf) ) == sizeof(buf))
1518         {
1519             unsigned int i, j;
1520             WCHAR *ret, *p;
1521 
1522             close( file );
1523             if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL;
1524             for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] );
1525             p[8] = '-';
1526             for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] );
1527             p[13] = '-';
1528             for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] );
1529             p[18] = '-';
1530             for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] );
1531             p[23] = '-';
1532             for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] );
1533             ret[i] = 0;
1534             return ret;
1535         }
1536         close( file );
1537     }
1538 #endif
1539     return heap_strdupW( compsysproduct_uuidW );
1540 }
1541 
1542 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1543 {
1544     struct record_computersystemproduct *rec;
1545     enum fill_status status = FILL_STATUS_UNFILTERED;
1546     UINT row = 0;
1547 
1548     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1549 
1550     rec = (struct record_computersystemproduct *)table->data;
1551     rec->identifyingnumber = compsysproduct_identifyingnumberW;
1552     rec->name              = compsysproduct_nameW;
1553     rec->skunumber         = NULL;
1554     rec->uuid              = get_compsysproduct_uuid();
1555     rec->vendor            = compsysproduct_vendorW;
1556     rec->version           = compsysproduct_versionW;
1557     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1558     else row++;
1559 
1560     TRACE("created %u rows\n", row);
1561     table->num_rows = row;
1562     return status;
1563 }
1564 
1565 struct dirstack
1566 {
1567     WCHAR **dirs;
1568     UINT   *len_dirs;
1569     UINT    num_dirs;
1570     UINT    num_allocated;
1571 };
1572 
1573 static struct dirstack *alloc_dirstack( UINT size )
1574 {
1575     struct dirstack *dirstack;
1576 
1577     if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL;
1578     if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size )))
1579     {
1580         heap_free( dirstack );
1581         return NULL;
1582     }
1583     if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size )))
1584     {
1585         heap_free( dirstack->dirs );
1586         heap_free( dirstack );
1587         return NULL;
1588     }
1589     dirstack->num_dirs = 0;
1590     dirstack->num_allocated = size;
1591     return dirstack;
1592 }
1593 
1594 static void clear_dirstack( struct dirstack *dirstack )
1595 {
1596     UINT i;
1597     for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] );
1598     dirstack->num_dirs = 0;
1599 }
1600 
1601 static void free_dirstack( struct dirstack *dirstack )
1602 {
1603     clear_dirstack( dirstack );
1604     heap_free( dirstack->dirs );
1605     heap_free( dirstack->len_dirs );
1606     heap_free( dirstack );
1607 }
1608 
1609 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1610 {
1611     UINT size, i = dirstack->num_dirs;
1612 
1613     if (!dir) return FALSE;
1614 
1615     if (i == dirstack->num_allocated)
1616     {
1617         WCHAR **tmp;
1618         UINT *len_tmp;
1619 
1620         size = dirstack->num_allocated * 2;
1621         if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1622         dirstack->dirs = tmp;
1623         if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1624         dirstack->len_dirs = len_tmp;
1625         dirstack->num_allocated = size;
1626     }
1627     dirstack->dirs[i] = dir;
1628     dirstack->len_dirs[i] = len;
1629     dirstack->num_dirs++;
1630     return TRUE;
1631 }
1632 
1633 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1634 {
1635     if (!dirstack->num_dirs)
1636     {
1637         *len = 0;
1638         return NULL;
1639     }
1640     dirstack->num_dirs--;
1641     *len = dirstack->len_dirs[dirstack->num_dirs];
1642     return dirstack->dirs[dirstack->num_dirs];
1643 }
1644 
1645 static const WCHAR *peek_dir( struct dirstack *dirstack )
1646 {
1647     if (!dirstack->num_dirs) return NULL;
1648     return dirstack->dirs[dirstack->num_dirs - 1];
1649 }
1650 
1651 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1652 {
1653     UINT i = 0;
1654     WCHAR *ret;
1655 
1656     if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1657     ret[i++] = drive;
1658     ret[i++] = ':';
1659     ret[i++] = '\\';
1660     if (path && len)
1661     {
1662         memcpy( ret + i, path, len * sizeof(WCHAR) );
1663         i += len;
1664         ret[i++] = '\\';
1665     }
1666     ret[i++] = '*';
1667     ret[i] = 0;
1668     return ret;
1669 }
1670 
1671 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1672 {
1673     UINT i = 0, len = 0;
1674     const WCHAR *p;
1675     WCHAR *ret;
1676 
1677     for (p = path; *p; p++)
1678     {
1679         if (*p == '\\') len += 2;
1680         else len++;
1681     };
1682     if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1683     ret[i++] = drive;
1684     ret[i++] = ':';
1685     ret[i++] = '\\';
1686     ret[i++] = '\\';
1687     for (p = path; *p; p++)
1688     {
1689         if (*p != '\\') ret[i++] = *p;
1690         else
1691         {
1692             ret[i++] = '\\';
1693             ret[i++] = '\\';
1694         }
1695     }
1696     ret[i] = 0;
1697     return ret;
1698 }
1699 
1700 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1701 {
1702     const WCHAR *p = path, *start;
1703     UINT len, i;
1704     WCHAR *ret;
1705 
1706     if (!isalphaW( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1707     start = path + 4;
1708     len = strlenW( start );
1709     p = start + len - 1;
1710     if (*p == '\\') return NULL;
1711 
1712     while (p >= start && *p != '\\') { len--; p--; };
1713     while (p >= start && *p == '\\') { len--; p--; };
1714 
1715     if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1716     for (i = 0, p = start; p < start + len; p++)
1717     {
1718         if (p[0] == '\\' && p[1] == '\\')
1719         {
1720             ret[i++] = '\\';
1721             p++;
1722         }
1723         else ret[i++] = *p;
1724     }
1725     ret[i] = 0;
1726     *ret_len = i;
1727     return ret;
1728 }
1729 
1730 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1731 {
1732     UINT i;
1733     for (i = 0; i < dirstack->num_dirs; i++) if (!strcmpW( dirstack->dirs[i], path )) return TRUE;
1734     return FALSE;
1735 }
1736 
1737 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1738 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1739 {
1740     const struct expr *left, *right;
1741 
1742     if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1743 
1744     left = cond->u.expr.left;
1745     right = cond->u.expr.right;
1746     if (cond->u.expr.op == OP_EQ)
1747     {
1748         UINT len;
1749         WCHAR *path;
1750         const WCHAR *str = NULL;
1751 
1752         if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1753             !strcmpW( left->u.propval->name, prop_nameW ) &&
1754             toupperW( right->u.sval[0] ) == toupperW( root ))
1755         {
1756             str = right->u.sval;
1757         }
1758         else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1759                  !strcmpW( right->u.propval->name, prop_nameW ) &&
1760                  toupperW( left->u.sval[0] ) == toupperW( root ))
1761         {
1762             str = left->u.sval;
1763         }
1764         if (str && (path = build_dirname( str, &len )))
1765         {
1766             if (seen_dir( dirstack, path ))
1767             {
1768                 heap_free( path );
1769                 return ++*count;
1770             }
1771             else if (push_dir( dirstack, path, len )) return ++*count;
1772             heap_free( path );
1773             return *count = 0;
1774         }
1775     }
1776     else if (cond->u.expr.op == OP_OR)
1777     {
1778         UINT left_count = 0, right_count = 0;
1779 
1780         if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
1781         if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
1782         return *count += left_count + right_count;
1783     }
1784     return *count = 0;
1785 }
1786 
1787 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
1788 {
1789     UINT len_path = 0, len_segment = strlenW( segment );
1790     WCHAR *ret;
1791 
1792     *len = 0;
1793     if (path) len_path = strlenW( path );
1794     if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
1795     if (path && len_path)
1796     {
1797         memcpy( ret, path, len_path * sizeof(WCHAR) );
1798         ret[len_path] = '\\';
1799         *len += len_path + 1;
1800     }
1801     memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
1802     *len += len_segment;
1803     ret[*len] = 0;
1804     return ret;
1805 }
1806 
1807 static WCHAR *get_file_version( const WCHAR *filename )
1808 {
1809     static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
1810     VS_FIXEDFILEINFO *info;
1811     DWORD size;
1812     void *block;
1813     WCHAR *ret;
1814 
1815     if (!(ret = heap_alloc( (4 * 5 + ARRAY_SIZE( fmtW )) * sizeof(WCHAR) ))) return NULL;
1816     if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size )))
1817     {
1818         heap_free( ret );
1819         return NULL;
1820     }
1821     if (!GetFileVersionInfoW( filename, 0, size, block ) ||
1822         !VerQueryValueW( block, slashW, (void **)&info, &size ))
1823     {
1824         heap_free( block );
1825         heap_free( ret );
1826         return NULL;
1827     }
1828     sprintfW( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
1829                          info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
1830     heap_free( block );
1831     return ret;
1832 }
1833 
1834 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
1835 {
1836     static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
1837     struct record_datafile *rec;
1838     UINT i, len, row = 0, offset = 0, num_expected_rows;
1839     WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
1840     DWORD drives = GetLogicalDrives();
1841     WIN32_FIND_DATAW data;
1842     HANDLE handle;
1843     struct dirstack *dirstack;
1844     enum fill_status status = FILL_STATUS_UNFILTERED;
1845 
1846     if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
1847 
1848     dirstack = alloc_dirstack(2);
1849 
1850     for (i = 0; i < 26; i++)
1851     {
1852         if (!(drives & (1 << i))) continue;
1853 
1854         root[0] = 'A' + i;
1855         if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1856 
1857         num_expected_rows = 0;
1858         if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1859 
1860         for (;;)
1861         {
1862             heap_free( glob );
1863             heap_free( path );
1864             path = pop_dir( dirstack, &len );
1865             if (!(glob = build_glob( root[0], path, len )))
1866             {
1867                 status = FILL_STATUS_FAILED;
1868                 goto done;
1869             }
1870             if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1871             {
1872                 do
1873                 {
1874                     if (!resize_table( table, row + 1, sizeof(*rec) ))
1875                     {
1876                         status = FILL_STATUS_FAILED;
1877                         FindClose( handle );
1878                         goto done;
1879                     }
1880                     if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue;
1881                     new_path = append_path( path, data.cFileName, &len );
1882 
1883                     if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1884                     {
1885                         if (push_dir( dirstack, new_path, len )) continue;
1886                         heap_free( new_path );
1887                         FindClose( handle );
1888                         status = FILL_STATUS_FAILED;
1889                         goto done;
1890                     }
1891                     rec = (struct record_datafile *)(table->data + offset);
1892                     rec->name    = build_name( root[0], new_path );
1893                     rec->version = get_file_version( rec->name );
1894                     if (!match_row( table, row, cond, &status ))
1895                     {
1896                         free_row_values( table, row );
1897                         continue;
1898                     }
1899                     else if (num_expected_rows && row == num_expected_rows - 1)
1900                     {
1901                         row++;
1902                         FindClose( handle );
1903                         status = FILL_STATUS_FILTERED;
1904                         goto done;
1905                     }
1906                     offset += sizeof(*rec);
1907                     row++;
1908                 }
1909                 while (FindNextFileW( handle, &data ));
1910                 FindClose( handle );
1911             }
1912             if (!peek_dir( dirstack )) break;
1913         }
1914     }
1915 
1916 done:
1917     free_dirstack( dirstack );
1918     heap_free( glob );
1919     heap_free( path );
1920 
1921     TRACE("created %u rows\n", row);
1922     table->num_rows = row;
1923     return status;
1924 }
1925 
1926 static UINT32 get_pixelsperxlogicalinch(void)
1927 {
1928     HDC hdc = GetDC( NULL );
1929     UINT32 ret;
1930 
1931     if (!hdc) return 96;
1932     ret = GetDeviceCaps( hdc, LOGPIXELSX );
1933     ReleaseDC( NULL, hdc );
1934     return ret;
1935 }
1936 
1937 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
1938 {
1939     struct record_desktopmonitor *rec;
1940     enum fill_status status = FILL_STATUS_UNFILTERED;
1941     UINT row = 0;
1942 
1943     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1944 
1945     rec = (struct record_desktopmonitor *)table->data;
1946     rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
1947 
1948     if (match_row( table, row, cond, &status )) row++;
1949 
1950     TRACE("created %u rows\n", row);
1951     table->num_rows = row;
1952     return status;
1953 }
1954 
1955 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
1956 {
1957     static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
1958     struct record_directory *rec;
1959     UINT i, len, row = 0, offset = 0, num_expected_rows;
1960     WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
1961     DWORD drives = GetLogicalDrives();
1962     WIN32_FIND_DATAW data;
1963     HANDLE handle;
1964     struct dirstack *dirstack;
1965     enum fill_status status = FILL_STATUS_UNFILTERED;
1966 
1967     if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
1968 
1969     dirstack = alloc_dirstack(2);
1970 
1971     for (i = 0; i < 26; i++)
1972     {
1973         if (!(drives & (1 << i))) continue;
1974 
1975         root[0] = 'A' + i;
1976         if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1977 
1978         num_expected_rows = 0;
1979         if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1980 
1981         for (;;)
1982         {
1983             heap_free( glob );
1984             heap_free( path );
1985             path = pop_dir( dirstack, &len );
1986             if (!(glob = build_glob( root[0], path, len )))
1987             {
1988                 status = FILL_STATUS_FAILED;
1989                 goto done;
1990             }
1991             if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1992             {
1993                 do
1994                 {
1995                     if (!resize_table( table, row + 1, sizeof(*rec) ))
1996                     {
1997                         FindClose( handle );
1998                         status = FILL_STATUS_FAILED;
1999                         goto done;
2000                     }
2001                     if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
2002                         !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW ))
2003                         continue;
2004 
2005                     new_path = append_path( path, data.cFileName, &len );
2006                     if (!(push_dir( dirstack, new_path, len )))
2007                     {
2008                         heap_free( new_path );
2009                         FindClose( handle );
2010                         status = FILL_STATUS_FAILED;
2011                         goto done;
2012                     }
2013                     rec = (struct record_directory *)(table->data + offset);
2014                     rec->accessmask = FILE_ALL_ACCESS;
2015                     rec->name       = build_name( root[0], new_path );
2016                     if (!match_row( table, row, cond, &status ))
2017                     {
2018                         free_row_values( table, row );
2019                         continue;
2020                     }
2021                     else if (num_expected_rows && row == num_expected_rows - 1)
2022                     {
2023                         row++;
2024                         FindClose( handle );
2025                         status = FILL_STATUS_FILTERED;
2026                         goto done;
2027                     }
2028                     offset += sizeof(*rec);
2029                     row++;
2030                 }
2031                 while (FindNextFileW( handle, &data ));
2032                 FindClose( handle );
2033             }
2034             if (!peek_dir( dirstack )) break;
2035         }
2036     }
2037 
2038 done:
2039     free_dirstack( dirstack );
2040     heap_free( glob );
2041     heap_free( path );
2042 
2043     TRACE("created %u rows\n", row);
2044     table->num_rows = row;
2045     return status;
2046 }
2047 
2048 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
2049 {
2050     WCHAR root[] = {'\\','\\','.','\\','A',':',0};
2051     ULARGE_INTEGER free;
2052     DISK_GEOMETRY_EX info;
2053     HANDLE handle;
2054     DWORD bytes_returned;
2055 
2056     free.QuadPart = 512 * 1024 * 1024;
2057     GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
2058 
2059     root[4] = dir[0];
2060     handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2061     if (handle != INVALID_HANDLE_VALUE)
2062     {
2063         if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
2064             *disksize = info.DiskSize.QuadPart;
2065         CloseHandle( handle );
2066     }
2067     return free.QuadPart;
2068 }
2069 
2070 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
2071 {
2072     static const WCHAR fmtW[] =
2073         {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','%','u',0};
2074     WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = {'A',':','\\',0};
2075     struct record_diskdrive *rec;
2076     UINT i, row = 0, offset = 0, index = 0, type;
2077     UINT64 size = 1024 * 1024 * 1024;
2078     DWORD drives = GetLogicalDrives();
2079     enum fill_status status = FILL_STATUS_UNFILTERED;
2080 
2081     if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
2082 
2083     for (i = 0; i < 26; i++)
2084     {
2085         if (drives & (1 << i))
2086         {
2087             root[0] = 'A' + i;
2088             type = GetDriveTypeW( root );
2089             if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2090                 continue;
2091 
2092             if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2093 
2094             rec = (struct record_diskdrive *)(table->data + offset);
2095             sprintfW( device_id, fmtW, index );
2096             rec->device_id     = heap_strdupW( device_id );
2097             rec->index         = index;
2098             rec->interfacetype = diskdrive_interfacetypeW;
2099             rec->manufacturer  = diskdrive_manufacturerW;
2100             if (type == DRIVE_FIXED)
2101                 rec->mediatype = diskdrive_mediatype_fixedW;
2102             else
2103                 rec->mediatype = diskdrive_mediatype_removableW;
2104             rec->model         = diskdrive_modelW;
2105             rec->pnpdevice_id  = diskdrive_pnpdeviceidW;
2106             rec->serialnumber  = diskdrive_serialW;
2107             get_freespace( root, &size );
2108             rec->size          = size;
2109             if (!match_row( table, row, cond, &status ))
2110             {
2111                 free_row_values( table, row );
2112                 continue;
2113             }
2114             offset += sizeof(*rec);
2115             index++;
2116             row++;
2117         }
2118     }
2119     TRACE("created %u rows\n", row);
2120     table->num_rows = row;
2121     return status;
2122 }
2123 
2124 static WCHAR *get_filesystem( const WCHAR *root )
2125 {
2126     static const WCHAR ntfsW[] = {'N','T','F','S',0};
2127     WCHAR buffer[MAX_PATH + 1];
2128 
2129     if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
2130         return heap_strdupW( buffer );
2131     return heap_strdupW( ntfsW );
2132 }
2133 
2134 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2135 {
2136     static const WCHAR fmtW[] =
2137         {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0};
2138     WCHAR device_id[32], root[] = {'A',':','\\',0};
2139     struct record_diskpartition *rec;
2140     UINT i, row = 0, offset = 0, type, index = 0;
2141     UINT64 size = 1024 * 1024 * 1024;
2142     DWORD drives = GetLogicalDrives();
2143     enum fill_status status = FILL_STATUS_UNFILTERED;
2144 
2145     if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2146 
2147     for (i = 0; i < 26; i++)
2148     {
2149         if (drives & (1 << i))
2150         {
2151             root[0] = 'A' + i;
2152             type = GetDriveTypeW( root );
2153             if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2154                 continue;
2155 
2156             if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2157 
2158             rec = (struct record_diskpartition *)(table->data + offset);
2159             rec->bootable       = (i == 2) ? -1 : 0;
2160             rec->bootpartition  = (i == 2) ? -1 : 0;
2161             sprintfW( device_id, fmtW, index );
2162             rec->device_id      = heap_strdupW( device_id );
2163             rec->diskindex      = index;
2164             rec->index          = 0;
2165             rec->pnpdevice_id   = heap_strdupW( device_id );
2166             get_freespace( root, &size );
2167             rec->size           = size;
2168             rec->startingoffset = 0;
2169             rec->type           = get_filesystem( root );
2170             if (!match_row( table, row, cond, &status ))
2171             {
2172                 free_row_values( table, row );
2173                 continue;
2174             }
2175             offset += sizeof(*rec);
2176             row++;
2177             index++;
2178         }
2179     }
2180     TRACE("created %u rows\n", row);
2181     table->num_rows = row;
2182     return status;
2183 }
2184 
2185 static WCHAR *get_ip4_string( DWORD addr )
2186 {
2187     static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
2188     WCHAR *ret;
2189 
2190     if (!(ret = heap_alloc( sizeof("ddd.ddd.ddd.ddd") * sizeof(WCHAR) ))) return NULL;
2191     sprintfW( ret, fmtW, (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2192     return ret;
2193 }
2194 
2195 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2196 {
2197     struct record_ip4routetable *rec;
2198     UINT i, row = 0, offset = 0, size = 0;
2199     MIB_IPFORWARDTABLE *forwards;
2200     enum fill_status status = FILL_STATUS_UNFILTERED;
2201 
2202     if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2203     if (!(forwards = heap_alloc( size ))) return FILL_STATUS_FAILED;
2204     if (GetIpForwardTable( forwards, &size, TRUE ))
2205     {
2206         heap_free( forwards );
2207         return FILL_STATUS_FAILED;
2208     }
2209     if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) ))
2210     {
2211         heap_free( forwards );
2212         return FILL_STATUS_FAILED;
2213     }
2214 
2215     for (i = 0; i < forwards->dwNumEntries; i++)
2216     {
2217         rec = (struct record_ip4routetable *)(table->data + offset);
2218 
2219         rec->destination    = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2220         rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2221         rec->nexthop        = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2222 
2223         if (!match_row( table, row, cond, &status ))
2224         {
2225             free_row_values( table, row );
2226             continue;
2227         }
2228         offset += sizeof(*rec);
2229         row++;
2230     }
2231     TRACE("created %u rows\n", row);
2232     table->num_rows = row;
2233 
2234     heap_free( forwards );
2235     return status;
2236 }
2237 
2238 static WCHAR *get_volumename( const WCHAR *root )
2239 {
2240     WCHAR buf[MAX_PATH + 1] = {0};
2241     GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 );
2242     return heap_strdupW( buf );
2243 }
2244 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2245 {
2246     static const WCHAR fmtW[] = {'%','0','8','X',0};
2247     DWORD serial = 0;
2248     WCHAR buffer[9];
2249 
2250     GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2251     sprintfW( buffer, fmtW, serial );
2252     return heap_strdupW( buffer );
2253 }
2254 
2255 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2256 {
2257     static const WCHAR fmtW[] = {'%','c',':',0};
2258     WCHAR device_id[3], root[] = {'A',':','\\',0};
2259     struct record_logicaldisk *rec;
2260     UINT i, row = 0, offset = 0, type;
2261     UINT64 size = 1024 * 1024 * 1024;
2262     DWORD drives = GetLogicalDrives();
2263     enum fill_status status = FILL_STATUS_UNFILTERED;
2264 
2265     if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2266 
2267     for (i = 0; i < 26; i++)
2268     {
2269         if (drives & (1 << i))
2270         {
2271             root[0] = 'A' + i;
2272             type = GetDriveTypeW( root );
2273             if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2274                 continue;
2275 
2276             if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2277 
2278             rec = (struct record_logicaldisk *)(table->data + offset);
2279             sprintfW( device_id, fmtW, 'A' + i );
2280             rec->device_id          = heap_strdupW( device_id );
2281             rec->drivetype          = type;
2282             rec->filesystem         = get_filesystem( root );
2283             rec->freespace          = get_freespace( root, &size );
2284             rec->name               = heap_strdupW( device_id );
2285             rec->size               = size;
2286             rec->volumename         = get_volumename( root );
2287             rec->volumeserialnumber = get_volumeserialnumber( root );
2288             if (!match_row( table, row, cond, &status ))
2289             {
2290                 free_row_values( table, row );
2291                 continue;
2292             }
2293             offset += sizeof(*rec);
2294             row++;
2295         }
2296     }
2297     TRACE("created %u rows\n", row);
2298     table->num_rows = row;
2299     return status;
2300 }
2301 
2302 static UINT16 get_connection_status( IF_OPER_STATUS status )
2303 {
2304     switch (status)
2305     {
2306     case IfOperStatusDown:
2307         return 0; /* Disconnected */
2308     case IfOperStatusUp:
2309         return 2; /* Connected */
2310     default:
2311         ERR("unhandled status %u\n", status);
2312         break;
2313     }
2314     return 0;
2315 }
2316 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2317 {
2318     static const WCHAR fmtW[] =
2319         {'%','0','2','x',':','%','0','2','x',':','%','0','2','x',':',
2320          '%','0','2','x',':','%','0','2','x',':','%','0','2','x',0};
2321     WCHAR *ret;
2322 
2323     if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL;
2324     sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2325     return ret;
2326 }
2327 static const WCHAR *get_adaptertype( DWORD type, int *physical )
2328 {
2329     static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0};
2330     static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0};
2331     static const WCHAR firewireW[] = {'1','3','9','4',0};
2332     static const WCHAR tunnelW[]   = {'T','u','n','n','e','l',0};
2333 
2334     switch (type)
2335     {
2336     case IF_TYPE_ETHERNET_CSMACD: *physical = -1; return ethernetW;
2337     case IF_TYPE_IEEE80211:       *physical = -1; return wirelessW;
2338     case IF_TYPE_IEEE1394:        *physical = -1; return firewireW;
2339     case IF_TYPE_TUNNEL:          *physical = 0; return tunnelW;
2340     default:                      *physical = 0; return NULL;
2341     }
2342 }
2343 
2344 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2345 {
2346     static const WCHAR fmtW[] = {'%','u',0};
2347     WCHAR device_id[11];
2348     struct record_networkadapter *rec;
2349     IP_ADAPTER_ADDRESSES *aa, *buffer;
2350     UINT row = 0, offset = 0, count = 0;
2351     DWORD size = 0, ret;
2352     int physical;
2353     enum fill_status status = FILL_STATUS_UNFILTERED;
2354 
2355     ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
2356     if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2357 
2358     if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2359     if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size ))
2360     {
2361         heap_free( buffer );
2362         return FILL_STATUS_FAILED;
2363     }
2364     for (aa = buffer; aa; aa = aa->Next)
2365     {
2366         if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2367     }
2368     if (!resize_table( table, count, sizeof(*rec) ))
2369     {
2370         heap_free( buffer );
2371         return FILL_STATUS_FAILED;
2372     }
2373     for (aa = buffer; aa; aa = aa->Next)
2374     {
2375         if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2376 
2377         rec = (struct record_networkadapter *)(table->data + offset);
2378         sprintfW( device_id, fmtW, aa->u.s.IfIndex );
2379         rec->adaptertype          = get_adaptertype( aa->IfType, &physical );
2380         rec->device_id            = heap_strdupW( device_id );
2381         rec->index                = aa->u.s.IfIndex;
2382         rec->interface_index      = aa->u.s.IfIndex;
2383         rec->mac_address          = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2384         rec->manufacturer         = compsys_manufacturerW;
2385         rec->name                 = heap_strdupW( aa->FriendlyName );
2386         rec->netconnection_status = get_connection_status( aa->OperStatus );
2387         rec->physicaladapter      = physical;
2388         rec->pnpdevice_id         = networkadapter_pnpdeviceidW;
2389         rec->speed                = 1000000;
2390         if (!match_row( table, row, cond, &status ))
2391         {
2392             free_row_values( table, row );
2393             continue;
2394         }
2395         offset += sizeof(*rec);
2396         row++;
2397     }
2398     TRACE("created %u rows\n", row);
2399     table->num_rows = row;
2400 
2401     heap_free( buffer );
2402     return status;
2403 }
2404 
2405 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2406 {
2407     const SOCKET_ADDRESS *sa = &addr->Address;
2408     WCHAR buf[NI_MAXHOST];
2409 
2410     if (!addr) return NULL;
2411     if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL,
2412                       0, NI_NAMEREQD )) return NULL;
2413     return heap_strdupW( buf );
2414 }
2415 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2416 {
2417     IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2418     struct array *ret;
2419     ULONG buflen, i = 0, count = 0;
2420     WCHAR **ptr, buf[54]; /* max IPv6 address length */
2421 
2422     if (!list) return NULL;
2423     for (gateway = list; gateway; gateway = gateway->Next) count++;
2424 
2425     if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2426     if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2427     {
2428         heap_free( ret );
2429         return NULL;
2430     }
2431     for (gateway = list; gateway; gateway = gateway->Next)
2432     {
2433         buflen = ARRAY_SIZE( buf );
2434         if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2435                                  NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2436         {
2437             for (; i > 0; i--) heap_free( ptr[i - 1] );
2438             heap_free( ptr );
2439             heap_free( ret );
2440             return NULL;
2441         }
2442     }
2443     ret->count = count;
2444     ret->ptr   = ptr;
2445     return ret;
2446 }
2447 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2448 {
2449     IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2450     struct array *ret;
2451     ULONG buflen, i = 0, count = 0;
2452     WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2453 
2454     if (!list) return NULL;
2455     for (server = list; server; server = server->Next) count++;
2456 
2457     if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2458     if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2459     {
2460         heap_free( ret );
2461         return NULL;
2462     }
2463     for (server = list; server; server = server->Next)
2464     {
2465         buflen = ARRAY_SIZE( buf );
2466         if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2467                                  NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2468         {
2469             for (; i > 0; i--) heap_free( ptr[i - 1] );
2470             heap_free( ptr );
2471             heap_free( ret );
2472             return NULL;
2473         }
2474         if ((p = strrchrW( ptr[i - 1], ':' ))) *p = 0;
2475     }
2476     ret->count = count;
2477     ret->ptr   = ptr;
2478     return ret;
2479 }
2480 
2481 #ifndef __REACTOS__
2482 
2483 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2484 {
2485     IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2486     struct array *ret;
2487     ULONG buflen, i = 0, count = 0;
2488     WCHAR **ptr, buf[54]; /* max IPv6 address length */
2489 
2490     if (!list) return NULL;
2491     for (address = list; address; address = address->Next) count++;
2492 
2493     if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2494     if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2495     {
2496         heap_free( ret );
2497         return NULL;
2498     }
2499     for (address = list; address; address = address->Next)
2500     {
2501         buflen = ARRAY_SIZE( buf );
2502         if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength,
2503                                  NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2504         {
2505             for (; i > 0; i--) heap_free( ptr[i - 1] );
2506             heap_free( ptr );
2507             heap_free( ret );
2508             return NULL;
2509         }
2510     }
2511     ret->count = count;
2512     ret->ptr   = ptr;
2513     return ret;
2514 }
2515 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2516 {
2517     IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2518     struct array *ret;
2519     ULONG i = 0, count = 0;
2520     WCHAR **ptr;
2521 
2522     if (!list) return NULL;
2523     for (address = list; address; address = address->Next) count++;
2524 
2525     if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2526     if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2527     {
2528         heap_free( ret );
2529         return NULL;
2530     }
2531     for (address = list; address; address = address->Next)
2532     {
2533         if (address->Address.lpSockaddr->sa_family == WS_AF_INET)
2534         {
2535             WCHAR buf[INET_ADDRSTRLEN];
2536             SOCKADDR_IN addr;
2537             ULONG buflen = ARRAY_SIZE( buf );
2538 
2539             memset( &addr, 0, sizeof(addr) );
2540             addr.sin_family = WS_AF_INET;
2541             if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
2542                     || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
2543                 ptr[i] = NULL;
2544             else
2545                 ptr[i] = heap_strdupW( buf );
2546         }
2547         else
2548         {
2549             static const WCHAR fmtW[] = {'%','u',0};
2550             WCHAR buf[11];
2551 
2552             sprintfW(buf, fmtW, address->OnLinkPrefixLength);
2553             ptr[i] = heap_strdupW( buf );
2554         }
2555         if (!ptr[i++])
2556         {
2557             for (; i > 0; i--) heap_free( ptr[i - 1] );
2558             heap_free( ptr );
2559             heap_free( ret );
2560             return NULL;
2561         }
2562     }
2563     ret->count = count;
2564     ret->ptr   = ptr;
2565     return ret;
2566 }
2567 
2568 #endif /* !__REACTOS__ */
2569 
2570 static WCHAR *get_settingid( UINT32 index )
2571 {
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;
2580 }
2581 
2582 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
2583 {
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;
2589 
2590     ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size );
2591     if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2592 
2593     if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2594     if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size ))
2595     {
2596         heap_free( buffer );
2597         return FILL_STATUS_FAILED;
2598     }
2599     for (aa = buffer; aa; aa = aa->Next)
2600     {
2601         if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2602     }
2603     if (!resize_table( table, count, sizeof(*rec) ))
2604     {
2605         heap_free( buffer );
2606         return FILL_STATUS_FAILED;
2607     }
2608     for (aa = buffer; aa; aa = aa->Next)
2609     {
2610         if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2611 
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 #ifndef __REACTOS__
2620         rec->ipaddress            = get_ipaddress( aa->FirstUnicastAddress );
2621 #endif
2622         rec->ipconnectionmetric   = 20;
2623         rec->ipenabled            = -1;
2624 #ifndef __REACTOS__
2625         rec->ipsubnet             = get_ipsubnet( aa->FirstUnicastAddress );
2626 #endif
2627         rec->mac_address          = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2628         rec->settingid            = get_settingid( rec->index );
2629         if (!match_row( table, row, cond, &status ))
2630         {
2631             free_row_values( table, row );
2632             continue;
2633         }
2634         offset += sizeof(*rec);
2635         row++;
2636     }
2637     TRACE("created %u rows\n", row);
2638     table->num_rows = row;
2639 
2640     heap_free( buffer );
2641     return status;
2642 }
2643 
2644 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
2645 {
2646     struct record_physicalmemory *rec;
2647     enum fill_status status = FILL_STATUS_UNFILTERED;
2648     UINT row = 0;
2649 
2650     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2651 
2652     rec = (struct record_physicalmemory *)table->data;
2653     rec->capacity   = get_total_physical_memory();
2654     rec->memorytype = 9; /* RAM */
2655     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2656     else row++;
2657 
2658     TRACE("created %u rows\n", row);
2659     table->num_rows = row;
2660     return status;
2661 }
2662 
2663 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond )
2664 {
2665     struct record_pnpentity *rec;
2666     enum fill_status status = FILL_STATUS_UNFILTERED;
2667     HDEVINFO device_info_set;
2668     SP_DEVINFO_DATA devinfo = {0};
2669     DWORD idx;
2670 
2671     device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT );
2672 
2673     devinfo.cbSize = sizeof(devinfo);
2674 
2675     idx = 0;
2676     while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
2677     {
2678         /* noop */
2679     }
2680 
2681     resize_table( table, idx, sizeof(*rec) );
2682     table->num_rows = 0;
2683     rec = (struct record_pnpentity *)table->data;
2684 
2685     idx = 0;
2686     while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
2687     {
2688         WCHAR device_id[MAX_PATH];
2689         if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
2690                     ARRAY_SIZE(device_id), NULL ))
2691         {
2692             rec->device_id = heap_strdupW( device_id );
2693 
2694             table->num_rows++;
2695             if (!match_row( table, table->num_rows - 1, cond, &status ))
2696             {
2697                 free_row_values( table, table->num_rows - 1 );
2698                 table->num_rows--;
2699             }
2700             else
2701                 rec++;
2702         }
2703     }
2704 
2705     SetupDiDestroyDeviceInfoList( device_info_set );
2706 
2707     return status;
2708 }
2709 
2710 static enum fill_status fill_printer( struct table *table, const struct expr *cond )
2711 {
2712     static const WCHAR fmtW[] = {'P','r','i','n','t','e','r','%','d',0};
2713     struct record_printer *rec;
2714     enum fill_status status = FILL_STATUS_UNFILTERED;
2715     PRINTER_INFO_2W *info;
2716     DWORD i, offset = 0, count = 0, size = 0, num_rows = 0;
2717     WCHAR id[20];
2718 
2719     EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
2720     if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2721 
2722     if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED;
2723     if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
2724     {
2725         heap_free( info );
2726         return FILL_STATUS_FAILED;
2727     }
2728     if (!resize_table( table, count, sizeof(*rec) ))
2729     {
2730         heap_free( info );
2731         return FILL_STATUS_FAILED;
2732     }
2733 
2734     for (i = 0; i < count; i++)
2735     {
2736         rec = (struct record_printer *)(table->data + offset);
2737         rec->attributes           = info[i].Attributes;
2738         sprintfW( id, fmtW, i );
2739         rec->device_id            = heap_strdupW( id );
2740         rec->drivername           = heap_strdupW( info[i].pDriverName );
2741         rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality;
2742         rec->local                = -1;
2743         rec->location             = heap_strdupW( info[i].pLocation );
2744         rec->name                 = heap_strdupW( info[i].pPrinterName );
2745         rec->network              = 0;
2746         rec->portname             = heap_strdupW( info[i].pPortName );
2747         if (!match_row( table, i, cond, &status ))
2748         {
2749             free_row_values( table, i );
2750             continue;
2751         }
2752         offset += sizeof(*rec);
2753         num_rows++;
2754     }
2755     TRACE("created %u rows\n", num_rows);
2756     table->num_rows = num_rows;
2757 
2758     heap_free( info );
2759     return status;
2760 }
2761 
2762 static WCHAR *get_cmdline( DWORD process_id )
2763 {
2764     if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() );
2765     return NULL; /* FIXME handle different process case */
2766 }
2767 
2768 static enum fill_status fill_process( struct table *table, const struct expr *cond )
2769 {
2770     static const WCHAR fmtW[] = {'%','u',0};
2771     WCHAR handle[11];
2772     struct record_process *rec;
2773     PROCESSENTRY32W entry;
2774     HANDLE snap;
2775     enum fill_status status = FILL_STATUS_FAILED;
2776     UINT row = 0, offset = 0;
2777 
2778     snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
2779     if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
2780 
2781     entry.dwSize = sizeof(entry);
2782     if (!Process32FirstW( snap, &entry )) goto done;
2783     if (!resize_table( table, 8, sizeof(*rec) )) goto done;
2784 
2785     do
2786     {
2787         if (!resize_table( table, row + 1, sizeof(*rec) )) goto done;
2788 
2789         rec = (struct record_process *)(table->data + offset);
2790         rec->caption        = heap_strdupW( entry.szExeFile );
2791         rec->commandline    = get_cmdline( entry.th32ProcessID );
2792         rec->description    = heap_strdupW( entry.szExeFile );
2793         sprintfW( handle, fmtW, entry.th32ProcessID );
2794         rec->handle         = heap_strdupW( handle );
2795         rec->name           = heap_strdupW( entry.szExeFile );
2796         rec->process_id     = entry.th32ProcessID;
2797         rec->pprocess_id    = entry.th32ParentProcessID;
2798         rec->thread_count   = entry.cntThreads;
2799         rec->workingsetsize = 0;
2800         rec->get_owner      = process_get_owner;
2801         if (!match_row( table, row, cond, &status ))
2802         {
2803             free_row_values( table, row );
2804             continue;
2805         }
2806         offset += sizeof(*rec);
2807         row++;
2808     } while (Process32NextW( snap, &entry ));
2809 
2810     TRACE("created %u rows\n", row);
2811     table->num_rows = row;
2812     status = FILL_STATUS_UNFILTERED;
2813 
2814 done:
2815     CloseHandle( snap );
2816     return status;
2817 }
2818 
2819 static inline void do_cpuid( unsigned int ax, unsigned int *p )
2820 {
2821 #ifdef __i386__
2822 #ifdef _MSC_VER
2823     __cpuid(p, ax);
2824 #else
2825     __asm__("pushl %%ebx\n\t"
2826                 "cpuid\n\t"
2827                 "movl %%ebx, %%esi\n\t"
2828                 "popl %%ebx"
2829                 : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3])
2830                 :  "0" (ax));
2831 #endif
2832 #endif
2833 }
2834 static const WCHAR *get_osarchitecture(void)
2835 {
2836     SYSTEM_INFO info;
2837     GetNativeSystemInfo( &info );
2838     if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW;
2839     return os_32bitW;
2840 }
2841 static void get_processor_caption( WCHAR *caption )
2842 {
2843     static const WCHAR fmtW[] =
2844         {'%','s',' ','F','a','m','i','l','y',' ','%','u',' ',
2845          'M','o','d','e','l',' ','%','u',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
2846     static const WCHAR x86W[] = {'x','8','6',0};
2847     static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0};
2848     const WCHAR *arch = (get_osarchitecture() == os_32bitW) ? x86W : intel64W;
2849     unsigned int regs[4] = {0, 0, 0, 0};
2850 
2851     do_cpuid( 1, regs );
2852     sprintfW( caption, fmtW, arch, (regs[0] & (15 << 8)) >> 8, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 );
2853 }
2854 static void get_processor_version( WCHAR *version )
2855 {
2856     static const WCHAR fmtW[] =
2857         {'M','o','d','e','l',' ','%','u',',',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
2858     unsigned int regs[4] = {0, 0, 0, 0};
2859 
2860     do_cpuid( 1, regs );
2861     sprintfW( version, fmtW, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 );
2862 }
2863 static UINT16 get_processor_revision(void)
2864 {
2865     unsigned int regs[4] = {0, 0, 0, 0};
2866     do_cpuid( 1, regs );
2867     return regs[0];
2868 }
2869 static void get_processor_id( WCHAR *processor_id )
2870 {
2871     static const WCHAR fmtW[] = {'%','0','8','X','%','0','8','X',0};
2872     unsigned int regs[4] = {0, 0, 0, 0};
2873 
2874     do_cpuid( 1, regs );
2875     sprintfW( processor_id, fmtW, regs[3], regs[0] );
2876 }
2877 static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
2878 {
2879     unsigned int i;
2880     unsigned char *p = (unsigned char *)regs;
2881 
2882     for (i = 0; i < len; i++) { buffer[i] = *p++; }
2883     buffer[i] = 0;
2884 }
2885 static void get_processor_manufacturer( WCHAR *manufacturer )
2886 {
2887     unsigned int tmp, regs[4] = {0, 0, 0, 0};
2888 
2889     do_cpuid( 0, regs );
2890     tmp = regs[2];      /* swap edx and ecx */
2891     regs[2] = regs[3];
2892     regs[3] = tmp;
2893 
2894     regs_to_str( regs + 1, 12, manufacturer );
2895 }
2896 static void get_processor_name( WCHAR *name )
2897 {
2898     unsigned int regs[4] = {0, 0, 0, 0};
2899 
2900     do_cpuid( 0x80000000, regs );
2901     if (regs[0] >= 0x80000004)
2902     {
2903         do_cpuid( 0x80000002, regs );
2904         regs_to_str( regs, 16, name );
2905         do_cpuid( 0x80000003, regs );
2906         regs_to_str( regs, 16, name + 16 );
2907         do_cpuid( 0x80000004, regs );
2908         regs_to_str( regs, 16, name + 32 );
2909     }
2910 }
2911 static UINT get_processor_currentclockspeed( UINT index )
2912 {
2913     PROCESSOR_POWER_INFORMATION *info;
2914     UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
2915     NTSTATUS status;
2916 
2917     if ((info = heap_alloc( size )))
2918     {
2919         status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
2920         if (!status) ret = info[index].CurrentMhz;
2921         heap_free( info );
2922     }
2923     return ret;
2924 }
2925 static UINT get_processor_maxclockspeed( UINT index )
2926 {
2927     PROCESSOR_POWER_INFORMATION *info;
2928     UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
2929     NTSTATUS status;
2930 
2931     if ((info = heap_alloc( size )))
2932     {
2933         status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
2934         if (!status) ret = info[index].MaxMhz;
2935         heap_free( info );
2936     }
2937     return ret;
2938 }
2939 
2940 static enum fill_status fill_processor( struct table *table, const struct expr *cond )
2941 {
2942     static const WCHAR fmtW[] = {'C','P','U','%','u',0};
2943     WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
2944     struct record_processor *rec;
2945     UINT i, offset = 0, num_rows = 0, num_cores, num_logical_processors, count = get_processor_count();
2946     enum fill_status status = FILL_STATUS_UNFILTERED;
2947 
2948     if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED;
2949 
2950     get_processor_caption( caption );
2951     get_processor_id( processor_id );
2952     get_processor_manufacturer( manufacturer );
2953     get_processor_name( name );
2954     get_processor_version( version );
2955 
2956     num_logical_processors = get_logical_processor_count( &num_cores ) / count;
2957     num_cores /= count;
2958 
2959     for (i = 0; i < count; i++)
2960     {
2961         rec = (struct record_processor *)(table->data + offset);
2962         rec->addresswidth           = get_osarchitecture() == os_32bitW ? 32 : 64;
2963         rec->architecture           = get_osarchitecture() == os_32bitW ? 0 : 9;
2964         rec->caption                = heap_strdupW( caption );
2965         rec->cpu_status             = 1; /* CPU Enabled */
2966         rec->currentclockspeed      = get_processor_currentclockspeed( i );
2967         rec->datawidth              = get_osarchitecture() == os_32bitW ? 32 : 64;
2968         rec->description            = heap_strdupW( caption );
2969         sprintfW( device_id, fmtW, i );
2970         rec->device_id              = heap_strdupW( device_id );
2971         rec->family                 = 2; /* Unknown */
2972         rec->level                  = 15;
2973         rec->manufacturer           = heap_strdupW( manufacturer );
2974         rec->maxclockspeed          = get_processor_maxclockspeed( i );
2975         rec->name                   = heap_strdupW( name );
2976         rec->num_cores              = num_cores;
2977         rec->num_logical_processors = num_logical_processors;
2978         rec->processor_id           = heap_strdupW( processor_id );
2979         rec->processortype          = 3; /* central processor */
2980         rec->revision               = get_processor_revision();
2981         rec->unique_id              = NULL;
2982         rec->version                = heap_strdupW( version );
2983         if (!match_row( table, i, cond, &status ))
2984         {
2985             free_row_values( table, i );
2986             continue;
2987         }
2988         offset += sizeof(*rec);
2989         num_rows++;
2990     }
2991 
2992     TRACE("created %u rows\n", num_rows);
2993     table->num_rows = num_rows;
2994     return status;
2995 }
2996 
2997 static WCHAR *get_lastbootuptime(void)
2998 {
2999     static const WCHAR fmtW[] =
3000         {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u',
3001          '.','%','0','6','u','+','0','0','0',0};
3002     SYSTEM_TIMEOFDAY_INFORMATION ti;
3003     TIME_FIELDS tf;
3004     WCHAR *ret;
3005 
3006     if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3007 
3008     NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
3009     RtlTimeToTimeFields( &ti.liKeBootTime, &tf );
3010     sprintfW( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 );
3011     return ret;
3012 }
3013 static WCHAR *get_localdatetime(void)
3014 {
3015     static const WCHAR fmtW[] =
3016         {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u',
3017          '.','%','0','6','u','%','+','0','3','d',0};
3018     TIME_ZONE_INFORMATION tzi;
3019     SYSTEMTIME st;
3020     WCHAR *ret;
3021     DWORD Status;
3022     LONG Bias;
3023 
3024     Status = GetTimeZoneInformation(&tzi);
3025 
3026     if(Status == TIME_ZONE_ID_INVALID) return NULL;
3027     Bias = tzi.Bias;
3028     if(Status == TIME_ZONE_ID_DAYLIGHT)
3029         Bias+= tzi.DaylightBias;
3030     else
3031         Bias+= tzi.StandardBias;
3032     if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3033 
3034     GetLocalTime(&st);
3035     sprintfW( ret, fmtW, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000, -Bias);
3036     return ret;
3037 }
3038 static WCHAR *get_systemdirectory(void)
3039 {
3040     void *redir;
3041     WCHAR *ret;
3042 
3043     if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL;
3044     Wow64DisableWow64FsRedirection( &redir );
3045     GetSystemDirectoryW( ret, MAX_PATH );
3046     Wow64RevertWow64FsRedirection( redir );
3047     return ret;
3048 }
3049 static WCHAR *get_codeset(void)
3050 {
3051     static const WCHAR fmtW[] = {'%','u',0};
3052     WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3053     if (ret) sprintfW( ret, fmtW, GetACP() );
3054     return ret;
3055 }
3056 static WCHAR *get_countrycode(void)
3057 {
3058     WCHAR *ret = heap_alloc( 6 * sizeof(WCHAR) );
3059     if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 );
3060     return ret;
3061 }
3062 static WCHAR *get_locale(void)
3063 {
3064     WCHAR *ret = heap_alloc( 5 * sizeof(WCHAR) );
3065     if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 );
3066     return ret;
3067 }
3068 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
3069 {
3070     static const WCHAR fmtW[] = {'%','u',0};
3071     WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3072     if (ret) sprintfW( ret, fmtW, ver->dwBuildNumber );
3073     return ret;
3074 }
3075 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
3076 {
3077     static const WCHAR windowsW[] =
3078         {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' '};
3079     static const WCHAR win2000W[] =
3080         {'2','0','0','0',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
3081     static const WCHAR win2003W[] =
3082         {'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};
3083     static const WCHAR winxpW[] =
3084         {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
3085     static const WCHAR winxp64W[] =
3086         {'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};
3087     static const WCHAR vistaW[] =
3088         {'V','i','s','t','a',' ','U','l','t','i','m','a','t','e',0};
3089     static const WCHAR win2008W[] =
3090         {'S','e','r','v','e','r',' ','2','0','0','8',' ','S','t','a','n','d','a','r','d',0};
3091     static const WCHAR win7W[] =
3092         {'7',' ','P','r','o','f','e','s','s','i','o','n','a','l',0};
3093     static const WCHAR win2008r2W[] =
3094         {'S','e','r','v','e','r',' ','2','0','0','8',' ','R','2',' ','S','t','a','n','d','a','r','d',0};
3095     static const WCHAR win8W[] =
3096         {'8',' ','P','r','o',0};
3097     static const WCHAR win81W[] =
3098         {'8','.','1',' ','P','r','o',0};
3099     static const WCHAR win10W[] =
3100         {'1','0',' ','P','r','o',0};
3101     int len = ARRAY_SIZE( windowsW );
3102     WCHAR *ret;
3103 
3104     if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL;
3105     memcpy( ret, windowsW, sizeof(windowsW) );
3106     if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) );
3107     else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win8W, sizeof(win8W) );
3108     else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win81W, sizeof(win81W) );
3109     else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1)
3110     {
3111         if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) );
3112         else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) );
3113     }
3114     else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0)
3115     {
3116         if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) );
3117         else memcpy( ret + len, win2008W, sizeof(win2008W) );
3118     }
3119     else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2)
3120     {
3121         if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) );
3122         else memcpy( ret + len, win2003W, sizeof(win2003W) );
3123     }
3124     else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) );
3125     else memcpy( ret + len, win2000W, sizeof(win2000W) );
3126     return ret;
3127 }
3128 static WCHAR *get_osname( const WCHAR *caption )
3129 {
3130     static const WCHAR partitionW[] =
3131         {'|','C',':','\\','W','I','N','D','O','W','S','|','\\','D','e','v','i','c','e','\\',
3132          'H','a','r','d','d','i','s','k','0','\\','P','a','r','t','i','t','i','o','n','1',0};
3133     int len = strlenW( caption );
3134     WCHAR *ret;
3135 
3136     if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
3137     memcpy( ret, caption, len * sizeof(WCHAR) );
3138     memcpy( ret + len, partitionW, sizeof(partitionW) );
3139     return ret;
3140 }
3141 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
3142 {
3143     static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u',0};
3144     WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) );
3145     if (ret) sprintfW( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
3146     return ret;
3147 }
3148 
3149 static enum fill_status fill_os( struct table *table, const struct expr *cond )
3150 {
3151     struct record_operatingsystem *rec;
3152     enum fill_status status = FILL_STATUS_UNFILTERED;
3153     OSVERSIONINFOEXW ver;
3154     UINT row = 0;
3155 
3156     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3157 
3158     ver.dwOSVersionInfoSize = sizeof(ver);
3159     GetVersionExW( (OSVERSIONINFOW *)&ver );
3160 
3161     rec = (struct record_operatingsystem *)table->data;
3162     rec->buildnumber            = get_osbuildnumber( &ver );
3163     rec->caption                = get_oscaption( &ver );
3164     rec->codeset                = get_codeset();
3165     rec->countrycode            = get_countrycode();
3166     rec->csdversion             = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL;
3167     rec->freephysicalmemory     = get_available_physical_memory() / 1024;
3168     rec->installdate            = os_installdateW;
3169     rec->lastbootuptime         = get_lastbootuptime();
3170     rec->localdatetime          = get_localdatetime();
3171     rec->locale                 = get_locale();
3172     rec->name                   = get_osname( rec->caption );
3173     rec->osarchitecture         = get_osarchitecture();
3174     rec->oslanguage             = GetSystemDefaultLangID();
3175     rec->osproductsuite         = 2461140; /* Windows XP Professional  */
3176     rec->ostype                 = 18;      /* WINNT */
3177     rec->primary                = -1;
3178     rec->serialnumber           = os_serialnumberW;
3179     rec->servicepackmajor       = ver.wServicePackMajor;
3180     rec->servicepackminor       = ver.wServicePackMinor;
3181     rec->suitemask              = 272;     /* Single User + Terminal */
3182     rec->systemdirectory        = get_systemdirectory();
3183     rec->totalvirtualmemorysize = get_total_physical_memory() / 1024;
3184     rec->totalvisiblememorysize = rec->totalvirtualmemorysize;
3185     rec->version                = get_osversion( &ver );
3186     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3187     else row++;
3188 
3189     TRACE("created %u rows\n", row);
3190     table->num_rows = row;
3191     return status;
3192 }
3193 
3194 static const WCHAR *get_service_type( DWORD type )
3195 {
3196     static const WCHAR filesystem_driverW[] =
3197         {'F','i','l','e',' ','S','y','s','t','e','m',' ','D','r','i','v','e','r',0};
3198     static const WCHAR kernel_driverW[] =
3199         {'K','e','r','n','e','l',' ','D','r','i','v','e','r',0};
3200     static const WCHAR own_processW[] =
3201         {'O','w','n',' ','P','r','o','c','e','s','s',0};
3202     static const WCHAR share_processW[] =
3203         {'S','h','a','r','e',' ','P','r','o','c','e','s','s',0};
3204 
3205     if (type & SERVICE_KERNEL_DRIVER)            return kernel_driverW;
3206     else if (type & SERVICE_FILE_SYSTEM_DRIVER)  return filesystem_driverW;
3207     else if (type & SERVICE_WIN32_OWN_PROCESS)   return own_processW;
3208     else if (type & SERVICE_WIN32_SHARE_PROCESS) return share_processW;
3209     else ERR("unhandled type 0x%08x\n", type);
3210     return NULL;
3211 }
3212 static const WCHAR *get_service_state( DWORD state )
3213 {
3214     static const WCHAR runningW[] =
3215         {'R','u','n','n','i','n','g',0};
3216     static const WCHAR start_pendingW[] =
3217         {'S','t','a','r','t',' ','P','e','n','d','i','n','g',0};
3218     static const WCHAR stop_pendingW[] =
3219         {'S','t','o','p',' ','P','e','n','d','i','n','g',0};
3220     static const WCHAR stoppedW[] =
3221         {'S','t','o','p','p','e','d',0};
3222     static const WCHAR unknownW[] =
3223         {'U','n','k','n','o','w','n',0};
3224 
3225     switch (state)
3226     {
3227     case SERVICE_STOPPED:       return stoppedW;
3228     case SERVICE_START_PENDING: return start_pendingW;
3229     case SERVICE_STOP_PENDING:  return stop_pendingW;
3230     case SERVICE_RUNNING:       return runningW;
3231     default:
3232         ERR("unknown state %u\n", state);
3233         return unknownW;
3234     }
3235 }
3236 static const WCHAR *get_service_startmode( DWORD mode )
3237 {
3238     static const WCHAR bootW[] = {'B','o','o','t',0};
3239     static const WCHAR systemW[] = {'S','y','s','t','e','m',0};
3240     static const WCHAR autoW[] = {'A','u','t','o',0};
3241     static const WCHAR manualW[] = {'M','a','n','u','a','l',0};
3242     static const WCHAR disabledW[] = {'D','i','s','a','b','l','e','d',0};
3243     static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',0};
3244 
3245     switch (mode)
3246     {
3247     case SERVICE_BOOT_START:   return bootW;
3248     case SERVICE_SYSTEM_START: return systemW;
3249     case SERVICE_AUTO_START:   return autoW;
3250     case SERVICE_DEMAND_START: return manualW;
3251     case SERVICE_DISABLED:     return disabledW;
3252     default:
3253         ERR("unknown mode 0x%x\n", mode);
3254         return unknownW;
3255     }
3256 }
3257 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
3258 {
3259     QUERY_SERVICE_CONFIGW *config = NULL;
3260     SC_HANDLE service;
3261     DWORD size;
3262 
3263     if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL;
3264     QueryServiceConfigW( service, NULL, 0, &size );
3265     if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
3266     if (!(config = heap_alloc( size ))) goto done;
3267     if (QueryServiceConfigW( service, config, size, &size )) goto done;
3268     heap_free( config );
3269     config = NULL;
3270 
3271 done:
3272     CloseServiceHandle( service );
3273     return config;
3274 }
3275 
3276 static enum fill_status fill_service( struct table *table, const struct expr *cond )
3277 {
3278     struct record_service *rec;
3279     SC_HANDLE manager;
3280     ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL;
3281     SERVICE_STATUS_PROCESS *status;
3282     WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
3283     DWORD len = ARRAY_SIZE( sysnameW );
3284     UINT i, row = 0, offset = 0, size = 256, needed, count;
3285     enum fill_status fill_status = FILL_STATUS_FAILED;
3286     BOOL ret;
3287 
3288     if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED;
3289     if (!(services = heap_alloc( size ))) goto done;
3290 
3291     ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3292                                  SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3293                                  &count, NULL, NULL );
3294     if (!ret)
3295     {
3296         if (GetLastError() != ERROR_MORE_DATA) goto done;
3297         size = needed;
3298         if (!(tmp = heap_realloc( services, size ))) goto done;
3299         services = tmp;
3300         ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3301                                      SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3302                                      &count, NULL, NULL );
3303         if (!ret) goto done;
3304     }
3305     if (!resize_table( table, count, sizeof(*rec) )) goto done;
3306 
3307     GetComputerNameW( sysnameW, &len );
3308     fill_status = FILL_STATUS_UNFILTERED;
3309 
3310     for (i = 0; i < count; i++)
3311     {
3312         QUERY_SERVICE_CONFIGW *config;
3313 
3314         if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue;
3315 
3316         status = &services[i].ServiceStatusProcess;
3317         rec = (struct record_service *)(table->data + offset);
3318         rec->accept_pause   = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0;
3319         rec->accept_stop    = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0;
3320         rec->displayname    = heap_strdupW( services[i].lpDisplayName );
3321         rec->name           = heap_strdupW( services[i].lpServiceName );
3322         rec->process_id     = status->dwProcessId;
3323         rec->servicetype    = get_service_type( status->dwServiceType );
3324         rec->startmode      = get_service_startmode( config->dwStartType );
3325         rec->state          = get_service_state( status->dwCurrentState );
3326         rec->systemname     = heap_strdupW( sysnameW );
3327         rec->pause_service  = service_pause_service;
3328         rec->resume_service = service_resume_service;
3329         rec->start_service  = service_start_service;
3330         rec->stop_service   = service_stop_service;
3331         heap_free( config );
3332         if (!match_row( table, row, cond, &fill_status ))
3333         {
3334             free_row_values( table, row );
3335             continue;
3336         }
3337         offset += sizeof(*rec);
3338         row++;
3339     }
3340 
3341     TRACE("created %u rows\n", row);
3342     table->num_rows = row;
3343 
3344 done:
3345     CloseServiceHandle( manager );
3346     heap_free( services );
3347     return fill_status;
3348 }
3349 
3350 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
3351 {
3352     if (!name || !name->Name.Buffer) return NULL;
3353     return heap_strdupW( name->Name.Buffer );
3354 }
3355 static struct array *get_binaryrepresentation( PSID sid, UINT len )
3356 {
3357     struct array *array = heap_alloc( sizeof(struct array) );
3358     if (array)
3359     {
3360         UINT8 *ret = heap_alloc( len );
3361         if (ret)
3362         {
3363             memcpy( ret, sid, len );
3364             array->count = len;
3365             array->ptr = ret;
3366             return array;
3367         }
3368         heap_free( array );
3369     }
3370     return NULL;
3371 }
3372 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
3373 {
3374     if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL;
3375     return heap_strdupW( domain->Domains->Name.Buffer );
3376 }
3377 static const WCHAR *find_sid_str( const struct expr *cond )
3378 {
3379     const struct expr *left, *right;
3380     const WCHAR *ret = NULL;
3381 
3382     if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL;
3383 
3384     left = cond->u.expr.left;
3385     right = cond->u.expr.right;
3386     if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !strcmpiW( left->u.propval->name, prop_sidW ))
3387     {
3388         ret = right->u.sval;
3389     }
3390     else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !strcmpiW( right->u.propval->name, prop_sidW ))
3391     {
3392         ret = left->u.sval;
3393     }
3394     return ret;
3395 }
3396 
3397 static enum fill_status fill_sid( struct table *table, const struct expr *cond )
3398 {
3399     PSID sid;
3400     LSA_REFERENCED_DOMAIN_LIST *domain;
3401     LSA_TRANSLATED_NAME *name;
3402     LSA_HANDLE handle;
3403     LSA_OBJECT_ATTRIBUTES attrs;
3404     const WCHAR *str;
3405     struct record_sid *rec;
3406     UINT len;
3407 
3408     if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED;
3409     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3410 
3411     if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED;
3412     len = GetLengthSid( sid );
3413 
3414     memset( &attrs, 0, sizeof(attrs) );
3415     attrs.Length = sizeof(attrs);
3416     if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ))
3417     {
3418         LocalFree( sid );
3419         return FILL_STATUS_FAILED;
3420     }
3421     if (LsaLookupSids( handle, 1, &sid, &domain, &name ))
3422     {
3423         LocalFree( sid );
3424         LsaClose( handle );
3425         return FILL_STATUS_FAILED;
3426     }
3427 
3428     rec = (struct record_sid *)table->data;
3429     rec->accountname            = get_accountname( name );
3430     rec->binaryrepresentation   = get_binaryrepresentation( sid, len );
3431     rec->referenceddomainname   = get_referenceddomainname( domain );
3432     rec->sid                    = heap_strdupW( str );
3433     rec->sidlength              = len;
3434 
3435     TRACE("created 1 row\n");
3436     table->num_rows = 1;
3437 
3438     LsaFreeMemory( domain );
3439     LsaFreeMemory( name );
3440     LocalFree( sid );
3441     LsaClose( handle );
3442     return FILL_STATUS_FILTERED;
3443 }
3444 
3445 #ifndef __REACTOS__
3446 
3447 static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres )
3448 {
3449     HDC hdc = GetDC( NULL );
3450     UINT32 ret;
3451 
3452     if (!hdc) return 32;
3453     ret = GetDeviceCaps( hdc, BITSPIXEL );
3454     *hres = GetDeviceCaps( hdc, HORZRES );
3455     *vres = GetDeviceCaps( hdc, VERTRES );
3456     ReleaseDC( NULL, hdc );
3457     return ret;
3458 }
3459 static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
3460 {
3461     static const WCHAR fmtW[] =
3462         {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X',
3463          '&','S','U','B','S','Y','S','_','%','0','8','X','&','R','E','V','_','%','0','2','X','\\',
3464          '0','&','D','E','A','D','B','E','E','F','&','0','&','D','E','A','D',0};
3465     WCHAR *ret;
3466 
3467     if (!(ret = heap_alloc( sizeof(fmtW) + 2 * sizeof(WCHAR) ))) return NULL;
3468     sprintfW( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
3469     return ret;
3470 }
3471 
3472 #define HW_VENDOR_AMD    0x1002
3473 #define HW_VENDOR_NVIDIA 0x10de
3474 #define HW_VENDOR_VMWARE 0x15ad
3475 #define HW_VENDOR_INTEL  0x8086
3476 
3477 static const WCHAR *get_installeddriver( UINT vendorid )
3478 {
3479     static const WCHAR driver_amdW[] = {'a','t','i','c','f','x','3','2','.','d','l','l',0};
3480     static const WCHAR driver_intelW[] = {'i','g','d','u','m','d','i','m','3','2','.','d','l','l',0};
3481     static const WCHAR driver_nvidiaW[] = {'n','v','d','3','d','u','m','.','d','l','l',0};
3482     static const WCHAR driver_wineW[] = {'w','i','n','e','.','d','l','l',0};
3483 
3484     /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
3485 
3486     if (vendorid == HW_VENDOR_AMD)
3487         return driver_amdW;
3488     else if (vendorid == HW_VENDOR_NVIDIA)
3489         return driver_nvidiaW;
3490     else if (vendorid == HW_VENDOR_INTEL)
3491         return driver_intelW;
3492     return driver_wineW;
3493 }
3494 
3495 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
3496 {
3497     static const WCHAR fmtW[] = {'%','u',' ','x',' ','%','u',' ','x',' ','%','I','6','4','u',' ','c','o','l','o','r','s',0};
3498     struct record_videocontroller *rec;
3499     HRESULT hr;
3500     IDXGIFactory *factory = NULL;
3501     IDXGIAdapter *adapter = NULL;
3502     DXGI_ADAPTER_DESC desc;
3503     UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
3504     const WCHAR *name = videocontroller_deviceidW;
3505     enum fill_status status = FILL_STATUS_UNFILTERED;
3506     WCHAR mode[44];
3507 
3508     if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3509 
3510     memset (&desc, 0, sizeof(desc));
3511     hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
3512     if (FAILED(hr)) goto done;
3513 
3514     hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
3515     if (FAILED(hr)) goto done;
3516 
3517     hr = IDXGIAdapter_GetDesc( adapter, &desc );
3518     if (SUCCEEDED(hr))
3519     {
3520         vidmem = desc.DedicatedVideoMemory;
3521         name   = desc.Description;
3522     }
3523 
3524 done:
3525     rec = (struct record_videocontroller *)table->data;
3526     rec->adapter_dactype       = videocontroller_dactypeW;
3527     rec->adapter_ram           = vidmem;
3528     rec->availability          = 3; /* Running or Full Power */
3529     rec->config_errorcode      = 0; /* no error */
3530     rec->caption               = heap_strdupW( name );
3531     rec->current_bitsperpixel  = get_bits_per_pixel( &hres, &vres );
3532     rec->current_horizontalres = hres;
3533     rec->current_refreshrate   = 0; /* default refresh rate */
3534     rec->current_scanmode      = 2; /* Unknown */
3535     rec->current_verticalres   = vres;
3536     rec->description           = heap_strdupW( name );
3537     rec->device_id             = videocontroller_deviceidW;
3538     rec->driverdate            = videocontroller_driverdateW;
3539     rec->driverversion         = videocontroller_driverversionW;
3540     rec->installeddriver       = get_installeddriver( desc.VendorId );
3541     rec->name                  = heap_strdupW( name );
3542     rec->pnpdevice_id          = get_pnpdeviceid( &desc );
3543     rec->status                = videocontroller_statusW;
3544     rec->videoarchitecture     = 2; /* Unknown */
3545     rec->videomemorytype       = 2; /* Unknown */
3546     wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel );
3547     rec->videomodedescription  = heap_strdupW( mode );
3548     rec->videoprocessor        = heap_strdupW( name );
3549     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3550     else row++;
3551 
3552     TRACE("created %u rows\n", row);
3553     table->num_rows = row;
3554 
3555     if (adapter) IDXGIAdapter_Release( adapter );
3556     if (factory) IDXGIFactory_Release( factory );
3557     return status;
3558 }
3559 
3560 #endif /* !__REACTOS__ */
3561 
3562 static struct table builtin_classes[] =
3563 {
3564     { class_baseboardW, ARRAY_SIZE(col_baseboard), col_baseboard, ARRAY_SIZE(data_baseboard), 0, (BYTE *)data_baseboard },
3565     { class_biosW, ARRAY_SIZE(col_bios), col_bios, ARRAY_SIZE(data_bios), 0, (BYTE *)data_bios },
3566     { class_cdromdriveW, ARRAY_SIZE(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive },
3567     { class_compsysW, ARRAY_SIZE(col_compsys), col_compsys, 0, 0, NULL, fill_compsys },
3568     { class_compsysproductW, ARRAY_SIZE(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct },
3569     { class_datafileW, ARRAY_SIZE(col_datafile), col_datafile, 0, 0, NULL, fill_datafile },
3570     { class_desktopmonitorW, ARRAY_SIZE(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor },
3571     { class_directoryW, ARRAY_SIZE(col_directory), col_directory, 0, 0, NULL, fill_directory },
3572     { class_diskdriveW, ARRAY_SIZE(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive },
3573     { class_diskpartitionW, ARRAY_SIZE(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition },
3574     { class_ip4routetableW, ARRAY_SIZE(col_ip4routetable), col_ip4routetable, 0, 0, NULL, fill_ip4routetable },
3575     { class_logicaldiskW, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
3576     { class_logicaldisk2W, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk },
3577     { class_networkadapterW, ARRAY_SIZE(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter },
3578     { class_networkadapterconfigW, ARRAY_SIZE(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, fill_networkadapterconfig },
3579     { class_osW, ARRAY_SIZE(col_os), col_os, 0, 0, NULL, fill_os },
3580     { class_paramsW, ARRAY_SIZE(col_param), col_param, ARRAY_SIZE(data_param), 0, (BYTE *)data_param },
3581     { class_physicalmediaW, ARRAY_SIZE(col_physicalmedia), col_physicalmedia, ARRAY_SIZE(data_physicalmedia), 0, (BYTE *)data_physicalmedia },
3582     { class_physicalmemoryW, ARRAY_SIZE(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory },
3583     { class_pnpentityW, ARRAY_SIZE(col_pnpentity), col_pnpentity, 0, 0, NULL, fill_pnpentity },
3584     { class_printerW, ARRAY_SIZE(col_printer), col_printer, 0, 0, NULL, fill_printer },
3585     { class_processW, ARRAY_SIZE(col_process), col_process, 0, 0, NULL, fill_process },
3586     { class_processorW, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
3587     { class_processor2W, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor },
3588     { class_qualifiersW, ARRAY_SIZE(col_qualifier), col_qualifier, ARRAY_SIZE(data_qualifier), 0, (BYTE *)data_qualifier },
3589     { class_serviceW, ARRAY_SIZE(col_service), col_service, 0, 0, NULL, fill_service },
3590     { class_sidW, ARRAY_SIZE(col_sid), col_sid, 0, 0, NULL, fill_sid },
3591     { class_sounddeviceW, ARRAY_SIZE(col_sounddevice), col_sounddevice, ARRAY_SIZE(data_sounddevice), 0, (BYTE *)data_sounddevice },
3592     { class_stdregprovW, ARRAY_SIZE(col_stdregprov), col_stdregprov, ARRAY_SIZE(data_stdregprov), 0, (BYTE *)data_stdregprov },
3593     { class_systemsecurityW, ARRAY_SIZE(col_systemsecurity), col_systemsecurity, ARRAY_SIZE(data_systemsecurity), 0, (BYTE *)data_systemsecurity },
3594     { class_systemenclosureW, ARRAY_SIZE(col_systemenclosure), col_systemenclosure, ARRAY_SIZE(data_systemenclosure), 0, (BYTE *)data_systemenclosure },
3595 #ifndef __REACTOS__
3596     /* Requires dxgi.dll */
3597     { class_videocontrollerW, ARRAY_SIZE(col_videocontroller), col_videocontroller, 0, 0, NULL, fill_videocontroller }
3598 #endif
3599 };
3600 
3601 void init_table_list( void )
3602 {
3603     static struct list tables = LIST_INIT( tables );
3604     UINT i;
3605 
3606     for (i = 0; i < ARRAY_SIZE(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry );
3607     table_list = &tables;
3608 }
3609