wbemprox: Mark some string properties as dynamic.
[wine.git] / dlls / wbemprox / builtin.c
blob9bd58ca77e6587b38e2c2e855ea4d5a03283367d
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"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
181 { L"DriveType", CIM_UINT32 },
182 { L"FileSystem", CIM_STRING|COL_FLAG_DYNAMIC },
183 { L"FreeSpace", CIM_UINT64 },
184 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
185 { L"Size", CIM_UINT64 },
186 { L"VolumeName", CIM_STRING|COL_FLAG_DYNAMIC },
187 { L"VolumeSerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
189 static const struct column col_logicaldisktopartition[] =
191 { L"Antecedent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
192 { L"Dependent", CIM_REFERENCE|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
194 static const struct column col_networkadapter[] =
196 { L"AdapterType", CIM_STRING },
197 { L"AdapterTypeID", CIM_UINT16 },
198 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
199 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
200 { L"Index", CIM_UINT32 },
201 { L"InterfaceIndex", CIM_UINT32 },
202 { L"MACAddress", CIM_STRING|COL_FLAG_DYNAMIC },
203 { L"Manufacturer", CIM_STRING },
204 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
205 { L"NetConnectionStatus", CIM_UINT16 },
206 { L"PhysicalAdapter", CIM_BOOLEAN },
207 { L"PNPDeviceID", CIM_STRING },
208 { L"Speed", CIM_UINT64 },
210 static const struct column col_networkadapterconfig[] =
212 { L"DefaultIPGateway", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
213 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
214 { L"DHCPEnabled", CIM_BOOLEAN },
215 { L"DNSHostName", CIM_STRING|COL_FLAG_DYNAMIC },
216 { L"DNSServerSearchOrder", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
217 { L"Index", CIM_UINT32|COL_FLAG_KEY },
218 { L"IPAddress", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
219 { L"IPConnectionMetric", CIM_UINT32 },
220 { L"IPEnabled", CIM_BOOLEAN },
221 { L"IPSubnet", CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
222 { L"MACAddress", CIM_STRING|COL_FLAG_DYNAMIC },
223 { L"SettingID", CIM_STRING|COL_FLAG_DYNAMIC },
225 static const struct column col_operatingsystem[] =
227 { L"BuildNumber", CIM_STRING|COL_FLAG_DYNAMIC },
228 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
229 { L"CodeSet", CIM_STRING|COL_FLAG_DYNAMIC },
230 { L"CountryCode", CIM_STRING|COL_FLAG_DYNAMIC },
231 { L"CSDVersion", CIM_STRING|COL_FLAG_DYNAMIC },
232 { L"CSName", CIM_STRING|COL_FLAG_DYNAMIC },
233 { L"CurrentTimeZone", CIM_SINT16 },
234 { L"FreePhysicalMemory", CIM_UINT64 },
235 { L"InstallDate", CIM_DATETIME },
236 { L"LastBootUpTime", CIM_DATETIME|COL_FLAG_DYNAMIC },
237 { L"LocalDateTime", CIM_DATETIME|COL_FLAG_DYNAMIC },
238 { L"Locale", CIM_STRING|COL_FLAG_DYNAMIC },
239 { L"Manufacturer", CIM_STRING },
240 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
241 { L"OperatingSystemSKU", CIM_UINT32 },
242 { L"OSArchitecture", CIM_STRING },
243 { L"OSLanguage", CIM_UINT32 },
244 { L"OSProductSuite", CIM_UINT32 },
245 { L"OSType", CIM_UINT16 },
246 { L"Primary", CIM_BOOLEAN },
247 { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC },
248 { L"ServicePackMajorVersion", CIM_UINT16 },
249 { L"ServicePackMinorVersion", CIM_UINT16 },
250 { L"SuiteMask", CIM_UINT32 },
251 { L"SystemDirectory", CIM_STRING|COL_FLAG_DYNAMIC },
252 { L"SystemDrive", CIM_STRING|COL_FLAG_DYNAMIC },
253 { L"TotalVirtualMemorySize", CIM_UINT64 },
254 { L"TotalVisibleMemorySize", CIM_UINT64 },
255 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
257 static const struct column col_param[] =
259 { L"Class", CIM_STRING },
260 { L"Method", CIM_STRING },
261 { L"Direction", CIM_SINT32 },
262 { L"Parameter", CIM_STRING },
263 { L"Type", CIM_UINT32 },
264 { L"DefaultValue", CIM_UINT32 },
266 static const struct column col_physicalmedia[] =
268 { L"SerialNumber", CIM_STRING },
269 { L"Tag", CIM_STRING },
271 static const struct column col_physicalmemory[] =
273 { L"BankLabel", CIM_STRING },
274 { L"Capacity", CIM_UINT64 },
275 { L"Caption", CIM_STRING },
276 { L"ConfiguredClockSpeed", CIM_UINT32 },
277 { L"DeviceLocator", CIM_STRING },
278 { L"FormFactor", CIM_UINT16 },
279 { L"MemoryType", CIM_UINT16 },
280 { L"PartNumber", CIM_STRING },
281 { L"SerialNumber", CIM_STRING },
283 static const struct column col_pnpentity[] =
285 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC },
287 static const struct column col_printer[] =
289 { L"Attributes", CIM_UINT32 },
290 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
291 { L"DriverName", CIM_STRING|COL_FLAG_DYNAMIC },
292 { L"HorizontalResolution", CIM_UINT32 },
293 { L"Local", CIM_BOOLEAN },
294 { L"Location", CIM_STRING|COL_FLAG_DYNAMIC },
295 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
296 { L"Network", CIM_BOOLEAN },
297 { L"PortName", CIM_STRING|COL_FLAG_DYNAMIC },
299 static const struct column col_process[] =
301 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
302 { L"CommandLine", CIM_STRING|COL_FLAG_DYNAMIC },
303 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
304 { L"Handle", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
305 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
306 { L"ParentProcessID", CIM_UINT32 },
307 { L"ProcessID", CIM_UINT32 },
308 { L"ThreadCount", CIM_UINT32 },
309 { L"WorkingSetSize", CIM_UINT64 },
310 /* methods */
311 { L"GetOwner", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
313 static const struct column col_processor[] =
315 { L"AddressWidth", CIM_UINT16 },
316 { L"Architecture", CIM_UINT16 },
317 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
318 { L"CpuStatus", CIM_UINT16 },
319 { L"CurrentClockSpeed", CIM_UINT32 },
320 { L"DataWidth", CIM_UINT16 },
321 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
322 { L"DeviceId", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
323 { L"Family", CIM_UINT16 },
324 { L"Level", CIM_UINT16 },
325 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
326 { L"MaxClockSpeed", CIM_UINT32 },
327 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
328 { L"NumberOfCores", CIM_UINT32 },
329 { L"NumberOfLogicalProcessors", CIM_UINT32 },
330 { L"ProcessorId", CIM_STRING|COL_FLAG_DYNAMIC },
331 { L"ProcessorType", CIM_UINT16 },
332 { L"Revision", CIM_UINT16 },
333 { L"UniqueId", CIM_STRING },
334 { L"Version", CIM_STRING|COL_FLAG_DYNAMIC },
336 static const struct column col_qualifier[] =
338 { L"Class", CIM_STRING },
339 { L"Member", CIM_STRING },
340 { L"Type", CIM_UINT32 },
341 { L"Flavor", CIM_SINT32 },
342 { L"Name", CIM_STRING },
343 { L"IntegerValue", CIM_SINT32 },
344 { L"StringValue", CIM_STRING },
345 { L"BoolValue", CIM_BOOLEAN },
347 static const struct column col_quickfixengineering[] =
349 { L"Caption", CIM_STRING },
350 { L"HotFixID", CIM_STRING|COL_FLAG_KEY },
352 static const struct column col_service[] =
354 { L"AcceptPause", CIM_BOOLEAN },
355 { L"AcceptStop", CIM_BOOLEAN },
356 { L"DisplayName", CIM_STRING|COL_FLAG_DYNAMIC },
357 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
358 { L"ProcessID", CIM_UINT32 },
359 { L"ServiceType", CIM_STRING },
360 { L"StartMode", CIM_STRING },
361 { L"State", CIM_STRING },
362 { L"SystemName", CIM_STRING|COL_FLAG_DYNAMIC },
363 /* methods */
364 { L"PauseService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
365 { L"ResumeService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
366 { L"StartService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
367 { L"StopService", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
369 static const struct column col_sid[] =
371 { L"AccountName", CIM_STRING|COL_FLAG_DYNAMIC },
372 { L"BinaryRepresentation", CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
373 { L"ReferencedDomainName", CIM_STRING|COL_FLAG_DYNAMIC },
374 { L"SID", CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
375 { L"SidLength", CIM_UINT32 },
377 static const struct column col_sounddevice[] =
379 { L"DeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
380 { L"Manufacturer", CIM_STRING },
381 { L"Name", CIM_STRING },
382 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
383 { L"ProductName", CIM_STRING },
384 { L"Status", CIM_STRING },
385 { L"StatusInfo", CIM_UINT16 },
387 static const struct column col_stdregprov[] =
389 { L"CreateKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
390 { L"EnumKey", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
391 { L"EnumValues", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
392 { L"GetStringValue", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
394 static const struct column col_systemenclosure[] =
396 { L"Caption", CIM_STRING },
397 { L"ChassisTypes", CIM_UINT16|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC },
398 { L"Description", CIM_STRING },
399 { L"LockPresent", CIM_BOOLEAN },
400 { L"Manufacturer", CIM_STRING|COL_FLAG_DYNAMIC },
401 { L"Name", CIM_STRING },
402 { L"Tag", CIM_STRING },
404 static const struct column col_systemsecurity[] =
406 { L"GetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
407 { L"SetSD", CIM_FLAG_ARRAY|COL_FLAG_METHOD },
409 static const struct column col_videocontroller[] =
411 { L"AdapterCompatibility", CIM_STRING },
412 { L"AdapterDACType", CIM_STRING },
413 { L"AdapterRAM", CIM_UINT32 },
414 { L"Availability", CIM_UINT16 },
415 { L"Caption", CIM_STRING|COL_FLAG_DYNAMIC },
416 { L"ConfigManagerErrorCode", CIM_UINT32 },
417 { L"CurrentBitsPerPixel", CIM_UINT32 },
418 { L"CurrentHorizontalResolution", CIM_UINT32 },
419 { L"CurrentRefreshRate", CIM_UINT32 },
420 { L"CurrentScanMode", CIM_UINT16 },
421 { L"CurrentVerticalResolution", CIM_UINT32 },
422 { L"Description", CIM_STRING|COL_FLAG_DYNAMIC },
423 { L"DeviceId", CIM_STRING|COL_FLAG_KEY },
424 { L"DriverDate", CIM_DATETIME },
425 { L"DriverVersion", CIM_STRING },
426 { L"InstalledDisplayDrivers", CIM_STRING },
427 { L"Name", CIM_STRING|COL_FLAG_DYNAMIC },
428 { L"PNPDeviceID", CIM_STRING|COL_FLAG_DYNAMIC },
429 { L"Status", CIM_STRING },
430 { L"VideoArchitecture", CIM_UINT16 },
431 { L"VideoMemoryType", CIM_UINT16 },
432 { L"VideoModeDescription", CIM_STRING|COL_FLAG_DYNAMIC },
433 { L"VideoProcessor", CIM_STRING|COL_FLAG_DYNAMIC },
435 static const struct column col_winsat[] =
437 { L"CPUScore", CIM_REAL32 },
438 { L"D3DScore", CIM_REAL32 },
439 { L"DiskScore", CIM_REAL32 },
440 { L"GraphicsScore", CIM_REAL32 },
441 { L"MemoryScore", CIM_REAL32 },
442 { L"TimeTaken", CIM_STRING|COL_FLAG_KEY },
443 { L"WinSATAssessmentState", CIM_UINT32 },
444 { L"WinSPRLevel", CIM_REAL32 },
447 #include "pshpack1.h"
448 struct record_associator
450 const WCHAR *assocclass;
451 const WCHAR *class;
452 const WCHAR *associator;
454 struct record_baseboard
456 const WCHAR *manufacturer;
457 const WCHAR *model;
458 const WCHAR *name;
459 const WCHAR *product;
460 const WCHAR *serialnumber;
461 const WCHAR *tag;
462 const WCHAR *version;
464 struct record_bios
466 const WCHAR *currentlanguage;
467 const WCHAR *description;
468 UINT8 ecmajorversion;
469 UINT8 ecminorversion;
470 const WCHAR *identificationcode;
471 const WCHAR *manufacturer;
472 const WCHAR *name;
473 const WCHAR *releasedate;
474 const WCHAR *serialnumber;
475 const WCHAR *smbiosbiosversion;
476 UINT16 smbiosmajorversion;
477 UINT16 smbiosminorversion;
478 UINT8 systembiosmajorversion;
479 UINT8 systembiosminorversion;
480 const WCHAR *version;
482 struct record_cdromdrive
484 const WCHAR *device_id;
485 const WCHAR *drive;
486 const WCHAR *mediatype;
487 const WCHAR *name;
488 const WCHAR *pnpdevice_id;
490 struct record_computersystem
492 const WCHAR *description;
493 const WCHAR *domain;
494 UINT16 domainrole;
495 const WCHAR *manufacturer;
496 const WCHAR *model;
497 const WCHAR *name;
498 UINT32 num_logical_processors;
499 UINT32 num_processors;
500 UINT64 total_physical_memory;
501 const WCHAR *username;
503 struct record_computersystemproduct
505 const WCHAR *identifyingnumber;
506 const WCHAR *name;
507 const WCHAR *skunumber;
508 const WCHAR *uuid;
509 const WCHAR *vendor;
510 const WCHAR *version;
512 struct record_datafile
514 const WCHAR *name;
515 const WCHAR *version;
517 struct record_desktopmonitor
519 const WCHAR *name;
520 UINT32 pixelsperxlogicalinch;
522 struct record_directory
524 UINT32 accessmask;
525 const WCHAR *name;
527 struct record_diskdrive
529 const WCHAR *device_id;
530 UINT32 index;
531 const WCHAR *interfacetype;
532 const WCHAR *manufacturer;
533 const WCHAR *mediatype;
534 const WCHAR *model;
535 const WCHAR *pnpdevice_id;
536 const WCHAR *serialnumber;
537 UINT64 size;
539 struct record_diskdrivetodiskpartition
541 const WCHAR *antecedent;
542 const WCHAR *dependent;
544 struct record_diskpartition
546 int bootable;
547 int bootpartition;
548 const WCHAR *device_id;
549 UINT32 diskindex;
550 UINT32 index;
551 const WCHAR *pnpdevice_id;
552 UINT64 size;
553 UINT64 startingoffset;
554 const WCHAR *type;
556 struct record_displaycontrollerconfig
558 UINT32 bitsperpixel;
559 const WCHAR *caption;
560 UINT32 horizontalresolution;
561 const WCHAR *name;
562 UINT32 verticalresolution;
564 struct record_ip4routetable
566 const WCHAR *destination;
567 INT32 interfaceindex;
568 const WCHAR *nexthop;
570 struct record_logicaldisk
572 const WCHAR *device_id;
573 UINT32 drivetype;
574 const WCHAR *filesystem;
575 UINT64 freespace;
576 const WCHAR *name;
577 UINT64 size;
578 const WCHAR *volumename;
579 const WCHAR *volumeserialnumber;
581 struct record_logicaldisktopartition
583 const WCHAR *antecedent;
584 const WCHAR *dependent;
586 struct record_networkadapter
588 const WCHAR *adaptertype;
589 UINT16 adaptertypeid;
590 const WCHAR *description;
591 const WCHAR *device_id;
592 UINT32 index;
593 UINT32 interface_index;
594 const WCHAR *mac_address;
595 const WCHAR *manufacturer;
596 const WCHAR *name;
597 UINT16 netconnection_status;
598 int physicaladapter;
599 const WCHAR *pnpdevice_id;
600 UINT64 speed;
602 struct record_networkadapterconfig
604 const struct array *defaultipgateway;
605 const WCHAR *description;
606 int dhcpenabled;
607 const WCHAR *dnshostname;
608 const struct array *dnsserversearchorder;
609 UINT32 index;
610 const struct array *ipaddress;
611 UINT32 ipconnectionmetric;
612 int ipenabled;
613 const struct array *ipsubnet;
614 const WCHAR *mac_address;
615 const WCHAR *settingid;
617 struct record_operatingsystem
619 const WCHAR *buildnumber;
620 const WCHAR *caption;
621 const WCHAR *codeset;
622 const WCHAR *countrycode;
623 const WCHAR *csdversion;
624 const WCHAR *csname;
625 INT16 currenttimezone;
626 UINT64 freephysicalmemory;
627 const WCHAR *installdate;
628 const WCHAR *lastbootuptime;
629 const WCHAR *localdatetime;
630 const WCHAR *locale;
631 const WCHAR *manufacturer;
632 const WCHAR *name;
633 UINT32 operatingsystemsku;
634 const WCHAR *osarchitecture;
635 UINT32 oslanguage;
636 UINT32 osproductsuite;
637 UINT16 ostype;
638 int primary;
639 const WCHAR *serialnumber;
640 UINT16 servicepackmajor;
641 UINT16 servicepackminor;
642 UINT32 suitemask;
643 const WCHAR *systemdirectory;
644 const WCHAR *systemdrive;
645 UINT64 totalvirtualmemorysize;
646 UINT64 totalvisiblememorysize;
647 const WCHAR *version;
649 struct record_param
651 const WCHAR *class;
652 const WCHAR *method;
653 INT32 direction;
654 const WCHAR *parameter;
655 UINT32 type;
656 UINT32 defaultvalue;
658 struct record_physicalmedia
660 const WCHAR *serialnumber;
661 const WCHAR *tag;
663 struct record_physicalmemory
665 const WCHAR *banklabel;
666 UINT64 capacity;
667 const WCHAR *caption;
668 UINT32 configuredclockspeed;
669 const WCHAR *devicelocator;
670 UINT16 formfactor;
671 UINT16 memorytype;
672 const WCHAR *partnumber;
673 const WCHAR *serial;
675 struct record_pnpentity
677 const WCHAR *device_id;
679 struct record_printer
681 UINT32 attributes;
682 const WCHAR *device_id;
683 const WCHAR *drivername;
684 UINT32 horizontalresolution;
685 int local;
686 const WCHAR *location;
687 const WCHAR *name;
688 int network;
689 const WCHAR *portname;
691 struct record_process
693 const WCHAR *caption;
694 const WCHAR *commandline;
695 const WCHAR *description;
696 const WCHAR *handle;
697 const WCHAR *name;
698 UINT32 pprocess_id;
699 UINT32 process_id;
700 UINT32 thread_count;
701 UINT64 workingsetsize;
702 /* methods */
703 class_method *get_owner;
705 struct record_processor
707 UINT16 addresswidth;
708 UINT16 architecture;
709 const WCHAR *caption;
710 UINT16 cpu_status;
711 UINT32 currentclockspeed;
712 UINT16 datawidth;
713 const WCHAR *description;
714 const WCHAR *device_id;
715 UINT16 family;
716 UINT16 level;
717 const WCHAR *manufacturer;
718 UINT32 maxclockspeed;
719 const WCHAR *name;
720 UINT32 num_cores;
721 UINT32 num_logical_processors;
722 const WCHAR *processor_id;
723 UINT16 processortype;
724 UINT16 revision;
725 const WCHAR *unique_id;
726 const WCHAR *version;
728 struct record_qualifier
730 const WCHAR *class;
731 const WCHAR *member;
732 UINT32 type;
733 INT32 flavor;
734 const WCHAR *name;
735 INT32 intvalue;
736 const WCHAR *strvalue;
737 int boolvalue;
739 struct record_quickfixengineering
741 const WCHAR *caption;
742 const WCHAR *hotfixid;
744 struct record_service
746 int accept_pause;
747 int accept_stop;
748 const WCHAR *displayname;
749 const WCHAR *name;
750 UINT32 process_id;
751 const WCHAR *servicetype;
752 const WCHAR *startmode;
753 const WCHAR *state;
754 const WCHAR *systemname;
755 /* methods */
756 class_method *pause_service;
757 class_method *resume_service;
758 class_method *start_service;
759 class_method *stop_service;
761 struct record_sid
763 const WCHAR *accountname;
764 const struct array *binaryrepresentation;
765 const WCHAR *referenceddomainname;
766 const WCHAR *sid;
767 UINT32 sidlength;
769 struct record_sounddevice
771 const WCHAR *deviceid;
772 const WCHAR *manufacturer;
773 const WCHAR *name;
774 const WCHAR *pnpdeviceid;
775 const WCHAR *productname;
776 const WCHAR *status;
777 UINT16 statusinfo;
779 struct record_stdregprov
781 class_method *createkey;
782 class_method *enumkey;
783 class_method *enumvalues;
784 class_method *getstringvalue;
786 struct record_systemsecurity
788 class_method *getsd;
789 class_method *setsd;
791 struct record_systemenclosure
793 const WCHAR *caption;
794 const struct array *chassistypes;
795 const WCHAR *description;
796 int lockpresent;
797 const WCHAR *manufacturer;
798 const WCHAR *name;
799 const WCHAR *tag;
801 struct record_videocontroller
803 const WCHAR *adapter_compatibility;
804 const WCHAR *adapter_dactype;
805 UINT32 adapter_ram;
806 UINT16 availability;
807 const WCHAR *caption;
808 UINT32 config_errorcode;
809 UINT32 current_bitsperpixel;
810 UINT32 current_horizontalres;
811 UINT32 current_refreshrate;
812 UINT16 current_scanmode;
813 UINT32 current_verticalres;
814 const WCHAR *description;
815 const WCHAR *device_id;
816 const WCHAR *driverdate;
817 const WCHAR *driverversion;
818 const WCHAR *installeddriver;
819 const WCHAR *name;
820 const WCHAR *pnpdevice_id;
821 const WCHAR *status;
822 UINT16 videoarchitecture;
823 UINT16 videomemorytype;
824 const WCHAR *videomodedescription;
825 const WCHAR *videoprocessor;
827 struct record_winsat
829 FLOAT cpuscore;
830 FLOAT d3dscore;
831 FLOAT diskscrore;
832 FLOAT graphicsscore;
833 FLOAT memoryscore;
834 const WCHAR *timetaken;
835 UINT32 winsatassessmentstate;
836 FLOAT winsprlevel;
838 #include "poppack.h"
840 static const struct record_associator data_associator[] =
842 { L"Win32_DiskDriveToDiskPartition", L"Win32_DiskPartition", L"Win32_DiskDrive" },
843 { L"Win32_LogicalDiskToPartition", L"Win32_LogicalDisk", L"Win32_DiskPartition" },
845 static const struct record_param data_param[] =
847 { L"__SystemSecurity", L"GetSD", -1, L"ReturnValue", CIM_UINT32 },
848 { L"__SystemSecurity", L"GetSD", -1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
849 { L"__SystemSecurity", L"SetSD", 1, L"SD", CIM_UINT8|CIM_FLAG_ARRAY },
850 { L"__SystemSecurity", L"SetSD", -1, L"ReturnValue", CIM_UINT32 },
851 { L"StdRegProv", L"CreateKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
852 { L"StdRegProv", L"CreateKey", 1, L"sSubKeyName", CIM_STRING },
853 { L"StdRegProv", L"CreateKey", -1, L"ReturnValue", CIM_UINT32 },
854 { L"StdRegProv", L"EnumKey", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
855 { L"StdRegProv", L"EnumKey", 1, L"sSubKeyName", CIM_STRING },
856 { L"StdRegProv", L"EnumKey", -1, L"ReturnValue", CIM_UINT32 },
857 { L"StdRegProv", L"EnumKey", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
858 { L"StdRegProv", L"EnumValues", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
859 { L"StdRegProv", L"EnumValues", 1, L"sSubKeyName", CIM_STRING },
860 { L"StdRegProv", L"EnumValues", -1, L"ReturnValue", CIM_UINT32 },
861 { L"StdRegProv", L"EnumValues", -1, L"sNames", CIM_STRING|CIM_FLAG_ARRAY },
862 { L"StdRegProv", L"EnumValues", -1, L"Types", CIM_SINT32|CIM_FLAG_ARRAY },
863 { L"StdRegProv", L"GetStringValue", 1, L"hDefKey", CIM_SINT32, 0x80000002 },
864 { L"StdRegProv", L"GetStringValue", 1, L"sSubKeyName", CIM_STRING },
865 { L"StdRegProv", L"GetStringValue", 1, L"sValueName", CIM_STRING },
866 { L"StdRegProv", L"GetStringValue", -1, L"ReturnValue", CIM_UINT32 },
867 { L"StdRegProv", L"GetStringValue", -1, L"sValue", CIM_STRING },
868 { L"Win32_Process", L"GetOwner", -1, L"ReturnValue", CIM_UINT32 },
869 { L"Win32_Process", L"GetOwner", -1, L"User", CIM_STRING },
870 { L"Win32_Process", L"GetOwner", -1, L"Domain", CIM_STRING },
871 { L"Win32_Service", L"PauseService", -1, L"ReturnValue", CIM_UINT32 },
872 { L"Win32_Service", L"ResumeService", -1, L"ReturnValue", CIM_UINT32 },
873 { L"Win32_Service", L"StartService", -1, L"ReturnValue", CIM_UINT32 },
874 { L"Win32_Service", L"StopService", -1, L"ReturnValue", CIM_UINT32 },
877 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
878 WBEM_FLAVOR_ORIGIN_PROPAGATED)
880 static const struct record_physicalmedia data_physicalmedia[] =
882 { L"WINEHDISK", L"\\\\.\\PHYSICALDRIVE0" }
884 static const struct record_qualifier data_qualifier[] =
886 { L"__WIN32_PROCESS_GETOWNER_OUT", L"User", CIM_SINT32, FLAVOR_ID, L"ID", 0 },
887 { L"__WIN32_PROCESS_GETOWNER_OUT", L"Domain", CIM_SINT32, FLAVOR_ID, L"ID", 1 }
889 static const struct record_quickfixengineering data_quickfixengineering[] =
891 { L"http://winehq.org", L"KB1234567" },
894 static const struct record_stdregprov data_stdregprov[] =
896 { reg_create_key, reg_enum_key, reg_enum_values, reg_get_stringvalue }
898 static UINT16 systemenclosure_chassistypes[] =
902 static const struct array systemenclosure_chassistypes_array =
904 sizeof(*systemenclosure_chassistypes),
905 ARRAY_SIZE(systemenclosure_chassistypes),
906 &systemenclosure_chassistypes
908 static const struct record_systemsecurity data_systemsecurity[] =
910 { security_get_sd, security_set_sd }
912 static const struct record_winsat data_winsat[] =
914 { 8.0f, 8.0f, 8.0f, 8.0f, 8.0f, L"MostRecentAssessment", 1 /* Valid */, 8.0f },
917 /* check if row matches condition and update status */
918 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status )
920 LONGLONG val;
921 UINT type;
923 if (!cond)
925 *status = FILL_STATUS_UNFILTERED;
926 return TRUE;
928 if (eval_cond( table, row, cond, &val, &type ) != S_OK)
930 *status = FILL_STATUS_FAILED;
931 return FALSE;
933 *status = FILL_STATUS_FILTERED;
934 return val != 0;
937 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size )
939 if (!table->num_rows_allocated)
941 if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE;
942 table->num_rows_allocated = row_count;
943 return TRUE;
945 if (row_count > table->num_rows_allocated)
947 BYTE *data;
948 UINT count = max( row_count, table->num_rows_allocated * 2 );
949 if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE;
950 table->data = data;
951 table->num_rows_allocated = count;
953 return TRUE;
956 #include "pshpack1.h"
957 struct smbios_prologue
959 BYTE calling_method;
960 BYTE major_version;
961 BYTE minor_version;
962 BYTE revision;
963 DWORD length;
966 enum smbios_type
968 SMBIOS_TYPE_BIOS,
969 SMBIOS_TYPE_SYSTEM,
970 SMBIOS_TYPE_BASEBOARD,
971 SMBIOS_TYPE_CHASSIS,
974 struct smbios_header
976 BYTE type;
977 BYTE length;
978 WORD handle;
981 struct smbios_baseboard
983 struct smbios_header hdr;
984 BYTE vendor;
985 BYTE product;
986 BYTE version;
987 BYTE serial;
990 struct smbios_bios
992 struct smbios_header hdr;
993 BYTE vendor;
994 BYTE version;
995 WORD start;
996 BYTE date;
997 BYTE size;
998 UINT64 characteristics;
999 BYTE characteristics_ext[2];
1000 BYTE system_bios_major_release;
1001 BYTE system_bios_minor_release;
1002 BYTE ec_firmware_major_release;
1003 BYTE ec_firmware_minor_release;
1006 struct smbios_chassis
1008 struct smbios_header hdr;
1009 BYTE vendor;
1010 BYTE type;
1011 BYTE version;
1012 BYTE serial;
1013 BYTE asset_tag;
1016 struct smbios_system
1018 struct smbios_header hdr;
1019 BYTE vendor;
1020 BYTE product;
1021 BYTE version;
1022 BYTE serial;
1023 BYTE uuid[16];
1025 #include "poppack.h"
1027 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1029 static const struct smbios_header *find_smbios_entry( enum smbios_type type, const char *buf, UINT len )
1031 const char *ptr, *start;
1032 const struct smbios_prologue *prologue;
1033 const struct smbios_header *hdr;
1035 if (len < sizeof(struct smbios_prologue)) return NULL;
1036 prologue = (const struct smbios_prologue *)buf;
1037 if (prologue->length > len - sizeof(*prologue) || prologue->length < sizeof(*hdr)) return NULL;
1039 start = (const char *)(prologue + 1);
1040 hdr = (const struct smbios_header *)start;
1042 for (;;)
1044 if ((const char *)hdr - start >= prologue->length - sizeof(*hdr)) return NULL;
1046 if (!hdr->length)
1048 WARN( "invalid entry\n" );
1049 return NULL;
1052 if (hdr->type == type)
1054 if ((const char *)hdr - start + hdr->length > prologue->length) return NULL;
1055 break;
1057 else /* skip other entries and their strings */
1059 for (ptr = (const char *)hdr + hdr->length; ptr - buf < len && *ptr; ptr++)
1061 for (; ptr - buf < len; ptr++) if (!*ptr) break;
1063 if (ptr == (const char *)hdr + hdr->length) ptr++;
1064 hdr = (const struct smbios_header *)(ptr + 1);
1068 return hdr;
1071 static WCHAR *get_smbios_string( BYTE id, const char *buf, UINT offset, UINT buflen )
1073 const char *ptr = buf + offset;
1074 UINT i = 0;
1076 if (!id || offset >= buflen) return NULL;
1077 for (ptr = buf + offset; ptr - buf < buflen && *ptr; ptr++)
1079 if (++i == id) return heap_strdupAW( ptr );
1080 for (; ptr - buf < buflen; ptr++) if (!*ptr) break;
1082 return NULL;
1085 static WCHAR *get_baseboard_string( BYTE id, const char *buf, UINT len )
1087 const struct smbios_header *hdr;
1088 const struct smbios_baseboard *baseboard;
1089 UINT offset;
1091 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BASEBOARD, buf, len ))) return NULL;
1093 baseboard = (const struct smbios_baseboard *)hdr;
1094 offset = (const char *)baseboard - buf + baseboard->hdr.length;
1095 return get_smbios_string( id, buf, offset, len );
1098 static WCHAR *get_baseboard_manufacturer( const char *buf, UINT len )
1100 WCHAR *ret = get_baseboard_string( 1, buf, len );
1101 if (!ret) return heap_strdupW( L"Intel Corporation" );
1102 return ret;
1105 static WCHAR *get_baseboard_product( const char *buf, UINT len )
1107 WCHAR *ret = get_baseboard_string( 2, buf, len );
1108 if (!ret) return heap_strdupW( L"Base Board" );
1109 return ret;
1112 static WCHAR *get_baseboard_serialnumber( const char *buf, UINT len )
1114 WCHAR *ret = get_baseboard_string( 4, buf, len );
1115 if (!ret) return heap_strdupW( L"None" );
1116 return ret;
1119 static WCHAR *get_baseboard_version( const char *buf, UINT len )
1121 WCHAR *ret = get_baseboard_string( 3, buf, len );
1122 if (!ret) return heap_strdupW( L"1.0" );
1123 return ret;
1126 static enum fill_status fill_baseboard( struct table *table, const struct expr *cond )
1128 struct record_baseboard *rec;
1129 enum fill_status status = FILL_STATUS_UNFILTERED;
1130 UINT row = 0, len;
1131 char *buf;
1133 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1135 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1136 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
1137 GetSystemFirmwareTable( RSMB, 0, buf, len );
1139 rec = (struct record_baseboard *)table->data;
1140 rec->manufacturer = get_baseboard_manufacturer( buf, len );
1141 rec->model = L"Base Board";
1142 rec->name = L"Base Board";
1143 rec->product = get_baseboard_product( buf, len );
1144 rec->serialnumber = get_baseboard_serialnumber( buf, len );
1145 rec->tag = L"Base Board";
1146 rec->version = get_baseboard_version( buf, len );
1147 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1148 else row++;
1150 heap_free( buf );
1152 TRACE("created %u rows\n", row);
1153 table->num_rows = row;
1154 return status;
1157 static UINT16 get_bios_smbiosmajorversion( const char *buf, UINT len )
1159 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1160 if (len < sizeof(*prologue)) return 2;
1161 return prologue->major_version;
1164 static UINT16 get_bios_smbiosminorversion( const char *buf, UINT len )
1166 const struct smbios_prologue *prologue = (const struct smbios_prologue *)buf;
1167 if (len < sizeof(*prologue)) return 0;
1168 return prologue->minor_version;
1171 static WCHAR *get_bios_string( BYTE id, const char *buf, UINT len )
1173 const struct smbios_header *hdr;
1174 const struct smbios_bios *bios;
1175 UINT offset;
1177 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return NULL;
1179 bios = (const struct smbios_bios *)hdr;
1180 offset = (const char *)bios - buf + bios->hdr.length;
1181 return get_smbios_string( id, buf, offset, len );
1184 static WCHAR *get_bios_manufacturer( const char *buf, UINT len )
1186 WCHAR *ret = get_bios_string( 1, buf, len );
1187 if (!ret) return heap_strdupW( L"The Wine Project" );
1188 return ret;
1191 static WCHAR *convert_bios_date( const WCHAR *str )
1193 static const WCHAR fmtW[] = L"%04u%02u%02u000000.000000+000";
1194 UINT year, month, day, len = lstrlenW( str );
1195 const WCHAR *p = str, *q;
1196 WCHAR *ret;
1198 while (len && iswspace( *p )) { p++; len--; }
1199 while (len && iswspace( p[len - 1] )) { len--; }
1201 q = p;
1202 while (len && is_digit( *q )) { q++; len--; };
1203 if (q - p != 2 || !len || *q != '/') return NULL;
1204 month = (p[0] - '0') * 10 + p[1] - '0';
1206 p = ++q; len--;
1207 while (len && is_digit( *q )) { q++; len--; };
1208 if (q - p != 2 || !len || *q != '/') return NULL;
1209 day = (p[0] - '0') * 10 + p[1] - '0';
1211 p = ++q; len--;
1212 while (len && is_digit( *q )) { q++; len--; };
1213 if (q - p == 4) year = (p[0] - '0') * 1000 + (p[1] - '0') * 100 + (p[2] - '0') * 10 + p[3] - '0';
1214 else if (q - p == 2) year = 1900 + (p[0] - '0') * 10 + p[1] - '0';
1215 else return NULL;
1217 if (!(ret = heap_alloc( sizeof(fmtW) ))) return NULL;
1218 swprintf( ret, ARRAY_SIZE(fmtW), fmtW, year, month, day );
1219 return ret;
1222 static WCHAR *get_bios_releasedate( const char *buf, UINT len )
1224 WCHAR *ret, *date = get_bios_string( 3, buf, len );
1225 if (!date || !(ret = convert_bios_date( date ))) ret = heap_strdupW( L"20120608000000.000000+000" );
1226 heap_free( date );
1227 return ret;
1230 static WCHAR *get_bios_smbiosbiosversion( const char *buf, UINT len )
1232 WCHAR *ret = get_bios_string( 2, buf, len );
1233 if (!ret) return heap_strdupW( L"Wine" );
1234 return ret;
1237 static BYTE get_bios_ec_firmware_major_release( const char *buf, UINT len )
1239 const struct smbios_header *hdr;
1240 const struct smbios_bios *bios;
1242 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1244 bios = (const struct smbios_bios *)hdr;
1245 if (bios->hdr.length >= 0x18) return bios->ec_firmware_major_release;
1246 else return 0xFF;
1249 static BYTE get_bios_ec_firmware_minor_release( const char *buf, UINT len )
1251 const struct smbios_header *hdr;
1252 const struct smbios_bios *bios;
1254 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1256 bios = (const struct smbios_bios *)hdr;
1257 if (bios->hdr.length >= 0x18) return bios->ec_firmware_minor_release;
1258 else return 0xFF;
1261 static BYTE get_bios_system_bios_major_release( const char *buf, UINT len )
1263 const struct smbios_header *hdr;
1264 const struct smbios_bios *bios;
1266 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1268 bios = (const struct smbios_bios *)hdr;
1269 if (bios->hdr.length >= 0x18) return bios->system_bios_major_release;
1270 else return 0xFF;
1273 static BYTE get_bios_system_bios_minor_release( const char *buf, UINT len )
1275 const struct smbios_header *hdr;
1276 const struct smbios_bios *bios;
1278 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_BIOS, buf, len ))) return 0xFF;
1280 bios = (const struct smbios_bios *)hdr;
1281 if (bios->hdr.length >= 0x18) return bios->system_bios_minor_release;
1282 else return 0xFF;
1285 static enum fill_status fill_bios( struct table *table, const struct expr *cond )
1287 struct record_bios *rec;
1288 enum fill_status status = FILL_STATUS_UNFILTERED;
1289 UINT row = 0, len;
1290 char *buf;
1292 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1294 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1295 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
1296 GetSystemFirmwareTable( RSMB, 0, buf, len );
1298 rec = (struct record_bios *)table->data;
1299 rec->currentlanguage = NULL;
1300 rec->description = L"Default System BIOS";
1301 rec->ecmajorversion = get_bios_ec_firmware_major_release( buf, len );
1302 rec->ecminorversion = get_bios_ec_firmware_minor_release( buf, len );
1303 rec->identificationcode = NULL;
1304 rec->manufacturer = get_bios_manufacturer( buf, len );
1305 rec->name = L"Default System BIOS";
1306 rec->releasedate = get_bios_releasedate( buf, len );
1307 rec->serialnumber = L"0";
1308 rec->smbiosbiosversion = get_bios_smbiosbiosversion( buf, len );
1309 rec->smbiosmajorversion = get_bios_smbiosmajorversion( buf, len );
1310 rec->smbiosminorversion = get_bios_smbiosminorversion( buf, len );
1311 rec->systembiosmajorversion = get_bios_system_bios_major_release( buf, len );
1312 rec->systembiosminorversion = get_bios_system_bios_minor_release( buf, len );
1313 rec->version = L"WINE - 1";
1314 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1315 else row++;
1317 heap_free( buf );
1319 TRACE("created %u rows\n", row);
1320 table->num_rows = row;
1321 return status;
1324 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond )
1326 WCHAR drive[3], root[] = L"A:\\";
1327 struct record_cdromdrive *rec;
1328 UINT i, row = 0, offset = 0;
1329 DWORD drives = GetLogicalDrives();
1330 enum fill_status status = FILL_STATUS_UNFILTERED;
1332 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1334 for (i = 0; i < 26; i++)
1336 if (drives & (1 << i))
1338 root[0] = 'A' + i;
1339 if (GetDriveTypeW( root ) != DRIVE_CDROM)
1340 continue;
1342 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1344 rec = (struct record_cdromdrive *)(table->data + offset);
1345 rec->device_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1346 swprintf( drive, ARRAY_SIZE( drive ), L"%c:", 'A' + i );
1347 rec->drive = heap_strdupW( drive );
1348 rec->mediatype = L"CR-ROM";
1349 rec->name = L"Wine CD_ROM ATA Device";
1350 rec->pnpdevice_id = L"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1351 if (!match_row( table, row, cond, &status ))
1353 free_row_values( table, row );
1354 continue;
1356 offset += sizeof(*rec);
1357 row++;
1360 TRACE("created %u rows\n", row);
1361 table->num_rows = row;
1362 return status;
1365 static UINT get_processor_count(void)
1367 SYSTEM_BASIC_INFORMATION info;
1369 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1;
1370 return info.NumberOfProcessors;
1373 static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
1375 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
1376 UINT core_relation_count = 0, package_relation_count = 0;
1377 NTSTATUS status;
1378 ULONG len, offset = 0;
1379 BOOL smt_enabled = FALSE;
1380 DWORD all = RelationAll;
1382 if (num_packages) *num_packages = 1;
1383 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
1384 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
1386 if (!(buf = heap_alloc( len ))) return get_processor_count();
1387 status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
1388 if (status != STATUS_SUCCESS)
1390 heap_free( buf );
1391 return get_processor_count();
1394 while (offset < len)
1396 entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
1398 if (entry->Relationship == RelationProcessorCore)
1400 core_relation_count++;
1401 if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
1403 else if (entry->Relationship == RelationProcessorPackage)
1405 package_relation_count++;
1407 offset += entry->Size;
1410 heap_free( buf );
1411 if (num_physical) *num_physical = core_relation_count;
1412 if (num_packages) *num_packages = package_relation_count;
1413 return smt_enabled ? core_relation_count * 2 : core_relation_count;
1416 static UINT64 get_total_physical_memory(void)
1418 MEMORYSTATUSEX status;
1420 status.dwLength = sizeof(status);
1421 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1422 return status.ullTotalPhys;
1425 static UINT64 get_available_physical_memory(void)
1427 MEMORYSTATUSEX status;
1429 status.dwLength = sizeof(status);
1430 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024;
1431 return status.ullAvailPhys;
1434 static WCHAR *get_computername(void)
1436 WCHAR *ret;
1437 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1439 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1440 GetComputerNameW( ret, &size );
1441 return ret;
1444 static WCHAR *get_username(void)
1446 WCHAR *ret;
1447 DWORD compsize, usersize;
1448 DWORD size;
1450 compsize = 0;
1451 GetComputerNameW( NULL, &compsize );
1452 usersize = 0;
1453 GetUserNameW( NULL, &usersize );
1454 size = compsize + usersize; /* two null terminators account for the \ */
1455 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL;
1456 GetComputerNameW( ret, &compsize );
1457 ret[compsize] = '\\';
1458 GetUserNameW( ret + compsize + 1, &usersize );
1459 return ret;
1462 static enum fill_status fill_compsys( struct table *table, const struct expr *cond )
1464 struct record_computersystem *rec;
1465 enum fill_status status = FILL_STATUS_UNFILTERED;
1466 UINT row = 0;
1468 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1470 rec = (struct record_computersystem *)table->data;
1471 rec->description = L"AT/AT COMPATIBLE";
1472 rec->domain = L"WORKGROUP";
1473 rec->domainrole = 0; /* standalone workstation */
1474 rec->manufacturer = L"The Wine Project";
1475 rec->model = L"Wine";
1476 rec->name = get_computername();
1477 rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
1478 rec->total_physical_memory = get_total_physical_memory();
1479 rec->username = get_username();
1480 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1481 else row++;
1483 TRACE("created %u rows\n", row);
1484 table->num_rows = row;
1485 return status;
1488 static WCHAR *get_compsysproduct_string( BYTE id, const char *buf, UINT len )
1490 const struct smbios_header *hdr;
1491 const struct smbios_system *system;
1492 UINT offset;
1494 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len ))) return NULL;
1496 system = (const struct smbios_system *)hdr;
1497 offset = (const char *)system - buf + system->hdr.length;
1498 return get_smbios_string( id, buf, offset, len );
1501 static WCHAR *get_compsysproduct_identifyingnumber( const char *buf, UINT len )
1503 WCHAR *ret = get_compsysproduct_string( 4, buf, len );
1504 if (!ret) return heap_strdupW( L"0" );
1505 return ret;
1508 static WCHAR *get_compsysproduct_name( const char *buf, UINT len )
1510 WCHAR *ret = get_compsysproduct_string( 2, buf, len );
1511 if (!ret) return heap_strdupW( L"Wine" );
1512 return ret;
1515 static WCHAR *get_compsysproduct_uuid( const char *buf, UINT len )
1517 static const BYTE none[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1518 const struct smbios_header *hdr;
1519 const struct smbios_system *system;
1520 const BYTE *ptr;
1521 WCHAR *ret = NULL;
1523 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_SYSTEM, buf, len )) || hdr->length < sizeof(*system)) goto done;
1524 system = (const struct smbios_system *)hdr;
1525 if (!memcmp( system->uuid, none, sizeof(none) ) || !(ret = heap_alloc( 37 * sizeof(WCHAR) ))) goto done;
1527 ptr = system->uuid;
1528 swprintf( ret, 37, L"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr[0], ptr[1],
1529 ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1530 ptr[14], ptr[15] );
1531 done:
1532 if (!ret) ret = heap_strdupW( L"deaddead-dead-dead-dead-deaddeaddead" );
1533 return ret;
1536 static WCHAR *get_compsysproduct_vendor( const char *buf, UINT len )
1538 WCHAR *ret = get_compsysproduct_string( 1, buf, len );
1539 if (!ret) return heap_strdupW( L"The Wine Project" );
1540 return ret;
1543 static WCHAR *get_compsysproduct_version( const char *buf, UINT len )
1545 WCHAR *ret = get_compsysproduct_string( 3, buf, len );
1546 if (!ret) return heap_strdupW( L"1.0" );
1547 return ret;
1550 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond )
1552 struct record_computersystemproduct *rec;
1553 enum fill_status status = FILL_STATUS_UNFILTERED;
1554 UINT row = 0, len;
1555 char *buf;
1557 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1559 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
1560 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
1561 GetSystemFirmwareTable( RSMB, 0, buf, len );
1563 rec = (struct record_computersystemproduct *)table->data;
1564 rec->identifyingnumber = get_compsysproduct_identifyingnumber( buf, len );
1565 rec->name = get_compsysproduct_name( buf, len );
1566 rec->skunumber = NULL;
1567 rec->uuid = get_compsysproduct_uuid( buf, len );
1568 rec->vendor = get_compsysproduct_vendor( buf, len );
1569 rec->version = get_compsysproduct_version( buf, len );
1570 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
1571 else row++;
1573 heap_free( buf );
1575 TRACE("created %u rows\n", row);
1576 table->num_rows = row;
1577 return status;
1580 struct dirstack
1582 WCHAR **dirs;
1583 UINT *len_dirs;
1584 UINT num_dirs;
1585 UINT num_allocated;
1588 static struct dirstack *alloc_dirstack( UINT size )
1590 struct dirstack *dirstack;
1592 if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL;
1593 if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size )))
1595 heap_free( dirstack );
1596 return NULL;
1598 if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size )))
1600 heap_free( dirstack->dirs );
1601 heap_free( dirstack );
1602 return NULL;
1604 dirstack->num_dirs = 0;
1605 dirstack->num_allocated = size;
1606 return dirstack;
1609 static void clear_dirstack( struct dirstack *dirstack )
1611 UINT i;
1612 for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] );
1613 dirstack->num_dirs = 0;
1616 static void free_dirstack( struct dirstack *dirstack )
1618 clear_dirstack( dirstack );
1619 heap_free( dirstack->dirs );
1620 heap_free( dirstack->len_dirs );
1621 heap_free( dirstack );
1624 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len )
1626 UINT size, i = dirstack->num_dirs;
1628 if (!dir) return FALSE;
1630 if (i == dirstack->num_allocated)
1632 WCHAR **tmp;
1633 UINT *len_tmp;
1635 size = dirstack->num_allocated * 2;
1636 if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE;
1637 dirstack->dirs = tmp;
1638 if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE;
1639 dirstack->len_dirs = len_tmp;
1640 dirstack->num_allocated = size;
1642 dirstack->dirs[i] = dir;
1643 dirstack->len_dirs[i] = len;
1644 dirstack->num_dirs++;
1645 return TRUE;
1648 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len )
1650 if (!dirstack->num_dirs)
1652 *len = 0;
1653 return NULL;
1655 dirstack->num_dirs--;
1656 *len = dirstack->len_dirs[dirstack->num_dirs];
1657 return dirstack->dirs[dirstack->num_dirs];
1660 static const WCHAR *peek_dir( struct dirstack *dirstack )
1662 if (!dirstack->num_dirs) return NULL;
1663 return dirstack->dirs[dirstack->num_dirs - 1];
1666 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len )
1668 UINT i = 0;
1669 WCHAR *ret;
1671 if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL;
1672 ret[i++] = drive;
1673 ret[i++] = ':';
1674 ret[i++] = '\\';
1675 if (path && len)
1677 memcpy( ret + i, path, len * sizeof(WCHAR) );
1678 i += len;
1679 ret[i++] = '\\';
1681 ret[i++] = '*';
1682 ret[i] = 0;
1683 return ret;
1686 static WCHAR *build_name( WCHAR drive, const WCHAR *path )
1688 UINT i = 0, len = 0;
1689 const WCHAR *p;
1690 WCHAR *ret;
1692 for (p = path; *p; p++)
1694 if (*p == '\\') len += 2;
1695 else len++;
1697 if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL;
1698 ret[i++] = drive;
1699 ret[i++] = ':';
1700 ret[i++] = '\\';
1701 ret[i++] = '\\';
1702 for (p = path; *p; p++)
1704 if (*p != '\\') ret[i++] = *p;
1705 else
1707 ret[i++] = '\\';
1708 ret[i++] = '\\';
1711 ret[i] = 0;
1712 return ret;
1715 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len )
1717 const WCHAR *p = path, *start;
1718 UINT len, i;
1719 WCHAR *ret;
1721 if (!iswalpha( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL;
1722 start = path + 4;
1723 len = lstrlenW( start );
1724 p = start + len - 1;
1725 if (*p == '\\') return NULL;
1727 while (p >= start && *p != '\\') { len--; p--; };
1728 while (p >= start && *p == '\\') { len--; p--; };
1730 if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1731 for (i = 0, p = start; p < start + len; p++)
1733 if (p[0] == '\\' && p[1] == '\\')
1735 ret[i++] = '\\';
1736 p++;
1738 else ret[i++] = *p;
1740 ret[i] = 0;
1741 *ret_len = i;
1742 return ret;
1745 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path )
1747 UINT i;
1748 for (i = 0; i < dirstack->num_dirs; i++) if (!wcscmp( dirstack->dirs[i], path )) return TRUE;
1749 return FALSE;
1752 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1753 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count )
1755 const struct expr *left, *right;
1757 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0;
1759 left = cond->u.expr.left;
1760 right = cond->u.expr.right;
1761 if (cond->u.expr.op == OP_EQ)
1763 UINT len;
1764 WCHAR *path;
1765 const WCHAR *str = NULL;
1767 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL &&
1768 !wcscmp( left->u.propval->name, L"Name" ) &&
1769 towupper( right->u.sval[0] ) == towupper( root ))
1771 str = right->u.sval;
1773 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL &&
1774 !wcscmp( right->u.propval->name, L"Name" ) &&
1775 towupper( left->u.sval[0] ) == towupper( root ))
1777 str = left->u.sval;
1779 if (str && (path = build_dirname( str, &len )))
1781 if (seen_dir( dirstack, path ))
1783 heap_free( path );
1784 return ++*count;
1786 else if (push_dir( dirstack, path, len )) return ++*count;
1787 heap_free( path );
1788 return *count = 0;
1791 else if (cond->u.expr.op == OP_OR)
1793 UINT left_count = 0, right_count = 0;
1795 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0;
1796 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0;
1797 return *count += left_count + right_count;
1799 return *count = 0;
1802 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len )
1804 UINT len_path = 0, len_segment = lstrlenW( segment );
1805 WCHAR *ret;
1807 *len = 0;
1808 if (path) len_path = lstrlenW( path );
1809 if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL;
1810 if (path && len_path)
1812 memcpy( ret, path, len_path * sizeof(WCHAR) );
1813 ret[len_path] = '\\';
1814 *len += len_path + 1;
1816 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) );
1817 *len += len_segment;
1818 ret[*len] = 0;
1819 return ret;
1822 static WCHAR *get_file_version( const WCHAR *filename )
1824 VS_FIXEDFILEINFO *info;
1825 DWORD size, len = 4 * 5 + ARRAY_SIZE( L"%u.%u.%u.%u" );
1826 void *block;
1827 WCHAR *ret;
1829 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
1830 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size )))
1832 heap_free( ret );
1833 return NULL;
1835 if (!GetFileVersionInfoW( filename, 0, size, block ) ||
1836 !VerQueryValueW( block, L"\\", (void **)&info, &size ))
1838 heap_free( block );
1839 heap_free( ret );
1840 return NULL;
1842 swprintf( ret, len, L"%u.%u.%u.%u", info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff,
1843 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff );
1844 heap_free( block );
1845 return ret;
1848 static enum fill_status fill_datafile( struct table *table, const struct expr *cond )
1850 struct record_datafile *rec;
1851 UINT i, len, row = 0, offset = 0, num_expected_rows;
1852 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
1853 DWORD drives = GetLogicalDrives();
1854 WIN32_FIND_DATAW data;
1855 HANDLE handle;
1856 struct dirstack *dirstack;
1857 enum fill_status status = FILL_STATUS_UNFILTERED;
1859 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED;
1861 dirstack = alloc_dirstack(2);
1863 for (i = 0; i < 26; i++)
1865 if (!(drives & (1 << i))) continue;
1867 root[0] = 'A' + i;
1868 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1870 num_expected_rows = 0;
1871 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
1873 for (;;)
1875 heap_free( glob );
1876 heap_free( path );
1877 path = pop_dir( dirstack, &len );
1878 if (!(glob = build_glob( root[0], path, len )))
1880 status = FILL_STATUS_FAILED;
1881 goto done;
1883 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
1887 if (!resize_table( table, row + 1, sizeof(*rec) ))
1889 status = FILL_STATUS_FAILED;
1890 FindClose( handle );
1891 goto done;
1893 if (!wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." )) continue;
1895 if (!(new_path = append_path( path, data.cFileName, &len )))
1897 status = FILL_STATUS_FAILED;
1898 FindClose( handle );
1899 goto done;
1902 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1904 if (push_dir( dirstack, new_path, len )) continue;
1905 heap_free( new_path );
1906 FindClose( handle );
1907 status = FILL_STATUS_FAILED;
1908 goto done;
1910 rec = (struct record_datafile *)(table->data + offset);
1911 rec->name = build_name( root[0], new_path );
1912 rec->version = get_file_version( rec->name );
1913 heap_free( new_path );
1914 if (!match_row( table, row, cond, &status ))
1916 free_row_values( table, row );
1917 continue;
1919 else if (num_expected_rows && row == num_expected_rows - 1)
1921 row++;
1922 FindClose( handle );
1923 status = FILL_STATUS_FILTERED;
1924 goto done;
1926 offset += sizeof(*rec);
1927 row++;
1929 while (FindNextFileW( handle, &data ));
1930 FindClose( handle );
1932 if (!peek_dir( dirstack )) break;
1936 done:
1937 free_dirstack( dirstack );
1938 heap_free( glob );
1939 heap_free( path );
1941 TRACE("created %u rows\n", row);
1942 table->num_rows = row;
1943 return status;
1946 static UINT32 get_pixelsperxlogicalinch(void)
1948 HDC hdc = GetDC( NULL );
1949 UINT32 ret;
1951 if (!hdc) return 96;
1952 ret = GetDeviceCaps( hdc, LOGPIXELSX );
1953 ReleaseDC( NULL, hdc );
1954 return ret;
1957 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond )
1959 struct record_desktopmonitor *rec;
1960 enum fill_status status = FILL_STATUS_UNFILTERED;
1961 UINT row = 0;
1963 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
1965 rec = (struct record_desktopmonitor *)table->data;
1966 rec->name = L"Generic Non-PnP Monitor";
1967 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch();
1969 if (match_row( table, row, cond, &status )) row++;
1971 TRACE("created %u rows\n", row);
1972 table->num_rows = row;
1973 return status;
1976 static enum fill_status fill_directory( struct table *table, const struct expr *cond )
1978 struct record_directory *rec;
1979 UINT i, len, row = 0, offset = 0, num_expected_rows;
1980 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = L"A:\\";
1981 DWORD drives = GetLogicalDrives();
1982 WIN32_FIND_DATAW data;
1983 HANDLE handle;
1984 struct dirstack *dirstack;
1985 enum fill_status status = FILL_STATUS_UNFILTERED;
1987 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
1989 dirstack = alloc_dirstack(2);
1991 for (i = 0; i < 26; i++)
1993 if (!(drives & (1 << i))) continue;
1995 root[0] = 'A' + i;
1996 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue;
1998 num_expected_rows = 0;
1999 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack );
2001 for (;;)
2003 heap_free( glob );
2004 heap_free( path );
2005 path = pop_dir( dirstack, &len );
2006 if (!(glob = build_glob( root[0], path, len )))
2008 status = FILL_STATUS_FAILED;
2009 goto done;
2011 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE)
2015 if (!resize_table( table, row + 1, sizeof(*rec) ))
2017 FindClose( handle );
2018 status = FILL_STATUS_FAILED;
2019 goto done;
2021 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
2022 !wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." ))
2023 continue;
2025 if (!(new_path = append_path( path, data.cFileName, &len )))
2027 FindClose( handle );
2028 status = FILL_STATUS_FAILED;
2029 goto done;
2032 if (!(push_dir( dirstack, new_path, len )))
2034 heap_free( new_path );
2035 FindClose( handle );
2036 status = FILL_STATUS_FAILED;
2037 goto done;
2039 rec = (struct record_directory *)(table->data + offset);
2040 rec->accessmask = FILE_ALL_ACCESS;
2041 rec->name = build_name( root[0], new_path );
2042 heap_free( new_path );
2043 if (!match_row( table, row, cond, &status ))
2045 free_row_values( table, row );
2046 continue;
2048 else if (num_expected_rows && row == num_expected_rows - 1)
2050 row++;
2051 FindClose( handle );
2052 status = FILL_STATUS_FILTERED;
2053 goto done;
2055 offset += sizeof(*rec);
2056 row++;
2058 while (FindNextFileW( handle, &data ));
2059 FindClose( handle );
2061 if (!peek_dir( dirstack )) break;
2065 done:
2066 free_dirstack( dirstack );
2067 heap_free( glob );
2068 heap_free( path );
2070 TRACE("created %u rows\n", row);
2071 table->num_rows = row;
2072 return status;
2075 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize )
2077 WCHAR root[] = L"\\\\.\\A:";
2078 ULARGE_INTEGER free;
2079 DISK_GEOMETRY_EX info;
2080 HANDLE handle;
2081 DWORD bytes_returned;
2083 free.QuadPart = 512 * 1024 * 1024;
2084 GetDiskFreeSpaceExW( dir, NULL, NULL, &free );
2086 root[4] = dir[0];
2087 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2088 if (handle != INVALID_HANDLE_VALUE)
2090 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL ))
2091 *disksize = info.DiskSize.QuadPart;
2092 CloseHandle( handle );
2094 return free.QuadPart;
2096 static WCHAR *get_diskdrive_serialnumber( WCHAR letter )
2098 WCHAR *ret = NULL;
2099 STORAGE_DEVICE_DESCRIPTOR *desc;
2100 HANDLE handle = INVALID_HANDLE_VALUE;
2101 STORAGE_PROPERTY_QUERY query = {0};
2102 WCHAR drive[7];
2103 DWORD size;
2105 swprintf( drive, ARRAY_SIZE(drive), L"\\\\.\\%c:", letter );
2106 handle = CreateFileW( drive, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2107 if (handle == INVALID_HANDLE_VALUE) goto done;
2109 query.PropertyId = StorageDeviceProperty;
2110 query.QueryType = PropertyStandardQuery;
2112 size = sizeof(*desc) + 256;
2113 for (;;)
2115 if (!(desc = heap_alloc( size ))) break;
2116 if (DeviceIoControl( handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), desc, size, NULL, NULL ))
2118 if (desc->SerialNumberOffset) ret = heap_strdupAW( (const char *)desc + desc->SerialNumberOffset );
2119 heap_free( desc );
2120 break;
2122 size = desc->Size;
2123 heap_free( desc );
2124 if (GetLastError() != ERROR_MORE_DATA) break;
2127 done:
2128 if (handle != INVALID_HANDLE_VALUE) CloseHandle( handle );
2129 if (!ret) ret = heap_strdupW( L"WINEHDISK" );
2130 return ret;
2133 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond )
2135 static const WCHAR fmtW[] = L"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2136 WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = L"A:\\";
2137 struct record_diskdrive *rec;
2138 UINT i, row = 0, offset = 0, index = 0, type;
2139 UINT64 size = 1024 * 1024 * 1024;
2140 DWORD drives = GetLogicalDrives();
2141 enum fill_status status = FILL_STATUS_UNFILTERED;
2143 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED;
2145 for (i = 0; i < 26; i++)
2147 if (drives & (1 << i))
2149 root[0] = 'A' + i;
2150 type = GetDriveTypeW( root );
2151 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2152 continue;
2154 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2156 rec = (struct record_diskdrive *)(table->data + offset);
2157 swprintf( device_id, ARRAY_SIZE( device_id ), fmtW, index );
2158 rec->device_id = heap_strdupW( device_id );
2159 rec->index = index++;
2160 rec->interfacetype = L"IDE";
2161 rec->manufacturer = L"(Standard disk drives)";
2162 rec->mediatype = (type == DRIVE_FIXED) ? L"Fixed hard disk" : L"Removable media";
2163 rec->model = L"Wine Disk Drive";
2164 rec->pnpdevice_id = L"IDE\\Disk\\VEN_WINE";
2165 rec->serialnumber = get_diskdrive_serialnumber( root[0] );
2166 get_freespace( root, &size );
2167 rec->size = size;
2168 if (!match_row( table, row, cond, &status ))
2170 free_row_values( table, row );
2171 continue;
2173 offset += sizeof(*rec);
2174 row++;
2177 TRACE("created %u rows\n", row);
2178 table->num_rows = row;
2179 return status;
2182 struct association
2184 WCHAR *ref;
2185 WCHAR *ref2;
2188 static void free_associations( struct association *assoc, UINT count )
2190 UINT i;
2191 if (!assoc) return;
2192 for (i = 0; i < count; i++)
2194 heap_free( assoc[i].ref );
2195 heap_free( assoc[i].ref2 );
2197 heap_free( assoc );
2200 static struct association *get_diskdrivetodiskpartition_pairs( UINT *count )
2202 struct association *ret = NULL;
2203 struct query *query, *query2 = NULL;
2204 VARIANT val;
2205 HRESULT hr;
2206 UINT i;
2208 if (!(query = create_query())) return NULL;
2209 if ((hr = parse_query( L"SELECT * FROM Win32_DiskDrive", &query->view, &query->mem )) != S_OK) goto done;
2210 if ((hr = execute_view( query->view )) != S_OK) goto done;
2212 if (!(query2 = create_query())) return FALSE;
2213 if ((hr = parse_query( L"SELECT * FROM Win32_DiskPartition", &query2->view, &query2->mem )) != S_OK) goto done;
2214 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2216 if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
2218 for (i = 0; i < query->view->result_count; i++)
2220 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2221 if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
2222 VariantClear( &val );
2224 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2225 if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done;
2226 VariantClear( &val );
2229 *count = query->view->result_count;
2231 done:
2232 if (!ret) free_associations( ret, query->view->result_count );
2233 free_query( query );
2234 free_query( query2 );
2235 return ret;
2238 static enum fill_status fill_diskdrivetodiskpartition( struct table *table, const struct expr *cond )
2240 struct record_diskdrivetodiskpartition *rec;
2241 UINT i, row = 0, offset = 0, count = 0;
2242 enum fill_status status = FILL_STATUS_UNFILTERED;
2243 struct association *assoc;
2245 if (!(assoc = get_diskdrivetodiskpartition_pairs( &count ))) return FILL_STATUS_FAILED;
2246 if (!count)
2248 free_associations( assoc, count );
2249 return FILL_STATUS_UNFILTERED;
2251 if (!resize_table( table, count, sizeof(*rec) ))
2253 free_associations( assoc, count );
2254 return FILL_STATUS_FAILED;
2257 for (i = 0; i < count; i++)
2259 rec = (struct record_diskdrivetodiskpartition *)(table->data + offset);
2260 rec->antecedent = assoc[i].ref;
2261 rec->dependent = assoc[i].ref2;
2262 if (!match_row( table, row, cond, &status ))
2264 free_row_values( table, row );
2265 continue;
2267 offset += sizeof(*rec);
2268 row++;
2271 heap_free( assoc );
2273 TRACE("created %u rows\n", row);
2274 table->num_rows = row;
2275 return status;
2278 static WCHAR *get_filesystem( const WCHAR *root )
2280 WCHAR buffer[MAX_PATH + 1];
2282 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 ))
2283 return heap_strdupW( buffer );
2284 return heap_strdupW( L"NTFS" );
2287 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond )
2289 WCHAR device_id[32], root[] = L"A:\\";
2290 struct record_diskpartition *rec;
2291 UINT i, row = 0, offset = 0, type, index = 0;
2292 UINT64 size = 1024 * 1024 * 1024;
2293 DWORD drives = GetLogicalDrives();
2294 enum fill_status status = FILL_STATUS_UNFILTERED;
2296 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2298 for (i = 0; i < 26; i++)
2300 if (drives & (1 << i))
2302 root[0] = 'A' + i;
2303 type = GetDriveTypeW( root );
2304 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE)
2305 continue;
2307 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2309 rec = (struct record_diskpartition *)(table->data + offset);
2310 rec->bootable = (i == 2) ? -1 : 0;
2311 rec->bootpartition = (i == 2) ? -1 : 0;
2312 swprintf( device_id, ARRAY_SIZE( device_id ), L"Disk #%u, Partition #0", index );
2313 rec->device_id = heap_strdupW( device_id );
2314 rec->diskindex = index++;
2315 rec->index = 0;
2316 rec->pnpdevice_id = heap_strdupW( device_id );
2317 get_freespace( root, &size );
2318 rec->size = size;
2319 rec->startingoffset = 0;
2320 rec->type = get_filesystem( root );
2321 if (!match_row( table, row, cond, &status ))
2323 free_row_values( table, row );
2324 continue;
2326 offset += sizeof(*rec);
2327 row++;
2330 TRACE("created %u rows\n", row);
2331 table->num_rows = row;
2332 return status;
2335 static UINT32 get_bitsperpixel( UINT *hres, UINT *vres )
2337 HDC hdc = GetDC( NULL );
2338 UINT32 ret;
2340 if (!hdc) return 32;
2341 ret = GetDeviceCaps( hdc, BITSPIXEL );
2342 *hres = GetDeviceCaps( hdc, HORZRES );
2343 *vres = GetDeviceCaps( hdc, VERTRES );
2344 ReleaseDC( NULL, hdc );
2345 return ret;
2348 static enum fill_status fill_displaycontrollerconfig( struct table *table, const struct expr *cond )
2350 struct record_displaycontrollerconfig *rec;
2351 UINT row = 0, hres = 1024, vres = 768;
2352 enum fill_status status = FILL_STATUS_UNFILTERED;
2354 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2356 rec = (struct record_displaycontrollerconfig *)table->data;
2357 rec->bitsperpixel = get_bitsperpixel( &hres, &vres );
2358 rec->caption = L"VideoController1";
2359 rec->horizontalresolution = hres;
2360 rec->name = L"VideoController1";
2361 rec->verticalresolution = vres;
2362 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2363 else row++;
2365 TRACE("created %u rows\n", row);
2366 table->num_rows = row;
2367 return status;
2370 static WCHAR *get_ip4_string( DWORD addr )
2372 DWORD len = sizeof("ddd.ddd.ddd.ddd");
2373 WCHAR *ret;
2375 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
2376 swprintf( ret, len, L"%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff );
2377 return ret;
2380 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond )
2382 struct record_ip4routetable *rec;
2383 UINT i, row = 0, offset = 0, size = 0;
2384 MIB_IPFORWARDTABLE *forwards;
2385 enum fill_status status = FILL_STATUS_UNFILTERED;
2387 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED;
2388 if (!(forwards = heap_alloc( size ))) return FILL_STATUS_FAILED;
2389 if (GetIpForwardTable( forwards, &size, TRUE ))
2391 heap_free( forwards );
2392 return FILL_STATUS_FAILED;
2394 if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) ))
2396 heap_free( forwards );
2397 return FILL_STATUS_FAILED;
2400 for (i = 0; i < forwards->dwNumEntries; i++)
2402 rec = (struct record_ip4routetable *)(table->data + offset);
2404 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) );
2405 rec->interfaceindex = forwards->table[i].dwForwardIfIndex;
2406 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) );
2408 if (!match_row( table, row, cond, &status ))
2410 free_row_values( table, row );
2411 continue;
2413 offset += sizeof(*rec);
2414 row++;
2416 TRACE("created %u rows\n", row);
2417 table->num_rows = row;
2419 heap_free( forwards );
2420 return status;
2423 static WCHAR *get_volumename( const WCHAR *root )
2425 WCHAR buf[MAX_PATH + 1] = {0};
2426 GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 );
2427 return heap_strdupW( buf );
2429 static WCHAR *get_volumeserialnumber( const WCHAR *root )
2431 DWORD serial = 0;
2432 WCHAR buffer[9];
2434 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 );
2435 swprintf( buffer, ARRAY_SIZE( buffer ), L"%08X", serial );
2436 return heap_strdupW( buffer );
2439 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond )
2441 WCHAR device_id[3], root[] = L"A:\\";
2442 struct record_logicaldisk *rec;
2443 UINT i, row = 0, offset = 0, type;
2444 UINT64 size = 1024 * 1024 * 1024;
2445 DWORD drives = GetLogicalDrives();
2446 enum fill_status status = FILL_STATUS_UNFILTERED;
2448 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED;
2450 for (i = 0; i < 26; i++)
2452 if (drives & (1 << i))
2454 root[0] = 'A' + i;
2455 type = GetDriveTypeW( root );
2456 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE)
2457 continue;
2459 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2461 rec = (struct record_logicaldisk *)(table->data + offset);
2462 swprintf( device_id, ARRAY_SIZE( device_id ), L"%c:", 'A' + i );
2463 rec->device_id = heap_strdupW( device_id );
2464 rec->drivetype = type;
2465 rec->filesystem = get_filesystem( root );
2466 rec->freespace = get_freespace( root, &size );
2467 rec->name = heap_strdupW( device_id );
2468 rec->size = size;
2469 rec->volumename = get_volumename( root );
2470 rec->volumeserialnumber = get_volumeserialnumber( root );
2471 if (!match_row( table, row, cond, &status ))
2473 free_row_values( table, row );
2474 continue;
2476 offset += sizeof(*rec);
2477 row++;
2480 TRACE("created %u rows\n", row);
2481 table->num_rows = row;
2482 return status;
2485 static struct association *get_logicaldisktopartition_pairs( UINT *count )
2487 struct association *ret = NULL;
2488 struct query *query, *query2 = NULL;
2489 VARIANT val;
2490 HRESULT hr;
2491 UINT i;
2493 if (!(query = create_query())) return NULL;
2494 if ((hr = parse_query( L"SELECT * FROM Win32_DiskPartition", &query->view, &query->mem )) != S_OK) goto done;
2495 if ((hr = execute_view( query->view )) != S_OK) goto done;
2497 if (!(query2 = create_query())) return FALSE;
2498 if ((hr = parse_query( L"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2->view,
2499 &query2->mem )) != S_OK) goto done;
2500 if ((hr = execute_view( query2->view )) != S_OK) goto done;
2502 if (!(ret = heap_alloc_zero( query->view->result_count * sizeof(*ret) ))) goto done;
2504 /* assume fixed and removable disks are enumerated in the same order as partitions */
2505 for (i = 0; i < query->view->result_count; i++)
2507 if ((hr = get_propval( query->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2508 if (!(ret[i].ref = heap_strdupW( V_BSTR(&val) ))) goto done;
2509 VariantClear( &val );
2511 if ((hr = get_propval( query2->view, i, L"__PATH", &val, NULL, NULL )) != S_OK) goto done;
2512 if (!(ret[i].ref2 = heap_strdupW( V_BSTR(&val) ))) goto done;
2513 VariantClear( &val );
2516 *count = query->view->result_count;
2518 done:
2519 if (!ret) free_associations( ret, query->view->result_count );
2520 free_query( query );
2521 free_query( query2 );
2522 return ret;
2525 static enum fill_status fill_logicaldisktopartition( struct table *table, const struct expr *cond )
2527 struct record_logicaldisktopartition *rec;
2528 UINT i, row = 0, offset = 0, count = 0;
2529 enum fill_status status = FILL_STATUS_UNFILTERED;
2530 struct association *assoc;
2532 if (!(assoc = get_logicaldisktopartition_pairs( &count ))) return FILL_STATUS_FAILED;
2533 if (!count)
2535 free_associations( assoc, count );
2536 return FILL_STATUS_UNFILTERED;
2538 if (!resize_table( table, count, sizeof(*rec) ))
2540 free_associations( assoc, count );
2541 return FILL_STATUS_FAILED;
2544 for (i = 0; i < count; i++)
2546 rec = (struct record_logicaldisktopartition *)(table->data + offset);
2547 rec->antecedent = assoc[i].ref;
2548 rec->dependent = assoc[i].ref2;
2549 if (!match_row( table, row, cond, &status ))
2551 free_row_values( table, row );
2552 continue;
2554 offset += sizeof(*rec);
2555 row++;
2558 heap_free( assoc );
2560 TRACE("created %u rows\n", row);
2561 table->num_rows = row;
2562 return status;
2565 static UINT16 get_connection_status( IF_OPER_STATUS status )
2567 switch (status)
2569 case IfOperStatusDown:
2570 return 0; /* Disconnected */
2571 case IfOperStatusUp:
2572 return 2; /* Connected */
2573 default:
2574 ERR("unhandled status %u\n", status);
2575 break;
2577 return 0;
2579 static WCHAR *get_mac_address( const BYTE *addr, DWORD len )
2581 WCHAR *ret;
2582 if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL;
2583 swprintf( ret, 18, L"%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] );
2584 return ret;
2586 static const WCHAR *get_adaptertype( DWORD type, int *id, int *physical )
2588 switch (type)
2590 case IF_TYPE_ETHERNET_CSMACD:
2591 *id = 0;
2592 *physical = -1;
2593 return L"Ethernet 802.3";
2595 case IF_TYPE_IEEE80211:
2596 *id = 9;
2597 *physical = -1;
2598 return L"Wireless";
2600 case IF_TYPE_IEEE1394:
2601 *id = 13;
2602 *physical = -1;
2603 return L"1394";
2605 case IF_TYPE_TUNNEL:
2606 *id = 15;
2607 *physical = 0;
2608 return L"Tunnel";
2610 default:
2611 *id = -1;
2612 *physical = 0;
2613 return NULL;
2617 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond )
2619 WCHAR device_id[11];
2620 struct record_networkadapter *rec;
2621 IP_ADAPTER_ADDRESSES *aa, *buffer;
2622 UINT row = 0, offset = 0, count = 0;
2623 DWORD size = 0, ret;
2624 int adaptertypeid, physical;
2625 enum fill_status status = FILL_STATUS_UNFILTERED;
2627 ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size );
2628 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2630 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2631 if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size ))
2633 heap_free( buffer );
2634 return FILL_STATUS_FAILED;
2636 for (aa = buffer; aa; aa = aa->Next)
2638 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2640 if (!resize_table( table, count, sizeof(*rec) ))
2642 heap_free( buffer );
2643 return FILL_STATUS_FAILED;
2645 for (aa = buffer; aa; aa = aa->Next)
2647 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2649 rec = (struct record_networkadapter *)(table->data + offset);
2650 swprintf( device_id, ARRAY_SIZE( device_id ), L"%u", aa->u.s.IfIndex );
2651 rec->adaptertype = get_adaptertype( aa->IfType, &adaptertypeid, &physical );
2652 rec->adaptertypeid = adaptertypeid;
2653 rec->description = heap_strdupW( aa->Description );
2654 rec->device_id = heap_strdupW( device_id );
2655 rec->index = aa->u.s.IfIndex;
2656 rec->interface_index = aa->u.s.IfIndex;
2657 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2658 rec->manufacturer = L"The Wine Project";
2659 rec->name = heap_strdupW( aa->FriendlyName );
2660 rec->netconnection_status = get_connection_status( aa->OperStatus );
2661 rec->physicaladapter = physical;
2662 rec->pnpdevice_id = L"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2663 rec->speed = 1000000;
2664 if (!match_row( table, row, cond, &status ))
2666 free_row_values( table, row );
2667 continue;
2669 offset += sizeof(*rec);
2670 row++;
2672 TRACE("created %u rows\n", row);
2673 table->num_rows = row;
2675 heap_free( buffer );
2676 return status;
2679 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr )
2681 const SOCKET_ADDRESS *sa = &addr->Address;
2682 WCHAR buf[NI_MAXHOST];
2684 if (!addr) return NULL;
2685 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL,
2686 0, NI_NAMEREQD )) return NULL;
2687 return heap_strdupW( buf );
2689 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list )
2691 IP_ADAPTER_GATEWAY_ADDRESS *gateway;
2692 struct array *ret;
2693 ULONG buflen, i = 0, count = 0;
2694 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2696 if (!list) return NULL;
2697 for (gateway = list; gateway; gateway = gateway->Next) count++;
2699 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2700 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2702 heap_free( ret );
2703 return NULL;
2705 for (gateway = list; gateway; gateway = gateway->Next)
2707 buflen = ARRAY_SIZE( buf );
2708 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength,
2709 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2711 for (; i > 0; i--) heap_free( ptr[i - 1] );
2712 heap_free( ptr );
2713 heap_free( ret );
2714 return NULL;
2717 ret->elem_size = sizeof(*ptr);
2718 ret->count = count;
2719 ret->ptr = ptr;
2720 return ret;
2722 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list )
2724 IP_ADAPTER_DNS_SERVER_ADDRESS *server;
2725 struct array *ret;
2726 ULONG buflen, i = 0, count = 0;
2727 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */
2729 if (!list) return NULL;
2730 for (server = list; server; server = server->Next) count++;
2732 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2733 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2735 heap_free( ret );
2736 return NULL;
2738 for (server = list; server; server = server->Next)
2740 buflen = ARRAY_SIZE( buf );
2741 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength,
2742 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2744 for (; i > 0; i--) heap_free( ptr[i - 1] );
2745 heap_free( ptr );
2746 heap_free( ret );
2747 return NULL;
2749 if ((p = wcsrchr( ptr[i - 1], ':' ))) *p = 0;
2751 ret->elem_size = sizeof(*ptr);
2752 ret->count = count;
2753 ret->ptr = ptr;
2754 return ret;
2756 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2758 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2759 struct array *ret;
2760 ULONG buflen, i = 0, count = 0;
2761 WCHAR **ptr, buf[54]; /* max IPv6 address length */
2763 if (!list) return NULL;
2764 for (address = list; address; address = address->Next) count++;
2766 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2767 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2769 heap_free( ret );
2770 return NULL;
2772 for (address = list; address; address = address->Next)
2774 buflen = ARRAY_SIZE( buf );
2775 if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength,
2776 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf )))
2778 for (; i > 0; i--) heap_free( ptr[i - 1] );
2779 heap_free( ptr );
2780 heap_free( ret );
2781 return NULL;
2784 ret->elem_size = sizeof(*ptr);
2785 ret->count = count;
2786 ret->ptr = ptr;
2787 return ret;
2789 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list )
2791 IP_ADAPTER_UNICAST_ADDRESS_LH *address;
2792 struct array *ret;
2793 ULONG i = 0, count = 0;
2794 WCHAR **ptr;
2796 if (!list) return NULL;
2797 for (address = list; address; address = address->Next) count++;
2799 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
2800 if (!(ptr = heap_alloc( sizeof(*ptr) * count )))
2802 heap_free( ret );
2803 return NULL;
2805 for (address = list; address; address = address->Next)
2807 if (address->Address.lpSockaddr->sa_family == AF_INET)
2809 WCHAR buf[INET_ADDRSTRLEN];
2810 SOCKADDR_IN addr;
2811 ULONG buflen = ARRAY_SIZE( buf );
2813 memset( &addr, 0, sizeof(addr) );
2814 addr.sin_family = AF_INET;
2815 if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR
2816 || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen))
2817 ptr[i] = NULL;
2818 else
2819 ptr[i] = heap_strdupW( buf );
2821 else
2823 WCHAR buf[11];
2824 swprintf( buf, ARRAY_SIZE( buf ), L"%u", address->OnLinkPrefixLength );
2825 ptr[i] = heap_strdupW( buf );
2827 if (!ptr[i++])
2829 for (; i > 0; i--) heap_free( ptr[i - 1] );
2830 heap_free( ptr );
2831 heap_free( ret );
2832 return NULL;
2835 ret->elem_size = sizeof(*ptr);
2836 ret->count = count;
2837 ret->ptr = ptr;
2838 return ret;
2840 static WCHAR *get_settingid( UINT32 index )
2842 GUID guid;
2843 WCHAR *ret, *str;
2844 memset( &guid, 0, sizeof(guid) );
2845 guid.Data1 = index;
2846 UuidToStringW( &guid, &str );
2847 ret = heap_strdupW( str );
2848 RpcStringFreeW( &str );
2849 return ret;
2852 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond )
2854 struct record_networkadapterconfig *rec;
2855 IP_ADAPTER_ADDRESSES *aa, *buffer;
2856 UINT row = 0, offset = 0, count = 0;
2857 DWORD size = 0, ret;
2858 enum fill_status status = FILL_STATUS_UNFILTERED;
2860 ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size );
2861 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED;
2863 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED;
2864 if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size ))
2866 heap_free( buffer );
2867 return FILL_STATUS_FAILED;
2869 for (aa = buffer; aa; aa = aa->Next)
2871 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++;
2873 if (!resize_table( table, count, sizeof(*rec) ))
2875 heap_free( buffer );
2876 return FILL_STATUS_FAILED;
2878 for (aa = buffer; aa; aa = aa->Next)
2880 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue;
2882 rec = (struct record_networkadapterconfig *)(table->data + offset);
2883 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress );
2884 rec->description = heap_strdupW( aa->Description );
2885 rec->dhcpenabled = -1;
2886 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress );
2887 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress );
2888 rec->index = aa->u.s.IfIndex;
2889 rec->ipaddress = get_ipaddress( aa->FirstUnicastAddress );
2890 rec->ipconnectionmetric = 20;
2891 rec->ipenabled = -1;
2892 rec->ipsubnet = get_ipsubnet( aa->FirstUnicastAddress );
2893 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength );
2894 rec->settingid = get_settingid( rec->index );
2895 if (!match_row( table, row, cond, &status ))
2897 free_row_values( table, row );
2898 continue;
2900 offset += sizeof(*rec);
2901 row++;
2903 TRACE("created %u rows\n", row);
2904 table->num_rows = row;
2906 heap_free( buffer );
2907 return status;
2910 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond )
2912 struct record_physicalmemory *rec;
2913 enum fill_status status = FILL_STATUS_UNFILTERED;
2914 UINT row = 0;
2916 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
2918 rec = (struct record_physicalmemory *)table->data;
2919 rec->banklabel = L"BANK 0";
2920 rec->capacity = get_total_physical_memory();
2921 rec->caption = L"Physical Memory";
2922 rec->configuredclockspeed = 1600;
2923 rec->devicelocator = L"DIMM 0";
2924 rec->formfactor = 8; /* DIMM */
2925 rec->memorytype = 9; /* RAM */
2926 rec->partnumber = L"";
2927 rec->serial = L"";
2928 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
2929 else row++;
2931 TRACE("created %u rows\n", row);
2932 table->num_rows = row;
2933 return status;
2936 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond )
2938 struct record_pnpentity *rec;
2939 enum fill_status status = FILL_STATUS_UNFILTERED;
2940 HDEVINFO device_info_set;
2941 SP_DEVINFO_DATA devinfo = {0};
2942 DWORD idx;
2944 device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT );
2946 devinfo.cbSize = sizeof(devinfo);
2948 idx = 0;
2949 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
2951 /* noop */
2954 resize_table( table, idx, sizeof(*rec) );
2955 table->num_rows = 0;
2956 rec = (struct record_pnpentity *)table->data;
2958 idx = 0;
2959 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo ))
2961 WCHAR device_id[MAX_PATH];
2962 if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id,
2963 ARRAY_SIZE(device_id), NULL ))
2965 rec->device_id = heap_strdupW( device_id );
2967 table->num_rows++;
2968 if (!match_row( table, table->num_rows - 1, cond, &status ))
2970 free_row_values( table, table->num_rows - 1 );
2971 table->num_rows--;
2973 else
2974 rec++;
2978 SetupDiDestroyDeviceInfoList( device_info_set );
2980 return status;
2983 static enum fill_status fill_printer( struct table *table, const struct expr *cond )
2985 struct record_printer *rec;
2986 enum fill_status status = FILL_STATUS_UNFILTERED;
2987 PRINTER_INFO_2W *info;
2988 DWORD i, offset = 0, count = 0, size = 0, num_rows = 0;
2989 WCHAR id[20];
2991 EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count );
2992 if (!count) return FILL_STATUS_UNFILTERED;
2994 if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED;
2995 if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count ))
2997 heap_free( info );
2998 return FILL_STATUS_FAILED;
3000 if (!resize_table( table, count, sizeof(*rec) ))
3002 heap_free( info );
3003 return FILL_STATUS_FAILED;
3006 for (i = 0; i < count; i++)
3008 rec = (struct record_printer *)(table->data + offset);
3009 rec->attributes = info[i].Attributes;
3010 swprintf( id, ARRAY_SIZE( id ), L"Printer%u", i );
3011 rec->device_id = heap_strdupW( id );
3012 rec->drivername = heap_strdupW( info[i].pDriverName );
3013 rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality;
3014 rec->local = -1;
3015 rec->location = heap_strdupW( info[i].pLocation );
3016 rec->name = heap_strdupW( info[i].pPrinterName );
3017 rec->network = 0;
3018 rec->portname = heap_strdupW( info[i].pPortName );
3019 if (!match_row( table, i, cond, &status ))
3021 free_row_values( table, i );
3022 continue;
3024 offset += sizeof(*rec);
3025 num_rows++;
3027 TRACE("created %u rows\n", num_rows);
3028 table->num_rows = num_rows;
3030 heap_free( info );
3031 return status;
3034 static WCHAR *get_cmdline( DWORD process_id )
3036 if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() );
3037 return NULL; /* FIXME handle different process case */
3040 static enum fill_status fill_process( struct table *table, const struct expr *cond )
3042 WCHAR handle[11];
3043 struct record_process *rec;
3044 PROCESSENTRY32W entry;
3045 HANDLE snap;
3046 enum fill_status status = FILL_STATUS_FAILED;
3047 UINT row = 0, offset = 0;
3049 snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
3050 if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED;
3052 entry.dwSize = sizeof(entry);
3053 if (!Process32FirstW( snap, &entry )) goto done;
3054 if (!resize_table( table, 8, sizeof(*rec) )) goto done;
3058 if (!resize_table( table, row + 1, sizeof(*rec) ))
3060 status = FILL_STATUS_FAILED;
3061 goto done;
3064 rec = (struct record_process *)(table->data + offset);
3065 rec->caption = heap_strdupW( entry.szExeFile );
3066 rec->commandline = get_cmdline( entry.th32ProcessID );
3067 rec->description = heap_strdupW( entry.szExeFile );
3068 swprintf( handle, ARRAY_SIZE( handle ), L"%u", entry.th32ProcessID );
3069 rec->handle = heap_strdupW( handle );
3070 rec->name = heap_strdupW( entry.szExeFile );
3071 rec->process_id = entry.th32ProcessID;
3072 rec->pprocess_id = entry.th32ParentProcessID;
3073 rec->thread_count = entry.cntThreads;
3074 rec->workingsetsize = 0;
3075 rec->get_owner = process_get_owner;
3076 if (!match_row( table, row, cond, &status ))
3078 free_row_values( table, row );
3079 continue;
3081 offset += sizeof(*rec);
3082 row++;
3083 } while (Process32NextW( snap, &entry ));
3085 TRACE("created %u rows\n", row);
3086 table->num_rows = row;
3088 done:
3089 CloseHandle( snap );
3090 return status;
3093 void do_cpuid( unsigned int ax, int *p )
3095 #if defined(__i386__) || defined(__x86_64__)
3096 __cpuid( p, ax );
3097 #else
3098 FIXME("\n");
3099 #endif
3102 static unsigned int get_processor_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
3104 unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
3106 model = (reg0 & (0x0f << 4)) >> 4;
3107 if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
3108 if (family)
3110 *family = family_id;
3111 if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
3113 *stepping = reg0 & 0x0f;
3114 return model;
3116 static void regs_to_str( int *regs, unsigned int len, WCHAR *buffer )
3118 unsigned int i;
3119 unsigned char *p = (unsigned char *)regs;
3121 for (i = 0; i < len; i++) { buffer[i] = *p++; }
3122 buffer[i] = 0;
3124 static void get_processor_manufacturer( WCHAR *manufacturer, UINT len )
3126 int tmp, regs[4] = {0, 0, 0, 0};
3128 do_cpuid( 0, regs );
3129 tmp = regs[2]; /* swap edx and ecx */
3130 regs[2] = regs[3];
3131 regs[3] = tmp;
3133 regs_to_str( regs + 1, min( 12, len ), manufacturer );
3135 static const WCHAR *get_osarchitecture(void)
3137 SYSTEM_INFO info;
3138 GetNativeSystemInfo( &info );
3139 if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return L"64-bit";
3140 return L"32-bit";
3142 static void get_processor_caption( WCHAR *caption, UINT len )
3144 const WCHAR *arch;
3145 WCHAR manufacturer[13];
3146 int regs[4] = {0, 0, 0, 0};
3147 unsigned int family, model, stepping;
3149 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3150 if (!wcscmp( get_osarchitecture(), L"32-bit" )) arch = L"x86";
3151 else if (!wcscmp( manufacturer, L"AuthenticAMD" )) arch = L"AMD64";
3152 else arch = L"Intel64";
3154 do_cpuid( 1, regs );
3156 model = get_processor_model( regs[0], &stepping, &family );
3157 swprintf( caption, len, L"%s Family %u Model %u Stepping %u", arch, family, model, stepping );
3159 static void get_processor_version( WCHAR *version, UINT len )
3161 int regs[4] = {0, 0, 0, 0};
3162 unsigned int model, stepping;
3164 do_cpuid( 1, regs );
3166 model = get_processor_model( regs[0], &stepping, NULL );
3167 swprintf( version, len, L"Model %u Stepping %u", model, stepping );
3169 static UINT16 get_processor_revision(void)
3171 int regs[4] = {0, 0, 0, 0};
3172 do_cpuid( 1, regs );
3173 return regs[0];
3175 static void get_processor_id( WCHAR *processor_id, UINT len )
3177 int regs[4] = {0, 0, 0, 0};
3179 do_cpuid( 1, regs );
3180 swprintf( processor_id, len, L"%08X%08X", regs[3], regs[0] );
3182 static void get_processor_name( WCHAR *name )
3184 int regs[4] = {0, 0, 0, 0};
3185 int i;
3187 do_cpuid( 0x80000000, regs );
3188 if (regs[0] >= 0x80000004)
3190 do_cpuid( 0x80000002, regs );
3191 regs_to_str( regs, 16, name );
3192 do_cpuid( 0x80000003, regs );
3193 regs_to_str( regs, 16, name + 16 );
3194 do_cpuid( 0x80000004, regs );
3195 regs_to_str( regs, 16, name + 32 );
3197 for (i = lstrlenW(name) - 1; i >= 0 && name[i] == ' '; i--) name[i] = 0;
3199 static UINT get_processor_currentclockspeed( UINT index )
3201 PROCESSOR_POWER_INFORMATION *info;
3202 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3203 NTSTATUS status;
3205 if ((info = heap_alloc( size )))
3207 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3208 if (!status) ret = info[index].CurrentMhz;
3209 heap_free( info );
3211 return ret;
3213 static UINT get_processor_maxclockspeed( UINT index )
3215 PROCESSOR_POWER_INFORMATION *info;
3216 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION);
3217 NTSTATUS status;
3219 if ((info = heap_alloc( size )))
3221 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size );
3222 if (!status) ret = info[index].MaxMhz;
3223 heap_free( info );
3225 return ret;
3228 static enum fill_status fill_processor( struct table *table, const struct expr *cond )
3230 WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
3231 struct record_processor *rec;
3232 UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
3233 enum fill_status status = FILL_STATUS_UNFILTERED;
3235 num_logical = get_logical_processor_count( &num_physical, &num_packages );
3237 if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
3239 get_processor_caption( caption, ARRAY_SIZE( caption ) );
3240 get_processor_id( processor_id, ARRAY_SIZE( processor_id ) );
3241 get_processor_manufacturer( manufacturer, ARRAY_SIZE( manufacturer ) );
3242 get_processor_name( name );
3243 get_processor_version( version, ARRAY_SIZE( version ) );
3245 for (i = 0; i < num_packages; i++)
3247 rec = (struct record_processor *)(table->data + offset);
3248 rec->addresswidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3249 rec->architecture = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 0 : 9;
3250 rec->caption = heap_strdupW( caption );
3251 rec->cpu_status = 1; /* CPU Enabled */
3252 rec->currentclockspeed = get_processor_currentclockspeed( i );
3253 rec->datawidth = !wcscmp( get_osarchitecture(), L"32-bit" ) ? 32 : 64;
3254 rec->description = heap_strdupW( caption );
3255 swprintf( device_id, ARRAY_SIZE( device_id ), L"CPU%u", i );
3256 rec->device_id = heap_strdupW( device_id );
3257 rec->family = 2; /* Unknown */
3258 rec->level = 15;
3259 rec->manufacturer = heap_strdupW( manufacturer );
3260 rec->maxclockspeed = get_processor_maxclockspeed( i );
3261 rec->name = heap_strdupW( name );
3262 rec->num_cores = num_physical / num_packages;
3263 rec->num_logical_processors = num_logical / num_packages;
3264 rec->processor_id = heap_strdupW( processor_id );
3265 rec->processortype = 3; /* central processor */
3266 rec->revision = get_processor_revision();
3267 rec->unique_id = NULL;
3268 rec->version = heap_strdupW( version );
3269 if (!match_row( table, i, cond, &status ))
3271 free_row_values( table, i );
3272 continue;
3274 offset += sizeof(*rec);
3275 num_rows++;
3278 TRACE("created %u rows\n", num_rows);
3279 table->num_rows = num_rows;
3280 return status;
3283 static WCHAR *get_lastbootuptime(void)
3285 SYSTEM_TIMEOFDAY_INFORMATION ti;
3286 TIME_FIELDS tf;
3287 WCHAR *ret;
3289 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3291 NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL );
3292 RtlTimeToTimeFields( &ti.BootTime, &tf );
3293 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u+000", tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute,
3294 tf.Second, tf.Milliseconds * 1000 );
3295 return ret;
3297 static WCHAR *get_localdatetime(void)
3299 TIME_ZONE_INFORMATION tzi;
3300 SYSTEMTIME st;
3301 WCHAR *ret;
3302 DWORD Status;
3303 LONG Bias;
3305 Status = GetTimeZoneInformation(&tzi);
3307 if(Status == TIME_ZONE_ID_INVALID) return NULL;
3308 Bias = tzi.Bias;
3309 if(Status == TIME_ZONE_ID_DAYLIGHT)
3310 Bias+= tzi.DaylightBias;
3311 else
3312 Bias+= tzi.StandardBias;
3313 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL;
3315 GetLocalTime(&st);
3316 swprintf( ret, 26, L"%04u%02u%02u%02u%02u%02u.%06u%+03d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
3317 st.wSecond, st.wMilliseconds * 1000, -Bias );
3318 return ret;
3320 static WCHAR *get_systemdirectory(void)
3322 void *redir;
3323 WCHAR *ret;
3325 if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL;
3326 Wow64DisableWow64FsRedirection( &redir );
3327 GetSystemDirectoryW( ret, MAX_PATH );
3328 Wow64RevertWow64FsRedirection( redir );
3329 return ret;
3331 static WCHAR *get_systemdrive(void)
3333 WCHAR *ret = heap_alloc( 3 * sizeof(WCHAR) ); /* "c:" */
3334 if (ret && GetEnvironmentVariableW( L"SystemDrive", ret, 3 )) return ret;
3335 heap_free( ret );
3336 return NULL;
3338 static WCHAR *get_codeset(void)
3340 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3341 if (ret) swprintf( ret, 11, L"%u", GetACP() );
3342 return ret;
3344 static WCHAR *get_countrycode(void)
3346 WCHAR *ret = heap_alloc( 6 * sizeof(WCHAR) );
3347 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 );
3348 return ret;
3350 static WCHAR *get_locale(void)
3352 WCHAR *ret = heap_alloc( 5 * sizeof(WCHAR) );
3353 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 );
3354 return ret;
3356 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver )
3358 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) );
3359 if (ret) swprintf( ret, 11, L"%u", ver->dwBuildNumber );
3360 return ret;
3362 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver )
3364 static const WCHAR windowsW[] = L"Microsoft Windows ";
3365 static const WCHAR win2000W[] = L"2000 Professional";
3366 static const WCHAR win2003W[] = L"Server 2003 Standard Edition";
3367 static const WCHAR winxpW[] = L"XP Professional";
3368 static const WCHAR winxp64W[] = L"XP Professional x64 Edition";
3369 static const WCHAR vistaW[] = L"Vista Ultimate";
3370 static const WCHAR win2008W[] = L"Server 2008 Standard";
3371 static const WCHAR win7W[] = L"7 Professional";
3372 static const WCHAR win2008r2W[] = L"Server 2008 R2 Standard";
3373 static const WCHAR win8W[] = L"8 Pro";
3374 static const WCHAR win81W[] = L"8.1 Pro";
3375 static const WCHAR win10W[] = L"10 Pro";
3376 int len = ARRAY_SIZE( windowsW ) - 1;
3377 WCHAR *ret;
3379 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL;
3380 memcpy( ret, windowsW, sizeof(windowsW) );
3381 if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) );
3382 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win8W, sizeof(win8W) );
3383 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win81W, sizeof(win81W) );
3384 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1)
3386 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) );
3387 else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) );
3389 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0)
3391 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) );
3392 else memcpy( ret + len, win2008W, sizeof(win2008W) );
3394 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2)
3396 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) );
3397 else memcpy( ret + len, win2003W, sizeof(win2003W) );
3399 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) );
3400 else memcpy( ret + len, win2000W, sizeof(win2000W) );
3401 return ret;
3403 static WCHAR *get_osname( const WCHAR *caption )
3405 static const WCHAR partitionW[] = L"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3406 int len = lstrlenW( caption );
3407 WCHAR *ret;
3409 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL;
3410 memcpy( ret, caption, len * sizeof(WCHAR) );
3411 memcpy( ret + len, partitionW, sizeof(partitionW) );
3412 return ret;
3414 static WCHAR *get_osserialnumber(void)
3416 HKEY hkey = 0;
3417 DWORD size, type;
3418 WCHAR *ret = NULL;
3420 if (!RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hkey ) &&
3421 !RegQueryValueExW( hkey, L"ProductId", NULL, &type, NULL, &size ) && type == REG_SZ &&
3422 (ret = heap_alloc( size + sizeof(WCHAR) )))
3424 size += sizeof(WCHAR);
3425 if (RegQueryValueExW( hkey, L"ProductId", NULL, NULL, (BYTE *)ret, &size ))
3427 heap_free( ret );
3428 ret = NULL;
3431 if (hkey) RegCloseKey( hkey );
3432 if (!ret) return heap_strdupW( L"12345-OEM-1234567-12345" );
3433 return ret;
3435 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver )
3437 WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) );
3438 if (ret) swprintf( ret, 33, L"%u.%u.%u", ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber );
3439 return ret;
3441 static DWORD get_operatingsystemsku(void)
3443 DWORD ret = PRODUCT_UNDEFINED;
3444 GetProductInfo( 6, 0, 0, 0, &ret );
3445 return ret;
3447 static INT16 get_currenttimezone(void)
3449 TIME_ZONE_INFORMATION info;
3450 DWORD status = GetTimeZoneInformation( &info );
3451 if (status == TIME_ZONE_ID_INVALID) return 0;
3452 if (status == TIME_ZONE_ID_DAYLIGHT) return -(info.Bias + info.DaylightBias);
3453 return -(info.Bias + info.StandardBias);
3456 static enum fill_status fill_operatingsystem( struct table *table, const struct expr *cond )
3458 struct record_operatingsystem *rec;
3459 enum fill_status status = FILL_STATUS_UNFILTERED;
3460 OSVERSIONINFOEXW ver;
3461 UINT row = 0;
3463 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3465 ver.dwOSVersionInfoSize = sizeof(ver);
3466 GetVersionExW( (OSVERSIONINFOW *)&ver );
3468 rec = (struct record_operatingsystem *)table->data;
3469 rec->buildnumber = get_osbuildnumber( &ver );
3470 rec->caption = get_oscaption( &ver );
3471 rec->codeset = get_codeset();
3472 rec->countrycode = get_countrycode();
3473 rec->csdversion = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL;
3474 rec->csname = get_computername();
3475 rec->currenttimezone = get_currenttimezone();
3476 rec->freephysicalmemory = get_available_physical_memory() / 1024;
3477 rec->installdate = L"20140101000000.000000+000";
3478 rec->lastbootuptime = get_lastbootuptime();
3479 rec->localdatetime = get_localdatetime();
3480 rec->locale = get_locale();
3481 rec->manufacturer = L"The Wine Project";
3482 rec->name = get_osname( rec->caption );
3483 rec->operatingsystemsku = get_operatingsystemsku();
3484 rec->osarchitecture = get_osarchitecture();
3485 rec->oslanguage = GetSystemDefaultLangID();
3486 rec->osproductsuite = 2461140; /* Windows XP Professional */
3487 rec->ostype = 18; /* WINNT */
3488 rec->primary = -1;
3489 rec->serialnumber = get_osserialnumber();
3490 rec->servicepackmajor = ver.wServicePackMajor;
3491 rec->servicepackminor = ver.wServicePackMinor;
3492 rec->suitemask = 272; /* Single User + Terminal */
3493 rec->systemdirectory = get_systemdirectory();
3494 rec->systemdrive = get_systemdrive();
3495 rec->totalvirtualmemorysize = get_total_physical_memory() / 1024;
3496 rec->totalvisiblememorysize = rec->totalvirtualmemorysize;
3497 rec->version = get_osversion( &ver );
3498 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3499 else row++;
3501 TRACE("created %u rows\n", row);
3502 table->num_rows = row;
3503 return status;
3506 static const WCHAR *get_service_type( DWORD type )
3508 if (type & SERVICE_KERNEL_DRIVER) return L"Kernel Driver";
3509 else if (type & SERVICE_FILE_SYSTEM_DRIVER) return L"File System Driver";
3510 else if (type & SERVICE_WIN32_OWN_PROCESS) return L"Own Process";
3511 else if (type & SERVICE_WIN32_SHARE_PROCESS) return L"Share Process";
3512 else ERR("unhandled type 0x%08x\n", type);
3513 return NULL;
3515 static const WCHAR *get_service_state( DWORD state )
3517 switch (state)
3519 case SERVICE_STOPPED: return L"Stopped";
3520 case SERVICE_START_PENDING: return L"Start Pending";
3521 case SERVICE_STOP_PENDING: return L"Stop Pending";
3522 case SERVICE_RUNNING: return L"Running";
3523 default:
3524 ERR("unknown state %u\n", state);
3525 return L"Unknown";
3528 static const WCHAR *get_service_startmode( DWORD mode )
3530 switch (mode)
3532 case SERVICE_BOOT_START: return L"Boot";
3533 case SERVICE_SYSTEM_START: return L"System";
3534 case SERVICE_AUTO_START: return L"Auto";
3535 case SERVICE_DEMAND_START: return L"Manual";
3536 case SERVICE_DISABLED: return L"Disabled";
3537 default:
3538 ERR("unknown mode 0x%x\n", mode);
3539 return L"Unknown";
3542 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name )
3544 QUERY_SERVICE_CONFIGW *config = NULL;
3545 SC_HANDLE service;
3546 DWORD size;
3548 if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL;
3549 QueryServiceConfigW( service, NULL, 0, &size );
3550 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
3551 if (!(config = heap_alloc( size ))) goto done;
3552 if (QueryServiceConfigW( service, config, size, &size )) goto done;
3553 heap_free( config );
3554 config = NULL;
3556 done:
3557 CloseServiceHandle( service );
3558 return config;
3561 static enum fill_status fill_service( struct table *table, const struct expr *cond )
3563 struct record_service *rec;
3564 SC_HANDLE manager;
3565 ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL;
3566 SERVICE_STATUS_PROCESS *status;
3567 WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1];
3568 DWORD len = ARRAY_SIZE( sysnameW );
3569 UINT i, row = 0, offset = 0, size = 256, needed, count;
3570 enum fill_status fill_status = FILL_STATUS_FAILED;
3571 BOOL ret;
3573 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED;
3574 if (!(services = heap_alloc( size ))) goto done;
3576 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3577 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3578 &count, NULL, NULL );
3579 if (!ret)
3581 if (GetLastError() != ERROR_MORE_DATA) goto done;
3582 size = needed;
3583 if (!(tmp = heap_realloc( services, size ))) goto done;
3584 services = tmp;
3585 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL,
3586 SERVICE_STATE_ALL, (BYTE *)services, size, &needed,
3587 &count, NULL, NULL );
3588 if (!ret) goto done;
3590 if (!resize_table( table, count, sizeof(*rec) )) goto done;
3592 GetComputerNameW( sysnameW, &len );
3593 fill_status = FILL_STATUS_UNFILTERED;
3595 for (i = 0; i < count; i++)
3597 QUERY_SERVICE_CONFIGW *config;
3599 if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue;
3601 status = &services[i].ServiceStatusProcess;
3602 rec = (struct record_service *)(table->data + offset);
3603 rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0;
3604 rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0;
3605 rec->displayname = heap_strdupW( services[i].lpDisplayName );
3606 rec->name = heap_strdupW( services[i].lpServiceName );
3607 rec->process_id = status->dwProcessId;
3608 rec->servicetype = get_service_type( status->dwServiceType );
3609 rec->startmode = get_service_startmode( config->dwStartType );
3610 rec->state = get_service_state( status->dwCurrentState );
3611 rec->systemname = heap_strdupW( sysnameW );
3612 rec->pause_service = service_pause_service;
3613 rec->resume_service = service_resume_service;
3614 rec->start_service = service_start_service;
3615 rec->stop_service = service_stop_service;
3616 heap_free( config );
3617 if (!match_row( table, row, cond, &fill_status ))
3619 free_row_values( table, row );
3620 continue;
3622 offset += sizeof(*rec);
3623 row++;
3626 TRACE("created %u rows\n", row);
3627 table->num_rows = row;
3629 done:
3630 CloseServiceHandle( manager );
3631 heap_free( services );
3632 return fill_status;
3635 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name )
3637 if (!name || !name->Name.Buffer) return NULL;
3638 return heap_strdupW( name->Name.Buffer );
3640 static struct array *get_binaryrepresentation( PSID sid, UINT len )
3642 struct array *ret;
3643 UINT8 *ptr;
3645 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
3646 if (!(ptr = heap_alloc( len )))
3648 heap_free( ret );
3649 return NULL;
3651 memcpy( ptr, sid, len );
3652 ret->elem_size = sizeof(*ptr);
3653 ret->count = len;
3654 ret->ptr = ptr;
3655 return ret;
3657 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain )
3659 if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL;
3660 return heap_strdupW( domain->Domains->Name.Buffer );
3662 static const WCHAR *find_sid_str( const struct expr *cond )
3664 const struct expr *left, *right;
3665 const WCHAR *ret = NULL;
3667 if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL;
3669 left = cond->u.expr.left;
3670 right = cond->u.expr.right;
3671 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !wcsicmp( left->u.propval->name, L"SID" ))
3673 ret = right->u.sval;
3675 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !wcsicmp( right->u.propval->name, L"SID" ))
3677 ret = left->u.sval;
3679 return ret;
3682 static enum fill_status fill_sid( struct table *table, const struct expr *cond )
3684 PSID sid;
3685 LSA_REFERENCED_DOMAIN_LIST *domain;
3686 LSA_TRANSLATED_NAME *name;
3687 LSA_HANDLE handle;
3688 LSA_OBJECT_ATTRIBUTES attrs;
3689 const WCHAR *str;
3690 struct record_sid *rec;
3691 UINT len;
3693 if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED;
3694 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3696 if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED;
3697 len = GetLengthSid( sid );
3699 memset( &attrs, 0, sizeof(attrs) );
3700 attrs.Length = sizeof(attrs);
3701 if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle ))
3703 LocalFree( sid );
3704 return FILL_STATUS_FAILED;
3706 if (LsaLookupSids( handle, 1, &sid, &domain, &name ))
3708 LocalFree( sid );
3709 LsaClose( handle );
3710 return FILL_STATUS_FAILED;
3713 rec = (struct record_sid *)table->data;
3714 rec->accountname = get_accountname( name );
3715 rec->binaryrepresentation = get_binaryrepresentation( sid, len );
3716 rec->referenceddomainname = get_referenceddomainname( domain );
3717 rec->sid = heap_strdupW( str );
3718 rec->sidlength = len;
3720 TRACE("created 1 row\n");
3721 table->num_rows = 1;
3723 LsaFreeMemory( domain );
3724 LsaFreeMemory( name );
3725 LocalFree( sid );
3726 LsaClose( handle );
3727 return FILL_STATUS_FILTERED;
3730 static WCHAR *get_systemenclosure_string( BYTE id, const char *buf, UINT len )
3732 const struct smbios_header *hdr;
3733 const struct smbios_chassis *chassis;
3734 UINT offset;
3736 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len ))) return NULL;
3738 chassis = (const struct smbios_chassis *)hdr;
3739 offset = (const char *)chassis - buf + chassis->hdr.length;
3740 return get_smbios_string( id, buf, offset, len );
3743 static WCHAR *get_systemenclosure_manufacturer( const char *buf, UINT len )
3745 WCHAR *ret = get_systemenclosure_string( 1, buf, len );
3746 if (!ret) return heap_strdupW( L"Wine" );
3747 return ret;
3750 static int get_systemenclosure_lockpresent( const char *buf, UINT len )
3752 const struct smbios_header *hdr;
3753 const struct smbios_chassis *chassis;
3755 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) return 0;
3757 chassis = (const struct smbios_chassis *)hdr;
3758 return (chassis->type & 0x80) ? -1 : 0;
3761 static struct array *dup_array( const struct array *src )
3763 struct array *dst;
3764 if (!(dst = heap_alloc( sizeof(*dst) ))) return NULL;
3765 if (!(dst->ptr = heap_alloc( src->count * src->elem_size )))
3767 heap_free( dst );
3768 return NULL;
3770 memcpy( dst->ptr, src->ptr, src->count * src->elem_size );
3771 dst->elem_size = src->elem_size;
3772 dst->count = src->count;
3773 return dst;
3776 static struct array *get_systemenclosure_chassistypes( const char *buf, UINT len )
3778 const struct smbios_header *hdr;
3779 const struct smbios_chassis *chassis;
3780 struct array *ret = NULL;
3781 UINT16 *types;
3783 if (!(hdr = find_smbios_entry( SMBIOS_TYPE_CHASSIS, buf, len )) || hdr->length < sizeof(*chassis)) goto done;
3784 chassis = (const struct smbios_chassis *)hdr;
3786 if (!(ret = heap_alloc( sizeof(*ret) ))) goto done;
3787 if (!(types = heap_alloc( sizeof(*types) )))
3789 heap_free( ret );
3790 return NULL;
3792 types[0] = chassis->type & ~0x80;
3794 ret->elem_size = sizeof(*types);
3795 ret->count = 1;
3796 ret->ptr = types;
3798 done:
3799 if (!ret) ret = dup_array( &systemenclosure_chassistypes_array );
3800 return ret;
3803 static enum fill_status fill_systemenclosure( struct table *table, const struct expr *cond )
3805 struct record_systemenclosure *rec;
3806 enum fill_status status = FILL_STATUS_UNFILTERED;
3807 UINT row = 0, len;
3808 char *buf;
3810 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3812 len = GetSystemFirmwareTable( RSMB, 0, NULL, 0 );
3813 if (!(buf = heap_alloc( len ))) return FILL_STATUS_FAILED;
3814 GetSystemFirmwareTable( RSMB, 0, buf, len );
3816 rec = (struct record_systemenclosure *)table->data;
3817 rec->caption = L"System Enclosure";
3818 rec->chassistypes = get_systemenclosure_chassistypes( buf, len );
3819 rec->description = L"System Enclosure";
3820 rec->lockpresent = get_systemenclosure_lockpresent( buf, len );
3821 rec->manufacturer = get_systemenclosure_manufacturer( buf, len );
3822 rec->name = L"System Enclosure";
3823 rec->tag = L"System Enclosure 0";
3824 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3825 else row++;
3827 heap_free( buf );
3829 TRACE("created %u rows\n", row);
3830 table->num_rows = row;
3831 return status;
3834 static WCHAR *get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
3836 static const WCHAR fmtW[] = L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
3837 UINT len = sizeof(fmtW) + 2;
3838 WCHAR *ret;
3840 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
3841 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
3842 return ret;
3845 #define HW_VENDOR_AMD 0x1002
3846 #define HW_VENDOR_NVIDIA 0x10de
3847 #define HW_VENDOR_VMWARE 0x15ad
3848 #define HW_VENDOR_INTEL 0x8086
3850 static const WCHAR *get_videocontroller_installeddriver( UINT vendorid )
3852 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
3854 if (vendorid == HW_VENDOR_AMD) return L"aticfx32.dll";
3855 else if (vendorid == HW_VENDOR_NVIDIA) return L"nvd3dum.dll";
3856 else if (vendorid == HW_VENDOR_INTEL) return L"igdudim32.dll";
3857 return L"wine.dll";
3860 static BOOL get_dxgi_adapter_desc( DXGI_ADAPTER_DESC *desc )
3862 IDXGIFactory *factory;
3863 IDXGIAdapter *adapter;
3864 HRESULT hr;
3866 memset( desc, 0, sizeof(*desc) );
3867 hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory );
3868 if (FAILED( hr )) return FALSE;
3870 hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter );
3871 if (FAILED( hr ))
3873 IDXGIFactory_Release( factory );
3874 return FALSE;
3877 hr = IDXGIAdapter_GetDesc( adapter, desc );
3878 IDXGIAdapter_Release( adapter );
3879 IDXGIFactory_Release( factory );
3880 return SUCCEEDED( hr );
3883 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond )
3885 struct record_videocontroller *rec;
3886 DXGI_ADAPTER_DESC desc;
3887 UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024;
3888 const WCHAR *name = L"VideoController1";
3889 enum fill_status status = FILL_STATUS_UNFILTERED;
3890 WCHAR mode[44];
3892 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3894 if (get_dxgi_adapter_desc( &desc ))
3896 if (desc.DedicatedVideoMemory > UINT_MAX) vidmem = 0xfff00000;
3897 else vidmem = desc.DedicatedVideoMemory;
3898 name = desc.Description;
3901 rec = (struct record_videocontroller *)table->data;
3902 rec->adapter_compatibility = L"(Standard display types)";
3903 rec->adapter_dactype = L"Integrated RAMDAC";
3904 rec->adapter_ram = vidmem;
3905 rec->availability = 3; /* Running or Full Power */
3906 rec->config_errorcode = 0; /* no error */
3907 rec->caption = heap_strdupW( name );
3908 rec->current_bitsperpixel = get_bitsperpixel( &hres, &vres );
3909 rec->current_horizontalres = hres;
3910 rec->current_refreshrate = 0; /* default refresh rate */
3911 rec->current_scanmode = 2; /* Unknown */
3912 rec->current_verticalres = vres;
3913 rec->description = heap_strdupW( name );
3914 rec->device_id = L"VideoController1";
3915 rec->driverdate = L"20170101000000.000000+000";
3916 rec->driverversion = L"1.0";
3917 rec->installeddriver = get_videocontroller_installeddriver( desc.VendorId );
3918 rec->name = heap_strdupW( name );
3919 rec->pnpdevice_id = get_videocontroller_pnpdeviceid( &desc );
3920 rec->status = L"OK";
3921 rec->videoarchitecture = 2; /* Unknown */
3922 rec->videomemorytype = 2; /* Unknown */
3923 swprintf( mode, ARRAY_SIZE( mode ), L"%u x %u x %I64u colors", hres, vres, (UINT64)1 << rec->current_bitsperpixel );
3924 rec->videomodedescription = heap_strdupW( mode );
3925 rec->videoprocessor = heap_strdupW( name );
3926 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3927 else row++;
3929 TRACE("created %u rows\n", row);
3930 table->num_rows = row;
3931 return status;
3934 static WCHAR *get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC *desc )
3936 static const WCHAR fmtW[] = L"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
3937 UINT len = sizeof(fmtW) + 2;
3938 WCHAR *ret;
3940 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
3941 swprintf( ret, len, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision );
3942 return ret;
3945 static enum fill_status fill_sounddevice( struct table *table, const struct expr *cond )
3947 struct record_sounddevice *rec;
3948 DXGI_ADAPTER_DESC desc;
3949 UINT row = 0;
3950 enum fill_status status = FILL_STATUS_UNFILTERED;
3952 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED;
3954 get_dxgi_adapter_desc( &desc );
3956 rec = (struct record_sounddevice *)table->data;
3957 rec->deviceid = get_sounddevice_pnpdeviceid( &desc );
3958 rec->manufacturer = L"The Wine Project";
3959 rec->name = L"Wine Audio Device";
3960 rec->pnpdeviceid = get_sounddevice_pnpdeviceid( &desc );
3961 rec->productname = L"Wine Audio Device";
3962 rec->status = L"OK";
3963 rec->statusinfo = 3;
3964 if (!match_row( table, row, cond, &status )) free_row_values( table, row );
3965 else row++;
3967 TRACE("created %u rows\n", row);
3968 table->num_rows = row;
3969 return status;
3972 #define C(c) sizeof(c)/sizeof(c[0]), c
3973 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
3974 static struct table builtin_classes[] =
3976 { L"__ASSOCIATORS", C(col_associator), D(data_associator) },
3977 { L"__PARAMETERS", C(col_param), D(data_param) },
3978 { L"__QUALIFIERS", C(col_qualifier), D(data_qualifier) },
3979 { L"__SystemSecurity", C(col_systemsecurity), D(data_systemsecurity) },
3980 { L"CIM_DataFile", C(col_datafile), 0, 0, NULL, fill_datafile },
3981 { L"CIM_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
3982 { L"CIM_Processor", C(col_processor), 0, 0, NULL, fill_processor },
3983 { L"StdRegProv", C(col_stdregprov), D(data_stdregprov) },
3984 { L"Win32_BIOS", C(col_bios), 0, 0, NULL, fill_bios },
3985 { L"Win32_BaseBoard", C(col_baseboard), 0, 0, NULL, fill_baseboard },
3986 { L"Win32_CDROMDrive", C(col_cdromdrive), 0, 0, NULL, fill_cdromdrive },
3987 { L"Win32_ComputerSystem", C(col_compsys), 0, 0, NULL, fill_compsys },
3988 { L"Win32_ComputerSystemProduct", C(col_compsysproduct), 0, 0, NULL, fill_compsysproduct },
3989 { L"Win32_DesktopMonitor", C(col_desktopmonitor), 0, 0, NULL, fill_desktopmonitor },
3990 { L"Win32_Directory", C(col_directory), 0, 0, NULL, fill_directory },
3991 { L"Win32_DiskDrive", C(col_diskdrive), 0, 0, NULL, fill_diskdrive },
3992 { L"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition), 0, 0, NULL, fill_diskdrivetodiskpartition },
3993 { L"Win32_DiskPartition", C(col_diskpartition), 0, 0, NULL, fill_diskpartition },
3994 { L"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig), 0, 0, NULL, fill_displaycontrollerconfig },
3995 { L"Win32_IP4RouteTable", C(col_ip4routetable), 0, 0, NULL, fill_ip4routetable },
3996 { L"Win32_LogicalDisk", C(col_logicaldisk), 0, 0, NULL, fill_logicaldisk },
3997 { L"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition), 0, 0, NULL, fill_logicaldisktopartition },
3998 { L"Win32_NetworkAdapter", C(col_networkadapter), 0, 0, NULL, fill_networkadapter },
3999 { L"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig), 0, 0, NULL, fill_networkadapterconfig },
4000 { L"Win32_OperatingSystem", C(col_operatingsystem), 0, 0, NULL, fill_operatingsystem },
4001 { L"Win32_PhysicalMedia", C(col_physicalmedia), D(data_physicalmedia) },
4002 { L"Win32_PhysicalMemory", C(col_physicalmemory), 0, 0, NULL, fill_physicalmemory },
4003 { L"Win32_PnPEntity", C(col_pnpentity), 0, 0, NULL, fill_pnpentity },
4004 { L"Win32_Printer", C(col_printer), 0, 0, NULL, fill_printer },
4005 { L"Win32_Process", C(col_process), 0, 0, NULL, fill_process },
4006 { L"Win32_Processor", C(col_processor), 0, 0, NULL, fill_processor },
4007 { L"Win32_QuickFixEngineering", C(col_quickfixengineering), D(data_quickfixengineering) },
4008 { L"Win32_SID", C(col_sid), 0, 0, NULL, fill_sid },
4009 { L"Win32_Service", C(col_service), 0, 0, NULL, fill_service },
4010 { L"Win32_SoundDevice", C(col_sounddevice), 0, 0, NULL, fill_sounddevice },
4011 { L"Win32_SystemEnclosure", C(col_systemenclosure), 0, 0, NULL, fill_systemenclosure },
4012 { L"Win32_VideoController", C(col_videocontroller), 0, 0, NULL, fill_videocontroller },
4013 { L"Win32_WinSAT", C(col_winsat), D(data_winsat) },
4015 #undef C
4016 #undef D
4018 void init_table_list( void )
4020 static struct list tables = LIST_INIT( tables );
4021 UINT i;
4023 for (i = 0; i < ARRAY_SIZE(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry );
4024 table_list = &tables;