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
"SystemType", CIM_STRING
},
109 { L
"TotalPhysicalMemory", CIM_UINT64
},
110 { L
"UserName", CIM_STRING
|COL_FLAG_DYNAMIC
},
112 static const struct column col_compsysproduct
[] =
114 { L
"IdentifyingNumber", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
115 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
116 { L
"SKUNumber", CIM_STRING
},
117 { L
"UUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
118 { L
"Vendor", CIM_STRING
|COL_FLAG_DYNAMIC
},
119 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
121 static const struct column col_datafile
[] =
123 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
124 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
126 static const struct column col_desktopmonitor
[] =
128 { L
"Name", CIM_STRING
},
129 { L
"PixelsPerXLogicalInch", CIM_UINT32
},
131 static const struct column col_directory
[] =
133 { L
"AccessMask", CIM_UINT32
},
134 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
136 static const struct column col_diskdrive
[] =
138 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
139 { L
"Index", CIM_UINT32
},
140 { L
"InterfaceType", CIM_STRING
},
141 { L
"Manufacturer", CIM_STRING
},
142 { L
"MediaType", CIM_STRING
},
143 { L
"Model", CIM_STRING
},
144 { L
"PNPDeviceID", CIM_STRING
},
145 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
146 { L
"Size", CIM_UINT64
},
148 static const struct column col_diskdrivetodiskpartition
[] =
150 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
151 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
153 static const struct column col_diskpartition
[] =
155 { L
"Bootable", CIM_BOOLEAN
},
156 { L
"BootPartition", CIM_BOOLEAN
},
157 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
158 { L
"DiskIndex", CIM_UINT32
},
159 { L
"Index", CIM_UINT32
},
160 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
161 { L
"Size", CIM_UINT64
},
162 { L
"StartingOffset", CIM_UINT64
},
163 { L
"Type", CIM_STRING
|COL_FLAG_DYNAMIC
},
165 static const struct column col_displaycontrollerconfig
[] =
167 { L
"BitsPerPixel", CIM_UINT32
},
168 { L
"Caption", CIM_STRING
},
169 { L
"HorizontalResolution", CIM_UINT32
},
170 { L
"Name", CIM_STRING
|COL_FLAG_KEY
},
171 { L
"VerticalResolution", CIM_UINT32
},
173 static const struct column col_ip4routetable
[] =
175 { L
"Destination", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
176 { L
"InterfaceIndex", CIM_SINT32
|COL_FLAG_KEY
},
177 { L
"NextHop", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
179 static const struct column col_logicaldisk
[] =
181 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
182 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
183 { L
"DriveType", CIM_UINT32
},
184 { L
"FileSystem", CIM_STRING
|COL_FLAG_DYNAMIC
},
185 { L
"FreeSpace", CIM_UINT64
},
186 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
187 { L
"Size", CIM_UINT64
},
188 { L
"VolumeName", CIM_STRING
|COL_FLAG_DYNAMIC
},
189 { L
"VolumeSerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
191 static const struct column col_logicaldisktopartition
[] =
193 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
194 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
196 static const struct column col_networkadapter
[] =
198 { L
"AdapterType", CIM_STRING
},
199 { L
"AdapterTypeID", CIM_UINT16
},
200 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
201 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
202 { L
"GUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
203 { L
"Index", CIM_UINT32
},
204 { L
"InterfaceIndex", CIM_UINT32
},
205 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
206 { L
"Manufacturer", CIM_STRING
},
207 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
208 { L
"NetConnectionStatus", CIM_UINT16
},
209 { L
"PhysicalAdapter", CIM_BOOLEAN
},
210 { L
"PNPDeviceID", CIM_STRING
},
211 { L
"ServiceName", CIM_STRING
|COL_FLAG_DYNAMIC
},
212 { L
"Speed", CIM_UINT64
},
214 static const struct column col_networkadapterconfig
[] =
216 { L
"DefaultIPGateway", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
217 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
218 { L
"DHCPEnabled", CIM_BOOLEAN
},
219 { L
"DNSDomain", CIM_STRING
},
220 { L
"DNSHostName", CIM_STRING
|COL_FLAG_DYNAMIC
},
221 { L
"DNSServerSearchOrder", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
222 { L
"Index", CIM_UINT32
|COL_FLAG_KEY
},
223 { L
"IPAddress", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
224 { L
"IPConnectionMetric", CIM_UINT32
},
225 { L
"IPEnabled", CIM_BOOLEAN
},
226 { L
"IPSubnet", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
227 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
228 { L
"SettingID", CIM_STRING
|COL_FLAG_DYNAMIC
},
230 static const struct column col_operatingsystem
[] =
232 { L
"BootDevice", CIM_STRING
},
233 { L
"BuildNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
234 { L
"BuildType", CIM_STRING
},
235 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
236 { L
"CodeSet", CIM_STRING
|COL_FLAG_DYNAMIC
},
237 { L
"CountryCode", CIM_STRING
|COL_FLAG_DYNAMIC
},
238 { L
"CSDVersion", CIM_STRING
|COL_FLAG_DYNAMIC
},
239 { L
"CSName", CIM_STRING
|COL_FLAG_DYNAMIC
},
240 { L
"CurrentTimeZone", CIM_SINT16
},
241 { L
"FreePhysicalMemory", CIM_UINT64
},
242 { L
"InstallDate", CIM_DATETIME
},
243 { L
"LastBootUpTime", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
244 { L
"LocalDateTime", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
245 { L
"Locale", CIM_STRING
|COL_FLAG_DYNAMIC
},
246 { L
"Manufacturer", CIM_STRING
},
247 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
248 { L
"OperatingSystemSKU", CIM_UINT32
},
249 { L
"Organization", CIM_STRING
|COL_FLAG_DYNAMIC
},
250 { L
"OSArchitecture", CIM_STRING
},
251 { L
"OSLanguage", CIM_UINT32
},
252 { L
"OSProductSuite", CIM_UINT32
},
253 { L
"OSType", CIM_UINT16
},
254 { L
"Primary", CIM_BOOLEAN
},
255 { L
"ProductType", CIM_UINT32
},
256 { L
"RegisteredUser", CIM_STRING
|COL_FLAG_DYNAMIC
},
257 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
258 { L
"ServicePackMajorVersion", CIM_UINT16
},
259 { L
"ServicePackMinorVersion", CIM_UINT16
},
260 { L
"Status", CIM_STRING
},
261 { L
"SuiteMask", CIM_UINT32
},
262 { L
"SystemDirectory", CIM_STRING
|COL_FLAG_DYNAMIC
},
263 { L
"SystemDrive", CIM_STRING
|COL_FLAG_DYNAMIC
},
264 { L
"TotalVirtualMemorySize", CIM_UINT64
},
265 { L
"TotalVisibleMemorySize", CIM_UINT64
},
266 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
267 { L
"WindowsDirectory", CIM_STRING
|COL_FLAG_DYNAMIC
},
269 static const struct column col_pagefileusage
[] =
271 { L
"Name", CIM_STRING
},
273 static const struct column col_param
[] =
275 { L
"Class", CIM_STRING
},
276 { L
"Method", CIM_STRING
},
277 { L
"Direction", CIM_SINT32
},
278 { L
"Parameter", CIM_STRING
},
279 { L
"Type", CIM_UINT32
},
280 { L
"DefaultValue", CIM_UINT32
},
282 static const struct column col_physicalmedia
[] =
284 { L
"SerialNumber", CIM_STRING
},
285 { L
"Tag", CIM_STRING
},
287 static const struct column col_physicalmemory
[] =
289 { L
"BankLabel", CIM_STRING
},
290 { L
"Capacity", CIM_UINT64
},
291 { L
"Caption", CIM_STRING
},
292 { L
"ConfiguredClockSpeed", CIM_UINT32
},
293 { L
"DeviceLocator", CIM_STRING
},
294 { L
"FormFactor", CIM_UINT16
},
295 { L
"MemoryType", CIM_UINT16
},
296 { L
"PartNumber", CIM_STRING
},
297 { L
"SerialNumber", CIM_STRING
},
299 static const struct column col_pnpentity
[] =
301 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
},
302 { L
"Manufacturer", CIM_STRING
},
303 { L
"Name", CIM_STRING
},
305 static const struct column col_printer
[] =
307 { L
"Attributes", CIM_UINT32
},
308 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
309 { L
"DriverName", CIM_STRING
|COL_FLAG_DYNAMIC
},
310 { L
"HorizontalResolution", CIM_UINT32
},
311 { L
"Local", CIM_BOOLEAN
},
312 { L
"Location", CIM_STRING
|COL_FLAG_DYNAMIC
},
313 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
314 { L
"Network", CIM_BOOLEAN
},
315 { L
"PortName", CIM_STRING
|COL_FLAG_DYNAMIC
},
317 static const struct column col_process
[] =
319 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
320 { L
"CommandLine", CIM_STRING
|COL_FLAG_DYNAMIC
},
321 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
322 { L
"Handle", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
323 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
324 { L
"ParentProcessID", CIM_UINT32
},
325 { L
"ProcessID", CIM_UINT32
},
326 { L
"ThreadCount", CIM_UINT32
},
327 { L
"WorkingSetSize", CIM_UINT64
},
329 { L
"Create", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
330 { L
"GetOwner", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
332 static const struct column col_processor
[] =
334 { L
"AddressWidth", CIM_UINT16
},
335 { L
"Architecture", CIM_UINT16
},
336 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
337 { L
"CpuStatus", CIM_UINT16
},
338 { L
"CurrentClockSpeed", CIM_UINT32
},
339 { L
"DataWidth", CIM_UINT16
},
340 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
341 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
342 { L
"Family", CIM_UINT16
},
343 { L
"Level", CIM_UINT16
},
344 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
345 { L
"MaxClockSpeed", CIM_UINT32
},
346 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
347 { L
"NumberOfCores", CIM_UINT32
},
348 { L
"NumberOfLogicalProcessors", CIM_UINT32
},
349 { L
"ProcessorId", CIM_STRING
|COL_FLAG_DYNAMIC
},
350 { L
"ProcessorType", CIM_UINT16
},
351 { L
"Revision", CIM_UINT16
},
352 { L
"UniqueId", CIM_STRING
},
353 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
355 static const struct column col_qualifier
[] =
357 { L
"Class", CIM_STRING
},
358 { L
"Member", CIM_STRING
},
359 { L
"Type", CIM_UINT32
},
360 { L
"Flavor", CIM_SINT32
},
361 { L
"Name", CIM_STRING
},
362 { L
"IntegerValue", CIM_SINT32
},
363 { L
"StringValue", CIM_STRING
},
364 { L
"BoolValue", CIM_BOOLEAN
},
366 static const struct column col_quickfixengineering
[] =
368 { L
"Caption", CIM_STRING
},
369 { L
"HotFixID", CIM_STRING
|COL_FLAG_KEY
},
371 static const struct column col_rawsmbiostables
[] =
373 { L
"SMBiosData", CIM_UINT8
|CIM_FLAG_ARRAY
},
375 static const struct column col_service
[] =
377 { L
"AcceptPause", CIM_BOOLEAN
},
378 { L
"AcceptStop", CIM_BOOLEAN
},
379 { L
"DisplayName", CIM_STRING
|COL_FLAG_DYNAMIC
},
380 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
381 { L
"ProcessID", CIM_UINT32
},
382 { L
"ServiceType", CIM_STRING
},
383 { L
"StartMode", CIM_STRING
},
384 { L
"State", CIM_STRING
},
385 { L
"SystemName", CIM_STRING
|COL_FLAG_DYNAMIC
},
387 { L
"PauseService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
388 { L
"ResumeService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
389 { L
"StartService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
390 { L
"StopService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
392 static const struct column col_sid
[] =
394 { L
"AccountName", CIM_STRING
|COL_FLAG_DYNAMIC
},
395 { L
"BinaryRepresentation", CIM_UINT8
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
396 { L
"ReferencedDomainName", CIM_STRING
|COL_FLAG_DYNAMIC
},
397 { L
"SID", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
398 { L
"SidLength", CIM_UINT32
},
400 static const struct column col_softwarelicensingproduct
[] =
402 { L
"LicenseIsAddon", CIM_BOOLEAN
},
403 { L
"LicenseStatus", CIM_UINT32
},
405 static const struct column col_sounddevice
[] =
407 { L
"DeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
408 { L
"Manufacturer", CIM_STRING
},
409 { L
"Name", CIM_STRING
},
410 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
411 { L
"ProductName", CIM_STRING
},
412 { L
"Status", CIM_STRING
},
413 { L
"StatusInfo", CIM_UINT16
},
415 static const struct column col_stdregprov
[] =
417 { L
"CreateKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
418 { L
"EnumKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
419 { L
"EnumValues", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
420 { L
"GetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
421 { L
"SetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
422 { L
"SetDWORDValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
423 { L
"DeleteKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
425 static const struct column col_systemenclosure
[] =
427 { L
"Caption", CIM_STRING
},
428 { L
"ChassisTypes", CIM_UINT16
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
429 { L
"Description", CIM_STRING
},
430 { L
"LockPresent", CIM_BOOLEAN
},
431 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
432 { L
"Name", CIM_STRING
},
433 { L
"Tag", CIM_STRING
},
435 static const struct column col_systemsecurity
[] =
437 { L
"GetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
438 { L
"SetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
440 static const struct column col_sysrestore
[] =
442 { L
"CreationTime", CIM_STRING
},
443 { L
"Description", CIM_STRING
},
444 { L
"EventType", CIM_UINT32
},
445 { L
"RestorePointType", CIM_UINT32
},
446 { L
"SequenceNumber", CIM_UINT32
},
448 { L
"CreateRestorePoint", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
449 { L
"Disable", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
450 { L
"Enable", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
451 { L
"GetLastRestoreStatus", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
452 { L
"Restore", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
454 static const struct column col_videocontroller
[] =
456 { L
"AdapterCompatibility", CIM_STRING
},
457 { L
"AdapterDACType", CIM_STRING
},
458 { L
"AdapterRAM", CIM_UINT32
},
459 { L
"Availability", CIM_UINT16
},
460 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
461 { L
"ConfigManagerErrorCode", CIM_UINT32
},
462 { L
"CurrentBitsPerPixel", CIM_UINT32
},
463 { L
"CurrentHorizontalResolution", CIM_UINT32
},
464 { L
"CurrentRefreshRate", CIM_UINT32
},
465 { L
"CurrentScanMode", CIM_UINT16
},
466 { L
"CurrentVerticalResolution", CIM_UINT32
},
467 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
468 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
469 { L
"DriverDate", CIM_DATETIME
},
470 { L
"DriverVersion", CIM_STRING
},
471 { L
"InstalledDisplayDrivers", CIM_STRING
},
472 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
473 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
474 { L
"Status", CIM_STRING
},
475 { L
"VideoArchitecture", CIM_UINT16
},
476 { L
"VideoMemoryType", CIM_UINT16
},
477 { L
"VideoModeDescription", CIM_STRING
|COL_FLAG_DYNAMIC
},
478 { L
"VideoProcessor", CIM_STRING
|COL_FLAG_DYNAMIC
},
480 static const struct column col_winsat
[] =
482 { L
"CPUScore", CIM_REAL32
},
483 { L
"D3DScore", CIM_REAL32
},
484 { L
"DiskScore", CIM_REAL32
},
485 { L
"GraphicsScore", CIM_REAL32
},
486 { L
"MemoryScore", CIM_REAL32
},
487 { L
"TimeTaken", CIM_STRING
|COL_FLAG_KEY
},
488 { L
"WinSATAssessmentState", CIM_UINT32
},
489 { L
"WinSPRLevel", CIM_REAL32
},
492 #include "pshpack1.h"
493 struct record_associator
495 const WCHAR
*assocclass
;
497 const WCHAR
*associator
;
499 struct record_baseboard
501 const WCHAR
*manufacturer
;
504 const WCHAR
*product
;
505 const WCHAR
*serialnumber
;
507 const WCHAR
*version
;
511 const WCHAR
*currentlanguage
;
512 const WCHAR
*description
;
513 UINT8 ecmajorversion
;
514 UINT8 ecminorversion
;
515 const WCHAR
*identificationcode
;
516 const WCHAR
*manufacturer
;
518 const WCHAR
*releasedate
;
519 const WCHAR
*serialnumber
;
520 const WCHAR
*smbiosbiosversion
;
521 UINT16 smbiosmajorversion
;
522 UINT16 smbiosminorversion
;
523 UINT8 systembiosmajorversion
;
524 UINT8 systembiosminorversion
;
525 const WCHAR
*version
;
527 struct record_cdromdrive
529 const WCHAR
*device_id
;
531 const WCHAR
*mediatype
;
533 const WCHAR
*pnpdevice_id
;
535 struct record_computersystem
537 const WCHAR
*description
;
540 const WCHAR
*manufacturer
;
543 UINT32 num_logical_processors
;
544 UINT32 num_processors
;
545 const WCHAR
*systemtype
;
546 UINT64 total_physical_memory
;
547 const WCHAR
*username
;
549 struct record_computersystemproduct
551 const WCHAR
*identifyingnumber
;
553 const WCHAR
*skunumber
;
556 const WCHAR
*version
;
558 struct record_datafile
561 const WCHAR
*version
;
563 struct record_desktopmonitor
566 UINT32 pixelsperxlogicalinch
;
568 struct record_directory
573 struct record_diskdrive
575 const WCHAR
*device_id
;
577 const WCHAR
*interfacetype
;
578 const WCHAR
*manufacturer
;
579 const WCHAR
*mediatype
;
581 const WCHAR
*pnpdevice_id
;
582 const WCHAR
*serialnumber
;
585 struct record_diskdrivetodiskpartition
587 const WCHAR
*antecedent
;
588 const WCHAR
*dependent
;
590 struct record_diskpartition
594 const WCHAR
*device_id
;
597 const WCHAR
*pnpdevice_id
;
599 UINT64 startingoffset
;
602 struct record_displaycontrollerconfig
605 const WCHAR
*caption
;
606 UINT32 horizontalresolution
;
608 UINT32 verticalresolution
;
610 struct record_ip4routetable
612 const WCHAR
*destination
;
613 INT32 interfaceindex
;
614 const WCHAR
*nexthop
;
616 struct record_logicaldisk
618 const WCHAR
*caption
;
619 const WCHAR
*device_id
;
621 const WCHAR
*filesystem
;
625 const WCHAR
*volumename
;
626 const WCHAR
*volumeserialnumber
;
628 struct record_logicaldisktopartition
630 const WCHAR
*antecedent
;
631 const WCHAR
*dependent
;
633 struct record_networkadapter
635 const WCHAR
*adaptertype
;
636 UINT16 adaptertypeid
;
637 const WCHAR
*description
;
638 const WCHAR
*device_id
;
641 UINT32 interface_index
;
642 const WCHAR
*mac_address
;
643 const WCHAR
*manufacturer
;
645 UINT16 netconnection_status
;
647 const WCHAR
*pnpdevice_id
;
648 const WCHAR
*servicename
;
651 struct record_networkadapterconfig
653 const struct array
*defaultipgateway
;
654 const WCHAR
*description
;
656 const WCHAR
*dnsdomain
;
657 const WCHAR
*dnshostname
;
658 const struct array
*dnsserversearchorder
;
660 const struct array
*ipaddress
;
661 UINT32 ipconnectionmetric
;
663 const struct array
*ipsubnet
;
664 const WCHAR
*mac_address
;
665 const WCHAR
*settingid
;
667 struct record_operatingsystem
669 const WCHAR
*bootdevice
;
670 const WCHAR
*buildnumber
;
671 const WCHAR
*buildtype
;
672 const WCHAR
*caption
;
673 const WCHAR
*codeset
;
674 const WCHAR
*countrycode
;
675 const WCHAR
*csdversion
;
677 INT16 currenttimezone
;
678 UINT64 freephysicalmemory
;
679 const WCHAR
*installdate
;
680 const WCHAR
*lastbootuptime
;
681 const WCHAR
*localdatetime
;
683 const WCHAR
*manufacturer
;
685 UINT32 operatingsystemsku
;
686 const WCHAR
*organization
;
687 const WCHAR
*osarchitecture
;
689 UINT32 osproductsuite
;
693 const WCHAR
*registereduser
;
694 const WCHAR
*serialnumber
;
695 UINT16 servicepackmajor
;
696 UINT16 servicepackminor
;
699 const WCHAR
*systemdirectory
;
700 const WCHAR
*systemdrive
;
701 UINT64 totalvirtualmemorysize
;
702 UINT64 totalvisiblememorysize
;
703 const WCHAR
*version
;
704 const WCHAR
*windowsdirectory
;
706 struct record_pagefileusage
715 const WCHAR
*parameter
;
719 struct record_physicalmedia
721 const WCHAR
*serialnumber
;
724 struct record_physicalmemory
726 const WCHAR
*banklabel
;
728 const WCHAR
*caption
;
729 UINT32 configuredclockspeed
;
730 const WCHAR
*devicelocator
;
733 const WCHAR
*partnumber
;
736 struct record_pnpentity
738 const WCHAR
*device_id
;
739 const WCHAR
*manufacturer
;
742 struct record_printer
745 const WCHAR
*device_id
;
746 const WCHAR
*drivername
;
747 UINT32 horizontalresolution
;
749 const WCHAR
*location
;
752 const WCHAR
*portname
;
754 struct record_process
756 const WCHAR
*caption
;
757 const WCHAR
*commandline
;
758 const WCHAR
*description
;
764 UINT64 workingsetsize
;
766 class_method
*create
;
767 class_method
*get_owner
;
769 struct record_processor
773 const WCHAR
*caption
;
775 UINT32 currentclockspeed
;
777 const WCHAR
*description
;
778 const WCHAR
*device_id
;
781 const WCHAR
*manufacturer
;
782 UINT32 maxclockspeed
;
785 UINT32 num_logical_processors
;
786 const WCHAR
*processor_id
;
787 UINT16 processortype
;
789 const WCHAR
*unique_id
;
790 const WCHAR
*version
;
792 struct record_qualifier
800 const WCHAR
*strvalue
;
803 struct record_quickfixengineering
805 const WCHAR
*caption
;
806 const WCHAR
*hotfixid
;
808 struct record_rawsmbiostables
810 const struct array
*smbiosdata
;
812 struct record_service
816 const WCHAR
*displayname
;
819 const WCHAR
*servicetype
;
820 const WCHAR
*startmode
;
822 const WCHAR
*systemname
;
824 class_method
*pause_service
;
825 class_method
*resume_service
;
826 class_method
*start_service
;
827 class_method
*stop_service
;
831 const WCHAR
*accountname
;
832 const struct array
*binaryrepresentation
;
833 const WCHAR
*referenceddomainname
;
837 struct record_softwarelicensingproduct
839 int license_is_addon
;
840 UINT32 license_status
;
842 struct record_sounddevice
844 const WCHAR
*deviceid
;
845 const WCHAR
*manufacturer
;
847 const WCHAR
*pnpdeviceid
;
848 const WCHAR
*productname
;
852 struct record_stdregprov
854 class_method
*createkey
;
855 class_method
*enumkey
;
856 class_method
*enumvalues
;
857 class_method
*getstringvalue
;
858 class_method
*setstringvalue
;
859 class_method
*setdwordvalue
;
860 class_method
*deletekey
;
862 struct record_sysrestore
864 const WCHAR
*creation_time
;
865 const WCHAR
*description
;
867 UINT32 restore_point_type
;
868 UINT32 sequence_number
;
869 class_method
*create_restore_point
;
870 class_method
*disable_restore
;
871 class_method
*enable_restore
;
872 class_method
*get_last_restore_status
;
873 class_method
*restore
;
875 struct record_systemsecurity
880 struct record_systemenclosure
882 const WCHAR
*caption
;
883 const struct array
*chassistypes
;
884 const WCHAR
*description
;
886 const WCHAR
*manufacturer
;
890 struct record_videocontroller
892 const WCHAR
*adapter_compatibility
;
893 const WCHAR
*adapter_dactype
;
896 const WCHAR
*caption
;
897 UINT32 config_errorcode
;
898 UINT32 current_bitsperpixel
;
899 UINT32 current_horizontalres
;
900 UINT32 current_refreshrate
;
901 UINT16 current_scanmode
;
902 UINT32 current_verticalres
;
903 const WCHAR
*description
;
904 const WCHAR
*device_id
;
905 const WCHAR
*driverdate
;
906 const WCHAR
*driverversion
;
907 const WCHAR
*installeddriver
;
909 const WCHAR
*pnpdevice_id
;
911 UINT16 videoarchitecture
;
912 UINT16 videomemorytype
;
913 const WCHAR
*videomodedescription
;
914 const WCHAR
*videoprocessor
;
923 const WCHAR
*timetaken
;
924 UINT32 winsatassessmentstate
;
929 static const struct record_associator data_associator
[] =
931 { L
"Win32_DiskDriveToDiskPartition", L
"Win32_DiskPartition", L
"Win32_DiskDrive" },
932 { L
"Win32_LogicalDiskToPartition", L
"Win32_LogicalDisk", L
"Win32_DiskPartition" },
934 static const struct record_pagefileusage data_pagefileusage
[] =
936 { L
"c:\\pagefile.sys", },
938 static const struct record_param data_param
[] =
940 { L
"__SystemSecurity", L
"GetSD", -1, L
"ReturnValue", CIM_UINT32
},
941 { L
"__SystemSecurity", L
"GetSD", -1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
942 { L
"__SystemSecurity", L
"SetSD", 1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
943 { L
"__SystemSecurity", L
"SetSD", -1, L
"ReturnValue", CIM_UINT32
},
944 { L
"StdRegProv", L
"CreateKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
945 { L
"StdRegProv", L
"CreateKey", 1, L
"sSubKeyName", CIM_STRING
},
946 { L
"StdRegProv", L
"CreateKey", -1, L
"ReturnValue", CIM_UINT32
},
947 { L
"StdRegProv", L
"DeleteKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
948 { L
"StdRegProv", L
"DeleteKey", 1, L
"sSubKeyName", CIM_STRING
},
949 { L
"StdRegProv", L
"DeleteKey", -1, L
"ReturnValue", CIM_UINT32
},
950 { L
"StdRegProv", L
"EnumKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
951 { L
"StdRegProv", L
"EnumKey", 1, L
"sSubKeyName", CIM_STRING
},
952 { L
"StdRegProv", L
"EnumKey", -1, L
"ReturnValue", CIM_UINT32
},
953 { L
"StdRegProv", L
"EnumKey", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
954 { L
"StdRegProv", L
"EnumValues", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
955 { L
"StdRegProv", L
"EnumValues", 1, L
"sSubKeyName", CIM_STRING
},
956 { L
"StdRegProv", L
"EnumValues", -1, L
"ReturnValue", CIM_UINT32
},
957 { L
"StdRegProv", L
"EnumValues", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
958 { L
"StdRegProv", L
"EnumValues", -1, L
"Types", CIM_SINT32
|CIM_FLAG_ARRAY
},
959 { L
"StdRegProv", L
"GetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
960 { L
"StdRegProv", L
"GetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
961 { L
"StdRegProv", L
"GetStringValue", 1, L
"sValueName", CIM_STRING
},
962 { L
"StdRegProv", L
"GetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
963 { L
"StdRegProv", L
"GetStringValue", -1, L
"sValue", CIM_STRING
},
964 { L
"StdRegProv", L
"SetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
965 { L
"StdRegProv", L
"SetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
966 { L
"StdRegProv", L
"SetStringValue", 1, L
"sValueName", CIM_STRING
},
967 { L
"StdRegProv", L
"SetStringValue", 1, L
"sValue", CIM_STRING
},
968 { L
"StdRegProv", L
"SetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
969 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
970 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"sSubKeyName", CIM_STRING
},
971 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"sValueName", CIM_STRING
},
972 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"uValue", CIM_UINT32
},
973 { L
"StdRegProv", L
"SetDWORDValue", -1, L
"ReturnValue", CIM_UINT32
},
974 { L
"SystemRestore", L
"Disable", 1, L
"Drive", CIM_STRING
},
975 { L
"SystemRestore", L
"Disable", -1, L
"ReturnValue", CIM_UINT32
},
976 { L
"SystemRestore", L
"Enable", 1, L
"Drive", CIM_STRING
},
977 { L
"SystemRestore", L
"Enable", -1, L
"ReturnValue", CIM_UINT32
},
978 { L
"Win32_Process", L
"Create", 1, L
"CommandLine", CIM_STRING
},
979 { L
"Win32_Process", L
"Create", 1, L
"CurrentDirectory", CIM_STRING
},
980 { L
"Win32_Process", L
"Create", -1, L
"ProcessId", CIM_UINT32
},
981 { L
"Win32_Process", L
"Create", -1, L
"ReturnValue", CIM_UINT32
},
982 { L
"Win32_Process", L
"GetOwner", -1, L
"ReturnValue", CIM_UINT32
},
983 { L
"Win32_Process", L
"GetOwner", -1, L
"User", CIM_STRING
},
984 { L
"Win32_Process", L
"GetOwner", -1, L
"Domain", CIM_STRING
},
985 { L
"Win32_Service", L
"PauseService", -1, L
"ReturnValue", CIM_UINT32
},
986 { L
"Win32_Service", L
"ResumeService", -1, L
"ReturnValue", CIM_UINT32
},
987 { L
"Win32_Service", L
"StartService", -1, L
"ReturnValue", CIM_UINT32
},
988 { L
"Win32_Service", L
"StopService", -1, L
"ReturnValue", CIM_UINT32
},
991 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
992 WBEM_FLAVOR_ORIGIN_PROPAGATED)
994 static const struct record_physicalmedia data_physicalmedia
[] =
996 { L
"WINEHDISK", L
"\\\\.\\PHYSICALDRIVE0" }
999 static const struct record_rawsmbiostables data_rawsmbiostables
[] =
1004 static const struct record_qualifier data_qualifier
[] =
1006 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"User", CIM_SINT32
, FLAVOR_ID
, L
"ID", 0 },
1007 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"Domain", CIM_SINT32
, FLAVOR_ID
, L
"ID", 1 }
1010 static const struct record_quickfixengineering data_quickfixengineering
[] =
1012 { L
"http://winehq.org", L
"KB1234567" },
1015 static const struct record_softwarelicensingproduct data_softwarelicensingproduct
[] =
1020 static const struct record_stdregprov data_stdregprov
[] =
1026 reg_get_stringvalue
,
1027 reg_set_stringvalue
,
1033 static const struct record_sysrestore data_sysrestore
[] =
1035 { NULL
, NULL
, 0, 0, 0, sysrestore_create
, sysrestore_disable
, sysrestore_enable
, sysrestore_get_last_status
,
1036 sysrestore_restore
}
1039 static UINT16 systemenclosure_chassistypes
[] =
1043 static const struct array systemenclosure_chassistypes_array
=
1045 sizeof(*systemenclosure_chassistypes
),
1046 ARRAY_SIZE(systemenclosure_chassistypes
),
1047 &systemenclosure_chassistypes
1049 static const struct record_systemsecurity data_systemsecurity
[] =
1051 { security_get_sd
, security_set_sd
}
1053 static const struct record_winsat data_winsat
[] =
1055 { 8.0f
, 8.0f
, 8.0f
, 8.0f
, 8.0f
, L
"MostRecentAssessment", 1 /* Valid */, 8.0f
},
1058 /* check if row matches condition and update status */
1059 static BOOL
match_row( const struct table
*table
, UINT row
, const struct expr
*cond
, enum fill_status
*status
)
1066 *status
= FILL_STATUS_UNFILTERED
;
1069 if (eval_cond( table
, row
, cond
, &val
, &type
) != S_OK
)
1071 *status
= FILL_STATUS_FAILED
;
1074 *status
= FILL_STATUS_FILTERED
;
1078 static BOOL
resize_table( struct table
*table
, UINT row_count
, UINT row_size
)
1080 if (!table
->num_rows_allocated
)
1082 if (!(table
->data
= malloc( row_count
* row_size
))) return FALSE
;
1083 table
->num_rows_allocated
= row_count
;
1086 if (row_count
> table
->num_rows_allocated
)
1089 UINT count
= max( row_count
, table
->num_rows_allocated
* 2 );
1090 if (!(data
= realloc( table
->data
, count
* row_size
))) return FALSE
;
1092 table
->num_rows_allocated
= count
;
1097 #include "pshpack1.h"
1098 struct smbios_prologue
1100 BYTE calling_method
;
1111 SMBIOS_TYPE_BASEBOARD
,
1112 SMBIOS_TYPE_CHASSIS
,
1115 struct smbios_header
1122 struct smbios_baseboard
1124 struct smbios_header hdr
;
1133 struct smbios_header hdr
;
1139 UINT64 characteristics
;
1140 BYTE characteristics_ext
[2];
1141 BYTE system_bios_major_release
;
1142 BYTE system_bios_minor_release
;
1143 BYTE ec_firmware_major_release
;
1144 BYTE ec_firmware_minor_release
;
1147 struct smbios_chassis
1149 struct smbios_header hdr
;
1157 struct smbios_system
1159 struct smbios_header hdr
;
1166 #include "poppack.h"
1168 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1170 static const struct smbios_header
*find_smbios_entry( enum smbios_type type
, const char *buf
, UINT len
)
1172 const char *ptr
, *start
;
1173 const struct smbios_prologue
*prologue
;
1174 const struct smbios_header
*hdr
;
1176 if (len
< sizeof(struct smbios_prologue
)) return NULL
;
1177 prologue
= (const struct smbios_prologue
*)buf
;
1178 if (prologue
->length
> len
- sizeof(*prologue
) || prologue
->length
< sizeof(*hdr
)) return NULL
;
1180 start
= (const char *)(prologue
+ 1);
1181 hdr
= (const struct smbios_header
*)start
;
1185 if ((const char *)hdr
- start
>= prologue
->length
- sizeof(*hdr
)) return NULL
;
1189 WARN( "invalid entry\n" );
1193 if (hdr
->type
== type
)
1195 if ((const char *)hdr
- start
+ hdr
->length
> prologue
->length
) return NULL
;
1198 else /* skip other entries and their strings */
1200 for (ptr
= (const char *)hdr
+ hdr
->length
; ptr
- buf
< len
&& *ptr
; ptr
++)
1202 for (; ptr
- buf
< len
; ptr
++) if (!*ptr
) break;
1204 if (ptr
== (const char *)hdr
+ hdr
->length
) ptr
++;
1205 hdr
= (const struct smbios_header
*)(ptr
+ 1);
1212 static WCHAR
*get_smbios_string( BYTE id
, const char *buf
, UINT offset
, UINT buflen
)
1214 const char *ptr
= buf
+ offset
;
1217 if (!id
|| offset
>= buflen
) return NULL
;
1218 for (ptr
= buf
+ offset
; ptr
- buf
< buflen
&& *ptr
; ptr
++)
1220 if (++i
== id
) return heap_strdupAW( ptr
);
1221 for (; ptr
- buf
< buflen
; ptr
++) if (!*ptr
) break;
1226 static WCHAR
*get_baseboard_string( BYTE id
, const char *buf
, UINT len
)
1228 const struct smbios_header
*hdr
;
1229 const struct smbios_baseboard
*baseboard
;
1232 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BASEBOARD
, buf
, len
))) return NULL
;
1234 baseboard
= (const struct smbios_baseboard
*)hdr
;
1235 offset
= (const char *)baseboard
- buf
+ baseboard
->hdr
.length
;
1236 return get_smbios_string( id
, buf
, offset
, len
);
1239 static WCHAR
*get_baseboard_manufacturer( const char *buf
, UINT len
)
1241 WCHAR
*ret
= get_baseboard_string( 1, buf
, len
);
1242 if (!ret
) return wcsdup( L
"Intel Corporation" );
1246 static WCHAR
*get_baseboard_product( const char *buf
, UINT len
)
1248 WCHAR
*ret
= get_baseboard_string( 2, buf
, len
);
1249 if (!ret
) return wcsdup( L
"Base Board" );
1253 static WCHAR
*get_baseboard_serialnumber( const char *buf
, UINT len
)
1255 WCHAR
*ret
= get_baseboard_string( 4, buf
, len
);
1256 if (!ret
) return wcsdup( L
"None" );
1260 static WCHAR
*get_baseboard_version( const char *buf
, UINT len
)
1262 WCHAR
*ret
= get_baseboard_string( 3, buf
, len
);
1263 if (!ret
) return wcsdup( L
"1.0" );
1267 static enum fill_status
fill_baseboard( struct table
*table
, const struct expr
*cond
)
1269 struct record_baseboard
*rec
;
1270 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1274 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1276 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1277 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1278 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1280 rec
= (struct record_baseboard
*)table
->data
;
1281 rec
->manufacturer
= get_baseboard_manufacturer( buf
, len
);
1282 rec
->model
= L
"Base Board";
1283 rec
->name
= L
"Base Board";
1284 rec
->product
= get_baseboard_product( buf
, len
);
1285 rec
->serialnumber
= get_baseboard_serialnumber( buf
, len
);
1286 rec
->tag
= L
"Base Board";
1287 rec
->version
= get_baseboard_version( buf
, len
);
1288 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1293 TRACE("created %u rows\n", row
);
1294 table
->num_rows
= row
;
1298 static UINT16
get_bios_smbiosmajorversion( const char *buf
, UINT len
)
1300 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1301 if (len
< sizeof(*prologue
)) return 2;
1302 return prologue
->major_version
;
1305 static UINT16
get_bios_smbiosminorversion( const char *buf
, UINT len
)
1307 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1308 if (len
< sizeof(*prologue
)) return 0;
1309 return prologue
->minor_version
;
1312 static WCHAR
*get_bios_string( BYTE id
, const char *buf
, UINT len
)
1314 const struct smbios_header
*hdr
;
1315 const struct smbios_bios
*bios
;
1318 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return NULL
;
1320 bios
= (const struct smbios_bios
*)hdr
;
1321 offset
= (const char *)bios
- buf
+ bios
->hdr
.length
;
1322 return get_smbios_string( id
, buf
, offset
, len
);
1325 static WCHAR
*get_bios_manufacturer( const char *buf
, UINT len
)
1327 WCHAR
*ret
= get_bios_string( 1, buf
, len
);
1328 if (!ret
) return wcsdup( L
"The Wine Project" );
1332 static WCHAR
*convert_bios_date( const WCHAR
*str
)
1334 static const WCHAR fmtW
[] = L
"%04u%02u%02u000000.000000+000";
1335 UINT year
, month
, day
, len
= lstrlenW( str
);
1336 const WCHAR
*p
= str
, *q
;
1339 while (len
&& iswspace( *p
)) { p
++; len
--; }
1340 while (len
&& iswspace( p
[len
- 1] )) { len
--; }
1343 while (len
&& is_digit( *q
)) { q
++; len
--; };
1344 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1345 month
= (p
[0] - '0') * 10 + p
[1] - '0';
1348 while (len
&& is_digit( *q
)) { q
++; len
--; };
1349 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1350 day
= (p
[0] - '0') * 10 + p
[1] - '0';
1353 while (len
&& is_digit( *q
)) { q
++; len
--; };
1354 if (q
- p
== 4) year
= (p
[0] - '0') * 1000 + (p
[1] - '0') * 100 + (p
[2] - '0') * 10 + p
[3] - '0';
1355 else if (q
- p
== 2) year
= 1900 + (p
[0] - '0') * 10 + p
[1] - '0';
1358 if (!(ret
= malloc( sizeof(fmtW
) ))) return NULL
;
1359 swprintf( ret
, ARRAY_SIZE(fmtW
), fmtW
, year
, month
, day
);
1363 static WCHAR
*get_bios_releasedate( const char *buf
, UINT len
)
1365 WCHAR
*ret
, *date
= get_bios_string( 3, buf
, len
);
1366 if (!date
|| !(ret
= convert_bios_date( date
))) ret
= wcsdup( L
"20120608000000.000000+000" );
1371 static WCHAR
*get_bios_smbiosbiosversion( const char *buf
, UINT len
)
1373 WCHAR
*ret
= get_bios_string( 2, buf
, len
);
1374 if (!ret
) return wcsdup( L
"Wine" );
1378 static BYTE
get_bios_ec_firmware_major_release( const char *buf
, UINT len
)
1380 const struct smbios_header
*hdr
;
1381 const struct smbios_bios
*bios
;
1383 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1385 bios
= (const struct smbios_bios
*)hdr
;
1386 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_major_release
;
1390 static BYTE
get_bios_ec_firmware_minor_release( const char *buf
, UINT len
)
1392 const struct smbios_header
*hdr
;
1393 const struct smbios_bios
*bios
;
1395 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1397 bios
= (const struct smbios_bios
*)hdr
;
1398 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_minor_release
;
1402 static BYTE
get_bios_system_bios_major_release( const char *buf
, UINT len
)
1404 const struct smbios_header
*hdr
;
1405 const struct smbios_bios
*bios
;
1407 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1409 bios
= (const struct smbios_bios
*)hdr
;
1410 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_major_release
;
1414 static BYTE
get_bios_system_bios_minor_release( const char *buf
, UINT len
)
1416 const struct smbios_header
*hdr
;
1417 const struct smbios_bios
*bios
;
1419 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1421 bios
= (const struct smbios_bios
*)hdr
;
1422 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_minor_release
;
1426 static enum fill_status
fill_bios( struct table
*table
, const struct expr
*cond
)
1428 struct record_bios
*rec
;
1429 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1433 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1435 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1436 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1437 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1439 rec
= (struct record_bios
*)table
->data
;
1440 rec
->currentlanguage
= NULL
;
1441 rec
->description
= L
"Default System BIOS";
1442 rec
->ecmajorversion
= get_bios_ec_firmware_major_release( buf
, len
);
1443 rec
->ecminorversion
= get_bios_ec_firmware_minor_release( buf
, len
);
1444 rec
->identificationcode
= NULL
;
1445 rec
->manufacturer
= get_bios_manufacturer( buf
, len
);
1446 rec
->name
= L
"Default System BIOS";
1447 rec
->releasedate
= get_bios_releasedate( buf
, len
);
1448 rec
->serialnumber
= L
"0";
1449 rec
->smbiosbiosversion
= get_bios_smbiosbiosversion( buf
, len
);
1450 rec
->smbiosmajorversion
= get_bios_smbiosmajorversion( buf
, len
);
1451 rec
->smbiosminorversion
= get_bios_smbiosminorversion( buf
, len
);
1452 rec
->systembiosmajorversion
= get_bios_system_bios_major_release( buf
, len
);
1453 rec
->systembiosminorversion
= get_bios_system_bios_minor_release( buf
, len
);
1454 rec
->version
= L
"WINE - 1";
1455 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1460 TRACE("created %u rows\n", row
);
1461 table
->num_rows
= row
;
1465 static enum fill_status
fill_cdromdrive( struct table
*table
, const struct expr
*cond
)
1467 WCHAR drive
[3], root
[] = L
"A:\\";
1468 struct record_cdromdrive
*rec
;
1469 UINT i
, row
= 0, offset
= 0;
1470 DWORD drives
= GetLogicalDrives();
1471 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1473 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1475 for (i
= 0; i
< 26; i
++)
1477 if (drives
& (1 << i
))
1480 if (GetDriveTypeW( root
) != DRIVE_CDROM
)
1483 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1485 rec
= (struct record_cdromdrive
*)(table
->data
+ offset
);
1486 rec
->device_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1487 swprintf( drive
, ARRAY_SIZE( drive
), L
"%c:", 'A' + i
);
1488 rec
->drive
= wcsdup( drive
);
1489 rec
->mediatype
= L
"CR-ROM";
1490 rec
->name
= L
"Wine CD_ROM ATA Device";
1491 rec
->pnpdevice_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1492 if (!match_row( table
, row
, cond
, &status
))
1494 free_row_values( table
, row
);
1497 offset
+= sizeof(*rec
);
1501 TRACE("created %u rows\n", row
);
1502 table
->num_rows
= row
;
1506 static UINT
get_processor_count(void)
1508 SYSTEM_BASIC_INFORMATION info
;
1510 if (NtQuerySystemInformation( SystemBasicInformation
, &info
, sizeof(info
), NULL
)) return 1;
1511 return info
.NumberOfProcessors
;
1514 static UINT
get_logical_processor_count( UINT
*num_physical
, UINT
*num_packages
)
1516 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*buf
, *entry
;
1517 UINT core_relation_count
= 0, package_relation_count
= 0;
1519 ULONG len
, offset
= 0;
1520 BOOL smt_enabled
= FALSE
;
1521 DWORD all
= RelationAll
;
1523 if (num_packages
) *num_packages
= 1;
1524 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), NULL
, 0, &len
);
1525 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) return get_processor_count();
1527 if (!(buf
= malloc( len
))) return get_processor_count();
1528 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), buf
, len
, NULL
);
1529 if (status
!= STATUS_SUCCESS
)
1532 return get_processor_count();
1535 while (offset
< len
)
1537 entry
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*)((char *)buf
+ offset
);
1539 if (entry
->Relationship
== RelationProcessorCore
)
1541 core_relation_count
++;
1542 if (entry
->u
.Processor
.Flags
& LTP_PC_SMT
) smt_enabled
= TRUE
;
1544 else if (entry
->Relationship
== RelationProcessorPackage
)
1546 package_relation_count
++;
1548 offset
+= entry
->Size
;
1552 if (num_physical
) *num_physical
= core_relation_count
;
1553 if (num_packages
) *num_packages
= package_relation_count
;
1554 return smt_enabled
? core_relation_count
* 2 : core_relation_count
;
1557 static UINT64
get_total_physical_memory(void)
1559 MEMORYSTATUSEX status
;
1561 status
.dwLength
= sizeof(status
);
1562 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1563 return status
.ullTotalPhys
;
1566 static UINT64
get_available_physical_memory(void)
1568 MEMORYSTATUSEX status
;
1570 status
.dwLength
= sizeof(status
);
1571 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1572 return status
.ullAvailPhys
;
1575 static WCHAR
*get_computername(void)
1578 DWORD size
= MAX_COMPUTERNAME_LENGTH
+ 1;
1580 if (!(ret
= malloc( size
* sizeof(WCHAR
) ))) return NULL
;
1581 GetComputerNameW( ret
, &size
);
1585 static const WCHAR
*get_systemtype(void)
1588 GetNativeSystemInfo( &info
);
1589 if (info
.u
.s
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"x64 based PC";
1590 return L
"x86 based PC";
1593 static WCHAR
*get_username(void)
1596 DWORD compsize
, usersize
;
1600 GetComputerNameW( NULL
, &compsize
);
1602 GetUserNameW( NULL
, &usersize
);
1603 size
= compsize
+ usersize
; /* two null terminators account for the \ */
1604 if (!(ret
= malloc( size
* sizeof(WCHAR
) ))) return NULL
;
1605 GetComputerNameW( ret
, &compsize
);
1606 ret
[compsize
] = '\\';
1607 GetUserNameW( ret
+ compsize
+ 1, &usersize
);
1611 static enum fill_status
fill_compsys( struct table
*table
, const struct expr
*cond
)
1613 struct record_computersystem
*rec
;
1614 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1617 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1619 rec
= (struct record_computersystem
*)table
->data
;
1620 rec
->description
= L
"AT/AT COMPATIBLE";
1621 rec
->domain
= L
"WORKGROUP";
1622 rec
->domainrole
= 0; /* standalone workstation */
1623 rec
->manufacturer
= L
"The Wine Project";
1624 rec
->model
= L
"Wine";
1625 rec
->name
= get_computername();
1626 rec
->num_logical_processors
= get_logical_processor_count( NULL
, &rec
->num_processors
);
1627 rec
->systemtype
= get_systemtype();
1628 rec
->total_physical_memory
= get_total_physical_memory();
1629 rec
->username
= get_username();
1630 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1633 TRACE("created %u rows\n", row
);
1634 table
->num_rows
= row
;
1638 static WCHAR
*get_compsysproduct_string( BYTE id
, const char *buf
, UINT len
)
1640 const struct smbios_header
*hdr
;
1641 const struct smbios_system
*system
;
1644 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
))) return NULL
;
1646 system
= (const struct smbios_system
*)hdr
;
1647 offset
= (const char *)system
- buf
+ system
->hdr
.length
;
1648 return get_smbios_string( id
, buf
, offset
, len
);
1651 static WCHAR
*get_compsysproduct_identifyingnumber( const char *buf
, UINT len
)
1653 WCHAR
*ret
= get_compsysproduct_string( 4, buf
, len
);
1654 if (!ret
) return wcsdup( L
"0" );
1658 static WCHAR
*get_compsysproduct_name( const char *buf
, UINT len
)
1660 WCHAR
*ret
= get_compsysproduct_string( 2, buf
, len
);
1661 if (!ret
) return wcsdup( L
"Wine" );
1665 static WCHAR
*get_compsysproduct_uuid( const char *buf
, UINT len
)
1667 static const BYTE none
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1668 const struct smbios_header
*hdr
;
1669 const struct smbios_system
*system
;
1673 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
)) || hdr
->length
< sizeof(*system
)) goto done
;
1674 system
= (const struct smbios_system
*)hdr
;
1675 if (!memcmp( system
->uuid
, none
, sizeof(none
) ) || !(ret
= malloc( 37 * sizeof(WCHAR
) ))) goto done
;
1678 swprintf( ret
, 37, L
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr
[0], ptr
[1],
1679 ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7], ptr
[8], ptr
[9], ptr
[10], ptr
[11], ptr
[12], ptr
[13],
1682 if (!ret
) ret
= wcsdup( L
"deaddead-dead-dead-dead-deaddeaddead" );
1686 static WCHAR
*get_compsysproduct_vendor( const char *buf
, UINT len
)
1688 WCHAR
*ret
= get_compsysproduct_string( 1, buf
, len
);
1689 if (!ret
) return wcsdup( L
"The Wine Project" );
1693 static WCHAR
*get_compsysproduct_version( const char *buf
, UINT len
)
1695 WCHAR
*ret
= get_compsysproduct_string( 3, buf
, len
);
1696 if (!ret
) return wcsdup( L
"1.0" );
1700 static enum fill_status
fill_compsysproduct( struct table
*table
, const struct expr
*cond
)
1702 struct record_computersystemproduct
*rec
;
1703 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1707 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1709 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1710 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1711 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1713 rec
= (struct record_computersystemproduct
*)table
->data
;
1714 rec
->identifyingnumber
= get_compsysproduct_identifyingnumber( buf
, len
);
1715 rec
->name
= get_compsysproduct_name( buf
, len
);
1716 rec
->skunumber
= NULL
;
1717 rec
->uuid
= get_compsysproduct_uuid( buf
, len
);
1718 rec
->vendor
= get_compsysproduct_vendor( buf
, len
);
1719 rec
->version
= get_compsysproduct_version( buf
, len
);
1720 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1725 TRACE("created %u rows\n", row
);
1726 table
->num_rows
= row
;
1738 static struct dirstack
*alloc_dirstack( UINT size
)
1740 struct dirstack
*dirstack
;
1742 if (!(dirstack
= malloc( sizeof(*dirstack
) ))) return NULL
;
1743 if (!(dirstack
->dirs
= malloc( sizeof(WCHAR
*) * size
)))
1748 if (!(dirstack
->len_dirs
= malloc( sizeof(UINT
) * size
)))
1750 free( dirstack
->dirs
);
1754 dirstack
->num_dirs
= 0;
1755 dirstack
->num_allocated
= size
;
1759 static void clear_dirstack( struct dirstack
*dirstack
)
1762 for (i
= 0; i
< dirstack
->num_dirs
; i
++) free( dirstack
->dirs
[i
] );
1763 dirstack
->num_dirs
= 0;
1766 static void free_dirstack( struct dirstack
*dirstack
)
1768 clear_dirstack( dirstack
);
1769 free( dirstack
->dirs
);
1770 free( dirstack
->len_dirs
);
1774 static BOOL
push_dir( struct dirstack
*dirstack
, WCHAR
*dir
, UINT len
)
1776 UINT size
, i
= dirstack
->num_dirs
;
1778 if (!dir
) return FALSE
;
1780 if (i
== dirstack
->num_allocated
)
1785 size
= dirstack
->num_allocated
* 2;
1786 if (!(tmp
= realloc( dirstack
->dirs
, size
* sizeof(WCHAR
*) ))) return FALSE
;
1787 dirstack
->dirs
= tmp
;
1788 if (!(len_tmp
= realloc( dirstack
->len_dirs
, size
* sizeof(UINT
) ))) return FALSE
;
1789 dirstack
->len_dirs
= len_tmp
;
1790 dirstack
->num_allocated
= size
;
1792 dirstack
->dirs
[i
] = dir
;
1793 dirstack
->len_dirs
[i
] = len
;
1794 dirstack
->num_dirs
++;
1798 static WCHAR
*pop_dir( struct dirstack
*dirstack
, UINT
*len
)
1800 if (!dirstack
->num_dirs
)
1805 dirstack
->num_dirs
--;
1806 *len
= dirstack
->len_dirs
[dirstack
->num_dirs
];
1807 return dirstack
->dirs
[dirstack
->num_dirs
];
1810 static const WCHAR
*peek_dir( struct dirstack
*dirstack
)
1812 if (!dirstack
->num_dirs
) return NULL
;
1813 return dirstack
->dirs
[dirstack
->num_dirs
- 1];
1816 static WCHAR
*build_glob( WCHAR drive
, const WCHAR
*path
, UINT len
)
1821 if (!(ret
= malloc( (len
+ 6) * sizeof(WCHAR
) ))) return NULL
;
1827 memcpy( ret
+ i
, path
, len
* sizeof(WCHAR
) );
1836 static WCHAR
*build_name( WCHAR drive
, const WCHAR
*path
)
1838 UINT i
= 0, len
= 0;
1842 for (p
= path
; *p
; p
++)
1844 if (*p
== '\\') len
+= 2;
1847 if (!(ret
= malloc( (len
+ 5) * sizeof(WCHAR
) ))) return NULL
;
1852 for (p
= path
; *p
; p
++)
1854 if (*p
!= '\\') ret
[i
++] = *p
;
1865 static WCHAR
*build_dirname( const WCHAR
*path
, UINT
*ret_len
)
1867 const WCHAR
*p
= path
, *start
;
1871 if (!iswalpha( p
[0] ) || p
[1] != ':' || p
[2] != '\\' || p
[3] != '\\' || !p
[4]) return NULL
;
1873 len
= lstrlenW( start
);
1874 p
= start
+ len
- 1;
1875 if (*p
== '\\') return NULL
;
1877 while (p
>= start
&& *p
!= '\\') { len
--; p
--; };
1878 while (p
>= start
&& *p
== '\\') { len
--; p
--; };
1880 if (!(ret
= malloc( (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1881 for (i
= 0, p
= start
; p
< start
+ len
; p
++)
1883 if (p
[0] == '\\' && p
[1] == '\\')
1895 static BOOL
seen_dir( struct dirstack
*dirstack
, const WCHAR
*path
)
1898 for (i
= 0; i
< dirstack
->num_dirs
; i
++) if (!wcscmp( dirstack
->dirs
[i
], path
)) return TRUE
;
1902 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1903 static UINT
seed_dirs( struct dirstack
*dirstack
, const struct expr
*cond
, WCHAR root
, UINT
*count
)
1905 const struct expr
*left
, *right
;
1907 if (!cond
|| cond
->type
!= EXPR_COMPLEX
) return *count
= 0;
1909 left
= cond
->u
.expr
.left
;
1910 right
= cond
->u
.expr
.right
;
1911 if (cond
->u
.expr
.op
== OP_EQ
)
1915 const WCHAR
*str
= NULL
;
1917 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&&
1918 !wcscmp( left
->u
.propval
->name
, L
"Name" ) &&
1919 towupper( right
->u
.sval
[0] ) == towupper( root
))
1921 str
= right
->u
.sval
;
1923 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&&
1924 !wcscmp( right
->u
.propval
->name
, L
"Name" ) &&
1925 towupper( left
->u
.sval
[0] ) == towupper( root
))
1929 if (str
&& (path
= build_dirname( str
, &len
)))
1931 if (seen_dir( dirstack
, path
))
1936 else if (push_dir( dirstack
, path
, len
)) return ++*count
;
1941 else if (cond
->u
.expr
.op
== OP_OR
)
1943 UINT left_count
= 0, right_count
= 0;
1945 if (!(seed_dirs( dirstack
, left
, root
, &left_count
))) return *count
= 0;
1946 if (!(seed_dirs( dirstack
, right
, root
, &right_count
))) return *count
= 0;
1947 return *count
+= left_count
+ right_count
;
1952 static WCHAR
*append_path( const WCHAR
*path
, const WCHAR
*segment
, UINT
*len
)
1954 UINT len_path
= 0, len_segment
= lstrlenW( segment
);
1958 if (path
) len_path
= lstrlenW( path
);
1959 if (!(ret
= malloc( (len_path
+ len_segment
+ 2) * sizeof(WCHAR
) ))) return NULL
;
1960 if (path
&& len_path
)
1962 memcpy( ret
, path
, len_path
* sizeof(WCHAR
) );
1963 ret
[len_path
] = '\\';
1964 *len
+= len_path
+ 1;
1966 memcpy( ret
+ *len
, segment
, len_segment
* sizeof(WCHAR
) );
1967 *len
+= len_segment
;
1972 static WCHAR
*get_file_version( const WCHAR
*filename
)
1974 VS_FIXEDFILEINFO
*info
;
1976 DWORD len
= 4 * 5 + ARRAY_SIZE( L
"%u.%u.%u.%u" );
1980 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
1981 if (!(size
= GetFileVersionInfoSizeW( filename
, NULL
)) || !(block
= malloc( size
)))
1986 if (!GetFileVersionInfoW( filename
, 0, size
, block
) ||
1987 !VerQueryValueW( block
, L
"\\", (void **)&info
, &size
))
1993 swprintf( ret
, len
, L
"%u.%u.%u.%u", info
->dwFileVersionMS
>> 16, info
->dwFileVersionMS
& 0xffff,
1994 info
->dwFileVersionLS
>> 16, info
->dwFileVersionLS
& 0xffff );
1999 static enum fill_status
fill_datafile( struct table
*table
, const struct expr
*cond
)
2001 struct record_datafile
*rec
;
2002 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
2003 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
2004 DWORD drives
= GetLogicalDrives();
2005 WIN32_FIND_DATAW data
;
2007 struct dirstack
*dirstack
;
2008 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2010 if (!resize_table( table
, 8, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2012 dirstack
= alloc_dirstack(2);
2014 for (i
= 0; i
< 26; i
++)
2016 if (!(drives
& (1 << i
))) continue;
2019 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
2021 num_expected_rows
= 0;
2022 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2028 path
= pop_dir( dirstack
, &len
);
2029 if (!(glob
= build_glob( root
[0], path
, len
)))
2031 status
= FILL_STATUS_FAILED
;
2034 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2038 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2040 status
= FILL_STATUS_FAILED
;
2041 FindClose( handle
);
2044 if (!wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." )) continue;
2046 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2048 status
= FILL_STATUS_FAILED
;
2049 FindClose( handle
);
2053 if (data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
2055 if (push_dir( dirstack
, new_path
, len
)) continue;
2057 FindClose( handle
);
2058 status
= FILL_STATUS_FAILED
;
2061 rec
= (struct record_datafile
*)(table
->data
+ offset
);
2062 rec
->name
= build_name( root
[0], new_path
);
2063 rec
->version
= get_file_version( rec
->name
);
2065 if (!match_row( table
, row
, cond
, &status
))
2067 free_row_values( table
, row
);
2070 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2073 FindClose( handle
);
2074 status
= FILL_STATUS_FILTERED
;
2077 offset
+= sizeof(*rec
);
2080 while (FindNextFileW( handle
, &data
));
2081 FindClose( handle
);
2083 if (!peek_dir( dirstack
)) break;
2088 free_dirstack( dirstack
);
2092 TRACE("created %u rows\n", row
);
2093 table
->num_rows
= row
;
2097 static UINT32
get_pixelsperxlogicalinch(void)
2099 HDC hdc
= GetDC( NULL
);
2102 if (!hdc
) return 96;
2103 ret
= GetDeviceCaps( hdc
, LOGPIXELSX
);
2104 ReleaseDC( NULL
, hdc
);
2108 static enum fill_status
fill_desktopmonitor( struct table
*table
, const struct expr
*cond
)
2110 struct record_desktopmonitor
*rec
;
2111 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2114 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2116 rec
= (struct record_desktopmonitor
*)table
->data
;
2117 rec
->name
= L
"Generic Non-PnP Monitor";
2118 rec
->pixelsperxlogicalinch
= get_pixelsperxlogicalinch();
2120 if (match_row( table
, row
, cond
, &status
)) row
++;
2122 TRACE("created %u rows\n", row
);
2123 table
->num_rows
= row
;
2127 static enum fill_status
fill_directory( struct table
*table
, const struct expr
*cond
)
2129 struct record_directory
*rec
;
2130 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
2131 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
2132 DWORD drives
= GetLogicalDrives();
2133 WIN32_FIND_DATAW data
;
2135 struct dirstack
*dirstack
;
2136 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2138 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2140 dirstack
= alloc_dirstack(2);
2142 for (i
= 0; i
< 26; i
++)
2144 if (!(drives
& (1 << i
))) continue;
2147 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
2149 num_expected_rows
= 0;
2150 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2156 path
= pop_dir( dirstack
, &len
);
2157 if (!(glob
= build_glob( root
[0], path
, len
)))
2159 status
= FILL_STATUS_FAILED
;
2162 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2166 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2168 FindClose( handle
);
2169 status
= FILL_STATUS_FAILED
;
2172 if (!(data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ||
2173 !wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." ))
2176 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2178 FindClose( handle
);
2179 status
= FILL_STATUS_FAILED
;
2183 if (!(push_dir( dirstack
, new_path
, len
)))
2186 FindClose( handle
);
2187 status
= FILL_STATUS_FAILED
;
2190 rec
= (struct record_directory
*)(table
->data
+ offset
);
2191 rec
->accessmask
= FILE_ALL_ACCESS
;
2192 rec
->name
= build_name( root
[0], new_path
);
2194 if (!match_row( table
, row
, cond
, &status
))
2196 free_row_values( table
, row
);
2199 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2202 FindClose( handle
);
2203 status
= FILL_STATUS_FILTERED
;
2206 offset
+= sizeof(*rec
);
2209 while (FindNextFileW( handle
, &data
));
2210 FindClose( handle
);
2212 if (!peek_dir( dirstack
)) break;
2217 free_dirstack( dirstack
);
2221 TRACE("created %u rows\n", row
);
2222 table
->num_rows
= row
;
2226 static UINT64
get_freespace( const WCHAR
*dir
, UINT64
*disksize
)
2228 WCHAR root
[] = L
"\\\\.\\A:";
2229 ULARGE_INTEGER free
;
2230 DISK_GEOMETRY_EX info
;
2232 DWORD bytes_returned
;
2234 free
.QuadPart
= 512 * 1024 * 1024;
2235 GetDiskFreeSpaceExW( dir
, NULL
, NULL
, &free
);
2238 handle
= CreateFileW( root
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2239 if (handle
!= INVALID_HANDLE_VALUE
)
2241 if (DeviceIoControl( handle
, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
, NULL
, 0, &info
, sizeof(info
), &bytes_returned
, NULL
))
2242 *disksize
= info
.DiskSize
.QuadPart
;
2243 CloseHandle( handle
);
2245 return free
.QuadPart
;
2247 static WCHAR
*get_diskdrive_serialnumber( WCHAR letter
)
2250 STORAGE_DEVICE_DESCRIPTOR
*desc
;
2251 HANDLE handle
= INVALID_HANDLE_VALUE
;
2252 STORAGE_PROPERTY_QUERY query
= {0};
2256 swprintf( drive
, ARRAY_SIZE(drive
), L
"\\\\.\\%c:", letter
);
2257 handle
= CreateFileW( drive
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2258 if (handle
== INVALID_HANDLE_VALUE
) goto done
;
2260 query
.PropertyId
= StorageDeviceProperty
;
2261 query
.QueryType
= PropertyStandardQuery
;
2263 size
= sizeof(*desc
) + 256;
2266 if (!(desc
= malloc( size
))) break;
2267 if (DeviceIoControl( handle
, IOCTL_STORAGE_QUERY_PROPERTY
, &query
, sizeof(query
), desc
, size
, NULL
, NULL
))
2269 if (desc
->SerialNumberOffset
) ret
= heap_strdupAW( (const char *)desc
+ desc
->SerialNumberOffset
);
2275 if (GetLastError() != ERROR_MORE_DATA
) break;
2279 if (handle
!= INVALID_HANDLE_VALUE
) CloseHandle( handle
);
2280 if (!ret
) ret
= wcsdup( L
"WINEHDISK" );
2284 static enum fill_status
fill_diskdrive( struct table
*table
, const struct expr
*cond
)
2286 static const WCHAR fmtW
[] = L
"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2287 WCHAR device_id
[ARRAY_SIZE( fmtW
) + 10], root
[] = L
"A:\\";
2288 struct record_diskdrive
*rec
;
2289 UINT i
, row
= 0, offset
= 0, index
= 0, type
;
2290 UINT64 size
= 1024 * 1024 * 1024;
2291 DWORD drives
= GetLogicalDrives();
2292 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2294 if (!resize_table( table
, 2, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2296 for (i
= 0; i
< 26; i
++)
2298 if (drives
& (1 << i
))
2301 type
= GetDriveTypeW( root
);
2302 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2305 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2307 rec
= (struct record_diskdrive
*)(table
->data
+ offset
);
2308 swprintf( device_id
, ARRAY_SIZE( device_id
), fmtW
, index
);
2309 rec
->device_id
= wcsdup( device_id
);
2310 rec
->index
= index
++;
2311 rec
->interfacetype
= L
"IDE";
2312 rec
->manufacturer
= L
"(Standard disk drives)";
2313 rec
->mediatype
= (type
== DRIVE_FIXED
) ? L
"Fixed hard disk" : L
"Removable media";
2314 rec
->model
= L
"Wine Disk Drive";
2315 rec
->pnpdevice_id
= L
"IDE\\Disk\\VEN_WINE";
2316 rec
->serialnumber
= get_diskdrive_serialnumber( root
[0] );
2317 get_freespace( root
, &size
);
2319 if (!match_row( table
, row
, cond
, &status
))
2321 free_row_values( table
, row
);
2324 offset
+= sizeof(*rec
);
2328 TRACE("created %u rows\n", row
);
2329 table
->num_rows
= row
;
2339 static void free_associations( struct association
*assoc
, UINT count
)
2343 for (i
= 0; i
< count
; i
++)
2345 free( assoc
[i
].ref
);
2346 free( assoc
[i
].ref2
);
2351 static struct association
*get_diskdrivetodiskpartition_pairs( UINT
*count
)
2353 struct association
*ret
= NULL
;
2354 struct query
*query
, *query2
= NULL
;
2359 if (!(query
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return NULL
;
2360 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskDrive",
2361 &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2362 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2364 if (!(query2
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return FALSE
;
2365 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskPartition",
2366 &query2
->view
, &query2
->mem
)) != S_OK
) goto done
;
2367 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2369 if (!(ret
= calloc( query
->view
->result_count
, sizeof(*ret
) ))) goto done
;
2371 for (i
= 0; i
< query
->view
->result_count
; i
++)
2373 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2374 if (!(ret
[i
].ref
= wcsdup( V_BSTR(&val
) ))) goto done
;
2375 VariantClear( &val
);
2377 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2378 if (!(ret
[i
].ref2
= wcsdup( V_BSTR(&val
) ))) goto done
;
2379 VariantClear( &val
);
2382 *count
= query
->view
->result_count
;
2385 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2386 free_query( query
);
2387 free_query( query2
);
2391 static enum fill_status
fill_diskdrivetodiskpartition( struct table
*table
, const struct expr
*cond
)
2393 struct record_diskdrivetodiskpartition
*rec
;
2394 UINT i
, row
= 0, offset
= 0, count
= 0;
2395 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2396 struct association
*assoc
;
2398 if (!(assoc
= get_diskdrivetodiskpartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2401 free_associations( assoc
, count
);
2402 return FILL_STATUS_UNFILTERED
;
2404 if (!resize_table( table
, count
, sizeof(*rec
) ))
2406 free_associations( assoc
, count
);
2407 return FILL_STATUS_FAILED
;
2410 for (i
= 0; i
< count
; i
++)
2412 rec
= (struct record_diskdrivetodiskpartition
*)(table
->data
+ offset
);
2413 rec
->antecedent
= assoc
[i
].ref
;
2414 rec
->dependent
= assoc
[i
].ref2
;
2415 if (!match_row( table
, row
, cond
, &status
))
2417 free_row_values( table
, row
);
2420 offset
+= sizeof(*rec
);
2426 TRACE("created %u rows\n", row
);
2427 table
->num_rows
= row
;
2431 static WCHAR
*get_filesystem( const WCHAR
*root
)
2433 WCHAR buffer
[MAX_PATH
+ 1];
2435 if (GetVolumeInformationW( root
, NULL
, 0, NULL
, NULL
, NULL
, buffer
, MAX_PATH
+ 1 ))
2436 return wcsdup( buffer
);
2437 return wcsdup( L
"NTFS" );
2440 static enum fill_status
fill_diskpartition( struct table
*table
, const struct expr
*cond
)
2442 WCHAR device_id
[32], root
[] = L
"A:\\";
2443 struct record_diskpartition
*rec
;
2444 UINT i
, row
= 0, offset
= 0, type
, index
= 0;
2445 UINT64 size
= 1024 * 1024 * 1024;
2446 DWORD drives
= GetLogicalDrives();
2447 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2449 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2451 for (i
= 0; i
< 26; i
++)
2453 if (drives
& (1 << i
))
2456 type
= GetDriveTypeW( root
);
2457 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2460 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2462 rec
= (struct record_diskpartition
*)(table
->data
+ offset
);
2463 rec
->bootable
= (i
== 2) ? -1 : 0;
2464 rec
->bootpartition
= (i
== 2) ? -1 : 0;
2465 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"Disk #%u, Partition #0", index
);
2466 rec
->device_id
= wcsdup( device_id
);
2467 rec
->diskindex
= index
++;
2469 rec
->pnpdevice_id
= wcsdup( device_id
);
2470 get_freespace( root
, &size
);
2472 rec
->startingoffset
= 0;
2473 rec
->type
= get_filesystem( root
);
2474 if (!match_row( table
, row
, cond
, &status
))
2476 free_row_values( table
, row
);
2479 offset
+= sizeof(*rec
);
2483 TRACE("created %u rows\n", row
);
2484 table
->num_rows
= row
;
2488 static UINT32
get_bitsperpixel( UINT
*hres
, UINT
*vres
)
2490 HDC hdc
= GetDC( NULL
);
2493 if (!hdc
) return 32;
2494 ret
= GetDeviceCaps( hdc
, BITSPIXEL
);
2495 *hres
= GetDeviceCaps( hdc
, HORZRES
);
2496 *vres
= GetDeviceCaps( hdc
, VERTRES
);
2497 ReleaseDC( NULL
, hdc
);
2501 static enum fill_status
fill_displaycontrollerconfig( struct table
*table
, const struct expr
*cond
)
2503 struct record_displaycontrollerconfig
*rec
;
2504 UINT row
= 0, hres
= 1024, vres
= 768;
2505 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2507 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2509 rec
= (struct record_displaycontrollerconfig
*)table
->data
;
2510 rec
->bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
2511 rec
->caption
= L
"VideoController1";
2512 rec
->horizontalresolution
= hres
;
2513 rec
->name
= L
"VideoController1";
2514 rec
->verticalresolution
= vres
;
2515 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
2518 TRACE("created %u rows\n", row
);
2519 table
->num_rows
= row
;
2523 static WCHAR
*get_ip4_string( DWORD addr
)
2525 DWORD len
= sizeof("ddd.ddd.ddd.ddd");
2528 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
2529 swprintf( ret
, len
, L
"%u.%u.%u.%u", (addr
>> 24) & 0xff, (addr
>> 16) & 0xff, (addr
>> 8) & 0xff, addr
& 0xff );
2533 static enum fill_status
fill_ip4routetable( struct table
*table
, const struct expr
*cond
)
2535 struct record_ip4routetable
*rec
;
2536 UINT i
, row
= 0, offset
= 0;
2538 MIB_IPFORWARDTABLE
*forwards
;
2539 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2541 if (GetIpForwardTable( NULL
, &size
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
) return FILL_STATUS_FAILED
;
2542 if (!(forwards
= malloc( size
))) return FILL_STATUS_FAILED
;
2543 if (GetIpForwardTable( forwards
, &size
, TRUE
))
2546 return FILL_STATUS_FAILED
;
2548 if (!resize_table( table
, max(forwards
->dwNumEntries
, 1), sizeof(*rec
) ))
2551 return FILL_STATUS_FAILED
;
2554 for (i
= 0; i
< forwards
->dwNumEntries
; i
++)
2556 rec
= (struct record_ip4routetable
*)(table
->data
+ offset
);
2558 rec
->destination
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardDest
) );
2559 rec
->interfaceindex
= forwards
->table
[i
].dwForwardIfIndex
;
2560 rec
->nexthop
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardNextHop
) );
2562 if (!match_row( table
, row
, cond
, &status
))
2564 free_row_values( table
, row
);
2567 offset
+= sizeof(*rec
);
2570 TRACE("created %u rows\n", row
);
2571 table
->num_rows
= row
;
2577 static WCHAR
*get_volumename( const WCHAR
*root
)
2579 WCHAR buf
[MAX_PATH
+ 1] = {0};
2580 GetVolumeInformationW( root
, buf
, ARRAY_SIZE( buf
), NULL
, NULL
, NULL
, NULL
, 0 );
2581 return wcsdup( buf
);
2583 static WCHAR
*get_volumeserialnumber( const WCHAR
*root
)
2588 GetVolumeInformationW( root
, NULL
, 0, &serial
, NULL
, NULL
, NULL
, 0 );
2589 swprintf( buffer
, ARRAY_SIZE( buffer
), L
"%08X", serial
);
2590 return wcsdup( buffer
);
2593 static enum fill_status
fill_logicaldisk( struct table
*table
, const struct expr
*cond
)
2595 WCHAR device_id
[3], root
[] = L
"A:\\";
2596 struct record_logicaldisk
*rec
;
2597 UINT i
, row
= 0, offset
= 0, type
;
2598 UINT64 size
= 1024 * 1024 * 1024;
2599 DWORD drives
= GetLogicalDrives();
2600 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2602 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2604 for (i
= 0; i
< 26; i
++)
2606 if (drives
& (1 << i
))
2609 type
= GetDriveTypeW( root
);
2610 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_CDROM
&& type
!= DRIVE_REMOVABLE
)
2613 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2615 rec
= (struct record_logicaldisk
*)(table
->data
+ offset
);
2616 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%c:", 'A' + i
);
2617 rec
->caption
= wcsdup( device_id
);
2618 rec
->device_id
= wcsdup( device_id
);
2619 rec
->drivetype
= type
;
2620 rec
->filesystem
= get_filesystem( root
);
2621 rec
->freespace
= get_freespace( root
, &size
);
2622 rec
->name
= wcsdup( device_id
);
2624 rec
->volumename
= get_volumename( root
);
2625 rec
->volumeserialnumber
= get_volumeserialnumber( root
);
2626 if (!match_row( table
, row
, cond
, &status
))
2628 free_row_values( table
, row
);
2631 offset
+= sizeof(*rec
);
2635 TRACE("created %u rows\n", row
);
2636 table
->num_rows
= row
;
2640 static struct association
*get_logicaldisktopartition_pairs( UINT
*count
)
2642 struct association
*ret
= NULL
;
2643 struct query
*query
, *query2
= NULL
;
2648 if (!(query
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return NULL
;
2649 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskPartition",
2650 &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2651 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2653 if (!(query2
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return FALSE
;
2654 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
,
2655 L
"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2
->view
,
2656 &query2
->mem
)) != S_OK
) goto done
;
2657 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2659 if (!(ret
= calloc( query
->view
->result_count
, sizeof(*ret
) ))) goto done
;
2661 /* assume fixed and removable disks are enumerated in the same order as partitions */
2662 for (i
= 0; i
< query
->view
->result_count
; i
++)
2664 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2665 if (!(ret
[i
].ref
= wcsdup( V_BSTR(&val
) ))) goto done
;
2666 VariantClear( &val
);
2668 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2669 if (!(ret
[i
].ref2
= wcsdup( V_BSTR(&val
) ))) goto done
;
2670 VariantClear( &val
);
2673 *count
= query
->view
->result_count
;
2676 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2677 free_query( query
);
2678 free_query( query2
);
2682 static enum fill_status
fill_logicaldisktopartition( struct table
*table
, const struct expr
*cond
)
2684 struct record_logicaldisktopartition
*rec
;
2685 UINT i
, row
= 0, offset
= 0, count
= 0;
2686 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2687 struct association
*assoc
;
2689 if (!(assoc
= get_logicaldisktopartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2692 free_associations( assoc
, count
);
2693 return FILL_STATUS_UNFILTERED
;
2695 if (!resize_table( table
, count
, sizeof(*rec
) ))
2697 free_associations( assoc
, count
);
2698 return FILL_STATUS_FAILED
;
2701 for (i
= 0; i
< count
; i
++)
2703 rec
= (struct record_logicaldisktopartition
*)(table
->data
+ offset
);
2704 rec
->antecedent
= assoc
[i
].ref
;
2705 rec
->dependent
= assoc
[i
].ref2
;
2706 if (!match_row( table
, row
, cond
, &status
))
2708 free_row_values( table
, row
);
2711 offset
+= sizeof(*rec
);
2717 TRACE("created %u rows\n", row
);
2718 table
->num_rows
= row
;
2722 static UINT16
get_connection_status( IF_OPER_STATUS status
)
2726 case IfOperStatusDown
:
2727 return 0; /* Disconnected */
2728 case IfOperStatusUp
:
2729 return 2; /* Connected */
2731 ERR("unhandled status %u\n", status
);
2736 static WCHAR
*get_mac_address( const BYTE
*addr
, DWORD len
)
2739 if (len
!= 6 || !(ret
= malloc( 18 * sizeof(WCHAR
) ))) return NULL
;
2740 swprintf( ret
, 18, L
"%02x:%02x:%02x:%02x:%02x:%02x", addr
[0], addr
[1], addr
[2], addr
[3], addr
[4], addr
[5] );
2743 static const WCHAR
*get_adaptertype( DWORD type
, int *id
, int *physical
)
2747 case IF_TYPE_ETHERNET_CSMACD
:
2750 return L
"Ethernet 802.3";
2752 case IF_TYPE_IEEE80211
:
2757 case IF_TYPE_IEEE1394
:
2762 case IF_TYPE_TUNNEL
:
2774 #define GUID_SIZE 39
2775 static WCHAR
*guid_to_str( const GUID
*ptr
)
2778 if (!(ret
= malloc( GUID_SIZE
* sizeof(WCHAR
) ))) return NULL
;
2779 swprintf( ret
, GUID_SIZE
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2780 ptr
->Data1
, ptr
->Data2
, ptr
->Data3
, ptr
->Data4
[0], ptr
->Data4
[1], ptr
->Data4
[2],
2781 ptr
->Data4
[3], ptr
->Data4
[4], ptr
->Data4
[5], ptr
->Data4
[6], ptr
->Data4
[7] );
2785 static WCHAR
*get_networkadapter_guid( const IF_LUID
*luid
)
2788 if (ConvertInterfaceLuidToGuid( luid
, &guid
)) return NULL
;
2789 return guid_to_str( &guid
);
2792 static enum fill_status
fill_networkadapter( struct table
*table
, const struct expr
*cond
)
2794 WCHAR device_id
[11];
2795 struct record_networkadapter
*rec
;
2796 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
2797 UINT row
= 0, offset
= 0, count
= 0;
2798 DWORD size
= 0, ret
;
2799 int adaptertypeid
, physical
;
2800 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2802 ret
= GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, NULL
, &size
);
2803 if (ret
!= ERROR_BUFFER_OVERFLOW
) return FILL_STATUS_FAILED
;
2805 if (!(buffer
= malloc( size
))) return FILL_STATUS_FAILED
;
2806 if (GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, buffer
, &size
))
2809 return FILL_STATUS_FAILED
;
2811 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2813 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
2815 if (!resize_table( table
, count
, sizeof(*rec
) ))
2818 return FILL_STATUS_FAILED
;
2820 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2822 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
2824 rec
= (struct record_networkadapter
*)(table
->data
+ offset
);
2825 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%u", aa
->u
.s
.IfIndex
);
2826 rec
->adaptertype
= get_adaptertype( aa
->IfType
, &adaptertypeid
, &physical
);
2827 rec
->adaptertypeid
= adaptertypeid
;
2828 rec
->description
= wcsdup( aa
->Description
);
2829 rec
->device_id
= wcsdup( device_id
);
2830 rec
->guid
= get_networkadapter_guid( &aa
->Luid
);
2831 rec
->index
= aa
->u
.s
.IfIndex
;
2832 rec
->interface_index
= aa
->u
.s
.IfIndex
;
2833 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
2834 rec
->manufacturer
= L
"The Wine Project";
2835 rec
->name
= wcsdup( aa
->FriendlyName
);
2836 rec
->netconnection_status
= get_connection_status( aa
->OperStatus
);
2837 rec
->physicaladapter
= physical
;
2838 rec
->pnpdevice_id
= L
"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2839 rec
->servicename
= wcsdup( aa
->FriendlyName
);
2840 rec
->speed
= 1000000;
2841 if (!match_row( table
, row
, cond
, &status
))
2843 free_row_values( table
, row
);
2846 offset
+= sizeof(*rec
);
2849 TRACE("created %u rows\n", row
);
2850 table
->num_rows
= row
;
2856 static WCHAR
*get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS
*addr
)
2858 const SOCKET_ADDRESS
*sa
= &addr
->Address
;
2859 WCHAR buf
[NI_MAXHOST
];
2861 if (!addr
) return NULL
;
2862 if (GetNameInfoW( sa
->lpSockaddr
, sa
->iSockaddrLength
, buf
, ARRAY_SIZE( buf
), NULL
,
2863 0, NI_NAMEREQD
)) return NULL
;
2864 return wcsdup( buf
);
2866 static struct array
*get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS
*list
)
2868 IP_ADAPTER_GATEWAY_ADDRESS
*gateway
;
2870 ULONG buflen
, i
= 0, count
= 0;
2871 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2873 if (!list
) return NULL
;
2874 for (gateway
= list
; gateway
; gateway
= gateway
->Next
) count
++;
2876 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2877 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2882 for (gateway
= list
; gateway
; gateway
= gateway
->Next
)
2884 buflen
= ARRAY_SIZE( buf
);
2885 if (WSAAddressToStringW( gateway
->Address
.lpSockaddr
, gateway
->Address
.iSockaddrLength
,
2886 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2888 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2894 ret
->elem_size
= sizeof(*ptr
);
2899 static struct array
*get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS
*list
)
2901 IP_ADAPTER_DNS_SERVER_ADDRESS
*server
;
2903 ULONG buflen
, i
= 0, count
= 0;
2904 WCHAR
**ptr
, *p
, buf
[54]; /* max IPv6 address length */
2906 if (!list
) return NULL
;
2907 for (server
= list
; server
; server
= server
->Next
) count
++;
2909 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2910 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2915 for (server
= list
; server
; server
= server
->Next
)
2917 buflen
= ARRAY_SIZE( buf
);
2918 if (WSAAddressToStringW( server
->Address
.lpSockaddr
, server
->Address
.iSockaddrLength
,
2919 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2921 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2926 if ((p
= wcsrchr( ptr
[i
- 1], ':' ))) *p
= 0;
2928 ret
->elem_size
= sizeof(*ptr
);
2933 static struct array
*get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
2935 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
2937 ULONG buflen
, i
= 0, count
= 0;
2938 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2940 if (!list
) return NULL
;
2941 for (address
= list
; address
; address
= address
->Next
) count
++;
2943 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2944 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2949 for (address
= list
; address
; address
= address
->Next
)
2951 buflen
= ARRAY_SIZE( buf
);
2952 if (WSAAddressToStringW( address
->Address
.lpSockaddr
, address
->Address
.iSockaddrLength
,
2953 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2955 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2961 ret
->elem_size
= sizeof(*ptr
);
2966 static struct array
*get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
2968 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
2970 ULONG i
= 0, count
= 0;
2973 if (!list
) return NULL
;
2974 for (address
= list
; address
; address
= address
->Next
) count
++;
2976 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2977 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2982 for (address
= list
; address
; address
= address
->Next
)
2984 if (address
->Address
.lpSockaddr
->sa_family
== AF_INET
)
2986 WCHAR buf
[INET_ADDRSTRLEN
];
2988 ULONG buflen
= ARRAY_SIZE( buf
);
2990 memset( &addr
, 0, sizeof(addr
) );
2991 addr
.sin_family
= AF_INET
;
2992 if (ConvertLengthToIpv4Mask( address
->OnLinkPrefixLength
, &addr
.sin_addr
.S_un
.S_addr
) != NO_ERROR
2993 || WSAAddressToStringW( (SOCKADDR
*)&addr
, sizeof(addr
), NULL
, buf
, &buflen
))
2996 ptr
[i
] = wcsdup( buf
);
3001 swprintf( buf
, ARRAY_SIZE( buf
), L
"%u", address
->OnLinkPrefixLength
);
3002 ptr
[i
] = wcsdup( buf
);
3006 for (; i
> 0; i
--) free( ptr
[i
- 1] );
3012 ret
->elem_size
= sizeof(*ptr
);
3017 static WCHAR
*get_settingid( UINT32 index
)
3020 memset( &guid
, 0, sizeof(guid
) );
3022 return guid_to_str( &guid
);
3025 static enum fill_status
fill_networkadapterconfig( struct table
*table
, const struct expr
*cond
)
3027 struct record_networkadapterconfig
*rec
;
3028 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
3029 UINT row
= 0, offset
= 0, count
= 0;
3030 DWORD size
= 0, ret
;
3031 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3033 ret
= GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_GATEWAYS
, NULL
, NULL
, &size
);
3034 if (ret
!= ERROR_BUFFER_OVERFLOW
) return FILL_STATUS_FAILED
;
3036 if (!(buffer
= malloc( size
))) return FILL_STATUS_FAILED
;
3037 if (GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_GATEWAYS
, NULL
, buffer
, &size
))
3040 return FILL_STATUS_FAILED
;
3042 for (aa
= buffer
; aa
; aa
= aa
->Next
)
3044 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
3046 if (!resize_table( table
, count
, sizeof(*rec
) ))
3049 return FILL_STATUS_FAILED
;
3051 for (aa
= buffer
; aa
; aa
= aa
->Next
)
3053 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
3055 rec
= (struct record_networkadapterconfig
*)(table
->data
+ offset
);
3056 rec
->defaultipgateway
= get_defaultipgateway( aa
->FirstGatewayAddress
);
3057 rec
->description
= wcsdup( aa
->Description
);
3058 rec
->dhcpenabled
= -1;
3059 rec
->dnsdomain
= L
"";
3060 rec
->dnshostname
= get_dnshostname( aa
->FirstUnicastAddress
);
3061 rec
->dnsserversearchorder
= get_dnsserversearchorder( aa
->FirstDnsServerAddress
);
3062 rec
->index
= aa
->u
.s
.IfIndex
;
3063 rec
->ipaddress
= get_ipaddress( aa
->FirstUnicastAddress
);
3064 rec
->ipconnectionmetric
= 20;
3065 rec
->ipenabled
= -1;
3066 rec
->ipsubnet
= get_ipsubnet( aa
->FirstUnicastAddress
);
3067 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
3068 rec
->settingid
= get_settingid( rec
->index
);
3069 if (!match_row( table
, row
, cond
, &status
))
3071 free_row_values( table
, row
);
3074 offset
+= sizeof(*rec
);
3077 TRACE("created %u rows\n", row
);
3078 table
->num_rows
= row
;
3084 static enum fill_status
fill_physicalmemory( struct table
*table
, const struct expr
*cond
)
3086 struct record_physicalmemory
*rec
;
3087 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3090 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3092 rec
= (struct record_physicalmemory
*)table
->data
;
3093 rec
->banklabel
= L
"BANK 0";
3094 rec
->capacity
= get_total_physical_memory();
3095 rec
->caption
= L
"Physical Memory";
3096 rec
->configuredclockspeed
= 1600;
3097 rec
->devicelocator
= L
"DIMM 0";
3098 rec
->formfactor
= 8; /* DIMM */
3099 rec
->memorytype
= 9; /* RAM */
3100 rec
->partnumber
= L
"";
3102 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3105 TRACE("created %u rows\n", row
);
3106 table
->num_rows
= row
;
3110 static enum fill_status
fill_pnpentity( struct table
*table
, const struct expr
*cond
)
3112 struct record_pnpentity
*rec
;
3113 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3114 HDEVINFO device_info_set
;
3115 SP_DEVINFO_DATA devinfo
= {0};
3118 device_info_set
= SetupDiGetClassDevsW( NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
|DIGCF_PRESENT
);
3120 devinfo
.cbSize
= sizeof(devinfo
);
3123 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
3128 resize_table( table
, idx
, sizeof(*rec
) );
3129 table
->num_rows
= 0;
3130 rec
= (struct record_pnpentity
*)table
->data
;
3133 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
3135 WCHAR device_id
[MAX_PATH
];
3136 if (SetupDiGetDeviceInstanceIdW( device_info_set
, &devinfo
, device_id
,
3137 ARRAY_SIZE(device_id
), NULL
))
3139 rec
->device_id
= wcsdup( device_id
);
3140 rec
->manufacturer
= L
"The Wine Project";
3141 rec
->name
= L
"Wine PnP Device";
3144 if (!match_row( table
, table
->num_rows
- 1, cond
, &status
))
3146 free_row_values( table
, table
->num_rows
- 1 );
3154 SetupDiDestroyDeviceInfoList( device_info_set
);
3159 static enum fill_status
fill_printer( struct table
*table
, const struct expr
*cond
)
3161 struct record_printer
*rec
;
3162 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3163 PRINTER_INFO_2W
*info
;
3164 DWORD i
, offset
= 0, count
= 0, size
= 0;
3168 EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &size
, &count
);
3169 if (!count
) return FILL_STATUS_UNFILTERED
;
3171 if (!(info
= malloc( size
))) return FILL_STATUS_FAILED
;
3172 if (!EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, (BYTE
*)info
, size
, &size
, &count
))
3175 return FILL_STATUS_FAILED
;
3177 if (!resize_table( table
, count
, sizeof(*rec
) ))
3180 return FILL_STATUS_FAILED
;
3183 for (i
= 0; i
< count
; i
++)
3185 rec
= (struct record_printer
*)(table
->data
+ offset
);
3186 rec
->attributes
= info
[i
].Attributes
;
3187 swprintf( id
, ARRAY_SIZE( id
), L
"Printer%u", i
);
3188 rec
->device_id
= wcsdup( id
);
3189 rec
->drivername
= wcsdup( info
[i
].pDriverName
);
3190 rec
->horizontalresolution
= info
[i
].pDevMode
->u1
.s1
.dmPrintQuality
;
3192 rec
->location
= wcsdup( info
[i
].pLocation
);
3193 rec
->name
= wcsdup( info
[i
].pPrinterName
);
3195 rec
->portname
= wcsdup( info
[i
].pPortName
);
3196 if (!match_row( table
, i
, cond
, &status
))
3198 free_row_values( table
, i
);
3201 offset
+= sizeof(*rec
);
3204 TRACE("created %u rows\n", num_rows
);
3205 table
->num_rows
= num_rows
;
3211 static WCHAR
*get_cmdline( DWORD process_id
)
3213 if (process_id
== GetCurrentProcessId()) return wcsdup( GetCommandLineW() );
3214 return NULL
; /* FIXME handle different process case */
3217 static enum fill_status
fill_process( struct table
*table
, const struct expr
*cond
)
3220 struct record_process
*rec
;
3221 PROCESSENTRY32W entry
;
3223 enum fill_status status
= FILL_STATUS_FAILED
;
3224 UINT row
= 0, offset
= 0;
3226 snap
= CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS
, 0 );
3227 if (snap
== INVALID_HANDLE_VALUE
) return FILL_STATUS_FAILED
;
3229 entry
.dwSize
= sizeof(entry
);
3230 if (!Process32FirstW( snap
, &entry
)) goto done
;
3231 if (!resize_table( table
, 8, sizeof(*rec
) )) goto done
;
3235 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
3237 status
= FILL_STATUS_FAILED
;
3241 rec
= (struct record_process
*)(table
->data
+ offset
);
3242 rec
->caption
= wcsdup( entry
.szExeFile
);
3243 rec
->commandline
= get_cmdline( entry
.th32ProcessID
);
3244 rec
->description
= wcsdup( entry
.szExeFile
);
3245 swprintf( handle
, ARRAY_SIZE( handle
), L
"%u", entry
.th32ProcessID
);
3246 rec
->handle
= wcsdup( handle
);
3247 rec
->name
= wcsdup( entry
.szExeFile
);
3248 rec
->process_id
= entry
.th32ProcessID
;
3249 rec
->pprocess_id
= entry
.th32ParentProcessID
;
3250 rec
->thread_count
= entry
.cntThreads
;
3251 rec
->workingsetsize
= 0;
3253 rec
->create
= process_create
;
3254 rec
->get_owner
= process_get_owner
;
3255 if (!match_row( table
, row
, cond
, &status
))
3257 free_row_values( table
, row
);
3260 offset
+= sizeof(*rec
);
3262 } while (Process32NextW( snap
, &entry
));
3264 TRACE("created %u rows\n", row
);
3265 table
->num_rows
= row
;
3268 CloseHandle( snap
);
3272 void do_cpuid( unsigned int ax
, int *p
)
3274 #if defined(__i386__) || defined(__x86_64__)
3281 static unsigned int get_processor_model( unsigned int reg0
, unsigned int *stepping
, unsigned int *family
)
3283 unsigned int model
, family_id
= (reg0
& (0x0f << 8)) >> 8;
3285 model
= (reg0
& (0x0f << 4)) >> 4;
3286 if (family_id
== 6 || family_id
== 15) model
|= (reg0
& (0x0f << 16)) >> 12;
3289 *family
= family_id
;
3290 if (family_id
== 15) *family
+= (reg0
& (0xff << 20)) >> 20;
3292 *stepping
= reg0
& 0x0f;
3295 static void regs_to_str( int *regs
, unsigned int len
, WCHAR
*buffer
)
3298 unsigned char *p
= (unsigned char *)regs
;
3300 for (i
= 0; i
< len
; i
++) { buffer
[i
] = *p
++; }
3303 static void get_processor_manufacturer( WCHAR
*manufacturer
, UINT len
)
3305 int tmp
, regs
[4] = {0, 0, 0, 0};
3307 do_cpuid( 0, regs
);
3308 tmp
= regs
[2]; /* swap edx and ecx */
3312 regs_to_str( regs
+ 1, min( 12, len
), manufacturer
);
3314 static const WCHAR
*get_osarchitecture(void)
3317 GetNativeSystemInfo( &info
);
3318 if (info
.u
.s
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"64-bit";
3321 static void get_processor_caption( WCHAR
*caption
, UINT len
)
3324 WCHAR manufacturer
[13];
3325 int regs
[4] = {0, 0, 0, 0};
3326 unsigned int family
, model
, stepping
;
3328 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3329 if (!wcscmp( get_osarchitecture(), L
"32-bit" )) arch
= L
"x86";
3330 else if (!wcscmp( manufacturer
, L
"AuthenticAMD" )) arch
= L
"AMD64";
3331 else arch
= L
"Intel64";
3333 do_cpuid( 1, regs
);
3335 model
= get_processor_model( regs
[0], &stepping
, &family
);
3336 swprintf( caption
, len
, L
"%s Family %u Model %u Stepping %u", arch
, family
, model
, stepping
);
3338 static void get_processor_version( WCHAR
*version
, UINT len
)
3340 int regs
[4] = {0, 0, 0, 0};
3341 unsigned int model
, stepping
;
3343 do_cpuid( 1, regs
);
3345 model
= get_processor_model( regs
[0], &stepping
, NULL
);
3346 swprintf( version
, len
, L
"Model %u Stepping %u", model
, stepping
);
3348 static UINT16
get_processor_revision(void)
3350 int regs
[4] = {0, 0, 0, 0};
3351 do_cpuid( 1, regs
);
3354 static void get_processor_id( WCHAR
*processor_id
, UINT len
)
3356 int regs
[4] = {0, 0, 0, 0};
3358 do_cpuid( 1, regs
);
3359 swprintf( processor_id
, len
, L
"%08X%08X", regs
[3], regs
[0] );
3361 static void get_processor_name( WCHAR
*name
)
3363 int regs
[4] = {0, 0, 0, 0};
3366 do_cpuid( 0x80000000, regs
);
3367 if (regs
[0] >= 0x80000004)
3369 do_cpuid( 0x80000002, regs
);
3370 regs_to_str( regs
, 16, name
);
3371 do_cpuid( 0x80000003, regs
);
3372 regs_to_str( regs
, 16, name
+ 16 );
3373 do_cpuid( 0x80000004, regs
);
3374 regs_to_str( regs
, 16, name
+ 32 );
3376 for (i
= lstrlenW(name
) - 1; i
>= 0 && name
[i
] == ' '; i
--) name
[i
] = 0;
3378 static UINT
get_processor_currentclockspeed( UINT index
)
3380 PROCESSOR_POWER_INFORMATION
*info
;
3381 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3384 if ((info
= malloc( size
)))
3386 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3387 if (!status
) ret
= info
[index
].CurrentMhz
;
3392 static UINT
get_processor_maxclockspeed( UINT index
)
3394 PROCESSOR_POWER_INFORMATION
*info
;
3395 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3398 if ((info
= malloc( size
)))
3400 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3401 if (!status
) ret
= info
[index
].MaxMhz
;
3407 static enum fill_status
fill_processor( struct table
*table
, const struct expr
*cond
)
3409 WCHAR caption
[100], device_id
[14], processor_id
[17], manufacturer
[13], name
[49] = {0}, version
[50];
3410 struct record_processor
*rec
;
3411 UINT i
, offset
= 0, num_rows
= 0, num_logical
, num_physical
, num_packages
;
3412 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3414 num_logical
= get_logical_processor_count( &num_physical
, &num_packages
);
3416 if (!resize_table( table
, num_packages
, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3418 get_processor_caption( caption
, ARRAY_SIZE( caption
) );
3419 get_processor_id( processor_id
, ARRAY_SIZE( processor_id
) );
3420 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3421 get_processor_name( name
);
3422 get_processor_version( version
, ARRAY_SIZE( version
) );
3424 for (i
= 0; i
< num_packages
; i
++)
3426 rec
= (struct record_processor
*)(table
->data
+ offset
);
3427 rec
->addresswidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3428 rec
->architecture
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 0 : 9;
3429 rec
->caption
= wcsdup( caption
);
3430 rec
->cpu_status
= 1; /* CPU Enabled */
3431 rec
->currentclockspeed
= get_processor_currentclockspeed( i
);
3432 rec
->datawidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3433 rec
->description
= wcsdup( caption
);
3434 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"CPU%u", i
);
3435 rec
->device_id
= wcsdup( device_id
);
3436 rec
->family
= 2; /* Unknown */
3438 rec
->manufacturer
= wcsdup( manufacturer
);
3439 rec
->maxclockspeed
= get_processor_maxclockspeed( i
);
3440 rec
->name
= wcsdup( name
);
3441 rec
->num_cores
= num_physical
/ num_packages
;
3442 rec
->num_logical_processors
= num_logical
/ num_packages
;
3443 rec
->processor_id
= wcsdup( processor_id
);
3444 rec
->processortype
= 3; /* central processor */
3445 rec
->revision
= get_processor_revision();
3446 rec
->unique_id
= NULL
;
3447 rec
->version
= wcsdup( version
);
3448 if (!match_row( table
, i
, cond
, &status
))
3450 free_row_values( table
, i
);
3453 offset
+= sizeof(*rec
);
3457 TRACE("created %u rows\n", num_rows
);
3458 table
->num_rows
= num_rows
;
3462 static INT16
get_currenttimezone(void)
3464 TIME_ZONE_INFORMATION info
;
3465 DWORD status
= GetTimeZoneInformation( &info
);
3466 if (status
== TIME_ZONE_ID_INVALID
) return 0;
3467 if (status
== TIME_ZONE_ID_DAYLIGHT
) return -(info
.Bias
+ info
.DaylightBias
);
3468 return -(info
.Bias
+ info
.StandardBias
);
3471 static WCHAR
*get_lastbootuptime(void)
3473 SYSTEM_TIMEOFDAY_INFORMATION ti
;
3477 if (!(ret
= malloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3479 NtQuerySystemInformation( SystemTimeOfDayInformation
, &ti
, sizeof(ti
), NULL
);
3480 RtlTimeToTimeFields( &ti
.BootTime
, &tf
);
3481 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u+000", tf
.Year
, tf
.Month
, tf
.Day
, tf
.Hour
, tf
.Minute
,
3482 tf
.Second
, tf
.Milliseconds
* 1000 );
3485 static WCHAR
*get_localdatetime(void)
3487 TIME_ZONE_INFORMATION tzi
;
3493 Status
= GetTimeZoneInformation(&tzi
);
3495 if(Status
== TIME_ZONE_ID_INVALID
) return NULL
;
3497 if(Status
== TIME_ZONE_ID_DAYLIGHT
)
3498 Bias
+= tzi
.DaylightBias
;
3500 Bias
+= tzi
.StandardBias
;
3501 if (!(ret
= malloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3504 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u%+03d", st
.wYear
, st
.wMonth
, st
.wDay
, st
.wHour
, st
.wMinute
,
3505 st
.wSecond
, st
.wMilliseconds
* 1000, -Bias
);
3508 static WCHAR
*get_systemdirectory(void)
3513 if (!(ret
= malloc( MAX_PATH
* sizeof(WCHAR
) ))) return NULL
;
3514 Wow64DisableWow64FsRedirection( &redir
);
3515 GetSystemDirectoryW( ret
, MAX_PATH
);
3516 Wow64RevertWow64FsRedirection( redir
);
3519 static WCHAR
*get_systemdrive(void)
3521 WCHAR
*ret
= malloc( 3 * sizeof(WCHAR
) ); /* "c:" */
3522 if (ret
&& GetEnvironmentVariableW( L
"SystemDrive", ret
, 3 )) return ret
;
3526 static WCHAR
*get_codeset(void)
3528 WCHAR
*ret
= malloc( 11 * sizeof(WCHAR
) );
3529 if (ret
) swprintf( ret
, 11, L
"%u", GetACP() );
3532 static WCHAR
*get_countrycode(void)
3534 WCHAR
*ret
= malloc( 6 * sizeof(WCHAR
) );
3535 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ICOUNTRY
, ret
, 6 );
3538 static WCHAR
*get_locale(void)
3540 WCHAR
*ret
= malloc( 5 * sizeof(WCHAR
) );
3541 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, ret
, 5 );
3545 static WCHAR
*get_reg_str( HKEY root
, const WCHAR
*path
, const WCHAR
*value
)
3551 if (!RegOpenKeyExW( root
, path
, 0, KEY_READ
, &hkey
) &&
3552 !RegQueryValueExW( hkey
, value
, NULL
, &type
, NULL
, &size
) && type
== REG_SZ
&&
3553 (ret
= malloc( size
+ sizeof(WCHAR
) )))
3555 size
+= sizeof(WCHAR
);
3556 if (RegQueryValueExW( hkey
, value
, NULL
, NULL
, (BYTE
*)ret
, &size
))
3562 if (hkey
) RegCloseKey( hkey
);
3566 static WCHAR
*get_organization(void)
3568 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
3569 L
"RegisteredOrganization" );
3572 static WCHAR
*get_osbuildnumber( OSVERSIONINFOEXW
*ver
)
3574 WCHAR
*ret
= malloc( 11 * sizeof(WCHAR
) );
3575 if (ret
) swprintf( ret
, 11, L
"%u", ver
->dwBuildNumber
);
3578 static WCHAR
*get_oscaption( OSVERSIONINFOEXW
*ver
)
3580 static const WCHAR windowsW
[] = L
"Microsoft Windows ";
3581 static const WCHAR win2000W
[] = L
"2000 Professional";
3582 static const WCHAR win2003W
[] = L
"Server 2003 Standard Edition";
3583 static const WCHAR winxpW
[] = L
"XP Professional";
3584 static const WCHAR winxp64W
[] = L
"XP Professional x64 Edition";
3585 static const WCHAR vistaW
[] = L
"Vista Ultimate";
3586 static const WCHAR win2008W
[] = L
"Server 2008 Standard";
3587 static const WCHAR win7W
[] = L
"7 Professional";
3588 static const WCHAR win2008r2W
[] = L
"Server 2008 R2 Standard";
3589 static const WCHAR win8W
[] = L
"8 Pro";
3590 static const WCHAR win81W
[] = L
"8.1 Pro";
3591 static const WCHAR win10W
[] = L
"10 Pro";
3592 int len
= ARRAY_SIZE( windowsW
) - 1;
3595 if (!(ret
= malloc( len
* sizeof(WCHAR
) + sizeof(win2003W
) ))) return NULL
;
3596 memcpy( ret
, windowsW
, sizeof(windowsW
) );
3597 if (ver
->dwMajorVersion
== 10 && ver
->dwMinorVersion
== 0) memcpy( ret
+ len
, win10W
, sizeof(win10W
) );
3598 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 3) memcpy( ret
+ len
, win81W
, sizeof(win81W
) );
3599 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 2) memcpy( ret
+ len
, win8W
, sizeof(win8W
) );
3600 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 1)
3602 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, win7W
, sizeof(win7W
) );
3603 else memcpy( ret
+ len
, win2008r2W
, sizeof(win2008r2W
) );
3605 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 0)
3607 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, vistaW
, sizeof(vistaW
) );
3608 else memcpy( ret
+ len
, win2008W
, sizeof(win2008W
) );
3610 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 2)
3612 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, winxp64W
, sizeof(winxp64W
) );
3613 else memcpy( ret
+ len
, win2003W
, sizeof(win2003W
) );
3615 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 1) memcpy( ret
+ len
, winxpW
, sizeof(winxpW
) );
3616 else memcpy( ret
+ len
, win2000W
, sizeof(win2000W
) );
3619 static WCHAR
*get_osname( const WCHAR
*caption
)
3621 static const WCHAR partitionW
[] = L
"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3622 int len
= lstrlenW( caption
);
3625 if (!(ret
= malloc( len
* sizeof(WCHAR
) + sizeof(partitionW
) ))) return NULL
;
3626 memcpy( ret
, caption
, len
* sizeof(WCHAR
) );
3627 memcpy( ret
+ len
, partitionW
, sizeof(partitionW
) );
3631 static WCHAR
*get_osserialnumber(void)
3633 WCHAR
*ret
= get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"ProductId" );
3634 if (!ret
) ret
= wcsdup( L
"12345-OEM-1234567-12345" );
3638 static WCHAR
*get_osversion( OSVERSIONINFOEXW
*ver
)
3640 WCHAR
*ret
= malloc( 33 * sizeof(WCHAR
) );
3641 if (ret
) swprintf( ret
, 33, L
"%u.%u.%u", ver
->dwMajorVersion
, ver
->dwMinorVersion
, ver
->dwBuildNumber
);
3644 static DWORD
get_operatingsystemsku(void)
3646 DWORD ret
= PRODUCT_UNDEFINED
;
3647 GetProductInfo( 6, 0, 0, 0, &ret
);
3651 static WCHAR
*get_registereduser(void)
3653 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"RegisteredOwner" );
3656 static WCHAR
*get_windowsdirectory(void)
3658 WCHAR dir
[MAX_PATH
];
3659 if (!GetWindowsDirectoryW( dir
, ARRAY_SIZE(dir
) )) return NULL
;
3660 return wcsdup( dir
);
3663 static enum fill_status
fill_operatingsystem( struct table
*table
, const struct expr
*cond
)
3665 struct record_operatingsystem
*rec
;
3666 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3667 RTL_OSVERSIONINFOEXW ver
;
3670 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3672 ver
.dwOSVersionInfoSize
= sizeof(ver
);
3673 RtlGetVersion( &ver
);
3675 rec
= (struct record_operatingsystem
*)table
->data
;
3676 rec
->bootdevice
= L
"\\Device\\HarddiskVolume1";
3677 rec
->buildnumber
= get_osbuildnumber( &ver
);
3678 rec
->buildtype
= L
"Wine build";
3679 rec
->caption
= get_oscaption( &ver
);
3680 rec
->codeset
= get_codeset();
3681 rec
->countrycode
= get_countrycode();
3682 rec
->csdversion
= ver
.szCSDVersion
[0] ? wcsdup( ver
.szCSDVersion
) : NULL
;
3683 rec
->csname
= get_computername();
3684 rec
->currenttimezone
= get_currenttimezone();
3685 rec
->freephysicalmemory
= get_available_physical_memory() / 1024;
3686 rec
->installdate
= L
"20140101000000.000000+000";
3687 rec
->lastbootuptime
= get_lastbootuptime();
3688 rec
->localdatetime
= get_localdatetime();
3689 rec
->locale
= get_locale();
3690 rec
->manufacturer
= L
"The Wine Project";
3691 rec
->name
= get_osname( rec
->caption
);
3692 rec
->operatingsystemsku
= get_operatingsystemsku();
3693 rec
->organization
= get_organization();
3694 rec
->osarchitecture
= get_osarchitecture();
3695 rec
->oslanguage
= GetSystemDefaultLangID();
3696 rec
->osproductsuite
= 2461140; /* Windows XP Professional */
3697 rec
->ostype
= 18; /* WINNT */
3699 rec
->producttype
= 1;
3700 rec
->registereduser
= get_registereduser();
3701 rec
->serialnumber
= get_osserialnumber();
3702 rec
->servicepackmajor
= ver
.wServicePackMajor
;
3703 rec
->servicepackminor
= ver
.wServicePackMinor
;
3704 rec
->status
= L
"OK";
3705 rec
->suitemask
= 272; /* Single User + Terminal */
3706 rec
->systemdirectory
= get_systemdirectory();
3707 rec
->systemdrive
= get_systemdrive();
3708 rec
->totalvirtualmemorysize
= get_total_physical_memory() / 1024;
3709 rec
->totalvisiblememorysize
= rec
->totalvirtualmemorysize
;
3710 rec
->version
= get_osversion( &ver
);
3711 rec
->windowsdirectory
= get_windowsdirectory();
3712 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3715 TRACE("created %u rows\n", row
);
3716 table
->num_rows
= row
;
3720 static const WCHAR
*get_service_type( DWORD type
)
3722 if (type
& SERVICE_KERNEL_DRIVER
) return L
"Kernel Driver";
3723 else if (type
& SERVICE_FILE_SYSTEM_DRIVER
) return L
"File System Driver";
3724 else if (type
& SERVICE_WIN32_OWN_PROCESS
) return L
"Own Process";
3725 else if (type
& SERVICE_WIN32_SHARE_PROCESS
) return L
"Share Process";
3726 else ERR( "unhandled type %#lx\n", type
);
3729 static const WCHAR
*get_service_state( DWORD state
)
3733 case SERVICE_STOPPED
: return L
"Stopped";
3734 case SERVICE_START_PENDING
: return L
"Start Pending";
3735 case SERVICE_STOP_PENDING
: return L
"Stop Pending";
3736 case SERVICE_RUNNING
: return L
"Running";
3738 ERR( "unknown state %lu\n", state
);
3742 static const WCHAR
*get_service_startmode( DWORD mode
)
3746 case SERVICE_BOOT_START
: return L
"Boot";
3747 case SERVICE_SYSTEM_START
: return L
"System";
3748 case SERVICE_AUTO_START
: return L
"Auto";
3749 case SERVICE_DEMAND_START
: return L
"Manual";
3750 case SERVICE_DISABLED
: return L
"Disabled";
3752 ERR( "unknown mode %#lx\n", mode
);
3756 static QUERY_SERVICE_CONFIGW
*query_service_config( SC_HANDLE manager
, const WCHAR
*name
)
3758 QUERY_SERVICE_CONFIGW
*config
= NULL
;
3762 if (!(service
= OpenServiceW( manager
, name
, SERVICE_QUERY_CONFIG
))) return NULL
;
3763 QueryServiceConfigW( service
, NULL
, 0, &size
);
3764 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) goto done
;
3765 if (!(config
= malloc( size
))) goto done
;
3766 if (QueryServiceConfigW( service
, config
, size
, &size
)) goto done
;
3771 CloseServiceHandle( service
);
3775 static enum fill_status
fill_service( struct table
*table
, const struct expr
*cond
)
3777 struct record_service
*rec
;
3779 ENUM_SERVICE_STATUS_PROCESSW
*tmp
, *services
= NULL
;
3780 SERVICE_STATUS_PROCESS
*status
;
3781 WCHAR sysnameW
[MAX_COMPUTERNAME_LENGTH
+ 1];
3782 DWORD len
= ARRAY_SIZE( sysnameW
), needed
, count
;
3783 UINT i
, row
= 0, offset
= 0, size
= 256;
3784 enum fill_status fill_status
= FILL_STATUS_FAILED
;
3787 if (!(manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
))) return FILL_STATUS_FAILED
;
3788 if (!(services
= malloc( size
))) goto done
;
3790 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3791 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3792 &count
, NULL
, NULL
);
3795 if (GetLastError() != ERROR_MORE_DATA
) goto done
;
3797 if (!(tmp
= realloc( services
, size
))) goto done
;
3799 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3800 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3801 &count
, NULL
, NULL
);
3802 if (!ret
) goto done
;
3804 if (!resize_table( table
, count
, sizeof(*rec
) )) goto done
;
3806 GetComputerNameW( sysnameW
, &len
);
3807 fill_status
= FILL_STATUS_UNFILTERED
;
3809 for (i
= 0; i
< count
; i
++)
3811 QUERY_SERVICE_CONFIGW
*config
;
3813 if (!(config
= query_service_config( manager
, services
[i
].lpServiceName
))) continue;
3815 status
= &services
[i
].ServiceStatusProcess
;
3816 rec
= (struct record_service
*)(table
->data
+ offset
);
3817 rec
->accept_pause
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_PAUSE_CONTINUE
) ? -1 : 0;
3818 rec
->accept_stop
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_STOP
) ? -1 : 0;
3819 rec
->displayname
= wcsdup( services
[i
].lpDisplayName
);
3820 rec
->name
= wcsdup( services
[i
].lpServiceName
);
3821 rec
->process_id
= status
->dwProcessId
;
3822 rec
->servicetype
= get_service_type( status
->dwServiceType
);
3823 rec
->startmode
= get_service_startmode( config
->dwStartType
);
3824 rec
->state
= get_service_state( status
->dwCurrentState
);
3825 rec
->systemname
= wcsdup( sysnameW
);
3826 rec
->pause_service
= service_pause_service
;
3827 rec
->resume_service
= service_resume_service
;
3828 rec
->start_service
= service_start_service
;
3829 rec
->stop_service
= service_stop_service
;
3831 if (!match_row( table
, row
, cond
, &fill_status
))
3833 free_row_values( table
, row
);
3836 offset
+= sizeof(*rec
);
3840 TRACE("created %u rows\n", row
);
3841 table
->num_rows
= row
;
3844 CloseServiceHandle( manager
);
3849 static WCHAR
*get_accountname( LSA_TRANSLATED_NAME
*name
)
3851 if (!name
|| !name
->Name
.Buffer
) return NULL
;
3852 return wcsdup( name
->Name
.Buffer
);
3854 static struct array
*get_binaryrepresentation( PSID sid
, UINT len
)
3859 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
3860 if (!(ptr
= malloc( len
)))
3865 memcpy( ptr
, sid
, len
);
3866 ret
->elem_size
= sizeof(*ptr
);
3871 static WCHAR
*get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST
*domain
)
3873 if (!domain
|| !domain
->Domains
|| !domain
->Domains
->Name
.Buffer
) return NULL
;
3874 return wcsdup( domain
->Domains
->Name
.Buffer
);
3876 static const WCHAR
*find_sid_str( const struct expr
*cond
)
3878 const struct expr
*left
, *right
;
3879 const WCHAR
*ret
= NULL
;
3881 if (!cond
|| cond
->type
!= EXPR_COMPLEX
|| cond
->u
.expr
.op
!= OP_EQ
) return NULL
;
3883 left
= cond
->u
.expr
.left
;
3884 right
= cond
->u
.expr
.right
;
3885 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&& !wcsicmp( left
->u
.propval
->name
, L
"SID" ))
3887 ret
= right
->u
.sval
;
3889 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&& !wcsicmp( right
->u
.propval
->name
, L
"SID" ))
3896 static enum fill_status
fill_sid( struct table
*table
, const struct expr
*cond
)
3899 LSA_REFERENCED_DOMAIN_LIST
*domain
;
3900 LSA_TRANSLATED_NAME
*name
;
3902 LSA_OBJECT_ATTRIBUTES attrs
;
3904 struct record_sid
*rec
;
3907 if (!(str
= find_sid_str( cond
))) return FILL_STATUS_FAILED
;
3908 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3910 if (!ConvertStringSidToSidW( str
, &sid
)) return FILL_STATUS_FAILED
;
3911 len
= GetLengthSid( sid
);
3913 memset( &attrs
, 0, sizeof(attrs
) );
3914 attrs
.Length
= sizeof(attrs
);
3915 if (LsaOpenPolicy( NULL
, &attrs
, POLICY_ALL_ACCESS
, &handle
))
3918 return FILL_STATUS_FAILED
;
3920 if (LsaLookupSids( handle
, 1, &sid
, &domain
, &name
))
3924 return FILL_STATUS_FAILED
;
3927 rec
= (struct record_sid
*)table
->data
;
3928 rec
->accountname
= get_accountname( name
);
3929 rec
->binaryrepresentation
= get_binaryrepresentation( sid
, len
);
3930 rec
->referenceddomainname
= get_referenceddomainname( domain
);
3931 rec
->sid
= wcsdup( str
);
3932 rec
->sidlength
= len
;
3934 TRACE("created 1 row\n");
3935 table
->num_rows
= 1;
3937 LsaFreeMemory( domain
);
3938 LsaFreeMemory( name
);
3941 return FILL_STATUS_FILTERED
;
3944 static WCHAR
*get_systemenclosure_string( BYTE id
, const char *buf
, UINT len
)
3946 const struct smbios_header
*hdr
;
3947 const struct smbios_chassis
*chassis
;
3950 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
))) return NULL
;
3952 chassis
= (const struct smbios_chassis
*)hdr
;
3953 offset
= (const char *)chassis
- buf
+ chassis
->hdr
.length
;
3954 return get_smbios_string( id
, buf
, offset
, len
);
3957 static WCHAR
*get_systemenclosure_manufacturer( const char *buf
, UINT len
)
3959 WCHAR
*ret
= get_systemenclosure_string( 1, buf
, len
);
3960 if (!ret
) return wcsdup( L
"Wine" );
3964 static int get_systemenclosure_lockpresent( const char *buf
, UINT len
)
3966 const struct smbios_header
*hdr
;
3967 const struct smbios_chassis
*chassis
;
3969 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) return 0;
3971 chassis
= (const struct smbios_chassis
*)hdr
;
3972 return (chassis
->type
& 0x80) ? -1 : 0;
3975 static struct array
*dup_array( const struct array
*src
)
3978 if (!(dst
= malloc( sizeof(*dst
) ))) return NULL
;
3979 if (!(dst
->ptr
= malloc( src
->count
* src
->elem_size
)))
3984 memcpy( dst
->ptr
, src
->ptr
, src
->count
* src
->elem_size
);
3985 dst
->elem_size
= src
->elem_size
;
3986 dst
->count
= src
->count
;
3990 static struct array
*get_systemenclosure_chassistypes( const char *buf
, UINT len
)
3992 const struct smbios_header
*hdr
;
3993 const struct smbios_chassis
*chassis
;
3994 struct array
*ret
= NULL
;
3997 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) goto done
;
3998 chassis
= (const struct smbios_chassis
*)hdr
;
4000 if (!(ret
= malloc( sizeof(*ret
) ))) goto done
;
4001 if (!(types
= malloc( sizeof(*types
) )))
4006 types
[0] = chassis
->type
& ~0x80;
4008 ret
->elem_size
= sizeof(*types
);
4013 if (!ret
) ret
= dup_array( &systemenclosure_chassistypes_array
);
4017 static enum fill_status
fill_systemenclosure( struct table
*table
, const struct expr
*cond
)
4019 struct record_systemenclosure
*rec
;
4020 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4024 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4026 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
4027 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
4028 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
4030 rec
= (struct record_systemenclosure
*)table
->data
;
4031 rec
->caption
= L
"System Enclosure";
4032 rec
->chassistypes
= get_systemenclosure_chassistypes( buf
, len
);
4033 rec
->description
= L
"System Enclosure";
4034 rec
->lockpresent
= get_systemenclosure_lockpresent( buf
, len
);
4035 rec
->manufacturer
= get_systemenclosure_manufacturer( buf
, len
);
4036 rec
->name
= L
"System Enclosure";
4037 rec
->tag
= L
"System Enclosure 0";
4038 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4043 TRACE("created %u rows\n", row
);
4044 table
->num_rows
= row
;
4048 static WCHAR
*get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
4050 static const WCHAR fmtW
[] = L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
4051 UINT len
= sizeof(fmtW
) + 2;
4054 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4055 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
4059 #define HW_VENDOR_AMD 0x1002
4060 #define HW_VENDOR_NVIDIA 0x10de
4061 #define HW_VENDOR_VMWARE 0x15ad
4062 #define HW_VENDOR_INTEL 0x8086
4064 static const WCHAR
*get_videocontroller_installeddriver( UINT vendorid
)
4066 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
4068 if (vendorid
== HW_VENDOR_AMD
) return L
"aticfx32.dll";
4069 else if (vendorid
== HW_VENDOR_NVIDIA
) return L
"nvd3dum.dll";
4070 else if (vendorid
== HW_VENDOR_INTEL
) return L
"igdudim32.dll";
4074 static BOOL
get_dxgi_adapter_desc( DXGI_ADAPTER_DESC
*desc
)
4076 IDXGIFactory
*factory
;
4077 IDXGIAdapter
*adapter
;
4080 memset( desc
, 0, sizeof(*desc
) );
4081 hr
= CreateDXGIFactory( &IID_IDXGIFactory
, (void **)&factory
);
4082 if (FAILED( hr
)) return FALSE
;
4084 hr
= IDXGIFactory_EnumAdapters( factory
, 0, &adapter
);
4087 IDXGIFactory_Release( factory
);
4091 hr
= IDXGIAdapter_GetDesc( adapter
, desc
);
4092 IDXGIAdapter_Release( adapter
);
4093 IDXGIFactory_Release( factory
);
4094 return SUCCEEDED( hr
);
4097 static enum fill_status
fill_videocontroller( struct table
*table
, const struct expr
*cond
)
4099 struct record_videocontroller
*rec
;
4100 DXGI_ADAPTER_DESC desc
;
4101 UINT row
= 0, hres
= 1024, vres
= 768, vidmem
= 512 * 1024 * 1024;
4102 const WCHAR
*name
= L
"VideoController1";
4103 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4106 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4108 if (get_dxgi_adapter_desc( &desc
))
4110 if (desc
.DedicatedVideoMemory
> UINT_MAX
) vidmem
= 0xfff00000;
4111 else vidmem
= desc
.DedicatedVideoMemory
;
4112 name
= desc
.Description
;
4115 rec
= (struct record_videocontroller
*)table
->data
;
4116 rec
->adapter_compatibility
= L
"(Standard display types)";
4117 rec
->adapter_dactype
= L
"Integrated RAMDAC";
4118 rec
->adapter_ram
= vidmem
;
4119 rec
->availability
= 3; /* Running or Full Power */
4120 rec
->config_errorcode
= 0; /* no error */
4121 rec
->caption
= wcsdup( name
);
4122 rec
->current_bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
4123 rec
->current_horizontalres
= hres
;
4124 rec
->current_refreshrate
= 0; /* default refresh rate */
4125 rec
->current_scanmode
= 2; /* Unknown */
4126 rec
->current_verticalres
= vres
;
4127 rec
->description
= wcsdup( name
);
4128 rec
->device_id
= L
"VideoController1";
4129 rec
->driverdate
= L
"20220118000000.000000-000";
4130 rec
->driverversion
= L
"30.0.14023.3004";
4131 rec
->installeddriver
= get_videocontroller_installeddriver( desc
.VendorId
);
4132 rec
->name
= wcsdup( name
);
4133 rec
->pnpdevice_id
= get_videocontroller_pnpdeviceid( &desc
);
4134 rec
->status
= L
"OK";
4135 rec
->videoarchitecture
= 2; /* Unknown */
4136 rec
->videomemorytype
= 2; /* Unknown */
4137 swprintf( mode
, ARRAY_SIZE( mode
), L
"%u x %u x %I64u colors", hres
, vres
, (UINT64
)1 << rec
->current_bitsperpixel
);
4138 rec
->videomodedescription
= wcsdup( mode
);
4139 rec
->videoprocessor
= wcsdup( name
);
4140 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4143 TRACE("created %u rows\n", row
);
4144 table
->num_rows
= row
;
4148 static WCHAR
*get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
4150 static const WCHAR fmtW
[] = L
"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
4151 UINT len
= sizeof(fmtW
) + 2;
4154 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4155 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
4159 static enum fill_status
fill_sounddevice( struct table
*table
, const struct expr
*cond
)
4161 struct record_sounddevice
*rec
;
4162 DXGI_ADAPTER_DESC desc
;
4164 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4166 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4168 get_dxgi_adapter_desc( &desc
);
4170 rec
= (struct record_sounddevice
*)table
->data
;
4171 rec
->deviceid
= get_sounddevice_pnpdeviceid( &desc
);
4172 rec
->manufacturer
= L
"The Wine Project";
4173 rec
->name
= L
"Wine Audio Device";
4174 rec
->pnpdeviceid
= get_sounddevice_pnpdeviceid( &desc
);
4175 rec
->productname
= L
"Wine Audio Device";
4176 rec
->status
= L
"OK";
4177 rec
->statusinfo
= 3;
4178 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4181 TRACE("created %u rows\n", row
);
4182 table
->num_rows
= row
;
4186 #define C(c) sizeof(c)/sizeof(c[0]), c
4187 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
4188 static struct table cimv2_builtin_classes
[] =
4190 { L
"__ASSOCIATORS", C(col_associator
), D(data_associator
) },
4191 { L
"__PARAMETERS", C(col_param
), D(data_param
) },
4192 { L
"__QUALIFIERS", C(col_qualifier
), D(data_qualifier
) },
4193 { L
"__SystemSecurity", C(col_systemsecurity
), D(data_systemsecurity
) },
4194 { L
"CIM_DataFile", C(col_datafile
), 0, 0, NULL
, fill_datafile
},
4195 { L
"CIM_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
4196 { L
"CIM_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4197 { L
"SoftwareLicensingProduct", C(col_softwarelicensingproduct
), D(data_softwarelicensingproduct
) },
4198 { L
"StdRegProv", C(col_stdregprov
), D(data_stdregprov
) },
4199 { L
"SystemRestore", C(col_sysrestore
), D(data_sysrestore
) },
4200 { L
"Win32_BIOS", C(col_bios
), 0, 0, NULL
, fill_bios
},
4201 { L
"Win32_BaseBoard", C(col_baseboard
), 0, 0, NULL
, fill_baseboard
},
4202 { L
"Win32_CDROMDrive", C(col_cdromdrive
), 0, 0, NULL
, fill_cdromdrive
},
4203 { L
"Win32_ComputerSystem", C(col_compsys
), 0, 0, NULL
, fill_compsys
},
4204 { L
"Win32_ComputerSystemProduct", C(col_compsysproduct
), 0, 0, NULL
, fill_compsysproduct
},
4205 { L
"Win32_DesktopMonitor", C(col_desktopmonitor
), 0, 0, NULL
, fill_desktopmonitor
},
4206 { L
"Win32_Directory", C(col_directory
), 0, 0, NULL
, fill_directory
},
4207 { L
"Win32_DiskDrive", C(col_diskdrive
), 0, 0, NULL
, fill_diskdrive
},
4208 { L
"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition
), 0, 0, NULL
, fill_diskdrivetodiskpartition
},
4209 { L
"Win32_DiskPartition", C(col_diskpartition
), 0, 0, NULL
, fill_diskpartition
},
4210 { L
"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig
), 0, 0, NULL
, fill_displaycontrollerconfig
},
4211 { L
"Win32_IP4RouteTable", C(col_ip4routetable
), 0, 0, NULL
, fill_ip4routetable
},
4212 { L
"Win32_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
4213 { L
"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition
), 0, 0, NULL
, fill_logicaldisktopartition
},
4214 { L
"Win32_NetworkAdapter", C(col_networkadapter
), 0, 0, NULL
, fill_networkadapter
},
4215 { L
"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig
), 0, 0, NULL
, fill_networkadapterconfig
},
4216 { L
"Win32_OperatingSystem", C(col_operatingsystem
), 0, 0, NULL
, fill_operatingsystem
},
4217 { L
"Win32_PageFileUsage", C(col_pagefileusage
), D(data_pagefileusage
) },
4218 { L
"Win32_PhysicalMedia", C(col_physicalmedia
), D(data_physicalmedia
) },
4219 { L
"Win32_PhysicalMemory", C(col_physicalmemory
), 0, 0, NULL
, fill_physicalmemory
},
4220 { L
"Win32_PnPEntity", C(col_pnpentity
), 0, 0, NULL
, fill_pnpentity
},
4221 { L
"Win32_Printer", C(col_printer
), 0, 0, NULL
, fill_printer
},
4222 { L
"Win32_Process", C(col_process
), 0, 0, NULL
, fill_process
},
4223 { L
"Win32_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4224 { L
"Win32_QuickFixEngineering", C(col_quickfixengineering
), D(data_quickfixengineering
) },
4225 { L
"Win32_SID", C(col_sid
), 0, 0, NULL
, fill_sid
},
4226 { L
"Win32_Service", C(col_service
), 0, 0, NULL
, fill_service
},
4227 { L
"Win32_SoundDevice", C(col_sounddevice
), 0, 0, NULL
, fill_sounddevice
},
4228 { L
"Win32_SystemEnclosure", C(col_systemenclosure
), 0, 0, NULL
, fill_systemenclosure
},
4229 { L
"Win32_VideoController", C(col_videocontroller
), 0, 0, NULL
, fill_videocontroller
},
4230 { L
"Win32_WinSAT", C(col_winsat
), D(data_winsat
) },
4233 static struct table wmi_builtin_classes
[] =
4235 { L
"MSSMBios_RawSMBiosTables", C(col_rawsmbiostables
), D(data_rawsmbiostables
) },
4243 struct table
*classes
;
4244 unsigned int table_count
;
4246 builtin_namespaces
[WBEMPROX_NAMESPACE_LAST
] =
4248 {L
"cimv2", cimv2_builtin_classes
, ARRAY_SIZE(cimv2_builtin_classes
)},
4249 {L
"Microsoft\\Windows\\Storage", NULL
, 0},
4250 {L
"wmi", wmi_builtin_classes
, ARRAY_SIZE(wmi_builtin_classes
)},
4253 void init_table_list( void )
4255 static struct list tables
[WBEMPROX_NAMESPACE_LAST
];
4258 for (ns
= 0; ns
< ARRAY_SIZE(builtin_namespaces
); ns
++)
4260 list_init( &tables
[ns
] );
4261 for (i
= 0; i
< builtin_namespaces
[ns
].table_count
; i
++)
4262 list_add_tail( &tables
[ns
], &builtin_namespaces
[ns
].classes
[i
].entry
);
4263 table_list
[ns
] = &tables
[ns
];
4267 enum wbm_namespace
get_namespace_from_string( const WCHAR
*namespace )
4271 if (!wcsicmp( namespace, L
"default" )) return WBEMPROX_NAMESPACE_CIMV2
;
4273 for (i
= 0; i
< WBEMPROX_NAMESPACE_LAST
; ++i
)
4274 if (!wcsicmp( namespace, builtin_namespaces
[i
].name
)) return i
;
4276 return WBEMPROX_NAMESPACE_LAST
;