[WBEMPROX] Sync with Wine Staging 2.9. CORE-13362
[reactos.git] / reactos / dll / win32 / wbemprox / builtin.c
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 #include "wbemprox_private.h"
20
21 #include <winuser.h>
22 #include <wingdi.h>
23 #include <winsock2.h>
24 #include <ws2tcpip.h>
25 #include <iphlpapi.h>
26 #include <tlhelp32.h>
27 #include <winternl.h>
28 #include <winioctl.h>
29 #include <winver.h>
30 #include <ntsecapi.h>
31 #include <winspool.h>
32 #include <sddl.h>
33
34 static const WCHAR class_baseboardW[] =
35 {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0};
36 static const WCHAR class_biosW[] =
37 {'W','i','n','3','2','_','B','I','O','S',0};
38 static const WCHAR class_cdromdriveW[] =
39 {'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0};
40 static const WCHAR class_compsysW[] =
41 {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
42 static const WCHAR class_compsysproductW[] =
43 {'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};
44 static const WCHAR class_datafileW[] =
45 {'C','I','M','_','D','a','t','a','F','i','l','e',0};
46 static const WCHAR class_desktopmonitorW[] =
47 {'W','i','n','3','2','_','D','e','s','k','t','o','p','M','o','n','i','t','o','r',0};
48 static const WCHAR class_directoryW[] =
49 {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0};
50 static const WCHAR class_diskdriveW[] =
51 {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0};
52 static const WCHAR class_diskpartitionW[] =
53 {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0};
54 static const WCHAR class_ip4routetableW[] =
55 {'W','i','n','3','2','_','I','P','4','R','o','u','t','e','T','a','b','l','e',0};
56 static const WCHAR class_logicaldiskW[] =
57 {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0};
58 static const WCHAR class_logicaldisk2W[] =
59 {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0};
60 static const WCHAR class_networkadapterW[] =
61 {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0};
62 static const WCHAR class_networkadapterconfigW[] =
63 {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',
64 'C','o','n','f','i','g','u','r','a','t','i','o','n',0};
65 static const WCHAR class_osW[] =
66 {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
67 static const WCHAR class_paramsW[] =
68 {'_','_','P','A','R','A','M','E','T','E','R','S',0};
69 static const WCHAR class_physicalmediaW[] =
70 {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0};
71 static const WCHAR class_physicalmemoryW[] =
72 {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
73 static const WCHAR class_printerW[] =
74 {'W','i','n','3','2','_','P','r','i','n','t','e','r',0};
75 static const WCHAR class_process_getowner_outW[] =
76 {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W',
77 'N','E','R','_','O','U','T',0};
78 static const WCHAR class_processorW[] =
79 {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0};
80 static const WCHAR class_processor2W[] =
81 {'C','I','M','_','P','r','o','c','e','s','s','o','r',0};
82 static const WCHAR class_qualifiersW[] =
83 {'_','_','Q','U','A','L','I','F','I','E','R','S',0};
84 static const WCHAR class_sidW[] =
85 {'W','i','n','3','2','_','S','I','D',0};
86 static const WCHAR class_sounddeviceW[] =
87 {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0};
88 static const WCHAR class_systemenclosureW[] =
89 {'W','i','n','3','2','_','S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0};
90 static const WCHAR class_videocontrollerW[] =
91 {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0};
92
93 static const WCHAR prop_accountnameW[] =
94 {'A','c','c','o','u','n','t','N','a','m','e',0};
95 static const WCHAR prop_acceptpauseW[] =
96 {'A','c','c','e','p','t','P','a','u','s','e',0};
97 static const WCHAR prop_acceptstopW[] =
98 {'A','c','c','e','p','t','S','t','o','p',0};
99 static const WCHAR prop_accessmaskW[] =
100 {'A','c','c','e','s','s','M','a','s','k',0};
101 static const WCHAR prop_adapterdactypeW[] =
102 {'A','d','a','p','t','e','r','D','A','C','T','y','p','e',0};
103 static const WCHAR prop_adapterramW[] =
104 {'A','d','a','p','t','e','r','R','A','M',0};
105 static const WCHAR prop_adaptertypeW[] =
106 {'A','d','a','p','t','e','r','T','y','p','e',0};
107 static const WCHAR prop_addresswidthW[] =
108 {'A','d','d','r','e','s','s','W','i','d','t','h',0};
109 static const WCHAR prop_attributesW[] =
110 {'A','t','t','r','i','b','u','t','e','s',0};
111 static const WCHAR prop_availabilityW[] =
112 {'A','v','a','i','l','a','b','i','l','i','t','y',0};
113 static const WCHAR prop_binaryrepresentationW[] =
114 {'B','i','n','a','r','y','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
115 static const WCHAR prop_bootableW[] =
116 {'B','o','o','t','a','b','l','e',0};
117 static const WCHAR prop_bootpartitionW[] =
118 {'B','o','o','t','P','a','r','t','i','t','i','o','n',0};
119 static const WCHAR prop_buildnumberW[] =
120 {'B','u','i','l','d','N','u','m','b','e','r',0};
121 static const WCHAR prop_capacityW[] =
122 {'C','a','p','a','c','i','t','y',0};
123 static const WCHAR prop_captionW[] =
124 {'C','a','p','t','i','o','n',0};
125 static const WCHAR prop_chassistypesW[] =
126 {'C','h','a','s','s','i','s','T','y','p','e','s',0};
127 static const WCHAR prop_classW[] =
128 {'C','l','a','s','s',0};
129 static const WCHAR prop_codesetW[] =
130 {'C','o','d','e','S','e','t',0};
131 static const WCHAR prop_commandlineW[] =
132 {'C','o','m','m','a','n','d','L','i','n','e',0};
133 static const WCHAR prop_configmanagererrorcodeW[] =
134 {'C','o','n','f','i','g','M','a','n','a','g','e','r','E','r','r','o','r','C','o','d','e',0};
135 static const WCHAR prop_countrycodeW[] =
136 {'C','o','u','n','t','r','y','C','o','d','e',0};
137 static const WCHAR prop_cpustatusW[] =
138 {'C','p','u','S','t','a','t','u','s',0};
139 static const WCHAR prop_csdversionW[] =
140 {'C','S','D','V','e','r','s','i','o','n',0};
141 static const WCHAR prop_currentbitsperpixelW[] =
142 {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0};
143 static const WCHAR prop_currentclockspeedW[] =
144 {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0};
145 static const WCHAR prop_currenthorizontalresW[] =
146 {'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};
147 static const WCHAR prop_currentrefreshrateW[] =
148 {'C','u','r','r','e','n','t','R','e','f','r','e','s','h','R','a','t','e',0};
149 static const WCHAR prop_currentscanmodeW[] =
150 {'C','u','r','r','e','n','t','S','c','a','n','M','o','d','e',0};
151 static const WCHAR prop_currentverticalresW[] =
152 {'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};
153 static const WCHAR prop_datawidthW[] =
154 {'D','a','t','a','W','i','d','t','h',0};
155 static const WCHAR prop_defaultipgatewayW[] =
156 {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0};
157 static const WCHAR prop_defaultvalueW[] =
158 {'D','e','f','a','u','l','t','V','a','l','u','e',0};
159 static const WCHAR prop_descriptionW[] =
160 {'D','e','s','c','r','i','p','t','i','o','n',0};
161 static const WCHAR prop_destinationW[] =
162 {'D','e','s','t','i','n','a','t','i','o','n',0};
163 static const WCHAR prop_deviceidW[] =
164 {'D','e','v','i','c','e','I','d',0};
165 static const WCHAR prop_dhcpenabledW[] =
166 {'D','H','C','P','E','n','a','b','l','e','d',0};
167 static const WCHAR prop_directionW[] =
168 {'D','i','r','e','c','t','i','o','n',0};
169 static const WCHAR prop_displaynameW[] =
170 {'D','i','s','p','l','a','y','N','a','m','e',0};
171 static const WCHAR prop_diskindexW[] =
172 {'D','i','s','k','I','n','d','e','x',0};
173 static const WCHAR prop_dnshostnameW[] =
174 {'D','N','S','H','o','s','t','N','a','m','e',0};
175 static const WCHAR prop_dnsserversearchorderW[] =
176 {'D','N','S','S','e','r','v','e','r','S','e','a','r','c','h','O','r','d','e','r',0};
177 static const WCHAR prop_domainW[] =
178 {'D','o','m','a','i','n',0};
179 static const WCHAR prop_domainroleW[] =
180 {'D','o','m','a','i','n','R','o','l','e',0};
181 static const WCHAR prop_driveW[] =
182 {'D','r','i','v','e',0};
183 static const WCHAR prop_driverdateW[] =
184 {'D','r','i','v','e','r','D','a','t','e',0};
185 static const WCHAR prop_drivernameW[] =
186 {'D','r','i','v','e','r','N','a','m','e',0};
187 static const WCHAR prop_driverversionW[] =
188 {'D','r','i','v','e','r','V','e','r','s','i','o','n',0};
189 static const WCHAR prop_drivetypeW[] =
190 {'D','r','i','v','e','T','y','p','e',0};
191 static const WCHAR prop_familyW[] =
192 {'F','a','m','i','l','y',0};
193 static const WCHAR prop_filesystemW[] =
194 {'F','i','l','e','S','y','s','t','e','m',0};
195 static const WCHAR prop_flavorW[] =
196 {'F','l','a','v','o','r',0};
197 static const WCHAR prop_freespaceW[] =
198 {'F','r','e','e','S','p','a','c','e',0};
199 static const WCHAR prop_handleW[] =
200 {'H','a','n','d','l','e',0};
201 static const WCHAR prop_horizontalresolutionW[] =
202 {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
203 static const WCHAR prop_idW[] =
204 {'I','D',0};
205 static const WCHAR prop_identificationcodeW[] =
206 {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0};
207 static const WCHAR prop_identifyingnumberW[] =
208 {'I','d','e','n','t','i','f','y','i','n','g','N','u','m','b','e','r',0};
209 static const WCHAR prop_indexW[] =
210 {'I','n','d','e','x',0};
211 static const WCHAR prop_installdateW[] =
212 {'I','n','s','t','a','l','l','D','a','t','e',0};
213 static const WCHAR prop_installeddisplaydriversW[]=
214 {'I','n','s','t','a','l','l','e','d','D','i','s','p','l','a','y','D','r','i','v','e','r','s',0};
215 static const WCHAR prop_interfaceindexW[] =
216 {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0};
217 static const WCHAR prop_interfacetypeW[] =
218 {'I','n','t','e','r','f','a','c','e','T','y','p','e',0};
219 static const WCHAR prop_intvalueW[] =
220 {'I','n','t','e','g','e','r','V','a','l','u','e',0};
221 static const WCHAR prop_ipconnectionmetricW[] =
222 {'I','P','C','o','n','n','e','c','t','i','o','n','M','e','t','r','i','c',0};
223 static const WCHAR prop_ipenabledW[] =
224 {'I','P','E','n','a','b','l','e','d',0};
225 static const WCHAR prop_lastbootuptimeW[] =
226 {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0};
227 static const WCHAR prop_localW[] =
228 {'L','o','c','a','l',0};
229 static const WCHAR prop_localdatetimeW[] =
230 {'L','o','c','a','l','D','a','t','e','T','i','m','e',0};
231 static const WCHAR prop_localeW[] =
232 {'L','o','c','a','l','e',0};
233 static const WCHAR prop_locationW[] =
234 {'L','o','c','a','t','i','o','n',0};
235 static const WCHAR prop_lockpresentW[] =
236 {'L','o','c','k','P','r','e','s','e','n','t',0};
237 static const WCHAR prop_macaddressW[] =
238 {'M','A','C','A','d','d','r','e','s','s',0};
239 static const WCHAR prop_manufacturerW[] =
240 {'M','a','n','u','f','a','c','t','u','r','e','r',0};
241 static const WCHAR prop_maxclockspeedW[] =
242 {'M','a','x','C','l','o','c','k','S','p','e','e','d',0};
243 static const WCHAR prop_mediatypeW[] =
244 {'M','e','d','i','a','T','y','p','e',0};
245 static const WCHAR prop_memberW[] =
246 {'M','e','m','b','e','r',0};
247 static const WCHAR prop_memorytypeW[] =
248 {'M','e','m','o','r','y','T','y','p','e',0};
249 static const WCHAR prop_methodW[] =
250 {'M','e','t','h','o','d',0};
251 static const WCHAR prop_modelW[] =
252 {'M','o','d','e','l',0};
253 static const WCHAR prop_netconnectionstatusW[] =
254 {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0};
255 static const WCHAR prop_networkW[] =
256 {'N','e','t','w','o','r','k',0};
257 static const WCHAR prop_nexthopW[] =
258 {'N','e','x','t','H','o','p',0};
259 static const WCHAR prop_numcoresW[] =
260 {'N','u','m','b','e','r','O','f','C','o','r','e','s',0};
261 static const WCHAR prop_numlogicalprocessorsW[] =
262 {'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};
263 static const WCHAR prop_numprocessorsW[] =
264 {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
265 static const WCHAR prop_osarchitectureW[] =
266 {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0};
267 static const WCHAR prop_oslanguageW[] =
268 {'O','S','L','a','n','g','u','a','g','e',0};
269 static const WCHAR prop_osproductsuiteW[] =
270 {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0};
271 static const WCHAR prop_ostypeW[] =
272 {'O','S','T','y','p','e',0};
273 static const WCHAR prop_parameterW[] =
274 {'P','a','r','a','m','e','t','e','r',0};
275 static const WCHAR prop_physicaladapterW[] =
276 {'P','h','y','s','i','c','a','l','A','d','a','p','t','e','r',0};
277 static const WCHAR prop_pixelsperxlogicalinchW[] =
278 {'P','i','x','e','l','s','P','e','r','X','L','o','g','i','c','a','l','I','n','c','h',0};
279 static const WCHAR prop_pnpdeviceidW[] =
280 {'P','N','P','D','e','v','i','c','e','I','D',0};
281 static const WCHAR prop_portnameW[] =
282 {'P','o','r','t','N','a','m','e',0};
283 static const WCHAR prop_pprocessidW[] =
284 {'P','a','r','e','n','t','P','r','o','c','e','s','s','I','D',0};
285 static const WCHAR prop_primaryW[] =
286 {'P','r','i','m','a','r','y',0};
287 static const WCHAR prop_processidW[] =
288 {'P','r','o','c','e','s','s','I','D',0};
289 static const WCHAR prop_processoridW[] =
290 {'P','r','o','c','e','s','s','o','r','I','d',0};
291 static const WCHAR prop_processortypeW[] =
292 {'P','r','o','c','e','s','s','o','r','T','y','p','e',0};
293 static const WCHAR prop_productW[] =
294 {'P','r','o','d','u','c','t',0};
295 static const WCHAR prop_productnameW[] =
296 {'P','r','o','d','u','c','t','N','a','m','e',0};
297 static const WCHAR prop_referenceddomainnameW[] =
298 {'R','e','f','e','r','e','n','c','e','d','D','o','m','a','i','n','N','a','m','e',0};
299 static const WCHAR prop_releasedateW[] =
300 {'R','e','l','e','a','s','e','D','a','t','e',0};
301 static const WCHAR prop_serialnumberW[] =
302 {'S','e','r','i','a','l','N','u','m','b','e','r',0};
303 static const WCHAR prop_servicepackmajorW[] =
304 {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0};
305 static const WCHAR prop_servicepackminorW[] =
306 {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0};
307 static const WCHAR prop_servicetypeW[] =
308 {'S','e','r','v','i','c','e','T','y','p','e',0};
309 static const WCHAR prop_settingidW[] =
310 {'S','e','t','t','i','n','g','I','D',0};
311 static const WCHAR prop_smbiosbiosversionW[] =
312 {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0};
313 static const WCHAR prop_startmodeW[] =
314 {'S','t','a','r','t','M','o','d','e',0};
315 static const WCHAR prop_sidW[] =
316 {'S','I','D',0};
317 static const WCHAR prop_sidlengthW[] =
318 {'S','i','d','L','e','n','g','t','h',0};
319 static const WCHAR prop_sizeW[] =
320 {'S','i','z','e',0};
321 static const WCHAR prop_speedW[] =
322 {'S','p','e','e','d',0};
323 static const WCHAR prop_startingoffsetW[] =
324 {'S','t','a','r','t','i','n','g','O','f','f','s','e','t',0};
325 static const WCHAR prop_stateW[] =
326 {'S','t','a','t','e',0};
327 static const WCHAR prop_statusW[] =
328 {'S','t','a','t','u','s',0};
329 static const WCHAR prop_statusinfoW[] =
330 {'S','t','a','t','u','s','I','n','f','o',0};
331 static const WCHAR prop_strvalueW[] =
332 {'S','t','r','i','n','g','V','a','l','u','e',0};
333 static const WCHAR prop_suitemaskW[] =
334 {'S','u','i','t','e','M','a','s','k',0};
335 static const WCHAR prop_systemdirectoryW[] =
336 {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0};
337 static const WCHAR prop_systemnameW[] =
338 {'S','y','s','t','e','m','N','a','m','e',0};
339 static const WCHAR prop_tagW[] =
340 {'T','a','g',0};
341 static const WCHAR prop_threadcountW[] =
342 {'T','h','r','e','a','d','C','o','u','n','t',0};
343 static const WCHAR prop_totalphysicalmemoryW[] =
344 {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
345 static const WCHAR prop_totalvirtualmemorysizeW[] =
346 {'T','o','t','a','l','V','i','r','t','u','a','l','M','e','m','o','r','y','S','i','z','e',0};
347 static const WCHAR prop_totalvisiblememorysizeW[] =
348 {'T','o','t','a','l','V','i','s','i','b','l','e','M','e','m','o','r','y','S','i','z','e',0};
349 static const WCHAR prop_typeW[] =
350 {'T','y','p','e',0};
351 static const WCHAR prop_uniqueidW[] =
352 {'U','n','i','q','u','e','I','d',0};
353 static const WCHAR prop_usernameW[] =
354 {'U','s','e','r','N','a','m','e',0};
355 static const WCHAR prop_uuidW[] =
356 {'U','U','I','D',0};
357 static const WCHAR prop_varianttypeW[] =
358 {'V','a','r','i','a','n','t','T','y','p','e',0};
359 static const WCHAR prop_versionW[] =
360 {'V','e','r','s','i','o','n',0};
361 static const WCHAR prop_vendorW[] =
362 {'V','e','n','d','o','r',0};
363 static const WCHAR prop_videoarchitectureW[] =
364 {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0};
365 static const WCHAR prop_videomemorytypeW[] =
366 {'V','i','d','e','o','M','e','m','o','r','y','T','y','p','e',0};
367 static const WCHAR prop_videomodedescriptionW[] =
368 {'V','i','d','e','o','M','o','d','e','D','e','s','c','r','i','p','t','i','o','n',0};
369 static const WCHAR prop_videoprocessorW[] =
370 {'V','i','d','e','o','P','r','o','c','e','s','s','o','r',0};
371 static const WCHAR prop_volumenameW[] =
372 {'V','o','l','u','m','e','N','a','m','e',0};
373 static const WCHAR prop_volumeserialnumberW[] =
374 {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0};
375 static const WCHAR prop_workingsetsizeW[] =
376 {'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0};
377
378 /* column definitions must be kept in sync with record structures below */
379 static const struct column col_baseboard[] =
380 {
381 { prop_manufacturerW, CIM_STRING },
382 { prop_modelW, CIM_STRING },
383 { prop_nameW, CIM_STRING },
384 { prop_productW, CIM_STRING },
385 { prop_serialnumberW, CIM_STRING },
386 { prop_tagW, CIM_STRING|COL_FLAG_KEY },
387 { prop_versionW, CIM_STRING }
388 };
389 static const struct column col_bios[] =
390 {
391 { prop_descriptionW, CIM_STRING },
392 { prop_identificationcodeW, CIM_STRING },
393 { prop_manufacturerW, CIM_STRING },
394 { prop_nameW, CIM_STRING },
395 { prop_releasedateW, CIM_DATETIME },
396 { prop_serialnumberW, CIM_STRING },
397 { prop_smbiosbiosversionW, CIM_STRING },
398 { prop_versionW, CIM_STRING|COL_FLAG_KEY }
399 };
400 static const struct column col_cdromdrive[] =
401 {
402 { prop_deviceidW, CIM_STRING|COL_FLAG_KEY },
403 { prop_driveW, CIM_STRING|COL_FLAG_DYNAMIC },
404 { prop_mediatypeW, CIM_STRING },
405 { prop_nameW, CIM_STRING },
406 { prop_pnpdeviceidW, CIM_STRING }
407 };
408 static const struct column col_compsys[] =
409 {
410 { prop_descriptionW, CIM_STRING },
411 { prop_domainW, CIM_STRING },
412 { prop_domainroleW, CIM_UINT16, VT_I4 },
413 { prop_manufacturerW, CIM_STRING },
414 { prop_modelW, CIM_STRING },
415 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
416 { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
417 { prop_numprocessorsW, CIM_UINT32, VT_I4 },
418 { prop_totalphysicalmemoryW, CIM_UINT64 },
419 { prop_usernameW, CIM_STRING|COL_FLAG_DYNAMIC }
420 };
421 static const struct column col_compsysproduct[] =
422 {
423 { prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY },
424 { prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC },
425 { prop_vendorW, CIM_STRING },
426 };
427 static const struct column col_datafile[] =
428 {
429 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
430 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
431 };
432 static const struct column col_desktopmonitor[] =
433 {
434 { prop_pixelsperxlogicalinchW, CIM_UINT32 }
435 };
436 static const struct column col_directory[] =
437 {
438 { prop_accessmaskW, CIM_UINT32 },
439 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }
440 };
441 static const struct column col_diskdrive[] =
442 {
443 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
444 { prop_indexW, CIM_UINT32, VT_I4 },
445 { prop_interfacetypeW, CIM_STRING },
446 { prop_manufacturerW, CIM_STRING },
447 { prop_mediatypeW, CIM_STRING },
448 { prop_modelW, CIM_STRING },
449 { prop_pnpdeviceidW, CIM_STRING },
450 { prop_serialnumberW, CIM_STRING },
451 { prop_sizeW, CIM_UINT64 }
452 };
453 static const struct column col_diskpartition[] =
454 {
455 { prop_bootableW, CIM_BOOLEAN },
456 { prop_bootpartitionW, CIM_BOOLEAN },
457 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
458 { prop_diskindexW, CIM_UINT32, VT_I4 },
459 { prop_indexW, CIM_UINT32, VT_I4 },
460 { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC },
461 { prop_sizeW, CIM_UINT64 },
462 { prop_startingoffsetW, CIM_UINT64 },
463 { prop_typeW, CIM_STRING|COL_FLAG_DYNAMIC }
464 };
465 static const struct column col_ip4routetable[] =
466 {
467 { prop_destinationW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
468 { prop_interfaceindexW, CIM_SINT32|COL_FLAG_KEY },
469 { prop_nexthopW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
470 };
471 static const struct column col_logicaldisk[] =
472 {
473 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
474 { prop_drivetypeW, CIM_UINT32, VT_I4 },
475 { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC },
476 { prop_freespaceW, CIM_UINT64 },
477 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
478 { prop_sizeW, CIM_UINT64 },
479 { prop_volumenameW, CIM_STRING|COL_FLAG_DYNAMIC },
480 { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC }
481 };
482 static const struct column col_networkadapter[] =
483 {
484 { prop_adaptertypeW, CIM_STRING },
485 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
486 { prop_indexW, CIM_UINT32, VT_I4 },
487 { prop_interfaceindexW, CIM_UINT32, VT_I4 },
488 { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC },
489 { prop_manufacturerW, CIM_STRING },
490 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
491 { prop_netconnectionstatusW, CIM_UINT16, VT_I4 },
492 { prop_physicaladapterW, CIM_BOOLEAN },
493 { prop_pnpdeviceidW, CIM_STRING },
494 { prop_speedW, CIM_UINT64 }
495 };
496 static const struct column col_networkadapterconfig[] =
497 {
498 { prop_defaultipgatewayW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
499 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
500 { prop_dhcpenabledW, CIM_BOOLEAN },
501 { prop_dnshostnameW, CIM_STRING|COL_FLAG_DYNAMIC },
502 { prop_dnsserversearchorderW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
503 { prop_indexW, CIM_UINT32|COL_FLAG_KEY, VT_I4 },
504 { prop_ipconnectionmetricW, CIM_UINT32, VT_I4 },
505 { prop_ipenabledW, CIM_BOOLEAN },
506 { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC },
507 { prop_settingidW, CIM_STRING|COL_FLAG_DYNAMIC }
508 };
509 static const struct column col_os[] =
510 {
511 { prop_buildnumberW, CIM_STRING|COL_FLAG_DYNAMIC },
512 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
513 { prop_codesetW, CIM_STRING|COL_FLAG_DYNAMIC },
514 { prop_countrycodeW, CIM_STRING|COL_FLAG_DYNAMIC },
515 { prop_csdversionW, CIM_STRING|COL_FLAG_DYNAMIC },
516 { prop_installdateW, CIM_DATETIME },
517 { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC },
518 { prop_localdatetimeW, CIM_DATETIME|COL_FLAG_DYNAMIC },
519 { prop_localeW, CIM_STRING|COL_FLAG_DYNAMIC },
520 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
521 { prop_osarchitectureW, CIM_STRING },
522 { prop_oslanguageW, CIM_UINT32, VT_I4 },
523 { prop_osproductsuiteW, CIM_UINT32, VT_I4 },
524 { prop_ostypeW, CIM_UINT16, VT_I4 },
525 { prop_primaryW, CIM_BOOLEAN },
526 { prop_serialnumberW, CIM_STRING },
527 { prop_servicepackmajorW, CIM_UINT16, VT_I4 },
528 { prop_servicepackminorW, CIM_UINT16, VT_I4 },
529 { prop_suitemaskW, CIM_UINT32, VT_I4 },
530 { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC },
531 { prop_totalvirtualmemorysizeW, CIM_UINT64 },
532 { prop_totalvisiblememorysizeW, CIM_UINT64 },
533 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
534 };
535 static const struct column col_param[] =
536 {
537 { prop_classW, CIM_STRING },
538 { prop_methodW, CIM_STRING },
539 { prop_directionW, CIM_SINT32 },
540 { prop_parameterW, CIM_STRING },
541 { prop_typeW, CIM_UINT32 },
542 { prop_varianttypeW, CIM_UINT32 },
543 { prop_defaultvalueW, CIM_UINT32 }
544 };
545 static const struct column col_physicalmedia[] =
546 {
547 { prop_serialnumberW, CIM_STRING },
548 { prop_tagW, CIM_STRING }
549 };
550 static const struct column col_physicalmemory[] =
551 {
552 { prop_capacityW, CIM_UINT64 },
553 { prop_memorytypeW, CIM_UINT16, VT_I4 }
554 };
555 static const struct column col_printer[] =
556 {
557 { prop_attributesW, CIM_UINT32 },
558 { prop_drivernameW, CIM_STRING|COL_FLAG_DYNAMIC },
559 { prop_horizontalresolutionW, CIM_UINT32 },
560 { prop_localW, CIM_BOOLEAN },
561 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
562 { prop_networkW, CIM_BOOLEAN },
563 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
564 { prop_portnameW, CIM_STRING|COL_FLAG_DYNAMIC },
565 { prop_locationW, CIM_STRING|COL_FLAG_DYNAMIC },
566 };
567 static const struct column col_process[] =
568 {
569 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
570 { prop_commandlineW, CIM_STRING|COL_FLAG_DYNAMIC },
571 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
572 { prop_handleW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
573 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
574 { prop_pprocessidW, CIM_UINT32, VT_I4 },
575 { prop_processidW, CIM_UINT32, VT_I4 },
576 { prop_threadcountW, CIM_UINT32, VT_I4 },
577 { prop_workingsetsizeW, CIM_UINT64 },
578 /* methods */
579 { method_getownerW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
580 };
581 static const struct column col_processor[] =
582 {
583 { prop_addresswidthW, CIM_UINT16, VT_I4 },
584 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
585 { prop_cpustatusW, CIM_UINT16 },
586 { prop_currentclockspeedW, CIM_UINT32, VT_I4 },
587 { prop_datawidthW, CIM_UINT16, VT_I4 },
588 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
589 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
590 { prop_familyW, CIM_UINT16, VT_I4 },
591 { prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC },
592 { prop_maxclockspeedW, CIM_UINT32, VT_I4 },
593 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
594 { prop_numcoresW, CIM_UINT32, VT_I4 },
595 { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 },
596 { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC },
597 { prop_processortypeW, CIM_UINT16, VT_I4 },
598 { prop_uniqueidW, CIM_STRING },
599 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC }
600 };
601 static const struct column col_qualifier[] =
602 {
603 { prop_classW, CIM_STRING },
604 { prop_memberW, CIM_STRING },
605 { prop_typeW, CIM_UINT32 },
606 { prop_flavorW, CIM_SINT32 },
607 { prop_nameW, CIM_STRING },
608 { prop_intvalueW, CIM_SINT32 },
609 { prop_strvalueW, CIM_STRING }
610 };
611 static const struct column col_service[] =
612 {
613 { prop_acceptpauseW, CIM_BOOLEAN },
614 { prop_acceptstopW, CIM_BOOLEAN },
615 { prop_displaynameW, CIM_STRING|COL_FLAG_DYNAMIC },
616 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
617 { prop_processidW, CIM_UINT32 },
618 { prop_servicetypeW, CIM_STRING },
619 { prop_startmodeW, CIM_STRING },
620 { prop_stateW, CIM_STRING },
621 { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC },
622 /* methods */
623 { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
624 { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
625 { method_startserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
626 { method_stopserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
627 };
628 static const struct column col_sid[] =
629 {
630 { prop_accountnameW, CIM_STRING|COL_FLAG_DYNAMIC },
631 { prop_binaryrepresentationW, CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
632 { prop_referenceddomainnameW, CIM_STRING|COL_FLAG_DYNAMIC },
633 { prop_sidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
634 { prop_sidlengthW, CIM_UINT32 }
635 };
636 static const struct column col_sounddevice[] =
637 {
638 { prop_nameW, CIM_STRING },
639 { prop_productnameW, CIM_STRING },
640 { prop_statusinfoW, CIM_UINT16, VT_I4 }
641 };
642 static const struct column col_stdregprov[] =
643 {
644 { method_enumkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
645 { method_enumvaluesW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
646 { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
647 };
648 static const struct column col_systemenclosure[] =
649 {
650 { prop_captionW, CIM_STRING },
651 { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY },
652 { prop_descriptionW, CIM_STRING },
653 { prop_lockpresentW, CIM_BOOLEAN },
654 { prop_manufacturerW, CIM_STRING },
655 { prop_nameW, CIM_STRING },
656 { prop_tagW, CIM_STRING },
657 };
658 static const struct column col_systemsecurity[] =
659 {
660 { method_getsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
661 { method_setsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD },
662 };
663 static const struct column col_videocontroller[] =
664 {
665 { prop_adapterdactypeW, CIM_STRING },
666 { prop_adapterramW, CIM_UINT32, VT_I4 },
667 { prop_availabilityW, CIM_UINT16 },
668 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC },
669 { prop_configmanagererrorcodeW, CIM_UINT32, VT_I4 },
670 { prop_currentbitsperpixelW, CIM_UINT32, VT_I4 },
671 { prop_currenthorizontalresW, CIM_UINT32, VT_I4 },
672 { prop_currentrefreshrateW, CIM_UINT32, VT_I4 },
673 { prop_currentscanmodeW, CIM_UINT16, VT_I4 },
674 { prop_currentverticalresW, CIM_UINT32, VT_I4 },
675 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
676 { prop_deviceidW, CIM_STRING|COL_FLAG_KEY },
677 { prop_driverdateW, CIM_DATETIME },
678 { prop_driverversionW, CIM_STRING },
679 { prop_installeddisplaydriversW,CIM_STRING },
680 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC },
681 { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC },
682 { prop_statusW, CIM_STRING },
683 { prop_videoarchitectureW, CIM_UINT16, VT_I4 },
684 { prop_videomemorytypeW, CIM_UINT16, VT_I4 },
685 { prop_videomodedescriptionW, CIM_STRING|COL_FLAG_DYNAMIC },
686 { prop_videoprocessorW, CIM_STRING|COL_FLAG_DYNAMIC },
687 };
688
689 static const WCHAR baseboard_manufacturerW[] =
690 {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0};
691 static const WCHAR baseboard_serialnumberW[] =
692 {'N','o','n','e',0};
693 static const WCHAR baseboard_tagW[] =
694 {'B','a','s','e',' ','B','o','a','r','d',0};
695 static const WCHAR baseboard_versionW[] =
696 {'1','.','0',0};
697 static const WCHAR bios_descriptionW[] =
698 {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0};
699 static const WCHAR bios_manufacturerW[] =
700 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
701 static const WCHAR bios_nameW[] =
702 {'W','I','N','E',' ','B','I','O','S',0};
703 static const WCHAR bios_releasedateW[] =
704 {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
705 static const WCHAR bios_serialnumberW[] =
706 {'0',0};
707 static const WCHAR bios_smbiosbiosversionW[] =
708 {'W','i','n','e',0};
709 static const WCHAR bios_versionW[] =
710 {'W','I','N','E',' ',' ',' ','-',' ','1',0};
711 static const WCHAR cdromdrive_mediatypeW[] =
712 {'C','D','-','R','O','M',0};
713 static const WCHAR cdromdrive_nameW[] =
714 {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0};
715 static const WCHAR cdromdrive_pnpdeviceidW[]=
716 {'I','D','E','\\','C','D','R','O','M','W','I','N','E','_','C','D','-','R','O','M',
717 '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_',
718 '_','_','_','_','_','_','_','1','.','0','_','_','_','_','_','\\','5','&','3','A','2',
719 'A','5','8','5','4','&','0','&','1','.','0','.','0',0};
720 static const WCHAR compsys_descriptionW[] =
721 {'A','T','/','A','T',' ','C','O','M','P','A','T','I','B','L','E',0};
722 static const WCHAR compsys_domainW[] =
723 {'W','O','R','K','G','R','O','U','P',0};
724 static const WCHAR compsys_manufacturerW[] =
725 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0};
726 static const WCHAR compsys_modelW[] =
727 {'W','i','n','e',0};
728 static const WCHAR compsysproduct_identifyingnumberW[] =
729 {'0',0};
730 static const WCHAR compsysproduct_uuidW[] =
731 {'d','e','a','d','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-',
732 'd','e','a','d','d','e','a','d','d','e','a','d',0};
733 static const WCHAR compsysproduct_vendorW[] =
734 {'W','i','n','e',0};
735 static const WCHAR diskdrive_interfacetypeW[] =
736 {'I','D','E',0};
737 static const WCHAR diskdrive_manufacturerW[] =
738 {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0};
739 static const WCHAR diskdrive_mediatype_fixedW[] =
740 {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0};
741 static const WCHAR diskdrive_mediatype_removableW[] =
742 {'R','e','m','o','v','a','b','l','e',' ','m','e','d','i','a',0};
743 static const WCHAR diskdrive_modelW[] =
744 {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0};
745 static const WCHAR diskdrive_pnpdeviceidW[] =
746 {'I','D','E','\\','D','i','s','k','\\','V','E','N','_','W','I','N','E',0};
747 static const WCHAR diskdrive_serialW[] =
748 {'W','I','N','E','H','D','I','S','K',0};
749 static const WCHAR networkadapter_pnpdeviceidW[]=
750 {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&',
751 'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\',
752 '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0};
753 static const WCHAR os_32bitW[] =
754 {'3','2','-','b','i','t',0};
755 static const WCHAR os_64bitW[] =
756 {'6','4','-','b','i','t',0};
757 static const WCHAR os_installdateW[] =
758 {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
759 static const WCHAR os_serialnumberW[] =
760 {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0};
761 static const WCHAR physicalmedia_tagW[] =
762 {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0};
763 static const WCHAR sounddevice_productnameW[] =
764 {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0};
765 static const WCHAR systemenclosure_systemenclosureW[] =
766 {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',0};
767 static const WCHAR systemenclosure_tagW[] =
768 {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',' ','0',0};
769 static const WCHAR systemenclosure_manufacturerW[] =
770 {'W','i','n','e',0};
771 static const WCHAR videocontroller_dactypeW[] =
772 {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0};
773 static const WCHAR videocontroller_deviceidW[] =
774 {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0};
775 static const WCHAR videocontroller_driverDateW[] =
776 {'2','0','1','7','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0};
777 static const WCHAR videocontroller_driverversionW[] =
778 {'1','.','0',0};
779 static const WCHAR videocontroller_statusW[] =
780 {'O','K',0};
781
782 #include "pshpack1.h"
783 struct record_baseboard
784 {
785 const WCHAR *manufacturer;
786 const WCHAR *model;
787 const WCHAR *name;
788 const WCHAR *product;
789 const WCHAR *serialnumber;
790 const WCHAR *tag;
791 const WCHAR *version;
792 };
793 struct record_bios
794 {
795 const WCHAR *description;
796 const WCHAR *identificationcode;
797 const WCHAR *manufacturer;
798 const WCHAR *name;
799 const WCHAR *releasedate;
800 const WCHAR *serialnumber;
801 const WCHAR *smbiosbiosversion;
802 const WCHAR *version;
803 };
804 struct record_cdromdrive
805 {
806 const WCHAR *device_id;
807 const WCHAR *drive;
808 const WCHAR *mediatype;
809 const WCHAR *name;
810 const WCHAR *pnpdevice_id;
811 };
812 struct record_computersystem
813 {
814 const WCHAR *description;
815 const WCHAR *domain;
816 UINT16 domainrole;
817 const WCHAR *manufacturer;
818 const WCHAR *model;
819 const WCHAR *name;
820 UINT32 num_logical_processors;
821 UINT32 num_processors;
822 UINT64 total_physical_memory;
823 const WCHAR *username;
824 };
825 struct record_computersystemproduct
826 {
827 const WCHAR *identifyingnumber;
828 const WCHAR *uuid;
829 const WCHAR *vendor;
830 };
831 struct record_datafile
832 {
833 const WCHAR *name;
834 const WCHAR *version;
835 };
836 struct record_desktopmonitor
837 {
838 UINT32 pixelsperxlogicalinch;
839 };
840 struct record_directory
841 {
842 UINT32 accessmask;
843 const WCHAR *name;
844 };
845 struct record_diskdrive
846 {
847 const WCHAR *device_id;
848 UINT32 index;
849 const WCHAR *interfacetype;
850 const WCHAR *manufacturer;
851 const WCHAR *mediatype;
852 const WCHAR *model;
853 const WCHAR *pnpdevice_id;
854 const WCHAR *serialnumber;
855 UINT64 size;
856 };
857 struct record_diskpartition
858 {
859 int bootable;
860 int bootpartition;
861 const WCHAR *device_id;
862 UINT32 diskindex;
863 UINT32 index;
864 const WCHAR *pnpdevice_id;
865 UINT64 size;
866 UINT64 startingoffset;
867 const WCHAR *type;
868 };
869 struct record_ip4routetable
870 {
871 const WCHAR *destination;
872 INT32 interfaceindex;
873 const WCHAR *nexthop;
874 };
875 struct record_logicaldisk
876 {
877 const WCHAR *device_id;
878 UINT32 drivetype;
879 const WCHAR *filesystem;
880 UINT64 freespace;
881 const WCHAR *name;
882 UINT64 size;
883 const WCHAR *volumename;
884 const WCHAR *volumeserialnumber;
885 };
886 struct record_networkadapter
887 {
888 const WCHAR *adaptertype;
889 const WCHAR *device_id;
890 UINT32 index;
891 UINT32 interface_index;
892 const WCHAR *mac_address;
893 const WCHAR *manufacturer;
894 const WCHAR *name;
895 UINT16 netconnection_status;
896 int physicaladapter;
897 const WCHAR *pnpdevice_id;
898 UINT64 speed;
899 };
900 struct record_networkadapterconfig
901 {
902 const struct array *defaultipgateway;
903 const WCHAR *description;
904 int dhcpenabled;
905 const WCHAR *dnshostname;
906 const struct array *dnsserversearchorder;
907 UINT32 index;
908 UINT32 ipconnectionmetric;
909 int ipenabled;
910 const WCHAR *mac_address;
911 const WCHAR *settingid;
912 };
913 struct record_operatingsystem
914 {
915 const WCHAR *buildnumber;
916 const WCHAR *caption;
917 const WCHAR *codeset;
918 const WCHAR *countrycode;
919 const WCHAR *csdversion;
920 const WCHAR *installdate;
921 const WCHAR *lastbootuptime;
922 const WCHAR *localdatetime;
923 const WCHAR *locale;
924 const WCHAR *name;
925 const WCHAR *osarchitecture;
926 UINT32 oslanguage;
927 UINT32 osproductsuite;
928 UINT16 ostype;
929 int primary;
930 const WCHAR *serialnumber;
931 UINT16 servicepackmajor;
932 UINT16 servicepackminor;
933 UINT32 suitemask;
934 const WCHAR *systemdirectory;
935 UINT64 totalvirtualmemorysize;
936 UINT64 totalvisiblememorysize;
937 const WCHAR *version;
938 };
939 struct record_param
940 {
941 const WCHAR *class;
942 const WCHAR *method;
943 INT32 direction;
944 const WCHAR *parameter;
945 UINT32 type;
946 UINT32 varianttype;
947 UINT32 defaultvalue;
948 };
949 struct record_physicalmedia
950 {
951 const WCHAR *serialnumber;
952 const WCHAR *tag;
953 };
954 struct record_physicalmemory
955 {
956 UINT64 capacity;
957 UINT16 memorytype;
958 };
959 struct record_printer
960 {
961 UINT32 attributes;
962 const WCHAR *drivername;
963 UINT32 horizontalresolution;
964 int local;
965 const WCHAR *name;
966 int network;
967 const WCHAR *device_id;
968 const WCHAR *portname;
969 const WCHAR *location;
970 };
971 struct record_process
972 {
973 const WCHAR *caption;
974 const WCHAR *commandline;
975 const WCHAR *description;
976 const WCHAR *handle;
977 const WCHAR *name;
978 UINT32 pprocess_id;
979 UINT32 process_id;
980 UINT32 thread_count;
981 UINT64 workingsetsize;
982 /* methods */
983 class_method *get_owner;
984 };
985 struct record_processor
986 {
987 UINT16 addresswidth;
988 const WCHAR *caption;
989 UINT16 cpu_status;
990 UINT32 currentclockspeed;
991 UINT16 datawidth;
992 const WCHAR *description;
993 const WCHAR *device_id;
994 UINT16 family;
995 const WCHAR *manufacturer;
996 UINT32 maxclockspeed;
997 const WCHAR *name;
998 UINT32 num_cores;
999 UINT32 num_logical_processors;
1000 const WCHAR *processor_id;
1001 UINT16 processortype;
1002 const WCHAR *unique_id;
1003 const WCHAR *version;
1004 };
1005 struct record_qualifier
1006 {
1007 const WCHAR *class;
1008 const WCHAR *member;
1009 UINT32 type;
1010 INT32 flavor;
1011 const WCHAR *name;
1012 INT32 intvalue;
1013 const WCHAR *strvalue;
1014 };
1015 struct record_service
1016 {
1017 int accept_pause;
1018 int accept_stop;
1019 const WCHAR *displayname;
1020 const WCHAR *name;
1021 UINT32 process_id;
1022 const WCHAR *servicetype;
1023 const WCHAR *startmode;
1024 const WCHAR *state;
1025 const WCHAR *systemname;
1026 /* methods */
1027 class_method *pause_service;
1028 class_method *resume_service;
1029 class_method *start_service;
1030 class_method *stop_service;
1031 };
1032 struct record_sid
1033 {
1034 const WCHAR *accountname;
1035 const struct array *binaryrepresentation;
1036 const WCHAR *referenceddomainname;
1037 const WCHAR *sid;
1038 UINT32 sidlength;
1039 };
1040 struct record_sounddevice
1041 {
1042 const WCHAR *name;
1043 const WCHAR *productname;
1044 UINT16 statusinfo;
1045 };
1046 struct record_stdregprov
1047 {
1048 class_method *enumkey;
1049 class_method *enumvalues;
1050 class_method *getstringvalue;
1051 };
1052 struct record_systemsecurity
1053 {
1054 class_method *getsd;
1055 class_method *setsd;
1056 };
1057 struct record_systemenclosure
1058 {
1059 const WCHAR *caption;
1060 const struct array *chassistypes;
1061 const WCHAR *description;
1062 int lockpresent;
1063 const WCHAR *manufacturer;
1064 const WCHAR *name;
1065 const WCHAR *tag;
1066 };
1067 struct record_videocontroller
1068 {
1069 const WCHAR *adapter_dactype;
1070 UINT32 adapter_ram;
1071 UINT16 availability;
1072 const WCHAR *caption;
1073 UINT32 config_errorcode;
1074 UINT32 current_bitsperpixel;
1075 UINT32 current_horizontalres;
1076 UINT32 current_refreshrate;
1077 UINT16 current_scanmode;
1078 UINT32 current_verticalres;
1079 const WCHAR *description;
1080 const WCHAR *device_id;
1081 const WCHAR *driverdate;
1082 const WCHAR *driverversion;
1083 const WCHAR *installeddriver;
1084 const WCHAR *name;
1085 const WCHAR *pnpdevice_id;
1086 const WCHAR *status;
1087 UINT16 videoarchitecture;
1088 UINT16 videomemorytype;
1089 const WCHAR *videomodedescription;
1090 const WCHAR *videoprocessor;
1091 };
1092 #include "poppack.h"
1093
1094 static const struct record_baseboard data_baseboard[] =
1095 {
1096 { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW }
1097 };
1098 static const struct record_bios data_bios[] =
1099 {
1100 { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW,
1101 bios_smbiosbiosversionW, bios_versionW }
1102 };
1103 static const struct record_param data_param[] =
1104 {
1105 { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1106 { class_processW, method_getownerW, -1, param_userW, CIM_STRING },
1107 { class_processW, method_getownerW, -1, param_domainW, CIM_STRING },
1108 { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1109 { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1110 { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1111 { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1112 { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1113 { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING },
1114 { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1115 { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
1116 { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1117 { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING },
1118 { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1119 { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY },
1120 { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY },
1121 { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
1122 { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING },
1123 { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING },
1124 { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1125 { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING },
1126 { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1127 { class_systemsecurityW, method_getsdW, -1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
1128 { class_systemsecurityW, method_setsdW, 1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY },
1129 { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
1130 };
1131
1132 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1133 WBEM_FLAVOR_ORIGIN_PROPAGATED)
1134
1135 static const struct record_physicalmedia data_physicalmedia[] =
1136 {
1137 { diskdrive_serialW, physicalmedia_tagW }
1138 };
1139 static const struct record_qualifier data_qualifier[] =
1140 {
1141 { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 },
1142 { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 }
1143 };
1144 static const struct record_sounddevice data_sounddevice[] =
1145 {
1146 { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ }
1147 };
1148 static const struct record_stdregprov data_stdregprov[] =
1149 {
1150 { reg_enum_key, reg_enum_values, reg_get_stringvalue }
1151 };
1152 static UINT16 systemenclosure_chassistypes[] =
1153 {
1154 1,
1155 };
1156 static const struct array systemenclosure_chassistypes_array =
1157 {
1158 SIZEOF(systemenclosure_chassistypes),
1159 &systemenclosure_chassistypes
1160 };
1161 static const struct record_systemenclosure data_systemenclosure[] =
1162 {
1163 {
1164 systemenclosure_systemenclosureW,
1165 &systemenclosure_chassistypes_array,
1166 systemenclosure_systemenclosureW,
1167 FALSE,
1168 systemenclosure_manufacturerW,
1169 systemenclosure_systemenclosureW,
1170 systemenclosure_tagW,
1171 }
1172 };
1173 static const struct record_systemsecurity data_systemsecurity[] =
1174 {
1175 { security_get_sd, security_set_sd }
1176 };
1177
1178 /* check if row matches condition and update status */
1179 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
1180 {
1181 LONGLONG val;
1182 UINT type;
1183
1184 if (!cond)
1185 {
1186 *status = FILL_STATUS_UNFILTERED;
1187 return TRUE;
1188 }
1189 if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1190 {
1191 *status = FILL_STATUS_FAILED;
1192 return FALSE;
1193 }
1194 *status = FILL_STATUS_FILTERED;
1195 return val != 0;
1196 }
1197
1198 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
1199 {
1200 if (!table->num_rows_allocated)
1201 {
1202 if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE;
1203 table->num_rows_allocated = row_count;
1204 return TRUE;
1205 }
1206 if (row_count > table->num_rows_allocated)
1207 {
1208 BYTE *data;
1209 UINT count = max( row_count, table->num_rows_allocated * 2 );
1210 if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE;
1211 table->data = data;
1212 table->num_rows_allocated = count;
1213 }
1214 return TRUE;
1215 }
1216
1217 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1218 {
1219 static const WCHAR fmtW[] = {'%','c',':',0};
1220 WCHAR drive[3], root[] = {'A',':','\\',0};
1221 struct record_cdromdrive *rec;
1222 UINT i, row = 0, offset = 0;
1223 DWORD drives = GetLogicalDrives();
1224 enum fill_status status = FILL_STATUS_UNFILTERED;
1225
1226 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1227
1228 for (i = 0; i < 26; i++)
1229 {
1230 if (drives & (1 << i))
1231 {
1232 root[0] = 'A' + i;
1233 if (GetDriveTypeW( root ) != DRIVE_CDROM)
1234 continue;
1235
1236 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1237
1238 rec = (struct record_cdromdrive *)(table->data + offset);
1239 rec->device_id = cdromdrive_pnpdeviceidW;
1240 sprintfW( drive, fmtW, 'A' + i );
1241 rec->drive = heap_strdupW( drive );
1242 rec->mediatype = cdromdrive_mediatypeW;
1243 rec->name = cdromdrive_nameW;
1244 rec->pnpdevice_id = cdromdrive_pnpdeviceidW;
1245 if (!match_row( table, row, cond, &status ))
1246 {
1247 free_row_values( table, row );
1248 continue;
1249 }
1250 offset += sizeof(*rec);
1251 row++;
1252 }
1253 }
1254 TRACE("created %u rows\n", row);
1255 table->num_rows = row;
1256 return status;
1257 }
1258
1259 static UINT get_processor_count(void)
1260 {
1261 SYSTEM_BASIC_INFORMATION info;
1262
1263 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1264 return info.NumberOfProcessors;
1265 }
1266
1267 static UINT get_logical_processor_count( UINT *num_cores )
1268 {
1269 SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info;
1270 UINT i, j, count = 0;
1271 NTSTATUS status;
1272 ULONG len;
1273
1274 if (num_cores) *num_cores = get_processor_count();
1275 status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len );
1276 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1277
1278 if (!(info = heap_alloc( len ))) return get_processor_count();
1279 status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len );
1280 if (status != STATUS_SUCCESS)
1281 {
1282 heap_free( info );
1283 return get_processor_count();
1284 }
1285 if (num_cores) *num_cores = 0;
1286 for (i = 0; i < len / sizeof(*info); i++)
1287 {
1288 if (info[i].Relationship == RelationProcessorCore)
1289 {
1290 for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++;
1291 }
1292 else if (info[i].Relationship == RelationProcessorPackage && num_cores)
1293 {
1294 for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) (*num_cores)++;
1295 }
1296 }
1297 heap_free( info );
1298 return count;
1299 }
1300
1301 static UINT64 get_total_physical_memory(void)
1302 {
1303 MEMORYSTATUSEX status;
1304
1305 status.dwLength = sizeof(status);
1306 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1307 return status.ullTotalPhys;
1308 }
1309
1310 static WCHAR *get_computername(void)
1311 {
1312 WCHAR *ret;
1313 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1314
1315 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1316 GetComputerNameW( ret, &size );
1317 return ret;
1318 }
1319
1320 static WCHAR *get_username(void)
1321 {
1322 WCHAR *ret;
1323 DWORD compsize, usersize;
1324 DWORD size;
1325
1326 compsize = 0;
1327 GetComputerNameW( NULL, &compsize );
1328 usersize = 0;
1329 GetUserNameW( NULL, &usersize );
1330 size = compsize + usersize; /* two null terminators account for the \ */
1331 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1332 GetComputerNameW( ret, &compsize );
1333 ret[compsize] = '\\';
1334 GetUserNameW( ret + compsize + 1, &usersize );
1335 return ret;
1336 }
1337
1338 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1339 {
1340 struct record_computersystem *rec;
1341 enum fill_status status = FILL_STATUS_UNFILTERED;
1342 UINT row = 0;
1343
1344 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1345
1346 rec = (struct record_computersystem *)table->data;
1347 rec->description = compsys_descriptionW;
1348 rec->domain = compsys_domainW;
1349 rec->domainrole = 0; /* standalone workstation */
1350 rec->manufacturer = compsys_manufacturerW;
1351 rec->model = compsys_modelW;
1352 rec->name = get_computername();
1353 rec->num_logical_processors = get_logical_processor_count( NULL );
1354 rec->num_processors = get_processor_count();
1355 rec->total_physical_memory = get_total_physical_memory();
1356 rec->username = get_username();
1357 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1358 else row++;
1359
1360 TRACE("created %u rows\n", row);
1361 table->num_rows = row;
1362 return status;
1363 }
1364
1365 static WCHAR *get_compsysproduct_uuid(void)
1366 {
1367 #ifdef __APPLE__
1368 unsigned char uuid[16];
1369 const struct timespec timeout = {1, 0};
1370 if (!gethostuuid( uuid, &timeout ))
1371 {
1372 static const WCHAR fmtW[] =
1373 {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-',
1374 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X',
1375 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0};
1376 WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) );
1377 if (!ret) return NULL;
1378 sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
1379 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] );
1380 return ret;
1381 }
1382 #endif
1383 #ifdef __linux__
1384 int file;
1385 if ((file = open( "/var/lib/dbus/machine-id", O_RDONLY )) != -1)
1386 {
1387 unsigned char buf[32];
1388 if (read( file, buf, sizeof(buf) ) == sizeof(buf))
1389 {
1390 unsigned int i, j;
1391 WCHAR *ret, *p;
1392
1393 close( file );
1394 if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL;
1395 for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] );
1396 p[8] = '-';
1397 for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] );
1398 p[13] = '-';
1399 for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] );
1400 p[18] = '-';
1401 for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] );
1402 p[23] = '-';
1403 for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] );
1404 ret[i] = 0;
1405 return ret;
1406 }
1407 close( file );
1408 }
1409 #endif
1410 return heap_strdupW( compsysproduct_uuidW );
1411 }
1412
1413 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1414 {
1415 struct record_computersystemproduct *rec;
1416 enum fill_status status = FILL_STATUS_UNFILTERED;
1417 UINT row = 0;
1418
1419 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1420
1421 rec = (struct record_computersystemproduct *)table->data;
1422 rec->identifyingnumber = compsysproduct_identifyingnumberW;
1423 rec->uuid = get_compsysproduct_uuid();
1424 rec->vendor = compsysproduct_vendorW;
1425 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1426 else row++;
1427
1428 TRACE("created %u rows\n", row);
1429 table->num_rows = row;
1430 return status;
1431 }
1432
1433 struct dirstack
1434 {
1435 WCHAR **dirs;
1436 UINT *len_dirs;
1437 UINT num_dirs;
1438 UINT num_allocated;
1439 };
1440
1441 static struct dirstack *alloc_dirstack( UINT size )
1442 {
1443 struct dirstack *dirstack;
1444
1445 if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL;
1446 if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size )))
1447 {
1448 heap_free( dirstack );
1449 return NULL;
1450 }
1451 if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size )))
1452 {
1453 heap_free( dirstack->dirs );
1454 heap_free( dirstack );
1455 return NULL;
1456 }
1457 dirstack->num_dirs = 0;
1458 dirstack->num_allocated = size;
1459 return dirstack;
1460 }
1461
1462 static void clear_dirstack( struct dirstack *dirstack )
1463 {
1464 UINT i;
1465 for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] );
1466 dirstack->num_dirs = 0;
1467 }
1468
1469 static void free_dirstack( struct dirstack *dirstack )
1470 {
1471 clear_dirstack( dirstack );
1472 heap_free( dirstack->dirs );
1473 heap_free( dirstack->len_dirs );
1474 heap_free( dirstack );
1475 }
1476
1477 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1478 {
1479 UINT size, i = dirstack->num_dirs;
1480
1481 if (!dir) return FALSE;
1482
1483 if (i == dirstack->num_allocated)
1484 {
1485 WCHAR **tmp;
1486 UINT *len_tmp;
1487
1488 size = dirstack->num_allocated * 2;
1489 if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1490 dirstack->dirs = tmp;
1491 if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1492 dirstack->len_dirs = len_tmp;
1493 dirstack->num_allocated = size;
1494 }
1495 dirstack->dirs[i] = dir;
1496 dirstack->len_dirs[i] = len;
1497 dirstack->num_dirs++;
1498 return TRUE;
1499 }
1500
1501 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1502 {
1503 if (!dirstack->num_dirs)
1504 {
1505 *len = 0;
1506 return NULL;
1507 }
1508 dirstack->num_dirs--;
1509 *len = dirstack->len_dirs[dirstack->num_dirs];
1510 return dirstack->dirs[dirstack->num_dirs];
1511 }
1512
1513 static const WCHAR *peek_dir( struct dirstack *dirstack )
1514 {
1515 if (!dirstack->num_dirs) return NULL;
1516 return dirstack->dirs[dirstack->num_dirs - 1];
1517 }
1518
1519 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1520 {
1521 UINT i = 0;
1522 WCHAR *ret;
1523
1524 if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1525 ret[i++] = drive;
1526 ret[i++] = ':';
1527 ret[i++] = '\\';
1528 if (path && len)
1529 {
1530 memcpy( ret + i, path, len * sizeof(WCHAR) );
1531 i += len;
1532 ret[i++] = '\\';
1533 }
1534 ret[i++] = '*';
1535 ret[i] = 0;
1536 return ret;
1537 }
1538
1539 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1540 {
1541 UINT i = 0, len = 0;
1542 const WCHAR *p;
1543 WCHAR *ret;
1544
1545 for (p = path; *p; p++)
1546 {
1547 if (*p == '\\') len += 2;
1548 else len++;
1549 };
1550 if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1551 ret[i++] = drive;
1552 ret[i++] = ':';
1553 ret[i++] = '\\';
1554 ret[i++] = '\\';
1555 for (p = path; *p; p++)
1556 {
1557 if (*p != '\\') ret[i++] = *p;
1558 else
1559 {
1560 ret[i++] = '\\';
1561 ret[i++] = '\\';
1562 }
1563 }
1564 ret[i] = 0;
1565 return ret;
1566 }
1567
1568 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1569 {
1570 const WCHAR *p = path, *start;
1571 UINT len, i;
1572 WCHAR *ret;
1573
1574 if (!isalphaW( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1575 start = path + 4;
1576 len = strlenW( start );
1577 p = start + len - 1;
1578 if (*p == '\\') return NULL;
1579
1580 while (p >= start && *p != '\\') { len--; p--; };
1581 while (p >= start && *p == '\\') { len--; p--; };
1582
1583 if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1584 for (i = 0, p = start; p < start + len; p++)
1585 {
1586 if (p[0] == '\\' && p[1] == '\\')
1587 {
1588 ret[i++] = '\\';
1589 p++;
1590 }
1591 else ret[i++] = *p;
1592 }
1593 ret[i] = 0;
1594 *ret_len = i;
1595 return ret;
1596 }
1597
1598 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1599 {
1600 UINT i;
1601 for (i = 0; i < dirstack->num_dirs; i++) if (!strcmpW( dirstack->dirs[i], path )) return TRUE;
1602 return FALSE;
1603 }
1604
1605 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1606 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1607 {
1608 const struct expr *left, *right;
1609
1610 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1611
1612 left = cond->u.expr.left;
1613 right = cond->u.expr.right;
1614 if (cond->u.expr.op == OP_EQ)
1615 {
1616 UINT len;
1617 WCHAR *path;
1618 const WCHAR *str = NULL;
1619
1620 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1621 !strcmpW( left->u.propval->name, prop_nameW ) &&
1622 toupperW( right->u.sval[0] ) == toupperW( root ))
1623 {
1624 str = right->u.sval;
1625 }
1626 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1627 !strcmpW( right->u.propval->name, prop_nameW ) &&
1628 toupperW( left->u.sval[0] ) == toupperW( root ))
1629 {
1630 str = left->u.sval;
1631 }
1632 if (str && (path = build_dirname( str, &len )))
1633 {
1634 if (seen_dir( dirstack, path ))
1635 {
1636 heap_free( path );
1637 return ++*count;
1638 }
1639 else if (push_dir( dirstack, path, len )) return ++*count;
1640 heap_free( path );
1641 return *count = 0;
1642 }
1643 }
1644 else if (cond->u.expr.op == OP_OR)
1645 {
1646 UINT left_count = 0, right_count = 0;
1647
1648 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
1649 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
1650 return *count += left_count + right_count;
1651 }
1652 return *count = 0;
1653 }
1654
1655 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
1656 {
1657 UINT len_path = 0, len_segment = strlenW( segment );
1658 WCHAR *ret;
1659
1660 *len = 0;
1661 if (path) len_path = strlenW( path );
1662 if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
1663 if (path && len_path)
1664 {
1665 memcpy( ret, path, len_path * sizeof(WCHAR) );
1666 ret[len_path] = '\\';
1667 *len += len_path + 1;
1668 }
1669 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
1670 *len += len_segment;
1671 ret[*len] = 0;
1672 return ret;
1673 }
1674
1675 static WCHAR *get_file_version( const WCHAR *filename )
1676 {
1677 static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
1678 VS_FIXEDFILEINFO *info;
1679 DWORD size;
1680 void *block;
1681 WCHAR *ret;
1682
1683 if (!(ret = heap_alloc( (4 * 5 + sizeof(fmtW) / sizeof(fmtW[0])) * sizeof(WCHAR) ))) return NULL;
1684 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size )))
1685 {
1686 heap_free( ret );
1687 return NULL;
1688 }
1689 if (!GetFileVersionInfoW( filename, 0, size, block ) ||
1690 !VerQueryValueW( block, slashW, (void **)&info, &size ))
1691 {
1692 heap_free( block );
1693 heap_free( ret );
1694 return NULL;
1695 }
1696 sprintfW( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
1697 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
1698 heap_free( block );
1699 return ret;
1700 }
1701
1702 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
1703 {
1704 static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
1705 struct record_datafile *rec;
1706 UINT i, len, row = 0, offset = 0, num_expected_rows;
1707 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
1708 DWORD drives = GetLogicalDrives();
1709 WIN32_FIND_DATAW data;
1710 HANDLE handle;
1711 struct dirstack *dirstack;
1712 enum fill_status status = FILL_STATUS_UNFILTERED;
1713
1714 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
1715
1716 dirstack = alloc_dirstack(2);
1717
1718 for (i = 0; i < 26; i++)
1719 {
1720 if (!(drives & (1 << i))) continue;
1721
1722 root[0] = 'A' + i;
1723 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1724
1725 num_expected_rows = 0;
1726 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1727
1728 for (;;)
1729 {
1730 heap_free( glob );
1731 heap_free( path );
1732 path = pop_dir( dirstack, &len );
1733 if (!(glob = build_glob( root[0], path, len )))
1734 {
1735 status = FILL_STATUS_FAILED;
1736 goto done;
1737 }
1738 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1739 {
1740 do
1741 {
1742 if (!resize_table( table, row + 1, sizeof(*rec) ))
1743 {
1744 status = FILL_STATUS_FAILED;
1745 FindClose( handle );
1746 goto done;
1747 }
1748 if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue;
1749 new_path = append_path( path, data.cFileName, &len );
1750
1751 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1752 {
1753 if (push_dir( dirstack, new_path, len )) continue;
1754 heap_free( new_path );
1755 FindClose( handle );
1756 status = FILL_STATUS_FAILED;
1757 goto done;
1758 }
1759 rec = (struct record_datafile *)(table->data + offset);
1760 rec->name = build_name( root[0], new_path );
1761 rec->version = get_file_version( rec->name );
1762 if (!match_row( table, row, cond, &status ))
1763 {
1764 free_row_values( table, row );
1765 continue;
1766 }
1767 else if (num_expected_rows && row == num_expected_rows - 1)
1768 {
1769 row++;
1770 FindClose( handle );
1771 status = FILL_STATUS_FILTERED;
1772 goto done;
1773 }
1774 offset += sizeof(*rec);
1775 row++;
1776 }
1777 while (FindNextFileW( handle, &data ));
1778 FindClose( handle );
1779 }
1780 if (!peek_dir( dirstack )) break;
1781 }
1782 }
1783
1784 done:
1785 free_dirstack( dirstack );
1786 heap_free( glob );
1787 heap_free( path );
1788
1789 TRACE("created %u rows\n", row);
1790 table->num_rows = row;
1791 return status;
1792 }
1793
1794 static UINT32 get_pixelsperxlogicalinch(void)
1795 {
1796 HDC hdc = GetDC( NULL );
1797 UINT32 ret;
1798
1799 if (!hdc) return 96;
1800 ret = GetDeviceCaps( hdc, LOGPIXELSX );
1801 ReleaseDC( NULL, hdc );
1802 return ret;
1803 }
1804
1805 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
1806 {
1807 struct record_desktopmonitor *rec;
1808 enum fill_status status = FILL_STATUS_UNFILTERED;
1809 UINT row = 0;
1810
1811 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1812
1813 rec = (struct record_desktopmonitor *)table->data;
1814 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
1815
1816 if (match_row( table, row, cond, &status )) row++;
1817
1818 TRACE("created %u rows\n", row);
1819 table->num_rows = row;
1820 return status;
1821 }
1822
1823 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
1824 {
1825 static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0};
1826 struct record_directory *rec;
1827 UINT i, len, row = 0, offset = 0, num_expected_rows;
1828 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0};
1829 DWORD drives = GetLogicalDrives();
1830 WIN32_FIND_DATAW data;
1831 HANDLE handle;
1832 struct dirstack *dirstack;
1833 enum fill_status status = FILL_STATUS_UNFILTERED;
1834
1835 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
1836
1837 dirstack = alloc_dirstack(2);
1838
1839 for (i = 0; i < 26; i++)
1840 {
1841 if (!(drives & (1 << i))) continue;
1842
1843 root[0] = 'A' + i;
1844 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1845
1846 num_expected_rows = 0;
1847 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1848
1849 for (;;)
1850 {
1851 heap_free( glob );
1852 heap_free( path );
1853 path = pop_dir( dirstack, &len );
1854 if (!(glob = build_glob( root[0], path, len )))
1855 {
1856 status = FILL_STATUS_FAILED;
1857 goto done;
1858 }
1859 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1860 {
1861 do
1862 {
1863 if (!resize_table( table, row + 1, sizeof(*rec) ))
1864 {
1865 FindClose( handle );
1866 status = FILL_STATUS_FAILED;
1867 goto done;
1868 }
1869 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
1870 !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW ))
1871 continue;
1872
1873 new_path = append_path( path, data.cFileName, &len );
1874 if (!(push_dir( dirstack, new_path, len )))
1875 {
1876 heap_free( new_path );
1877 FindClose( handle );
1878 status = FILL_STATUS_FAILED;
1879 goto done;
1880 }
1881 rec = (struct record_directory *)(table->data + offset);
1882 rec->accessmask = FILE_ALL_ACCESS;
1883 rec->name = build_name( root[0], new_path );
1884 if (!match_row( table, row, cond, &status ))
1885 {
1886 free_row_values( table, row );
1887 continue;
1888 }
1889 else if (num_expected_rows && row == num_expected_rows - 1)
1890 {
1891 row++;
1892 FindClose( handle );
1893 status = FILL_STATUS_FILTERED;
1894 goto done;
1895 }
1896 offset += sizeof(*rec);
1897 row++;
1898 }
1899 while (FindNextFileW( handle, &data ));
1900 FindClose( handle );
1901 }
1902 if (!peek_dir( dirstack )) break;
1903 }
1904 }
1905
1906 done:
1907 free_dirstack( dirstack );
1908 heap_free( glob );
1909 heap_free( path );
1910
1911 TRACE("created %u rows\n", row);
1912 table->num_rows = row;
1913 return status;
1914 }
1915
1916 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
1917 {
1918 WCHAR root[] = {'\\','\\','.','\\','A',':',0};
1919 ULARGE_INTEGER free;
1920 DISK_GEOMETRY_EX info;
1921 HANDLE handle;
1922 DWORD bytes_returned;
1923
1924 free.QuadPart = 512 * 1024 * 1024;
1925 GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
1926
1927 root[4] = dir[0];
1928 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
1929 if (handle != INVALID_HANDLE_VALUE)
1930 {
1931 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
1932 *disksize = info.DiskSize.QuadPart;
1933 CloseHandle( handle );
1934 }
1935 return free.QuadPart;
1936 }
1937
1938 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
1939 {
1940 static const WCHAR fmtW[] =
1941 {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','%','u',0};
1942 WCHAR device_id[sizeof(fmtW)/sizeof(fmtW[0]) + 10], root[] = {'A',':','\\',0};
1943 struct record_diskdrive *rec;
1944 UINT i, row = 0, offset = 0, index = 0, type;
1945 UINT64 size = 1024 * 1024 * 1024;
1946 DWORD drives = GetLogicalDrives();
1947 enum fill_status status = FILL_STATUS_UNFILTERED;
1948
1949 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
1950
1951 for (i = 0; i < 26; i++)
1952 {
1953 if (drives & (1 << i))
1954 {
1955 root[0] = 'A' + i;
1956 type = GetDriveTypeW( root );
1957 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
1958 continue;
1959
1960 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1961
1962 rec = (struct record_diskdrive *)(table->data + offset);
1963 sprintfW( device_id, fmtW, index );
1964 rec->device_id = heap_strdupW( device_id );
1965 rec->index = index;
1966 rec->interfacetype = diskdrive_interfacetypeW;
1967 rec->manufacturer = diskdrive_manufacturerW;
1968 if (type == DRIVE_FIXED)
1969 rec->mediatype = diskdrive_mediatype_fixedW;
1970 else
1971 rec->mediatype = diskdrive_mediatype_removableW;
1972 rec->model = diskdrive_modelW;
1973 rec->pnpdevice_id = diskdrive_pnpdeviceidW;
1974 rec->serialnumber = diskdrive_serialW;
1975 get_freespace( root, &size );
1976 rec->size = size;
1977 if (!match_row( table, row, cond, &status ))
1978 {
1979 free_row_values( table, row );
1980 continue;
1981 }
1982 offset += sizeof(*rec);
1983 index++;
1984 row++;
1985 }
1986 }
1987 TRACE("created %u rows\n", row);
1988 table->num_rows = row;
1989 return status;
1990 }
1991
1992 static WCHAR *get_filesystem( const WCHAR *root )
1993 {
1994 static const WCHAR ntfsW[] = {'N','T','F','S',0};
1995 WCHAR buffer[MAX_PATH + 1];
1996
1997 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
1998 return heap_strdupW( buffer );
1999 return heap_strdupW( ntfsW );
2000 }
2001
2002 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2003 {
2004 static const WCHAR fmtW[] =
2005 {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0};
2006 WCHAR device_id[32], root[] = {'A',':','\\',0};
2007 struct record_diskpartition *rec;
2008 UINT i, row = 0, offset = 0, type, index = 0;
2009 UINT64 size = 1024 * 1024 * 1024;
2010 DWORD drives = GetLogicalDrives();
2011 enum fill_status status = FILL_STATUS_UNFILTERED;
2012
2013 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2014
2015 for (i = 0; i < 26; i++)
2016 {
2017 if (drives & (1 << i))
2018 {
2019 root[0] = 'A' + i;
2020 type = GetDriveTypeW( root );
2021 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2022 continue;
2023
2024 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2025
2026 rec = (struct record_diskpartition *)(table->data + offset);
2027 rec->bootable = (i == 2) ? -1 : 0;
2028 rec->bootpartition = (i == 2) ? -1 : 0;
2029 sprintfW( device_id, fmtW, index );
2030 rec->device_id = heap_strdupW( device_id );
2031 rec->diskindex = index;
2032 rec->index = 0;
2033 rec->pnpdevice_id = heap_strdupW( device_id );
2034 get_freespace( root, &size );
2035 rec->size = size;
2036 rec->startingoffset = 0;
2037 rec->type = get_filesystem( root );
2038 if (!match_row( table, row, cond, &status ))
2039 {
2040 free_row_values( table, row );
2041 continue;
2042 }
2043 offset += sizeof(*rec);
2044 row++;
2045 index++;
2046 }
2047 }
2048 TRACE("created %u rows\n", row);
2049 table->num_rows = row;
2050 return status;
2051 }
2052
2053 static WCHAR *get_ip4_string( DWORD addr )
2054 {
2055 static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
2056 WCHAR *ret;
2057
2058 if (!(ret = heap_alloc( sizeof("ddd.ddd.ddd.ddd") * sizeof(WCHAR) ))) return NULL;
2059 sprintfW( ret, fmtW, (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2060 return ret;
2061 }
2062
2063 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2064 {
2065 struct record_ip4routetable *rec;
2066 UINT i, row = 0, offset = 0, size = 0;
2067 MIB_IPFORWARDTABLE *forwards;
2068 enum fill_status status = FILL_STATUS_UNFILTERED;
2069
2070 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2071 if (!(forwards = heap_alloc( size ))) return FILL_STATUS_FAILED;
2072 if (GetIpForwardTable( forwards, &size, TRUE ))
2073 {
2074 heap_free( forwards );
2075 return FILL_STATUS_FAILED;
2076 }
2077 if (!resize_table( table, forwards->dwNumEntries, sizeof(*rec) ))
2078 {
2079 heap_free( forwards );
2080 return FILL_STATUS_FAILED;
2081 }
2082
2083 for (i = 0; i < forwards->dwNumEntries; i++)
2084 {
2085 rec = (struct record_ip4routetable *)(table->data + offset);
2086
2087 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2088 rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2089 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2090
2091 if (!match_row( table, row, cond, &status ))
2092 {
2093 free_row_values( table, row );
2094 continue;
2095 }
2096 offset += sizeof(*rec);
2097 row++;
2098 }
2099 TRACE("created %u rows\n", row);
2100 table->num_rows = row;
2101
2102 heap_free( forwards );
2103 return status;
2104 }
2105
2106 static WCHAR *get_volumename( const WCHAR *root )
2107 {
2108 WCHAR buf[MAX_PATH + 1] = {0};
2109 GetVolumeInformationW( root, buf, sizeof(buf)/sizeof(buf[0]), NULL, NULL, NULL, NULL, 0 );
2110 return heap_strdupW( buf );
2111 }
2112 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2113 {
2114 static const WCHAR fmtW[] = {'%','0','8','X',0};
2115 DWORD serial = 0;
2116 WCHAR buffer[9];
2117
2118 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2119 sprintfW( buffer, fmtW, serial );
2120 return heap_strdupW( buffer );
2121 }
2122
2123 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2124 {
2125 static const WCHAR fmtW[] = {'%','c',':',0};
2126 WCHAR device_id[3], root[] = {'A',':','\\',0};
2127 struct record_logicaldisk *rec;
2128 UINT i, row = 0, offset = 0, type;
2129 UINT64 size = 1024 * 1024 * 1024;
2130 DWORD drives = GetLogicalDrives();
2131 enum fill_status status = FILL_STATUS_UNFILTERED;
2132
2133 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2134
2135 for (i = 0; i < 26; i++)
2136 {
2137 if (drives & (1 << i))
2138 {
2139 root[0] = 'A' + i;
2140 type = GetDriveTypeW( root );
2141 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2142 continue;
2143
2144 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2145
2146 rec = (struct record_logicaldisk *)(table->data + offset);
2147 sprintfW( device_id, fmtW, 'A' + i );
2148 rec->device_id = heap_strdupW( device_id );
2149 rec->drivetype = type;
2150 rec->filesystem = get_filesystem( root );
2151 rec->freespace = get_freespace( root, &size );
2152 rec->name = heap_strdupW( device_id );
2153 rec->size = size;
2154 rec->volumename = get_volumename( root );
2155 rec->volumeserialnumber = get_volumeserialnumber( root );
2156 if (!match_row( table, row, cond, &status ))
2157 {
2158 free_row_values( table, row );
2159 continue;
2160 }
2161 offset += sizeof(*rec);
2162 row++;
2163 }
2164 }
2165 TRACE("created %u rows\n", row);
2166 table->num_rows = row;
2167 return status;
2168 }
2169
2170 static UINT16 get_connection_status( IF_OPER_STATUS status )
2171 {
2172 switch (status)
2173 {
2174 case IfOperStatusDown:
2175 return 0; /* Disconnected */
2176 case IfOperStatusUp:
2177 return 2; /* Connected */
2178 default:
2179 ERR("unhandled status %u\n", status);
2180 break;
2181 }
2182 return 0;
2183 }
2184 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2185 {
2186 static const WCHAR fmtW[] =
2187 {'%','0','2','x',':','%','0','2','x',':','%','0','2','x',':',
2188 '%','0','2','x',':','%','0','2','x',':','%','0','2','x',0};
2189 WCHAR *ret;
2190
2191 if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL;
2192 sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2193 return ret;
2194 }
2195 static const WCHAR *get_adaptertype( DWORD type, int *physical )
2196 {
2197 static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0};
2198 static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0};
2199 static const WCHAR firewireW[] = {'1','3','9','4',0};
2200 static const WCHAR tunnelW[] = {'T','u','n','n','e','l',0};
2201
2202 switch (type)
2203 {
2204 case IF_TYPE_ETHERNET_CSMACD: *physical = -1; return ethernetW;
2205 case IF_TYPE_IEEE80211: *physical = -1; return wirelessW;
2206 case IF_TYPE_IEEE1394: *physical = -1; return firewireW;
2207 case IF_TYPE_TUNNEL: *physical = 0; return tunnelW;
2208 default: *physical = 0; return NULL;
2209 }
2210 }
2211
2212 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2213 {
2214 static const WCHAR fmtW[] = {'%','u',0};
2215 WCHAR device_id[11];
2216 struct record_networkadapter *rec;
2217 IP_ADAPTER_ADDRESSES *aa, *buffer;
2218 UINT row = 0, offset = 0, count = 0;
2219 DWORD size = 0, ret;
2220 int physical;
2221 enum fill_status status = FILL_STATUS_UNFILTERED;
2222
2223 ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
2224 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2225
2226 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2227 if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size ))
2228 {
2229 heap_free( buffer );
2230 return FILL_STATUS_FAILED;
2231 }
2232 for (aa = buffer; aa; aa = aa->Next)
2233 {
2234 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2235 }
2236 if (!resize_table( table, count, sizeof(*rec) ))
2237 {
2238 heap_free( buffer );
2239 return FILL_STATUS_FAILED;
2240 }
2241 for (aa = buffer; aa; aa = aa->Next)
2242 {
2243 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2244
2245 rec = (struct record_networkadapter *)(table->data + offset);
2246 sprintfW( device_id, fmtW, aa->u.s.IfIndex );
2247 rec->adaptertype = get_adaptertype( aa->IfType, &physical );
2248 rec->device_id = heap_strdupW( device_id );
2249 rec->index = aa->u.s.IfIndex;
2250 rec->interface_index = aa->u.s.IfIndex;
2251 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2252 rec->manufacturer = compsys_manufacturerW;
2253 rec->name = heap_strdupW( aa->FriendlyName );
2254 rec->netconnection_status = get_connection_status( aa->OperStatus );
2255 rec->physicaladapter = physical;
2256 rec->pnpdevice_id = networkadapter_pnpdeviceidW;
2257 rec->speed = 1000000;
2258 if (!match_row( table, row, cond, &status ))
2259 {
2260 free_row_values( table, row );
2261 continue;
2262 }
2263 offset += sizeof(*rec);
2264 row++;
2265 }
2266 TRACE("created %u rows\n", row);
2267 table->num_rows = row;
2268
2269 heap_free( buffer );
2270 return status;
2271 }
2272
2273 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2274 {
2275 const SOCKET_ADDRESS *sa = &addr->Address;
2276 WCHAR buf[NI_MAXHOST];
2277
2278 if (!addr) return NULL;
2279 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, sizeof(buf)/sizeof(buf[0]), NULL,
2280 0, NI_NAMEREQD )) return NULL;
2281 return heap_strdupW( buf );
2282 }
2283 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2284 {
2285 IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2286 struct array *ret;
2287 ULONG buflen, i = 0, count = 0;
2288 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2289
2290 if (!list) return NULL;
2291 for (gateway = list; gateway; gateway = gateway->Next) count++;
2292
2293 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2294 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2295 {
2296 heap_free( ret );
2297 return NULL;
2298 }
2299 for (gateway = list; gateway; gateway = gateway->Next)
2300 {
2301 buflen = sizeof(buf)/sizeof(buf[0]);
2302 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2303 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2304 {
2305 for (; i > 0; i--) heap_free( ptr[i - 1] );
2306 heap_free( ptr );
2307 heap_free( ret );
2308 return NULL;
2309 }
2310 }
2311 ret->count = count;
2312 ret->ptr = ptr;
2313 return ret;
2314 }
2315 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2316 {
2317 IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2318 struct array *ret;
2319 ULONG buflen, i = 0, count = 0;
2320 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2321
2322 if (!list) return NULL;
2323 for (server = list; server; server = server->Next) count++;
2324
2325 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2326 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2327 {
2328 heap_free( ret );
2329 return NULL;
2330 }
2331 for (server = list; server; server = server->Next)
2332 {
2333 buflen = sizeof(buf)/sizeof(buf[0]);
2334 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2335 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2336 {
2337 for (; i > 0; i--) heap_free( ptr[i - 1] );
2338 heap_free( ptr );
2339 heap_free( ret );
2340 return NULL;
2341 }
2342 if ((p = strrchrW( ptr[i - 1], ':' ))) *p = 0;
2343 }
2344 ret->count = count;
2345 ret->ptr = ptr;
2346 return ret;
2347 }
2348 static WCHAR *get_settingid( UINT32 index )
2349 {
2350 GUID guid;
2351 WCHAR *ret, *str;
2352 memset( &guid, 0, sizeof(guid) );
2353 guid.Data1 = index;
2354 UuidToStringW( &guid, &str );
2355 ret = heap_strdupW( str );
2356 RpcStringFreeW( &str );
2357 return ret;
2358 }
2359
2360 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
2361 {
2362 struct record_networkadapterconfig *rec;
2363 IP_ADAPTER_ADDRESSES *aa, *buffer;
2364 UINT row = 0, offset = 0, count = 0;
2365 DWORD size = 0, ret;
2366 enum fill_status status = FILL_STATUS_UNFILTERED;
2367
2368 ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size );
2369 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2370
2371 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2372 if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size ))
2373 {
2374 heap_free( buffer );
2375 return FILL_STATUS_FAILED;
2376 }
2377 for (aa = buffer; aa; aa = aa->Next)
2378 {
2379 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2380 }
2381 if (!resize_table( table, count, sizeof(*rec) ))
2382 {
2383 heap_free( buffer );
2384 return FILL_STATUS_FAILED;
2385 }
2386 for (aa = buffer; aa; aa = aa->Next)
2387 {
2388 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2389
2390 rec = (struct record_networkadapterconfig *)(table->data + offset);
2391 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress );
2392 rec->description = heap_strdupW( aa->Description );
2393 rec->dhcpenabled = -1;
2394 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress );
2395 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress );
2396 rec->index = aa->u.s.IfIndex;
2397 rec->ipconnectionmetric = 20;
2398 rec->ipenabled = -1;
2399 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2400 rec->settingid = get_settingid( rec->index );
2401 if (!match_row( table, row, cond, &status ))
2402 {
2403 free_row_values( table, row );
2404 continue;
2405 }
2406 offset += sizeof(*rec);
2407 row++;
2408 }