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