winepulse: Remove AudioSessionManager.
[wine.git] / dlls / wbemprox / builtin.c
blob7c4e530a6d058f8d89e2646b6fa3208a5176f1c6
1 /*
2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
23 #include <stdarg.h>
24 #include <intrin.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winsock2.h"
31 #include "ws2tcpip.h"
32 #include "initguid.h"
33 #include "wbemcli.h"
34 #include "wbemprov.h"
35 #include "iphlpapi.h"
36 #include "netioapi.h"
37 #include "tlhelp32.h"
38 #include "d3d10.h"
39 #include "winternl.h"
40 #include "winioctl.h"
41 #include "winsvc.h"
42 #include "winver.h"
43 #include "sddl.h"
44 #include "ntsecapi.h"
45 #include "winspool.h"
46 #include "setupapi.h"
47 #include "ntddstor.h"
49 #include "wine/asm.h"
50 #include "wine/debug.h"
51 #include "wbemprox_private.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
55 /* column definitions must be kept in sync with record structures below */
56 static const struct column col_associator[] =
58 { L"AssocClass", CIM_STRING },
59 { L"Class", CIM_STRING },
60 { L"Associator", CIM_STRING }
62 static const struct column col_baseboard[] =
64 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
65 { L"Model", CIM_STRING },
66 { L"Name", CIM_STRING },
67 { L"Product", CIM_STRING|COL_FLAG_DYNAMIC },
68 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
69 { L"Tag", CIM_STRING|COL_FLAG_KEY },
70 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
72 static const struct column col_bios[] =
74 { L"CurrentLanguage", CIM_STRING },
75 { L"Description", CIM_STRING },
76 { L"EmbeddedControllerMajorVersion", CIM_UINT8 },
77 { L"EmbeddedControllerMinorVersion", CIM_UINT8 },
78 { L"IdentificationCode", CIM_STRING },
79 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
80 { L"Name", CIM_STRING },
81 { L"ReleaseDate", CIM_DATETIME|COL_FLAG_DYNAMIC },
82 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
83 { L"SMBIOSBIOSVersion", CIM_STRING|COL_FLAG_DYNAMIC },
84 { L"SMBIOSMajorVersion", CIM_UINT16 },
85 { L"SMBIOSMinorVersion", CIM_UINT16 },
86 { L"SystemBiosMajorVersion", CIM_UINT8 },
87 { L"SystemBiosMinorVersion", CIM_UINT8 },
88 { L"Version", CIM_STRING|COL_FLAG_KEY },
90 static const struct column col_cdromdrive[] =
92 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
93 { L"Drive", CIM_STRING|COL_FLAG_DYNAMIC },
94 { L"MediaType", CIM_STRING },
95 { L"Name", CIM_STRING },
96 { L"PNPDeviceID", CIM_STRING },
98 static const struct column col_compsys[] =
100 { L"Description", CIM_STRING },
101 { L"Domain", CIM_STRING },
102 { L"DomainRole", CIM_UINT16 },
103 { L"HypervisorPresent", CIM_BOOLEAN },
104 { L"Manufacturer", CIM_STRING },
105 { L"Model", CIM_STRING },
106 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
107 { L"NumberOfLogicalProcessors", CIM_UINT32 },
108 { L"NumberOfProcessors", CIM_UINT32 },
109 { L"SystemType", CIM_STRING },
110 { L"TotalPhysicalMemory", CIM_UINT64 },
111 { L"UserName", CIM_STRING|COL_FLAG_DYNAMIC },
113 static const struct column col_compsysproduct[] =
115 { L"IdentifyingNumber", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
116 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
117 { L"SKUNumber", CIM_STRING },
118 { L"UUID", CIM_STRING|COL_FLAG_DYNAMIC },
119 { L"Vendor", CIM_STRING|COL_FLAG_DYNAMIC },
120 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
122 static const struct column col_datafile[] =
124 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
125 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
127 static const struct column col_desktopmonitor[] =
129 { L"Name", CIM_STRING },
130 { L"PixelsPerXLogicalInch", CIM_UINT32 },
132 static const struct column col_directory[] =
134 { L"AccessMask", CIM_UINT32 },
135 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
137 static const struct column col_diskdrive[] =
139 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
140 { L"Index", CIM_UINT32 },
141 { L"InterfaceType", CIM_STRING },
142 { L"Manufacturer", CIM_STRING },
143 { L"MediaType", CIM_STRING },
144 { L"Model", CIM_STRING },
145 { L"PNPDeviceID", CIM_STRING },
146 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
147 { L"Size", CIM_UINT64 },
149 static const struct column col_diskdrivetodiskpartition[] =
151 { L"Antecedent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
152 { L"Dependent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
154 static const struct column col_diskpartition[] =
156 { L"Bootable", CIM_BOOLEAN },
157 { L"BootPartition", CIM_BOOLEAN },
158 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
159 { L"DiskIndex", CIM_UINT32 },
160 { L"Index", CIM_UINT32 },
161 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
162 { L"Size", CIM_UINT64 },
163 { L"StartingOffset", CIM_UINT64 },
164 { L"Type", CIM_STRING|COL_FLAG_DYNAMIC },
166 static const struct column col_displaycontrollerconfig[] =
168 { L"BitsPerPixel", CIM_UINT32 },
169 { L"Caption", CIM_STRING },
170 { L"HorizontalResolution", CIM_UINT32 },
171 { L"Name", CIM_STRING|COL_FLAG_KEY },
172 { L"VerticalResolution", CIM_UINT32 },
174 static const struct column col_ip4routetable[] =
176 { L"Destination", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
177 { L"InterfaceIndex", CIM_SINT32|COL_FLAG_KEY },
178 { L"NextHop", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
180 static const struct column col_logicaldisk[] =
182 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
183 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
184 { L"DriveType", CIM_UINT32 },
185 { L"FileSystem", CIM_STRING|COL_FLAG_DYNAMIC },
186 { L"FreeSpace", CIM_UINT64 },
187 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
188 { L"Size", CIM_UINT64 },
189 { L"VolumeName", CIM_STRING|COL_FLAG_DYNAMIC },
190 { L"VolumeSerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
192 static const struct column col_logicaldisktopartition[] =
194 { L"Antecedent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
195 { L"Dependent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
197 static const struct column col_networkadapter[] =
199 { L"AdapterType", CIM_STRING },
200 { L"AdapterTypeID", CIM_UINT16 },
201 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
202 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
203 { L"GUID", CIM_STRING|COL_FLAG_DYNAMIC },
204 { L"Index", CIM_UINT32 },
205 { L"InterfaceIndex", CIM_UINT32 },
206 { L"MACAddress", CIM_STRING|COL_FLAG_DYNAMIC },
207 { L"Manufacturer", CIM_STRING },
208 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
209 { L"NetConnectionStatus", CIM_UINT16 },
210 { L"PhysicalAdapter", CIM_BOOLEAN },
211 { L"PNPDeviceID", CIM_STRING },
212 { L"ServiceName", CIM_STRING|COL_FLAG_DYNAMIC },
213 { L"Speed", CIM_UINT64 },
215 static const struct column col_networkadapterconfig[] =
217 { L"DefaultIPGateway", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
218 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
219 { L"DHCPEnabled", CIM_BOOLEAN },
220 { L"DNSDomain", CIM_STRING },
221 { L"DNSHostName", CIM_STRING|COL_FLAG_DYNAMIC },
222 { L"DNSServerSearchOrder", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
223 { L"Index", CIM_UINT32|COL_FLAG_KEY },
224 { L"IPAddress", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
225 { L"IPConnectionMetric", CIM_UINT32 },
226 { L"IPEnabled", CIM_BOOLEAN },
227 { L"IPSubnet", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
228 { L"MACAddress", CIM_STRING|COL_FLAG_DYNAMIC },
229 { L"SettingID", CIM_STRING|COL_FLAG_DYNAMIC },
231 static const struct column col_operatingsystem[] =
233 { L"BootDevice", CIM_STRING },
234 { L"BuildNumber", CIM_STRING|COL_FLAG_DYNAMIC },
235 { L"BuildType", CIM_STRING },
236 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
237 { L"CodeSet", CIM_STRING|COL_FLAG_DYNAMIC },
238 { L"CountryCode", CIM_STRING|COL_FLAG_DYNAMIC },
239 { L"CSDVersion", CIM_STRING|COL_FLAG_DYNAMIC },
240 { L"CSName", CIM_STRING|COL_FLAG_DYNAMIC },
241 { L"CurrentTimeZone", CIM_SINT16 },
242 { L"FreePhysicalMemory", CIM_UINT64 },
243 { L"FreeVirtualMemory", CIM_UINT64 },
244 { L"InstallDate", CIM_DATETIME },
245 { L"LastBootUpTime", CIM_DATETIME|COL_FLAG_DYNAMIC },
246 { L"LocalDateTime", CIM_DATETIME|COL_FLAG_DYNAMIC },
247 { L"Locale", CIM_STRING|COL_FLAG_DYNAMIC },
248 { L"Manufacturer", CIM_STRING },
249 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
250 { L"OperatingSystemSKU", CIM_UINT32 },
251 { L"Organization", CIM_STRING|COL_FLAG_DYNAMIC },
252 { L"OSArchitecture", CIM_STRING },
253 { L"OSLanguage", CIM_UINT32 },
254 { L"OSProductSuite", CIM_UINT32 },
255 { L"OSType", CIM_UINT16 },
256 { L"Primary", CIM_BOOLEAN },
257 { L"ProductType", CIM_UINT32 },
258 { L"RegisteredUser", CIM_STRING|COL_FLAG_DYNAMIC },
259 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
260 { L"ServicePackMajorVersion", CIM_UINT16 },
261 { L"ServicePackMinorVersion", CIM_UINT16 },
262 { L"Status", CIM_STRING },
263 { L"SuiteMask", CIM_UINT32 },
264 { L"SystemDirectory", CIM_STRING|COL_FLAG_DYNAMIC },
265 { L"SystemDrive", CIM_STRING|COL_FLAG_DYNAMIC },
266 { L"TotalVirtualMemorySize", CIM_UINT64 },
267 { L"TotalVisibleMemorySize", CIM_UINT64 },
268 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
269 { L"WindowsDirectory", CIM_STRING|COL_FLAG_DYNAMIC },
271 static const struct column col_pagefileusage[] =
273 { L"Name", CIM_STRING },
275 static const struct column col_param[] =
277 { L"Class", CIM_STRING },
278 { L"Method", CIM_STRING },
279 { L"Direction", CIM_SINT32 },
280 { L"Parameter", CIM_STRING },
281 { L"Type", CIM_UINT32 },
282 { L"DefaultValue", CIM_UINT32 },
284 static const struct column col_physicalmedia[] =
286 { L"SerialNumber", CIM_STRING },
287 { L"Tag", CIM_STRING },
289 static const struct column col_physicalmemory[] =
291 { L"BankLabel", CIM_STRING },
292 { L"Capacity", CIM_UINT64 },
293 { L"Caption", CIM_STRING },
294 { L"ConfiguredClockSpeed", CIM_UINT32 },
295 { L"DeviceLocator", CIM_STRING },
296 { L"FormFactor", CIM_UINT16 },
297 { L"MemoryType", CIM_UINT16 },
298 { L"PartNumber", CIM_STRING },
299 { L"SerialNumber", CIM_STRING },
301 static const struct column col_pnpentity[] =
303 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC },
304 { L"Manufacturer", CIM_STRING },
305 { L"Name", CIM_STRING },
307 static const struct column col_printer[] =
309 { L"Attributes", CIM_UINT32 },
310 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
311 { L"DriverName", CIM_STRING|COL_FLAG_DYNAMIC },
312 { L"HorizontalResolution", CIM_UINT32 },
313 { L"Local", CIM_BOOLEAN },
314 { L"Location", CIM_STRING|COL_FLAG_DYNAMIC },
315 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
316 { L"Network", CIM_BOOLEAN },
317 { L"PortName", CIM_STRING|COL_FLAG_DYNAMIC },
319 static const struct column col_process[] =
321 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
322 { L"CommandLine", CIM_STRING|COL_FLAG_DYNAMIC },
323 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
324 { L"Handle", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
325 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
326 { L"ParentProcessID", CIM_UINT32 },
327 { L"ProcessID", CIM_UINT32 },
328 { L"ThreadCount", CIM_UINT32 },
329 { L"WorkingSetSize", CIM_UINT64 },
330 /* methods */
331 { L"Create", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
332 { L"GetOwner", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
334 static const struct column col_processor[] =
336 { L"AddressWidth", CIM_UINT16 },
337 { L"Architecture", CIM_UINT16 },
338 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
339 { L"CpuStatus", CIM_UINT16 },
340 { L"CurrentClockSpeed", CIM_UINT32 },
341 { L"DataWidth", CIM_UINT16 },
342 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
343 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
344 { L"Family", CIM_UINT16 },
345 { L"Level", CIM_UINT16 },
346 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
347 { L"MaxClockSpeed", CIM_UINT32 },
348 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
349 { L"NumberOfCores", CIM_UINT32 },
350 { L"NumberOfLogicalProcessors", CIM_UINT32 },
351 { L"ProcessorId", CIM_STRING|COL_FLAG_DYNAMIC },
352 { L"ProcessorType", CIM_UINT16 },
353 { L"Revision", CIM_UINT16 },
354 { L"UniqueId", CIM_STRING },
355 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
357 static const struct column col_qualifier[] =
359 { L"Class", CIM_STRING },
360 { L"Member", CIM_STRING },
361 { L"Type", CIM_UINT32 },
362 { L"Flavor", CIM_SINT32 },
363 { L"Name", CIM_STRING },
364 { L"IntegerValue", CIM_SINT32 },
365 { L"StringValue", CIM_STRING },
366 { L"BoolValue", CIM_BOOLEAN },
368 static const struct column col_quickfixengineering[] =
370 { L"Caption", CIM_STRING },
371 { L"Description", CIM_STRING },
372 { L"HotFixID", CIM_STRING|COL_FLAG_KEY },
373 { L"InstalledBy", CIM_STRING },
374 { L"InstalledOn", CIM_STRING },
376 static const struct column col_rawsmbiostables[] =
378 { L"SMBiosData", CIM_UINT8|CIM_FLAG_ARRAY },
380 static const struct column col_service[] =
382 { L"AcceptPause", CIM_BOOLEAN },
383 { L"AcceptStop", CIM_BOOLEAN },
384 { L"DisplayName", CIM_STRING|COL_FLAG_DYNAMIC },
385 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
386 { L"ProcessID", CIM_UINT32 },
387 { L"ServiceType", CIM_STRING },
388 { L"StartMode", CIM_STRING },
389 { L"State", CIM_STRING },
390 { L"SystemName", CIM_STRING|COL_FLAG_DYNAMIC },
391 /* methods */
392 { L"PauseService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
393 { L"ResumeService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
394 { L"StartService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
395 { L"StopService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
397 static const struct column col_sid[] =
399 { L"AccountName", CIM_STRING|COL_FLAG_DYNAMIC },
400 { L"BinaryRepresentation", CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
401 { L"ReferencedDomainName", CIM_STRING|COL_FLAG_DYNAMIC },
402 { L"SID", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
403 { L"SidLength", CIM_UINT32 },
405 static const struct column col_softwarelicensingproduct[] =
407 { L"LicenseIsAddon", CIM_BOOLEAN },
408 { L"LicenseStatus", CIM_UINT32 },
410 static const struct column col_sounddevice[] =
412 { L"DeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
413 { L"Manufacturer", CIM_STRING },
414 { L"Name", CIM_STRING },
415 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
416 { L"ProductName", CIM_STRING },
417 { L"Status", CIM_STRING },
418 { L"StatusInfo", CIM_UINT16 },
420 static const struct column col_stdregprov[] =
422 { L"CreateKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
423 { L"EnumKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
424 { L"EnumValues", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
425 { L"GetBinaryValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
426 { L"GetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
427 { L"SetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
428 { L"SetDWORDValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
429 { L"DeleteKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
431 static const struct column col_systemenclosure[] =
433 { L"Caption", CIM_STRING },
434 { L"ChassisTypes", CIM_UINT16|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
435 { L"Description", CIM_STRING },
436 { L"LockPresent", CIM_BOOLEAN },
437 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
438 { L"Name", CIM_STRING },
439 { L"Tag", CIM_STRING },
441 static const struct column col_systemsecurity[] =
443 { L"GetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
444 { L"SetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
446 static const struct column col_sysrestore[] =
448 { L"CreationTime", CIM_STRING },
449 { L"Description", CIM_STRING },
450 { L"EventType", CIM_UINT32 },
451 { L"RestorePointType", CIM_UINT32 },
452 { L"SequenceNumber", CIM_UINT32 },
453 /* methods */
454 { L"CreateRestorePoint", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
455 { L"Disable", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
456 { L"Enable", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
457 { L"GetLastRestoreStatus", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
458 { L"Restore", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
460 static const struct column col_videocontroller[] =
462 { L"AdapterCompatibility", CIM_STRING },
463 { L"AdapterDACType", CIM_STRING },
464 { L"AdapterRAM", CIM_UINT32 },
465 { L"Availability", CIM_UINT16 },
466 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
467 { L"ConfigManagerErrorCode", CIM_UINT32 },
468 { L"CurrentBitsPerPixel", CIM_UINT32 },
469 { L"CurrentHorizontalResolution", CIM_UINT32 },
470 { L"CurrentRefreshRate", CIM_UINT32 },
471 { L"CurrentScanMode", CIM_UINT16 },
472 { L"CurrentVerticalResolution", CIM_UINT32 },
473 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
474 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
475 { L"DriverDate", CIM_DATETIME },
476 { L"DriverVersion", CIM_STRING },
477 { L"InstalledDisplayDrivers", CIM_STRING },
478 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
479 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
480 { L"Status", CIM_STRING },
481 { L"VideoArchitecture", CIM_UINT16 },
482 { L"VideoMemoryType", CIM_UINT16 },
483 { L"VideoModeDescription", CIM_STRING|COL_FLAG_DYNAMIC },
484 { L"VideoProcessor", CIM_STRING|COL_FLAG_DYNAMIC },
487 static const struct column col_volume[] =
489 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
490 { L"DriveLetter", CIM_STRING|COL_FLAG_DYNAMIC },
493 static const struct column col_winsat[] =
495 { L"CPUScore", CIM_REAL32 },
496 { L"D3DScore", CIM_REAL32 },
497 { L"DiskScore", CIM_REAL32 },
498 { L"GraphicsScore", CIM_REAL32 },
499 { L"MemoryScore", CIM_REAL32 },
500 { L"TimeTaken", CIM_STRING|COL_FLAG_KEY },
501 { L"WinSATAssessmentState", CIM_UINT32 },
502 { L"WinSPRLevel", CIM_REAL32 },
505 #include "pshpack1.h"
506 struct record_associator
508 const WCHAR *assocclass;
509 const WCHAR *class;
510 const WCHAR *associator;
512 struct record_baseboard
514 const WCHAR *manufacturer;
515 const WCHAR *model;
516 const WCHAR *name;
517 const WCHAR *product;
518 const WCHAR *serialnumber;
519 const WCHAR *tag;
520 const WCHAR *version;
522 struct record_bios
524 const WCHAR *currentlanguage;
525 const WCHAR *description;
526 UINT8 ecmajorversion;
527 UINT8 ecminorversion;
528 const WCHAR *identificationcode;
529 const WCHAR *manufacturer;
530 const WCHAR *name;
531 const WCHAR *releasedate;
532 const WCHAR *serialnumber;
533 const WCHAR *smbiosbiosversion;
534 UINT16 smbiosmajorversion;
535 UINT16 smbiosminorversion;
536 UINT8 systembiosmajorversion;
537 UINT8 systembiosminorversion;
538 const WCHAR *version;
540 struct record_cdromdrive
542 const WCHAR *device_id;
543 const WCHAR *drive;
544 const WCHAR *mediatype;
545 const WCHAR *name;
546 const WCHAR *pnpdevice_id;
548 struct record_computersystem
550 const WCHAR *description;
551 const WCHAR *domain;
552 UINT16 domainrole;
553 int hypervisorpresent;
554 const WCHAR *manufacturer;
555 const WCHAR *model;
556 const WCHAR *name;
557 UINT32 num_logical_processors;
558 UINT32 num_processors;
559 const WCHAR *systemtype;
560 UINT64 total_physical_memory;
561 const WCHAR *username;
563 struct record_computersystemproduct
565 const WCHAR *identifyingnumber;
566 const WCHAR *name;
567 const WCHAR *skunumber;
568 const WCHAR *uuid;
569 const WCHAR *vendor;
570 const WCHAR *version;
572 struct record_datafile
574 const WCHAR *name;
575 const WCHAR *version;
577 struct record_desktopmonitor
579 const WCHAR *name;
580 UINT32 pixelsperxlogicalinch;
582 struct record_directory
584 UINT32 accessmask;
585 const WCHAR *name;
587 struct record_diskdrive
589 const WCHAR *device_id;
590 UINT32 index;
591 const WCHAR *interfacetype;
592 const WCHAR *manufacturer;
593 const WCHAR *mediatype;
594 const WCHAR *model;
595 const WCHAR *pnpdevice_id;
596 const WCHAR *serialnumber;
597 UINT64 size;
599 struct record_diskdrivetodiskpartition
601 const WCHAR *antecedent;
602 const WCHAR *dependent;
604 struct record_diskpartition
606 int bootable;
607 int bootpartition;
608 const WCHAR *device_id;
609 UINT32 diskindex;
610 UINT32 index;
611 const WCHAR *pnpdevice_id;
612 UINT64 size;
613 UINT64 startingoffset;
614 const WCHAR *type;
616 struct record_displaycontrollerconfig
618 UINT32 bitsperpixel;
619 const WCHAR *caption;
620 UINT32 horizontalresolution;
621 const WCHAR *name;
622 UINT32 verticalresolution;
624 struct record_ip4routetable
626 const WCHAR *destination;
627 INT32 interfaceindex;
628 const WCHAR *nexthop;
630 struct record_logicaldisk
632 const WCHAR *caption;
633 const WCHAR *device_id;
634 UINT32 drivetype;
635 const WCHAR *filesystem;
636 UINT64 freespace;
637 const WCHAR *name;
638 UINT64 size;
639 const WCHAR *volumename;
640 const WCHAR *volumeserialnumber;
642 struct record_logicaldisktopartition
644 const WCHAR *antecedent;
645 const WCHAR *dependent;
647 struct record_networkadapter
649 const WCHAR *adaptertype;
650 UINT16 adaptertypeid;
651 const WCHAR *description;
652 const WCHAR *device_id;
653 const WCHAR *guid;
654 UINT32 index;
655 UINT32 interface_index;
656 const WCHAR *mac_address;
657 const WCHAR *manufacturer;
658 const WCHAR *name;
659 UINT16 netconnection_status;
660 int physicaladapter;
661 const WCHAR *pnpdevice_id;
662 const WCHAR *servicename;
663 UINT64 speed;
665 struct record_networkadapterconfig
667 const struct array *defaultipgateway;
668 const WCHAR *description;
669 int dhcpenabled;
670 const WCHAR *dnsdomain;
671 const WCHAR *dnshostname;
672 const struct array *dnsserversearchorder;
673 UINT32 index;
674 const struct array *ipaddress;
675 UINT32 ipconnectionmetric;
676 int ipenabled;
677 const struct array *ipsubnet;
678 const WCHAR *mac_address;
679 const WCHAR *settingid;
681 struct record_operatingsystem
683 const WCHAR *bootdevice;
684 const WCHAR *buildnumber;
685 const WCHAR *buildtype;
686 const WCHAR *caption;
687 const WCHAR *codeset;
688 const WCHAR *countrycode;
689 const WCHAR *csdversion;
690 const WCHAR *csname;
691 INT16 currenttimezone;
692 UINT64 freephysicalmemory;
693 UINT64 freevirtualmemory;
694 const WCHAR *installdate;
695 const WCHAR *lastbootuptime;
696 const WCHAR *localdatetime;
697 const WCHAR *locale;
698 const WCHAR *manufacturer;
699 const WCHAR *name;
700 UINT32 operatingsystemsku;
701 const WCHAR *organization;
702 const WCHAR *osarchitecture;
703 UINT32 oslanguage;
704 UINT32 osproductsuite;
705 UINT16 ostype;
706 int primary;
707 UINT32 producttype;
708 const WCHAR *registereduser;
709 const WCHAR *serialnumber;
710 UINT16 servicepackmajor;
711 UINT16 servicepackminor;
712 const WCHAR *status;
713 UINT32 suitemask;
714 const WCHAR *systemdirectory;
715 const WCHAR *systemdrive;
716 UINT64 totalvirtualmemorysize;
717 UINT64 totalvisiblememorysize;
718 const WCHAR *version;
719 const WCHAR *windowsdirectory;
721 struct record_pagefileusage
723 const WCHAR *name;
725 struct record_param
727 const WCHAR *class;
728 const WCHAR *method;
729 INT32 direction;
730 const WCHAR *parameter;
731 UINT32 type;
732 UINT32 defaultvalue;
734 struct record_physicalmedia
736 const WCHAR *serialnumber;
737 const WCHAR *tag;
739 struct record_physicalmemory
741 const WCHAR *banklabel;
742 UINT64 capacity;
743 const WCHAR *caption;
744 UINT32 configuredclockspeed;
745 const WCHAR *devicelocator;
746 UINT16 formfactor;
747 UINT16 memorytype;
748 const WCHAR *partnumber;
749 const WCHAR *serial;
751 struct record_pnpentity
753 const WCHAR *device_id;
754 const WCHAR *manufacturer;
755 const WCHAR *name;
757 struct record_printer
759 UINT32 attributes;
760 const WCHAR *device_id;
761 const WCHAR *drivername;
762 UINT32 horizontalresolution;
763 int local;
764 const WCHAR *location;
765 const WCHAR *name;
766 int network;
767 const WCHAR *portname;
769 struct record_process
771 const WCHAR *caption;
772 const WCHAR *commandline;
773 const WCHAR *description;
774 const WCHAR *handle;
775 const WCHAR *name;
776 UINT32 pprocess_id;
777 UINT32 process_id;
778 UINT32 thread_count;
779 UINT64 workingsetsize;
780 /* methods */
781 class_method *create;
782 class_method *get_owner;
784 struct record_processor
786 UINT16 addresswidth;
787 UINT16 architecture;
788 const WCHAR *caption;
789 UINT16 cpu_status;
790 UINT32 currentclockspeed;
791 UINT16 datawidth;
792 const WCHAR *description;
793 const WCHAR *device_id;
794 UINT16 family;
795 UINT16 level;
796 const WCHAR *manufacturer;
797 UINT32 maxclockspeed;
798 const WCHAR *name;
799 UINT32 num_cores;
800 UINT32 num_logical_processors;
801 const WCHAR *processor_id;
802 UINT16 processortype;
803 UINT16 revision;
804 const WCHAR *unique_id;
805 const WCHAR *version;
807 struct record_qualifier
809 const WCHAR *class;
810 const WCHAR *member;
811 UINT32 type;
812 INT32 flavor;
813 const WCHAR *name;
814 INT32 intvalue;
815 const WCHAR *strvalue;
816 int boolvalue;
818 struct record_quickfixengineering
820 const WCHAR *caption;
821 const WCHAR *description;
822 const WCHAR *hotfixid;
823 const WCHAR *installedby;
824 const WCHAR *installedon;
826 struct record_rawsmbiostables
828 const struct array *smbiosdata;
830 struct record_service
832 int accept_pause;
833 int accept_stop;
834 const WCHAR *displayname;
835 const WCHAR *name;
836 UINT32 process_id;
837 const WCHAR *servicetype;
838 const WCHAR *startmode;
839 const WCHAR *state;
840 const WCHAR *systemname;
841 /* methods */
842 class_method *pause_service;
843 class_method *resume_service;
844 class_method *start_service;
845 class_method *stop_service;
847 struct record_sid
849 const WCHAR *accountname;
850 const struct array *binaryrepresentation;
851 const WCHAR *referenceddomainname;
852 const WCHAR *sid;
853 UINT32 sidlength;
855 struct record_softwarelicensingproduct
857 int license_is_addon;
858 UINT32 license_status;
860 struct record_sounddevice
862 const WCHAR *deviceid;
863 const WCHAR *manufacturer;
864 const WCHAR *name;
865 const WCHAR *pnpdeviceid;
866 const WCHAR *productname;
867 const WCHAR *status;
868 UINT16 statusinfo;
870 struct record_stdregprov
872 class_method *createkey;
873 class_method *enumkey;
874 class_method *enumvalues;
875 class_method *getbinaryvalue;
876 class_method *getstringvalue;
877 class_method *setstringvalue;
878 class_method *setdwordvalue;
879 class_method *deletekey;
881 struct record_sysrestore
883 const WCHAR *creation_time;
884 const WCHAR *description;
885 UINT32 event_type;
886 UINT32 restore_point_type;
887 UINT32 sequence_number;
888 class_method *create_restore_point;
889 class_method *disable_restore;
890 class_method *enable_restore;
891 class_method *get_last_restore_status;
892 class_method *restore;
894 struct record_systemsecurity
896 class_method *getsd;
897 class_method *setsd;
899 struct record_systemenclosure
901 const WCHAR *caption;
902 const struct array *chassistypes;
903 const WCHAR *description;
904 int lockpresent;
905 const WCHAR *manufacturer;
906 const WCHAR *name;
907 const WCHAR *tag;
909 struct record_videocontroller
911 const WCHAR *adapter_compatibility;
912 const WCHAR *adapter_dactype;
913 UINT32 adapter_ram;
914 UINT16 availability;
915 const WCHAR *caption;
916 UINT32 config_errorcode;
917 UINT32 current_bitsperpixel;
918 UINT32 current_horizontalres;
919 UINT32 current_refreshrate;
920 UINT16 current_scanmode;
921 UINT32 current_verticalres;
922 const WCHAR *description;
923 const WCHAR *device_id;
924 const WCHAR *driverdate;
925 const WCHAR *driverversion;
926 const WCHAR *installeddriver;
927 const WCHAR *name;
928 const WCHAR *pnpdevice_id;
929 const WCHAR *status;
930 UINT16 videoarchitecture;
931 UINT16 videomemorytype;
932 const WCHAR *videomodedescription;
933 const WCHAR *videoprocessor;
936 struct record_volume
938 const WCHAR *deviceid;
939 const WCHAR *driveletter;
942 struct record_winsat
944 FLOAT cpuscore;
945 FLOAT d3dscore;
946 FLOAT diskscrore;
947 FLOAT graphicsscore;
948 FLOAT memoryscore;
949 const WCHAR *timetaken;
950 UINT32 winsatassessmentstate;
951 FLOAT winsprlevel;
953 #include "poppack.h"
955 static const struct record_associator data_associator[] =
957 { L"Win32_DiskDriveToDiskPartition", L"Win32_DiskPartition", L"Win32_DiskDrive" },
958 { L"Win32_LogicalDiskToPartition", L"Win32_LogicalDisk", L"Win32_DiskPartition" },
960 static const struct record_pagefileusage data_pagefileusage[] =
962 { L"c:\\pagefile.sys", },
964 static const struct record_param data_param[] =
966 { L"__SystemSecurity", L"GetSD", -1, L"ReturnValue", CIM_UINT32 },
967 { L"__SystemSecurity", L"GetSD", -1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
968 { L"__SystemSecurity", L"SetSD", 1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
969 { L"__SystemSecurity", L"SetSD", -1, L"ReturnValue", CIM_UINT32 },
970 { L"StdRegProv", L"CreateKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
971 { L"StdRegProv", L"CreateKey", 1, L"sSubKeyName", CIM_STRING },
972 { L"StdRegProv", L"CreateKey", -1, L"ReturnValue", CIM_UINT32 },
973 { L"StdRegProv", L"DeleteKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
974 { L"StdRegProv", L"DeleteKey", 1, L"sSubKeyName", CIM_STRING },
975 { L"StdRegProv", L"DeleteKey", -1, L"ReturnValue", CIM_UINT32 },
976 { L"StdRegProv", L"EnumKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
977 { L"StdRegProv", L"EnumKey", 1, L"sSubKeyName", CIM_STRING },
978 { L"StdRegProv", L"EnumKey", -1, L"ReturnValue", CIM_UINT32 },
979 { L"StdRegProv", L"EnumKey", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
980 { L"StdRegProv", L"EnumValues", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
981 { L"StdRegProv", L"EnumValues", 1, L"sSubKeyName", CIM_STRING },
982 { L"StdRegProv", L"EnumValues", -1, L"ReturnValue", CIM_UINT32 },
983 { L"StdRegProv", L"EnumValues", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
984 { L"StdRegProv", L"EnumValues", -1, L"Types", CIM_SINT32|CIM_FLAG_ARRAY },
985 { L"StdRegProv", L"GetBinaryValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
986 { L"StdRegProv", L"GetBinaryValue", 1, L"sSubKeyName", CIM_STRING },
987 { L"StdRegProv", L"GetBinaryValue", 1, L"sValueName", CIM_STRING },
988 { L"StdRegProv", L"GetBinaryValue", -1, L"ReturnValue", CIM_UINT32 },
989 { L"StdRegProv", L"GetBinaryValue", -1, L"uValue", CIM_UINT8|CIM_FLAG_ARRAY },
990 { L"StdRegProv", L"GetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
991 { L"StdRegProv", L"GetStringValue", 1, L"sSubKeyName", CIM_STRING },
992 { L"StdRegProv", L"GetStringValue", 1, L"sValueName", CIM_STRING },
993 { L"StdRegProv", L"GetStringValue", -1, L"ReturnValue", CIM_UINT32 },
994 { L"StdRegProv", L"GetStringValue", -1, L"sValue", CIM_STRING },
995 { L"StdRegProv", L"SetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
996 { L"StdRegProv", L"SetStringValue", 1, L"sSubKeyName", CIM_STRING },
997 { L"StdRegProv", L"SetStringValue", 1, L"sValueName", CIM_STRING },
998 { L"StdRegProv", L"SetStringValue", 1, L"sValue", CIM_STRING },
999 { L"StdRegProv", L"SetStringValue", -1, L"ReturnValue", CIM_UINT32 },
1000 { L"StdRegProv", L"SetDWORDValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
1001 { L"StdRegProv", L"SetDWORDValue", 1, L"sSubKeyName", CIM_STRING },
1002 { L"StdRegProv", L"SetDWORDValue", 1, L"sValueName", CIM_STRING },
1003 { L"StdRegProv", L"SetDWORDValue", 1, L"uValue", CIM_UINT32 },
1004 { L"StdRegProv", L"SetDWORDValue", -1, L"ReturnValue", CIM_UINT32 },
1005 { L"SystemRestore", L"Disable", 1, L"Drive", CIM_STRING },
1006 { L"SystemRestore", L"Disable", -1, L"ReturnValue", CIM_UINT32 },
1007 { L"SystemRestore", L"Enable", 1, L"Drive", CIM_STRING },
1008 { L"SystemRestore", L"Enable", -1, L"ReturnValue", CIM_UINT32 },
1009 { L"Win32_Process", L"Create", 1, L"CommandLine", CIM_STRING },
1010 { L"Win32_Process", L"Create", 1, L"CurrentDirectory", CIM_STRING },
1011 { L"Win32_Process", L"Create", -1, L"ProcessId", CIM_UINT32 },
1012 { L"Win32_Process", L"Create", -1, L"ReturnValue", CIM_UINT32 },
1013 { L"Win32_Process", L"GetOwner", -1, L"ReturnValue", CIM_UINT32 },
1014 { L"Win32_Process", L"GetOwner", -1, L"User", CIM_STRING },
1015 { L"Win32_Process", L"GetOwner", -1, L"Domain", CIM_STRING },
1016 { L"Win32_Service", L"PauseService", -1, L"ReturnValue", CIM_UINT32 },
1017 { L"Win32_Service", L"ResumeService", -1, L"ReturnValue", CIM_UINT32 },
1018 { L"Win32_Service", L"StartService", -1, L"ReturnValue", CIM_UINT32 },
1019 { L"Win32_Service", L"StopService", -1, L"ReturnValue", CIM_UINT32 },
1022 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1023 WBEM_FLAVOR_ORIGIN_PROPAGATED)
1025 static const struct record_physicalmedia data_physicalmedia[] =
1027 { L"WINEHDISK", L"\\\\.\\PHYSICALDRIVE0" }
1030 static const struct record_rawsmbiostables data_rawsmbiostables[] =
1032 { 0 },
1035 static const struct record_qualifier data_qualifier[] =
1037 { L"__WIN32_PROCESS_GETOWNER_OUT", L"User", CIM_SINT32, FLAVOR_ID, L"ID", 0 },
1038 { L"__WIN32_PROCESS_GETOWNER_OUT", L"Domain", CIM_SINT32, FLAVOR_ID, L"ID", 1 }
1041 static const struct record_quickfixengineering data_quickfixengineering[] =
1043 { L"http://winehq.org", L"Update", L"KB1234567", L"", L"22/2/2022" },
1046 static const struct record_softwarelicensingproduct data_softwarelicensingproduct[] =
1048 { 0, 1 },
1051 static const struct record_stdregprov data_stdregprov[] =
1054 reg_create_key,
1055 reg_enum_key,
1056 reg_enum_values,
1057 reg_get_binaryvalue,
1058 reg_get_stringvalue,
1059 reg_set_stringvalue,
1060 reg_set_dwordvalue,
1061 reg_delete_key,
1065 static const struct record_sysrestore data_sysrestore[] =
1067 { NULL, NULL, 0, 0, 0, sysrestore_create, sysrestore_disable, sysrestore_enable, sysrestore_get_last_status,
1068 sysrestore_restore }
1071 static UINT16 systemenclosure_chassistypes[] =
1075 static const struct array systemenclosure_chassistypes_array =
1077 sizeof(*systemenclosure_chassistypes),
1078 ARRAY_SIZE(systemenclosure_chassistypes),
1079 &systemenclosure_chassistypes
1081 static const struct record_systemsecurity data_systemsecurity[] =
1083 { security_get_sd, security_set_sd }
1085 static const struct record_winsat data_winsat[] =
1087 { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, L"MostRecentAssessment", 1 /* Valid */, 8.0f },
1090 /* check if row matches condition and update status */
1091 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
1093 LONGLONG val;
1094 UINT type;
1096 if (!cond)
1098 *status = FILL_STATUS_UNFILTERED;
1099 return TRUE;
1101 if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1103 *status = FILL_STATUS_FAILED;
1104 return FALSE;
1106 *status = FILL_STATUS_FILTERED;
1107 return val != 0;
1110 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
1112 if (!table->num_rows_allocated)
1114 if (!(table->data = malloc( row_count * row_size ))) return FALSE;
1115 table->num_rows_allocated = row_count;
1116 return TRUE;
1118 if (row_count > table->num_rows_allocated)
1120 BYTE *data;
1121 UINT count = max( row_count, table->num_rows_allocated * 2 );
1122 if (!(data = realloc( table->data, count * row_size ))) return FALSE;
1123 table->data = data;
1124 table->num_rows_allocated = count;
1126 return TRUE;
1129 #include "pshpack1.h"
1130 struct smbios_prologue
1132 BYTE calling_method;
1133 BYTE major_version;
1134 BYTE minor_version;
1135 BYTE revision;
1136 DWORD length;
1139 enum smbios_type
1141 SMBIOS_TYPE_BIOS,
1142 SMBIOS_TYPE_SYSTEM,
1143 SMBIOS_TYPE_BASEBOARD,
1144 SMBIOS_TYPE_CHASSIS,
1147 struct smbios_header
1149 BYTE type;
1150 BYTE length;
1151 WORD handle;
1154 struct smbios_baseboard
1156 struct smbios_header hdr;
1157 BYTE vendor;
1158 BYTE product;
1159 BYTE version;
1160 BYTE serial;
1163 struct smbios_bios
1165 struct smbios_header hdr;
1166 BYTE vendor;
1167 BYTE version;
1168 WORD start;
1169 BYTE date;
1170 BYTE size;
1171 UINT64 characteristics;
1172 BYTE characteristics_ext[2];
1173 BYTE system_bios_major_release;
1174 BYTE system_bios_minor_release;
1175 BYTE ec_firmware_major_release;
1176 BYTE ec_firmware_minor_release;
1179 struct smbios_chassis
1181 struct smbios_header hdr;
1182 BYTE vendor;
1183 BYTE type;
1184 BYTE version;
1185 BYTE serial;
1186 BYTE asset_tag;
1189 struct smbios_system
1191 struct smbios_header hdr;
1192 BYTE vendor;
1193 BYTE product;
1194 BYTE version;
1195 BYTE serial;
1196 BYTE uuid[16];
1198 #include "poppack.h"
1200 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1202 static const struct smbios_header *find_smbios_entry( enum smbios_type type, const char *buf, UINT len )
1204 const char *ptr, *start;
1205 const struct smbios_prologue *prologue;
1206 const struct smbios_header *hdr;
1208 if (len < sizeof(struct smbios_prologue)) return NULL;
1209 prologue = (const struct smbios_prologue *)buf;
1210 if (prologue->length > len - sizeof(*prologue) || prologue->length < sizeof(*hdr)) return NULL;
1212 start = (const char *)(prologue + 1);
1213 hdr = (const struct smbios_header *)start;
1215 for (;;)
1217 if ((const char *)hdr - start >= prologue->length - sizeof(*hdr)) return NULL;
1219 if (!hdr->length)
1221 WARN( "invalid entry\n" );
1222 return NULL;
1225 if (hdr->type == type)
1227 if ((const char *)hdr - start + hdr->length > prologue->length) return NULL;
1228 break;
1230 else /* skip other entries and their strings */
1232 for (ptr = (const char *)hdr + hdr->length; ptr - buf < len && *ptr; ptr++)
1234 for (; ptr - buf < len; ptr++) if (!*ptr) break;
1236 if (ptr == (const char *)hdr + hdr->length) ptr++;
1237 hdr = (const struct smbios_header *)(ptr + 1);
1241 return hdr;
1244 static WCHAR *get_smbios_string( BYTE id, const char *buf, UINT offset, UINT buflen )
1246 const char *ptr = buf + offset;
1247 UINT i = 0;
1249 if (!id || offset >= buflen) return NULL;
1250 for (ptr = buf + offset; ptr - buf < buflen && *ptr; ptr++)
1252 if (++i == id) return heap_strdupAW( ptr );
1253 for (; ptr - buf < buflen; ptr++) if (!*ptr) break;
1255 return NULL;
1258 static WCHAR *get_baseboard_string( BYTE id, const char *buf, UINT len )
1260 const struct smbios_header *hdr;
1261 const struct smbios_baseboard *baseboard;
1262 UINT offset;
1264 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BASEBOARD, buf, len ))) return NULL;
1266 baseboard = (const struct smbios_baseboard *)hdr;
1267 offset = (const char *)baseboard - buf + baseboard->hdr.length;
1268 return get_smbios_string( id, buf, offset, len );
1271 static WCHAR *get_baseboard_manufacturer( const char *buf, UINT len )
1273 WCHAR *ret = get_baseboard_string( 1, buf, len );
1274 if (!ret) return wcsdup( L"Intel Corporation" );
1275 return ret;
1278 static WCHAR *get_baseboard_product( const char *buf, UINT len )
1280 WCHAR *ret = get_baseboard_string( 2, buf, len );
1281 if (!ret) return wcsdup( L"Base Board" );
1282 return ret;
1285 static WCHAR *get_baseboard_serialnumber( const char *buf, UINT len )
1287 WCHAR *ret = get_baseboard_string( 4, buf, len );
1288 if (!ret) return wcsdup( L"None" );
1289 return ret;
1292 static WCHAR *get_baseboard_version( const char *buf, UINT len )
1294 WCHAR *ret = get_baseboard_string( 3, buf, len );
1295 if (!ret) return wcsdup( L"1.0" );
1296 return ret;
1299 static enum fill_status fill_baseboard( struct table *table, const struct expr *cond )
1301 struct record_baseboard *rec;
1302 enum fill_status status = FILL_STATUS_UNFILTERED;
1303 UINT row = 0, len;
1304 char *buf;
1306 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1308 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1309 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1310 GetSystemFirmwareTable( RSMB, 0, buf, len );
1312 rec = (struct record_baseboard *)table->data;
1313 rec->manufacturer = get_baseboard_manufacturer( buf, len );
1314 rec->model = L"Base Board";
1315 rec->name = L"Base Board";
1316 rec->product = get_baseboard_product( buf, len );
1317 rec->serialnumber = get_baseboard_serialnumber( buf, len );
1318 rec->tag = L"Base Board";
1319 rec->version = get_baseboard_version( buf, len );
1320 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1321 else row++;
1323 free( buf );
1325 TRACE("created %u rows\n", row);
1326 table->num_rows = row;
1327 return status;
1330 static UINT16 get_bios_smbiosmajorversion( const char *buf, UINT len )
1332 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1333 if (len < sizeof(*prologue)) return 2;
1334 return prologue->major_version;
1337 static UINT16 get_bios_smbiosminorversion( const char *buf, UINT len )
1339 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1340 if (len < sizeof(*prologue)) return 0;
1341 return prologue->minor_version;
1344 static WCHAR *get_bios_string( BYTE id, const char *buf, UINT len )
1346 const struct smbios_header *hdr;
1347 const struct smbios_bios *bios;
1348 UINT offset;
1350 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return NULL;
1352 bios = (const struct smbios_bios *)hdr;
1353 offset = (const char *)bios - buf + bios->hdr.length;
1354 return get_smbios_string( id, buf, offset, len );
1357 static WCHAR *get_bios_manufacturer( const char *buf, UINT len )
1359 WCHAR *ret = get_bios_string( 1, buf, len );
1360 if (!ret) return wcsdup( L"The Wine Project" );
1361 return ret;
1364 static WCHAR *convert_bios_date( const WCHAR *str )
1366 static const WCHAR fmtW[] = L"%04u%02u%02u000000.000000+000";
1367 UINT year, month, day, len = lstrlenW( str );
1368 const WCHAR *p = str, *q;
1369 WCHAR *ret;
1371 while (len && iswspace( *p )) { p++; len--; }
1372 while (len && iswspace( p[len - 1] )) { len--; }
1374 q = p;
1375 while (len && is_digit( *q )) { q++; len--; };
1376 if (q - p != 2 || !len || *q != '/') return NULL;
1377 month = (p[0] - '0') * 10 + p[1] - '0';
1379 p = ++q; len--;
1380 while (len && is_digit( *q )) { q++; len--; };
1381 if (q - p != 2 || !len || *q != '/') return NULL;
1382 day = (p[0] - '0') * 10 + p[1] - '0';
1384 p = ++q; len--;
1385 while (len && is_digit( *q )) { q++; len--; };
1386 if (q - p == 4) year = (p[0] - '0') * 1000 + (p[1] - '0') * 100 + (p[2] - '0') * 10 + p[3] - '0';
1387 else if (q - p == 2) year = 1900 + (p[0] - '0') * 10 + p[1] - '0';
1388 else return NULL;
1390 if (!(ret = malloc( sizeof(fmtW) ))) return NULL;
1391 swprintf( ret, ARRAY_SIZE(fmtW), fmtW, year, month, day );
1392 return ret;
1395 static WCHAR *get_bios_releasedate( const char *buf, UINT len )
1397 WCHAR *ret, *date = get_bios_string( 3, buf, len );
1398 if (!date || !(ret = convert_bios_date( date ))) ret = wcsdup( L"20120608000000.000000+000" );
1399 free( date );
1400 return ret;
1403 static WCHAR *get_bios_serialnumber( const char *buf, UINT len )
1405 WCHAR *ret = get_bios_string( 4, buf, len );
1406 if (!ret) return wcsdup( L"0" );
1407 return ret;
1410 static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len )
1412 WCHAR *ret = get_bios_string( 2, buf, len );
1413 if (!ret) return wcsdup( L"Wine" );
1414 return ret;
1417 static BYTE get_bios_ec_firmware_major_release( const char *buf, UINT len )
1419 const struct smbios_header *hdr;
1420 const struct smbios_bios *bios;
1422 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1424 bios = (const struct smbios_bios *)hdr;
1425 if (bios->hdr.length >= 0x18) return bios->ec_firmware_major_release;
1426 else return 0xFF;
1429 static BYTE get_bios_ec_firmware_minor_release( const char *buf, UINT len )
1431 const struct smbios_header *hdr;
1432 const struct smbios_bios *bios;
1434 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1436 bios = (const struct smbios_bios *)hdr;
1437 if (bios->hdr.length >= 0x18) return bios->ec_firmware_minor_release;
1438 else return 0xFF;
1441 static BYTE get_bios_system_bios_major_release( const char *buf, UINT len )
1443 const struct smbios_header *hdr;
1444 const struct smbios_bios *bios;
1446 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1448 bios = (const struct smbios_bios *)hdr;
1449 if (bios->hdr.length >= 0x18) return bios->system_bios_major_release;
1450 else return 0xFF;
1453 static BYTE get_bios_system_bios_minor_release( const char *buf, UINT len )
1455 const struct smbios_header *hdr;
1456 const struct smbios_bios *bios;
1458 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1460 bios = (const struct smbios_bios *)hdr;
1461 if (bios->hdr.length >= 0x18) return bios->system_bios_minor_release;
1462 else return 0xFF;
1465 static enum fill_status fill_bios( struct table *table, const struct expr *cond )
1467 struct record_bios *rec;
1468 enum fill_status status = FILL_STATUS_UNFILTERED;
1469 UINT row = 0, len;
1470 char *buf;
1472 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1474 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1475 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1476 GetSystemFirmwareTable( RSMB, 0, buf, len );
1478 rec = (struct record_bios *)table->data;
1479 rec->currentlanguage = NULL;
1480 rec->description = L"Default System BIOS";
1481 rec->ecmajorversion = get_bios_ec_firmware_major_release( buf, len );
1482 rec->ecminorversion = get_bios_ec_firmware_minor_release( buf, len );
1483 rec->identificationcode = NULL;
1484 rec->manufacturer = get_bios_manufacturer( buf, len );
1485 rec->name = L"Default System BIOS";
1486 rec->releasedate = get_bios_releasedate( buf, len );
1487 rec->serialnumber = get_bios_serialnumber( buf, len );
1488 rec->smbiosbiosversion = get_bios_smbiosbiosversion( buf, len );
1489 rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len );
1490 rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
1491 rec->systembiosmajorversion = get_bios_system_bios_major_release( buf, len );
1492 rec->systembiosminorversion = get_bios_system_bios_minor_release( buf, len );
1493 rec->version = L"WINE - 1";
1494 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1495 else row++;
1497 free( buf );
1499 TRACE("created %u rows\n", row);
1500 table->num_rows = row;
1501 return status;
1504 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1506 WCHAR drive[3], root[] = L"A:\\";
1507 struct record_cdromdrive *rec;
1508 UINT i, row = 0, offset = 0;
1509 DWORD drives = GetLogicalDrives();
1510 enum fill_status status = FILL_STATUS_UNFILTERED;
1512 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1514 for (i = 0; i < 26; i++)
1516 if (drives & (1 << i))
1518 root[0] = 'A' + i;
1519 if (GetDriveTypeW( root ) != DRIVE_CDROM)
1520 continue;
1522 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1524 rec = (struct record_cdromdrive *)(table->data + offset);
1525 rec->device_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1526 swprintf( drive, ARRAY_SIZE( drive ), L"%c:", 'A' + i );
1527 rec->drive = wcsdup( drive );
1528 rec->mediatype = L"CR-ROM";
1529 rec->name = L"Wine CD_ROM ATA Device";
1530 rec->pnpdevice_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1531 if (!match_row( table, row, cond, &status ))
1533 free_row_values( table, row );
1534 continue;
1536 offset += sizeof(*rec);
1537 row++;
1540 TRACE("created %u rows\n", row);
1541 table->num_rows = row;
1542 return status;
1545 static UINT get_processor_count(void)
1547 SYSTEM_BASIC_INFORMATION info;
1549 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1550 return info.NumberOfProcessors;
1553 static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
1555 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
1556 UINT core_relation_count = 0, package_relation_count = 0;
1557 NTSTATUS status;
1558 ULONG len, offset = 0;
1559 BOOL smt_enabled = FALSE;
1560 DWORD all = RelationAll;
1562 if (num_packages) *num_packages = 1;
1563 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
1564 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1566 if (!(buf = malloc( len ))) return get_processor_count();
1567 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, &len );
1568 if (status != STATUS_SUCCESS)
1570 free( buf );
1571 return get_processor_count();
1574 while (offset < len)
1576 entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
1578 if (entry->Relationship == RelationProcessorCore)
1580 core_relation_count++;
1581 if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
1583 else if (entry->Relationship == RelationProcessorPackage)
1585 package_relation_count++;
1587 offset += entry->Size;
1590 free( buf );
1591 if (num_physical) *num_physical = core_relation_count;
1592 if (num_packages) *num_packages = package_relation_count;
1593 return smt_enabled ? core_relation_count * 2 : core_relation_count;
1596 static UINT64 get_total_physical_memory(void)
1598 MEMORYSTATUSEX status;
1600 status.dwLength = sizeof(status);
1601 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1602 return status.ullTotalPhys;
1605 static UINT64 get_available_physical_memory(void)
1607 MEMORYSTATUSEX status;
1609 status.dwLength = sizeof(status);
1610 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1611 return status.ullAvailPhys;
1614 static UINT64 get_available_virtual_memory(void)
1616 MEMORYSTATUSEX status;
1618 status.dwLength = sizeof(status);
1619 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1620 return status.ullAvailVirtual;
1623 static WCHAR *get_computername(void)
1625 WCHAR *ret;
1626 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1628 if (!(ret = malloc( size * sizeof(WCHAR) ))) return NULL;
1629 GetComputerNameW( ret, &size );
1630 return ret;
1633 static const WCHAR *get_systemtype(void)
1635 SYSTEM_INFO info;
1636 GetNativeSystemInfo( &info );
1637 if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return L"x64 based PC";
1638 return L"x86 based PC";
1641 static WCHAR *get_username(void)
1643 WCHAR *ret;
1644 DWORD compsize, usersize;
1645 DWORD size;
1647 compsize = 0;
1648 GetComputerNameW( NULL, &compsize );
1649 usersize = 0;
1650 GetUserNameW( NULL, &usersize );
1651 size = compsize + usersize; /* two null terminators account for the \ */
1652 if (!(ret = malloc( size * sizeof(WCHAR) ))) return NULL;
1653 GetComputerNameW( ret, &compsize );
1654 ret[compsize] = '\\';
1655 GetUserNameW( ret + compsize + 1, &usersize );
1656 return ret;
1659 static WCHAR *get_compsysproduct_string( BYTE id, const char *buf, UINT len )
1661 const struct smbios_header *hdr;
1662 const struct smbios_system *system;
1663 UINT offset;
1665 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL;
1667 system = (const struct smbios_system *)hdr;
1668 offset = (const char *)system - buf + system->hdr.length;
1669 return get_smbios_string( id, buf, offset, len );
1672 static WCHAR *get_compsysproduct_name( const char *buf, UINT len )
1674 WCHAR *ret = get_compsysproduct_string( 2, buf, len );
1675 if (!ret) return wcsdup( L"Wine" );
1676 return ret;
1679 static WCHAR *get_compsysproduct_vendor( const char *buf, UINT len )
1681 WCHAR *ret = get_compsysproduct_string( 1, buf, len );
1682 if (!ret) return wcsdup( L"The Wine Project" );
1683 return ret;
1686 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1688 struct record_computersystem *rec;
1689 enum fill_status status = FILL_STATUS_UNFILTERED;
1690 UINT row = 0, len;
1691 char *buf;
1693 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1695 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1696 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1697 GetSystemFirmwareTable( RSMB, 0, buf, len );
1699 rec = (struct record_computersystem *)table->data;
1700 rec->description = L"AT/AT COMPATIBLE";
1701 rec->domain = L"WORKGROUP";
1702 rec->domainrole = 0; /* standalone workstation */
1703 rec->hypervisorpresent = 0;
1704 rec->manufacturer = get_compsysproduct_vendor( buf, len );
1705 rec->model = get_compsysproduct_name( buf, len );
1706 rec->name = get_computername();
1707 rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
1708 rec->systemtype = get_systemtype();
1709 rec->total_physical_memory = get_total_physical_memory();
1710 rec->username = get_username();
1711 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1712 else row++;
1714 free( buf );
1716 TRACE("created %u rows\n", row);
1717 table->num_rows = row;
1718 return status;
1721 static WCHAR *get_compsysproduct_identifyingnumber( const char *buf, UINT len )
1723 WCHAR *ret = get_compsysproduct_string( 4, buf, len );
1724 if (!ret) return wcsdup( L"0" );
1725 return ret;
1728 static WCHAR *get_compsysproduct_uuid( const char *buf, UINT len )
1730 static const BYTE none[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1731 const struct smbios_header *hdr;
1732 const struct smbios_system *system;
1733 const BYTE *ptr;
1734 WCHAR *ret = NULL;
1736 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len )) || hdr->length < sizeof(*system)) goto done;
1737 system = (const struct smbios_system *)hdr;
1738 if (!memcmp( system->uuid, none, sizeof(none) ) || !(ret = malloc( 37 * sizeof(WCHAR) ))) goto done;
1740 ptr = system->uuid;
1741 swprintf( ret, 37, L"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr[0], ptr[1],
1742 ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1743 ptr[14], ptr[15] );
1744 done:
1745 if (!ret) ret = wcsdup( L"deaddead-dead-dead-dead-deaddeaddead" );
1746 return ret;
1749 static WCHAR *get_compsysproduct_version( const char *buf, UINT len )
1751 WCHAR *ret = get_compsysproduct_string( 3, buf, len );
1752 if (!ret) return wcsdup( L"1.0" );
1753 return ret;
1756 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1758 struct record_computersystemproduct *rec;
1759 enum fill_status status = FILL_STATUS_UNFILTERED;
1760 UINT row = 0, len;
1761 char *buf;
1763 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1765 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1766 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1767 GetSystemFirmwareTable( RSMB, 0, buf, len );
1769 rec = (struct record_computersystemproduct *)table->data;
1770 rec->identifyingnumber = get_compsysproduct_identifyingnumber( buf, len );
1771 rec->name = get_compsysproduct_name( buf, len );
1772 rec->skunumber = NULL;
1773 rec->uuid = get_compsysproduct_uuid( buf, len );
1774 rec->vendor = get_compsysproduct_vendor( buf, len );
1775 rec->version = get_compsysproduct_version( buf, len );
1776 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1777 else row++;
1779 free( buf );
1781 TRACE("created %u rows\n", row);
1782 table->num_rows = row;
1783 return status;
1786 struct dirstack
1788 WCHAR **dirs;
1789 UINT *len_dirs;
1790 UINT num_dirs;
1791 UINT num_allocated;
1794 static struct dirstack *alloc_dirstack( UINT size )
1796 struct dirstack *dirstack;
1798 if (!(dirstack = malloc( sizeof(*dirstack) ))) return NULL;
1799 if (!(dirstack->dirs = malloc( sizeof(WCHAR *) * size )))
1801 free( dirstack );
1802 return NULL;
1804 if (!(dirstack->len_dirs = malloc( sizeof(UINT) * size )))
1806 free( dirstack->dirs );
1807 free( dirstack );
1808 return NULL;
1810 dirstack->num_dirs = 0;
1811 dirstack->num_allocated = size;
1812 return dirstack;
1815 static void clear_dirstack( struct dirstack *dirstack )
1817 UINT i;
1818 for (i = 0; i < dirstack->num_dirs; i++) free( dirstack->dirs[i] );
1819 dirstack->num_dirs = 0;
1822 static void free_dirstack( struct dirstack *dirstack )
1824 clear_dirstack( dirstack );
1825 free( dirstack->dirs );
1826 free( dirstack->len_dirs );
1827 free( dirstack );
1830 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1832 UINT size, i = dirstack->num_dirs;
1834 if (!dir) return FALSE;
1836 if (i == dirstack->num_allocated)
1838 WCHAR **tmp;
1839 UINT *len_tmp;
1841 size = dirstack->num_allocated * 2;
1842 if (!(tmp = realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1843 dirstack->dirs = tmp;
1844 if (!(len_tmp = realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1845 dirstack->len_dirs = len_tmp;
1846 dirstack->num_allocated = size;
1848 dirstack->dirs[i] = dir;
1849 dirstack->len_dirs[i] = len;
1850 dirstack->num_dirs++;
1851 return TRUE;
1854 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1856 if (!dirstack->num_dirs)
1858 *len = 0;
1859 return NULL;
1861 dirstack->num_dirs--;
1862 *len = dirstack->len_dirs[dirstack->num_dirs];
1863 return dirstack->dirs[dirstack->num_dirs];
1866 static const WCHAR *peek_dir( struct dirstack *dirstack )
1868 if (!dirstack->num_dirs) return NULL;
1869 return dirstack->dirs[dirstack->num_dirs - 1];
1872 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1874 UINT i = 0;
1875 WCHAR *ret;
1877 if (!(ret = malloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1878 ret[i++] = drive;
1879 ret[i++] = ':';
1880 ret[i++] = '\\';
1881 if (path && len)
1883 memcpy( ret + i, path, len * sizeof(WCHAR) );
1884 i += len;
1885 ret[i++] = '\\';
1887 ret[i++] = '*';
1888 ret[i] = 0;
1889 return ret;
1892 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1894 UINT i = 0, len = 0;
1895 const WCHAR *p;
1896 WCHAR *ret;
1898 for (p = path; *p; p++)
1900 if (*p == '\\') len += 2;
1901 else len++;
1903 if (!(ret = malloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1904 ret[i++] = drive;
1905 ret[i++] = ':';
1906 ret[i++] = '\\';
1907 ret[i++] = '\\';
1908 for (p = path; *p; p++)
1910 if (*p != '\\') ret[i++] = *p;
1911 else
1913 ret[i++] = '\\';
1914 ret[i++] = '\\';
1917 ret[i] = 0;
1918 return ret;
1921 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1923 const WCHAR *p = path, *start;
1924 UINT len, i;
1925 WCHAR *ret;
1927 if (!iswalpha( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1928 start = path + 4;
1929 len = lstrlenW( start );
1930 p = start + len - 1;
1931 if (*p == '\\') return NULL;
1933 while (p >= start && *p != '\\') { len--; p--; };
1934 while (p >= start && *p == '\\') { len--; p--; };
1936 if (!(ret = malloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1937 for (i = 0, p = start; p < start + len; p++)
1939 if (p[0] == '\\' && p[1] == '\\')
1941 ret[i++] = '\\';
1942 p++;
1944 else ret[i++] = *p;
1946 ret[i] = 0;
1947 *ret_len = i;
1948 return ret;
1951 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1953 UINT i;
1954 for (i = 0; i < dirstack->num_dirs; i++) if (!wcscmp( dirstack->dirs[i], path )) return TRUE;
1955 return FALSE;
1958 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1959 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1961 const struct expr *left, *right;
1963 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1965 left = cond->u.expr.left;
1966 right = cond->u.expr.right;
1967 if (cond->u.expr.op == OP_EQ)
1969 UINT len;
1970 WCHAR *path;
1971 const WCHAR *str = NULL;
1973 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1974 !wcscmp( left->u.propval->name, L"Name" ) &&
1975 towupper( right->u.sval[0] ) == towupper( root ))
1977 str = right->u.sval;
1979 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1980 !wcscmp( right->u.propval->name, L"Name" ) &&
1981 towupper( left->u.sval[0] ) == towupper( root ))
1983 str = left->u.sval;
1985 if (str && (path = build_dirname( str, &len )))
1987 if (seen_dir( dirstack, path ))
1989 free( path );
1990 return ++*count;
1992 else if (push_dir( dirstack, path, len )) return ++*count;
1993 free( path );
1994 return *count = 0;
1997 else if (cond->u.expr.op == OP_OR)
1999 UINT left_count = 0, right_count = 0;
2001 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
2002 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
2003 return *count += left_count + right_count;
2005 return *count = 0;
2008 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
2010 UINT len_path = 0, len_segment = lstrlenW( segment );
2011 WCHAR *ret;
2013 *len = 0;
2014 if (path) len_path = lstrlenW( path );
2015 if (!(ret = malloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
2016 if (path && len_path)
2018 memcpy( ret, path, len_path * sizeof(WCHAR) );
2019 ret[len_path] = '\\';
2020 *len += len_path + 1;
2022 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
2023 *len += len_segment;
2024 ret[*len] = 0;
2025 return ret;
2028 static WCHAR *get_file_version( const WCHAR *filename )
2030 VS_FIXEDFILEINFO *info;
2031 UINT size;
2032 DWORD len = 4 * 5 + ARRAY_SIZE( L"%u.%u.%u.%u" );
2033 void *block;
2034 WCHAR *ret;
2036 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
2037 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = malloc( size )))
2039 free( ret );
2040 return NULL;
2042 if (!GetFileVersionInfoW( filename, 0, size, block ) ||
2043 !VerQueryValueW( block, L"\\", (void **)&info, &size ))
2045 free( block );
2046 free( ret );
2047 return NULL;
2049 swprintf( ret, len, L"%u.%u.%u.%u", info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
2050 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
2051 free( block );
2052 return ret;
2055 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
2057 struct record_datafile *rec;
2058 UINT i, len, row = 0, offset = 0, num_expected_rows;
2059 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
2060 DWORD drives = GetLogicalDrives();
2061 WIN32_FIND_DATAW data;
2062 HANDLE handle;
2063 struct dirstack *dirstack;
2064 enum fill_status status = FILL_STATUS_UNFILTERED;
2066 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
2068 dirstack = alloc_dirstack(2);
2070 for (i = 0; i < 26; i++)
2072 if (!(drives & (1 << i))) continue;
2074 root[0] = 'A' + i;
2075 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
2077 num_expected_rows = 0;
2078 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
2080 for (;;)
2082 free( glob );
2083 free( path );
2084 path = pop_dir( dirstack, &len );
2085 if (!(glob = build_glob( root[0], path, len )))
2087 status = FILL_STATUS_FAILED;
2088 goto done;
2090 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
2094 if (!resize_table( table, row + 1, sizeof(*rec) ))
2096 status = FILL_STATUS_FAILED;
2097 FindClose( handle );
2098 goto done;
2100 if (!wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." )) continue;
2102 if (!(new_path = append_path( path, data.cFileName, &len )))
2104 status = FILL_STATUS_FAILED;
2105 FindClose( handle );
2106 goto done;
2109 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2111 if (push_dir( dirstack, new_path, len )) continue;
2112 free( new_path );
2113 FindClose( handle );
2114 status = FILL_STATUS_FAILED;
2115 goto done;
2117 rec = (struct record_datafile *)(table->data + offset);
2118 rec->name = build_name( root[0], new_path );
2119 rec->version = get_file_version( rec->name );
2120 free( new_path );
2121 if (!match_row( table, row, cond, &status ))
2123 free_row_values( table, row );
2124 continue;
2126 else if (num_expected_rows && row == num_expected_rows - 1)
2128 row++;
2129 FindClose( handle );
2130 status = FILL_STATUS_FILTERED;
2131 goto done;
2133 offset += sizeof(*rec);
2134 row++;
2136 while (FindNextFileW( handle, &data ));
2137 FindClose( handle );
2139 if (!peek_dir( dirstack )) break;
2143 done:
2144 free_dirstack( dirstack );
2145 free( glob );
2146 free( path );
2148 TRACE("created %u rows\n", row);
2149 table->num_rows = row;
2150 return status;
2153 static UINT32 get_pixelsperxlogicalinch(void)
2155 HDC hdc = GetDC( NULL );
2156 UINT32 ret;
2158 if (!hdc) return 96;
2159 ret = GetDeviceCaps( hdc, LOGPIXELSX );
2160 ReleaseDC( NULL, hdc );
2161 return ret;
2164 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
2166 struct record_desktopmonitor *rec;
2167 enum fill_status status = FILL_STATUS_UNFILTERED;
2168 UINT row = 0;
2170 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2172 rec = (struct record_desktopmonitor *)table->data;
2173 rec->name = L"Generic Non-PnP Monitor";
2174 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
2176 if (match_row( table, row, cond, &status )) row++;
2178 TRACE("created %u rows\n", row);
2179 table->num_rows = row;
2180 return status;
2183 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
2185 struct record_directory *rec;
2186 UINT i, len, row = 0, offset = 0, num_expected_rows;
2187 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
2188 DWORD drives = GetLogicalDrives();
2189 WIN32_FIND_DATAW data;
2190 HANDLE handle;
2191 struct dirstack *dirstack;
2192 enum fill_status status = FILL_STATUS_UNFILTERED;
2194 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2196 dirstack = alloc_dirstack(2);
2198 for (i = 0; i < 26; i++)
2200 if (!(drives & (1 << i))) continue;
2202 root[0] = 'A' + i;
2203 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
2205 num_expected_rows = 0;
2206 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
2208 for (;;)
2210 free( glob );
2211 free( path );
2212 path = pop_dir( dirstack, &len );
2213 if (!(glob = build_glob( root[0], path, len )))
2215 status = FILL_STATUS_FAILED;
2216 goto done;
2218 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
2222 if (!resize_table( table, row + 1, sizeof(*rec) ))
2224 FindClose( handle );
2225 status = FILL_STATUS_FAILED;
2226 goto done;
2228 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
2229 !wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." ))
2230 continue;
2232 if (!(new_path = append_path( path, data.cFileName, &len )))
2234 FindClose( handle );
2235 status = FILL_STATUS_FAILED;
2236 goto done;
2239 if (!(push_dir( dirstack, new_path, len )))
2241 free( new_path );
2242 FindClose( handle );
2243 status = FILL_STATUS_FAILED;
2244 goto done;
2246 rec = (struct record_directory *)(table->data + offset);
2247 rec->accessmask = FILE_ALL_ACCESS;
2248 rec->name = build_name( root[0], new_path );
2249 free( new_path );
2250 if (!match_row( table, row, cond, &status ))
2252 free_row_values( table, row );
2253 continue;
2255 else if (num_expected_rows && row == num_expected_rows - 1)
2257 row++;
2258 FindClose( handle );
2259 status = FILL_STATUS_FILTERED;
2260 goto done;
2262 offset += sizeof(*rec);
2263 row++;
2265 while (FindNextFileW( handle, &data ));
2266 FindClose( handle );
2268 if (!peek_dir( dirstack )) break;
2272 done:
2273 free_dirstack( dirstack );
2274 free( glob );
2275 free( path );
2277 TRACE("created %u rows\n", row);
2278 table->num_rows = row;
2279 return status;
2282 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
2284 WCHAR root[] = L"\\\\.\\A:";
2285 ULARGE_INTEGER free;
2286 DISK_GEOMETRY_EX info;
2287 HANDLE handle;
2288 DWORD bytes_returned;
2290 free.QuadPart = 512 * 1024 * 1024;
2291 GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
2293 root[4] = dir[0];
2294 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2295 if (handle != INVALID_HANDLE_VALUE)
2297 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
2298 *disksize = info.DiskSize.QuadPart;
2299 CloseHandle( handle );
2301 return free.QuadPart;
2303 static WCHAR *get_diskdrive_serialnumber( WCHAR letter )
2305 WCHAR *ret = NULL;
2306 STORAGE_DEVICE_DESCRIPTOR *desc;
2307 HANDLE handle = INVALID_HANDLE_VALUE;
2308 STORAGE_PROPERTY_QUERY query = {0};
2309 WCHAR drive[7];
2310 DWORD size;
2312 swprintf( drive, ARRAY_SIZE(drive), L"\\\\.\\%c:", letter );
2313 handle = CreateFileW( drive, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2314 if (handle == INVALID_HANDLE_VALUE) goto done;
2316 query.PropertyId = StorageDeviceProperty;
2317 query.QueryType = PropertyStandardQuery;
2319 size = sizeof(*desc) + 256;
2320 for (;;)
2322 if (!(desc = malloc( size ))) break;
2323 if (DeviceIoControl( handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), desc, size, NULL, NULL ))
2325 if (desc->SerialNumberOffset) ret = heap_strdupAW( (const char *)desc + desc->SerialNumberOffset );
2326 free( desc );
2327 break;
2329 size = desc->Size;
2330 free( desc );
2331 if (GetLastError() != ERROR_MORE_DATA) break;
2334 done:
2335 if (handle != INVALID_HANDLE_VALUE) CloseHandle( handle );
2336 if (!ret) ret = wcsdup( L"WINEHDISK" );
2337 return ret;
2340 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
2342 static const WCHAR fmtW[] = L"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2343 WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = L"A:\\";
2344 struct record_diskdrive *rec;
2345 UINT i, row = 0, offset = 0, index = 0, type;
2346 UINT64 size = 1024 * 1024 * 1024;
2347 DWORD drives = GetLogicalDrives();
2348 enum fill_status status = FILL_STATUS_UNFILTERED;
2350 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
2352 for (i = 0; i < 26; i++)
2354 if (drives & (1 << i))
2356 root[0] = 'A' + i;
2357 type = GetDriveTypeW( root );
2358 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2359 continue;
2361 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2363 rec = (struct record_diskdrive *)(table->data + offset);
2364 swprintf( device_id, ARRAY_SIZE( device_id ), fmtW, index );
2365 rec->device_id = wcsdup( device_id );
2366 rec->index = index++;
2367 rec->interfacetype = L"IDE";
2368 rec->manufacturer = L"(Standard disk drives)";
2369 rec->mediatype = (type == DRIVE_FIXED) ? L"Fixed hard disk" : L"Removable media";
2370 rec->model = L"Wine Disk Drive";
2371 rec->pnpdevice_id = L"IDE\\Disk\\VEN_WINE";
2372 rec->serialnumber = get_diskdrive_serialnumber( root[0] );
2373 get_freespace( root, &size );
2374 rec->size = size;
2375 if (!match_row( table, row, cond, &status ))
2377 free_row_values( table, row );
2378 continue;
2380 offset += sizeof(*rec);
2381 row++;
2384 TRACE("created %u rows\n", row);
2385 table->num_rows = row;
2386 return status;
2389 struct association
2391 WCHAR *ref;
2392 WCHAR *ref2;
2395 static void free_associations( struct association *assoc, UINT count )
2397 UINT i;
2398 if (!assoc) return;
2399 for (i = 0; i < count; i++)
2401 free( assoc[i].ref );
2402 free( assoc[i].ref2 );
2404 free( assoc );
2407 static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
2409 struct association *ret = NULL;
2410 struct query *query, *query2 = NULL;
2411 VARIANT val;
2412 HRESULT hr;
2413 UINT i;
2415 if (!(query = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return NULL;
2416 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2, L"SELECT * FROM Win32_DiskDrive",
2417 &query->view, &query->mem )) != S_OK) goto done;
2418 if ((hr = execute_view( query->view )) != S_OK) goto done;
2420 if (!(query2 = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return FALSE;
2421 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2, L"SELECT * FROM Win32_DiskPartition",
2422 &query2->view, &query2->mem )) != S_OK) goto done;
2423 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2425 if (!(ret = calloc( query->view->result_count, sizeof(*ret) ))) goto done;
2427 for (i = 0; i < query->view->result_count; i++)
2429 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2430 if (!(ret[i].ref = wcsdup( V_BSTR(&val) ))) goto done;
2431 VariantClear( &val );
2433 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2434 if (!(ret[i].ref2 = wcsdup( V_BSTR(&val) ))) goto done;
2435 VariantClear( &val );
2438 *count = query->view->result_count;
2440 done:
2441 if (!ret) free_associations( ret, query->view->result_count );
2442 free_query( query );
2443 free_query( query2 );
2444 return ret;
2447 static enum fill_status fill_diskdrivetodiskpartition( struct table *table, const struct expr *cond )
2449 struct record_diskdrivetodiskpartition *rec;
2450 UINT i, row = 0, offset = 0, count = 0;
2451 enum fill_status status = FILL_STATUS_UNFILTERED;
2452 struct association *assoc;
2454 if (!(assoc = get_diskdrivetodiskpartition_pairs( &count ))) return FILL_STATUS_FAILED;
2455 if (!count)
2457 free_associations( assoc, count );
2458 return FILL_STATUS_UNFILTERED;
2460 if (!resize_table( table, count, sizeof(*rec) ))
2462 free_associations( assoc, count );
2463 return FILL_STATUS_FAILED;
2466 for (i = 0; i < count; i++)
2468 rec = (struct record_diskdrivetodiskpartition *)(table->data + offset);
2469 rec->antecedent = assoc[i].ref;
2470 rec->dependent = assoc[i].ref2;
2471 if (!match_row( table, row, cond, &status ))
2473 free_row_values( table, row );
2474 continue;
2476 offset += sizeof(*rec);
2477 row++;
2480 free( assoc );
2482 TRACE("created %u rows\n", row);
2483 table->num_rows = row;
2484 return status;
2487 static WCHAR *get_filesystem( const WCHAR *root )
2489 WCHAR buffer[MAX_PATH + 1];
2491 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
2492 return wcsdup( buffer );
2493 return wcsdup( L"NTFS" );
2496 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2498 WCHAR device_id[32], root[] = L"A:\\";
2499 struct record_diskpartition *rec;
2500 UINT i, row = 0, offset = 0, type, index = 0;
2501 UINT64 size = 1024 * 1024 * 1024;
2502 DWORD drives = GetLogicalDrives();
2503 enum fill_status status = FILL_STATUS_UNFILTERED;
2505 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2507 for (i = 0; i < 26; i++)
2509 if (drives & (1 << i))
2511 root[0] = 'A' + i;
2512 type = GetDriveTypeW( root );
2513 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2514 continue;
2516 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2518 rec = (struct record_diskpartition *)(table->data + offset);
2519 rec->bootable = (i == 2) ? -1 : 0;
2520 rec->bootpartition = (i == 2) ? -1 : 0;
2521 swprintf( device_id, ARRAY_SIZE( device_id ), L"Disk #%u, Partition #0", index );
2522 rec->device_id = wcsdup( device_id );
2523 rec->diskindex = index++;
2524 rec->index = 0;
2525 rec->pnpdevice_id = wcsdup( device_id );
2526 get_freespace( root, &size );
2527 rec->size = size;
2528 rec->startingoffset = 0;
2529 rec->type = get_filesystem( root );
2530 if (!match_row( table, row, cond, &status ))
2532 free_row_values( table, row );
2533 continue;
2535 offset += sizeof(*rec);
2536 row++;
2539 TRACE("created %u rows\n", row);
2540 table->num_rows = row;
2541 return status;
2544 static UINT32 get_bitsperpixel( UINT *hres, UINT *vres )
2546 HDC hdc = GetDC( NULL );
2547 UINT32 ret;
2549 if (!hdc) return 32;
2550 ret = GetDeviceCaps( hdc, BITSPIXEL );
2551 *hres = GetDeviceCaps( hdc, HORZRES );
2552 *vres = GetDeviceCaps( hdc, VERTRES );
2553 ReleaseDC( NULL, hdc );
2554 return ret;
2557 static enum fill_status fill_displaycontrollerconfig( struct table *table, const struct expr *cond )
2559 struct record_displaycontrollerconfig *rec;
2560 UINT row = 0, hres = 1024, vres = 768;
2561 enum fill_status status = FILL_STATUS_UNFILTERED;
2563 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2565 rec = (struct record_displaycontrollerconfig *)table->data;
2566 rec->bitsperpixel = get_bitsperpixel( &hres, &vres );
2567 rec->caption = L"VideoController1";
2568 rec->horizontalresolution = hres;
2569 rec->name = L"VideoController1";
2570 rec->verticalresolution = vres;
2571 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2572 else row++;
2574 TRACE("created %u rows\n", row);
2575 table->num_rows = row;
2576 return status;
2579 static WCHAR *get_ip4_string( DWORD addr )
2581 DWORD len = sizeof("ddd.ddd.ddd.ddd");
2582 WCHAR *ret;
2584 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
2585 swprintf( ret, len, L"%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2586 return ret;
2589 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2591 struct record_ip4routetable *rec;
2592 UINT i, row = 0, offset = 0;
2593 ULONG size = 0;
2594 MIB_IPFORWARDTABLE *forwards;
2595 enum fill_status status = FILL_STATUS_UNFILTERED;
2597 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2598 if (!(forwards = malloc( size ))) return FILL_STATUS_FAILED;
2599 if (GetIpForwardTable( forwards, &size, TRUE ))
2601 free( forwards );
2602 return FILL_STATUS_FAILED;
2604 if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) ))
2606 free( forwards );
2607 return FILL_STATUS_FAILED;
2610 for (i = 0; i < forwards->dwNumEntries; i++)
2612 rec = (struct record_ip4routetable *)(table->data + offset);
2614 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2615 rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2616 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2618 if (!match_row( table, row, cond, &status ))
2620 free_row_values( table, row );
2621 continue;
2623 offset += sizeof(*rec);
2624 row++;
2626 TRACE("created %u rows\n", row);
2627 table->num_rows = row;
2629 free( forwards );
2630 return status;
2633 static WCHAR *get_volumename( const WCHAR *root )
2635 WCHAR buf[MAX_PATH + 1] = {0};
2636 GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 );
2637 return wcsdup( buf );
2639 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2641 DWORD serial = 0;
2642 WCHAR buffer[9];
2644 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2645 swprintf( buffer, ARRAY_SIZE( buffer ), L"%08X", serial );
2646 return wcsdup( buffer );
2649 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2651 WCHAR device_id[3], root[] = L"A:\\";
2652 struct record_logicaldisk *rec;
2653 UINT i, row = 0, offset = 0, type;
2654 UINT64 size = 1024 * 1024 * 1024;
2655 DWORD drives = GetLogicalDrives();
2656 enum fill_status status = FILL_STATUS_UNFILTERED;
2658 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2660 for (i = 0; i < 26; i++)
2662 if (drives & (1 << i))
2664 root[0] = 'A' + i;
2665 type = GetDriveTypeW( root );
2666 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2667 continue;
2669 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2671 rec = (struct record_logicaldisk *)(table->data + offset);
2672 swprintf( device_id, ARRAY_SIZE( device_id ), L"%c:", 'A' + i );
2673 rec->caption = wcsdup( device_id );
2674 rec->device_id = wcsdup( device_id );
2675 rec->drivetype = type;
2676 rec->filesystem = get_filesystem( root );
2677 rec->freespace = get_freespace( root, &size );
2678 rec->name = wcsdup( device_id );
2679 rec->size = size;
2680 rec->volumename = get_volumename( root );
2681 rec->volumeserialnumber = get_volumeserialnumber( root );
2682 if (!match_row( table, row, cond, &status ))
2684 free_row_values( table, row );
2685 continue;
2687 offset += sizeof(*rec);
2688 row++;
2691 TRACE("created %u rows\n", row);
2692 table->num_rows = row;
2693 return status;
2696 static struct association *get_logicaldisktopartition_pairs( UINT *count )
2698 struct association *ret = NULL;
2699 struct query *query, *query2 = NULL;
2700 VARIANT val;
2701 HRESULT hr;
2702 UINT i;
2704 if (!(query = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return NULL;
2705 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2, L"SELECT * FROM Win32_DiskPartition",
2706 &query->view, &query->mem )) != S_OK) goto done;
2707 if ((hr = execute_view( query->view )) != S_OK) goto done;
2709 if (!(query2 = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return FALSE;
2710 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2,
2711 L"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2->view,
2712 &query2->mem )) != S_OK) goto done;
2713 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2715 if (!(ret = calloc( query->view->result_count, sizeof(*ret) ))) goto done;
2717 /* assume fixed and removable disks are enumerated in the same order as partitions */
2718 for (i = 0; i < query->view->result_count; i++)
2720 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2721 if (!(ret[i].ref = wcsdup( V_BSTR(&val) ))) goto done;
2722 VariantClear( &val );
2724 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2725 if (!(ret[i].ref2 = wcsdup( V_BSTR(&val) ))) goto done;
2726 VariantClear( &val );
2729 *count = query->view->result_count;
2731 done:
2732 if (!ret) free_associations( ret, query->view->result_count );
2733 free_query( query );
2734 free_query( query2 );
2735 return ret;
2738 static enum fill_status fill_logicaldisktopartition( struct table *table, const struct expr *cond )
2740 struct record_logicaldisktopartition *rec;
2741 UINT i, row = 0, offset = 0, count = 0;
2742 enum fill_status status = FILL_STATUS_UNFILTERED;
2743 struct association *assoc;
2745 if (!(assoc = get_logicaldisktopartition_pairs( &count ))) return FILL_STATUS_FAILED;
2746 if (!count)
2748 free_associations( assoc, count );
2749 return FILL_STATUS_UNFILTERED;
2751 if (!resize_table( table, count, sizeof(*rec) ))
2753 free_associations( assoc, count );
2754 return FILL_STATUS_FAILED;
2757 for (i = 0; i < count; i++)
2759 rec = (struct record_logicaldisktopartition *)(table->data + offset);
2760 rec->antecedent = assoc[i].ref;
2761 rec->dependent = assoc[i].ref2;
2762 if (!match_row( table, row, cond, &status ))
2764 free_row_values( table, row );
2765 continue;
2767 offset += sizeof(*rec);
2768 row++;
2771 free( assoc );
2773 TRACE("created %u rows\n", row);
2774 table->num_rows = row;
2775 return status;
2778 static UINT16 get_connection_status( IF_OPER_STATUS status )
2780 switch (status)
2782 case IfOperStatusDown:
2783 return 0; /* Disconnected */
2784 case IfOperStatusUp:
2785 return 2; /* Connected */
2786 default:
2787 ERR("unhandled status %u\n", status);
2788 break;
2790 return 0;
2792 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2794 WCHAR *ret;
2795 if (len != 6 || !(ret = malloc( 18 * sizeof(WCHAR) ))) return NULL;
2796 swprintf( ret, 18, L"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2797 return ret;
2799 static const WCHAR *get_adaptertype( DWORD type, int *id, int *physical )
2801 switch (type)
2803 case IF_TYPE_ETHERNET_CSMACD:
2804 *id = 0;
2805 *physical = -1;
2806 return L"Ethernet 802.3";
2808 case IF_TYPE_IEEE80211:
2809 *id = 9;
2810 *physical = -1;
2811 return L"Wireless";
2813 case IF_TYPE_IEEE1394:
2814 *id = 13;
2815 *physical = -1;
2816 return L"1394";
2818 case IF_TYPE_TUNNEL:
2819 *id = 15;
2820 *physical = 0;
2821 return L"Tunnel";
2823 default:
2824 *id = -1;
2825 *physical = 0;
2826 return NULL;
2830 #define GUID_SIZE 39
2831 static WCHAR *guid_to_str( const GUID *ptr )
2833 WCHAR *ret;
2834 if (!(ret = malloc( GUID_SIZE * sizeof(WCHAR) ))) return NULL;
2835 swprintf( ret, GUID_SIZE, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2836 ptr->Data1, ptr->Data2, ptr->Data3, ptr->Data4[0], ptr->Data4[1], ptr->Data4[2],
2837 ptr->Data4[3], ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] );
2838 return ret;
2841 static WCHAR *get_networkadapter_guid( const IF_LUID *luid )
2843 GUID guid;
2844 if (ConvertInterfaceLuidToGuid( luid, &guid )) return NULL;
2845 return guid_to_str( &guid );
2848 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2850 WCHAR device_id[11];
2851 struct record_networkadapter *rec;
2852 IP_ADAPTER_ADDRESSES *aa, *buffer;
2853 UINT row = 0, offset = 0, count = 0;
2854 DWORD size = 0, ret;
2855 int adaptertypeid, physical;
2856 enum fill_status status = FILL_STATUS_UNFILTERED;
2858 ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
2859 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2861 if (!(buffer = malloc( size ))) return FILL_STATUS_FAILED;
2862 if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size ))
2864 free( buffer );
2865 return FILL_STATUS_FAILED;
2867 for (aa = buffer; aa; aa = aa->Next)
2869 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2871 if (!resize_table( table, count, sizeof(*rec) ))
2873 free( buffer );
2874 return FILL_STATUS_FAILED;
2876 for (aa = buffer; aa; aa = aa->Next)
2878 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2880 rec = (struct record_networkadapter *)(table->data + offset);
2881 swprintf( device_id, ARRAY_SIZE( device_id ), L"%u", aa->u.s.IfIndex );
2882 rec->adaptertype = get_adaptertype( aa->IfType, &adaptertypeid, &physical );
2883 rec->adaptertypeid = adaptertypeid;
2884 rec->description = wcsdup( aa->Description );
2885 rec->device_id = wcsdup( device_id );
2886 rec->guid = get_networkadapter_guid( &aa->Luid );
2887 rec->index = aa->u.s.IfIndex;
2888 rec->interface_index = aa->u.s.IfIndex;
2889 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2890 rec->manufacturer = L"The Wine Project";
2891 rec->name = wcsdup( aa->FriendlyName );
2892 rec->netconnection_status = get_connection_status( aa->OperStatus );
2893 rec->physicaladapter = physical;
2894 rec->pnpdevice_id = L"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2895 rec->servicename = wcsdup( aa->FriendlyName );
2896 rec->speed = 1000000;
2897 if (!match_row( table, row, cond, &status ))
2899 free_row_values( table, row );
2900 continue;
2902 offset += sizeof(*rec);
2903 row++;
2905 TRACE("created %u rows\n", row);
2906 table->num_rows = row;
2908 free( buffer );
2909 return status;
2912 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2914 const SOCKET_ADDRESS *sa = &addr->Address;
2915 WCHAR buf[NI_MAXHOST];
2917 if (!addr) return NULL;
2918 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL,
2919 0, NI_NAMEREQD )) return NULL;
2920 return wcsdup( buf );
2922 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2924 IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2925 struct array *ret;
2926 ULONG buflen, i = 0, count = 0;
2927 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2929 if (!list) return NULL;
2930 for (gateway = list; gateway; gateway = gateway->Next) count++;
2932 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
2933 if (!(ptr = malloc( sizeof(*ptr) * count )))
2935 free( ret );
2936 return NULL;
2938 for (gateway = list; gateway; gateway = gateway->Next)
2940 buflen = ARRAY_SIZE( buf );
2941 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2942 NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf )))
2944 for (; i > 0; i--) free( ptr[i - 1] );
2945 free( ptr );
2946 free( ret );
2947 return NULL;
2950 ret->elem_size = sizeof(*ptr);
2951 ret->count = count;
2952 ret->ptr = ptr;
2953 return ret;
2955 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2957 IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2958 struct array *ret;
2959 ULONG buflen, i = 0, count = 0;
2960 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2962 if (!list) return NULL;
2963 for (server = list; server; server = server->Next) count++;
2965 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
2966 if (!(ptr = malloc( sizeof(*ptr) * count )))
2968 free( ret );
2969 return NULL;
2971 for (server = list; server; server = server->Next)
2973 buflen = ARRAY_SIZE( buf );
2974 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2975 NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf )))
2977 for (; i > 0; i--) free( ptr[i - 1] );
2978 free( ptr );
2979 free( ret );
2980 return NULL;
2982 if ((p = wcsrchr( ptr[i - 1], ':' ))) *p = 0;
2984 ret->elem_size = sizeof(*ptr);
2985 ret->count = count;
2986 ret->ptr = ptr;
2987 return ret;
2989 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2991 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2992 struct array *ret;
2993 ULONG buflen, i = 0, count = 0;
2994 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2996 if (!list) return NULL;
2997 for (address = list; address; address = address->Next) count++;
2999 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
3000 if (!(ptr = malloc( sizeof(*ptr) * count )))
3002 free( ret );
3003 return NULL;
3005 for (address = list; address; address = address->Next)
3007 buflen = ARRAY_SIZE( buf );
3008 if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength,
3009 NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf )))
3011 for (; i > 0; i--) free( ptr[i - 1] );
3012 free( ptr );
3013 free( ret );
3014 return NULL;
3017 ret->elem_size = sizeof(*ptr);
3018 ret->count = count;
3019 ret->ptr = ptr;
3020 return ret;
3022 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
3024 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
3025 struct array *ret;
3026 ULONG i = 0, count = 0;
3027 WCHAR **ptr;
3029 if (!list) return NULL;
3030 for (address = list; address; address = address->Next) count++;
3032 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
3033 if (!(ptr = malloc( sizeof(*ptr) * count )))
3035 free( ret );
3036 return NULL;
3038 for (address = list; address; address = address->Next)
3040 if (address->Address.lpSockaddr->sa_family == AF_INET)
3042 WCHAR buf[INET_ADDRSTRLEN];
3043 SOCKADDR_IN addr;
3044 ULONG buflen = ARRAY_SIZE( buf );
3046 memset( &addr, 0, sizeof(addr) );
3047 addr.sin_family = AF_INET;
3048 if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
3049 || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
3050 ptr[i] = NULL;
3051 else
3052 ptr[i] = wcsdup( buf );
3054 else
3056 WCHAR buf[11];
3057 swprintf( buf, ARRAY_SIZE( buf ), L"%u", address->OnLinkPrefixLength );
3058 ptr[i] = wcsdup( buf );
3060 if (!ptr[i++])
3062 for (; i > 0; i--) free( ptr[i - 1] );
3063 free( ptr );
3064 free( ret );
3065 return NULL;
3068 ret->elem_size = sizeof(*ptr);
3069 ret->count = count;
3070 ret->ptr = ptr;
3071 return ret;
3073 static WCHAR *get_settingid( UINT32 index )
3075 GUID guid;
3076 memset( &guid, 0, sizeof(guid) );
3077 guid.Data1 = index;
3078 return guid_to_str( &guid );
3081 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
3083 struct record_networkadapterconfig *rec;
3084 IP_ADAPTER_ADDRESSES *aa, *buffer;
3085 UINT row = 0, offset = 0, count = 0;
3086 DWORD size = 0, ret;
3087 enum fill_status status = FILL_STATUS_UNFILTERED;
3089 ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS, NULL, NULL, &size );
3090 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
3092 if (!(buffer = malloc( size ))) return FILL_STATUS_FAILED;
3093 if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS, NULL, buffer, &size ))
3095 free( buffer );
3096 return FILL_STATUS_FAILED;
3098 for (aa = buffer; aa; aa = aa->Next)
3100 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
3102 if (!resize_table( table, count, sizeof(*rec) ))
3104 free( buffer );
3105 return FILL_STATUS_FAILED;
3107 for (aa = buffer; aa; aa = aa->Next)
3109 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
3111 rec = (struct record_networkadapterconfig *)(table->data + offset);
3112 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress );
3113 rec->description = wcsdup( aa->Description );
3114 rec->dhcpenabled = -1;
3115 rec->dnsdomain = L"";
3116 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress );
3117 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress );
3118 rec->index = aa->u.s.IfIndex;
3119 rec->ipaddress = get_ipaddress( aa->FirstUnicastAddress );
3120 rec->ipconnectionmetric = 20;
3121 rec->ipenabled = -1;
3122 rec->ipsubnet = get_ipsubnet( aa->FirstUnicastAddress );
3123 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
3124 rec->settingid = get_settingid( rec->index );
3125 if (!match_row( table, row, cond, &status ))
3127 free_row_values( table, row );
3128 continue;
3130 offset += sizeof(*rec);
3131 row++;
3133 TRACE("created %u rows\n", row);
3134 table->num_rows = row;
3136 free( buffer );
3137 return status;
3140 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
3142 struct record_physicalmemory *rec;
3143 enum fill_status status = FILL_STATUS_UNFILTERED;
3144 UINT row = 0;
3146 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3148 rec = (struct record_physicalmemory *)table->data;
3149 rec->banklabel = L"BANK 0";
3150 rec->capacity = get_total_physical_memory();
3151 rec->caption = L"Physical Memory";
3152 rec->configuredclockspeed = 1600;
3153 rec->devicelocator = L"DIMM 0";
3154 rec->formfactor = 8; /* DIMM */
3155 rec->memorytype = 9; /* RAM */
3156 rec->partnumber = L"";
3157 rec->serial = L"";
3158 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3159 else row++;
3161 TRACE("created %u rows\n", row);
3162 table->num_rows = row;
3163 return status;
3166 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond )
3168 struct record_pnpentity *rec;
3169 enum fill_status status = FILL_STATUS_UNFILTERED;
3170 HDEVINFO device_info_set;
3171 SP_DEVINFO_DATA devinfo = {0};
3172 DWORD idx;
3174 device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT );
3176 devinfo.cbSize = sizeof(devinfo);
3178 idx = 0;
3179 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
3181 /* noop */
3184 resize_table( table, idx, sizeof(*rec) );
3185 table->num_rows = 0;
3186 rec = (struct record_pnpentity *)table->data;
3188 idx = 0;
3189 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
3191 WCHAR device_id[MAX_PATH];
3192 if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
3193 ARRAY_SIZE(device_id), NULL ))
3195 rec->device_id = wcsdup( device_id );
3196 rec->manufacturer = L"The Wine Project";
3197 rec->name = L"Wine PnP Device";
3199 table->num_rows++;
3200 if (!match_row( table, table->num_rows - 1, cond, &status ))
3202 free_row_values( table, table->num_rows - 1 );
3203 table->num_rows--;
3205 else
3206 rec++;
3210 SetupDiDestroyDeviceInfoList( device_info_set );
3212 return status;
3215 static enum fill_status fill_printer( struct table *table, const struct expr *cond )
3217 struct record_printer *rec;
3218 enum fill_status status = FILL_STATUS_UNFILTERED;
3219 PRINTER_INFO_2W *info;
3220 DWORD i, offset = 0, count = 0, size = 0;
3221 UINT num_rows = 0;
3222 WCHAR id[20];
3224 EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
3225 if (!count) return FILL_STATUS_UNFILTERED;
3227 if (!(info = malloc( size ))) return FILL_STATUS_FAILED;
3228 if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
3230 free( info );
3231 return FILL_STATUS_FAILED;
3233 if (!resize_table( table, count, sizeof(*rec) ))
3235 free( info );
3236 return FILL_STATUS_FAILED;
3239 for (i = 0; i < count; i++)
3241 rec = (struct record_printer *)(table->data + offset);
3242 rec->attributes = info[i].Attributes;
3243 swprintf( id, ARRAY_SIZE( id ), L"Printer%u", i );
3244 rec->device_id = wcsdup( id );
3245 rec->drivername = wcsdup( info[i].pDriverName );
3246 rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality;
3247 rec->local = -1;
3248 rec->location = wcsdup( info[i].pLocation );
3249 rec->name = wcsdup( info[i].pPrinterName );
3250 rec->network = 0;
3251 rec->portname = wcsdup( info[i].pPortName );
3252 if (!match_row( table, i, cond, &status ))
3254 free_row_values( table, i );
3255 continue;
3257 offset += sizeof(*rec);
3258 num_rows++;
3260 TRACE("created %u rows\n", num_rows);
3261 table->num_rows = num_rows;
3263 free( info );
3264 return status;
3267 static WCHAR *get_cmdline( DWORD process_id )
3269 if (process_id == GetCurrentProcessId()) return wcsdup( GetCommandLineW() );
3270 return NULL; /* FIXME handle different process case */
3273 static enum fill_status fill_process( struct table *table, const struct expr *cond )
3275 WCHAR handle[11];
3276 struct record_process *rec;
3277 PROCESSENTRY32W entry;
3278 HANDLE snap;
3279 enum fill_status status = FILL_STATUS_FAILED;
3280 UINT row = 0, offset = 0;
3282 snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
3283 if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
3285 entry.dwSize = sizeof(entry);
3286 if (!Process32FirstW( snap, &entry )) goto done;
3287 if (!resize_table( table, 8, sizeof(*rec) )) goto done;
3291 if (!resize_table( table, row + 1, sizeof(*rec) ))
3293 status = FILL_STATUS_FAILED;
3294 goto done;
3297 rec = (struct record_process *)(table->data + offset);
3298 rec->caption = wcsdup( entry.szExeFile );
3299 rec->commandline = get_cmdline( entry.th32ProcessID );
3300 rec->description = wcsdup( entry.szExeFile );
3301 swprintf( handle, ARRAY_SIZE( handle ), L"%u", entry.th32ProcessID );
3302 rec->handle = wcsdup( handle );
3303 rec->name = wcsdup( entry.szExeFile );
3304 rec->process_id = entry.th32ProcessID;
3305 rec->pprocess_id = entry.th32ParentProcessID;
3306 rec->thread_count = entry.cntThreads;
3307 rec->workingsetsize = 0;
3308 /* methods */
3309 rec->create = process_create;
3310 rec->get_owner = process_get_owner;
3311 if (!match_row( table, row, cond, &status ))
3313 free_row_values( table, row );
3314 continue;
3316 offset += sizeof(*rec);
3317 row++;
3318 } while (Process32NextW( snap, &entry ));
3320 TRACE("created %u rows\n", row);
3321 table->num_rows = row;
3323 done:
3324 CloseHandle( snap );
3325 return status;
3328 void do_cpuid( unsigned int ax, int *p )
3330 #if defined(__i386__) || defined(__x86_64__)
3331 __cpuid( p, ax );
3332 #else
3333 FIXME("\n");
3334 #endif
3337 static unsigned int get_processor_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
3339 unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
3341 model = (reg0 & (0x0f << 4)) >> 4;
3342 if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
3343 if (family)
3345 *family = family_id;
3346 if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
3348 *stepping = reg0 & 0x0f;
3349 return model;
3351 static void regs_to_str( int *regs, unsigned int len, WCHAR *buffer )
3353 unsigned int i;
3354 unsigned char *p = (unsigned char *)regs;
3356 for (i = 0; i < len; i++) { buffer[i] = *p++; }
3357 buffer[i] = 0;
3359 static void get_processor_manufacturer( WCHAR *manufacturer, UINT len )
3361 int tmp, regs[4] = {0, 0, 0, 0};
3363 do_cpuid( 0, regs );
3364 tmp = regs[2]; /* swap edx and ecx */
3365 regs[2] = regs[3];
3366 regs[3] = tmp;
3368 regs_to_str( regs + 1, min( 12, len ), manufacturer );
3370 static const WCHAR *get_osarchitecture(void)
3372 SYSTEM_INFO info;
3373 GetNativeSystemInfo( &info );
3374 if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return L"64-bit";
3375 return L"32-bit";
3377 static void get_processor_caption( WCHAR *caption, UINT len )
3379 const WCHAR *arch;
3380 WCHAR manufacturer[13];
3381 int regs[4] = {0, 0, 0, 0};
3382 unsigned int family, model, stepping;
3384 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3385 if (!wcscmp( get_osarchitecture(), L"32-bit" )) arch = L"x86";
3386 else if (!wcscmp( manufacturer, L"AuthenticAMD" )) arch = L"AMD64";
3387 else arch = L"Intel64";
3389 do_cpuid( 1, regs );
3391 model = get_processor_model( regs[0], &stepping, &family );
3392 swprintf( caption, len, L"%s Family %u Model %u Stepping %u", arch, family, model, stepping );
3394 static void get_processor_version( WCHAR *version, UINT len )
3396 int regs[4] = {0, 0, 0, 0};
3397 unsigned int model, stepping;
3399 do_cpuid( 1, regs );
3401 model = get_processor_model( regs[0], &stepping, NULL );
3402 swprintf( version, len, L"Model %u Stepping %u", model, stepping );
3404 static UINT16 get_processor_revision(void)
3406 int regs[4] = {0, 0, 0, 0};
3407 do_cpuid( 1, regs );
3408 return regs[0];
3410 static void get_processor_id( WCHAR *processor_id, UINT len )
3412 int regs[4] = {0, 0, 0, 0};
3414 do_cpuid( 1, regs );
3415 swprintf( processor_id, len, L"%08X%08X", regs[3], regs[0] );
3417 static void get_processor_name( WCHAR *name )
3419 int regs[4] = {0, 0, 0, 0};
3420 int i;
3422 do_cpuid( 0x80000000, regs );
3423 if (regs[0] >= 0x80000004)
3425 do_cpuid( 0x80000002, regs );
3426 regs_to_str( regs, 16, name );
3427 do_cpuid( 0x80000003, regs );
3428 regs_to_str( regs, 16, name + 16 );
3429 do_cpuid( 0x80000004, regs );
3430 regs_to_str( regs, 16, name + 32 );
3432 for (i = lstrlenW(name) - 1; i >= 0 && name[i] == ' '; i--) name[i] = 0;
3434 static UINT get_processor_currentclockspeed( UINT index )
3436 PROCESSOR_POWER_INFORMATION *info;
3437 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3438 NTSTATUS status;
3440 if ((info = malloc( size )))
3442 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3443 if (!status) ret = info[index].CurrentMhz;
3444 free( info );
3446 return ret;
3448 static UINT get_processor_maxclockspeed( UINT index )
3450 PROCESSOR_POWER_INFORMATION *info;
3451 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3452 NTSTATUS status;
3454 if ((info = malloc( size )))
3456 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3457 if (!status) ret = info[index].MaxMhz;
3458 free( info );
3460 return ret;
3463 static enum fill_status fill_processor( struct table *table, const struct expr *cond )
3465 WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
3466 struct record_processor *rec;
3467 UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
3468 enum fill_status status = FILL_STATUS_UNFILTERED;
3470 num_logical = get_logical_processor_count( &num_physical, &num_packages );
3472 if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
3474 get_processor_caption( caption, ARRAY_SIZE( caption ) );
3475 get_processor_id( processor_id, ARRAY_SIZE( processor_id ) );
3476 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3477 get_processor_name( name );
3478 get_processor_version( version, ARRAY_SIZE( version ) );
3480 for (i = 0; i < num_packages; i++)
3482 rec = (struct record_processor *)(table->data + offset);
3483 rec->addresswidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3484 rec->architecture = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 0 : 9;
3485 rec->caption = wcsdup( caption );
3486 rec->cpu_status = 1; /* CPU Enabled */
3487 rec->currentclockspeed = get_processor_currentclockspeed( i );
3488 rec->datawidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3489 rec->description = wcsdup( caption );
3490 swprintf( device_id, ARRAY_SIZE( device_id ), L"CPU%u", i );
3491 rec->device_id = wcsdup( device_id );
3492 rec->family = 2; /* Unknown */
3493 rec->level = 15;
3494 rec->manufacturer = wcsdup( manufacturer );
3495 rec->maxclockspeed = get_processor_maxclockspeed( i );
3496 rec->name = wcsdup( name );
3497 rec->num_cores = num_physical / num_packages;
3498 rec->num_logical_processors = num_logical / num_packages;
3499 rec->processor_id = wcsdup( processor_id );
3500 rec->processortype = 3; /* central processor */
3501 rec->revision = get_processor_revision();
3502 rec->unique_id = NULL;
3503 rec->version = wcsdup( version );
3504 if (!match_row( table, i, cond, &status ))
3506 free_row_values( table, i );
3507 continue;
3509 offset += sizeof(*rec);
3510 num_rows++;
3513 TRACE("created %u rows\n", num_rows);
3514 table->num_rows = num_rows;
3515 return status;
3518 static INT16 get_currenttimezone(void)
3520 TIME_ZONE_INFORMATION info;
3521 DWORD status = GetTimeZoneInformation( &info );
3522 if (status == TIME_ZONE_ID_INVALID) return 0;
3523 if (status == TIME_ZONE_ID_DAYLIGHT) return -(info.Bias + info.DaylightBias);
3524 return -(info.Bias + info.StandardBias);
3527 static WCHAR *get_lastbootuptime(void)
3529 SYSTEM_TIMEOFDAY_INFORMATION ti;
3530 TIME_FIELDS tf;
3531 WCHAR *ret;
3533 if (!(ret = malloc( 26 * sizeof(WCHAR) ))) return NULL;
3535 NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
3536 RtlTimeToTimeFields( &ti.BootTime, &tf );
3537 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u+000", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute,
3538 tf.Second, tf.Milliseconds * 1000 );
3539 return ret;
3541 static WCHAR *get_localdatetime(void)
3543 TIME_ZONE_INFORMATION tzi;
3544 SYSTEMTIME st;
3545 WCHAR *ret;
3546 DWORD Status;
3547 LONG Bias;
3549 Status = GetTimeZoneInformation(&tzi);
3551 if(Status == TIME_ZONE_ID_INVALID) return NULL;
3552 Bias = tzi.Bias;
3553 if(Status == TIME_ZONE_ID_DAYLIGHT)
3554 Bias+= tzi.DaylightBias;
3555 else
3556 Bias+= tzi.StandardBias;
3557 if (!(ret = malloc( 26 * sizeof(WCHAR) ))) return NULL;
3559 GetLocalTime(&st);
3560 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u%+03d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
3561 st.wSecond, st.wMilliseconds * 1000, -Bias );
3562 return ret;
3564 static WCHAR *get_systemdirectory(void)
3566 void *redir;
3567 WCHAR *ret;
3569 if (!(ret = malloc( MAX_PATH * sizeof(WCHAR) ))) return NULL;
3570 Wow64DisableWow64FsRedirection( &redir );
3571 GetSystemDirectoryW( ret, MAX_PATH );
3572 Wow64RevertWow64FsRedirection( redir );
3573 return ret;
3575 static WCHAR *get_systemdrive(void)
3577 WCHAR *ret = malloc( 3 * sizeof(WCHAR) ); /* "c:" */
3578 if (ret && GetEnvironmentVariableW( L"SystemDrive", ret, 3 )) return ret;
3579 free( ret );
3580 return NULL;
3582 static WCHAR *get_codeset(void)
3584 WCHAR *ret = malloc( 11 * sizeof(WCHAR) );
3585 if (ret) swprintf( ret, 11, L"%u", GetACP() );
3586 return ret;
3588 static WCHAR *get_countrycode(void)
3590 WCHAR *ret = malloc( 6 * sizeof(WCHAR) );
3591 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 );
3592 return ret;
3594 static WCHAR *get_locale(void)
3596 WCHAR *ret = malloc( 5 * sizeof(WCHAR) );
3597 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 );
3598 return ret;
3601 static WCHAR *get_reg_str( HKEY root, const WCHAR *path, const WCHAR *value )
3603 HKEY hkey = 0;
3604 DWORD size, type;
3605 WCHAR *ret = NULL;
3607 if (!RegOpenKeyExW( root, path, 0, KEY_READ, &hkey ) &&
3608 !RegQueryValueExW( hkey, value, NULL, &type, NULL, &size ) && type == REG_SZ &&
3609 (ret = malloc( size + sizeof(WCHAR) )))
3611 size += sizeof(WCHAR);
3612 if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)ret, &size ))
3614 free( ret );
3615 ret = NULL;
3618 if (hkey) RegCloseKey( hkey );
3619 return ret;
3622 static WCHAR *get_organization(void)
3624 return get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion",
3625 L"RegisteredOrganization" );
3628 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
3630 WCHAR *ret = malloc( 11 * sizeof(WCHAR) );
3631 if (ret) swprintf( ret, 11, L"%u", ver->dwBuildNumber );
3632 return ret;
3635 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
3637 static const WCHAR windowsW[] = L"Microsoft Windows ";
3638 static const WCHAR win2000W[] = L"2000 Professional";
3639 static const WCHAR win2003W[] = L"Server 2003 Standard Edition";
3640 static const WCHAR winxpW[] = L"XP Professional";
3641 static const WCHAR winxp64W[] = L"XP Professional x64 Edition";
3642 static const WCHAR vistaW[] = L"Vista Ultimate";
3643 static const WCHAR win2008W[] = L"Server 2008 Standard";
3644 static const WCHAR win7W[] = L"7 Professional";
3645 static const WCHAR win2008r2W[] = L"Server 2008 R2 Standard";
3646 static const WCHAR win8W[] = L"8 Pro";
3647 static const WCHAR win81W[] = L"8.1 Pro";
3648 static const WCHAR win10W[] = L"10 Pro";
3649 static const WCHAR win11W[] = L"11 Pro";
3650 int len = ARRAY_SIZE( windowsW ) - 1;
3651 WCHAR *ret;
3653 if (!(ret = malloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL;
3654 memcpy( ret, windowsW, sizeof(windowsW) );
3655 if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0)
3657 if (ver->dwBuildNumber >= 22000) memcpy( ret + len, win11W, sizeof(win11W) );
3658 else memcpy( ret + len, win10W, sizeof(win10W) );
3660 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win81W, sizeof(win81W) );
3661 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win8W, sizeof(win8W) );
3662 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1)
3664 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) );
3665 else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) );
3667 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0)
3669 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) );
3670 else memcpy( ret + len, win2008W, sizeof(win2008W) );
3672 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2)
3674 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) );
3675 else memcpy( ret + len, win2003W, sizeof(win2003W) );
3677 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) );
3678 else memcpy( ret + len, win2000W, sizeof(win2000W) );
3679 return ret;
3682 static WCHAR *get_osname( const WCHAR *caption )
3684 static const WCHAR partitionW[] = L"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3685 int len = lstrlenW( caption );
3686 WCHAR *ret;
3688 if (!(ret = malloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
3689 memcpy( ret, caption, len * sizeof(WCHAR) );
3690 memcpy( ret + len, partitionW, sizeof(partitionW) );
3691 return ret;
3694 static WCHAR *get_osserialnumber(void)
3696 WCHAR *ret = get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", L"ProductId" );
3697 if (!ret) ret = wcsdup( L"12345-OEM-1234567-12345" );
3698 return ret;
3701 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
3703 WCHAR *ret = malloc( 33 * sizeof(WCHAR) );
3704 if (ret) swprintf( ret, 33, L"%u.%u.%u", ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
3705 return ret;
3708 static DWORD get_operatingsystemsku(void)
3710 DWORD ret = PRODUCT_UNDEFINED;
3711 GetProductInfo( 6, 0, 0, 0, &ret );
3712 return ret;
3715 static WCHAR *get_registereduser(void)
3717 return get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", L"RegisteredOwner" );
3720 static WCHAR *get_windowsdirectory(void)
3722 WCHAR dir[MAX_PATH];
3723 if (!GetWindowsDirectoryW( dir, ARRAY_SIZE(dir) )) return NULL;
3724 return wcsdup( dir );
3727 static enum fill_status fill_operatingsystem( struct table *table, const struct expr *cond )
3729 struct record_operatingsystem *rec;
3730 enum fill_status status = FILL_STATUS_UNFILTERED;
3731 RTL_OSVERSIONINFOEXW ver;
3732 UINT row = 0;
3734 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3736 ver.dwOSVersionInfoSize = sizeof(ver);
3737 RtlGetVersion( &ver );
3739 rec = (struct record_operatingsystem *)table->data;
3740 rec->bootdevice = L"\\Device\\HarddiskVolume1";
3741 rec->buildnumber = get_osbuildnumber( &ver );
3742 rec->buildtype = L"Wine build";
3743 rec->caption = get_oscaption( &ver );
3744 rec->codeset = get_codeset();
3745 rec->countrycode = get_countrycode();
3746 rec->csdversion = ver.szCSDVersion[0] ? wcsdup( ver.szCSDVersion ) : NULL;
3747 rec->csname = get_computername();
3748 rec->currenttimezone = get_currenttimezone();
3749 rec->freephysicalmemory = get_available_physical_memory() / 1024;
3750 rec->freevirtualmemory = get_available_virtual_memory() / 1024;
3751 rec->installdate = L"20140101000000.000000+000";
3752 rec->lastbootuptime = get_lastbootuptime();
3753 rec->localdatetime = get_localdatetime();
3754 rec->locale = get_locale();
3755 rec->manufacturer = L"The Wine Project";
3756 rec->name = get_osname( rec->caption );
3757 rec->operatingsystemsku = get_operatingsystemsku();
3758 rec->organization = get_organization();
3759 rec->osarchitecture = get_osarchitecture();
3760 rec->oslanguage = GetSystemDefaultLangID();
3761 rec->osproductsuite = 2461140; /* Windows XP Professional */
3762 rec->ostype = 18; /* WINNT */
3763 rec->primary = -1;
3764 rec->producttype = 1;
3765 rec->registereduser = get_registereduser();
3766 rec->serialnumber = get_osserialnumber();
3767 rec->servicepackmajor = ver.wServicePackMajor;
3768 rec->servicepackminor = ver.wServicePackMinor;
3769 rec->status = L"OK";
3770 rec->suitemask = 272; /* Single User + Terminal */
3771 rec->systemdirectory = get_systemdirectory();
3772 rec->systemdrive = get_systemdrive();
3773 rec->totalvirtualmemorysize = get_total_physical_memory() / 1024;
3774 rec->totalvisiblememorysize = rec->totalvirtualmemorysize;
3775 rec->version = get_osversion( &ver );
3776 rec->windowsdirectory = get_windowsdirectory();
3777 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3778 else row++;
3780 TRACE("created %u rows\n", row);
3781 table->num_rows = row;
3782 return status;
3785 static const WCHAR *get_service_type( DWORD type )
3787 if (type & SERVICE_KERNEL_DRIVER) return L"Kernel Driver";
3788 else if (type & SERVICE_FILE_SYSTEM_DRIVER) return L"File System Driver";
3789 else if (type & SERVICE_WIN32_OWN_PROCESS) return L"Own Process";
3790 else if (type & SERVICE_WIN32_SHARE_PROCESS) return L"Share Process";
3791 else ERR( "unhandled type %#lx\n", type );
3792 return NULL;
3794 static const WCHAR *get_service_state( DWORD state )
3796 switch (state)
3798 case SERVICE_STOPPED: return L"Stopped";
3799 case SERVICE_START_PENDING: return L"Start Pending";
3800 case SERVICE_STOP_PENDING: return L"Stop Pending";
3801 case SERVICE_RUNNING: return L"Running";
3802 default:
3803 ERR( "unknown state %lu\n", state );
3804 return L"Unknown";
3807 static const WCHAR *get_service_startmode( DWORD mode )
3809 switch (mode)
3811 case SERVICE_BOOT_START: return L"Boot";
3812 case SERVICE_SYSTEM_START: return L"System";
3813 case SERVICE_AUTO_START: return L"Auto";
3814 case SERVICE_DEMAND_START: return L"Manual";
3815 case SERVICE_DISABLED: return L"Disabled";
3816 default:
3817 ERR( "unknown mode %#lx\n", mode );
3818 return L"Unknown";
3821 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
3823 QUERY_SERVICE_CONFIGW *config = NULL;
3824 SC_HANDLE service;
3825 DWORD size;
3827 if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL;
3828 QueryServiceConfigW( service, NULL, 0, &size );
3829 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
3830 if (!(config = malloc( size ))) goto done;
3831 if (QueryServiceConfigW( service, config, size, &size )) goto done;
3832 free( config );
3833 config = NULL;
3835 done:
3836 CloseServiceHandle( service );
3837 return config;
3840 static enum fill_status fill_service( struct table *table, const struct expr *cond )
3842 struct record_service *rec;
3843 SC_HANDLE manager;
3844 ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL;
3845 SERVICE_STATUS_PROCESS *status;
3846 WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
3847 DWORD len = ARRAY_SIZE( sysnameW ), needed, count;
3848 UINT i, row = 0, offset = 0, size = 256;
3849 enum fill_status fill_status = FILL_STATUS_FAILED;
3850 BOOL ret;
3852 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED;
3853 if (!(services = malloc( size ))) goto done;
3855 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3856 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3857 &count, NULL, NULL );
3858 if (!ret)
3860 if (GetLastError() != ERROR_MORE_DATA) goto done;
3861 size = needed;
3862 if (!(tmp = realloc( services, size ))) goto done;
3863 services = tmp;
3864 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3865 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3866 &count, NULL, NULL );
3867 if (!ret) goto done;
3869 if (!resize_table( table, count, sizeof(*rec) )) goto done;
3871 GetComputerNameW( sysnameW, &len );
3872 fill_status = FILL_STATUS_UNFILTERED;
3874 for (i = 0; i < count; i++)
3876 QUERY_SERVICE_CONFIGW *config;
3878 if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue;
3880 status = &services[i].ServiceStatusProcess;
3881 rec = (struct record_service *)(table->data + offset);
3882 rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0;
3883 rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0;
3884 rec->displayname = wcsdup( services[i].lpDisplayName );
3885 rec->name = wcsdup( services[i].lpServiceName );
3886 rec->process_id = status->dwProcessId;
3887 rec->servicetype = get_service_type( status->dwServiceType );
3888 rec->startmode = get_service_startmode( config->dwStartType );
3889 rec->state = get_service_state( status->dwCurrentState );
3890 rec->systemname = wcsdup( sysnameW );
3891 rec->pause_service = service_pause_service;
3892 rec->resume_service = service_resume_service;
3893 rec->start_service = service_start_service;
3894 rec->stop_service = service_stop_service;
3895 free( config );
3896 if (!match_row( table, row, cond, &fill_status ))
3898 free_row_values( table, row );
3899 continue;
3901 offset += sizeof(*rec);
3902 row++;
3905 TRACE("created %u rows\n", row);
3906 table->num_rows = row;
3908 done:
3909 CloseServiceHandle( manager );
3910 free( services );
3911 return fill_status;
3914 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
3916 if (!name || !name->Name.Buffer) return NULL;
3917 return wcsdup( name->Name.Buffer );
3919 static struct array *get_binaryrepresentation( PSID sid, UINT len )
3921 struct array *ret;
3922 UINT8 *ptr;
3924 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
3925 if (!(ptr = malloc( len )))
3927 free( ret );
3928 return NULL;
3930 memcpy( ptr, sid, len );
3931 ret->elem_size = sizeof(*ptr);
3932 ret->count = len;
3933 ret->ptr = ptr;
3934 return ret;
3936 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
3938 if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL;
3939 return wcsdup( domain->Domains->Name.Buffer );
3941 static const WCHAR *find_sid_str( const struct expr *cond )
3943 const struct expr *left, *right;
3944 const WCHAR *ret = NULL;
3946 if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL;
3948 left = cond->u.expr.left;
3949 right = cond->u.expr.right;
3950 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !wcsicmp( left->u.propval->name, L"SID" ))
3952 ret = right->u.sval;
3954 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !wcsicmp( right->u.propval->name, L"SID" ))
3956 ret = left->u.sval;
3958 return ret;
3961 static enum fill_status fill_sid( struct table *table, const struct expr *cond )
3963 PSID sid;
3964 LSA_REFERENCED_DOMAIN_LIST *domain;
3965 LSA_TRANSLATED_NAME *name;
3966 LSA_HANDLE handle;
3967 LSA_OBJECT_ATTRIBUTES attrs;
3968 const WCHAR *str;
3969 struct record_sid *rec;
3970 UINT len;
3972 if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED;
3973 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3975 if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED;
3976 len = GetLengthSid( sid );
3978 memset( &attrs, 0, sizeof(attrs) );
3979 attrs.Length = sizeof(attrs);
3980 if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ))
3982 LocalFree( sid );
3983 return FILL_STATUS_FAILED;
3985 if (LsaLookupSids( handle, 1, &sid, &domain, &name ))
3987 LocalFree( sid );
3988 LsaClose( handle );
3989 return FILL_STATUS_FAILED;
3992 rec = (struct record_sid *)table->data;
3993 rec->accountname = get_accountname( name );
3994 rec->binaryrepresentation = get_binaryrepresentation( sid, len );
3995 rec->referenceddomainname = get_referenceddomainname( domain );
3996 rec->sid = wcsdup( str );
3997 rec->sidlength = len;
3999 TRACE("created 1 row\n");
4000 table->num_rows = 1;
4002 LsaFreeMemory( domain );
4003 LsaFreeMemory( name );
4004 LocalFree( sid );
4005 LsaClose( handle );
4006 return FILL_STATUS_FILTERED;
4009 static WCHAR *get_systemenclosure_string( BYTE id, const char *buf, UINT len )
4011 const struct smbios_header *hdr;
4012 const struct smbios_chassis *chassis;
4013 UINT offset;
4015 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len ))) return NULL;
4017 chassis = (const struct smbios_chassis *)hdr;
4018 offset = (const char *)chassis - buf + chassis->hdr.length;
4019 return get_smbios_string( id, buf, offset, len );
4022 static WCHAR *get_systemenclosure_manufacturer( const char *buf, UINT len )
4024 WCHAR *ret = get_systemenclosure_string( 1, buf, len );
4025 if (!ret) return wcsdup( L"Wine" );
4026 return ret;
4029 static int get_systemenclosure_lockpresent( const char *buf, UINT len )
4031 const struct smbios_header *hdr;
4032 const struct smbios_chassis *chassis;
4034 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) return 0;
4036 chassis = (const struct smbios_chassis *)hdr;
4037 return (chassis->type & 0x80) ? -1 : 0;
4040 static struct array *dup_array( const struct array *src )
4042 struct array *dst;
4043 if (!(dst = malloc( sizeof(*dst) ))) return NULL;
4044 if (!(dst->ptr = malloc( src->count * src->elem_size )))
4046 free( dst );
4047 return NULL;
4049 memcpy( dst->ptr, src->ptr, src->count * src->elem_size );
4050 dst->elem_size = src->elem_size;
4051 dst->count = src->count;
4052 return dst;
4055 static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len )
4057 const struct smbios_header *hdr;
4058 const struct smbios_chassis *chassis;
4059 struct array *ret = NULL;
4060 UINT16 *types;
4062 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) goto done;
4063 chassis = (const struct smbios_chassis *)hdr;
4065 if (!(ret = malloc( sizeof(*ret) ))) goto done;
4066 if (!(types = malloc( sizeof(*types) )))
4068 free( ret );
4069 return NULL;
4071 types[0] = chassis->type & ~0x80;
4073 ret->elem_size = sizeof(*types);
4074 ret->count = 1;
4075 ret->ptr = types;
4077 done:
4078 if (!ret) ret = dup_array( &systemenclosure_chassistypes_array );
4079 return ret;
4082 static enum fill_status fill_systemenclosure( struct table *table, const struct expr *cond )
4084 struct record_systemenclosure *rec;
4085 enum fill_status status = FILL_STATUS_UNFILTERED;
4086 UINT row = 0, len;
4087 char *buf;
4089 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4091 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
4092 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
4093 GetSystemFirmwareTable( RSMB, 0, buf, len );
4095 rec = (struct record_systemenclosure *)table->data;
4096 rec->caption = L"System Enclosure";
4097 rec->chassistypes = get_systemenclosure_chassistypes( buf, len );
4098 rec->description = L"System Enclosure";
4099 rec->lockpresent = get_systemenclosure_lockpresent( buf, len );
4100 rec->manufacturer = get_systemenclosure_manufacturer( buf, len );
4101 rec->name = L"System Enclosure";
4102 rec->tag = L"System Enclosure 0";
4103 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4104 else row++;
4106 free( buf );
4108 TRACE("created %u rows\n", row);
4109 table->num_rows = row;
4110 return status;
4113 static WCHAR *get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
4115 static const WCHAR fmtW[] = L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
4116 UINT len = sizeof(fmtW) + 2;
4117 WCHAR *ret;
4119 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
4120 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
4121 return ret;
4124 #define HW_VENDOR_AMD 0x1002
4125 #define HW_VENDOR_NVIDIA 0x10de
4126 #define HW_VENDOR_VMWARE 0x15ad
4127 #define HW_VENDOR_INTEL 0x8086
4129 static const WCHAR *get_videocontroller_installeddriver( UINT vendorid )
4131 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
4133 if (vendorid == HW_VENDOR_AMD) return L"aticfx32.dll";
4134 else if (vendorid == HW_VENDOR_NVIDIA) return L"nvd3dum.dll";
4135 else if (vendorid == HW_VENDOR_INTEL) return L"igdudim32.dll";
4136 return L"wine.dll";
4139 static BOOL get_dxgi_adapter_desc( DXGI_ADAPTER_DESC *desc )
4141 IDXGIFactory *factory;
4142 IDXGIAdapter *adapter;
4143 HRESULT hr;
4145 memset( desc, 0, sizeof(*desc) );
4146 hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
4147 if (FAILED( hr )) return FALSE;
4149 hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
4150 if (FAILED( hr ))
4152 IDXGIFactory_Release( factory );
4153 return FALSE;
4156 hr = IDXGIAdapter_GetDesc( adapter, desc );
4157 IDXGIAdapter_Release( adapter );
4158 IDXGIFactory_Release( factory );
4159 return SUCCEEDED( hr );
4162 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
4164 struct record_videocontroller *rec;
4165 DXGI_ADAPTER_DESC desc;
4166 UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
4167 const WCHAR *name = L"VideoController1";
4168 enum fill_status status = FILL_STATUS_UNFILTERED;
4169 WCHAR mode[44];
4171 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4173 if (get_dxgi_adapter_desc( &desc ))
4175 if (desc.DedicatedVideoMemory > UINT_MAX) vidmem = 0xfff00000;
4176 else vidmem = desc.DedicatedVideoMemory;
4177 name = desc.Description;
4180 rec = (struct record_videocontroller *)table->data;
4181 rec->adapter_compatibility = L"(Standard display types)";
4182 rec->adapter_dactype = L"Integrated RAMDAC";
4183 rec->adapter_ram = vidmem;
4184 rec->availability = 3; /* Running or Full Power */
4185 rec->config_errorcode = 0; /* no error */
4186 rec->caption = wcsdup( name );
4187 rec->current_bitsperpixel = get_bitsperpixel( &hres, &vres );
4188 rec->current_horizontalres = hres;
4189 rec->current_refreshrate = 0; /* default refresh rate */
4190 rec->current_scanmode = 2; /* Unknown */
4191 rec->current_verticalres = vres;
4192 rec->description = wcsdup( name );
4193 rec->device_id = L"VideoController1";
4194 rec->driverdate = L"20220118000000.000000-000";
4195 rec->driverversion = L"30.0.14023.3004";
4196 rec->installeddriver = get_videocontroller_installeddriver( desc.VendorId );
4197 rec->name = wcsdup( name );
4198 rec->pnpdevice_id = get_videocontroller_pnpdeviceid( &desc );
4199 rec->status = L"OK";
4200 rec->videoarchitecture = 2; /* Unknown */
4201 rec->videomemorytype = 2; /* Unknown */
4202 swprintf( mode, ARRAY_SIZE( mode ), L"%u x %u x %I64u colors", hres, vres, (UINT64)1 << rec->current_bitsperpixel );
4203 rec->videomodedescription = wcsdup( mode );
4204 rec->videoprocessor = wcsdup( name );
4205 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4206 else row++;
4208 TRACE("created %u rows\n", row);
4209 table->num_rows = row;
4210 return status;
4213 static WCHAR *get_volume_driveletter( const WCHAR *volume )
4215 DWORD len = 0;
4216 WCHAR *ret;
4218 if (!GetVolumePathNamesForVolumeNameW( volume, NULL, 0, &len ) && GetLastError() != ERROR_MORE_DATA) return NULL;
4219 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
4220 if (!GetVolumePathNamesForVolumeNameW( volume, ret, len, &len ) || !wcschr( ret, ':' ))
4222 free( ret );
4223 return NULL;
4225 wcschr( ret, ':' )[1] = 0;
4226 return ret;
4229 static enum fill_status fill_volume( struct table *table, const struct expr *cond )
4231 struct record_volume *rec;
4232 enum fill_status status = FILL_STATUS_UNFILTERED;
4233 UINT row = 0, offset = 0;
4234 WCHAR path[MAX_PATH];
4235 HANDLE handle;
4237 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
4239 handle = FindFirstVolumeW( path, ARRAY_SIZE(path) );
4240 while (handle != INVALID_HANDLE_VALUE)
4242 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4244 rec = (struct record_volume *)(table->data + offset);
4245 rec->deviceid = wcsdup( path );
4246 rec->driveletter = get_volume_driveletter( path );
4248 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4249 else
4251 offset += sizeof(*rec);
4252 row++;
4255 if (!FindNextVolumeW( handle, path, ARRAY_SIZE(path) ))
4257 FindVolumeClose( handle );
4258 handle = INVALID_HANDLE_VALUE;
4262 TRACE("created %u rows\n", row);
4263 table->num_rows = row;
4264 return status;
4267 static WCHAR *get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
4269 static const WCHAR fmtW[] = L"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
4270 UINT len = sizeof(fmtW) + 2;
4271 WCHAR *ret;
4273 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
4274 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
4275 return ret;
4278 static enum fill_status fill_sounddevice( struct table *table, const struct expr *cond )
4280 struct record_sounddevice *rec;
4281 DXGI_ADAPTER_DESC desc;
4282 UINT row = 0;
4283 enum fill_status status = FILL_STATUS_UNFILTERED;
4285 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4287 get_dxgi_adapter_desc( &desc );
4289 rec = (struct record_sounddevice *)table->data;
4290 rec->deviceid = get_sounddevice_pnpdeviceid( &desc );
4291 rec->manufacturer = L"The Wine Project";
4292 rec->name = L"Wine Audio Device";
4293 rec->pnpdeviceid = get_sounddevice_pnpdeviceid( &desc );
4294 rec->productname = L"Wine Audio Device";
4295 rec->status = L"OK";
4296 rec->statusinfo = 3;
4297 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4298 else row++;
4300 TRACE("created %u rows\n", row);
4301 table->num_rows = row;
4302 return status;
4305 #define C(c) sizeof(c)/sizeof(c[0]), c
4306 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
4307 static struct table cimv2_builtin_classes[] =
4309 { L"__ASSOCIATORS", C(col_associator), D(data_associator) },
4310 { L"__PARAMETERS", C(col_param), D(data_param) },
4311 { L"__QUALIFIERS", C(col_qualifier), D(data_qualifier) },
4312 { L"__SystemSecurity", C(col_systemsecurity), D(data_systemsecurity) },
4313 { L"CIM_DataFile", C(col_datafile), 0, 0, NULL, fill_datafile },
4314 { L"CIM_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
4315 { L"CIM_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4316 { L"SoftwareLicensingProduct", C(col_softwarelicensingproduct), D(data_softwarelicensingproduct) },
4317 { L"StdRegProv", C(col_stdregprov), D(data_stdregprov) },
4318 { L"SystemRestore", C(col_sysrestore), D(data_sysrestore) },
4319 { L"Win32_BIOS", C(col_bios), 0, 0, NULL, fill_bios },
4320 { L"Win32_BaseBoard", C(col_baseboard), 0, 0, NULL, fill_baseboard },
4321 { L"Win32_CDROMDrive", C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
4322 { L"Win32_ComputerSystem", C(col_compsys), 0, 0, NULL, fill_compsys },
4323 { L"Win32_ComputerSystemProduct", C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct },
4324 { L"Win32_DesktopMonitor", C(col_desktopmonitor), 0, 0, NULL, fill_desktopmonitor },
4325 { L"Win32_Directory", C(col_directory), 0, 0, NULL, fill_directory },
4326 { L"Win32_DiskDrive", C(col_diskdrive), 0, 0, NULL, fill_diskdrive },
4327 { L"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition), 0, 0, NULL, fill_diskdrivetodiskpartition },
4328 { L"Win32_DiskPartition", C(col_diskpartition), 0, 0, NULL, fill_diskpartition },
4329 { L"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig), 0, 0, NULL, fill_displaycontrollerconfig },
4330 { L"Win32_IP4RouteTable", C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable },
4331 { L"Win32_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
4332 { L"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition), 0, 0, NULL, fill_logicaldisktopartition },
4333 { L"Win32_NetworkAdapter", C(col_networkadapter), 0, 0, NULL, fill_networkadapter },
4334 { L"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig },
4335 { L"Win32_OperatingSystem", C(col_operatingsystem), 0, 0, NULL, fill_operatingsystem },
4336 { L"Win32_PageFileUsage", C(col_pagefileusage), D(data_pagefileusage) },
4337 { L"Win32_PhysicalMedia", C(col_physicalmedia), D(data_physicalmedia) },
4338 { L"Win32_PhysicalMemory", C(col_physicalmemory), 0, 0, NULL, fill_physicalmemory },
4339 { L"Win32_PnPEntity", C(col_pnpentity), 0, 0, NULL, fill_pnpentity },
4340 { L"Win32_Printer", C(col_printer), 0, 0, NULL, fill_printer },
4341 { L"Win32_Process", C(col_process), 0, 0, NULL, fill_process },
4342 { L"Win32_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4343 { L"Win32_QuickFixEngineering", C(col_quickfixengineering), D(data_quickfixengineering) },
4344 { L"Win32_SID", C(col_sid), 0, 0, NULL, fill_sid },
4345 { L"Win32_Service", C(col_service), 0, 0, NULL, fill_service },
4346 { L"Win32_SoundDevice", C(col_sounddevice), 0, 0, NULL, fill_sounddevice },
4347 { L"Win32_SystemEnclosure", C(col_systemenclosure), 0, 0, NULL, fill_systemenclosure },
4348 { L"Win32_VideoController", C(col_videocontroller), 0, 0, NULL, fill_videocontroller },
4349 { L"Win32_Volume", C(col_volume), 0, 0, NULL, fill_volume },
4350 { L"Win32_WinSAT", C(col_winsat), D(data_winsat) },
4353 static struct table wmi_builtin_classes[] =
4355 { L"MSSMBios_RawSMBiosTables", C(col_rawsmbiostables), D(data_rawsmbiostables) },
4357 #undef C
4358 #undef D
4360 static const struct
4362 const WCHAR *name;
4363 struct table *classes;
4364 unsigned int table_count;
4366 builtin_namespaces[WBEMPROX_NAMESPACE_LAST] =
4368 {L"cimv2", cimv2_builtin_classes, ARRAY_SIZE(cimv2_builtin_classes)},
4369 {L"Microsoft\\Windows\\Storage", NULL, 0},
4370 {L"wmi", wmi_builtin_classes, ARRAY_SIZE(wmi_builtin_classes)},
4373 void init_table_list( void )
4375 static struct list tables[WBEMPROX_NAMESPACE_LAST];
4376 UINT ns, i;
4378 for (ns = 0; ns < ARRAY_SIZE(builtin_namespaces); ns++)
4380 list_init( &tables[ns] );
4381 for (i = 0; i < builtin_namespaces[ns].table_count; i++)
4382 list_add_tail( &tables[ns], &builtin_namespaces[ns].classes[i].entry );
4383 table_list[ns] = &tables[ns];
4387 enum wbm_namespace get_namespace_from_string( const WCHAR *namespace )
4389 unsigned int i;
4391 if (!wcsicmp( namespace, L"default" )) return WBEMPROX_NAMESPACE_CIMV2;
4393 for (i = 0; i < WBEMPROX_NAMESPACE_LAST; ++i)
4394 if (!wcsicmp( namespace, builtin_namespaces[i].name )) return i;
4396 return WBEMPROX_NAMESPACE_LAST;