winewayland.drv: Implement vkGetPhysicalDeviceSurfaceSupportKHR.
[wine.git] / dlls / wbemprox / builtin.c
blobe751299e4e6262b5310e0f99813f7a97d6500911
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
21 #include <stdarg.h>
22 #include <intrin.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winsock2.h"
29 #include "ws2tcpip.h"
30 #include "initguid.h"
31 #include "wbemcli.h"
32 #include "wbemprov.h"
33 #include "iphlpapi.h"
34 #include "netioapi.h"
35 #include "tlhelp32.h"
36 #include "d3d10.h"
37 #include "winternl.h"
38 #include "winioctl.h"
39 #include "winsvc.h"
40 #include "winver.h"
41 #include "sddl.h"
42 #include "ntsecapi.h"
43 #include "winspool.h"
44 #include "setupapi.h"
45 #include "ntddstor.h"
47 #include "wine/asm.h"
48 #include "wine/debug.h"
49 #include "wbemprox_private.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
53 /* column definitions must be kept in sync with record structures below */
54 static const struct column col_associator[] =
56 { L"AssocClass", CIM_STRING },
57 { L"Class", CIM_STRING },
58 { L"Associator", CIM_STRING }
60 static const struct column col_baseboard[] =
62 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
63 { L"Model", CIM_STRING },
64 { L"Name", CIM_STRING },
65 { L"Product", CIM_STRING|COL_FLAG_DYNAMIC },
66 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
67 { L"Tag", CIM_STRING|COL_FLAG_KEY },
68 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
70 static const struct column col_bios[] =
72 { L"CurrentLanguage", CIM_STRING },
73 { L"Description", CIM_STRING },
74 { L"EmbeddedControllerMajorVersion", CIM_UINT8 },
75 { L"EmbeddedControllerMinorVersion", CIM_UINT8 },
76 { L"IdentificationCode", CIM_STRING },
77 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
78 { L"Name", CIM_STRING },
79 { L"ReleaseDate", CIM_DATETIME|COL_FLAG_DYNAMIC },
80 { L"SerialNumber", CIM_STRING },
81 { L"SMBIOSBIOSVersion", CIM_STRING|COL_FLAG_DYNAMIC },
82 { L"SMBIOSMajorVersion", CIM_UINT16 },
83 { L"SMBIOSMinorVersion", CIM_UINT16 },
84 { L"SystemBiosMajorVersion", CIM_UINT8 },
85 { L"SystemBiosMinorVersion", CIM_UINT8 },
86 { L"Version", CIM_STRING|COL_FLAG_KEY },
88 static const struct column col_cdromdrive[] =
90 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
91 { L"Drive", CIM_STRING|COL_FLAG_DYNAMIC },
92 { L"MediaType", CIM_STRING },
93 { L"Name", CIM_STRING },
94 { L"PNPDeviceID", CIM_STRING },
96 static const struct column col_compsys[] =
98 { L"Description", CIM_STRING },
99 { L"Domain", CIM_STRING },
100 { L"DomainRole", CIM_UINT16 },
101 { L"HypervisorPresent", CIM_BOOLEAN },
102 { L"Manufacturer", CIM_STRING },
103 { L"Model", CIM_STRING },
104 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
105 { L"NumberOfLogicalProcessors", CIM_UINT32 },
106 { L"NumberOfProcessors", CIM_UINT32 },
107 { L"SystemType", CIM_STRING },
108 { L"TotalPhysicalMemory", CIM_UINT64 },
109 { L"UserName", CIM_STRING|COL_FLAG_DYNAMIC },
111 static const struct column col_compsysproduct[] =
113 { L"IdentifyingNumber", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
114 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
115 { L"SKUNumber", CIM_STRING },
116 { L"UUID", CIM_STRING|COL_FLAG_DYNAMIC },
117 { L"Vendor", CIM_STRING|COL_FLAG_DYNAMIC },
118 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
120 static const struct column col_datafile[] =
122 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
123 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
125 static const struct column col_desktopmonitor[] =
127 { L"Name", CIM_STRING },
128 { L"PixelsPerXLogicalInch", CIM_UINT32 },
130 static const struct column col_directory[] =
132 { L"AccessMask", CIM_UINT32 },
133 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
135 static const struct column col_diskdrive[] =
137 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
138 { L"Index", CIM_UINT32 },
139 { L"InterfaceType", CIM_STRING },
140 { L"Manufacturer", CIM_STRING },
141 { L"MediaType", CIM_STRING },
142 { L"Model", CIM_STRING },
143 { L"PNPDeviceID", CIM_STRING },
144 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
145 { L"Size", CIM_UINT64 },
147 static const struct column col_diskdrivetodiskpartition[] =
149 { L"Antecedent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
150 { L"Dependent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
152 static const struct column col_diskpartition[] =
154 { L"Bootable", CIM_BOOLEAN },
155 { L"BootPartition", CIM_BOOLEAN },
156 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
157 { L"DiskIndex", CIM_UINT32 },
158 { L"Index", CIM_UINT32 },
159 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
160 { L"Size", CIM_UINT64 },
161 { L"StartingOffset", CIM_UINT64 },
162 { L"Type", CIM_STRING|COL_FLAG_DYNAMIC },
164 static const struct column col_displaycontrollerconfig[] =
166 { L"BitsPerPixel", CIM_UINT32 },
167 { L"Caption", CIM_STRING },
168 { L"HorizontalResolution", CIM_UINT32 },
169 { L"Name", CIM_STRING|COL_FLAG_KEY },
170 { L"VerticalResolution", CIM_UINT32 },
172 static const struct column col_ip4routetable[] =
174 { L"Destination", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
175 { L"InterfaceIndex", CIM_SINT32|COL_FLAG_KEY },
176 { L"NextHop", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
178 static const struct column col_logicaldisk[] =
180 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
181 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
182 { L"DriveType", CIM_UINT32 },
183 { L"FileSystem", CIM_STRING|COL_FLAG_DYNAMIC },
184 { L"FreeSpace", CIM_UINT64 },
185 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
186 { L"Size", CIM_UINT64 },
187 { L"VolumeName", CIM_STRING|COL_FLAG_DYNAMIC },
188 { L"VolumeSerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
190 static const struct column col_logicaldisktopartition[] =
192 { L"Antecedent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
193 { L"Dependent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
195 static const struct column col_networkadapter[] =
197 { L"AdapterType", CIM_STRING },
198 { L"AdapterTypeID", CIM_UINT16 },
199 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
200 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
201 { L"GUID", CIM_STRING|COL_FLAG_DYNAMIC },
202 { L"Index", CIM_UINT32 },
203 { L"InterfaceIndex", CIM_UINT32 },
204 { L"MACAddress", CIM_STRING|COL_FLAG_DYNAMIC },
205 { L"Manufacturer", CIM_STRING },
206 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
207 { L"NetConnectionID", CIM_STRING },
208 { L"NetConnectionStatus", CIM_UINT16 },
209 { L"NetEnabled", CIM_BOOLEAN },
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|COL_FLAG_DYNAMIC },
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|COL_FLAG_DYNAMIC },
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"Caption", CIM_STRING },
413 { L"DeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
414 { L"Manufacturer", CIM_STRING },
415 { L"Name", CIM_STRING },
416 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
417 { L"ProductName", CIM_STRING },
418 { L"Status", CIM_STRING },
419 { L"StatusInfo", CIM_UINT16 },
421 static const struct column col_stdregprov[] =
423 { L"CreateKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
424 { L"EnumKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
425 { L"EnumValues", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
426 { L"GetBinaryValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
427 { L"GetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
428 { L"SetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
429 { L"SetDWORDValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
430 { L"DeleteKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
432 static const struct column col_systemenclosure[] =
434 { L"Caption", CIM_STRING },
435 { L"ChassisTypes", CIM_UINT16|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
436 { L"Description", CIM_STRING },
437 { L"LockPresent", CIM_BOOLEAN },
438 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
439 { L"Name", CIM_STRING },
440 { L"Tag", CIM_STRING },
442 static const struct column col_systemsecurity[] =
444 { L"GetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
445 { L"SetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
447 static const struct column col_sysrestore[] =
449 { L"CreationTime", CIM_STRING },
450 { L"Description", CIM_STRING },
451 { L"EventType", CIM_UINT32 },
452 { L"RestorePointType", CIM_UINT32 },
453 { L"SequenceNumber", CIM_UINT32 },
454 /* methods */
455 { L"CreateRestorePoint", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
456 { L"Disable", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
457 { L"Enable", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
458 { L"GetLastRestoreStatus", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
459 { L"Restore", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
461 static const struct column col_videocontroller[] =
463 { L"AdapterCompatibility", CIM_STRING },
464 { L"AdapterDACType", CIM_STRING },
465 { L"AdapterRAM", CIM_UINT32 },
466 { L"Availability", CIM_UINT16 },
467 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
468 { L"ConfigManagerErrorCode", CIM_UINT32 },
469 { L"CurrentBitsPerPixel", CIM_UINT32 },
470 { L"CurrentHorizontalResolution", CIM_UINT32 },
471 { L"CurrentRefreshRate", CIM_UINT32 },
472 { L"CurrentScanMode", CIM_UINT16 },
473 { L"CurrentVerticalResolution", CIM_UINT32 },
474 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
475 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
476 { L"DriverDate", CIM_DATETIME },
477 { L"DriverVersion", CIM_STRING },
478 { L"InstalledDisplayDrivers", CIM_STRING },
479 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
480 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
481 { L"Status", CIM_STRING },
482 { L"VideoArchitecture", CIM_UINT16 },
483 { L"VideoMemoryType", CIM_UINT16 },
484 { L"VideoModeDescription", CIM_STRING|COL_FLAG_DYNAMIC },
485 { L"VideoProcessor", CIM_STRING|COL_FLAG_DYNAMIC },
488 static const struct column col_volume[] =
490 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
491 { L"DriveLetter", CIM_STRING|COL_FLAG_DYNAMIC },
494 static const struct column col_winsat[] =
496 { L"CPUScore", CIM_REAL32 },
497 { L"D3DScore", CIM_REAL32 },
498 { L"DiskScore", CIM_REAL32 },
499 { L"GraphicsScore", CIM_REAL32 },
500 { L"MemoryScore", CIM_REAL32 },
501 { L"TimeTaken", CIM_STRING|COL_FLAG_KEY },
502 { L"WinSATAssessmentState", CIM_UINT32 },
503 { L"WinSPRLevel", CIM_REAL32 },
506 #include "pshpack1.h"
507 struct record_associator
509 const WCHAR *assocclass;
510 const WCHAR *class;
511 const WCHAR *associator;
513 struct record_baseboard
515 const WCHAR *manufacturer;
516 const WCHAR *model;
517 const WCHAR *name;
518 const WCHAR *product;
519 const WCHAR *serialnumber;
520 const WCHAR *tag;
521 const WCHAR *version;
523 struct record_bios
525 const WCHAR *currentlanguage;
526 const WCHAR *description;
527 UINT8 ecmajorversion;
528 UINT8 ecminorversion;
529 const WCHAR *identificationcode;
530 const WCHAR *manufacturer;
531 const WCHAR *name;
532 const WCHAR *releasedate;
533 const WCHAR *serialnumber;
534 const WCHAR *smbiosbiosversion;
535 UINT16 smbiosmajorversion;
536 UINT16 smbiosminorversion;
537 UINT8 systembiosmajorversion;
538 UINT8 systembiosminorversion;
539 const WCHAR *version;
541 struct record_cdromdrive
543 const WCHAR *device_id;
544 const WCHAR *drive;
545 const WCHAR *mediatype;
546 const WCHAR *name;
547 const WCHAR *pnpdevice_id;
549 struct record_computersystem
551 const WCHAR *description;
552 const WCHAR *domain;
553 UINT16 domainrole;
554 int hypervisorpresent;
555 const WCHAR *manufacturer;
556 const WCHAR *model;
557 const WCHAR *name;
558 UINT32 num_logical_processors;
559 UINT32 num_processors;
560 const WCHAR *systemtype;
561 UINT64 total_physical_memory;
562 const WCHAR *username;
564 struct record_computersystemproduct
566 const WCHAR *identifyingnumber;
567 const WCHAR *name;
568 const WCHAR *skunumber;
569 const WCHAR *uuid;
570 const WCHAR *vendor;
571 const WCHAR *version;
573 struct record_datafile
575 const WCHAR *name;
576 const WCHAR *version;
578 struct record_desktopmonitor
580 const WCHAR *name;
581 UINT32 pixelsperxlogicalinch;
583 struct record_directory
585 UINT32 accessmask;
586 const WCHAR *name;
588 struct record_diskdrive
590 const WCHAR *device_id;
591 UINT32 index;
592 const WCHAR *interfacetype;
593 const WCHAR *manufacturer;
594 const WCHAR *mediatype;
595 const WCHAR *model;
596 const WCHAR *pnpdevice_id;
597 const WCHAR *serialnumber;
598 UINT64 size;
600 struct record_diskdrivetodiskpartition
602 const WCHAR *antecedent;
603 const WCHAR *dependent;
605 struct record_diskpartition
607 int bootable;
608 int bootpartition;
609 const WCHAR *device_id;
610 UINT32 diskindex;
611 UINT32 index;
612 const WCHAR *pnpdevice_id;
613 UINT64 size;
614 UINT64 startingoffset;
615 const WCHAR *type;
617 struct record_displaycontrollerconfig
619 UINT32 bitsperpixel;
620 const WCHAR *caption;
621 UINT32 horizontalresolution;
622 const WCHAR *name;
623 UINT32 verticalresolution;
625 struct record_ip4routetable
627 const WCHAR *destination;
628 INT32 interfaceindex;
629 const WCHAR *nexthop;
631 struct record_logicaldisk
633 const WCHAR *caption;
634 const WCHAR *device_id;
635 UINT32 drivetype;
636 const WCHAR *filesystem;
637 UINT64 freespace;
638 const WCHAR *name;
639 UINT64 size;
640 const WCHAR *volumename;
641 const WCHAR *volumeserialnumber;
643 struct record_logicaldisktopartition
645 const WCHAR *antecedent;
646 const WCHAR *dependent;
648 struct record_networkadapter
650 const WCHAR *adaptertype;
651 UINT16 adaptertypeid;
652 const WCHAR *description;
653 const WCHAR *device_id;
654 const WCHAR *guid;
655 UINT32 index;
656 UINT32 interface_index;
657 const WCHAR *mac_address;
658 const WCHAR *manufacturer;
659 const WCHAR *name;
660 const WCHAR *netconnection_id;
661 UINT16 netconnection_status;
662 int netenabled;
663 int physicaladapter;
664 const WCHAR *pnpdevice_id;
665 const WCHAR *servicename;
666 UINT64 speed;
668 struct record_networkadapterconfig
670 const struct array *defaultipgateway;
671 const WCHAR *description;
672 int dhcpenabled;
673 const WCHAR *dnsdomain;
674 const WCHAR *dnshostname;
675 const struct array *dnsserversearchorder;
676 UINT32 index;
677 const struct array *ipaddress;
678 UINT32 ipconnectionmetric;
679 int ipenabled;
680 const struct array *ipsubnet;
681 const WCHAR *mac_address;
682 const WCHAR *settingid;
684 struct record_operatingsystem
686 const WCHAR *bootdevice;
687 const WCHAR *buildnumber;
688 const WCHAR *buildtype;
689 const WCHAR *caption;
690 const WCHAR *codeset;
691 const WCHAR *countrycode;
692 const WCHAR *csdversion;
693 const WCHAR *csname;
694 INT16 currenttimezone;
695 UINT64 freephysicalmemory;
696 UINT64 freevirtualmemory;
697 const WCHAR *installdate;
698 const WCHAR *lastbootuptime;
699 const WCHAR *localdatetime;
700 const WCHAR *locale;
701 const WCHAR *manufacturer;
702 const WCHAR *name;
703 UINT32 operatingsystemsku;
704 const WCHAR *organization;
705 const WCHAR *osarchitecture;
706 UINT32 oslanguage;
707 UINT32 osproductsuite;
708 UINT16 ostype;
709 int primary;
710 UINT32 producttype;
711 const WCHAR *registereduser;
712 const WCHAR *serialnumber;
713 UINT16 servicepackmajor;
714 UINT16 servicepackminor;
715 const WCHAR *status;
716 UINT32 suitemask;
717 const WCHAR *systemdirectory;
718 const WCHAR *systemdrive;
719 UINT64 totalvirtualmemorysize;
720 UINT64 totalvisiblememorysize;
721 const WCHAR *version;
722 const WCHAR *windowsdirectory;
724 struct record_pagefileusage
726 const WCHAR *name;
728 struct record_param
730 const WCHAR *class;
731 const WCHAR *method;
732 INT32 direction;
733 const WCHAR *parameter;
734 UINT32 type;
735 UINT32 defaultvalue;
737 struct record_physicalmedia
739 const WCHAR *serialnumber;
740 const WCHAR *tag;
742 struct record_physicalmemory
744 const WCHAR *banklabel;
745 UINT64 capacity;
746 const WCHAR *caption;
747 UINT32 configuredclockspeed;
748 const WCHAR *devicelocator;
749 UINT16 formfactor;
750 UINT16 memorytype;
751 const WCHAR *partnumber;
752 const WCHAR *serial;
754 struct record_pnpentity
756 const WCHAR *device_id;
757 const WCHAR *manufacturer;
758 const WCHAR *name;
760 struct record_printer
762 UINT32 attributes;
763 const WCHAR *device_id;
764 const WCHAR *drivername;
765 UINT32 horizontalresolution;
766 int local;
767 const WCHAR *location;
768 const WCHAR *name;
769 int network;
770 const WCHAR *portname;
772 struct record_process
774 const WCHAR *caption;
775 const WCHAR *commandline;
776 const WCHAR *description;
777 const WCHAR *handle;
778 const WCHAR *name;
779 UINT32 pprocess_id;
780 UINT32 process_id;
781 UINT32 thread_count;
782 UINT64 workingsetsize;
783 /* methods */
784 class_method *create;
785 class_method *get_owner;
787 struct record_processor
789 UINT16 addresswidth;
790 UINT16 architecture;
791 const WCHAR *caption;
792 UINT16 cpu_status;
793 UINT32 currentclockspeed;
794 UINT16 datawidth;
795 const WCHAR *description;
796 const WCHAR *device_id;
797 UINT16 family;
798 UINT16 level;
799 const WCHAR *manufacturer;
800 UINT32 maxclockspeed;
801 const WCHAR *name;
802 UINT32 num_cores;
803 UINT32 num_logical_processors;
804 const WCHAR *processor_id;
805 UINT16 processortype;
806 UINT16 revision;
807 const WCHAR *unique_id;
808 const WCHAR *version;
810 struct record_qualifier
812 const WCHAR *class;
813 const WCHAR *member;
814 UINT32 type;
815 INT32 flavor;
816 const WCHAR *name;
817 INT32 intvalue;
818 const WCHAR *strvalue;
819 int boolvalue;
821 struct record_quickfixengineering
823 const WCHAR *caption;
824 const WCHAR *description;
825 const WCHAR *hotfixid;
826 const WCHAR *installedby;
827 const WCHAR *installedon;
829 struct record_rawsmbiostables
831 const struct array *smbiosdata;
833 struct record_service
835 int accept_pause;
836 int accept_stop;
837 const WCHAR *displayname;
838 const WCHAR *name;
839 UINT32 process_id;
840 const WCHAR *servicetype;
841 const WCHAR *startmode;
842 const WCHAR *state;
843 const WCHAR *systemname;
844 /* methods */
845 class_method *pause_service;
846 class_method *resume_service;
847 class_method *start_service;
848 class_method *stop_service;
850 struct record_sid
852 const WCHAR *accountname;
853 const struct array *binaryrepresentation;
854 const WCHAR *referenceddomainname;
855 const WCHAR *sid;
856 UINT32 sidlength;
858 struct record_softwarelicensingproduct
860 int license_is_addon;
861 UINT32 license_status;
863 struct record_sounddevice
865 const WCHAR *caption;
866 const WCHAR *deviceid;
867 const WCHAR *manufacturer;
868 const WCHAR *name;
869 const WCHAR *pnpdeviceid;
870 const WCHAR *productname;
871 const WCHAR *status;
872 UINT16 statusinfo;
874 struct record_stdregprov
876 class_method *createkey;
877 class_method *enumkey;
878 class_method *enumvalues;
879 class_method *getbinaryvalue;
880 class_method *getstringvalue;
881 class_method *setstringvalue;
882 class_method *setdwordvalue;
883 class_method *deletekey;
885 struct record_sysrestore
887 const WCHAR *creation_time;
888 const WCHAR *description;
889 UINT32 event_type;
890 UINT32 restore_point_type;
891 UINT32 sequence_number;
892 class_method *create_restore_point;
893 class_method *disable_restore;
894 class_method *enable_restore;
895 class_method *get_last_restore_status;
896 class_method *restore;
898 struct record_systemsecurity
900 class_method *getsd;
901 class_method *setsd;
903 struct record_systemenclosure
905 const WCHAR *caption;
906 const struct array *chassistypes;
907 const WCHAR *description;
908 int lockpresent;
909 const WCHAR *manufacturer;
910 const WCHAR *name;
911 const WCHAR *tag;
913 struct record_videocontroller
915 const WCHAR *adapter_compatibility;
916 const WCHAR *adapter_dactype;
917 UINT32 adapter_ram;
918 UINT16 availability;
919 const WCHAR *caption;
920 UINT32 config_errorcode;
921 UINT32 current_bitsperpixel;
922 UINT32 current_horizontalres;
923 UINT32 current_refreshrate;
924 UINT16 current_scanmode;
925 UINT32 current_verticalres;
926 const WCHAR *description;
927 const WCHAR *device_id;
928 const WCHAR *driverdate;
929 const WCHAR *driverversion;
930 const WCHAR *installeddriver;
931 const WCHAR *name;
932 const WCHAR *pnpdevice_id;
933 const WCHAR *status;
934 UINT16 videoarchitecture;
935 UINT16 videomemorytype;
936 const WCHAR *videomodedescription;
937 const WCHAR *videoprocessor;
940 struct record_volume
942 const WCHAR *deviceid;
943 const WCHAR *driveletter;
946 struct record_winsat
948 FLOAT cpuscore;
949 FLOAT d3dscore;
950 FLOAT diskscrore;
951 FLOAT graphicsscore;
952 FLOAT memoryscore;
953 const WCHAR *timetaken;
954 UINT32 winsatassessmentstate;
955 FLOAT winsprlevel;
957 #include "poppack.h"
959 static const struct record_associator data_associator[] =
961 { L"Win32_DiskDriveToDiskPartition", L"Win32_DiskPartition", L"Win32_DiskDrive" },
962 { L"Win32_LogicalDiskToPartition", L"Win32_LogicalDisk", L"Win32_DiskPartition" },
964 static const struct record_pagefileusage data_pagefileusage[] =
966 { L"c:\\pagefile.sys", },
968 static const struct record_param data_param[] =
970 { L"__SystemSecurity", L"GetSD", -1, L"ReturnValue", CIM_UINT32 },
971 { L"__SystemSecurity", L"GetSD", -1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
972 { L"__SystemSecurity", L"SetSD", 1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
973 { L"__SystemSecurity", L"SetSD", -1, L"ReturnValue", CIM_UINT32 },
974 { L"StdRegProv", L"CreateKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
975 { L"StdRegProv", L"CreateKey", 1, L"sSubKeyName", CIM_STRING },
976 { L"StdRegProv", L"CreateKey", -1, L"ReturnValue", CIM_UINT32 },
977 { L"StdRegProv", L"DeleteKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
978 { L"StdRegProv", L"DeleteKey", 1, L"sSubKeyName", CIM_STRING },
979 { L"StdRegProv", L"DeleteKey", -1, L"ReturnValue", CIM_UINT32 },
980 { L"StdRegProv", L"EnumKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
981 { L"StdRegProv", L"EnumKey", 1, L"sSubKeyName", CIM_STRING },
982 { L"StdRegProv", L"EnumKey", -1, L"ReturnValue", CIM_UINT32 },
983 { L"StdRegProv", L"EnumKey", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
984 { L"StdRegProv", L"EnumValues", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
985 { L"StdRegProv", L"EnumValues", 1, L"sSubKeyName", CIM_STRING },
986 { L"StdRegProv", L"EnumValues", -1, L"ReturnValue", CIM_UINT32 },
987 { L"StdRegProv", L"EnumValues", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
988 { L"StdRegProv", L"EnumValues", -1, L"Types", CIM_SINT32|CIM_FLAG_ARRAY },
989 { L"StdRegProv", L"GetBinaryValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
990 { L"StdRegProv", L"GetBinaryValue", 1, L"sSubKeyName", CIM_STRING },
991 { L"StdRegProv", L"GetBinaryValue", 1, L"sValueName", CIM_STRING },
992 { L"StdRegProv", L"GetBinaryValue", -1, L"ReturnValue", CIM_UINT32 },
993 { L"StdRegProv", L"GetBinaryValue", -1, L"uValue", CIM_UINT8|CIM_FLAG_ARRAY },
994 { L"StdRegProv", L"GetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
995 { L"StdRegProv", L"GetStringValue", 1, L"sSubKeyName", CIM_STRING },
996 { L"StdRegProv", L"GetStringValue", 1, L"sValueName", CIM_STRING },
997 { L"StdRegProv", L"GetStringValue", -1, L"ReturnValue", CIM_UINT32 },
998 { L"StdRegProv", L"GetStringValue", -1, L"sValue", CIM_STRING },
999 { L"StdRegProv", L"SetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
1000 { L"StdRegProv", L"SetStringValue", 1, L"sSubKeyName", CIM_STRING },
1001 { L"StdRegProv", L"SetStringValue", 1, L"sValueName", CIM_STRING },
1002 { L"StdRegProv", L"SetStringValue", 1, L"sValue", CIM_STRING },
1003 { L"StdRegProv", L"SetStringValue", -1, L"ReturnValue", CIM_UINT32 },
1004 { L"StdRegProv", L"SetDWORDValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
1005 { L"StdRegProv", L"SetDWORDValue", 1, L"sSubKeyName", CIM_STRING },
1006 { L"StdRegProv", L"SetDWORDValue", 1, L"sValueName", CIM_STRING },
1007 { L"StdRegProv", L"SetDWORDValue", 1, L"uValue", CIM_UINT32 },
1008 { L"StdRegProv", L"SetDWORDValue", -1, L"ReturnValue", CIM_UINT32 },
1009 { L"SystemRestore", L"Disable", 1, L"Drive", CIM_STRING },
1010 { L"SystemRestore", L"Disable", -1, L"ReturnValue", CIM_UINT32 },
1011 { L"SystemRestore", L"Enable", 1, L"Drive", CIM_STRING },
1012 { L"SystemRestore", L"Enable", -1, L"ReturnValue", CIM_UINT32 },
1013 { L"Win32_Process", L"Create", 1, L"CommandLine", CIM_STRING },
1014 { L"Win32_Process", L"Create", 1, L"CurrentDirectory", CIM_STRING },
1015 { L"Win32_Process", L"Create", -1, L"ProcessId", CIM_UINT32 },
1016 { L"Win32_Process", L"Create", -1, L"ReturnValue", CIM_UINT32 },
1017 { L"Win32_Process", L"GetOwner", -1, L"ReturnValue", CIM_UINT32 },
1018 { L"Win32_Process", L"GetOwner", -1, L"User", CIM_STRING },
1019 { L"Win32_Process", L"GetOwner", -1, L"Domain", CIM_STRING },
1020 { L"Win32_Service", L"PauseService", -1, L"ReturnValue", CIM_UINT32 },
1021 { L"Win32_Service", L"ResumeService", -1, L"ReturnValue", CIM_UINT32 },
1022 { L"Win32_Service", L"StartService", -1, L"ReturnValue", CIM_UINT32 },
1023 { L"Win32_Service", L"StopService", -1, L"ReturnValue", CIM_UINT32 },
1026 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1027 WBEM_FLAVOR_ORIGIN_PROPAGATED)
1029 static const struct record_physicalmedia data_physicalmedia[] =
1031 { L"WINEHDISK", L"\\\\.\\PHYSICALDRIVE0" }
1034 static const struct record_rawsmbiostables data_rawsmbiostables[] =
1036 { 0 },
1039 static const struct record_qualifier data_qualifier[] =
1041 { L"__WIN32_PROCESS_GETOWNER_OUT", L"User", CIM_SINT32, FLAVOR_ID, L"ID", 0 },
1042 { L"__WIN32_PROCESS_GETOWNER_OUT", L"Domain", CIM_SINT32, FLAVOR_ID, L"ID", 1 }
1045 static const struct record_quickfixengineering data_quickfixengineering[] =
1047 { L"http://winehq.org", L"Update", L"KB1234567", L"", L"22/2/2022" },
1050 static const struct record_softwarelicensingproduct data_softwarelicensingproduct[] =
1052 { 0, 1 },
1055 static const struct record_stdregprov data_stdregprov[] =
1058 reg_create_key,
1059 reg_enum_key,
1060 reg_enum_values,
1061 reg_get_binaryvalue,
1062 reg_get_stringvalue,
1063 reg_set_stringvalue,
1064 reg_set_dwordvalue,
1065 reg_delete_key,
1069 static const struct record_sysrestore data_sysrestore[] =
1071 { NULL, NULL, 0, 0, 0, sysrestore_create, sysrestore_disable, sysrestore_enable, sysrestore_get_last_status,
1072 sysrestore_restore }
1075 static UINT16 systemenclosure_chassistypes[] =
1079 static const struct array systemenclosure_chassistypes_array =
1081 sizeof(*systemenclosure_chassistypes),
1082 ARRAY_SIZE(systemenclosure_chassistypes),
1083 &systemenclosure_chassistypes
1085 static const struct record_systemsecurity data_systemsecurity[] =
1087 { security_get_sd, security_set_sd }
1089 static const struct record_winsat data_winsat[] =
1091 { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, L"MostRecentAssessment", 1 /* Valid */, 8.0f },
1094 /* check if row matches condition and update status */
1095 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
1097 LONGLONG val;
1098 UINT type;
1100 if (!cond)
1102 *status = FILL_STATUS_UNFILTERED;
1103 return TRUE;
1105 if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1107 *status = FILL_STATUS_FAILED;
1108 return FALSE;
1110 *status = FILL_STATUS_FILTERED;
1111 return val != 0;
1114 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
1116 if (!table->num_rows_allocated)
1118 if (!(table->data = malloc( row_count * row_size ))) return FALSE;
1119 table->num_rows_allocated = row_count;
1120 return TRUE;
1122 if (row_count > table->num_rows_allocated)
1124 BYTE *data;
1125 UINT count = max( row_count, table->num_rows_allocated * 2 );
1126 if (!(data = realloc( table->data, count * row_size ))) return FALSE;
1127 table->data = data;
1128 table->num_rows_allocated = count;
1130 return TRUE;
1133 #include "pshpack1.h"
1134 struct smbios_prologue
1136 BYTE calling_method;
1137 BYTE major_version;
1138 BYTE minor_version;
1139 BYTE revision;
1140 DWORD length;
1143 enum smbios_type
1145 SMBIOS_TYPE_BIOS,
1146 SMBIOS_TYPE_SYSTEM,
1147 SMBIOS_TYPE_BASEBOARD,
1148 SMBIOS_TYPE_CHASSIS,
1151 struct smbios_header
1153 BYTE type;
1154 BYTE length;
1155 WORD handle;
1158 struct smbios_baseboard
1160 struct smbios_header hdr;
1161 BYTE vendor;
1162 BYTE product;
1163 BYTE version;
1164 BYTE serial;
1167 struct smbios_bios
1169 struct smbios_header hdr;
1170 BYTE vendor;
1171 BYTE version;
1172 WORD start;
1173 BYTE date;
1174 BYTE size;
1175 UINT64 characteristics;
1176 BYTE characteristics_ext[2];
1177 BYTE system_bios_major_release;
1178 BYTE system_bios_minor_release;
1179 BYTE ec_firmware_major_release;
1180 BYTE ec_firmware_minor_release;
1183 struct smbios_chassis
1185 struct smbios_header hdr;
1186 BYTE vendor;
1187 BYTE type;
1188 BYTE version;
1189 BYTE serial;
1190 BYTE asset_tag;
1193 struct smbios_system
1195 struct smbios_header hdr;
1196 BYTE vendor;
1197 BYTE product;
1198 BYTE version;
1199 BYTE serial;
1200 BYTE uuid[16];
1202 #include "poppack.h"
1204 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1206 static const struct smbios_header *find_smbios_entry( enum smbios_type type, const char *buf, UINT len )
1208 const char *ptr, *start;
1209 const struct smbios_prologue *prologue;
1210 const struct smbios_header *hdr;
1212 if (len < sizeof(struct smbios_prologue)) return NULL;
1213 prologue = (const struct smbios_prologue *)buf;
1214 if (prologue->length > len - sizeof(*prologue) || prologue->length < sizeof(*hdr)) return NULL;
1216 start = (const char *)(prologue + 1);
1217 hdr = (const struct smbios_header *)start;
1219 for (;;)
1221 if ((const char *)hdr - start >= prologue->length - sizeof(*hdr)) return NULL;
1223 if (!hdr->length)
1225 WARN( "invalid entry\n" );
1226 return NULL;
1229 if (hdr->type == type)
1231 if ((const char *)hdr - start + hdr->length > prologue->length) return NULL;
1232 break;
1234 else /* skip other entries and their strings */
1236 for (ptr = (const char *)hdr + hdr->length; ptr - buf < len && *ptr; ptr++)
1238 for (; ptr - buf < len; ptr++) if (!*ptr) break;
1240 if (ptr == (const char *)hdr + hdr->length) ptr++;
1241 hdr = (const struct smbios_header *)(ptr + 1);
1245 return hdr;
1248 static WCHAR *get_smbios_string_by_id( BYTE id, const char *buf, UINT offset, UINT buflen )
1250 const char *ptr = buf + offset;
1251 UINT i = 0;
1253 if (!id || offset >= buflen) return NULL;
1254 for (ptr = buf + offset; ptr - buf < buflen && *ptr; ptr++)
1256 if (++i == id) return heap_strdupAW( ptr );
1257 for (; ptr - buf < buflen; ptr++) if (!*ptr) break;
1259 return NULL;
1262 static WCHAR *get_smbios_string( enum smbios_type type, size_t field_offset, const char *buf, UINT len )
1264 const struct smbios_header *hdr;
1265 UINT offset;
1267 if (!(hdr = find_smbios_entry( type, buf, len ))) return NULL;
1269 if (field_offset + sizeof(BYTE) > hdr->length) return NULL;
1271 offset = (const char *)hdr - buf + hdr->length;
1272 return get_smbios_string_by_id( ((const BYTE *)hdr)[field_offset], buf, offset, len );
1275 static WCHAR *get_baseboard_manufacturer( const char *buf, UINT len )
1277 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_BASEBOARD, offsetof(struct smbios_baseboard, vendor), buf, len );
1278 if (!ret) return wcsdup( L"Intel Corporation" );
1279 return ret;
1282 static WCHAR *get_baseboard_product( const char *buf, UINT len )
1284 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_BASEBOARD, offsetof(struct smbios_baseboard, product), buf, len );
1285 if (!ret) return wcsdup( L"Base Board" );
1286 return ret;
1289 static WCHAR *get_baseboard_serialnumber( const char *buf, UINT len )
1291 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_BASEBOARD, offsetof(struct smbios_baseboard, serial), buf, len );
1292 if (!ret) return wcsdup( L"None" );
1293 return ret;
1296 static WCHAR *get_baseboard_version( const char *buf, UINT len )
1298 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_BASEBOARD, offsetof(struct smbios_baseboard, version), buf, len );
1299 if (!ret) return wcsdup( L"1.0" );
1300 return ret;
1303 static enum fill_status fill_baseboard( struct table *table, const struct expr *cond )
1305 struct record_baseboard *rec;
1306 enum fill_status status = FILL_STATUS_UNFILTERED;
1307 UINT row = 0, len;
1308 char *buf;
1310 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1312 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1313 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1314 GetSystemFirmwareTable( RSMB, 0, buf, len );
1316 rec = (struct record_baseboard *)table->data;
1317 rec->manufacturer = get_baseboard_manufacturer( buf, len );
1318 rec->model = L"Base Board";
1319 rec->name = L"Base Board";
1320 rec->product = get_baseboard_product( buf, len );
1321 rec->serialnumber = get_baseboard_serialnumber( buf, len );
1322 rec->tag = L"Base Board";
1323 rec->version = get_baseboard_version( buf, len );
1324 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1325 else row++;
1327 free( buf );
1329 TRACE("created %u rows\n", row);
1330 table->num_rows = row;
1331 return status;
1334 static UINT16 get_bios_smbiosmajorversion( const char *buf, UINT len )
1336 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1337 if (len < sizeof(*prologue)) return 2;
1338 return prologue->major_version;
1341 static UINT16 get_bios_smbiosminorversion( const char *buf, UINT len )
1343 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1344 if (len < sizeof(*prologue)) return 0;
1345 return prologue->minor_version;
1347 static WCHAR *get_bios_manufacturer( const char *buf, UINT len )
1349 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_BIOS, offsetof(struct smbios_bios, vendor), buf, len );
1350 if (!ret) return wcsdup( L"The Wine Project" );
1351 return ret;
1354 static WCHAR *convert_bios_date( const WCHAR *str )
1356 static const WCHAR fmtW[] = L"%04u%02u%02u000000.000000+000";
1357 UINT year, month, day, len = lstrlenW( str );
1358 const WCHAR *p = str, *q;
1359 WCHAR *ret;
1361 while (len && iswspace( *p )) { p++; len--; }
1362 while (len && iswspace( p[len - 1] )) { len--; }
1364 q = p;
1365 while (len && is_digit( *q )) { q++; len--; };
1366 if (q - p != 2 || !len || *q != '/') return NULL;
1367 month = (p[0] - '0') * 10 + p[1] - '0';
1369 p = ++q; len--;
1370 while (len && is_digit( *q )) { q++; len--; };
1371 if (q - p != 2 || !len || *q != '/') return NULL;
1372 day = (p[0] - '0') * 10 + p[1] - '0';
1374 p = ++q; len--;
1375 while (len && is_digit( *q )) { q++; len--; };
1376 if (q - p == 4) year = (p[0] - '0') * 1000 + (p[1] - '0') * 100 + (p[2] - '0') * 10 + p[3] - '0';
1377 else if (q - p == 2) year = 1900 + (p[0] - '0') * 10 + p[1] - '0';
1378 else return NULL;
1380 if (!(ret = malloc( sizeof(fmtW) ))) return NULL;
1381 swprintf( ret, ARRAY_SIZE(fmtW), fmtW, year, month, day );
1382 return ret;
1385 static WCHAR *get_bios_releasedate( const char *buf, UINT len )
1387 WCHAR *ret, *date = get_smbios_string( SMBIOS_TYPE_BIOS, offsetof(struct smbios_bios, date), buf, len );
1388 if (!date || !(ret = convert_bios_date( date ))) ret = wcsdup( L"20120608000000.000000+000" );
1389 free( date );
1390 return ret;
1393 static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len )
1395 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_BIOS, offsetof(struct smbios_bios, version), buf, len );
1396 if (!ret) return wcsdup( L"Wine" );
1397 return ret;
1400 static BYTE get_bios_ec_firmware_major_release( const char *buf, UINT len )
1402 const struct smbios_header *hdr;
1403 const struct smbios_bios *bios;
1405 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1407 bios = (const struct smbios_bios *)hdr;
1408 if (bios->hdr.length >= 0x18) return bios->ec_firmware_major_release;
1409 else return 0xFF;
1412 static BYTE get_bios_ec_firmware_minor_release( const char *buf, UINT len )
1414 const struct smbios_header *hdr;
1415 const struct smbios_bios *bios;
1417 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1419 bios = (const struct smbios_bios *)hdr;
1420 if (bios->hdr.length >= 0x18) return bios->ec_firmware_minor_release;
1421 else return 0xFF;
1424 static BYTE get_bios_system_bios_major_release( const char *buf, UINT len )
1426 const struct smbios_header *hdr;
1427 const struct smbios_bios *bios;
1429 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1431 bios = (const struct smbios_bios *)hdr;
1432 if (bios->hdr.length >= 0x18) return bios->system_bios_major_release;
1433 else return 0xFF;
1436 static BYTE get_bios_system_bios_minor_release( const char *buf, UINT len )
1438 const struct smbios_header *hdr;
1439 const struct smbios_bios *bios;
1441 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1443 bios = (const struct smbios_bios *)hdr;
1444 if (bios->hdr.length >= 0x18) return bios->system_bios_minor_release;
1445 else return 0xFF;
1448 static enum fill_status fill_bios( struct table *table, const struct expr *cond )
1450 struct record_bios *rec;
1451 enum fill_status status = FILL_STATUS_UNFILTERED;
1452 UINT row = 0, len;
1453 char *buf;
1455 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1457 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1458 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1459 GetSystemFirmwareTable( RSMB, 0, buf, len );
1461 rec = (struct record_bios *)table->data;
1462 rec->currentlanguage = NULL;
1463 rec->description = L"Default System BIOS";
1464 rec->ecmajorversion = get_bios_ec_firmware_major_release( buf, len );
1465 rec->ecminorversion = get_bios_ec_firmware_minor_release( buf, len );
1466 rec->identificationcode = NULL;
1467 rec->manufacturer = get_bios_manufacturer( buf, len );
1468 rec->name = L"Default System BIOS";
1469 rec->releasedate = get_bios_releasedate( buf, len );
1470 rec->serialnumber = L"Serial number";
1471 rec->smbiosbiosversion = get_bios_smbiosbiosversion( buf, len );
1472 rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len );
1473 rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
1474 rec->systembiosmajorversion = get_bios_system_bios_major_release( buf, len );
1475 rec->systembiosminorversion = get_bios_system_bios_minor_release( buf, len );
1476 rec->version = L"WINE - 1";
1477 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1478 else row++;
1480 free( buf );
1482 TRACE("created %u rows\n", row);
1483 table->num_rows = row;
1484 return status;
1487 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1489 WCHAR drive[3], root[] = L"A:\\";
1490 struct record_cdromdrive *rec;
1491 UINT i, row = 0, offset = 0;
1492 DWORD drives = GetLogicalDrives();
1493 enum fill_status status = FILL_STATUS_UNFILTERED;
1495 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1497 for (i = 0; i < 26; i++)
1499 if (drives & (1 << i))
1501 root[0] = 'A' + i;
1502 if (GetDriveTypeW( root ) != DRIVE_CDROM)
1503 continue;
1505 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1507 rec = (struct record_cdromdrive *)(table->data + offset);
1508 rec->device_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1509 swprintf( drive, ARRAY_SIZE( drive ), L"%c:", 'A' + i );
1510 rec->drive = wcsdup( drive );
1511 rec->mediatype = L"CR-ROM";
1512 rec->name = L"Wine CD_ROM ATA Device";
1513 rec->pnpdevice_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1514 if (!match_row( table, row, cond, &status ))
1516 free_row_values( table, row );
1517 continue;
1519 offset += sizeof(*rec);
1520 row++;
1523 TRACE("created %u rows\n", row);
1524 table->num_rows = row;
1525 return status;
1528 static UINT get_processor_count(void)
1530 SYSTEM_BASIC_INFORMATION info;
1532 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1533 return info.NumberOfProcessors;
1536 static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
1538 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
1539 UINT core_relation_count = 0, package_relation_count = 0;
1540 NTSTATUS status;
1541 ULONG len, offset = 0;
1542 BOOL smt_enabled = FALSE;
1543 DWORD all = RelationAll;
1545 if (num_packages) *num_packages = 1;
1546 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
1547 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1549 if (!(buf = malloc( len ))) return get_processor_count();
1550 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, &len );
1551 if (status != STATUS_SUCCESS)
1553 free( buf );
1554 return get_processor_count();
1557 while (offset < len)
1559 entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
1561 if (entry->Relationship == RelationProcessorCore)
1563 core_relation_count++;
1564 if (entry->Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
1566 else if (entry->Relationship == RelationProcessorPackage)
1568 package_relation_count++;
1570 offset += entry->Size;
1573 free( buf );
1574 if (num_physical) *num_physical = core_relation_count;
1575 if (num_packages) *num_packages = package_relation_count;
1576 return smt_enabled ? core_relation_count * 2 : core_relation_count;
1579 static UINT64 get_total_physical_memory(void)
1581 MEMORYSTATUSEX status;
1583 status.dwLength = sizeof(status);
1584 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1585 return status.ullTotalPhys;
1588 static UINT64 get_available_physical_memory(void)
1590 MEMORYSTATUSEX status;
1592 status.dwLength = sizeof(status);
1593 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1594 return status.ullAvailPhys;
1597 static UINT64 get_total_virtual_memory(void)
1599 MEMORYSTATUSEX status;
1601 status.dwLength = sizeof(status);
1602 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1603 return status.ullTotalVirtual;
1606 static UINT64 get_available_virtual_memory(void)
1608 MEMORYSTATUSEX status;
1610 status.dwLength = sizeof(status);
1611 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1612 return status.ullAvailVirtual;
1615 static WCHAR *get_computername(void)
1617 WCHAR *ret;
1618 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1620 if (!(ret = malloc( size * sizeof(WCHAR) ))) return NULL;
1621 GetComputerNameW( ret, &size );
1622 return ret;
1625 static const WCHAR *get_systemtype(void)
1627 SYSTEM_INFO info;
1628 GetNativeSystemInfo( &info );
1629 if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return L"x64 based PC";
1630 return L"x86 based PC";
1633 static WCHAR *get_username(void)
1635 WCHAR *ret;
1636 DWORD compsize, usersize;
1637 DWORD size;
1639 compsize = 0;
1640 GetComputerNameW( NULL, &compsize );
1641 usersize = 0;
1642 GetUserNameW( NULL, &usersize );
1643 size = compsize + usersize; /* two null terminators account for the \ */
1644 if (!(ret = malloc( size * sizeof(WCHAR) ))) return NULL;
1645 GetComputerNameW( ret, &compsize );
1646 ret[compsize] = '\\';
1647 GetUserNameW( ret + compsize + 1, &usersize );
1648 return ret;
1651 static WCHAR *get_compsysproduct_name( const char *buf, UINT len )
1653 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_SYSTEM, offsetof(struct smbios_system, product), buf, len );
1654 if (!ret) return wcsdup( L"Wine" );
1655 return ret;
1658 static WCHAR *get_compsysproduct_vendor( const char *buf, UINT len )
1660 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_SYSTEM, offsetof(struct smbios_system, vendor), buf, len );
1661 if (!ret) return wcsdup( L"The Wine Project" );
1662 return ret;
1665 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1667 struct record_computersystem *rec;
1668 enum fill_status status = FILL_STATUS_UNFILTERED;
1669 UINT row = 0, len;
1670 char *buf;
1672 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1674 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1675 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1676 GetSystemFirmwareTable( RSMB, 0, buf, len );
1678 rec = (struct record_computersystem *)table->data;
1679 rec->description = L"AT/AT COMPATIBLE";
1680 rec->domain = L"WORKGROUP";
1681 rec->domainrole = 0; /* standalone workstation */
1682 rec->hypervisorpresent = 0;
1683 rec->manufacturer = get_compsysproduct_vendor( buf, len );
1684 rec->model = get_compsysproduct_name( buf, len );
1685 rec->name = get_computername();
1686 rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
1687 rec->systemtype = get_systemtype();
1688 rec->total_physical_memory = get_total_physical_memory();
1689 rec->username = get_username();
1690 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1691 else row++;
1693 free( buf );
1695 TRACE("created %u rows\n", row);
1696 table->num_rows = row;
1697 return status;
1700 static WCHAR *get_compsysproduct_identifyingnumber( const char *buf, UINT len )
1702 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_SYSTEM, offsetof(struct smbios_system, serial), buf, len );
1703 if (!ret) return wcsdup( L"0" );
1704 return ret;
1707 static WCHAR *get_compsysproduct_uuid( const char *buf, UINT len )
1709 static const BYTE none[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1710 const struct smbios_header *hdr;
1711 const struct smbios_system *system;
1712 const BYTE *ptr;
1713 WCHAR *ret = NULL;
1715 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len )) || hdr->length < sizeof(*system)) goto done;
1716 system = (const struct smbios_system *)hdr;
1717 if (!memcmp( system->uuid, none, sizeof(none) ) || !(ret = malloc( 37 * sizeof(WCHAR) ))) goto done;
1719 ptr = system->uuid;
1720 swprintf( ret, 37, L"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr[0], ptr[1],
1721 ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1722 ptr[14], ptr[15] );
1723 done:
1724 if (!ret) ret = wcsdup( L"deaddead-dead-dead-dead-deaddeaddead" );
1725 return ret;
1728 static WCHAR *get_compsysproduct_version( const char *buf, UINT len )
1730 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_SYSTEM, offsetof(struct smbios_system, version), buf, len );
1731 if (!ret) return wcsdup( L"1.0" );
1732 return ret;
1735 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1737 struct record_computersystemproduct *rec;
1738 enum fill_status status = FILL_STATUS_UNFILTERED;
1739 UINT row = 0, len;
1740 char *buf;
1742 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1744 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1745 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
1746 GetSystemFirmwareTable( RSMB, 0, buf, len );
1748 rec = (struct record_computersystemproduct *)table->data;
1749 rec->identifyingnumber = get_compsysproduct_identifyingnumber( buf, len );
1750 rec->name = get_compsysproduct_name( buf, len );
1751 rec->skunumber = NULL;
1752 rec->uuid = get_compsysproduct_uuid( buf, len );
1753 rec->vendor = get_compsysproduct_vendor( buf, len );
1754 rec->version = get_compsysproduct_version( buf, len );
1755 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1756 else row++;
1758 free( buf );
1760 TRACE("created %u rows\n", row);
1761 table->num_rows = row;
1762 return status;
1765 struct dirstack
1767 WCHAR **dirs;
1768 UINT *len_dirs;
1769 UINT num_dirs;
1770 UINT num_allocated;
1773 static struct dirstack *alloc_dirstack( UINT size )
1775 struct dirstack *dirstack;
1777 if (!(dirstack = malloc( sizeof(*dirstack) ))) return NULL;
1778 if (!(dirstack->dirs = malloc( sizeof(WCHAR *) * size )))
1780 free( dirstack );
1781 return NULL;
1783 if (!(dirstack->len_dirs = malloc( sizeof(UINT) * size )))
1785 free( dirstack->dirs );
1786 free( dirstack );
1787 return NULL;
1789 dirstack->num_dirs = 0;
1790 dirstack->num_allocated = size;
1791 return dirstack;
1794 static void clear_dirstack( struct dirstack *dirstack )
1796 UINT i;
1797 for (i = 0; i < dirstack->num_dirs; i++) free( dirstack->dirs[i] );
1798 dirstack->num_dirs = 0;
1801 static void free_dirstack( struct dirstack *dirstack )
1803 clear_dirstack( dirstack );
1804 free( dirstack->dirs );
1805 free( dirstack->len_dirs );
1806 free( dirstack );
1809 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1811 UINT size, i = dirstack->num_dirs;
1813 if (!dir) return FALSE;
1815 if (i == dirstack->num_allocated)
1817 WCHAR **tmp;
1818 UINT *len_tmp;
1820 size = dirstack->num_allocated * 2;
1821 if (!(tmp = realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1822 dirstack->dirs = tmp;
1823 if (!(len_tmp = realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1824 dirstack->len_dirs = len_tmp;
1825 dirstack->num_allocated = size;
1827 dirstack->dirs[i] = dir;
1828 dirstack->len_dirs[i] = len;
1829 dirstack->num_dirs++;
1830 return TRUE;
1833 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1835 if (!dirstack->num_dirs)
1837 *len = 0;
1838 return NULL;
1840 dirstack->num_dirs--;
1841 *len = dirstack->len_dirs[dirstack->num_dirs];
1842 return dirstack->dirs[dirstack->num_dirs];
1845 static const WCHAR *peek_dir( struct dirstack *dirstack )
1847 if (!dirstack->num_dirs) return NULL;
1848 return dirstack->dirs[dirstack->num_dirs - 1];
1851 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1853 UINT i = 0;
1854 WCHAR *ret;
1856 if (!(ret = malloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1857 ret[i++] = drive;
1858 ret[i++] = ':';
1859 ret[i++] = '\\';
1860 if (path && len)
1862 memcpy( ret + i, path, len * sizeof(WCHAR) );
1863 i += len;
1864 ret[i++] = '\\';
1866 ret[i++] = '*';
1867 ret[i] = 0;
1868 return ret;
1871 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1873 UINT i = 0, len = 0;
1874 const WCHAR *p;
1875 WCHAR *ret;
1877 for (p = path; *p; p++)
1879 if (*p == '\\') len += 2;
1880 else len++;
1882 if (!(ret = malloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1883 ret[i++] = drive;
1884 ret[i++] = ':';
1885 ret[i++] = '\\';
1886 ret[i++] = '\\';
1887 for (p = path; *p; p++)
1889 if (*p != '\\') ret[i++] = *p;
1890 else
1892 ret[i++] = '\\';
1893 ret[i++] = '\\';
1896 ret[i] = 0;
1897 return ret;
1900 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1902 const WCHAR *p = path, *start;
1903 UINT len, i;
1904 WCHAR *ret;
1906 if (!iswalpha( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1907 start = path + 4;
1908 len = lstrlenW( start );
1909 p = start + len - 1;
1910 if (*p == '\\') return NULL;
1912 while (p >= start && *p != '\\') { len--; p--; };
1913 while (p >= start && *p == '\\') { len--; p--; };
1915 if (!(ret = malloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1916 for (i = 0, p = start; p < start + len; p++)
1918 if (p[0] == '\\' && p[1] == '\\')
1920 ret[i++] = '\\';
1921 p++;
1923 else ret[i++] = *p;
1925 ret[i] = 0;
1926 *ret_len = i;
1927 return ret;
1930 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1932 UINT i;
1933 for (i = 0; i < dirstack->num_dirs; i++) if (!wcscmp( dirstack->dirs[i], path )) return TRUE;
1934 return FALSE;
1937 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1938 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1940 const struct expr *left, *right;
1942 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1944 left = cond->u.expr.left;
1945 right = cond->u.expr.right;
1946 if (cond->u.expr.op == OP_EQ)
1948 UINT len;
1949 WCHAR *path;
1950 const WCHAR *str = NULL;
1952 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1953 !wcscmp( left->u.propval->name, L"Name" ) &&
1954 towupper( right->u.sval[0] ) == towupper( root ))
1956 str = right->u.sval;
1958 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1959 !wcscmp( right->u.propval->name, L"Name" ) &&
1960 towupper( left->u.sval[0] ) == towupper( root ))
1962 str = left->u.sval;
1964 if (str && (path = build_dirname( str, &len )))
1966 if (seen_dir( dirstack, path ))
1968 free( path );
1969 return ++*count;
1971 else if (push_dir( dirstack, path, len )) return ++*count;
1972 free( path );
1973 return *count = 0;
1976 else if (cond->u.expr.op == OP_OR)
1978 UINT left_count = 0, right_count = 0;
1980 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
1981 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
1982 return *count += left_count + right_count;
1984 return *count = 0;
1987 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
1989 UINT len_path = 0, len_segment = lstrlenW( segment );
1990 WCHAR *ret;
1992 *len = 0;
1993 if (path) len_path = lstrlenW( path );
1994 if (!(ret = malloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
1995 if (path && len_path)
1997 memcpy( ret, path, len_path * sizeof(WCHAR) );
1998 ret[len_path] = '\\';
1999 *len += len_path + 1;
2001 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
2002 *len += len_segment;
2003 ret[*len] = 0;
2004 return ret;
2007 static WCHAR *get_file_version( const WCHAR *filename )
2009 VS_FIXEDFILEINFO *info;
2010 UINT size;
2011 DWORD len = 4 * 5 + ARRAY_SIZE( L"%u.%u.%u.%u" );
2012 void *block;
2013 WCHAR *ret;
2015 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
2016 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = malloc( size )))
2018 free( ret );
2019 return NULL;
2021 if (!GetFileVersionInfoW( filename, 0, size, block ) ||
2022 !VerQueryValueW( block, L"\\", (void **)&info, &size ))
2024 free( block );
2025 free( ret );
2026 return NULL;
2028 swprintf( ret, len, L"%u.%u.%u.%u", info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
2029 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
2030 free( block );
2031 return ret;
2034 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
2036 struct record_datafile *rec;
2037 UINT i, len, row = 0, offset = 0, num_expected_rows;
2038 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
2039 DWORD drives = GetLogicalDrives();
2040 WIN32_FIND_DATAW data;
2041 HANDLE handle;
2042 struct dirstack *dirstack;
2043 enum fill_status status = FILL_STATUS_UNFILTERED;
2045 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
2047 dirstack = alloc_dirstack(2);
2049 for (i = 0; i < 26; i++)
2051 if (!(drives & (1 << i))) continue;
2053 root[0] = 'A' + i;
2054 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
2056 num_expected_rows = 0;
2057 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
2059 for (;;)
2061 free( glob );
2062 free( path );
2063 path = pop_dir( dirstack, &len );
2064 if (!(glob = build_glob( root[0], path, len )))
2066 status = FILL_STATUS_FAILED;
2067 goto done;
2069 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
2073 if (!resize_table( table, row + 1, sizeof(*rec) ))
2075 status = FILL_STATUS_FAILED;
2076 FindClose( handle );
2077 goto done;
2079 if (!wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." )) continue;
2081 if (!(new_path = append_path( path, data.cFileName, &len )))
2083 status = FILL_STATUS_FAILED;
2084 FindClose( handle );
2085 goto done;
2088 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2090 if (push_dir( dirstack, new_path, len )) continue;
2091 free( new_path );
2092 FindClose( handle );
2093 status = FILL_STATUS_FAILED;
2094 goto done;
2096 rec = (struct record_datafile *)(table->data + offset);
2097 rec->name = build_name( root[0], new_path );
2098 rec->version = get_file_version( rec->name );
2099 free( new_path );
2100 if (!match_row( table, row, cond, &status ))
2102 free_row_values( table, row );
2103 continue;
2105 else if (num_expected_rows && row == num_expected_rows - 1)
2107 row++;
2108 FindClose( handle );
2109 status = FILL_STATUS_FILTERED;
2110 goto done;
2112 offset += sizeof(*rec);
2113 row++;
2115 while (FindNextFileW( handle, &data ));
2116 FindClose( handle );
2118 if (!peek_dir( dirstack )) break;
2122 done:
2123 free_dirstack( dirstack );
2124 free( glob );
2125 free( path );
2127 TRACE("created %u rows\n", row);
2128 table->num_rows = row;
2129 return status;
2132 static UINT32 get_pixelsperxlogicalinch(void)
2134 HDC hdc = GetDC( NULL );
2135 UINT32 ret;
2137 if (!hdc) return 96;
2138 ret = GetDeviceCaps( hdc, LOGPIXELSX );
2139 ReleaseDC( NULL, hdc );
2140 return ret;
2143 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
2145 struct record_desktopmonitor *rec;
2146 enum fill_status status = FILL_STATUS_UNFILTERED;
2147 UINT row = 0;
2149 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2151 rec = (struct record_desktopmonitor *)table->data;
2152 rec->name = L"Generic Non-PnP Monitor";
2153 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
2155 if (match_row( table, row, cond, &status )) row++;
2157 TRACE("created %u rows\n", row);
2158 table->num_rows = row;
2159 return status;
2162 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
2164 struct record_directory *rec;
2165 UINT i, len, row = 0, offset = 0, num_expected_rows;
2166 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
2167 DWORD drives = GetLogicalDrives();
2168 WIN32_FIND_DATAW data;
2169 HANDLE handle;
2170 struct dirstack *dirstack;
2171 enum fill_status status = FILL_STATUS_UNFILTERED;
2173 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2175 dirstack = alloc_dirstack(2);
2177 for (i = 0; i < 26; i++)
2179 if (!(drives & (1 << i))) continue;
2181 root[0] = 'A' + i;
2182 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
2184 num_expected_rows = 0;
2185 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
2187 for (;;)
2189 free( glob );
2190 free( path );
2191 path = pop_dir( dirstack, &len );
2192 if (!(glob = build_glob( root[0], path, len )))
2194 status = FILL_STATUS_FAILED;
2195 goto done;
2197 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
2201 if (!resize_table( table, row + 1, sizeof(*rec) ))
2203 FindClose( handle );
2204 status = FILL_STATUS_FAILED;
2205 goto done;
2207 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
2208 !wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." ))
2209 continue;
2211 if (!(new_path = append_path( path, data.cFileName, &len )))
2213 FindClose( handle );
2214 status = FILL_STATUS_FAILED;
2215 goto done;
2218 if (!(push_dir( dirstack, new_path, len )))
2220 free( new_path );
2221 FindClose( handle );
2222 status = FILL_STATUS_FAILED;
2223 goto done;
2225 rec = (struct record_directory *)(table->data + offset);
2226 rec->accessmask = FILE_ALL_ACCESS;
2227 rec->name = build_name( root[0], new_path );
2228 free( new_path );
2229 if (!match_row( table, row, cond, &status ))
2231 free_row_values( table, row );
2232 continue;
2234 else if (num_expected_rows && row == num_expected_rows - 1)
2236 row++;
2237 FindClose( handle );
2238 status = FILL_STATUS_FILTERED;
2239 goto done;
2241 offset += sizeof(*rec);
2242 row++;
2244 while (FindNextFileW( handle, &data ));
2245 FindClose( handle );
2247 if (!peek_dir( dirstack )) break;
2251 done:
2252 free_dirstack( dirstack );
2253 free( glob );
2254 free( path );
2256 TRACE("created %u rows\n", row);
2257 table->num_rows = row;
2258 return status;
2261 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
2263 WCHAR root[] = L"\\\\.\\A:";
2264 ULARGE_INTEGER free;
2265 DISK_GEOMETRY_EX info;
2266 HANDLE handle;
2267 DWORD bytes_returned;
2269 free.QuadPart = 512 * 1024 * 1024;
2270 GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
2272 root[4] = dir[0];
2273 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2274 if (handle != INVALID_HANDLE_VALUE)
2276 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
2277 *disksize = info.DiskSize.QuadPart;
2278 CloseHandle( handle );
2280 return free.QuadPart;
2282 static WCHAR *get_diskdrive_serialnumber( WCHAR letter )
2284 WCHAR *ret = NULL;
2285 STORAGE_DEVICE_DESCRIPTOR *desc;
2286 HANDLE handle = INVALID_HANDLE_VALUE;
2287 STORAGE_PROPERTY_QUERY query = {0};
2288 WCHAR drive[7];
2289 DWORD size;
2291 swprintf( drive, ARRAY_SIZE(drive), L"\\\\.\\%c:", letter );
2292 handle = CreateFileW( drive, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2293 if (handle == INVALID_HANDLE_VALUE) goto done;
2295 query.PropertyId = StorageDeviceProperty;
2296 query.QueryType = PropertyStandardQuery;
2298 size = sizeof(*desc) + 256;
2299 for (;;)
2301 if (!(desc = malloc( size ))) break;
2302 if (DeviceIoControl( handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), desc, size, NULL, NULL ))
2304 if (desc->SerialNumberOffset) ret = heap_strdupAW( (const char *)desc + desc->SerialNumberOffset );
2305 free( desc );
2306 break;
2308 size = desc->Size;
2309 free( desc );
2310 if (GetLastError() != ERROR_MORE_DATA) break;
2313 done:
2314 if (handle != INVALID_HANDLE_VALUE) CloseHandle( handle );
2315 if (!ret) ret = wcsdup( L"WINEHDISK" );
2316 return ret;
2319 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
2321 static const WCHAR fmtW[] = L"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2322 WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = L"A:\\";
2323 struct record_diskdrive *rec;
2324 UINT i, row = 0, offset = 0, index = 0, type;
2325 UINT64 size = 1024 * 1024 * 1024;
2326 DWORD drives = GetLogicalDrives();
2327 enum fill_status status = FILL_STATUS_UNFILTERED;
2329 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
2331 for (i = 0; i < 26; i++)
2333 if (drives & (1 << i))
2335 root[0] = 'A' + i;
2336 type = GetDriveTypeW( root );
2337 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2338 continue;
2340 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2342 rec = (struct record_diskdrive *)(table->data + offset);
2343 swprintf( device_id, ARRAY_SIZE( device_id ), fmtW, index );
2344 rec->device_id = wcsdup( device_id );
2345 rec->index = index++;
2346 rec->interfacetype = L"IDE";
2347 rec->manufacturer = L"(Standard disk drives)";
2348 rec->mediatype = (type == DRIVE_FIXED) ? L"Fixed hard disk" : L"Removable media";
2349 rec->model = L"Wine Disk Drive";
2350 rec->pnpdevice_id = L"IDE\\Disk\\VEN_WINE";
2351 rec->serialnumber = get_diskdrive_serialnumber( root[0] );
2352 get_freespace( root, &size );
2353 rec->size = size;
2354 if (!match_row( table, row, cond, &status ))
2356 free_row_values( table, row );
2357 continue;
2359 offset += sizeof(*rec);
2360 row++;
2363 TRACE("created %u rows\n", row);
2364 table->num_rows = row;
2365 return status;
2368 struct association
2370 WCHAR *ref;
2371 WCHAR *ref2;
2374 static void free_associations( struct association *assoc, UINT count )
2376 UINT i;
2377 if (!assoc) return;
2378 for (i = 0; i < count; i++)
2380 free( assoc[i].ref );
2381 free( assoc[i].ref2 );
2383 free( assoc );
2386 static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
2388 struct association *ret = NULL;
2389 struct query *query, *query2 = NULL;
2390 VARIANT val;
2391 HRESULT hr;
2392 UINT i;
2394 if (!(query = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return NULL;
2395 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2, L"SELECT * FROM Win32_DiskDrive",
2396 &query->view, &query->mem )) != S_OK) goto done;
2397 if ((hr = execute_view( query->view )) != S_OK) goto done;
2399 if (!(query2 = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return FALSE;
2400 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2, L"SELECT * FROM Win32_DiskPartition",
2401 &query2->view, &query2->mem )) != S_OK) goto done;
2402 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2404 if (!(ret = calloc( query->view->result_count, sizeof(*ret) ))) goto done;
2406 for (i = 0; i < query->view->result_count; i++)
2408 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2409 if (!(ret[i].ref = wcsdup( V_BSTR(&val) ))) goto done;
2410 VariantClear( &val );
2412 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2413 if (!(ret[i].ref2 = wcsdup( V_BSTR(&val) ))) goto done;
2414 VariantClear( &val );
2417 *count = query->view->result_count;
2419 done:
2420 if (!ret) free_associations( ret, query->view->result_count );
2421 free_query( query );
2422 free_query( query2 );
2423 return ret;
2426 static enum fill_status fill_diskdrivetodiskpartition( struct table *table, const struct expr *cond )
2428 struct record_diskdrivetodiskpartition *rec;
2429 UINT i, row = 0, offset = 0, count = 0;
2430 enum fill_status status = FILL_STATUS_UNFILTERED;
2431 struct association *assoc;
2433 if (!(assoc = get_diskdrivetodiskpartition_pairs( &count ))) return FILL_STATUS_FAILED;
2434 if (!count)
2436 free_associations( assoc, count );
2437 return FILL_STATUS_UNFILTERED;
2439 if (!resize_table( table, count, sizeof(*rec) ))
2441 free_associations( assoc, count );
2442 return FILL_STATUS_FAILED;
2445 for (i = 0; i < count; i++)
2447 rec = (struct record_diskdrivetodiskpartition *)(table->data + offset);
2448 rec->antecedent = assoc[i].ref;
2449 rec->dependent = assoc[i].ref2;
2450 if (!match_row( table, row, cond, &status ))
2452 free_row_values( table, row );
2453 continue;
2455 offset += sizeof(*rec);
2456 row++;
2459 free( assoc );
2461 TRACE("created %u rows\n", row);
2462 table->num_rows = row;
2463 return status;
2466 static WCHAR *get_filesystem( const WCHAR *root )
2468 WCHAR buffer[MAX_PATH + 1];
2470 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
2471 return wcsdup( buffer );
2472 return wcsdup( L"NTFS" );
2475 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2477 WCHAR device_id[32], root[] = L"A:\\";
2478 struct record_diskpartition *rec;
2479 UINT i, row = 0, offset = 0, type, index = 0;
2480 UINT64 size = 1024 * 1024 * 1024;
2481 DWORD drives = GetLogicalDrives();
2482 enum fill_status status = FILL_STATUS_UNFILTERED;
2484 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2486 for (i = 0; i < 26; i++)
2488 if (drives & (1 << i))
2490 root[0] = 'A' + i;
2491 type = GetDriveTypeW( root );
2492 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2493 continue;
2495 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2497 rec = (struct record_diskpartition *)(table->data + offset);
2498 rec->bootable = (i == 2) ? -1 : 0;
2499 rec->bootpartition = (i == 2) ? -1 : 0;
2500 swprintf( device_id, ARRAY_SIZE( device_id ), L"Disk #%u, Partition #0", index );
2501 rec->device_id = wcsdup( device_id );
2502 rec->diskindex = index++;
2503 rec->index = 0;
2504 rec->pnpdevice_id = wcsdup( device_id );
2505 get_freespace( root, &size );
2506 rec->size = size;
2507 rec->startingoffset = 0;
2508 rec->type = get_filesystem( root );
2509 if (!match_row( table, row, cond, &status ))
2511 free_row_values( table, row );
2512 continue;
2514 offset += sizeof(*rec);
2515 row++;
2518 TRACE("created %u rows\n", row);
2519 table->num_rows = row;
2520 return status;
2523 static UINT32 get_bitsperpixel( UINT *hres, UINT *vres )
2525 HDC hdc = GetDC( NULL );
2526 UINT32 ret;
2528 if (!hdc) return 32;
2529 ret = GetDeviceCaps( hdc, BITSPIXEL );
2530 *hres = GetDeviceCaps( hdc, HORZRES );
2531 *vres = GetDeviceCaps( hdc, VERTRES );
2532 ReleaseDC( NULL, hdc );
2533 return ret;
2536 static enum fill_status fill_displaycontrollerconfig( struct table *table, const struct expr *cond )
2538 struct record_displaycontrollerconfig *rec;
2539 UINT row = 0, hres = 1024, vres = 768;
2540 enum fill_status status = FILL_STATUS_UNFILTERED;
2542 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2544 rec = (struct record_displaycontrollerconfig *)table->data;
2545 rec->bitsperpixel = get_bitsperpixel( &hres, &vres );
2546 rec->caption = L"VideoController1";
2547 rec->horizontalresolution = hres;
2548 rec->name = L"VideoController1";
2549 rec->verticalresolution = vres;
2550 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2551 else row++;
2553 TRACE("created %u rows\n", row);
2554 table->num_rows = row;
2555 return status;
2558 static WCHAR *get_ip4_string( DWORD addr )
2560 DWORD len = sizeof("ddd.ddd.ddd.ddd");
2561 WCHAR *ret;
2563 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
2564 swprintf( ret, len, L"%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2565 return ret;
2568 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2570 struct record_ip4routetable *rec;
2571 UINT i, row = 0, offset = 0;
2572 ULONG size = 0;
2573 MIB_IPFORWARDTABLE *forwards;
2574 enum fill_status status = FILL_STATUS_UNFILTERED;
2576 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2577 if (!(forwards = malloc( size ))) return FILL_STATUS_FAILED;
2578 if (GetIpForwardTable( forwards, &size, TRUE ))
2580 free( forwards );
2581 return FILL_STATUS_FAILED;
2583 if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) ))
2585 free( forwards );
2586 return FILL_STATUS_FAILED;
2589 for (i = 0; i < forwards->dwNumEntries; i++)
2591 rec = (struct record_ip4routetable *)(table->data + offset);
2593 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2594 rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2595 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2597 if (!match_row( table, row, cond, &status ))
2599 free_row_values( table, row );
2600 continue;
2602 offset += sizeof(*rec);
2603 row++;
2605 TRACE("created %u rows\n", row);
2606 table->num_rows = row;
2608 free( forwards );
2609 return status;
2612 static WCHAR *get_volumename( const WCHAR *root )
2614 WCHAR buf[MAX_PATH + 1] = {0};
2615 GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 );
2616 return wcsdup( buf );
2618 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2620 DWORD serial = 0;
2621 WCHAR buffer[9];
2623 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2624 swprintf( buffer, ARRAY_SIZE( buffer ), L"%08X", serial );
2625 return wcsdup( buffer );
2628 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2630 WCHAR device_id[3], root[] = L"A:\\";
2631 struct record_logicaldisk *rec;
2632 UINT i, row = 0, offset = 0, type;
2633 UINT64 size = 1024 * 1024 * 1024;
2634 DWORD drives = GetLogicalDrives();
2635 enum fill_status status = FILL_STATUS_UNFILTERED;
2637 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2639 for (i = 0; i < 26; i++)
2641 if (drives & (1 << i))
2643 root[0] = 'A' + i;
2644 type = GetDriveTypeW( root );
2645 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2646 continue;
2648 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2650 rec = (struct record_logicaldisk *)(table->data + offset);
2651 swprintf( device_id, ARRAY_SIZE( device_id ), L"%c:", 'A' + i );
2652 rec->caption = wcsdup( device_id );
2653 rec->device_id = wcsdup( device_id );
2654 rec->drivetype = type;
2655 rec->filesystem = get_filesystem( root );
2656 rec->freespace = get_freespace( root, &size );
2657 rec->name = wcsdup( device_id );
2658 rec->size = size;
2659 rec->volumename = get_volumename( root );
2660 rec->volumeserialnumber = get_volumeserialnumber( root );
2661 if (!match_row( table, row, cond, &status ))
2663 free_row_values( table, row );
2664 continue;
2666 offset += sizeof(*rec);
2667 row++;
2670 TRACE("created %u rows\n", row);
2671 table->num_rows = row;
2672 return status;
2675 static struct association *get_logicaldisktopartition_pairs( UINT *count )
2677 struct association *ret = NULL;
2678 struct query *query, *query2 = NULL;
2679 VARIANT val;
2680 HRESULT hr;
2681 UINT i;
2683 if (!(query = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return NULL;
2684 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2, L"SELECT * FROM Win32_DiskPartition",
2685 &query->view, &query->mem )) != S_OK) goto done;
2686 if ((hr = execute_view( query->view )) != S_OK) goto done;
2688 if (!(query2 = create_query( WBEMPROX_NAMESPACE_CIMV2 ))) return FALSE;
2689 if ((hr = parse_query( WBEMPROX_NAMESPACE_CIMV2,
2690 L"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2->view,
2691 &query2->mem )) != S_OK) goto done;
2692 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2694 if (!(ret = calloc( query->view->result_count, sizeof(*ret) ))) goto done;
2696 /* assume fixed and removable disks are enumerated in the same order as partitions */
2697 for (i = 0; i < query->view->result_count; i++)
2699 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2700 if (!(ret[i].ref = wcsdup( V_BSTR(&val) ))) goto done;
2701 VariantClear( &val );
2703 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2704 if (!(ret[i].ref2 = wcsdup( V_BSTR(&val) ))) goto done;
2705 VariantClear( &val );
2708 *count = query->view->result_count;
2710 done:
2711 if (!ret) free_associations( ret, query->view->result_count );
2712 free_query( query );
2713 free_query( query2 );
2714 return ret;
2717 static enum fill_status fill_logicaldisktopartition( struct table *table, const struct expr *cond )
2719 struct record_logicaldisktopartition *rec;
2720 UINT i, row = 0, offset = 0, count = 0;
2721 enum fill_status status = FILL_STATUS_UNFILTERED;
2722 struct association *assoc;
2724 if (!(assoc = get_logicaldisktopartition_pairs( &count ))) return FILL_STATUS_FAILED;
2725 if (!count)
2727 free_associations( assoc, count );
2728 return FILL_STATUS_UNFILTERED;
2730 if (!resize_table( table, count, sizeof(*rec) ))
2732 free_associations( assoc, count );
2733 return FILL_STATUS_FAILED;
2736 for (i = 0; i < count; i++)
2738 rec = (struct record_logicaldisktopartition *)(table->data + offset);
2739 rec->antecedent = assoc[i].ref;
2740 rec->dependent = assoc[i].ref2;
2741 if (!match_row( table, row, cond, &status ))
2743 free_row_values( table, row );
2744 continue;
2746 offset += sizeof(*rec);
2747 row++;
2750 free( assoc );
2752 TRACE("created %u rows\n", row);
2753 table->num_rows = row;
2754 return status;
2757 static UINT16 get_connection_status( IF_OPER_STATUS status )
2759 switch (status)
2761 case IfOperStatusDown:
2762 return 0; /* Disconnected */
2763 case IfOperStatusUp:
2764 return 2; /* Connected */
2765 default:
2766 ERR("unhandled status %u\n", status);
2767 break;
2769 return 0;
2771 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2773 WCHAR *ret;
2774 if (len != 6 || !(ret = malloc( 18 * sizeof(WCHAR) ))) return NULL;
2775 swprintf( ret, 18, L"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2776 return ret;
2778 static const WCHAR *get_adaptertype( DWORD type, int *id, int *physical )
2780 switch (type)
2782 case IF_TYPE_ETHERNET_CSMACD:
2783 *id = 0;
2784 *physical = -1;
2785 return L"Ethernet 802.3";
2787 case IF_TYPE_IEEE80211:
2788 *id = 9;
2789 *physical = -1;
2790 return L"Wireless";
2792 case IF_TYPE_IEEE1394:
2793 *id = 13;
2794 *physical = -1;
2795 return L"1394";
2797 case IF_TYPE_TUNNEL:
2798 *id = 15;
2799 *physical = 0;
2800 return L"Tunnel";
2802 default:
2803 *id = -1;
2804 *physical = 0;
2805 return NULL;
2809 #define GUID_SIZE 39
2810 static WCHAR *guid_to_str( const GUID *ptr )
2812 WCHAR *ret;
2813 if (!(ret = malloc( GUID_SIZE * sizeof(WCHAR) ))) return NULL;
2814 swprintf( ret, GUID_SIZE, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2815 ptr->Data1, ptr->Data2, ptr->Data3, ptr->Data4[0], ptr->Data4[1], ptr->Data4[2],
2816 ptr->Data4[3], ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] );
2817 return ret;
2820 static WCHAR *get_networkadapter_guid( const IF_LUID *luid )
2822 GUID guid;
2823 if (ConvertInterfaceLuidToGuid( luid, &guid )) return NULL;
2824 return guid_to_str( &guid );
2827 static IP_ADAPTER_ADDRESSES *get_network_adapters(void)
2829 ULONG err, size = 4096;
2830 IP_ADAPTER_ADDRESSES *tmp, *ret;
2832 if (!(ret = malloc( size ))) return NULL;
2833 err = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS, NULL, ret, &size );
2834 while (err == ERROR_BUFFER_OVERFLOW)
2836 if (!(tmp = realloc( ret, size ))) break;
2837 ret = tmp;
2838 err = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS, NULL, ret, &size );
2840 if (err == ERROR_SUCCESS) return ret;
2841 free( ret );
2842 return NULL;
2845 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2847 WCHAR device_id[11];
2848 struct record_networkadapter *rec;
2849 IP_ADAPTER_ADDRESSES *aa, *buffer;
2850 UINT row = 0, offset = 0, count = 0;
2851 int adaptertypeid, physical;
2852 UINT16 connection_status;
2853 enum fill_status status = FILL_STATUS_UNFILTERED;
2855 if (!(buffer = get_network_adapters())) return FILL_STATUS_FAILED;
2857 for (aa = buffer; aa; aa = aa->Next)
2859 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2861 if (!resize_table( table, count, sizeof(*rec) ))
2863 free( buffer );
2864 return FILL_STATUS_FAILED;
2866 for (aa = buffer; aa; aa = aa->Next)
2868 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2870 connection_status = get_connection_status( aa->OperStatus );
2872 rec = (struct record_networkadapter *)(table->data + offset);
2873 swprintf( device_id, ARRAY_SIZE( device_id ), L"%u", aa->IfIndex );
2874 rec->adaptertype = get_adaptertype( aa->IfType, &adaptertypeid, &physical );
2875 rec->adaptertypeid = adaptertypeid;
2876 rec->description = wcsdup( aa->Description );
2877 rec->device_id = wcsdup( device_id );
2878 rec->guid = get_networkadapter_guid( &aa->Luid );
2879 rec->index = aa->IfIndex;
2880 rec->interface_index = aa->IfIndex;
2881 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2882 rec->manufacturer = L"The Wine Project";
2883 rec->netconnection_id = NULL; /* FIXME Windows seems to fill this when it's connected and in use */
2884 rec->name = wcsdup( aa->FriendlyName );
2885 rec->netenabled = connection_status ? -1 : 0;
2886 rec->netconnection_status = connection_status;
2887 rec->physicaladapter = physical;
2888 rec->pnpdevice_id = L"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2889 rec->servicename = wcsdup( aa->FriendlyName );
2890 rec->speed = 1000000;
2891 if (!match_row( table, row, cond, &status ))
2893 free_row_values( table, row );
2894 continue;
2896 offset += sizeof(*rec);
2897 row++;
2899 TRACE("created %u rows\n", row);
2900 table->num_rows = row;
2902 free( buffer );
2903 return status;
2906 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2908 const SOCKET_ADDRESS *sa = &addr->Address;
2909 WCHAR buf[NI_MAXHOST];
2911 if (!addr) return NULL;
2912 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL,
2913 0, NI_NAMEREQD )) return NULL;
2914 return wcsdup( buf );
2916 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2918 IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2919 struct array *ret;
2920 ULONG buflen, i = 0, count = 0;
2921 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2923 if (!list) return NULL;
2924 for (gateway = list; gateway; gateway = gateway->Next) count++;
2926 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
2927 if (!(ptr = malloc( sizeof(*ptr) * count )))
2929 free( ret );
2930 return NULL;
2932 for (gateway = list; gateway; gateway = gateway->Next)
2934 buflen = ARRAY_SIZE( buf );
2935 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2936 NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf )))
2938 for (; i > 0; i--) free( ptr[i - 1] );
2939 free( ptr );
2940 free( ret );
2941 return NULL;
2944 ret->elem_size = sizeof(*ptr);
2945 ret->count = count;
2946 ret->ptr = ptr;
2947 return ret;
2949 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2951 IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2952 struct array *ret;
2953 ULONG buflen, i = 0, count = 0;
2954 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2956 if (!list) return NULL;
2957 for (server = list; server; server = server->Next) count++;
2959 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
2960 if (!(ptr = malloc( sizeof(*ptr) * count )))
2962 free( ret );
2963 return NULL;
2965 for (server = list; server; server = server->Next)
2967 buflen = ARRAY_SIZE( buf );
2968 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2969 NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf )))
2971 for (; i > 0; i--) free( ptr[i - 1] );
2972 free( ptr );
2973 free( ret );
2974 return NULL;
2976 if ((p = wcsrchr( ptr[i - 1], ':' ))) *p = 0;
2978 ret->elem_size = sizeof(*ptr);
2979 ret->count = count;
2980 ret->ptr = ptr;
2981 return ret;
2983 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2985 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2986 struct array *ret;
2987 ULONG buflen, i = 0, count = 0;
2988 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2990 if (!list) return NULL;
2991 for (address = list; address; address = address->Next) count++;
2993 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
2994 if (!(ptr = malloc( sizeof(*ptr) * count )))
2996 free( ret );
2997 return NULL;
2999 for (address = list; address; address = address->Next)
3001 buflen = ARRAY_SIZE( buf );
3002 if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength,
3003 NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf )))
3005 for (; i > 0; i--) free( ptr[i - 1] );
3006 free( ptr );
3007 free( ret );
3008 return NULL;
3011 ret->elem_size = sizeof(*ptr);
3012 ret->count = count;
3013 ret->ptr = ptr;
3014 return ret;
3016 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
3018 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
3019 struct array *ret;
3020 ULONG i = 0, count = 0;
3021 WCHAR **ptr;
3023 if (!list) return NULL;
3024 for (address = list; address; address = address->Next) count++;
3026 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
3027 if (!(ptr = malloc( sizeof(*ptr) * count )))
3029 free( ret );
3030 return NULL;
3032 for (address = list; address; address = address->Next)
3034 if (address->Address.lpSockaddr->sa_family == AF_INET)
3036 WCHAR buf[INET_ADDRSTRLEN];
3037 SOCKADDR_IN addr;
3038 ULONG buflen = ARRAY_SIZE( buf );
3040 memset( &addr, 0, sizeof(addr) );
3041 addr.sin_family = AF_INET;
3042 if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
3043 || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
3044 ptr[i] = NULL;
3045 else
3046 ptr[i] = wcsdup( buf );
3048 else
3050 WCHAR buf[11];
3051 swprintf( buf, ARRAY_SIZE( buf ), L"%u", address->OnLinkPrefixLength );
3052 ptr[i] = wcsdup( buf );
3054 if (!ptr[i++])
3056 for (; i > 0; i--) free( ptr[i - 1] );
3057 free( ptr );
3058 free( ret );
3059 return NULL;
3062 ret->elem_size = sizeof(*ptr);
3063 ret->count = count;
3064 ret->ptr = ptr;
3065 return ret;
3067 static WCHAR *get_settingid( UINT32 index )
3069 GUID guid;
3070 memset( &guid, 0, sizeof(guid) );
3071 guid.Data1 = index;
3072 return guid_to_str( &guid );
3075 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
3077 struct record_networkadapterconfig *rec;
3078 IP_ADAPTER_ADDRESSES *aa, *buffer;
3079 UINT row = 0, offset = 0, count = 0;
3080 enum fill_status status = FILL_STATUS_UNFILTERED;
3082 if (!(buffer = get_network_adapters())) return FILL_STATUS_FAILED;
3084 for (aa = buffer; aa; aa = aa->Next)
3086 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
3088 if (!resize_table( table, count, sizeof(*rec) ))
3090 free( buffer );
3091 return FILL_STATUS_FAILED;
3093 for (aa = buffer; aa; aa = aa->Next)
3095 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
3097 rec = (struct record_networkadapterconfig *)(table->data + offset);
3098 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress );
3099 rec->description = wcsdup( aa->Description );
3100 rec->dhcpenabled = -1;
3101 rec->dnsdomain = L"";
3102 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress );
3103 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress );
3104 rec->index = aa->IfIndex;
3105 rec->ipaddress = get_ipaddress( aa->FirstUnicastAddress );
3106 rec->ipconnectionmetric = 20;
3107 rec->ipenabled = -1;
3108 rec->ipsubnet = get_ipsubnet( aa->FirstUnicastAddress );
3109 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
3110 rec->settingid = get_settingid( rec->index );
3111 if (!match_row( table, row, cond, &status ))
3113 free_row_values( table, row );
3114 continue;
3116 offset += sizeof(*rec);
3117 row++;
3119 TRACE("created %u rows\n", row);
3120 table->num_rows = row;
3122 free( buffer );
3123 return status;
3126 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
3128 struct record_physicalmemory *rec;
3129 enum fill_status status = FILL_STATUS_UNFILTERED;
3130 UINT row = 0;
3132 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3134 rec = (struct record_physicalmemory *)table->data;
3135 rec->banklabel = L"BANK 0";
3136 rec->capacity = get_total_physical_memory();
3137 rec->caption = L"Physical Memory";
3138 rec->configuredclockspeed = 1600;
3139 rec->devicelocator = L"DIMM 0";
3140 rec->formfactor = 8; /* DIMM */
3141 rec->memorytype = 9; /* RAM */
3142 rec->partnumber = L"";
3143 rec->serial = L"";
3144 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3145 else row++;
3147 TRACE("created %u rows\n", row);
3148 table->num_rows = row;
3149 return status;
3152 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond )
3154 struct record_pnpentity *rec;
3155 enum fill_status status = FILL_STATUS_UNFILTERED;
3156 HDEVINFO device_info_set;
3157 SP_DEVINFO_DATA devinfo = {0};
3158 DWORD idx;
3160 device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT );
3162 devinfo.cbSize = sizeof(devinfo);
3164 idx = 0;
3165 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
3167 /* noop */
3170 resize_table( table, idx, sizeof(*rec) );
3171 table->num_rows = 0;
3172 rec = (struct record_pnpentity *)table->data;
3174 idx = 0;
3175 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
3177 WCHAR device_id[MAX_PATH];
3178 if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
3179 ARRAY_SIZE(device_id), NULL ))
3181 rec->device_id = wcsdup( device_id );
3182 rec->manufacturer = L"The Wine Project";
3183 rec->name = L"Wine PnP Device";
3185 table->num_rows++;
3186 if (!match_row( table, table->num_rows - 1, cond, &status ))
3188 free_row_values( table, table->num_rows - 1 );
3189 table->num_rows--;
3191 else
3192 rec++;
3196 SetupDiDestroyDeviceInfoList( device_info_set );
3198 return status;
3201 static enum fill_status fill_printer( struct table *table, const struct expr *cond )
3203 struct record_printer *rec;
3204 enum fill_status status = FILL_STATUS_UNFILTERED;
3205 PRINTER_INFO_2W *info;
3206 DWORD i, offset = 0, count = 0, size = 0;
3207 UINT num_rows = 0;
3208 WCHAR id[20];
3210 EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
3211 if (!count) return FILL_STATUS_UNFILTERED;
3213 if (!(info = malloc( size ))) return FILL_STATUS_FAILED;
3214 if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
3216 free( info );
3217 return FILL_STATUS_FAILED;
3219 if (!resize_table( table, count, sizeof(*rec) ))
3221 free( info );
3222 return FILL_STATUS_FAILED;
3225 for (i = 0; i < count; i++)
3227 rec = (struct record_printer *)(table->data + offset);
3228 rec->attributes = info[i].Attributes;
3229 swprintf( id, ARRAY_SIZE( id ), L"Printer%u", i );
3230 rec->device_id = wcsdup( id );
3231 rec->drivername = wcsdup( info[i].pDriverName );
3232 rec->horizontalresolution = info[i].pDevMode->dmPrintQuality;
3233 rec->local = -1;
3234 rec->location = wcsdup( info[i].pLocation );
3235 rec->name = wcsdup( info[i].pPrinterName );
3236 rec->network = 0;
3237 rec->portname = wcsdup( info[i].pPortName );
3238 if (!match_row( table, i, cond, &status ))
3240 free_row_values( table, i );
3241 continue;
3243 offset += sizeof(*rec);
3244 num_rows++;
3246 TRACE("created %u rows\n", num_rows);
3247 table->num_rows = num_rows;
3249 free( info );
3250 return status;
3253 static WCHAR *get_cmdline( DWORD process_id )
3255 if (process_id == GetCurrentProcessId()) return wcsdup( GetCommandLineW() );
3256 return NULL; /* FIXME handle different process case */
3259 static enum fill_status fill_process( struct table *table, const struct expr *cond )
3261 WCHAR handle[11];
3262 struct record_process *rec;
3263 PROCESSENTRY32W entry;
3264 HANDLE snap;
3265 enum fill_status status = FILL_STATUS_FAILED;
3266 UINT row = 0, offset = 0;
3268 snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
3269 if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
3271 entry.dwSize = sizeof(entry);
3272 if (!Process32FirstW( snap, &entry )) goto done;
3273 if (!resize_table( table, 8, sizeof(*rec) )) goto done;
3277 if (!resize_table( table, row + 1, sizeof(*rec) ))
3279 status = FILL_STATUS_FAILED;
3280 goto done;
3283 rec = (struct record_process *)(table->data + offset);
3284 rec->caption = wcsdup( entry.szExeFile );
3285 rec->commandline = get_cmdline( entry.th32ProcessID );
3286 rec->description = wcsdup( entry.szExeFile );
3287 swprintf( handle, ARRAY_SIZE( handle ), L"%u", entry.th32ProcessID );
3288 rec->handle = wcsdup( handle );
3289 rec->name = wcsdup( entry.szExeFile );
3290 rec->process_id = entry.th32ProcessID;
3291 rec->pprocess_id = entry.th32ParentProcessID;
3292 rec->thread_count = entry.cntThreads;
3293 rec->workingsetsize = 0;
3294 /* methods */
3295 rec->create = process_create;
3296 rec->get_owner = process_get_owner;
3297 if (!match_row( table, row, cond, &status ))
3299 free_row_values( table, row );
3300 continue;
3302 offset += sizeof(*rec);
3303 row++;
3304 } while (Process32NextW( snap, &entry ));
3306 TRACE("created %u rows\n", row);
3307 table->num_rows = row;
3309 done:
3310 CloseHandle( snap );
3311 return status;
3314 void do_cpuid( unsigned int ax, int *p )
3316 #if defined(__i386__) || defined(__x86_64__)
3317 __cpuid( p, ax );
3318 #else
3319 FIXME("\n");
3320 #endif
3323 static unsigned int get_processor_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
3325 unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
3327 model = (reg0 & (0x0f << 4)) >> 4;
3328 if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
3329 if (family)
3331 *family = family_id;
3332 if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
3334 *stepping = reg0 & 0x0f;
3335 return model;
3337 static void regs_to_str( int *regs, unsigned int len, WCHAR *buffer )
3339 unsigned int i;
3340 unsigned char *p = (unsigned char *)regs;
3342 for (i = 0; i < len; i++) { buffer[i] = *p++; }
3343 buffer[i] = 0;
3345 static void get_processor_manufacturer( WCHAR *manufacturer, UINT len )
3347 int tmp, regs[4] = {0, 0, 0, 0};
3349 do_cpuid( 0, regs );
3350 tmp = regs[2]; /* swap edx and ecx */
3351 regs[2] = regs[3];
3352 regs[3] = tmp;
3354 regs_to_str( regs + 1, min( 12, len ), manufacturer );
3356 static const WCHAR *get_osarchitecture(void)
3358 SYSTEM_INFO info;
3359 GetNativeSystemInfo( &info );
3360 if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return L"64-bit";
3361 return L"32-bit";
3363 static void get_processor_caption( WCHAR *caption, UINT len )
3365 const WCHAR *arch;
3366 WCHAR manufacturer[13];
3367 int regs[4] = {0, 0, 0, 0};
3368 unsigned int family, model, stepping;
3370 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3371 if (!wcscmp( get_osarchitecture(), L"32-bit" )) arch = L"x86";
3372 else if (!wcscmp( manufacturer, L"AuthenticAMD" )) arch = L"AMD64";
3373 else arch = L"Intel64";
3375 do_cpuid( 1, regs );
3377 model = get_processor_model( regs[0], &stepping, &family );
3378 swprintf( caption, len, L"%s Family %u Model %u Stepping %u", arch, family, model, stepping );
3380 static void get_processor_version( WCHAR *version, UINT len )
3382 int regs[4] = {0, 0, 0, 0};
3383 unsigned int model, stepping;
3385 do_cpuid( 1, regs );
3387 model = get_processor_model( regs[0], &stepping, NULL );
3388 swprintf( version, len, L"Model %u Stepping %u", model, stepping );
3390 static UINT16 get_processor_revision(void)
3392 int regs[4] = {0, 0, 0, 0};
3393 do_cpuid( 1, regs );
3394 return regs[0];
3396 static void get_processor_id( WCHAR *processor_id, UINT len )
3398 int regs[4] = {0, 0, 0, 0};
3400 do_cpuid( 1, regs );
3401 swprintf( processor_id, len, L"%08X%08X", regs[3], regs[0] );
3403 static void get_processor_name( WCHAR *name )
3405 int regs[4] = {0, 0, 0, 0};
3406 int i;
3408 do_cpuid( 0x80000000, regs );
3409 if (regs[0] >= 0x80000004)
3411 do_cpuid( 0x80000002, regs );
3412 regs_to_str( regs, 16, name );
3413 do_cpuid( 0x80000003, regs );
3414 regs_to_str( regs, 16, name + 16 );
3415 do_cpuid( 0x80000004, regs );
3416 regs_to_str( regs, 16, name + 32 );
3418 for (i = lstrlenW(name) - 1; i >= 0 && name[i] == ' '; i--) name[i] = 0;
3420 static UINT get_processor_currentclockspeed( UINT index )
3422 PROCESSOR_POWER_INFORMATION *info;
3423 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3424 NTSTATUS status;
3426 if ((info = malloc( size )))
3428 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3429 if (!status) ret = info[index].CurrentMhz;
3430 free( info );
3432 return ret;
3434 static UINT get_processor_maxclockspeed( 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].MaxMhz;
3444 free( info );
3446 return ret;
3449 static enum fill_status fill_processor( struct table *table, const struct expr *cond )
3451 WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
3452 struct record_processor *rec;
3453 UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
3454 enum fill_status status = FILL_STATUS_UNFILTERED;
3456 num_logical = get_logical_processor_count( &num_physical, &num_packages );
3458 if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
3460 get_processor_caption( caption, ARRAY_SIZE( caption ) );
3461 get_processor_id( processor_id, ARRAY_SIZE( processor_id ) );
3462 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3463 get_processor_name( name );
3464 get_processor_version( version, ARRAY_SIZE( version ) );
3466 for (i = 0; i < num_packages; i++)
3468 rec = (struct record_processor *)(table->data + offset);
3469 rec->addresswidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3470 rec->architecture = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 0 : 9;
3471 rec->caption = wcsdup( caption );
3472 rec->cpu_status = 1; /* CPU Enabled */
3473 rec->currentclockspeed = get_processor_currentclockspeed( i );
3474 rec->datawidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3475 rec->description = wcsdup( caption );
3476 swprintf( device_id, ARRAY_SIZE( device_id ), L"CPU%u", i );
3477 rec->device_id = wcsdup( device_id );
3478 rec->family = 2; /* Unknown */
3479 rec->level = 15;
3480 rec->manufacturer = wcsdup( manufacturer );
3481 rec->maxclockspeed = get_processor_maxclockspeed( i );
3482 rec->name = wcsdup( name );
3483 rec->num_cores = num_physical / num_packages;
3484 rec->num_logical_processors = num_logical / num_packages;
3485 rec->processor_id = wcsdup( processor_id );
3486 rec->processortype = 3; /* central processor */
3487 rec->revision = get_processor_revision();
3488 rec->unique_id = NULL;
3489 rec->version = wcsdup( version );
3490 if (!match_row( table, i, cond, &status ))
3492 free_row_values( table, i );
3493 continue;
3495 offset += sizeof(*rec);
3496 num_rows++;
3499 TRACE("created %u rows\n", num_rows);
3500 table->num_rows = num_rows;
3501 return status;
3504 static INT16 get_currenttimezone(void)
3506 TIME_ZONE_INFORMATION info;
3507 DWORD status = GetTimeZoneInformation( &info );
3508 if (status == TIME_ZONE_ID_INVALID) return 0;
3509 if (status == TIME_ZONE_ID_DAYLIGHT) return -(info.Bias + info.DaylightBias);
3510 return -(info.Bias + info.StandardBias);
3513 static WCHAR *get_lastbootuptime(void)
3515 SYSTEM_TIMEOFDAY_INFORMATION ti;
3516 TIME_FIELDS tf;
3517 WCHAR *ret;
3519 if (!(ret = malloc( 26 * sizeof(WCHAR) ))) return NULL;
3521 NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
3522 RtlTimeToTimeFields( &ti.BootTime, &tf );
3523 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u+000", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute,
3524 tf.Second, tf.Milliseconds * 1000 );
3525 return ret;
3527 static WCHAR *get_localdatetime(void)
3529 TIME_ZONE_INFORMATION tzi;
3530 SYSTEMTIME st;
3531 WCHAR *ret;
3532 DWORD Status;
3533 LONG Bias;
3535 Status = GetTimeZoneInformation(&tzi);
3537 if(Status == TIME_ZONE_ID_INVALID) return NULL;
3538 Bias = tzi.Bias;
3539 if(Status == TIME_ZONE_ID_DAYLIGHT)
3540 Bias+= tzi.DaylightBias;
3541 else
3542 Bias+= tzi.StandardBias;
3543 if (!(ret = malloc( 26 * sizeof(WCHAR) ))) return NULL;
3545 GetLocalTime(&st);
3546 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u%+03d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
3547 st.wSecond, st.wMilliseconds * 1000, -Bias );
3548 return ret;
3550 static WCHAR *get_systemdirectory(void)
3552 void *redir;
3553 WCHAR *ret;
3555 if (!(ret = malloc( MAX_PATH * sizeof(WCHAR) ))) return NULL;
3556 Wow64DisableWow64FsRedirection( &redir );
3557 GetSystemDirectoryW( ret, MAX_PATH );
3558 Wow64RevertWow64FsRedirection( redir );
3559 return ret;
3561 static WCHAR *get_systemdrive(void)
3563 WCHAR *ret = malloc( 3 * sizeof(WCHAR) ); /* "c:" */
3564 if (ret && GetEnvironmentVariableW( L"SystemDrive", ret, 3 )) return ret;
3565 free( ret );
3566 return NULL;
3568 static WCHAR *get_codeset(void)
3570 WCHAR *ret = malloc( 11 * sizeof(WCHAR) );
3571 if (ret) swprintf( ret, 11, L"%u", GetACP() );
3572 return ret;
3574 static WCHAR *get_countrycode(void)
3576 WCHAR *ret = malloc( 6 * sizeof(WCHAR) );
3577 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 );
3578 return ret;
3580 static WCHAR *get_locale(void)
3582 WCHAR *ret = malloc( 5 * sizeof(WCHAR) );
3583 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 );
3584 return ret;
3587 static WCHAR *get_reg_str( HKEY root, const WCHAR *path, const WCHAR *value )
3589 HKEY hkey = 0;
3590 DWORD size, type;
3591 WCHAR *ret = NULL;
3593 if (!RegOpenKeyExW( root, path, 0, KEY_READ, &hkey ) &&
3594 !RegQueryValueExW( hkey, value, NULL, &type, NULL, &size ) && type == REG_SZ &&
3595 (ret = malloc( size + sizeof(WCHAR) )))
3597 size += sizeof(WCHAR);
3598 if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)ret, &size ))
3600 free( ret );
3601 ret = NULL;
3604 if (hkey) RegCloseKey( hkey );
3605 return ret;
3608 static WCHAR *get_organization(void)
3610 return get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion",
3611 L"RegisteredOrganization" );
3614 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
3616 WCHAR *ret = malloc( 11 * sizeof(WCHAR) );
3617 if (ret) swprintf( ret, 11, L"%u", ver->dwBuildNumber );
3618 return ret;
3621 static WCHAR *get_osbuildtype(void)
3623 return get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", L"CurrentType" );
3626 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
3628 static const WCHAR windowsW[] = L"Microsoft Windows ";
3629 static const WCHAR win2000W[] = L"2000 Professional";
3630 static const WCHAR win2003W[] = L"Server 2003 Standard Edition";
3631 static const WCHAR winxpW[] = L"XP Professional";
3632 static const WCHAR winxp64W[] = L"XP Professional x64 Edition";
3633 static const WCHAR vistaW[] = L"Vista Ultimate";
3634 static const WCHAR win2008W[] = L"Server 2008 Standard";
3635 static const WCHAR win7W[] = L"7 Professional";
3636 static const WCHAR win2008r2W[] = L"Server 2008 R2 Standard";
3637 static const WCHAR win8W[] = L"8 Pro";
3638 static const WCHAR win81W[] = L"8.1 Pro";
3639 static const WCHAR win10W[] = L"10 Pro";
3640 static const WCHAR win11W[] = L"11 Pro";
3641 int len = ARRAY_SIZE( windowsW ) - 1;
3642 WCHAR *ret;
3644 if (!(ret = malloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL;
3645 memcpy( ret, windowsW, sizeof(windowsW) );
3646 if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0)
3648 if (ver->dwBuildNumber >= 22000) memcpy( ret + len, win11W, sizeof(win11W) );
3649 else memcpy( ret + len, win10W, sizeof(win10W) );
3651 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win81W, sizeof(win81W) );
3652 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win8W, sizeof(win8W) );
3653 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1)
3655 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) );
3656 else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) );
3658 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0)
3660 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) );
3661 else memcpy( ret + len, win2008W, sizeof(win2008W) );
3663 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2)
3665 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) );
3666 else memcpy( ret + len, win2003W, sizeof(win2003W) );
3668 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) );
3669 else memcpy( ret + len, win2000W, sizeof(win2000W) );
3670 return ret;
3673 static WCHAR *get_osname( const WCHAR *caption )
3675 static const WCHAR partitionW[] = L"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3676 int len = lstrlenW( caption );
3677 WCHAR *ret;
3679 if (!(ret = malloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
3680 memcpy( ret, caption, len * sizeof(WCHAR) );
3681 memcpy( ret + len, partitionW, sizeof(partitionW) );
3682 return ret;
3685 static WCHAR *get_osserialnumber(void)
3687 WCHAR *ret = get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", L"ProductId" );
3688 if (!ret) ret = wcsdup( L"12345-OEM-1234567-12345" );
3689 return ret;
3692 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
3694 WCHAR *ret = malloc( 33 * sizeof(WCHAR) );
3695 if (ret) swprintf( ret, 33, L"%u.%u.%u", ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
3696 return ret;
3699 static DWORD get_operatingsystemsku(void)
3701 DWORD ret = PRODUCT_UNDEFINED;
3702 GetProductInfo( 6, 0, 0, 0, &ret );
3703 return ret;
3706 static WCHAR *get_registereduser(void)
3708 return get_reg_str( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", L"RegisteredOwner" );
3711 static WCHAR *get_windowsdirectory(void)
3713 WCHAR dir[MAX_PATH];
3714 if (!GetWindowsDirectoryW( dir, ARRAY_SIZE(dir) )) return NULL;
3715 return wcsdup( dir );
3718 static WCHAR *get_osinstalldate(void)
3720 HANDLE handle = CreateFileW( L"c:\\", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
3721 FILE_FLAG_BACKUP_SEMANTICS, NULL );
3722 if (handle != INVALID_HANDLE_VALUE)
3724 FILETIME ft = { 0 };
3725 WCHAR *ret;
3727 GetFileTime( handle, &ft, NULL, NULL );
3728 CloseHandle( handle );
3729 if ((ret = malloc( 26 * sizeof(WCHAR) )))
3731 SYSTEMTIME st = { 0 };
3732 FileTimeToSystemTime( &ft, &st );
3733 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u+000", st.wYear, st.wMonth, st.wDay, st.wHour,
3734 st.wMinute, st.wSecond, st.wMilliseconds * 1000 );
3735 return ret;
3738 return wcsdup( L"20230101000000.000000+000" );
3741 static enum fill_status fill_operatingsystem( struct table *table, const struct expr *cond )
3743 struct record_operatingsystem *rec;
3744 enum fill_status status = FILL_STATUS_UNFILTERED;
3745 RTL_OSVERSIONINFOEXW ver;
3746 UINT row = 0;
3748 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3750 ver.dwOSVersionInfoSize = sizeof(ver);
3751 RtlGetVersion( &ver );
3753 rec = (struct record_operatingsystem *)table->data;
3754 rec->bootdevice = L"\\Device\\HarddiskVolume1";
3755 rec->buildnumber = get_osbuildnumber( &ver );
3756 rec->buildtype = get_osbuildtype();
3757 rec->caption = get_oscaption( &ver );
3758 rec->codeset = get_codeset();
3759 rec->countrycode = get_countrycode();
3760 rec->csdversion = ver.szCSDVersion[0] ? wcsdup( ver.szCSDVersion ) : NULL;
3761 rec->csname = get_computername();
3762 rec->currenttimezone = get_currenttimezone();
3763 rec->freephysicalmemory = get_available_physical_memory() / 1024;
3764 rec->freevirtualmemory = get_available_virtual_memory() / 1024;
3765 rec->installdate = get_osinstalldate();
3766 rec->lastbootuptime = get_lastbootuptime();
3767 rec->localdatetime = get_localdatetime();
3768 rec->locale = get_locale();
3769 rec->manufacturer = L"The Wine Project";
3770 rec->name = get_osname( rec->caption );
3771 rec->operatingsystemsku = get_operatingsystemsku();
3772 rec->organization = get_organization();
3773 rec->osarchitecture = get_osarchitecture();
3774 rec->oslanguage = GetSystemDefaultLangID();
3775 rec->osproductsuite = 2461140; /* Windows XP Professional */
3776 rec->ostype = 18; /* WINNT */
3777 rec->primary = -1;
3778 rec->producttype = 1;
3779 rec->registereduser = get_registereduser();
3780 rec->serialnumber = get_osserialnumber();
3781 rec->servicepackmajor = ver.wServicePackMajor;
3782 rec->servicepackminor = ver.wServicePackMinor;
3783 rec->status = L"OK";
3784 rec->suitemask = 272; /* Single User + Terminal */
3785 rec->systemdirectory = get_systemdirectory();
3786 rec->systemdrive = get_systemdrive();
3787 rec->totalvirtualmemorysize = get_total_virtual_memory() / 1024;
3788 rec->totalvisiblememorysize = get_total_physical_memory() / 1024;
3789 rec->version = get_osversion( &ver );
3790 rec->windowsdirectory = get_windowsdirectory();
3791 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3792 else row++;
3794 TRACE("created %u rows\n", row);
3795 table->num_rows = row;
3796 return status;
3799 static const WCHAR *get_service_type( DWORD type )
3801 if (type & SERVICE_KERNEL_DRIVER) return L"Kernel Driver";
3802 else if (type & SERVICE_FILE_SYSTEM_DRIVER) return L"File System Driver";
3803 else if (type & SERVICE_WIN32_OWN_PROCESS) return L"Own Process";
3804 else if (type & SERVICE_WIN32_SHARE_PROCESS) return L"Share Process";
3805 else ERR( "unhandled type %#lx\n", type );
3806 return NULL;
3808 static const WCHAR *get_service_state( DWORD state )
3810 switch (state)
3812 case SERVICE_STOPPED: return L"Stopped";
3813 case SERVICE_START_PENDING: return L"Start Pending";
3814 case SERVICE_STOP_PENDING: return L"Stop Pending";
3815 case SERVICE_RUNNING: return L"Running";
3816 default:
3817 ERR( "unknown state %lu\n", state );
3818 return L"Unknown";
3821 static const WCHAR *get_service_startmode( DWORD mode )
3823 switch (mode)
3825 case SERVICE_BOOT_START: return L"Boot";
3826 case SERVICE_SYSTEM_START: return L"System";
3827 case SERVICE_AUTO_START: return L"Auto";
3828 case SERVICE_DEMAND_START: return L"Manual";
3829 case SERVICE_DISABLED: return L"Disabled";
3830 default:
3831 ERR( "unknown mode %#lx\n", mode );
3832 return L"Unknown";
3835 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
3837 QUERY_SERVICE_CONFIGW *config = NULL;
3838 SC_HANDLE service;
3839 DWORD size;
3841 if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL;
3842 QueryServiceConfigW( service, NULL, 0, &size );
3843 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
3844 if (!(config = malloc( size ))) goto done;
3845 if (QueryServiceConfigW( service, config, size, &size )) goto done;
3846 free( config );
3847 config = NULL;
3849 done:
3850 CloseServiceHandle( service );
3851 return config;
3854 static enum fill_status fill_service( struct table *table, const struct expr *cond )
3856 struct record_service *rec;
3857 SC_HANDLE manager;
3858 ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL;
3859 SERVICE_STATUS_PROCESS *status;
3860 WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
3861 DWORD len = ARRAY_SIZE( sysnameW ), needed, count;
3862 UINT i, row = 0, offset = 0, size = 256;
3863 enum fill_status fill_status = FILL_STATUS_FAILED;
3864 BOOL ret;
3866 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED;
3867 if (!(services = malloc( size ))) goto done;
3869 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3870 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3871 &count, NULL, NULL );
3872 if (!ret)
3874 if (GetLastError() != ERROR_MORE_DATA) goto done;
3875 size = needed;
3876 if (!(tmp = realloc( services, size ))) goto done;
3877 services = tmp;
3878 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3879 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3880 &count, NULL, NULL );
3881 if (!ret) goto done;
3883 if (!resize_table( table, count, sizeof(*rec) )) goto done;
3885 GetComputerNameW( sysnameW, &len );
3886 fill_status = FILL_STATUS_UNFILTERED;
3888 for (i = 0; i < count; i++)
3890 QUERY_SERVICE_CONFIGW *config;
3892 if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue;
3894 status = &services[i].ServiceStatusProcess;
3895 rec = (struct record_service *)(table->data + offset);
3896 rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0;
3897 rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0;
3898 rec->displayname = wcsdup( services[i].lpDisplayName );
3899 rec->name = wcsdup( services[i].lpServiceName );
3900 rec->process_id = status->dwProcessId;
3901 rec->servicetype = get_service_type( status->dwServiceType );
3902 rec->startmode = get_service_startmode( config->dwStartType );
3903 rec->state = get_service_state( status->dwCurrentState );
3904 rec->systemname = wcsdup( sysnameW );
3905 rec->pause_service = service_pause_service;
3906 rec->resume_service = service_resume_service;
3907 rec->start_service = service_start_service;
3908 rec->stop_service = service_stop_service;
3909 free( config );
3910 if (!match_row( table, row, cond, &fill_status ))
3912 free_row_values( table, row );
3913 continue;
3915 offset += sizeof(*rec);
3916 row++;
3919 TRACE("created %u rows\n", row);
3920 table->num_rows = row;
3922 done:
3923 CloseServiceHandle( manager );
3924 free( services );
3925 return fill_status;
3928 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
3930 if (!name || !name->Name.Buffer) return NULL;
3931 return wcsdup( name->Name.Buffer );
3933 static struct array *get_binaryrepresentation( PSID sid, UINT len )
3935 struct array *ret;
3936 UINT8 *ptr;
3938 if (!(ret = malloc( sizeof(*ret) ))) return NULL;
3939 if (!(ptr = malloc( len )))
3941 free( ret );
3942 return NULL;
3944 memcpy( ptr, sid, len );
3945 ret->elem_size = sizeof(*ptr);
3946 ret->count = len;
3947 ret->ptr = ptr;
3948 return ret;
3950 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
3952 if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL;
3953 return wcsdup( domain->Domains->Name.Buffer );
3955 static const WCHAR *find_sid_str( const struct expr *cond )
3957 const struct expr *left, *right;
3958 const WCHAR *ret = NULL;
3960 if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL;
3962 left = cond->u.expr.left;
3963 right = cond->u.expr.right;
3964 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !wcsicmp( left->u.propval->name, L"SID" ))
3966 ret = right->u.sval;
3968 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !wcsicmp( right->u.propval->name, L"SID" ))
3970 ret = left->u.sval;
3972 return ret;
3975 static enum fill_status fill_sid( struct table *table, const struct expr *cond )
3977 PSID sid;
3978 LSA_REFERENCED_DOMAIN_LIST *domain;
3979 LSA_TRANSLATED_NAME *name;
3980 LSA_HANDLE handle;
3981 LSA_OBJECT_ATTRIBUTES attrs;
3982 const WCHAR *str;
3983 struct record_sid *rec;
3984 UINT len;
3986 if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED;
3987 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3989 if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED;
3990 len = GetLengthSid( sid );
3992 memset( &attrs, 0, sizeof(attrs) );
3993 attrs.Length = sizeof(attrs);
3994 if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ))
3996 LocalFree( sid );
3997 return FILL_STATUS_FAILED;
3999 if (LsaLookupSids( handle, 1, &sid, &domain, &name ))
4001 LocalFree( sid );
4002 LsaClose( handle );
4003 return FILL_STATUS_FAILED;
4006 rec = (struct record_sid *)table->data;
4007 rec->accountname = get_accountname( name );
4008 rec->binaryrepresentation = get_binaryrepresentation( sid, len );
4009 rec->referenceddomainname = get_referenceddomainname( domain );
4010 rec->sid = wcsdup( str );
4011 rec->sidlength = len;
4013 TRACE("created 1 row\n");
4014 table->num_rows = 1;
4016 LsaFreeMemory( domain );
4017 LsaFreeMemory( name );
4018 LocalFree( sid );
4019 LsaClose( handle );
4020 return FILL_STATUS_FILTERED;
4023 static WCHAR *get_systemenclosure_manufacturer( const char *buf, UINT len )
4025 WCHAR *ret = get_smbios_string( SMBIOS_TYPE_CHASSIS, offsetof(struct smbios_chassis, vendor), buf, len );
4026 if (!ret) return wcsdup( L"Wine" );
4027 return ret;
4030 static int get_systemenclosure_lockpresent( const char *buf, UINT len )
4032 const struct smbios_header *hdr;
4033 const struct smbios_chassis *chassis;
4035 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) return 0;
4037 chassis = (const struct smbios_chassis *)hdr;
4038 return (chassis->type & 0x80) ? -1 : 0;
4041 static struct array *dup_array( const struct array *src )
4043 struct array *dst;
4044 if (!(dst = malloc( sizeof(*dst) ))) return NULL;
4045 if (!(dst->ptr = malloc( src->count * src->elem_size )))
4047 free( dst );
4048 return NULL;
4050 memcpy( dst->ptr, src->ptr, src->count * src->elem_size );
4051 dst->elem_size = src->elem_size;
4052 dst->count = src->count;
4053 return dst;
4056 static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len )
4058 const struct smbios_header *hdr;
4059 const struct smbios_chassis *chassis;
4060 struct array *ret = NULL;
4061 UINT16 *types;
4063 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) goto done;
4064 chassis = (const struct smbios_chassis *)hdr;
4066 if (!(ret = malloc( sizeof(*ret) ))) goto done;
4067 if (!(types = malloc( sizeof(*types) )))
4069 free( ret );
4070 return NULL;
4072 types[0] = chassis->type & ~0x80;
4074 ret->elem_size = sizeof(*types);
4075 ret->count = 1;
4076 ret->ptr = types;
4078 done:
4079 if (!ret) ret = dup_array( &systemenclosure_chassistypes_array );
4080 return ret;
4083 static enum fill_status fill_systemenclosure( struct table *table, const struct expr *cond )
4085 struct record_systemenclosure *rec;
4086 enum fill_status status = FILL_STATUS_UNFILTERED;
4087 UINT row = 0, len;
4088 char *buf;
4090 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4092 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
4093 if (!(buf = malloc( len ))) return FILL_STATUS_FAILED;
4094 GetSystemFirmwareTable( RSMB, 0, buf, len );
4096 rec = (struct record_systemenclosure *)table->data;
4097 rec->caption = L"System Enclosure";
4098 rec->chassistypes = get_systemenclosure_chassistypes( buf, len );
4099 rec->description = L"System Enclosure";
4100 rec->lockpresent = get_systemenclosure_lockpresent( buf, len );
4101 rec->manufacturer = get_systemenclosure_manufacturer( buf, len );
4102 rec->name = L"System Enclosure";
4103 rec->tag = L"System Enclosure 0";
4104 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4105 else row++;
4107 free( buf );
4109 TRACE("created %u rows\n", row);
4110 table->num_rows = row;
4111 return status;
4114 static WCHAR *get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
4116 static const WCHAR fmtW[] = L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
4117 UINT len = sizeof(fmtW) + 2;
4118 WCHAR *ret;
4120 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
4121 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
4122 return ret;
4125 #define HW_VENDOR_AMD 0x1002
4126 #define HW_VENDOR_NVIDIA 0x10de
4127 #define HW_VENDOR_VMWARE 0x15ad
4128 #define HW_VENDOR_INTEL 0x8086
4130 static const WCHAR *get_videocontroller_installeddriver( UINT vendorid )
4132 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
4134 if (vendorid == HW_VENDOR_AMD) return L"aticfx32.dll";
4135 else if (vendorid == HW_VENDOR_NVIDIA) return L"nvd3dum.dll";
4136 else if (vendorid == HW_VENDOR_INTEL) return L"igdudim32.dll";
4137 return L"wine.dll";
4140 static BOOL get_dxgi_adapter_desc( DXGI_ADAPTER_DESC *desc )
4142 IDXGIFactory *factory;
4143 IDXGIAdapter *adapter;
4144 HRESULT hr;
4146 memset( desc, 0, sizeof(*desc) );
4147 hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
4148 if (FAILED( hr )) return FALSE;
4150 hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
4151 if (FAILED( hr ))
4153 IDXGIFactory_Release( factory );
4154 return FALSE;
4157 hr = IDXGIAdapter_GetDesc( adapter, desc );
4158 IDXGIAdapter_Release( adapter );
4159 IDXGIFactory_Release( factory );
4160 return SUCCEEDED( hr );
4163 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
4165 struct record_videocontroller *rec;
4166 DXGI_ADAPTER_DESC desc;
4167 UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
4168 const WCHAR *name = L"VideoController1";
4169 enum fill_status status = FILL_STATUS_UNFILTERED;
4170 WCHAR mode[44];
4172 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4174 if (get_dxgi_adapter_desc( &desc ))
4176 if (desc.DedicatedVideoMemory > UINT_MAX) vidmem = 0xfff00000;
4177 else vidmem = desc.DedicatedVideoMemory;
4178 name = desc.Description;
4181 rec = (struct record_videocontroller *)table->data;
4182 rec->adapter_compatibility = L"(Standard display types)";
4183 rec->adapter_dactype = L"Integrated RAMDAC";
4184 rec->adapter_ram = vidmem;
4185 rec->availability = 3; /* Running or Full Power */
4186 rec->config_errorcode = 0; /* no error */
4187 rec->caption = wcsdup( name );
4188 rec->current_bitsperpixel = get_bitsperpixel( &hres, &vres );
4189 rec->current_horizontalres = hres;
4190 rec->current_refreshrate = 0; /* default refresh rate */
4191 rec->current_scanmode = 2; /* Unknown */
4192 rec->current_verticalres = vres;
4193 rec->description = wcsdup( name );
4194 rec->device_id = L"VideoController1";
4195 rec->driverdate = L"20230420000000.000000-000";
4196 rec->driverversion = L"31.0.14051.5006";
4197 rec->installeddriver = get_videocontroller_installeddriver( desc.VendorId );
4198 rec->name = wcsdup( name );
4199 rec->pnpdevice_id = get_videocontroller_pnpdeviceid( &desc );
4200 rec->status = L"OK";
4201 rec->videoarchitecture = 2; /* Unknown */
4202 rec->videomemorytype = 2; /* Unknown */
4203 swprintf( mode, ARRAY_SIZE( mode ), L"%u x %u x %I64u colors", hres, vres, (UINT64)1 << rec->current_bitsperpixel );
4204 rec->videomodedescription = wcsdup( mode );
4205 rec->videoprocessor = wcsdup( name );
4206 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4207 else row++;
4209 TRACE("created %u rows\n", row);
4210 table->num_rows = row;
4211 return status;
4214 static WCHAR *get_volume_driveletter( const WCHAR *volume )
4216 DWORD len = 0;
4217 WCHAR *ret;
4219 if (!GetVolumePathNamesForVolumeNameW( volume, NULL, 0, &len ) && GetLastError() != ERROR_MORE_DATA) return NULL;
4220 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
4221 if (!GetVolumePathNamesForVolumeNameW( volume, ret, len, &len ) || !wcschr( ret, ':' ))
4223 free( ret );
4224 return NULL;
4226 wcschr( ret, ':' )[1] = 0;
4227 return ret;
4230 static enum fill_status fill_volume( struct table *table, const struct expr *cond )
4232 struct record_volume *rec;
4233 enum fill_status status = FILL_STATUS_UNFILTERED;
4234 UINT row = 0, offset = 0;
4235 WCHAR path[MAX_PATH];
4236 HANDLE handle;
4238 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
4240 handle = FindFirstVolumeW( path, ARRAY_SIZE(path) );
4241 while (handle != INVALID_HANDLE_VALUE)
4243 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4245 rec = (struct record_volume *)(table->data + offset);
4246 rec->deviceid = wcsdup( path );
4247 rec->driveletter = get_volume_driveletter( path );
4249 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4250 else
4252 offset += sizeof(*rec);
4253 row++;
4256 if (!FindNextVolumeW( handle, path, ARRAY_SIZE(path) ))
4258 FindVolumeClose( handle );
4259 handle = INVALID_HANDLE_VALUE;
4263 TRACE("created %u rows\n", row);
4264 table->num_rows = row;
4265 return status;
4268 static WCHAR *get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
4270 static const WCHAR fmtW[] = L"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
4271 UINT len = sizeof(fmtW) + 2;
4272 WCHAR *ret;
4274 if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
4275 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
4276 return ret;
4279 static enum fill_status fill_sounddevice( struct table *table, const struct expr *cond )
4281 struct record_sounddevice *rec;
4282 DXGI_ADAPTER_DESC desc;
4283 UINT row = 0;
4284 enum fill_status status = FILL_STATUS_UNFILTERED;
4286 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4288 get_dxgi_adapter_desc( &desc );
4290 rec = (struct record_sounddevice *)table->data;
4291 rec->caption = L"Wine Audio Device";
4292 rec->deviceid = get_sounddevice_pnpdeviceid( &desc );
4293 rec->manufacturer = L"The Wine Project";
4294 rec->name = L"Wine Audio Device";
4295 rec->pnpdeviceid = get_sounddevice_pnpdeviceid( &desc );
4296 rec->productname = L"Wine Audio Device";
4297 rec->status = L"OK";
4298 rec->statusinfo = 3;
4299 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4300 else row++;
4302 TRACE("created %u rows\n", row);
4303 table->num_rows = row;
4304 return status;
4307 #define C(c) sizeof(c)/sizeof(c[0]), c
4308 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
4309 static struct table cimv2_builtin_classes[] =
4311 { L"__ASSOCIATORS", C(col_associator), D(data_associator) },
4312 { L"__PARAMETERS", C(col_param), D(data_param) },
4313 { L"__QUALIFIERS", C(col_qualifier), D(data_qualifier) },
4314 { L"__SystemSecurity", C(col_systemsecurity), D(data_systemsecurity) },
4315 { L"CIM_DataFile", C(col_datafile), 0, 0, NULL, fill_datafile },
4316 { L"CIM_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
4317 { L"CIM_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4318 { L"SoftwareLicensingProduct", C(col_softwarelicensingproduct), D(data_softwarelicensingproduct) },
4319 { L"StdRegProv", C(col_stdregprov), D(data_stdregprov) },
4320 { L"SystemRestore", C(col_sysrestore), D(data_sysrestore) },
4321 { L"Win32_BIOS", C(col_bios), 0, 0, NULL, fill_bios },
4322 { L"Win32_BaseBoard", C(col_baseboard), 0, 0, NULL, fill_baseboard },
4323 { L"Win32_CDROMDrive", C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
4324 { L"Win32_ComputerSystem", C(col_compsys), 0, 0, NULL, fill_compsys },
4325 { L"Win32_ComputerSystemProduct", C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct },
4326 { L"Win32_DesktopMonitor", C(col_desktopmonitor), 0, 0, NULL, fill_desktopmonitor },
4327 { L"Win32_Directory", C(col_directory), 0, 0, NULL, fill_directory },
4328 { L"Win32_DiskDrive", C(col_diskdrive), 0, 0, NULL, fill_diskdrive },
4329 { L"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition), 0, 0, NULL, fill_diskdrivetodiskpartition },
4330 { L"Win32_DiskPartition", C(col_diskpartition), 0, 0, NULL, fill_diskpartition },
4331 { L"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig), 0, 0, NULL, fill_displaycontrollerconfig },
4332 { L"Win32_IP4RouteTable", C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable },
4333 { L"Win32_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
4334 { L"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition), 0, 0, NULL, fill_logicaldisktopartition },
4335 { L"Win32_NetworkAdapter", C(col_networkadapter), 0, 0, NULL, fill_networkadapter },
4336 { L"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig },
4337 { L"Win32_OperatingSystem", C(col_operatingsystem), 0, 0, NULL, fill_operatingsystem },
4338 { L"Win32_PageFileUsage", C(col_pagefileusage), D(data_pagefileusage) },
4339 { L"Win32_PhysicalMedia", C(col_physicalmedia), D(data_physicalmedia) },
4340 { L"Win32_PhysicalMemory", C(col_physicalmemory), 0, 0, NULL, fill_physicalmemory },
4341 { L"Win32_PnPEntity", C(col_pnpentity), 0, 0, NULL, fill_pnpentity },
4342 { L"Win32_Printer", C(col_printer), 0, 0, NULL, fill_printer },
4343 { L"Win32_Process", C(col_process), 0, 0, NULL, fill_process },
4344 { L"Win32_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4345 { L"Win32_QuickFixEngineering", C(col_quickfixengineering), D(data_quickfixengineering) },
4346 { L"Win32_SID", C(col_sid), 0, 0, NULL, fill_sid },
4347 { L"Win32_Service", C(col_service), 0, 0, NULL, fill_service },
4348 { L"Win32_SoundDevice", C(col_sounddevice), 0, 0, NULL, fill_sounddevice },
4349 { L"Win32_SystemEnclosure", C(col_systemenclosure), 0, 0, NULL, fill_systemenclosure },
4350 { L"Win32_VideoController", C(col_videocontroller), 0, 0, NULL, fill_videocontroller },
4351 { L"Win32_Volume", C(col_volume), 0, 0, NULL, fill_volume },
4352 { L"Win32_WinSAT", C(col_winsat), D(data_winsat) },
4355 static struct table wmi_builtin_classes[] =
4357 { L"MSSMBios_RawSMBiosTables", C(col_rawsmbiostables), D(data_rawsmbiostables) },
4359 #undef C
4360 #undef D
4362 static const struct
4364 const WCHAR *name;
4365 struct table *classes;
4366 unsigned int table_count;
4368 builtin_namespaces[WBEMPROX_NAMESPACE_LAST] =
4370 {L"cimv2", cimv2_builtin_classes, ARRAY_SIZE(cimv2_builtin_classes)},
4371 {L"Microsoft\\Windows\\Storage", NULL, 0},
4372 {L"StandardCimv2", NULL, 0},
4373 {L"wmi", wmi_builtin_classes, ARRAY_SIZE(wmi_builtin_classes)},
4376 void init_table_list( void )
4378 static struct list tables[WBEMPROX_NAMESPACE_LAST];
4379 UINT ns, i;
4381 for (ns = 0; ns < ARRAY_SIZE(builtin_namespaces); ns++)
4383 list_init( &tables[ns] );
4384 for (i = 0; i < builtin_namespaces[ns].table_count; i++)
4385 list_add_tail( &tables[ns], &builtin_namespaces[ns].classes[i].entry );
4386 table_list[ns] = &tables[ns];
4390 enum wbm_namespace get_namespace_from_string( const WCHAR *namespace )
4392 unsigned int i;
4394 if (!wcsicmp( namespace, L"default" )) return WBEMPROX_NAMESPACE_CIMV2;
4396 for (i = 0; i < WBEMPROX_NAMESPACE_LAST; ++i)
4397 if (!wcsicmp( namespace, builtin_namespaces[i].name )) return i;
4399 return WBEMPROX_NAMESPACE_LAST;