mfreadwrite/reader: Add missing allocation check (Coverity).
[wine/zf.git] / dlls / wbemprox / builtin.c
blob3922331f650f3aa2951c062202c379f4b536e9e5
1 /*
2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
23 #include <stdarg.h>
24 #include <intrin.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winsock2.h"
31 #include "ws2tcpip.h"
32 #include "initguid.h"
33 #include "wbemcli.h"
34 #include "wbemprov.h"
35 #include "iphlpapi.h"
36 #include "netioapi.h"
37 #include "tlhelp32.h"
38 #include "d3d10.h"
39 #include "winternl.h"
40 #include "winioctl.h"
41 #include "winsvc.h"
42 #include "winver.h"
43 #include "sddl.h"
44 #include "ntsecapi.h"
45 #include "winspool.h"
46 #include "setupapi.h"
47 #include "ntddstor.h"
49 #include "wine/asm.h"
50 #include "wine/debug.h"
51 #include "wbemprox_private.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
55 /* column definitions must be kept in sync with record structures below */
56 static const struct column col_associator[] =
58 { L"AssocClass", CIM_STRING },
59 { L"Class", CIM_STRING },
60 { L"Associator", CIM_STRING }
62 static const struct column col_baseboard[] =
64 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
65 { L"Model", CIM_STRING },
66 { L"Name", CIM_STRING },
67 { L"Product", CIM_STRING|COL_FLAG_DYNAMIC },
68 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
69 { L"Tag", CIM_STRING|COL_FLAG_KEY },
70 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
72 static const struct column col_bios[] =
74 { L"CurrentLanguage", CIM_STRING },
75 { L"Description", CIM_STRING },
76 { L"EmbeddedControllerMajorVersion", CIM_UINT8 },
77 { L"EmbeddedControllerMinorVersion", CIM_UINT8 },
78 { L"IdentificationCode", CIM_STRING },
79 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
80 { L"Name", CIM_STRING },
81 { L"ReleaseDate", CIM_DATETIME|COL_FLAG_DYNAMIC },
82 { L"SerialNumber", CIM_STRING },
83 { L"SMBIOSBIOSVersion", CIM_STRING|COL_FLAG_DYNAMIC },
84 { L"SMBIOSMajorVersion", CIM_UINT16 },
85 { L"SMBIOSMinorVersion", CIM_UINT16 },
86 { L"SystemBiosMajorVersion", CIM_UINT8 },
87 { L"SystemBiosMinorVersion", CIM_UINT8 },
88 { L"Version", CIM_STRING|COL_FLAG_KEY },
90 static const struct column col_cdromdrive[] =
92 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
93 { L"Drive", CIM_STRING|COL_FLAG_DYNAMIC },
94 { L"MediaType", CIM_STRING },
95 { L"Name", CIM_STRING },
96 { L"PNPDeviceID", CIM_STRING },
98 static const struct column col_compsys[] =
100 { L"Description", CIM_STRING },
101 { L"Domain", CIM_STRING },
102 { L"DomainRole", CIM_UINT16 },
103 { L"Manufacturer", CIM_STRING },
104 { L"Model", CIM_STRING },
105 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
106 { L"NumberOfLogicalProcessors", CIM_UINT32 },
107 { L"NumberOfProcessors", CIM_UINT32 },
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"NetConnectionStatus", CIM_UINT16 },
208 { L"PhysicalAdapter", CIM_BOOLEAN },
209 { L"PNPDeviceID", CIM_STRING },
210 { L"ServiceName", CIM_STRING|COL_FLAG_DYNAMIC },
211 { L"Speed", CIM_UINT64 },
213 static const struct column col_networkadapterconfig[] =
215 { L"DefaultIPGateway", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
216 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
217 { L"DHCPEnabled", CIM_BOOLEAN },
218 { L"DNSHostName", CIM_STRING|COL_FLAG_DYNAMIC },
219 { L"DNSServerSearchOrder", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
220 { L"Index", CIM_UINT32|COL_FLAG_KEY },
221 { L"IPAddress", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
222 { L"IPConnectionMetric", CIM_UINT32 },
223 { L"IPEnabled", CIM_BOOLEAN },
224 { L"IPSubnet", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
225 { L"MACAddress", CIM_STRING|COL_FLAG_DYNAMIC },
226 { L"SettingID", CIM_STRING|COL_FLAG_DYNAMIC },
228 static const struct column col_operatingsystem[] =
230 { L"BuildNumber", CIM_STRING|COL_FLAG_DYNAMIC },
231 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
232 { L"CodeSet", CIM_STRING|COL_FLAG_DYNAMIC },
233 { L"CountryCode", CIM_STRING|COL_FLAG_DYNAMIC },
234 { L"CSDVersion", CIM_STRING|COL_FLAG_DYNAMIC },
235 { L"CSName", CIM_STRING|COL_FLAG_DYNAMIC },
236 { L"CurrentTimeZone", CIM_SINT16 },
237 { L"FreePhysicalMemory", CIM_UINT64 },
238 { L"InstallDate", CIM_DATETIME },
239 { L"LastBootUpTime", CIM_DATETIME|COL_FLAG_DYNAMIC },
240 { L"LocalDateTime", CIM_DATETIME|COL_FLAG_DYNAMIC },
241 { L"Locale", CIM_STRING|COL_FLAG_DYNAMIC },
242 { L"Manufacturer", CIM_STRING },
243 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
244 { L"OperatingSystemSKU", CIM_UINT32 },
245 { L"OSArchitecture", CIM_STRING },
246 { L"OSLanguage", CIM_UINT32 },
247 { L"OSProductSuite", CIM_UINT32 },
248 { L"OSType", CIM_UINT16 },
249 { L"Primary", CIM_BOOLEAN },
250 { L"ProductType", CIM_UINT32 },
251 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
252 { L"ServicePackMajorVersion", CIM_UINT16 },
253 { L"ServicePackMinorVersion", CIM_UINT16 },
254 { L"SuiteMask", CIM_UINT32 },
255 { L"SystemDirectory", CIM_STRING|COL_FLAG_DYNAMIC },
256 { L"SystemDrive", CIM_STRING|COL_FLAG_DYNAMIC },
257 { L"TotalVirtualMemorySize", CIM_UINT64 },
258 { L"TotalVisibleMemorySize", CIM_UINT64 },
259 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
261 static const struct column col_param[] =
263 { L"Class", CIM_STRING },
264 { L"Method", CIM_STRING },
265 { L"Direction", CIM_SINT32 },
266 { L"Parameter", CIM_STRING },
267 { L"Type", CIM_UINT32 },
268 { L"DefaultValue", CIM_UINT32 },
270 static const struct column col_physicalmedia[] =
272 { L"SerialNumber", CIM_STRING },
273 { L"Tag", CIM_STRING },
275 static const struct column col_physicalmemory[] =
277 { L"BankLabel", CIM_STRING },
278 { L"Capacity", CIM_UINT64 },
279 { L"Caption", CIM_STRING },
280 { L"ConfiguredClockSpeed", CIM_UINT32 },
281 { L"DeviceLocator", CIM_STRING },
282 { L"FormFactor", CIM_UINT16 },
283 { L"MemoryType", CIM_UINT16 },
284 { L"PartNumber", CIM_STRING },
285 { L"SerialNumber", CIM_STRING },
287 static const struct column col_pnpentity[] =
289 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC },
291 static const struct column col_printer[] =
293 { L"Attributes", CIM_UINT32 },
294 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
295 { L"DriverName", CIM_STRING|COL_FLAG_DYNAMIC },
296 { L"HorizontalResolution", CIM_UINT32 },
297 { L"Local", CIM_BOOLEAN },
298 { L"Location", CIM_STRING|COL_FLAG_DYNAMIC },
299 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
300 { L"Network", CIM_BOOLEAN },
301 { L"PortName", CIM_STRING|COL_FLAG_DYNAMIC },
303 static const struct column col_process[] =
305 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
306 { L"CommandLine", CIM_STRING|COL_FLAG_DYNAMIC },
307 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
308 { L"Handle", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
309 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
310 { L"ParentProcessID", CIM_UINT32 },
311 { L"ProcessID", CIM_UINT32 },
312 { L"ThreadCount", CIM_UINT32 },
313 { L"WorkingSetSize", CIM_UINT64 },
314 /* methods */
315 { L"GetOwner", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
317 static const struct column col_processor[] =
319 { L"AddressWidth", CIM_UINT16 },
320 { L"Architecture", CIM_UINT16 },
321 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
322 { L"CpuStatus", CIM_UINT16 },
323 { L"CurrentClockSpeed", CIM_UINT32 },
324 { L"DataWidth", CIM_UINT16 },
325 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
326 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
327 { L"Family", CIM_UINT16 },
328 { L"Level", CIM_UINT16 },
329 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
330 { L"MaxClockSpeed", CIM_UINT32 },
331 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
332 { L"NumberOfCores", CIM_UINT32 },
333 { L"NumberOfLogicalProcessors", CIM_UINT32 },
334 { L"ProcessorId", CIM_STRING|COL_FLAG_DYNAMIC },
335 { L"ProcessorType", CIM_UINT16 },
336 { L"Revision", CIM_UINT16 },
337 { L"UniqueId", CIM_STRING },
338 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
340 static const struct column col_qualifier[] =
342 { L"Class", CIM_STRING },
343 { L"Member", CIM_STRING },
344 { L"Type", CIM_UINT32 },
345 { L"Flavor", CIM_SINT32 },
346 { L"Name", CIM_STRING },
347 { L"IntegerValue", CIM_SINT32 },
348 { L"StringValue", CIM_STRING },
349 { L"BoolValue", CIM_BOOLEAN },
351 static const struct column col_quickfixengineering[] =
353 { L"Caption", CIM_STRING },
354 { L"HotFixID", CIM_STRING|COL_FLAG_KEY },
356 static const struct column col_service[] =
358 { L"AcceptPause", CIM_BOOLEAN },
359 { L"AcceptStop", CIM_BOOLEAN },
360 { L"DisplayName", CIM_STRING|COL_FLAG_DYNAMIC },
361 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
362 { L"ProcessID", CIM_UINT32 },
363 { L"ServiceType", CIM_STRING },
364 { L"StartMode", CIM_STRING },
365 { L"State", CIM_STRING },
366 { L"SystemName", CIM_STRING|COL_FLAG_DYNAMIC },
367 /* methods */
368 { L"PauseService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
369 { L"ResumeService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
370 { L"StartService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
371 { L"StopService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
373 static const struct column col_sid[] =
375 { L"AccountName", CIM_STRING|COL_FLAG_DYNAMIC },
376 { L"BinaryRepresentation", CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
377 { L"ReferencedDomainName", CIM_STRING|COL_FLAG_DYNAMIC },
378 { L"SID", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
379 { L"SidLength", CIM_UINT32 },
381 static const struct column col_sounddevice[] =
383 { L"DeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
384 { L"Manufacturer", CIM_STRING },
385 { L"Name", CIM_STRING },
386 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
387 { L"ProductName", CIM_STRING },
388 { L"Status", CIM_STRING },
389 { L"StatusInfo", CIM_UINT16 },
391 static const struct column col_stdregprov[] =
393 { L"CreateKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
394 { L"EnumKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
395 { L"EnumValues", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
396 { L"GetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
397 { L"SetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
398 { L"SetDWORDValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
399 { L"DeleteKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
401 static const struct column col_systemenclosure[] =
403 { L"Caption", CIM_STRING },
404 { L"ChassisTypes", CIM_UINT16|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
405 { L"Description", CIM_STRING },
406 { L"LockPresent", CIM_BOOLEAN },
407 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
408 { L"Name", CIM_STRING },
409 { L"Tag", CIM_STRING },
411 static const struct column col_systemsecurity[] =
413 { L"GetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
414 { L"SetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
416 static const struct column col_sysrestore[] =
418 { L"CreationTime", CIM_STRING },
419 { L"Description", CIM_STRING },
420 { L"EventType", CIM_UINT32 },
421 { L"RestorePointType", CIM_UINT32 },
422 { L"SequenceNumber", CIM_UINT32 },
423 /* methods */
424 { L"CreateRestorePoint", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
425 { L"Disable", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
426 { L"Enable", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
427 { L"GetLastRestoreStatus", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
428 { L"Restore", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
430 static const struct column col_videocontroller[] =
432 { L"AdapterCompatibility", CIM_STRING },
433 { L"AdapterDACType", CIM_STRING },
434 { L"AdapterRAM", CIM_UINT32 },
435 { L"Availability", CIM_UINT16 },
436 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
437 { L"ConfigManagerErrorCode", CIM_UINT32 },
438 { L"CurrentBitsPerPixel", CIM_UINT32 },
439 { L"CurrentHorizontalResolution", CIM_UINT32 },
440 { L"CurrentRefreshRate", CIM_UINT32 },
441 { L"CurrentScanMode", CIM_UINT16 },
442 { L"CurrentVerticalResolution", CIM_UINT32 },
443 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
444 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
445 { L"DriverDate", CIM_DATETIME },
446 { L"DriverVersion", CIM_STRING },
447 { L"InstalledDisplayDrivers", CIM_STRING },
448 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
449 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
450 { L"Status", CIM_STRING },
451 { L"VideoArchitecture", CIM_UINT16 },
452 { L"VideoMemoryType", CIM_UINT16 },
453 { L"VideoModeDescription", CIM_STRING|COL_FLAG_DYNAMIC },
454 { L"VideoProcessor", CIM_STRING|COL_FLAG_DYNAMIC },
456 static const struct column col_winsat[] =
458 { L"CPUScore", CIM_REAL32 },
459 { L"D3DScore", CIM_REAL32 },
460 { L"DiskScore", CIM_REAL32 },
461 { L"GraphicsScore", CIM_REAL32 },
462 { L"MemoryScore", CIM_REAL32 },
463 { L"TimeTaken", CIM_STRING|COL_FLAG_KEY },
464 { L"WinSATAssessmentState", CIM_UINT32 },
465 { L"WinSPRLevel", CIM_REAL32 },
468 #include "pshpack1.h"
469 struct record_associator
471 const WCHAR *assocclass;
472 const WCHAR *class;
473 const WCHAR *associator;
475 struct record_baseboard
477 const WCHAR *manufacturer;
478 const WCHAR *model;
479 const WCHAR *name;
480 const WCHAR *product;
481 const WCHAR *serialnumber;
482 const WCHAR *tag;
483 const WCHAR *version;
485 struct record_bios
487 const WCHAR *currentlanguage;
488 const WCHAR *description;
489 UINT8 ecmajorversion;
490 UINT8 ecminorversion;
491 const WCHAR *identificationcode;
492 const WCHAR *manufacturer;
493 const WCHAR *name;
494 const WCHAR *releasedate;
495 const WCHAR *serialnumber;
496 const WCHAR *smbiosbiosversion;
497 UINT16 smbiosmajorversion;
498 UINT16 smbiosminorversion;
499 UINT8 systembiosmajorversion;
500 UINT8 systembiosminorversion;
501 const WCHAR *version;
503 struct record_cdromdrive
505 const WCHAR *device_id;
506 const WCHAR *drive;
507 const WCHAR *mediatype;
508 const WCHAR *name;
509 const WCHAR *pnpdevice_id;
511 struct record_computersystem
513 const WCHAR *description;
514 const WCHAR *domain;
515 UINT16 domainrole;
516 const WCHAR *manufacturer;
517 const WCHAR *model;
518 const WCHAR *name;
519 UINT32 num_logical_processors;
520 UINT32 num_processors;
521 UINT64 total_physical_memory;
522 const WCHAR *username;
524 struct record_computersystemproduct
526 const WCHAR *identifyingnumber;
527 const WCHAR *name;
528 const WCHAR *skunumber;
529 const WCHAR *uuid;
530 const WCHAR *vendor;
531 const WCHAR *version;
533 struct record_datafile
535 const WCHAR *name;
536 const WCHAR *version;
538 struct record_desktopmonitor
540 const WCHAR *name;
541 UINT32 pixelsperxlogicalinch;
543 struct record_directory
545 UINT32 accessmask;
546 const WCHAR *name;
548 struct record_diskdrive
550 const WCHAR *device_id;
551 UINT32 index;
552 const WCHAR *interfacetype;
553 const WCHAR *manufacturer;
554 const WCHAR *mediatype;
555 const WCHAR *model;
556 const WCHAR *pnpdevice_id;
557 const WCHAR *serialnumber;
558 UINT64 size;
560 struct record_diskdrivetodiskpartition
562 const WCHAR *antecedent;
563 const WCHAR *dependent;
565 struct record_diskpartition
567 int bootable;
568 int bootpartition;
569 const WCHAR *device_id;
570 UINT32 diskindex;
571 UINT32 index;
572 const WCHAR *pnpdevice_id;
573 UINT64 size;
574 UINT64 startingoffset;
575 const WCHAR *type;
577 struct record_displaycontrollerconfig
579 UINT32 bitsperpixel;
580 const WCHAR *caption;
581 UINT32 horizontalresolution;
582 const WCHAR *name;
583 UINT32 verticalresolution;
585 struct record_ip4routetable
587 const WCHAR *destination;
588 INT32 interfaceindex;
589 const WCHAR *nexthop;
591 struct record_logicaldisk
593 const WCHAR *caption;
594 const WCHAR *device_id;
595 UINT32 drivetype;
596 const WCHAR *filesystem;
597 UINT64 freespace;
598 const WCHAR *name;
599 UINT64 size;
600 const WCHAR *volumename;
601 const WCHAR *volumeserialnumber;
603 struct record_logicaldisktopartition
605 const WCHAR *antecedent;
606 const WCHAR *dependent;
608 struct record_networkadapter
610 const WCHAR *adaptertype;
611 UINT16 adaptertypeid;
612 const WCHAR *description;
613 const WCHAR *device_id;
614 const WCHAR *guid;
615 UINT32 index;
616 UINT32 interface_index;
617 const WCHAR *mac_address;
618 const WCHAR *manufacturer;
619 const WCHAR *name;
620 UINT16 netconnection_status;
621 int physicaladapter;
622 const WCHAR *pnpdevice_id;
623 const WCHAR *servicename;
624 UINT64 speed;
626 struct record_networkadapterconfig
628 const struct array *defaultipgateway;
629 const WCHAR *description;
630 int dhcpenabled;
631 const WCHAR *dnshostname;
632 const struct array *dnsserversearchorder;
633 UINT32 index;
634 const struct array *ipaddress;
635 UINT32 ipconnectionmetric;
636 int ipenabled;
637 const struct array *ipsubnet;
638 const WCHAR *mac_address;
639 const WCHAR *settingid;
641 struct record_operatingsystem
643 const WCHAR *buildnumber;
644 const WCHAR *caption;
645 const WCHAR *codeset;
646 const WCHAR *countrycode;
647 const WCHAR *csdversion;
648 const WCHAR *csname;
649 INT16 currenttimezone;
650 UINT64 freephysicalmemory;
651 const WCHAR *installdate;
652 const WCHAR *lastbootuptime;
653 const WCHAR *localdatetime;
654 const WCHAR *locale;
655 const WCHAR *manufacturer;
656 const WCHAR *name;
657 UINT32 operatingsystemsku;
658 const WCHAR *osarchitecture;
659 UINT32 oslanguage;
660 UINT32 osproductsuite;
661 UINT16 ostype;
662 int primary;
663 UINT32 producttype;
664 const WCHAR *serialnumber;
665 UINT16 servicepackmajor;
666 UINT16 servicepackminor;
667 UINT32 suitemask;
668 const WCHAR *systemdirectory;
669 const WCHAR *systemdrive;
670 UINT64 totalvirtualmemorysize;
671 UINT64 totalvisiblememorysize;
672 const WCHAR *version;
674 struct record_param
676 const WCHAR *class;
677 const WCHAR *method;
678 INT32 direction;
679 const WCHAR *parameter;
680 UINT32 type;
681 UINT32 defaultvalue;
683 struct record_physicalmedia
685 const WCHAR *serialnumber;
686 const WCHAR *tag;
688 struct record_physicalmemory
690 const WCHAR *banklabel;
691 UINT64 capacity;
692 const WCHAR *caption;
693 UINT32 configuredclockspeed;
694 const WCHAR *devicelocator;
695 UINT16 formfactor;
696 UINT16 memorytype;
697 const WCHAR *partnumber;
698 const WCHAR *serial;
700 struct record_pnpentity
702 const WCHAR *device_id;
704 struct record_printer
706 UINT32 attributes;
707 const WCHAR *device_id;
708 const WCHAR *drivername;
709 UINT32 horizontalresolution;
710 int local;
711 const WCHAR *location;
712 const WCHAR *name;
713 int network;
714 const WCHAR *portname;
716 struct record_process
718 const WCHAR *caption;
719 const WCHAR *commandline;
720 const WCHAR *description;
721 const WCHAR *handle;
722 const WCHAR *name;
723 UINT32 pprocess_id;
724 UINT32 process_id;
725 UINT32 thread_count;
726 UINT64 workingsetsize;
727 /* methods */
728 class_method *get_owner;
730 struct record_processor
732 UINT16 addresswidth;
733 UINT16 architecture;
734 const WCHAR *caption;
735 UINT16 cpu_status;
736 UINT32 currentclockspeed;
737 UINT16 datawidth;
738 const WCHAR *description;
739 const WCHAR *device_id;
740 UINT16 family;
741 UINT16 level;
742 const WCHAR *manufacturer;
743 UINT32 maxclockspeed;
744 const WCHAR *name;
745 UINT32 num_cores;
746 UINT32 num_logical_processors;
747 const WCHAR *processor_id;
748 UINT16 processortype;
749 UINT16 revision;
750 const WCHAR *unique_id;
751 const WCHAR *version;
753 struct record_qualifier
755 const WCHAR *class;
756 const WCHAR *member;
757 UINT32 type;
758 INT32 flavor;
759 const WCHAR *name;
760 INT32 intvalue;
761 const WCHAR *strvalue;
762 int boolvalue;
764 struct record_quickfixengineering
766 const WCHAR *caption;
767 const WCHAR *hotfixid;
769 struct record_service
771 int accept_pause;
772 int accept_stop;
773 const WCHAR *displayname;
774 const WCHAR *name;
775 UINT32 process_id;
776 const WCHAR *servicetype;
777 const WCHAR *startmode;
778 const WCHAR *state;
779 const WCHAR *systemname;
780 /* methods */
781 class_method *pause_service;
782 class_method *resume_service;
783 class_method *start_service;
784 class_method *stop_service;
786 struct record_sid
788 const WCHAR *accountname;
789 const struct array *binaryrepresentation;
790 const WCHAR *referenceddomainname;
791 const WCHAR *sid;
792 UINT32 sidlength;
794 struct record_sounddevice
796 const WCHAR *deviceid;
797 const WCHAR *manufacturer;
798 const WCHAR *name;
799 const WCHAR *pnpdeviceid;
800 const WCHAR *productname;
801 const WCHAR *status;
802 UINT16 statusinfo;
804 struct record_stdregprov
806 class_method *createkey;
807 class_method *enumkey;
808 class_method *enumvalues;
809 class_method *getstringvalue;
810 class_method *setstringvalue;
811 class_method *setdwordvalue;
812 class_method *deletekey;
814 struct record_sysrestore
816 const WCHAR *creation_time;
817 const WCHAR *description;
818 UINT32 event_type;
819 UINT32 restore_point_type;
820 UINT32 sequence_number;
821 class_method *create_restore_point;
822 class_method *disable_restore;
823 class_method *enable_restore;
824 class_method *get_last_restore_status;
825 class_method *restore;
827 struct record_systemsecurity
829 class_method *getsd;
830 class_method *setsd;
832 struct record_systemenclosure
834 const WCHAR *caption;
835 const struct array *chassistypes;
836 const WCHAR *description;
837 int lockpresent;
838 const WCHAR *manufacturer;
839 const WCHAR *name;
840 const WCHAR *tag;
842 struct record_videocontroller
844 const WCHAR *adapter_compatibility;
845 const WCHAR *adapter_dactype;
846 UINT32 adapter_ram;
847 UINT16 availability;
848 const WCHAR *caption;
849 UINT32 config_errorcode;
850 UINT32 current_bitsperpixel;
851 UINT32 current_horizontalres;
852 UINT32 current_refreshrate;
853 UINT16 current_scanmode;
854 UINT32 current_verticalres;
855 const WCHAR *description;
856 const WCHAR *device_id;
857 const WCHAR *driverdate;
858 const WCHAR *driverversion;
859 const WCHAR *installeddriver;
860 const WCHAR *name;
861 const WCHAR *pnpdevice_id;
862 const WCHAR *status;
863 UINT16 videoarchitecture;
864 UINT16 videomemorytype;
865 const WCHAR *videomodedescription;
866 const WCHAR *videoprocessor;
868 struct record_winsat
870 FLOAT cpuscore;
871 FLOAT d3dscore;
872 FLOAT diskscrore;
873 FLOAT graphicsscore;
874 FLOAT memoryscore;
875 const WCHAR *timetaken;
876 UINT32 winsatassessmentstate;
877 FLOAT winsprlevel;
879 #include "poppack.h"
881 static const struct record_associator data_associator[] =
883 { L"Win32_DiskDriveToDiskPartition", L"Win32_DiskPartition", L"Win32_DiskDrive" },
884 { L"Win32_LogicalDiskToPartition", L"Win32_LogicalDisk", L"Win32_DiskPartition" },
886 static const struct record_param data_param[] =
888 { L"__SystemSecurity", L"GetSD", -1, L"ReturnValue", CIM_UINT32 },
889 { L"__SystemSecurity", L"GetSD", -1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
890 { L"__SystemSecurity", L"SetSD", 1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
891 { L"__SystemSecurity", L"SetSD", -1, L"ReturnValue", CIM_UINT32 },
892 { L"StdRegProv", L"CreateKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
893 { L"StdRegProv", L"CreateKey", 1, L"sSubKeyName", CIM_STRING },
894 { L"StdRegProv", L"CreateKey", -1, L"ReturnValue", CIM_UINT32 },
895 { L"StdRegProv", L"EnumKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
896 { L"StdRegProv", L"EnumKey", 1, L"sSubKeyName", CIM_STRING },
897 { L"StdRegProv", L"EnumKey", -1, L"ReturnValue", CIM_UINT32 },
898 { L"StdRegProv", L"EnumKey", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
899 { L"StdRegProv", L"EnumValues", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
900 { L"StdRegProv", L"EnumValues", 1, L"sSubKeyName", CIM_STRING },
901 { L"StdRegProv", L"EnumValues", -1, L"ReturnValue", CIM_UINT32 },
902 { L"StdRegProv", L"EnumValues", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
903 { L"StdRegProv", L"EnumValues", -1, L"Types", CIM_SINT32|CIM_FLAG_ARRAY },
904 { L"StdRegProv", L"GetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
905 { L"StdRegProv", L"GetStringValue", 1, L"sSubKeyName", CIM_STRING },
906 { L"StdRegProv", L"GetStringValue", 1, L"sValueName", CIM_STRING },
907 { L"StdRegProv", L"GetStringValue", -1, L"ReturnValue", CIM_UINT32 },
908 { L"StdRegProv", L"GetStringValue", -1, L"sValue", CIM_STRING },
909 { L"StdRegProv", L"SetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
910 { L"StdRegProv", L"SetStringValue", 1, L"sSubKeyName", CIM_STRING },
911 { L"StdRegProv", L"SetStringValue", 1, L"sValueName", CIM_STRING },
912 { L"StdRegProv", L"SetStringValue", 1, L"sValue", CIM_STRING },
913 { L"StdRegProv", L"SetStringValue", -1, L"ReturnValue", CIM_UINT32 },
914 { L"StdRegProv", L"SetDWORDValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
915 { L"StdRegProv", L"SetDWORDValue", 1, L"sSubKeyName", CIM_STRING },
916 { L"StdRegProv", L"SetDWORDValue", 1, L"sValueName", CIM_STRING },
917 { L"StdRegProv", L"SetDWORDValue", 1, L"uValue", CIM_UINT32 },
918 { L"StdRegProv", L"SetDWORDValue", -1, L"ReturnValue", CIM_UINT32 },
919 { L"StdRegProv", L"DeleteKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
920 { L"StdRegProv", L"DeleteKey", 1, L"sSubKeyName", CIM_STRING },
921 { L"StdRegProv", L"DeleteKey", -1, L"ReturnValue", CIM_UINT32 },
922 { L"SystemRestore", L"Disable", 1, L"Drive", CIM_STRING },
923 { L"SystemRestore", L"Disable", -1, L"ReturnValue", CIM_UINT32 },
924 { L"SystemRestore", L"Enable", 1, L"Drive", CIM_STRING },
925 { L"SystemRestore", L"Enable", -1, L"ReturnValue", CIM_UINT32 },
926 { L"Win32_Process", L"GetOwner", -1, L"ReturnValue", CIM_UINT32 },
927 { L"Win32_Process", L"GetOwner", -1, L"User", CIM_STRING },
928 { L"Win32_Process", L"GetOwner", -1, L"Domain", CIM_STRING },
929 { L"Win32_Service", L"PauseService", -1, L"ReturnValue", CIM_UINT32 },
930 { L"Win32_Service", L"ResumeService", -1, L"ReturnValue", CIM_UINT32 },
931 { L"Win32_Service", L"StartService", -1, L"ReturnValue", CIM_UINT32 },
932 { L"Win32_Service", L"StopService", -1, L"ReturnValue", CIM_UINT32 },
935 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
936 WBEM_FLAVOR_ORIGIN_PROPAGATED)
938 static const struct record_physicalmedia data_physicalmedia[] =
940 { L"WINEHDISK", L"\\\\.\\PHYSICALDRIVE0" }
942 static const struct record_qualifier data_qualifier[] =
944 { L"__WIN32_PROCESS_GETOWNER_OUT", L"User", CIM_SINT32, FLAVOR_ID, L"ID", 0 },
945 { L"__WIN32_PROCESS_GETOWNER_OUT", L"Domain", CIM_SINT32, FLAVOR_ID, L"ID", 1 }
947 static const struct record_quickfixengineering data_quickfixengineering[] =
949 { L"http://winehq.org", L"KB1234567" },
952 static const struct record_stdregprov data_stdregprov[] =
955 reg_create_key,
956 reg_enum_key,
957 reg_enum_values,
958 reg_get_stringvalue,
959 reg_set_stringvalue,
960 reg_set_dwordvalue,
961 reg_delete_key,
965 static const struct record_sysrestore data_sysrestore[] =
967 { NULL, NULL, 0, 0, 0, sysrestore_create, sysrestore_disable, sysrestore_enable, sysrestore_get_last_status,
968 sysrestore_restore }
971 static UINT16 systemenclosure_chassistypes[] =
975 static const struct array systemenclosure_chassistypes_array =
977 sizeof(*systemenclosure_chassistypes),
978 ARRAY_SIZE(systemenclosure_chassistypes),
979 &systemenclosure_chassistypes
981 static const struct record_systemsecurity data_systemsecurity[] =
983 { security_get_sd, security_set_sd }
985 static const struct record_winsat data_winsat[] =
987 { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, L"MostRecentAssessment", 1 /* Valid */, 8.0f },
990 /* check if row matches condition and update status */
991 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
993 LONGLONG val;
994 UINT type;
996 if (!cond)
998 *status = FILL_STATUS_UNFILTERED;
999 return TRUE;
1001 if (eval_cond( table, row, cond, &val, &type ) != S_OK)
1003 *status = FILL_STATUS_FAILED;
1004 return FALSE;
1006 *status = FILL_STATUS_FILTERED;
1007 return val != 0;
1010 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
1012 if (!table->num_rows_allocated)
1014 if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE;
1015 table->num_rows_allocated = row_count;
1016 return TRUE;
1018 if (row_count > table->num_rows_allocated)
1020 BYTE *data;
1021 UINT count = max( row_count, table->num_rows_allocated * 2 );
1022 if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE;
1023 table->data = data;
1024 table->num_rows_allocated = count;
1026 return TRUE;
1029 #include "pshpack1.h"
1030 struct smbios_prologue
1032 BYTE calling_method;
1033 BYTE major_version;
1034 BYTE minor_version;
1035 BYTE revision;
1036 DWORD length;
1039 enum smbios_type
1041 SMBIOS_TYPE_BIOS,
1042 SMBIOS_TYPE_SYSTEM,
1043 SMBIOS_TYPE_BASEBOARD,
1044 SMBIOS_TYPE_CHASSIS,
1047 struct smbios_header
1049 BYTE type;
1050 BYTE length;
1051 WORD handle;
1054 struct smbios_baseboard
1056 struct smbios_header hdr;
1057 BYTE vendor;
1058 BYTE product;
1059 BYTE version;
1060 BYTE serial;
1063 struct smbios_bios
1065 struct smbios_header hdr;
1066 BYTE vendor;
1067 BYTE version;
1068 WORD start;
1069 BYTE date;
1070 BYTE size;
1071 UINT64 characteristics;
1072 BYTE characteristics_ext[2];
1073 BYTE system_bios_major_release;
1074 BYTE system_bios_minor_release;
1075 BYTE ec_firmware_major_release;
1076 BYTE ec_firmware_minor_release;
1079 struct smbios_chassis
1081 struct smbios_header hdr;
1082 BYTE vendor;
1083 BYTE type;
1084 BYTE version;
1085 BYTE serial;
1086 BYTE asset_tag;
1089 struct smbios_system
1091 struct smbios_header hdr;
1092 BYTE vendor;
1093 BYTE product;
1094 BYTE version;
1095 BYTE serial;
1096 BYTE uuid[16];
1098 #include "poppack.h"
1100 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1102 static const struct smbios_header *find_smbios_entry( enum smbios_type type, const char *buf, UINT len )
1104 const char *ptr, *start;
1105 const struct smbios_prologue *prologue;
1106 const struct smbios_header *hdr;
1108 if (len < sizeof(struct smbios_prologue)) return NULL;
1109 prologue = (const struct smbios_prologue *)buf;
1110 if (prologue->length > len - sizeof(*prologue) || prologue->length < sizeof(*hdr)) return NULL;
1112 start = (const char *)(prologue + 1);
1113 hdr = (const struct smbios_header *)start;
1115 for (;;)
1117 if ((const char *)hdr - start >= prologue->length - sizeof(*hdr)) return NULL;
1119 if (!hdr->length)
1121 WARN( "invalid entry\n" );
1122 return NULL;
1125 if (hdr->type == type)
1127 if ((const char *)hdr - start + hdr->length > prologue->length) return NULL;
1128 break;
1130 else /* skip other entries and their strings */
1132 for (ptr = (const char *)hdr + hdr->length; ptr - buf < len && *ptr; ptr++)
1134 for (; ptr - buf < len; ptr++) if (!*ptr) break;
1136 if (ptr == (const char *)hdr + hdr->length) ptr++;
1137 hdr = (const struct smbios_header *)(ptr + 1);
1141 return hdr;
1144 static WCHAR *get_smbios_string( BYTE id, const char *buf, UINT offset, UINT buflen )
1146 const char *ptr = buf + offset;
1147 UINT i = 0;
1149 if (!id || offset >= buflen) return NULL;
1150 for (ptr = buf + offset; ptr - buf < buflen && *ptr; ptr++)
1152 if (++i == id) return heap_strdupAW( ptr );
1153 for (; ptr - buf < buflen; ptr++) if (!*ptr) break;
1155 return NULL;
1158 static WCHAR *get_baseboard_string( BYTE id, const char *buf, UINT len )
1160 const struct smbios_header *hdr;
1161 const struct smbios_baseboard *baseboard;
1162 UINT offset;
1164 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BASEBOARD, buf, len ))) return NULL;
1166 baseboard = (const struct smbios_baseboard *)hdr;
1167 offset = (const char *)baseboard - buf + baseboard->hdr.length;
1168 return get_smbios_string( id, buf, offset, len );
1171 static WCHAR *get_baseboard_manufacturer( const char *buf, UINT len )
1173 WCHAR *ret = get_baseboard_string( 1, buf, len );
1174 if (!ret) return heap_strdupW( L"Intel Corporation" );
1175 return ret;
1178 static WCHAR *get_baseboard_product( const char *buf, UINT len )
1180 WCHAR *ret = get_baseboard_string( 2, buf, len );
1181 if (!ret) return heap_strdupW( L"Base Board" );
1182 return ret;
1185 static WCHAR *get_baseboard_serialnumber( const char *buf, UINT len )
1187 WCHAR *ret = get_baseboard_string( 4, buf, len );
1188 if (!ret) return heap_strdupW( L"None" );
1189 return ret;
1192 static WCHAR *get_baseboard_version( const char *buf, UINT len )
1194 WCHAR *ret = get_baseboard_string( 3, buf, len );
1195 if (!ret) return heap_strdupW( L"1.0" );
1196 return ret;
1199 static enum fill_status fill_baseboard( struct table *table, const struct expr *cond )
1201 struct record_baseboard *rec;
1202 enum fill_status status = FILL_STATUS_UNFILTERED;
1203 UINT row = 0, len;
1204 char *buf;
1206 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1208 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1209 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
1210 GetSystemFirmwareTable( RSMB, 0, buf, len );
1212 rec = (struct record_baseboard *)table->data;
1213 rec->manufacturer = get_baseboard_manufacturer( buf, len );
1214 rec->model = L"Base Board";
1215 rec->name = L"Base Board";
1216 rec->product = get_baseboard_product( buf, len );
1217 rec->serialnumber = get_baseboard_serialnumber( buf, len );
1218 rec->tag = L"Base Board";
1219 rec->version = get_baseboard_version( buf, len );
1220 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1221 else row++;
1223 heap_free( buf );
1225 TRACE("created %u rows\n", row);
1226 table->num_rows = row;
1227 return status;
1230 static UINT16 get_bios_smbiosmajorversion( const char *buf, UINT len )
1232 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1233 if (len < sizeof(*prologue)) return 2;
1234 return prologue->major_version;
1237 static UINT16 get_bios_smbiosminorversion( const char *buf, UINT len )
1239 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1240 if (len < sizeof(*prologue)) return 0;
1241 return prologue->minor_version;
1244 static WCHAR *get_bios_string( BYTE id, const char *buf, UINT len )
1246 const struct smbios_header *hdr;
1247 const struct smbios_bios *bios;
1248 UINT offset;
1250 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return NULL;
1252 bios = (const struct smbios_bios *)hdr;
1253 offset = (const char *)bios - buf + bios->hdr.length;
1254 return get_smbios_string( id, buf, offset, len );
1257 static WCHAR *get_bios_manufacturer( const char *buf, UINT len )
1259 WCHAR *ret = get_bios_string( 1, buf, len );
1260 if (!ret) return heap_strdupW( L"The Wine Project" );
1261 return ret;
1264 static WCHAR *convert_bios_date( const WCHAR *str )
1266 static const WCHAR fmtW[] = L"%04u%02u%02u000000.000000+000";
1267 UINT year, month, day, len = lstrlenW( str );
1268 const WCHAR *p = str, *q;
1269 WCHAR *ret;
1271 while (len && iswspace( *p )) { p++; len--; }
1272 while (len && iswspace( p[len - 1] )) { len--; }
1274 q = p;
1275 while (len && is_digit( *q )) { q++; len--; };
1276 if (q - p != 2 || !len || *q != '/') return NULL;
1277 month = (p[0] - '0') * 10 + p[1] - '0';
1279 p = ++q; len--;
1280 while (len && is_digit( *q )) { q++; len--; };
1281 if (q - p != 2 || !len || *q != '/') return NULL;
1282 day = (p[0] - '0') * 10 + p[1] - '0';
1284 p = ++q; len--;
1285 while (len && is_digit( *q )) { q++; len--; };
1286 if (q - p == 4) year = (p[0] - '0') * 1000 + (p[1] - '0') * 100 + (p[2] - '0') * 10 + p[3] - '0';
1287 else if (q - p == 2) year = 1900 + (p[0] - '0') * 10 + p[1] - '0';
1288 else return NULL;
1290 if (!(ret = heap_alloc( sizeof(fmtW) ))) return NULL;
1291 swprintf( ret, ARRAY_SIZE(fmtW), fmtW, year, month, day );
1292 return ret;
1295 static WCHAR *get_bios_releasedate( const char *buf, UINT len )
1297 WCHAR *ret, *date = get_bios_string( 3, buf, len );
1298 if (!date || !(ret = convert_bios_date( date ))) ret = heap_strdupW( L"20120608000000.000000+000" );
1299 heap_free( date );
1300 return ret;
1303 static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len )
1305 WCHAR *ret = get_bios_string( 2, buf, len );
1306 if (!ret) return heap_strdupW( L"Wine" );
1307 return ret;
1310 static BYTE get_bios_ec_firmware_major_release( const char *buf, UINT len )
1312 const struct smbios_header *hdr;
1313 const struct smbios_bios *bios;
1315 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1317 bios = (const struct smbios_bios *)hdr;
1318 if (bios->hdr.length >= 0x18) return bios->ec_firmware_major_release;
1319 else return 0xFF;
1322 static BYTE get_bios_ec_firmware_minor_release( const char *buf, UINT len )
1324 const struct smbios_header *hdr;
1325 const struct smbios_bios *bios;
1327 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1329 bios = (const struct smbios_bios *)hdr;
1330 if (bios->hdr.length >= 0x18) return bios->ec_firmware_minor_release;
1331 else return 0xFF;
1334 static BYTE get_bios_system_bios_major_release( const char *buf, UINT len )
1336 const struct smbios_header *hdr;
1337 const struct smbios_bios *bios;
1339 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1341 bios = (const struct smbios_bios *)hdr;
1342 if (bios->hdr.length >= 0x18) return bios->system_bios_major_release;
1343 else return 0xFF;
1346 static BYTE get_bios_system_bios_minor_release( const char *buf, UINT len )
1348 const struct smbios_header *hdr;
1349 const struct smbios_bios *bios;
1351 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1353 bios = (const struct smbios_bios *)hdr;
1354 if (bios->hdr.length >= 0x18) return bios->system_bios_minor_release;
1355 else return 0xFF;
1358 static enum fill_status fill_bios( struct table *table, const struct expr *cond )
1360 struct record_bios *rec;
1361 enum fill_status status = FILL_STATUS_UNFILTERED;
1362 UINT row = 0, len;
1363 char *buf;
1365 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1367 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1368 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
1369 GetSystemFirmwareTable( RSMB, 0, buf, len );
1371 rec = (struct record_bios *)table->data;
1372 rec->currentlanguage = NULL;
1373 rec->description = L"Default System BIOS";
1374 rec->ecmajorversion = get_bios_ec_firmware_major_release( buf, len );
1375 rec->ecminorversion = get_bios_ec_firmware_minor_release( buf, len );
1376 rec->identificationcode = NULL;
1377 rec->manufacturer = get_bios_manufacturer( buf, len );
1378 rec->name = L"Default System BIOS";
1379 rec->releasedate = get_bios_releasedate( buf, len );
1380 rec->serialnumber = L"0";
1381 rec->smbiosbiosversion = get_bios_smbiosbiosversion( buf, len );
1382 rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len );
1383 rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
1384 rec->systembiosmajorversion = get_bios_system_bios_major_release( buf, len );
1385 rec->systembiosminorversion = get_bios_system_bios_minor_release( buf, len );
1386 rec->version = L"WINE - 1";
1387 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1388 else row++;
1390 heap_free( buf );
1392 TRACE("created %u rows\n", row);
1393 table->num_rows = row;
1394 return status;
1397 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1399 WCHAR drive[3], root[] = L"A:\\";
1400 struct record_cdromdrive *rec;
1401 UINT i, row = 0, offset = 0;
1402 DWORD drives = GetLogicalDrives();
1403 enum fill_status status = FILL_STATUS_UNFILTERED;
1405 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1407 for (i = 0; i < 26; i++)
1409 if (drives & (1 << i))
1411 root[0] = 'A' + i;
1412 if (GetDriveTypeW( root ) != DRIVE_CDROM)
1413 continue;
1415 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1417 rec = (struct record_cdromdrive *)(table->data + offset);
1418 rec->device_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1419 swprintf( drive, ARRAY_SIZE( drive ), L"%c:", 'A' + i );
1420 rec->drive = heap_strdupW( drive );
1421 rec->mediatype = L"CR-ROM";
1422 rec->name = L"Wine CD_ROM ATA Device";
1423 rec->pnpdevice_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1424 if (!match_row( table, row, cond, &status ))
1426 free_row_values( table, row );
1427 continue;
1429 offset += sizeof(*rec);
1430 row++;
1433 TRACE("created %u rows\n", row);
1434 table->num_rows = row;
1435 return status;
1438 static UINT get_processor_count(void)
1440 SYSTEM_BASIC_INFORMATION info;
1442 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1443 return info.NumberOfProcessors;
1446 static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
1448 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
1449 UINT core_relation_count = 0, package_relation_count = 0;
1450 NTSTATUS status;
1451 ULONG len, offset = 0;
1452 BOOL smt_enabled = FALSE;
1453 DWORD all = RelationAll;
1455 if (num_packages) *num_packages = 1;
1456 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
1457 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1459 if (!(buf = heap_alloc( len ))) return get_processor_count();
1460 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
1461 if (status != STATUS_SUCCESS)
1463 heap_free( buf );
1464 return get_processor_count();
1467 while (offset < len)
1469 entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
1471 if (entry->Relationship == RelationProcessorCore)
1473 core_relation_count++;
1474 if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
1476 else if (entry->Relationship == RelationProcessorPackage)
1478 package_relation_count++;
1480 offset += entry->Size;
1483 heap_free( buf );
1484 if (num_physical) *num_physical = core_relation_count;
1485 if (num_packages) *num_packages = package_relation_count;
1486 return smt_enabled ? core_relation_count * 2 : core_relation_count;
1489 static UINT64 get_total_physical_memory(void)
1491 MEMORYSTATUSEX status;
1493 status.dwLength = sizeof(status);
1494 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1495 return status.ullTotalPhys;
1498 static UINT64 get_available_physical_memory(void)
1500 MEMORYSTATUSEX status;
1502 status.dwLength = sizeof(status);
1503 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1504 return status.ullAvailPhys;
1507 static WCHAR *get_computername(void)
1509 WCHAR *ret;
1510 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1512 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1513 GetComputerNameW( ret, &size );
1514 return ret;
1517 static WCHAR *get_username(void)
1519 WCHAR *ret;
1520 DWORD compsize, usersize;
1521 DWORD size;
1523 compsize = 0;
1524 GetComputerNameW( NULL, &compsize );
1525 usersize = 0;
1526 GetUserNameW( NULL, &usersize );
1527 size = compsize + usersize; /* two null terminators account for the \ */
1528 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1529 GetComputerNameW( ret, &compsize );
1530 ret[compsize] = '\\';
1531 GetUserNameW( ret + compsize + 1, &usersize );
1532 return ret;
1535 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1537 struct record_computersystem *rec;
1538 enum fill_status status = FILL_STATUS_UNFILTERED;
1539 UINT row = 0;
1541 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1543 rec = (struct record_computersystem *)table->data;
1544 rec->description = L"AT/AT COMPATIBLE";
1545 rec->domain = L"WORKGROUP";
1546 rec->domainrole = 0; /* standalone workstation */
1547 rec->manufacturer = L"The Wine Project";
1548 rec->model = L"Wine";
1549 rec->name = get_computername();
1550 rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
1551 rec->total_physical_memory = get_total_physical_memory();
1552 rec->username = get_username();
1553 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1554 else row++;
1556 TRACE("created %u rows\n", row);
1557 table->num_rows = row;
1558 return status;
1561 static WCHAR *get_compsysproduct_string( BYTE id, const char *buf, UINT len )
1563 const struct smbios_header *hdr;
1564 const struct smbios_system *system;
1565 UINT offset;
1567 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL;
1569 system = (const struct smbios_system *)hdr;
1570 offset = (const char *)system - buf + system->hdr.length;
1571 return get_smbios_string( id, buf, offset, len );
1574 static WCHAR *get_compsysproduct_identifyingnumber( const char *buf, UINT len )
1576 WCHAR *ret = get_compsysproduct_string( 4, buf, len );
1577 if (!ret) return heap_strdupW( L"0" );
1578 return ret;
1581 static WCHAR *get_compsysproduct_name( const char *buf, UINT len )
1583 WCHAR *ret = get_compsysproduct_string( 2, buf, len );
1584 if (!ret) return heap_strdupW( L"Wine" );
1585 return ret;
1588 static WCHAR *get_compsysproduct_uuid( const char *buf, UINT len )
1590 static const BYTE none[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1591 const struct smbios_header *hdr;
1592 const struct smbios_system *system;
1593 const BYTE *ptr;
1594 WCHAR *ret = NULL;
1596 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len )) || hdr->length < sizeof(*system)) goto done;
1597 system = (const struct smbios_system *)hdr;
1598 if (!memcmp( system->uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
1600 ptr = system->uuid;
1601 swprintf( ret, 37, L"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr[0], ptr[1],
1602 ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1603 ptr[14], ptr[15] );
1604 done:
1605 if (!ret) ret = heap_strdupW( L"deaddead-dead-dead-dead-deaddeaddead" );
1606 return ret;
1609 static WCHAR *get_compsysproduct_vendor( const char *buf, UINT len )
1611 WCHAR *ret = get_compsysproduct_string( 1, buf, len );
1612 if (!ret) return heap_strdupW( L"The Wine Project" );
1613 return ret;
1616 static WCHAR *get_compsysproduct_version( const char *buf, UINT len )
1618 WCHAR *ret = get_compsysproduct_string( 3, buf, len );
1619 if (!ret) return heap_strdupW( L"1.0" );
1620 return ret;
1623 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1625 struct record_computersystemproduct *rec;
1626 enum fill_status status = FILL_STATUS_UNFILTERED;
1627 UINT row = 0, len;
1628 char *buf;
1630 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1632 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1633 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
1634 GetSystemFirmwareTable( RSMB, 0, buf, len );
1636 rec = (struct record_computersystemproduct *)table->data;
1637 rec->identifyingnumber = get_compsysproduct_identifyingnumber( buf, len );
1638 rec->name = get_compsysproduct_name( buf, len );
1639 rec->skunumber = NULL;
1640 rec->uuid = get_compsysproduct_uuid( buf, len );
1641 rec->vendor = get_compsysproduct_vendor( buf, len );
1642 rec->version = get_compsysproduct_version( buf, len );
1643 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1644 else row++;
1646 heap_free( buf );
1648 TRACE("created %u rows\n", row);
1649 table->num_rows = row;
1650 return status;
1653 struct dirstack
1655 WCHAR **dirs;
1656 UINT *len_dirs;
1657 UINT num_dirs;
1658 UINT num_allocated;
1661 static struct dirstack *alloc_dirstack( UINT size )
1663 struct dirstack *dirstack;
1665 if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL;
1666 if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size )))
1668 heap_free( dirstack );
1669 return NULL;
1671 if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size )))
1673 heap_free( dirstack->dirs );
1674 heap_free( dirstack );
1675 return NULL;
1677 dirstack->num_dirs = 0;
1678 dirstack->num_allocated = size;
1679 return dirstack;
1682 static void clear_dirstack( struct dirstack *dirstack )
1684 UINT i;
1685 for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] );
1686 dirstack->num_dirs = 0;
1689 static void free_dirstack( struct dirstack *dirstack )
1691 clear_dirstack( dirstack );
1692 heap_free( dirstack->dirs );
1693 heap_free( dirstack->len_dirs );
1694 heap_free( dirstack );
1697 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1699 UINT size, i = dirstack->num_dirs;
1701 if (!dir) return FALSE;
1703 if (i == dirstack->num_allocated)
1705 WCHAR **tmp;
1706 UINT *len_tmp;
1708 size = dirstack->num_allocated * 2;
1709 if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1710 dirstack->dirs = tmp;
1711 if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1712 dirstack->len_dirs = len_tmp;
1713 dirstack->num_allocated = size;
1715 dirstack->dirs[i] = dir;
1716 dirstack->len_dirs[i] = len;
1717 dirstack->num_dirs++;
1718 return TRUE;
1721 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1723 if (!dirstack->num_dirs)
1725 *len = 0;
1726 return NULL;
1728 dirstack->num_dirs--;
1729 *len = dirstack->len_dirs[dirstack->num_dirs];
1730 return dirstack->dirs[dirstack->num_dirs];
1733 static const WCHAR *peek_dir( struct dirstack *dirstack )
1735 if (!dirstack->num_dirs) return NULL;
1736 return dirstack->dirs[dirstack->num_dirs - 1];
1739 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1741 UINT i = 0;
1742 WCHAR *ret;
1744 if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1745 ret[i++] = drive;
1746 ret[i++] = ':';
1747 ret[i++] = '\\';
1748 if (path && len)
1750 memcpy( ret + i, path, len * sizeof(WCHAR) );
1751 i += len;
1752 ret[i++] = '\\';
1754 ret[i++] = '*';
1755 ret[i] = 0;
1756 return ret;
1759 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1761 UINT i = 0, len = 0;
1762 const WCHAR *p;
1763 WCHAR *ret;
1765 for (p = path; *p; p++)
1767 if (*p == '\\') len += 2;
1768 else len++;
1770 if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1771 ret[i++] = drive;
1772 ret[i++] = ':';
1773 ret[i++] = '\\';
1774 ret[i++] = '\\';
1775 for (p = path; *p; p++)
1777 if (*p != '\\') ret[i++] = *p;
1778 else
1780 ret[i++] = '\\';
1781 ret[i++] = '\\';
1784 ret[i] = 0;
1785 return ret;
1788 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1790 const WCHAR *p = path, *start;
1791 UINT len, i;
1792 WCHAR *ret;
1794 if (!iswalpha( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1795 start = path + 4;
1796 len = lstrlenW( start );
1797 p = start + len - 1;
1798 if (*p == '\\') return NULL;
1800 while (p >= start && *p != '\\') { len--; p--; };
1801 while (p >= start && *p == '\\') { len--; p--; };
1803 if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1804 for (i = 0, p = start; p < start + len; p++)
1806 if (p[0] == '\\' && p[1] == '\\')
1808 ret[i++] = '\\';
1809 p++;
1811 else ret[i++] = *p;
1813 ret[i] = 0;
1814 *ret_len = i;
1815 return ret;
1818 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1820 UINT i;
1821 for (i = 0; i < dirstack->num_dirs; i++) if (!wcscmp( dirstack->dirs[i], path )) return TRUE;
1822 return FALSE;
1825 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1826 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1828 const struct expr *left, *right;
1830 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1832 left = cond->u.expr.left;
1833 right = cond->u.expr.right;
1834 if (cond->u.expr.op == OP_EQ)
1836 UINT len;
1837 WCHAR *path;
1838 const WCHAR *str = NULL;
1840 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1841 !wcscmp( left->u.propval->name, L"Name" ) &&
1842 towupper( right->u.sval[0] ) == towupper( root ))
1844 str = right->u.sval;
1846 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1847 !wcscmp( right->u.propval->name, L"Name" ) &&
1848 towupper( left->u.sval[0] ) == towupper( root ))
1850 str = left->u.sval;
1852 if (str && (path = build_dirname( str, &len )))
1854 if (seen_dir( dirstack, path ))
1856 heap_free( path );
1857 return ++*count;
1859 else if (push_dir( dirstack, path, len )) return ++*count;
1860 heap_free( path );
1861 return *count = 0;
1864 else if (cond->u.expr.op == OP_OR)
1866 UINT left_count = 0, right_count = 0;
1868 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
1869 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
1870 return *count += left_count + right_count;
1872 return *count = 0;
1875 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
1877 UINT len_path = 0, len_segment = lstrlenW( segment );
1878 WCHAR *ret;
1880 *len = 0;
1881 if (path) len_path = lstrlenW( path );
1882 if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
1883 if (path && len_path)
1885 memcpy( ret, path, len_path * sizeof(WCHAR) );
1886 ret[len_path] = '\\';
1887 *len += len_path + 1;
1889 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
1890 *len += len_segment;
1891 ret[*len] = 0;
1892 return ret;
1895 static WCHAR *get_file_version( const WCHAR *filename )
1897 VS_FIXEDFILEINFO *info;
1898 DWORD size, len = 4 * 5 + ARRAY_SIZE( L"%u.%u.%u.%u" );
1899 void *block;
1900 WCHAR *ret;
1902 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
1903 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size )))
1905 heap_free( ret );
1906 return NULL;
1908 if (!GetFileVersionInfoW( filename, 0, size, block ) ||
1909 !VerQueryValueW( block, L"\\", (void **)&info, &size ))
1911 heap_free( block );
1912 heap_free( ret );
1913 return NULL;
1915 swprintf( ret, len, L"%u.%u.%u.%u", info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
1916 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
1917 heap_free( block );
1918 return ret;
1921 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
1923 struct record_datafile *rec;
1924 UINT i, len, row = 0, offset = 0, num_expected_rows;
1925 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
1926 DWORD drives = GetLogicalDrives();
1927 WIN32_FIND_DATAW data;
1928 HANDLE handle;
1929 struct dirstack *dirstack;
1930 enum fill_status status = FILL_STATUS_UNFILTERED;
1932 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
1934 dirstack = alloc_dirstack(2);
1936 for (i = 0; i < 26; i++)
1938 if (!(drives & (1 << i))) continue;
1940 root[0] = 'A' + i;
1941 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1943 num_expected_rows = 0;
1944 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1946 for (;;)
1948 heap_free( glob );
1949 heap_free( path );
1950 path = pop_dir( dirstack, &len );
1951 if (!(glob = build_glob( root[0], path, len )))
1953 status = FILL_STATUS_FAILED;
1954 goto done;
1956 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1960 if (!resize_table( table, row + 1, sizeof(*rec) ))
1962 status = FILL_STATUS_FAILED;
1963 FindClose( handle );
1964 goto done;
1966 if (!wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." )) continue;
1968 if (!(new_path = append_path( path, data.cFileName, &len )))
1970 status = FILL_STATUS_FAILED;
1971 FindClose( handle );
1972 goto done;
1975 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1977 if (push_dir( dirstack, new_path, len )) continue;
1978 heap_free( new_path );
1979 FindClose( handle );
1980 status = FILL_STATUS_FAILED;
1981 goto done;
1983 rec = (struct record_datafile *)(table->data + offset);
1984 rec->name = build_name( root[0], new_path );
1985 rec->version = get_file_version( rec->name );
1986 heap_free( new_path );
1987 if (!match_row( table, row, cond, &status ))
1989 free_row_values( table, row );
1990 continue;
1992 else if (num_expected_rows && row == num_expected_rows - 1)
1994 row++;
1995 FindClose( handle );
1996 status = FILL_STATUS_FILTERED;
1997 goto done;
1999 offset += sizeof(*rec);
2000 row++;
2002 while (FindNextFileW( handle, &data ));
2003 FindClose( handle );
2005 if (!peek_dir( dirstack )) break;
2009 done:
2010 free_dirstack( dirstack );
2011 heap_free( glob );
2012 heap_free( path );
2014 TRACE("created %u rows\n", row);
2015 table->num_rows = row;
2016 return status;
2019 static UINT32 get_pixelsperxlogicalinch(void)
2021 HDC hdc = GetDC( NULL );
2022 UINT32 ret;
2024 if (!hdc) return 96;
2025 ret = GetDeviceCaps( hdc, LOGPIXELSX );
2026 ReleaseDC( NULL, hdc );
2027 return ret;
2030 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
2032 struct record_desktopmonitor *rec;
2033 enum fill_status status = FILL_STATUS_UNFILTERED;
2034 UINT row = 0;
2036 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2038 rec = (struct record_desktopmonitor *)table->data;
2039 rec->name = L"Generic Non-PnP Monitor";
2040 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
2042 if (match_row( table, row, cond, &status )) row++;
2044 TRACE("created %u rows\n", row);
2045 table->num_rows = row;
2046 return status;
2049 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
2051 struct record_directory *rec;
2052 UINT i, len, row = 0, offset = 0, num_expected_rows;
2053 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
2054 DWORD drives = GetLogicalDrives();
2055 WIN32_FIND_DATAW data;
2056 HANDLE handle;
2057 struct dirstack *dirstack;
2058 enum fill_status status = FILL_STATUS_UNFILTERED;
2060 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2062 dirstack = alloc_dirstack(2);
2064 for (i = 0; i < 26; i++)
2066 if (!(drives & (1 << i))) continue;
2068 root[0] = 'A' + i;
2069 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
2071 num_expected_rows = 0;
2072 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
2074 for (;;)
2076 heap_free( glob );
2077 heap_free( path );
2078 path = pop_dir( dirstack, &len );
2079 if (!(glob = build_glob( root[0], path, len )))
2081 status = FILL_STATUS_FAILED;
2082 goto done;
2084 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
2088 if (!resize_table( table, row + 1, sizeof(*rec) ))
2090 FindClose( handle );
2091 status = FILL_STATUS_FAILED;
2092 goto done;
2094 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
2095 !wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." ))
2096 continue;
2098 if (!(new_path = append_path( path, data.cFileName, &len )))
2100 FindClose( handle );
2101 status = FILL_STATUS_FAILED;
2102 goto done;
2105 if (!(push_dir( dirstack, new_path, len )))
2107 heap_free( new_path );
2108 FindClose( handle );
2109 status = FILL_STATUS_FAILED;
2110 goto done;
2112 rec = (struct record_directory *)(table->data + offset);
2113 rec->accessmask = FILE_ALL_ACCESS;
2114 rec->name = build_name( root[0], new_path );
2115 heap_free( new_path );
2116 if (!match_row( table, row, cond, &status ))
2118 free_row_values( table, row );
2119 continue;
2121 else if (num_expected_rows && row == num_expected_rows - 1)
2123 row++;
2124 FindClose( handle );
2125 status = FILL_STATUS_FILTERED;
2126 goto done;
2128 offset += sizeof(*rec);
2129 row++;
2131 while (FindNextFileW( handle, &data ));
2132 FindClose( handle );
2134 if (!peek_dir( dirstack )) break;
2138 done:
2139 free_dirstack( dirstack );
2140 heap_free( glob );
2141 heap_free( path );
2143 TRACE("created %u rows\n", row);
2144 table->num_rows = row;
2145 return status;
2148 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
2150 WCHAR root[] = L"\\\\.\\A:";
2151 ULARGE_INTEGER free;
2152 DISK_GEOMETRY_EX info;
2153 HANDLE handle;
2154 DWORD bytes_returned;
2156 free.QuadPart = 512 * 1024 * 1024;
2157 GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
2159 root[4] = dir[0];
2160 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2161 if (handle != INVALID_HANDLE_VALUE)
2163 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
2164 *disksize = info.DiskSize.QuadPart;
2165 CloseHandle( handle );
2167 return free.QuadPart;
2169 static WCHAR *get_diskdrive_serialnumber( WCHAR letter )
2171 WCHAR *ret = NULL;
2172 STORAGE_DEVICE_DESCRIPTOR *desc;
2173 HANDLE handle = INVALID_HANDLE_VALUE;
2174 STORAGE_PROPERTY_QUERY query = {0};
2175 WCHAR drive[7];
2176 DWORD size;
2178 swprintf( drive, ARRAY_SIZE(drive), L"\\\\.\\%c:", letter );
2179 handle = CreateFileW( drive, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2180 if (handle == INVALID_HANDLE_VALUE) goto done;
2182 query.PropertyId = StorageDeviceProperty;
2183 query.QueryType = PropertyStandardQuery;
2185 size = sizeof(*desc) + 256;
2186 for (;;)
2188 if (!(desc = heap_alloc( size ))) break;
2189 if (DeviceIoControl( handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), desc, size, NULL, NULL ))
2191 if (desc->SerialNumberOffset) ret = heap_strdupAW( (const char *)desc + desc->SerialNumberOffset );
2192 heap_free( desc );
2193 break;
2195 size = desc->Size;
2196 heap_free( desc );
2197 if (GetLastError() != ERROR_MORE_DATA) break;
2200 done:
2201 if (handle != INVALID_HANDLE_VALUE) CloseHandle( handle );
2202 if (!ret) ret = heap_strdupW( L"WINEHDISK" );
2203 return ret;
2206 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
2208 static const WCHAR fmtW[] = L"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2209 WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = L"A:\\";
2210 struct record_diskdrive *rec;
2211 UINT i, row = 0, offset = 0, index = 0, type;
2212 UINT64 size = 1024 * 1024 * 1024;
2213 DWORD drives = GetLogicalDrives();
2214 enum fill_status status = FILL_STATUS_UNFILTERED;
2216 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
2218 for (i = 0; i < 26; i++)
2220 if (drives & (1 << i))
2222 root[0] = 'A' + i;
2223 type = GetDriveTypeW( root );
2224 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2225 continue;
2227 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2229 rec = (struct record_diskdrive *)(table->data + offset);
2230 swprintf( device_id, ARRAY_SIZE( device_id ), fmtW, index );
2231 rec->device_id = heap_strdupW( device_id );
2232 rec->index = index++;
2233 rec->interfacetype = L"IDE";
2234 rec->manufacturer = L"(Standard disk drives)";
2235 rec->mediatype = (type == DRIVE_FIXED) ? L"Fixed hard disk" : L"Removable media";
2236 rec->model = L"Wine Disk Drive";
2237 rec->pnpdevice_id = L"IDE\\Disk\\VEN_WINE";
2238 rec->serialnumber = get_diskdrive_serialnumber( root[0] );
2239 get_freespace( root, &size );
2240 rec->size = size;
2241 if (!match_row( table, row, cond, &status ))
2243 free_row_values( table, row );
2244 continue;
2246 offset += sizeof(*rec);
2247 row++;
2250 TRACE("created %u rows\n", row);
2251 table->num_rows = row;
2252 return status;
2255 struct association
2257 WCHAR *ref;
2258 WCHAR *ref2;
2261 static void free_associations( struct association *assoc, UINT count )
2263 UINT i;
2264 if (!assoc) return;
2265 for (i = 0; i < count; i++)
2267 heap_free( assoc[i].ref );
2268 heap_free( assoc[i].ref2 );
2270 heap_free( assoc );
2273 static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
2275 struct association *ret = NULL;
2276 struct query *query, *query2 = NULL;
2277 VARIANT val;
2278 HRESULT hr;
2279 UINT i;
2281 if (!(query = create_query())) return NULL;
2282 if ((hr = parse_query( L"SELECT * FROM Win32_DiskDrive", &query->view, &query->mem )) != S_OK) goto done;
2283 if ((hr = execute_view( query->view )) != S_OK) goto done;
2285 if (!(query2 = create_query())) return FALSE;
2286 if ((hr = parse_query( L"SELECT * FROM Win32_DiskPartition", &query2->view, &query2->mem )) != S_OK) goto done;
2287 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2289 if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
2291 for (i = 0; i < query->view->result_count; i++)
2293 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2294 if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
2295 VariantClear( &val );
2297 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2298 if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done;
2299 VariantClear( &val );
2302 *count = query->view->result_count;
2304 done:
2305 if (!ret) free_associations( ret, query->view->result_count );
2306 free_query( query );
2307 free_query( query2 );
2308 return ret;
2311 static enum fill_status fill_diskdrivetodiskpartition( struct table *table, const struct expr *cond )
2313 struct record_diskdrivetodiskpartition *rec;
2314 UINT i, row = 0, offset = 0, count = 0;
2315 enum fill_status status = FILL_STATUS_UNFILTERED;
2316 struct association *assoc;
2318 if (!(assoc = get_diskdrivetodiskpartition_pairs( &count ))) return FILL_STATUS_FAILED;
2319 if (!count)
2321 free_associations( assoc, count );
2322 return FILL_STATUS_UNFILTERED;
2324 if (!resize_table( table, count, sizeof(*rec) ))
2326 free_associations( assoc, count );
2327 return FILL_STATUS_FAILED;
2330 for (i = 0; i < count; i++)
2332 rec = (struct record_diskdrivetodiskpartition *)(table->data + offset);
2333 rec->antecedent = assoc[i].ref;
2334 rec->dependent = assoc[i].ref2;
2335 if (!match_row( table, row, cond, &status ))
2337 free_row_values( table, row );
2338 continue;
2340 offset += sizeof(*rec);
2341 row++;
2344 heap_free( assoc );
2346 TRACE("created %u rows\n", row);
2347 table->num_rows = row;
2348 return status;
2351 static WCHAR *get_filesystem( const WCHAR *root )
2353 WCHAR buffer[MAX_PATH + 1];
2355 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
2356 return heap_strdupW( buffer );
2357 return heap_strdupW( L"NTFS" );
2360 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2362 WCHAR device_id[32], root[] = L"A:\\";
2363 struct record_diskpartition *rec;
2364 UINT i, row = 0, offset = 0, type, index = 0;
2365 UINT64 size = 1024 * 1024 * 1024;
2366 DWORD drives = GetLogicalDrives();
2367 enum fill_status status = FILL_STATUS_UNFILTERED;
2369 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2371 for (i = 0; i < 26; i++)
2373 if (drives & (1 << i))
2375 root[0] = 'A' + i;
2376 type = GetDriveTypeW( root );
2377 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2378 continue;
2380 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2382 rec = (struct record_diskpartition *)(table->data + offset);
2383 rec->bootable = (i == 2) ? -1 : 0;
2384 rec->bootpartition = (i == 2) ? -1 : 0;
2385 swprintf( device_id, ARRAY_SIZE( device_id ), L"Disk #%u, Partition #0", index );
2386 rec->device_id = heap_strdupW( device_id );
2387 rec->diskindex = index++;
2388 rec->index = 0;
2389 rec->pnpdevice_id = heap_strdupW( device_id );
2390 get_freespace( root, &size );
2391 rec->size = size;
2392 rec->startingoffset = 0;
2393 rec->type = get_filesystem( root );
2394 if (!match_row( table, row, cond, &status ))
2396 free_row_values( table, row );
2397 continue;
2399 offset += sizeof(*rec);
2400 row++;
2403 TRACE("created %u rows\n", row);
2404 table->num_rows = row;
2405 return status;
2408 static UINT32 get_bitsperpixel( UINT *hres, UINT *vres )
2410 HDC hdc = GetDC( NULL );
2411 UINT32 ret;
2413 if (!hdc) return 32;
2414 ret = GetDeviceCaps( hdc, BITSPIXEL );
2415 *hres = GetDeviceCaps( hdc, HORZRES );
2416 *vres = GetDeviceCaps( hdc, VERTRES );
2417 ReleaseDC( NULL, hdc );
2418 return ret;
2421 static enum fill_status fill_displaycontrollerconfig( struct table *table, const struct expr *cond )
2423 struct record_displaycontrollerconfig *rec;
2424 UINT row = 0, hres = 1024, vres = 768;
2425 enum fill_status status = FILL_STATUS_UNFILTERED;
2427 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2429 rec = (struct record_displaycontrollerconfig *)table->data;
2430 rec->bitsperpixel = get_bitsperpixel( &hres, &vres );
2431 rec->caption = L"VideoController1";
2432 rec->horizontalresolution = hres;
2433 rec->name = L"VideoController1";
2434 rec->verticalresolution = vres;
2435 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2436 else row++;
2438 TRACE("created %u rows\n", row);
2439 table->num_rows = row;
2440 return status;
2443 static WCHAR *get_ip4_string( DWORD addr )
2445 DWORD len = sizeof("ddd.ddd.ddd.ddd");
2446 WCHAR *ret;
2448 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
2449 swprintf( ret, len, L"%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2450 return ret;
2453 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2455 struct record_ip4routetable *rec;
2456 UINT i, row = 0, offset = 0, size = 0;
2457 MIB_IPFORWARDTABLE *forwards;
2458 enum fill_status status = FILL_STATUS_UNFILTERED;
2460 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2461 if (!(forwards = heap_alloc( size ))) return FILL_STATUS_FAILED;
2462 if (GetIpForwardTable( forwards, &size, TRUE ))
2464 heap_free( forwards );
2465 return FILL_STATUS_FAILED;
2467 if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) ))
2469 heap_free( forwards );
2470 return FILL_STATUS_FAILED;
2473 for (i = 0; i < forwards->dwNumEntries; i++)
2475 rec = (struct record_ip4routetable *)(table->data + offset);
2477 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2478 rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2479 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2481 if (!match_row( table, row, cond, &status ))
2483 free_row_values( table, row );
2484 continue;
2486 offset += sizeof(*rec);
2487 row++;
2489 TRACE("created %u rows\n", row);
2490 table->num_rows = row;
2492 heap_free( forwards );
2493 return status;
2496 static WCHAR *get_volumename( const WCHAR *root )
2498 WCHAR buf[MAX_PATH + 1] = {0};
2499 GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 );
2500 return heap_strdupW( buf );
2502 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2504 DWORD serial = 0;
2505 WCHAR buffer[9];
2507 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2508 swprintf( buffer, ARRAY_SIZE( buffer ), L"%08X", serial );
2509 return heap_strdupW( buffer );
2512 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2514 WCHAR device_id[3], root[] = L"A:\\";
2515 struct record_logicaldisk *rec;
2516 UINT i, row = 0, offset = 0, type;
2517 UINT64 size = 1024 * 1024 * 1024;
2518 DWORD drives = GetLogicalDrives();
2519 enum fill_status status = FILL_STATUS_UNFILTERED;
2521 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2523 for (i = 0; i < 26; i++)
2525 if (drives & (1 << i))
2527 root[0] = 'A' + i;
2528 type = GetDriveTypeW( root );
2529 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2530 continue;
2532 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2534 rec = (struct record_logicaldisk *)(table->data + offset);
2535 swprintf( device_id, ARRAY_SIZE( device_id ), L"%c:", 'A' + i );
2536 rec->caption = heap_strdupW( device_id );
2537 rec->device_id = heap_strdupW( device_id );
2538 rec->drivetype = type;
2539 rec->filesystem = get_filesystem( root );
2540 rec->freespace = get_freespace( root, &size );
2541 rec->name = heap_strdupW( device_id );
2542 rec->size = size;
2543 rec->volumename = get_volumename( root );
2544 rec->volumeserialnumber = get_volumeserialnumber( root );
2545 if (!match_row( table, row, cond, &status ))
2547 free_row_values( table, row );
2548 continue;
2550 offset += sizeof(*rec);
2551 row++;
2554 TRACE("created %u rows\n", row);
2555 table->num_rows = row;
2556 return status;
2559 static struct association *get_logicaldisktopartition_pairs( UINT *count )
2561 struct association *ret = NULL;
2562 struct query *query, *query2 = NULL;
2563 VARIANT val;
2564 HRESULT hr;
2565 UINT i;
2567 if (!(query = create_query())) return NULL;
2568 if ((hr = parse_query( L"SELECT * FROM Win32_DiskPartition", &query->view, &query->mem )) != S_OK) goto done;
2569 if ((hr = execute_view( query->view )) != S_OK) goto done;
2571 if (!(query2 = create_query())) return FALSE;
2572 if ((hr = parse_query( L"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2->view,
2573 &query2->mem )) != S_OK) goto done;
2574 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2576 if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
2578 /* assume fixed and removable disks are enumerated in the same order as partitions */
2579 for (i = 0; i < query->view->result_count; i++)
2581 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2582 if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
2583 VariantClear( &val );
2585 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2586 if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done;
2587 VariantClear( &val );
2590 *count = query->view->result_count;
2592 done:
2593 if (!ret) free_associations( ret, query->view->result_count );
2594 free_query( query );
2595 free_query( query2 );
2596 return ret;
2599 static enum fill_status fill_logicaldisktopartition( struct table *table, const struct expr *cond )
2601 struct record_logicaldisktopartition *rec;
2602 UINT i, row = 0, offset = 0, count = 0;
2603 enum fill_status status = FILL_STATUS_UNFILTERED;
2604 struct association *assoc;
2606 if (!(assoc = get_logicaldisktopartition_pairs( &count ))) return FILL_STATUS_FAILED;
2607 if (!count)
2609 free_associations( assoc, count );
2610 return FILL_STATUS_UNFILTERED;
2612 if (!resize_table( table, count, sizeof(*rec) ))
2614 free_associations( assoc, count );
2615 return FILL_STATUS_FAILED;
2618 for (i = 0; i < count; i++)
2620 rec = (struct record_logicaldisktopartition *)(table->data + offset);
2621 rec->antecedent = assoc[i].ref;
2622 rec->dependent = assoc[i].ref2;
2623 if (!match_row( table, row, cond, &status ))
2625 free_row_values( table, row );
2626 continue;
2628 offset += sizeof(*rec);
2629 row++;
2632 heap_free( assoc );
2634 TRACE("created %u rows\n", row);
2635 table->num_rows = row;
2636 return status;
2639 static UINT16 get_connection_status( IF_OPER_STATUS status )
2641 switch (status)
2643 case IfOperStatusDown:
2644 return 0; /* Disconnected */
2645 case IfOperStatusUp:
2646 return 2; /* Connected */
2647 default:
2648 ERR("unhandled status %u\n", status);
2649 break;
2651 return 0;
2653 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2655 WCHAR *ret;
2656 if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL;
2657 swprintf( ret, 18, L"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2658 return ret;
2660 static const WCHAR *get_adaptertype( DWORD type, int *id, int *physical )
2662 switch (type)
2664 case IF_TYPE_ETHERNET_CSMACD:
2665 *id = 0;
2666 *physical = -1;
2667 return L"Ethernet 802.3";
2669 case IF_TYPE_IEEE80211:
2670 *id = 9;
2671 *physical = -1;
2672 return L"Wireless";
2674 case IF_TYPE_IEEE1394:
2675 *id = 13;
2676 *physical = -1;
2677 return L"1394";
2679 case IF_TYPE_TUNNEL:
2680 *id = 15;
2681 *physical = 0;
2682 return L"Tunnel";
2684 default:
2685 *id = -1;
2686 *physical = 0;
2687 return NULL;
2691 #define GUID_SIZE 39
2692 static WCHAR *guid_to_str( const GUID *ptr )
2694 WCHAR *ret;
2695 if (!(ret = heap_alloc( GUID_SIZE * sizeof(WCHAR) ))) return NULL;
2696 swprintf( ret, GUID_SIZE, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2697 ptr->Data1, ptr->Data2, ptr->Data3, ptr->Data4[0], ptr->Data4[1], ptr->Data4[2],
2698 ptr->Data4[3], ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] );
2699 return ret;
2702 static WCHAR *get_networkadapter_guid( const IF_LUID *luid )
2704 GUID guid;
2705 if (ConvertInterfaceLuidToGuid( luid, &guid )) return NULL;
2706 return guid_to_str( &guid );
2709 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2711 WCHAR device_id[11];
2712 struct record_networkadapter *rec;
2713 IP_ADAPTER_ADDRESSES *aa, *buffer;
2714 UINT row = 0, offset = 0, count = 0;
2715 DWORD size = 0, ret;
2716 int adaptertypeid, physical;
2717 enum fill_status status = FILL_STATUS_UNFILTERED;
2719 ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
2720 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2722 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2723 if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size ))
2725 heap_free( buffer );
2726 return FILL_STATUS_FAILED;
2728 for (aa = buffer; aa; aa = aa->Next)
2730 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2732 if (!resize_table( table, count, sizeof(*rec) ))
2734 heap_free( buffer );
2735 return FILL_STATUS_FAILED;
2737 for (aa = buffer; aa; aa = aa->Next)
2739 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2741 rec = (struct record_networkadapter *)(table->data + offset);
2742 swprintf( device_id, ARRAY_SIZE( device_id ), L"%u", aa->u.s.IfIndex );
2743 rec->adaptertype = get_adaptertype( aa->IfType, &adaptertypeid, &physical );
2744 rec->adaptertypeid = adaptertypeid;
2745 rec->description = heap_strdupW( aa->Description );
2746 rec->device_id = heap_strdupW( device_id );
2747 rec->guid = get_networkadapter_guid( &aa->Luid );
2748 rec->index = aa->u.s.IfIndex;
2749 rec->interface_index = aa->u.s.IfIndex;
2750 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2751 rec->manufacturer = L"The Wine Project";
2752 rec->name = heap_strdupW( aa->FriendlyName );
2753 rec->netconnection_status = get_connection_status( aa->OperStatus );
2754 rec->physicaladapter = physical;
2755 rec->pnpdevice_id = L"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2756 rec->servicename = heap_strdupW( aa->FriendlyName );
2757 rec->speed = 1000000;
2758 if (!match_row( table, row, cond, &status ))
2760 free_row_values( table, row );
2761 continue;
2763 offset += sizeof(*rec);
2764 row++;
2766 TRACE("created %u rows\n", row);
2767 table->num_rows = row;
2769 heap_free( buffer );
2770 return status;
2773 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2775 const SOCKET_ADDRESS *sa = &addr->Address;
2776 WCHAR buf[NI_MAXHOST];
2778 if (!addr) return NULL;
2779 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL,
2780 0, NI_NAMEREQD )) return NULL;
2781 return heap_strdupW( buf );
2783 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2785 IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2786 struct array *ret;
2787 ULONG buflen, i = 0, count = 0;
2788 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2790 if (!list) return NULL;
2791 for (gateway = list; gateway; gateway = gateway->Next) count++;
2793 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2794 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2796 heap_free( ret );
2797 return NULL;
2799 for (gateway = list; gateway; gateway = gateway->Next)
2801 buflen = ARRAY_SIZE( buf );
2802 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2803 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2805 for (; i > 0; i--) heap_free( ptr[i - 1] );
2806 heap_free( ptr );
2807 heap_free( ret );
2808 return NULL;
2811 ret->elem_size = sizeof(*ptr);
2812 ret->count = count;
2813 ret->ptr = ptr;
2814 return ret;
2816 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2818 IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2819 struct array *ret;
2820 ULONG buflen, i = 0, count = 0;
2821 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2823 if (!list) return NULL;
2824 for (server = list; server; server = server->Next) count++;
2826 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2827 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2829 heap_free( ret );
2830 return NULL;
2832 for (server = list; server; server = server->Next)
2834 buflen = ARRAY_SIZE( buf );
2835 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2836 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2838 for (; i > 0; i--) heap_free( ptr[i - 1] );
2839 heap_free( ptr );
2840 heap_free( ret );
2841 return NULL;
2843 if ((p = wcsrchr( ptr[i - 1], ':' ))) *p = 0;
2845 ret->elem_size = sizeof(*ptr);
2846 ret->count = count;
2847 ret->ptr = ptr;
2848 return ret;
2850 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2852 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2853 struct array *ret;
2854 ULONG buflen, i = 0, count = 0;
2855 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2857 if (!list) return NULL;
2858 for (address = list; address; address = address->Next) count++;
2860 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2861 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2863 heap_free( ret );
2864 return NULL;
2866 for (address = list; address; address = address->Next)
2868 buflen = ARRAY_SIZE( buf );
2869 if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength,
2870 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2872 for (; i > 0; i--) heap_free( ptr[i - 1] );
2873 heap_free( ptr );
2874 heap_free( ret );
2875 return NULL;
2878 ret->elem_size = sizeof(*ptr);
2879 ret->count = count;
2880 ret->ptr = ptr;
2881 return ret;
2883 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2885 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2886 struct array *ret;
2887 ULONG i = 0, count = 0;
2888 WCHAR **ptr;
2890 if (!list) return NULL;
2891 for (address = list; address; address = address->Next) count++;
2893 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2894 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2896 heap_free( ret );
2897 return NULL;
2899 for (address = list; address; address = address->Next)
2901 if (address->Address.lpSockaddr->sa_family == AF_INET)
2903 WCHAR buf[INET_ADDRSTRLEN];
2904 SOCKADDR_IN addr;
2905 ULONG buflen = ARRAY_SIZE( buf );
2907 memset( &addr, 0, sizeof(addr) );
2908 addr.sin_family = AF_INET;
2909 if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
2910 || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
2911 ptr[i] = NULL;
2912 else
2913 ptr[i] = heap_strdupW( buf );
2915 else
2917 WCHAR buf[11];
2918 swprintf( buf, ARRAY_SIZE( buf ), L"%u", address->OnLinkPrefixLength );
2919 ptr[i] = heap_strdupW( buf );
2921 if (!ptr[i++])
2923 for (; i > 0; i--) heap_free( ptr[i - 1] );
2924 heap_free( ptr );
2925 heap_free( ret );
2926 return NULL;
2929 ret->elem_size = sizeof(*ptr);
2930 ret->count = count;
2931 ret->ptr = ptr;
2932 return ret;
2934 static WCHAR *get_settingid( UINT32 index )
2936 GUID guid;
2937 memset( &guid, 0, sizeof(guid) );
2938 guid.Data1 = index;
2939 return guid_to_str( &guid );
2942 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
2944 struct record_networkadapterconfig *rec;
2945 IP_ADAPTER_ADDRESSES *aa, *buffer;
2946 UINT row = 0, offset = 0, count = 0;
2947 DWORD size = 0, ret;
2948 enum fill_status status = FILL_STATUS_UNFILTERED;
2950 ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size );
2951 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2953 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2954 if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size ))
2956 heap_free( buffer );
2957 return FILL_STATUS_FAILED;
2959 for (aa = buffer; aa; aa = aa->Next)
2961 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2963 if (!resize_table( table, count, sizeof(*rec) ))
2965 heap_free( buffer );
2966 return FILL_STATUS_FAILED;
2968 for (aa = buffer; aa; aa = aa->Next)
2970 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2972 rec = (struct record_networkadapterconfig *)(table->data + offset);
2973 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress );
2974 rec->description = heap_strdupW( aa->Description );
2975 rec->dhcpenabled = -1;
2976 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress );
2977 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress );
2978 rec->index = aa->u.s.IfIndex;
2979 rec->ipaddress = get_ipaddress( aa->FirstUnicastAddress );
2980 rec->ipconnectionmetric = 20;
2981 rec->ipenabled = -1;
2982 rec->ipsubnet = get_ipsubnet( aa->FirstUnicastAddress );
2983 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2984 rec->settingid = get_settingid( rec->index );
2985 if (!match_row( table, row, cond, &status ))
2987 free_row_values( table, row );
2988 continue;
2990 offset += sizeof(*rec);
2991 row++;
2993 TRACE("created %u rows\n", row);
2994 table->num_rows = row;
2996 heap_free( buffer );
2997 return status;
3000 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
3002 struct record_physicalmemory *rec;
3003 enum fill_status status = FILL_STATUS_UNFILTERED;
3004 UINT row = 0;
3006 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3008 rec = (struct record_physicalmemory *)table->data;
3009 rec->banklabel = L"BANK 0";
3010 rec->capacity = get_total_physical_memory();
3011 rec->caption = L"Physical Memory";
3012 rec->configuredclockspeed = 1600;
3013 rec->devicelocator = L"DIMM 0";
3014 rec->formfactor = 8; /* DIMM */
3015 rec->memorytype = 9; /* RAM */
3016 rec->partnumber = L"";
3017 rec->serial = L"";
3018 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3019 else row++;
3021 TRACE("created %u rows\n", row);
3022 table->num_rows = row;
3023 return status;
3026 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond )
3028 struct record_pnpentity *rec;
3029 enum fill_status status = FILL_STATUS_UNFILTERED;
3030 HDEVINFO device_info_set;
3031 SP_DEVINFO_DATA devinfo = {0};
3032 DWORD idx;
3034 device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT );
3036 devinfo.cbSize = sizeof(devinfo);
3038 idx = 0;
3039 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
3041 /* noop */
3044 resize_table( table, idx, sizeof(*rec) );
3045 table->num_rows = 0;
3046 rec = (struct record_pnpentity *)table->data;
3048 idx = 0;
3049 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
3051 WCHAR device_id[MAX_PATH];
3052 if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
3053 ARRAY_SIZE(device_id), NULL ))
3055 rec->device_id = heap_strdupW( device_id );
3057 table->num_rows++;
3058 if (!match_row( table, table->num_rows - 1, cond, &status ))
3060 free_row_values( table, table->num_rows - 1 );
3061 table->num_rows--;
3063 else
3064 rec++;
3068 SetupDiDestroyDeviceInfoList( device_info_set );
3070 return status;
3073 static enum fill_status fill_printer( struct table *table, const struct expr *cond )
3075 struct record_printer *rec;
3076 enum fill_status status = FILL_STATUS_UNFILTERED;
3077 PRINTER_INFO_2W *info;
3078 DWORD i, offset = 0, count = 0, size = 0, num_rows = 0;
3079 WCHAR id[20];
3081 EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
3082 if (!count) return FILL_STATUS_UNFILTERED;
3084 if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED;
3085 if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
3087 heap_free( info );
3088 return FILL_STATUS_FAILED;
3090 if (!resize_table( table, count, sizeof(*rec) ))
3092 heap_free( info );
3093 return FILL_STATUS_FAILED;
3096 for (i = 0; i < count; i++)
3098 rec = (struct record_printer *)(table->data + offset);
3099 rec->attributes = info[i].Attributes;
3100 swprintf( id, ARRAY_SIZE( id ), L"Printer%u", i );
3101 rec->device_id = heap_strdupW( id );
3102 rec->drivername = heap_strdupW( info[i].pDriverName );
3103 rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality;
3104 rec->local = -1;
3105 rec->location = heap_strdupW( info[i].pLocation );
3106 rec->name = heap_strdupW( info[i].pPrinterName );
3107 rec->network = 0;
3108 rec->portname = heap_strdupW( info[i].pPortName );
3109 if (!match_row( table, i, cond, &status ))
3111 free_row_values( table, i );
3112 continue;
3114 offset += sizeof(*rec);
3115 num_rows++;
3117 TRACE("created %u rows\n", num_rows);
3118 table->num_rows = num_rows;
3120 heap_free( info );
3121 return status;
3124 static WCHAR *get_cmdline( DWORD process_id )
3126 if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() );
3127 return NULL; /* FIXME handle different process case */
3130 static enum fill_status fill_process( struct table *table, const struct expr *cond )
3132 WCHAR handle[11];
3133 struct record_process *rec;
3134 PROCESSENTRY32W entry;
3135 HANDLE snap;
3136 enum fill_status status = FILL_STATUS_FAILED;
3137 UINT row = 0, offset = 0;
3139 snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
3140 if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
3142 entry.dwSize = sizeof(entry);
3143 if (!Process32FirstW( snap, &entry )) goto done;
3144 if (!resize_table( table, 8, sizeof(*rec) )) goto done;
3148 if (!resize_table( table, row + 1, sizeof(*rec) ))
3150 status = FILL_STATUS_FAILED;
3151 goto done;
3154 rec = (struct record_process *)(table->data + offset);
3155 rec->caption = heap_strdupW( entry.szExeFile );
3156 rec->commandline = get_cmdline( entry.th32ProcessID );
3157 rec->description = heap_strdupW( entry.szExeFile );
3158 swprintf( handle, ARRAY_SIZE( handle ), L"%u", entry.th32ProcessID );
3159 rec->handle = heap_strdupW( handle );
3160 rec->name = heap_strdupW( entry.szExeFile );
3161 rec->process_id = entry.th32ProcessID;
3162 rec->pprocess_id = entry.th32ParentProcessID;
3163 rec->thread_count = entry.cntThreads;
3164 rec->workingsetsize = 0;
3165 rec->get_owner = process_get_owner;
3166 if (!match_row( table, row, cond, &status ))
3168 free_row_values( table, row );
3169 continue;
3171 offset += sizeof(*rec);
3172 row++;
3173 } while (Process32NextW( snap, &entry ));
3175 TRACE("created %u rows\n", row);
3176 table->num_rows = row;
3178 done:
3179 CloseHandle( snap );
3180 return status;
3183 void do_cpuid( unsigned int ax, int *p )
3185 #if defined(__i386__) || defined(__x86_64__)
3186 __cpuid( p, ax );
3187 #else
3188 FIXME("\n");
3189 #endif
3192 static unsigned int get_processor_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
3194 unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
3196 model = (reg0 & (0x0f << 4)) >> 4;
3197 if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
3198 if (family)
3200 *family = family_id;
3201 if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
3203 *stepping = reg0 & 0x0f;
3204 return model;
3206 static void regs_to_str( int *regs, unsigned int len, WCHAR *buffer )
3208 unsigned int i;
3209 unsigned char *p = (unsigned char *)regs;
3211 for (i = 0; i < len; i++) { buffer[i] = *p++; }
3212 buffer[i] = 0;
3214 static void get_processor_manufacturer( WCHAR *manufacturer, UINT len )
3216 int tmp, regs[4] = {0, 0, 0, 0};
3218 do_cpuid( 0, regs );
3219 tmp = regs[2]; /* swap edx and ecx */
3220 regs[2] = regs[3];
3221 regs[3] = tmp;
3223 regs_to_str( regs + 1, min( 12, len ), manufacturer );
3225 static const WCHAR *get_osarchitecture(void)
3227 SYSTEM_INFO info;
3228 GetNativeSystemInfo( &info );
3229 if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return L"64-bit";
3230 return L"32-bit";
3232 static void get_processor_caption( WCHAR *caption, UINT len )
3234 const WCHAR *arch;
3235 WCHAR manufacturer[13];
3236 int regs[4] = {0, 0, 0, 0};
3237 unsigned int family, model, stepping;
3239 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3240 if (!wcscmp( get_osarchitecture(), L"32-bit" )) arch = L"x86";
3241 else if (!wcscmp( manufacturer, L"AuthenticAMD" )) arch = L"AMD64";
3242 else arch = L"Intel64";
3244 do_cpuid( 1, regs );
3246 model = get_processor_model( regs[0], &stepping, &family );
3247 swprintf( caption, len, L"%s Family %u Model %u Stepping %u", arch, family, model, stepping );
3249 static void get_processor_version( WCHAR *version, UINT len )
3251 int regs[4] = {0, 0, 0, 0};
3252 unsigned int model, stepping;
3254 do_cpuid( 1, regs );
3256 model = get_processor_model( regs[0], &stepping, NULL );
3257 swprintf( version, len, L"Model %u Stepping %u", model, stepping );
3259 static UINT16 get_processor_revision(void)
3261 int regs[4] = {0, 0, 0, 0};
3262 do_cpuid( 1, regs );
3263 return regs[0];
3265 static void get_processor_id( WCHAR *processor_id, UINT len )
3267 int regs[4] = {0, 0, 0, 0};
3269 do_cpuid( 1, regs );
3270 swprintf( processor_id, len, L"%08X%08X", regs[3], regs[0] );
3272 static void get_processor_name( WCHAR *name )
3274 int regs[4] = {0, 0, 0, 0};
3275 int i;
3277 do_cpuid( 0x80000000, regs );
3278 if (regs[0] >= 0x80000004)
3280 do_cpuid( 0x80000002, regs );
3281 regs_to_str( regs, 16, name );
3282 do_cpuid( 0x80000003, regs );
3283 regs_to_str( regs, 16, name + 16 );
3284 do_cpuid( 0x80000004, regs );
3285 regs_to_str( regs, 16, name + 32 );
3287 for (i = lstrlenW(name) - 1; i >= 0 && name[i] == ' '; i--) name[i] = 0;
3289 static UINT get_processor_currentclockspeed( UINT index )
3291 PROCESSOR_POWER_INFORMATION *info;
3292 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3293 NTSTATUS status;
3295 if ((info = heap_alloc( size )))
3297 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3298 if (!status) ret = info[index].CurrentMhz;
3299 heap_free( info );
3301 return ret;
3303 static UINT get_processor_maxclockspeed( UINT index )
3305 PROCESSOR_POWER_INFORMATION *info;
3306 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3307 NTSTATUS status;
3309 if ((info = heap_alloc( size )))
3311 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3312 if (!status) ret = info[index].MaxMhz;
3313 heap_free( info );
3315 return ret;
3318 static enum fill_status fill_processor( struct table *table, const struct expr *cond )
3320 WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
3321 struct record_processor *rec;
3322 UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
3323 enum fill_status status = FILL_STATUS_UNFILTERED;
3325 num_logical = get_logical_processor_count( &num_physical, &num_packages );
3327 if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
3329 get_processor_caption( caption, ARRAY_SIZE( caption ) );
3330 get_processor_id( processor_id, ARRAY_SIZE( processor_id ) );
3331 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3332 get_processor_name( name );
3333 get_processor_version( version, ARRAY_SIZE( version ) );
3335 for (i = 0; i < num_packages; i++)
3337 rec = (struct record_processor *)(table->data + offset);
3338 rec->addresswidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3339 rec->architecture = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 0 : 9;
3340 rec->caption = heap_strdupW( caption );
3341 rec->cpu_status = 1; /* CPU Enabled */
3342 rec->currentclockspeed = get_processor_currentclockspeed( i );
3343 rec->datawidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3344 rec->description = heap_strdupW( caption );
3345 swprintf( device_id, ARRAY_SIZE( device_id ), L"CPU%u", i );
3346 rec->device_id = heap_strdupW( device_id );
3347 rec->family = 2; /* Unknown */
3348 rec->level = 15;
3349 rec->manufacturer = heap_strdupW( manufacturer );
3350 rec->maxclockspeed = get_processor_maxclockspeed( i );
3351 rec->name = heap_strdupW( name );
3352 rec->num_cores = num_physical / num_packages;
3353 rec->num_logical_processors = num_logical / num_packages;
3354 rec->processor_id = heap_strdupW( processor_id );
3355 rec->processortype = 3; /* central processor */
3356 rec->revision = get_processor_revision();
3357 rec->unique_id = NULL;
3358 rec->version = heap_strdupW( version );
3359 if (!match_row( table, i, cond, &status ))
3361 free_row_values( table, i );
3362 continue;
3364 offset += sizeof(*rec);
3365 num_rows++;
3368 TRACE("created %u rows\n", num_rows);
3369 table->num_rows = num_rows;
3370 return status;
3373 static WCHAR *get_lastbootuptime(void)
3375 SYSTEM_TIMEOFDAY_INFORMATION ti;
3376 TIME_FIELDS tf;
3377 WCHAR *ret;
3379 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3381 NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
3382 RtlTimeToTimeFields( &ti.BootTime, &tf );
3383 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u+000", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute,
3384 tf.Second, tf.Milliseconds * 1000 );
3385 return ret;
3387 static WCHAR *get_localdatetime(void)
3389 TIME_ZONE_INFORMATION tzi;
3390 SYSTEMTIME st;
3391 WCHAR *ret;
3392 DWORD Status;
3393 LONG Bias;
3395 Status = GetTimeZoneInformation(&tzi);
3397 if(Status == TIME_ZONE_ID_INVALID) return NULL;
3398 Bias = tzi.Bias;
3399 if(Status == TIME_ZONE_ID_DAYLIGHT)
3400 Bias+= tzi.DaylightBias;
3401 else
3402 Bias+= tzi.StandardBias;
3403 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3405 GetLocalTime(&st);
3406 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u%+03d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
3407 st.wSecond, st.wMilliseconds * 1000, -Bias );
3408 return ret;
3410 static WCHAR *get_systemdirectory(void)
3412 void *redir;
3413 WCHAR *ret;
3415 if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL;
3416 Wow64DisableWow64FsRedirection( &redir );
3417 GetSystemDirectoryW( ret, MAX_PATH );
3418 Wow64RevertWow64FsRedirection( redir );
3419 return ret;
3421 static WCHAR *get_systemdrive(void)
3423 WCHAR *ret = heap_alloc( 3 * sizeof(WCHAR) ); /* "c:" */
3424 if (ret && GetEnvironmentVariableW( L"SystemDrive", ret, 3 )) return ret;
3425 heap_free( ret );
3426 return NULL;
3428 static WCHAR *get_codeset(void)
3430 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3431 if (ret) swprintf( ret, 11, L"%u", GetACP() );
3432 return ret;
3434 static WCHAR *get_countrycode(void)
3436 WCHAR *ret = heap_alloc( 6 * sizeof(WCHAR) );
3437 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 );
3438 return ret;
3440 static WCHAR *get_locale(void)
3442 WCHAR *ret = heap_alloc( 5 * sizeof(WCHAR) );
3443 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 );
3444 return ret;
3446 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
3448 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3449 if (ret) swprintf( ret, 11, L"%u", ver->dwBuildNumber );
3450 return ret;
3452 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
3454 static const WCHAR windowsW[] = L"Microsoft Windows ";
3455 static const WCHAR win2000W[] = L"2000 Professional";
3456 static const WCHAR win2003W[] = L"Server 2003 Standard Edition";
3457 static const WCHAR winxpW[] = L"XP Professional";
3458 static const WCHAR winxp64W[] = L"XP Professional x64 Edition";
3459 static const WCHAR vistaW[] = L"Vista Ultimate";
3460 static const WCHAR win2008W[] = L"Server 2008 Standard";
3461 static const WCHAR win7W[] = L"7 Professional";
3462 static const WCHAR win2008r2W[] = L"Server 2008 R2 Standard";
3463 static const WCHAR win8W[] = L"8 Pro";
3464 static const WCHAR win81W[] = L"8.1 Pro";
3465 static const WCHAR win10W[] = L"10 Pro";
3466 int len = ARRAY_SIZE( windowsW ) - 1;
3467 WCHAR *ret;
3469 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL;
3470 memcpy( ret, windowsW, sizeof(windowsW) );
3471 if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) );
3472 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win81W, sizeof(win81W) );
3473 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win8W, sizeof(win8W) );
3474 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1)
3476 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) );
3477 else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) );
3479 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0)
3481 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) );
3482 else memcpy( ret + len, win2008W, sizeof(win2008W) );
3484 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2)
3486 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) );
3487 else memcpy( ret + len, win2003W, sizeof(win2003W) );
3489 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) );
3490 else memcpy( ret + len, win2000W, sizeof(win2000W) );
3491 return ret;
3493 static WCHAR *get_osname( const WCHAR *caption )
3495 static const WCHAR partitionW[] = L"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3496 int len = lstrlenW( caption );
3497 WCHAR *ret;
3499 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
3500 memcpy( ret, caption, len * sizeof(WCHAR) );
3501 memcpy( ret + len, partitionW, sizeof(partitionW) );
3502 return ret;
3504 static WCHAR *get_osserialnumber(void)
3506 HKEY hkey = 0;
3507 DWORD size, type;
3508 WCHAR *ret = NULL;
3510 if (!RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hkey ) &&
3511 !RegQueryValueExW( hkey, L"ProductId", NULL, &type, NULL, &size ) && type == REG_SZ &&
3512 (ret = heap_alloc( size + sizeof(WCHAR) )))
3514 size += sizeof(WCHAR);
3515 if (RegQueryValueExW( hkey, L"ProductId", NULL, NULL, (BYTE *)ret, &size ))
3517 heap_free( ret );
3518 ret = NULL;
3521 if (hkey) RegCloseKey( hkey );
3522 if (!ret) return heap_strdupW( L"12345-OEM-1234567-12345" );
3523 return ret;
3525 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
3527 WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) );
3528 if (ret) swprintf( ret, 33, L"%u.%u.%u", ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
3529 return ret;
3531 static DWORD get_operatingsystemsku(void)
3533 DWORD ret = PRODUCT_UNDEFINED;
3534 GetProductInfo( 6, 0, 0, 0, &ret );
3535 return ret;
3537 static INT16 get_currenttimezone(void)
3539 TIME_ZONE_INFORMATION info;
3540 DWORD status = GetTimeZoneInformation( &info );
3541 if (status == TIME_ZONE_ID_INVALID) return 0;
3542 if (status == TIME_ZONE_ID_DAYLIGHT) return -(info.Bias + info.DaylightBias);
3543 return -(info.Bias + info.StandardBias);
3546 static enum fill_status fill_operatingsystem( struct table *table, const struct expr *cond )
3548 struct record_operatingsystem *rec;
3549 enum fill_status status = FILL_STATUS_UNFILTERED;
3550 RTL_OSVERSIONINFOEXW ver;
3551 UINT row = 0;
3553 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3555 ver.dwOSVersionInfoSize = sizeof(ver);
3556 RtlGetVersion( &ver );
3558 rec = (struct record_operatingsystem *)table->data;
3559 rec->buildnumber = get_osbuildnumber( &ver );
3560 rec->caption = get_oscaption( &ver );
3561 rec->codeset = get_codeset();
3562 rec->countrycode = get_countrycode();
3563 rec->csdversion = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL;
3564 rec->csname = get_computername();
3565 rec->currenttimezone = get_currenttimezone();
3566 rec->freephysicalmemory = get_available_physical_memory() / 1024;
3567 rec->installdate = L"20140101000000.000000+000";
3568 rec->lastbootuptime = get_lastbootuptime();
3569 rec->localdatetime = get_localdatetime();
3570 rec->locale = get_locale();
3571 rec->manufacturer = L"The Wine Project";
3572 rec->name = get_osname( rec->caption );
3573 rec->operatingsystemsku = get_operatingsystemsku();
3574 rec->osarchitecture = get_osarchitecture();
3575 rec->oslanguage = GetSystemDefaultLangID();
3576 rec->osproductsuite = 2461140; /* Windows XP Professional */
3577 rec->ostype = 18; /* WINNT */
3578 rec->primary = -1;
3579 rec->producttype = 1;
3580 rec->serialnumber = get_osserialnumber();
3581 rec->servicepackmajor = ver.wServicePackMajor;
3582 rec->servicepackminor = ver.wServicePackMinor;
3583 rec->suitemask = 272; /* Single User + Terminal */
3584 rec->systemdirectory = get_systemdirectory();
3585 rec->systemdrive = get_systemdrive();
3586 rec->totalvirtualmemorysize = get_total_physical_memory() / 1024;
3587 rec->totalvisiblememorysize = rec->totalvirtualmemorysize;
3588 rec->version = get_osversion( &ver );
3589 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3590 else row++;
3592 TRACE("created %u rows\n", row);
3593 table->num_rows = row;
3594 return status;
3597 static const WCHAR *get_service_type( DWORD type )
3599 if (type & SERVICE_KERNEL_DRIVER) return L"Kernel Driver";
3600 else if (type & SERVICE_FILE_SYSTEM_DRIVER) return L"File System Driver";
3601 else if (type & SERVICE_WIN32_OWN_PROCESS) return L"Own Process";
3602 else if (type & SERVICE_WIN32_SHARE_PROCESS) return L"Share Process";
3603 else ERR("unhandled type 0x%08x\n", type);
3604 return NULL;
3606 static const WCHAR *get_service_state( DWORD state )
3608 switch (state)
3610 case SERVICE_STOPPED: return L"Stopped";
3611 case SERVICE_START_PENDING: return L"Start Pending";
3612 case SERVICE_STOP_PENDING: return L"Stop Pending";
3613 case SERVICE_RUNNING: return L"Running";
3614 default:
3615 ERR("unknown state %u\n", state);
3616 return L"Unknown";
3619 static const WCHAR *get_service_startmode( DWORD mode )
3621 switch (mode)
3623 case SERVICE_BOOT_START: return L"Boot";
3624 case SERVICE_SYSTEM_START: return L"System";
3625 case SERVICE_AUTO_START: return L"Auto";
3626 case SERVICE_DEMAND_START: return L"Manual";
3627 case SERVICE_DISABLED: return L"Disabled";
3628 default:
3629 ERR("unknown mode 0x%x\n", mode);
3630 return L"Unknown";
3633 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
3635 QUERY_SERVICE_CONFIGW *config = NULL;
3636 SC_HANDLE service;
3637 DWORD size;
3639 if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL;
3640 QueryServiceConfigW( service, NULL, 0, &size );
3641 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
3642 if (!(config = heap_alloc( size ))) goto done;
3643 if (QueryServiceConfigW( service, config, size, &size )) goto done;
3644 heap_free( config );
3645 config = NULL;
3647 done:
3648 CloseServiceHandle( service );
3649 return config;
3652 static enum fill_status fill_service( struct table *table, const struct expr *cond )
3654 struct record_service *rec;
3655 SC_HANDLE manager;
3656 ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL;
3657 SERVICE_STATUS_PROCESS *status;
3658 WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
3659 DWORD len = ARRAY_SIZE( sysnameW );
3660 UINT i, row = 0, offset = 0, size = 256, needed, count;
3661 enum fill_status fill_status = FILL_STATUS_FAILED;
3662 BOOL ret;
3664 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED;
3665 if (!(services = heap_alloc( size ))) goto done;
3667 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3668 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3669 &count, NULL, NULL );
3670 if (!ret)
3672 if (GetLastError() != ERROR_MORE_DATA) goto done;
3673 size = needed;
3674 if (!(tmp = heap_realloc( services, size ))) goto done;
3675 services = tmp;
3676 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3677 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3678 &count, NULL, NULL );
3679 if (!ret) goto done;
3681 if (!resize_table( table, count, sizeof(*rec) )) goto done;
3683 GetComputerNameW( sysnameW, &len );
3684 fill_status = FILL_STATUS_UNFILTERED;
3686 for (i = 0; i < count; i++)
3688 QUERY_SERVICE_CONFIGW *config;
3690 if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue;
3692 status = &services[i].ServiceStatusProcess;
3693 rec = (struct record_service *)(table->data + offset);
3694 rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0;
3695 rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0;
3696 rec->displayname = heap_strdupW( services[i].lpDisplayName );
3697 rec->name = heap_strdupW( services[i].lpServiceName );
3698 rec->process_id = status->dwProcessId;
3699 rec->servicetype = get_service_type( status->dwServiceType );
3700 rec->startmode = get_service_startmode( config->dwStartType );
3701 rec->state = get_service_state( status->dwCurrentState );
3702 rec->systemname = heap_strdupW( sysnameW );
3703 rec->pause_service = service_pause_service;
3704 rec->resume_service = service_resume_service;
3705 rec->start_service = service_start_service;
3706 rec->stop_service = service_stop_service;
3707 heap_free( config );
3708 if (!match_row( table, row, cond, &fill_status ))
3710 free_row_values( table, row );
3711 continue;
3713 offset += sizeof(*rec);
3714 row++;
3717 TRACE("created %u rows\n", row);
3718 table->num_rows = row;
3720 done:
3721 CloseServiceHandle( manager );
3722 heap_free( services );
3723 return fill_status;
3726 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
3728 if (!name || !name->Name.Buffer) return NULL;
3729 return heap_strdupW( name->Name.Buffer );
3731 static struct array *get_binaryrepresentation( PSID sid, UINT len )
3733 struct array *ret;
3734 UINT8 *ptr;
3736 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
3737 if (!(ptr = heap_alloc( len )))
3739 heap_free( ret );
3740 return NULL;
3742 memcpy( ptr, sid, len );
3743 ret->elem_size = sizeof(*ptr);
3744 ret->count = len;
3745 ret->ptr = ptr;
3746 return ret;
3748 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
3750 if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL;
3751 return heap_strdupW( domain->Domains->Name.Buffer );
3753 static const WCHAR *find_sid_str( const struct expr *cond )
3755 const struct expr *left, *right;
3756 const WCHAR *ret = NULL;
3758 if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL;
3760 left = cond->u.expr.left;
3761 right = cond->u.expr.right;
3762 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !wcsicmp( left->u.propval->name, L"SID" ))
3764 ret = right->u.sval;
3766 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !wcsicmp( right->u.propval->name, L"SID" ))
3768 ret = left->u.sval;
3770 return ret;
3773 static enum fill_status fill_sid( struct table *table, const struct expr *cond )
3775 PSID sid;
3776 LSA_REFERENCED_DOMAIN_LIST *domain;
3777 LSA_TRANSLATED_NAME *name;
3778 LSA_HANDLE handle;
3779 LSA_OBJECT_ATTRIBUTES attrs;
3780 const WCHAR *str;
3781 struct record_sid *rec;
3782 UINT len;
3784 if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED;
3785 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3787 if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED;
3788 len = GetLengthSid( sid );
3790 memset( &attrs, 0, sizeof(attrs) );
3791 attrs.Length = sizeof(attrs);
3792 if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ))
3794 LocalFree( sid );
3795 return FILL_STATUS_FAILED;
3797 if (LsaLookupSids( handle, 1, &sid, &domain, &name ))
3799 LocalFree( sid );
3800 LsaClose( handle );
3801 return FILL_STATUS_FAILED;
3804 rec = (struct record_sid *)table->data;
3805 rec->accountname = get_accountname( name );
3806 rec->binaryrepresentation = get_binaryrepresentation( sid, len );
3807 rec->referenceddomainname = get_referenceddomainname( domain );
3808 rec->sid = heap_strdupW( str );
3809 rec->sidlength = len;
3811 TRACE("created 1 row\n");
3812 table->num_rows = 1;
3814 LsaFreeMemory( domain );
3815 LsaFreeMemory( name );
3816 LocalFree( sid );
3817 LsaClose( handle );
3818 return FILL_STATUS_FILTERED;
3821 static WCHAR *get_systemenclosure_string( BYTE id, const char *buf, UINT len )
3823 const struct smbios_header *hdr;
3824 const struct smbios_chassis *chassis;
3825 UINT offset;
3827 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len ))) return NULL;
3829 chassis = (const struct smbios_chassis *)hdr;
3830 offset = (const char *)chassis - buf + chassis->hdr.length;
3831 return get_smbios_string( id, buf, offset, len );
3834 static WCHAR *get_systemenclosure_manufacturer( const char *buf, UINT len )
3836 WCHAR *ret = get_systemenclosure_string( 1, buf, len );
3837 if (!ret) return heap_strdupW( L"Wine" );
3838 return ret;
3841 static int get_systemenclosure_lockpresent( const char *buf, UINT len )
3843 const struct smbios_header *hdr;
3844 const struct smbios_chassis *chassis;
3846 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) return 0;
3848 chassis = (const struct smbios_chassis *)hdr;
3849 return (chassis->type & 0x80) ? -1 : 0;
3852 static struct array *dup_array( const struct array *src )
3854 struct array *dst;
3855 if (!(dst = heap_alloc( sizeof(*dst) ))) return NULL;
3856 if (!(dst->ptr = heap_alloc( src->count * src->elem_size )))
3858 heap_free( dst );
3859 return NULL;
3861 memcpy( dst->ptr, src->ptr, src->count * src->elem_size );
3862 dst->elem_size = src->elem_size;
3863 dst->count = src->count;
3864 return dst;
3867 static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len )
3869 const struct smbios_header *hdr;
3870 const struct smbios_chassis *chassis;
3871 struct array *ret = NULL;
3872 UINT16 *types;
3874 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) goto done;
3875 chassis = (const struct smbios_chassis *)hdr;
3877 if (!(ret = heap_alloc( sizeof(*ret) ))) goto done;
3878 if (!(types = heap_alloc( sizeof(*types) )))
3880 heap_free( ret );
3881 return NULL;
3883 types[0] = chassis->type & ~0x80;
3885 ret->elem_size = sizeof(*types);
3886 ret->count = 1;
3887 ret->ptr = types;
3889 done:
3890 if (!ret) ret = dup_array( &systemenclosure_chassistypes_array );
3891 return ret;
3894 static enum fill_status fill_systemenclosure( struct table *table, const struct expr *cond )
3896 struct record_systemenclosure *rec;
3897 enum fill_status status = FILL_STATUS_UNFILTERED;
3898 UINT row = 0, len;
3899 char *buf;
3901 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3903 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
3904 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
3905 GetSystemFirmwareTable( RSMB, 0, buf, len );
3907 rec = (struct record_systemenclosure *)table->data;
3908 rec->caption = L"System Enclosure";
3909 rec->chassistypes = get_systemenclosure_chassistypes( buf, len );
3910 rec->description = L"System Enclosure";
3911 rec->lockpresent = get_systemenclosure_lockpresent( buf, len );
3912 rec->manufacturer = get_systemenclosure_manufacturer( buf, len );
3913 rec->name = L"System Enclosure";
3914 rec->tag = L"System Enclosure 0";
3915 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3916 else row++;
3918 heap_free( buf );
3920 TRACE("created %u rows\n", row);
3921 table->num_rows = row;
3922 return status;
3925 static WCHAR *get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
3927 static const WCHAR fmtW[] = L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
3928 UINT len = sizeof(fmtW) + 2;
3929 WCHAR *ret;
3931 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
3932 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
3933 return ret;
3936 #define HW_VENDOR_AMD 0x1002
3937 #define HW_VENDOR_NVIDIA 0x10de
3938 #define HW_VENDOR_VMWARE 0x15ad
3939 #define HW_VENDOR_INTEL 0x8086
3941 static const WCHAR *get_videocontroller_installeddriver( UINT vendorid )
3943 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
3945 if (vendorid == HW_VENDOR_AMD) return L"aticfx32.dll";
3946 else if (vendorid == HW_VENDOR_NVIDIA) return L"nvd3dum.dll";
3947 else if (vendorid == HW_VENDOR_INTEL) return L"igdudim32.dll";
3948 return L"wine.dll";
3951 static BOOL get_dxgi_adapter_desc( DXGI_ADAPTER_DESC *desc )
3953 IDXGIFactory *factory;
3954 IDXGIAdapter *adapter;
3955 HRESULT hr;
3957 memset( desc, 0, sizeof(*desc) );
3958 hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
3959 if (FAILED( hr )) return FALSE;
3961 hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
3962 if (FAILED( hr ))
3964 IDXGIFactory_Release( factory );
3965 return FALSE;
3968 hr = IDXGIAdapter_GetDesc( adapter, desc );
3969 IDXGIAdapter_Release( adapter );
3970 IDXGIFactory_Release( factory );
3971 return SUCCEEDED( hr );
3974 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
3976 struct record_videocontroller *rec;
3977 DXGI_ADAPTER_DESC desc;
3978 UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
3979 const WCHAR *name = L"VideoController1";
3980 enum fill_status status = FILL_STATUS_UNFILTERED;
3981 WCHAR mode[44];
3983 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3985 if (get_dxgi_adapter_desc( &desc ))
3987 if (desc.DedicatedVideoMemory > UINT_MAX) vidmem = 0xfff00000;
3988 else vidmem = desc.DedicatedVideoMemory;
3989 name = desc.Description;
3992 rec = (struct record_videocontroller *)table->data;
3993 rec->adapter_compatibility = L"(Standard display types)";
3994 rec->adapter_dactype = L"Integrated RAMDAC";
3995 rec->adapter_ram = vidmem;
3996 rec->availability = 3; /* Running or Full Power */
3997 rec->config_errorcode = 0; /* no error */
3998 rec->caption = heap_strdupW( name );
3999 rec->current_bitsperpixel = get_bitsperpixel( &hres, &vres );
4000 rec->current_horizontalres = hres;
4001 rec->current_refreshrate = 0; /* default refresh rate */
4002 rec->current_scanmode = 2; /* Unknown */
4003 rec->current_verticalres = vres;
4004 rec->description = heap_strdupW( name );
4005 rec->device_id = L"VideoController1";
4006 rec->driverdate = L"20170101000000.000000+000";
4007 rec->driverversion = L"1.0";
4008 rec->installeddriver = get_videocontroller_installeddriver( desc.VendorId );
4009 rec->name = heap_strdupW( name );
4010 rec->pnpdevice_id = get_videocontroller_pnpdeviceid( &desc );
4011 rec->status = L"OK";
4012 rec->videoarchitecture = 2; /* Unknown */
4013 rec->videomemorytype = 2; /* Unknown */
4014 swprintf( mode, ARRAY_SIZE( mode ), L"%u x %u x %I64u colors", hres, vres, (UINT64)1 << rec->current_bitsperpixel );
4015 rec->videomodedescription = heap_strdupW( mode );
4016 rec->videoprocessor = heap_strdupW( name );
4017 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4018 else row++;
4020 TRACE("created %u rows\n", row);
4021 table->num_rows = row;
4022 return status;
4025 static WCHAR *get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
4027 static const WCHAR fmtW[] = L"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
4028 UINT len = sizeof(fmtW) + 2;
4029 WCHAR *ret;
4031 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
4032 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
4033 return ret;
4036 static enum fill_status fill_sounddevice( struct table *table, const struct expr *cond )
4038 struct record_sounddevice *rec;
4039 DXGI_ADAPTER_DESC desc;
4040 UINT row = 0;
4041 enum fill_status status = FILL_STATUS_UNFILTERED;
4043 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
4045 get_dxgi_adapter_desc( &desc );
4047 rec = (struct record_sounddevice *)table->data;
4048 rec->deviceid = get_sounddevice_pnpdeviceid( &desc );
4049 rec->manufacturer = L"The Wine Project";
4050 rec->name = L"Wine Audio Device";
4051 rec->pnpdeviceid = get_sounddevice_pnpdeviceid( &desc );
4052 rec->productname = L"Wine Audio Device";
4053 rec->status = L"OK";
4054 rec->statusinfo = 3;
4055 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
4056 else row++;
4058 TRACE("created %u rows\n", row);
4059 table->num_rows = row;
4060 return status;
4063 #define C(c) sizeof(c)/sizeof(c[0]), c
4064 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
4065 static struct table builtin_classes[] =
4067 { L"__ASSOCIATORS", C(col_associator), D(data_associator) },
4068 { L"__PARAMETERS", C(col_param), D(data_param) },
4069 { L"__QUALIFIERS", C(col_qualifier), D(data_qualifier) },
4070 { L"__SystemSecurity", C(col_systemsecurity), D(data_systemsecurity) },
4071 { L"CIM_DataFile", C(col_datafile), 0, 0, NULL, fill_datafile },
4072 { L"CIM_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
4073 { L"CIM_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4074 { L"StdRegProv", C(col_stdregprov), D(data_stdregprov) },
4075 { L"SystemRestore", C(col_sysrestore), D(data_sysrestore) },
4076 { L"Win32_BIOS", C(col_bios), 0, 0, NULL, fill_bios },
4077 { L"Win32_BaseBoard", C(col_baseboard), 0, 0, NULL, fill_baseboard },
4078 { L"Win32_CDROMDrive", C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
4079 { L"Win32_ComputerSystem", C(col_compsys), 0, 0, NULL, fill_compsys },
4080 { L"Win32_ComputerSystemProduct", C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct },
4081 { L"Win32_DesktopMonitor", C(col_desktopmonitor), 0, 0, NULL, fill_desktopmonitor },
4082 { L"Win32_Directory", C(col_directory), 0, 0, NULL, fill_directory },
4083 { L"Win32_DiskDrive", C(col_diskdrive), 0, 0, NULL, fill_diskdrive },
4084 { L"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition), 0, 0, NULL, fill_diskdrivetodiskpartition },
4085 { L"Win32_DiskPartition", C(col_diskpartition), 0, 0, NULL, fill_diskpartition },
4086 { L"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig), 0, 0, NULL, fill_displaycontrollerconfig },
4087 { L"Win32_IP4RouteTable", C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable },
4088 { L"Win32_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
4089 { L"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition), 0, 0, NULL, fill_logicaldisktopartition },
4090 { L"Win32_NetworkAdapter", C(col_networkadapter), 0, 0, NULL, fill_networkadapter },
4091 { L"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig },
4092 { L"Win32_OperatingSystem", C(col_operatingsystem), 0, 0, NULL, fill_operatingsystem },
4093 { L"Win32_PhysicalMedia", C(col_physicalmedia), D(data_physicalmedia) },
4094 { L"Win32_PhysicalMemory", C(col_physicalmemory), 0, 0, NULL, fill_physicalmemory },
4095 { L"Win32_PnPEntity", C(col_pnpentity), 0, 0, NULL, fill_pnpentity },
4096 { L"Win32_Printer", C(col_printer), 0, 0, NULL, fill_printer },
4097 { L"Win32_Process", C(col_process), 0, 0, NULL, fill_process },
4098 { L"Win32_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4099 { L"Win32_QuickFixEngineering", C(col_quickfixengineering), D(data_quickfixengineering) },
4100 { L"Win32_SID", C(col_sid), 0, 0, NULL, fill_sid },
4101 { L"Win32_Service", C(col_service), 0, 0, NULL, fill_service },
4102 { L"Win32_SoundDevice", C(col_sounddevice), 0, 0, NULL, fill_sounddevice },
4103 { L"Win32_SystemEnclosure", C(col_systemenclosure), 0, 0, NULL, fill_systemenclosure },
4104 { L"Win32_VideoController", C(col_videocontroller), 0, 0, NULL, fill_videocontroller },
4105 { L"Win32_WinSAT", C(col_winsat), D(data_winsat) },
4107 #undef C
4108 #undef D
4110 void init_table_list( void )
4112 static struct list tables = LIST_INIT( tables );
4113 UINT i;
4115 for (i = 0; i < ARRAY_SIZE(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry );
4116 table_list = &tables;