ReactOS  0.4.14-dev-52-g6116262
builtin.c
Go to the documentation of this file.
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 
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};
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};
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};
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__
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
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};
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__
195  {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0};
196 #endif
198  {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0};
199 #ifndef __REACTOS__
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};
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};
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};
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};
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};
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};
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};
266  {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0};
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};
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};
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};
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};
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};
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};
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};
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};
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};
382  {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0};
384  {'S','M','B','I','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0};
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};
418  {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
420  {'T','o','t','a','l','V','i','r','t','u','a','l','M','e','m','o','r','y','S','i','z','e',0};
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__
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};
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};
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 {
458  { prop_modelW, CIM_STRING },
459  { prop_nameW, CIM_STRING },
464 };
465 static const struct column col_bios[] =
466 {
470  { prop_nameW, CIM_STRING },
477 };
478 static const struct column col_cdromdrive[] =
479 {
483  { prop_nameW, CIM_STRING },
485 };
486 static const struct column col_compsys[] =
487 {
492  { prop_modelW, CIM_STRING },
498 };
499 static const struct column col_compsysproduct[] =
500 {
507 };
508 static const struct column col_datafile[] =
509 {
512 };
513 static const struct column col_desktopmonitor[] =
514 {
516 };
517 static const struct column col_directory[] =
518 {
521 };
522 static const struct column col_diskdrive[] =
523 {
529  { prop_modelW, CIM_STRING },
533 };
534 static const struct column col_diskpartition[] =
535 {
542  { prop_sizeW, CIM_UINT64 },
545 };
546 static const struct column col_ip4routetable[] =
547 {
551 };
552 static const struct column col_logicaldisk[] =
553 {
559  { prop_sizeW, CIM_UINT64 },
562 };
563 static const struct column col_networkadapter[] =
564 {
576 };
577 static const struct column col_networkadapterconfig[] =
578 {
591 };
592 static const struct column col_os[] =
593 {
618 };
619 static const struct column col_param[] =
620 {
621  { prop_classW, CIM_STRING },
625  { prop_typeW, CIM_UINT32 },
628 };
629 static const struct column col_physicalmedia[] =
630 {
632  { prop_tagW, CIM_STRING }
633 };
634 static const struct column col_physicalmemory[] =
635 {
638 };
639 static const struct column col_pnpentity[] =
640 {
642 };
643 static const struct column col_printer[] =
644 {
654 };
655 static const struct column col_process[] =
656 {
666  /* methods */
668 };
669 static const struct column col_processor[] =
670 {
691 };
692 static const struct column col_qualifier[] =
693 {
694  { prop_classW, CIM_STRING },
696  { prop_typeW, CIM_UINT32 },
698  { prop_nameW, CIM_STRING },
701 };
702 static const struct column col_service[] =
703 {
711  { prop_stateW, CIM_STRING },
713  /* methods */
718 };
719 static const struct column col_sid[] =
720 {
726 };
727 static const struct column col_sounddevice[] =
728 {
729  { prop_nameW, CIM_STRING },
732 };
733 static const struct column col_stdregprov[] =
734 {
739 };
740 static const struct column col_systemenclosure[] =
741 {
747  { prop_nameW, CIM_STRING },
748  { prop_tagW, CIM_STRING },
749 };
750 static const struct column col_systemsecurity[] =
751 {
754 };
755 
756 #ifndef __REACTOS__
757 static const struct column col_videocontroller[] =
758 {
781 };
782 #endif
783 
785  {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0};
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};
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};
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};
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};
831  {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
833  {'1','.','0',0};
835  {'I','D','E',0};
837  {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0};
839  {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0};
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};
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};
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};
863  {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
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};
869  {'W','i','n','e',0};
870 #ifndef __REACTOS__
872  {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0};
874  {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0};
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};
878  {'1','.','0',0};
880  {'O','K',0};
881 #endif
882 
883 #include "pshpack1.h"
885 {
887  const WCHAR *model;
888  const WCHAR *name;
889  const WCHAR *product;
891  const WCHAR *tag;
892  const WCHAR *version;
893 };
895 {
899  const WCHAR *name;
905  const WCHAR *version;
906 };
908 {
909  const WCHAR *device_id;
910  const WCHAR *drive;
911  const WCHAR *mediatype;
912  const WCHAR *name;
914 };
916 {
918  const WCHAR *domain;
921  const WCHAR *model;
922  const WCHAR *name;
926  const WCHAR *username;
927 };
929 {
931  const WCHAR *name;
932  const WCHAR *skunumber;
933  const WCHAR *uuid;
934  const WCHAR *vendor;
935  const WCHAR *version;
936 };
938 {
939  const WCHAR *name;
940  const WCHAR *version;
941 };
943 {
945 };
947 {
949  const WCHAR *name;
950 };
952 {
953  const WCHAR *device_id;
957  const WCHAR *mediatype;
958  const WCHAR *model;
962 };
964 {
965  int bootable;
967  const WCHAR *device_id;
973  const WCHAR *type;
974 };
976 {
979  const WCHAR *nexthop;
980 };
982 {
983  const WCHAR *device_id;
987  const WCHAR *name;
991 };
993 {
995  const WCHAR *device_id;
1000  const WCHAR *name;
1005 };
1007 {
1008  const struct array *defaultipgateway;
1014  const struct array *ipaddress;
1017  const struct array *ipsubnet;
1020 };
1022 {
1024  const WCHAR *caption;
1025  const WCHAR *codeset;
1032  const WCHAR *locale;
1033  const WCHAR *name;
1038  int primary;
1046  const WCHAR *version;
1047 };
1049 {
1050  const WCHAR *class;
1051  const WCHAR *method;
1057 };
1059 {
1061  const WCHAR *tag;
1062 };
1064 {
1067 };
1069 {
1071 };
1073 {
1078  int local;
1079  const WCHAR *location;
1080  const WCHAR *name;
1081  int network;
1082  const WCHAR *portname;
1083 };
1085 {
1086  const WCHAR *caption;
1089  const WCHAR *handle;
1090  const WCHAR *name;
1095  /* methods */
1097 };
1099 {
1102  const WCHAR *caption;
1112  const WCHAR *name;
1119  const WCHAR *version;
1120 };
1122 {
1123  const WCHAR *class;
1124  const WCHAR *member;
1127  const WCHAR *name;
1129  const WCHAR *strvalue;
1130 };
1132 {
1136  const WCHAR *name;
1140  const WCHAR *state;
1142  /* methods */
1147 };
1149 {
1153  const WCHAR *sid;
1155 };
1157 {
1158  const WCHAR *name;
1161 };
1163 {
1168 };
1170 {
1173 };
1175 {
1176  const WCHAR *caption;
1177  const struct array *chassistypes;
1181  const WCHAR *name;
1182  const WCHAR *tag;
1183 };
1185 {
1189  const WCHAR *caption;
1201  const WCHAR *name;
1203  const WCHAR *status;
1208 };
1209 #include "poppack.h"
1210 
1211 static const struct record_baseboard data_baseboard[] =
1212 {
1214 };
1215 static const struct record_bios data_bios[] =
1216 {
1219 };
1220 static const struct record_param data_param[] =
1221 {
1232  { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1250 };
1251 
1252 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1253  WBEM_FLAVOR_ORIGIN_PROPAGATED)
1254 
1256 {
1258 };
1259 static const struct record_qualifier data_qualifier[] =
1260 {
1263 };
1264 static const struct record_sounddevice data_sounddevice[] =
1265 {
1267 };
1268 static const struct record_stdregprov data_stdregprov[] =
1269 {
1271 };
1273 {
1274  1,
1275 };
1277 {
1280 };
1282 {
1283  {
1287  FALSE,
1291  }
1292 };
1294 {
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  {
1307  return TRUE;
1308  }
1309  if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1310  {
1312  return FALSE;
1313  }
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;
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();
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);
1360  sprintfW( drive, fmtW, 'A' + i );
1361  rec->drive = heap_strdupW( drive );
1363  rec->name = cdromdrive_nameW;
1365  if (!match_row( table, row, cond, &status ))
1366  {
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 
1380 {
1382 
1383  if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1384  return info.NumberOfProcessors;
1385 }
1386 
1388 {
1390  UINT i, j, count = 0;
1391  NTSTATUS status;
1392  ULONG len;
1393 
1394  if (num_cores) *num_cores = get_processor_count();
1397 
1398  if (!(info = heap_alloc( len ))) return get_processor_count();
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 
1422 {
1423  MEMORYSTATUSEX status;
1424 
1425  status.dwLength = sizeof(status);
1426  if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1427  return status.ullTotalPhys;
1428 }
1429 
1431 {
1432  MEMORYSTATUSEX status;
1433 
1434  status.dwLength = sizeof(status);
1435  if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1436  return status.ullAvailPhys;
1437 }
1438 
1440 {
1441  WCHAR *ret;
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;
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;
1477  rec->domain = compsys_domainW;
1478  rec->domainrole = 0; /* standalone workstation */
1480  rec->model = compsys_modelW;
1481  rec->name = get_computername();
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 
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
1540 }
1541 
1542 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1543 {
1544  struct record_computersystemproduct *rec;
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;
1552  rec->name = compsysproduct_nameW;
1553  rec->skunumber = NULL;
1554  rec->uuid = get_compsysproduct_uuid();
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 {
1571 };
1572 
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;
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 {
1604  heap_free( dirstack->dirs );
1606  heap_free( dirstack );
1607 }
1608 
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;
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--;
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 
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 
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 
1808 {
1809  static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
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();
1842  HANDLE handle;
1843  struct dirstack *dirstack;
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  {
1868  goto done;
1869  }
1871  {
1872  do
1873  {
1874  if (!resize_table( table, row + 1, sizeof(*rec) ))
1875  {
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 );
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  {
1897  continue;
1898  }
1899  else if (num_expected_rows && row == num_expected_rows - 1)
1900  {
1901  row++;
1902  FindClose( handle );
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:
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 
1927 {
1928  HDC hdc = GetDC( NULL );
1929  UINT32 ret;
1930 
1931  if (!hdc) return 96;
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;
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;
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();
1963  HANDLE handle;
1964  struct dirstack *dirstack;
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  {
1989  goto done;
1990  }
1992  {
1993  do
1994  {
1995  if (!resize_table( table, row + 1, sizeof(*rec) ))
1996  {
1997  FindClose( handle );
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 );
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  {
2019  continue;
2020  }
2021  else if (num_expected_rows && row == num_expected_rows - 1)
2022  {
2023  row++;
2024  FindClose( handle );
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:
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};
2053  HANDLE handle;
2054  DWORD bytes_returned;
2055 
2056  free.QuadPart = 512 * 1024 * 1024;
2058 
2059  root[4] = dir[0];
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();
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;
2100  if (type == DRIVE_FIXED)
2102  else
2104  rec->model = diskdrive_modelW;
2107  get_freespace( root, &size );
2108  rec->size = size;
2109  if (!match_row( table, row, cond, &status ))
2110  {
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 
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();
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;
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  {
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 
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;
2201 
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  {
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};
2242  return heap_strdupW( buf );
2243 }
2245 {
2246  static const WCHAR fmtW[] = {'%','0','8','X',0};
2247  DWORD serial = 0;
2248  WCHAR buffer[9];
2249 
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();
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 );
2288  if (!match_row( table, row, cond, &status ))
2289  {
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 
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 }
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;
2354 
2355  ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
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 );
2385  rec->name = heap_strdupW( aa->FriendlyName );
2386  rec->netconnection_status = get_connection_status( aa->OperStatus );
2387  rec->physicaladapter = physical;
2389  rec->speed = 1000000;
2390  if (!match_row( table, row, cond, &status ))
2391  {
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  {
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 
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;
2589 
2590  ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size );
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  {
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;
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;
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;
2667  HDEVINFO device_info_set;
2668  SP_DEVINFO_DATA devinfo = {0};
2669  DWORD idx;
2670 
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  {
2689  if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
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  {
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;
2716  DWORD i, offset = 0, count = 0, size = 0, num_rows = 0;
2717  WCHAR id[20];
2718 
2721 
2722  if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED;
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;
2774  HANDLE snap;
2776  UINT row = 0, offset = 0;
2777 
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;
2801  if (!match_row( table, row, cond, &status ))
2802  {
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;
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;
2838  if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW;
2839  return os_32bitW;
2840 }
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 }
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 }
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 }
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 }
2912 {
2915  NTSTATUS status;
2916 
2917  if ((info = heap_alloc( size )))
2918  {
2920  if (!status) ret = info[index].CurrentMhz;
2921  heap_free( info );
2922  }
2923  return ret;
2924 }
2926 {
2929  NTSTATUS status;
2930 
2931  if ((info = heap_alloc( size )))
2932  {
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;
2947 
2948  if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED;
2949 
2955 
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 */
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;
2975  rec->name = heap_strdupW( name );
2976  rec->num_cores = num_cores;
2979  rec->processortype = 3; /* centr