2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
27 #define WIN32_NO_STATUS
50 #include "wine/debug.h"
51 #include "wbemprox_private.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox
);
55 /* column definitions must be kept in sync with record structures below */
56 static const struct column col_associator
[] =
58 { L
"AssocClass", CIM_STRING
},
59 { L
"Class", CIM_STRING
},
60 { L
"Associator", CIM_STRING
}
62 static const struct column col_baseboard
[] =
64 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
65 { L
"Model", CIM_STRING
},
66 { L
"Name", CIM_STRING
},
67 { L
"Product", CIM_STRING
|COL_FLAG_DYNAMIC
},
68 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
69 { L
"Tag", CIM_STRING
|COL_FLAG_KEY
},
70 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
72 static const struct column col_bios
[] =
74 { L
"CurrentLanguage", CIM_STRING
},
75 { L
"Description", CIM_STRING
},
76 { L
"EmbeddedControllerMajorVersion", CIM_UINT8
},
77 { L
"EmbeddedControllerMinorVersion", CIM_UINT8
},
78 { L
"IdentificationCode", CIM_STRING
},
79 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
80 { L
"Name", CIM_STRING
},
81 { L
"ReleaseDate", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
82 { L
"SerialNumber", CIM_STRING
},
83 { L
"SMBIOSBIOSVersion", CIM_STRING
|COL_FLAG_DYNAMIC
},
84 { L
"SMBIOSMajorVersion", CIM_UINT16
},
85 { L
"SMBIOSMinorVersion", CIM_UINT16
},
86 { L
"SystemBiosMajorVersion", CIM_UINT8
},
87 { L
"SystemBiosMinorVersion", CIM_UINT8
},
88 { L
"Version", CIM_STRING
|COL_FLAG_KEY
},
90 static const struct column col_cdromdrive
[] =
92 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
93 { L
"Drive", CIM_STRING
|COL_FLAG_DYNAMIC
},
94 { L
"MediaType", CIM_STRING
},
95 { L
"Name", CIM_STRING
},
96 { L
"PNPDeviceID", CIM_STRING
},
98 static const struct column col_compsys
[] =
100 { L
"Description", CIM_STRING
},
101 { L
"Domain", CIM_STRING
},
102 { L
"DomainRole", CIM_UINT16
},
103 { L
"Manufacturer", CIM_STRING
},
104 { L
"Model", CIM_STRING
},
105 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
106 { L
"NumberOfLogicalProcessors", CIM_UINT32
},
107 { L
"NumberOfProcessors", CIM_UINT32
},
108 { L
"TotalPhysicalMemory", CIM_UINT64
},
109 { L
"UserName", CIM_STRING
|COL_FLAG_DYNAMIC
},
111 static const struct column col_compsysproduct
[] =
113 { L
"IdentifyingNumber", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
114 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
115 { L
"SKUNumber", CIM_STRING
},
116 { L
"UUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
117 { L
"Vendor", CIM_STRING
|COL_FLAG_DYNAMIC
},
118 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
120 static const struct column col_datafile
[] =
122 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
123 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
125 static const struct column col_desktopmonitor
[] =
127 { L
"Name", CIM_STRING
},
128 { L
"PixelsPerXLogicalInch", CIM_UINT32
},
130 static const struct column col_directory
[] =
132 { L
"AccessMask", CIM_UINT32
},
133 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
135 static const struct column col_diskdrive
[] =
137 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
138 { L
"Index", CIM_UINT32
},
139 { L
"InterfaceType", CIM_STRING
},
140 { L
"Manufacturer", CIM_STRING
},
141 { L
"MediaType", CIM_STRING
},
142 { L
"Model", CIM_STRING
},
143 { L
"PNPDeviceID", CIM_STRING
},
144 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
145 { L
"Size", CIM_UINT64
},
147 static const struct column col_diskdrivetodiskpartition
[] =
149 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
150 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
152 static const struct column col_diskpartition
[] =
154 { L
"Bootable", CIM_BOOLEAN
},
155 { L
"BootPartition", CIM_BOOLEAN
},
156 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
157 { L
"DiskIndex", CIM_UINT32
},
158 { L
"Index", CIM_UINT32
},
159 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
160 { L
"Size", CIM_UINT64
},
161 { L
"StartingOffset", CIM_UINT64
},
162 { L
"Type", CIM_STRING
|COL_FLAG_DYNAMIC
},
164 static const struct column col_displaycontrollerconfig
[] =
166 { L
"BitsPerPixel", CIM_UINT32
},
167 { L
"Caption", CIM_STRING
},
168 { L
"HorizontalResolution", CIM_UINT32
},
169 { L
"Name", CIM_STRING
|COL_FLAG_KEY
},
170 { L
"VerticalResolution", CIM_UINT32
},
172 static const struct column col_ip4routetable
[] =
174 { L
"Destination", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
175 { L
"InterfaceIndex", CIM_SINT32
|COL_FLAG_KEY
},
176 { L
"NextHop", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
178 static const struct column col_logicaldisk
[] =
180 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
181 { L
"DriveType", CIM_UINT32
},
182 { L
"FileSystem", CIM_STRING
|COL_FLAG_DYNAMIC
},
183 { L
"FreeSpace", CIM_UINT64
},
184 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
185 { L
"Size", CIM_UINT64
},
186 { L
"VolumeName", CIM_STRING
|COL_FLAG_DYNAMIC
},
187 { L
"VolumeSerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
189 static const struct column col_logicaldisktopartition
[] =
191 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
192 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
194 static const struct column col_networkadapter
[] =
196 { L
"AdapterType", CIM_STRING
},
197 { L
"AdapterTypeID", CIM_UINT16
},
198 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
199 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
200 { L
"Index", CIM_UINT32
},
201 { L
"InterfaceIndex", CIM_UINT32
},
202 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
203 { L
"Manufacturer", CIM_STRING
},
204 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
205 { L
"NetConnectionStatus", CIM_UINT16
},
206 { L
"PhysicalAdapter", CIM_BOOLEAN
},
207 { L
"PNPDeviceID", CIM_STRING
},
208 { L
"Speed", CIM_UINT64
},
210 static const struct column col_networkadapterconfig
[] =
212 { L
"DefaultIPGateway", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
213 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
214 { L
"DHCPEnabled", CIM_BOOLEAN
},
215 { L
"DNSHostName", CIM_STRING
|COL_FLAG_DYNAMIC
},
216 { L
"DNSServerSearchOrder", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
217 { L
"Index", CIM_UINT32
|COL_FLAG_KEY
},
218 { L
"IPAddress", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
219 { L
"IPConnectionMetric", CIM_UINT32
},
220 { L
"IPEnabled", CIM_BOOLEAN
},
221 { L
"IPSubnet", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
222 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
223 { L
"SettingID", CIM_STRING
|COL_FLAG_DYNAMIC
},
225 static const struct column col_operatingsystem
[] =
227 { L
"BuildNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
228 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
229 { L
"CodeSet", CIM_STRING
|COL_FLAG_DYNAMIC
},
230 { L
"CountryCode", CIM_STRING
|COL_FLAG_DYNAMIC
},
231 { L
"CSDVersion", CIM_STRING
|COL_FLAG_DYNAMIC
},
232 { L
"CSName", CIM_STRING
|COL_FLAG_DYNAMIC
},
233 { L
"CurrentTimeZone", CIM_SINT16
},
234 { L
"FreePhysicalMemory", CIM_UINT64
},
235 { L
"InstallDate", CIM_DATETIME
},
236 { L
"LastBootUpTime", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
237 { L
"LocalDateTime", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
238 { L
"Locale", CIM_STRING
|COL_FLAG_DYNAMIC
},
239 { L
"Manufacturer", CIM_STRING
},
240 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
241 { L
"OperatingSystemSKU", CIM_UINT32
},
242 { L
"OSArchitecture", CIM_STRING
},
243 { L
"OSLanguage", CIM_UINT32
},
244 { L
"OSProductSuite", CIM_UINT32
},
245 { L
"OSType", CIM_UINT16
},
246 { L
"Primary", CIM_BOOLEAN
},
247 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
248 { L
"ServicePackMajorVersion", CIM_UINT16
},
249 { L
"ServicePackMinorVersion", CIM_UINT16
},
250 { L
"SuiteMask", CIM_UINT32
},
251 { L
"SystemDirectory", CIM_STRING
|COL_FLAG_DYNAMIC
},
252 { L
"SystemDrive", CIM_STRING
|COL_FLAG_DYNAMIC
},
253 { L
"TotalVirtualMemorySize", CIM_UINT64
},
254 { L
"TotalVisibleMemorySize", CIM_UINT64
},
255 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
257 static const struct column col_param
[] =
259 { L
"Class", CIM_STRING
},
260 { L
"Method", CIM_STRING
},
261 { L
"Direction", CIM_SINT32
},
262 { L
"Parameter", CIM_STRING
},
263 { L
"Type", CIM_UINT32
},
264 { L
"DefaultValue", CIM_UINT32
},
266 static const struct column col_physicalmedia
[] =
268 { L
"SerialNumber", CIM_STRING
},
269 { L
"Tag", CIM_STRING
},
271 static const struct column col_physicalmemory
[] =
273 { L
"BankLabel", CIM_STRING
},
274 { L
"Capacity", CIM_UINT64
},
275 { L
"Caption", CIM_STRING
},
276 { L
"ConfiguredClockSpeed", CIM_UINT32
},
277 { L
"DeviceLocator", CIM_STRING
},
278 { L
"FormFactor", CIM_UINT16
},
279 { L
"MemoryType", CIM_UINT16
},
280 { L
"PartNumber", CIM_STRING
},
281 { L
"SerialNumber", CIM_STRING
},
283 static const struct column col_pnpentity
[] =
285 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
},
287 static const struct column col_printer
[] =
289 { L
"Attributes", CIM_UINT32
},
290 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
291 { L
"DriverName", CIM_STRING
|COL_FLAG_DYNAMIC
},
292 { L
"HorizontalResolution", CIM_UINT32
},
293 { L
"Local", CIM_BOOLEAN
},
294 { L
"Location", CIM_STRING
|COL_FLAG_DYNAMIC
},
295 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
296 { L
"Network", CIM_BOOLEAN
},
297 { L
"PortName", CIM_STRING
|COL_FLAG_DYNAMIC
},
299 static const struct column col_process
[] =
301 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
302 { L
"CommandLine", CIM_STRING
|COL_FLAG_DYNAMIC
},
303 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
304 { L
"Handle", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
305 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
306 { L
"ParentProcessID", CIM_UINT32
},
307 { L
"ProcessID", CIM_UINT32
},
308 { L
"ThreadCount", CIM_UINT32
},
309 { L
"WorkingSetSize", CIM_UINT64
},
311 { L
"GetOwner", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
313 static const struct column col_processor
[] =
315 { L
"AddressWidth", CIM_UINT16
},
316 { L
"Architecture", CIM_UINT16
},
317 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
318 { L
"CpuStatus", CIM_UINT16
},
319 { L
"CurrentClockSpeed", CIM_UINT32
},
320 { L
"DataWidth", CIM_UINT16
},
321 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
322 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
323 { L
"Family", CIM_UINT16
},
324 { L
"Level", CIM_UINT16
},
325 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
326 { L
"MaxClockSpeed", CIM_UINT32
},
327 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
328 { L
"NumberOfCores", CIM_UINT32
},
329 { L
"NumberOfLogicalProcessors", CIM_UINT32
},
330 { L
"ProcessorId", CIM_STRING
|COL_FLAG_DYNAMIC
},
331 { L
"ProcessorType", CIM_UINT16
},
332 { L
"Revision", CIM_UINT16
},
333 { L
"UniqueId", CIM_STRING
},
334 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
336 static const struct column col_qualifier
[] =
338 { L
"Class", CIM_STRING
},
339 { L
"Member", CIM_STRING
},
340 { L
"Type", CIM_UINT32
},
341 { L
"Flavor", CIM_SINT32
},
342 { L
"Name", CIM_STRING
},
343 { L
"IntegerValue", CIM_SINT32
},
344 { L
"StringValue", CIM_STRING
},
345 { L
"BoolValue", CIM_BOOLEAN
},
347 static const struct column col_quickfixengineering
[] =
349 { L
"Caption", CIM_STRING
},
350 { L
"HotFixID", CIM_STRING
|COL_FLAG_KEY
},
352 static const struct column col_service
[] =
354 { L
"AcceptPause", CIM_BOOLEAN
},
355 { L
"AcceptStop", CIM_BOOLEAN
},
356 { L
"DisplayName", CIM_STRING
|COL_FLAG_DYNAMIC
},
357 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
358 { L
"ProcessID", CIM_UINT32
},
359 { L
"ServiceType", CIM_STRING
},
360 { L
"StartMode", CIM_STRING
},
361 { L
"State", CIM_STRING
},
362 { L
"SystemName", CIM_STRING
|COL_FLAG_DYNAMIC
},
364 { L
"PauseService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
365 { L
"ResumeService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
366 { L
"StartService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
367 { L
"StopService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
369 static const struct column col_sid
[] =
371 { L
"AccountName", CIM_STRING
|COL_FLAG_DYNAMIC
},
372 { L
"BinaryRepresentation", CIM_UINT8
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
373 { L
"ReferencedDomainName", CIM_STRING
|COL_FLAG_DYNAMIC
},
374 { L
"SID", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
375 { L
"SidLength", CIM_UINT32
},
377 static const struct column col_sounddevice
[] =
379 { L
"DeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
380 { L
"Manufacturer", CIM_STRING
},
381 { L
"Name", CIM_STRING
},
382 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
383 { L
"ProductName", CIM_STRING
},
384 { L
"Status", CIM_STRING
},
385 { L
"StatusInfo", CIM_UINT16
},
387 static const struct column col_stdregprov
[] =
389 { L
"CreateKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
390 { L
"EnumKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
391 { L
"EnumValues", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
392 { L
"GetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
394 static const struct column col_systemenclosure
[] =
396 { L
"Caption", CIM_STRING
},
397 { L
"ChassisTypes", CIM_UINT16
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
398 { L
"Description", CIM_STRING
},
399 { L
"LockPresent", CIM_BOOLEAN
},
400 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
401 { L
"Name", CIM_STRING
},
402 { L
"Tag", CIM_STRING
},
404 static const struct column col_systemsecurity
[] =
406 { L
"GetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
407 { L
"SetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
409 static const struct column col_videocontroller
[] =
411 { L
"AdapterCompatibility", CIM_STRING
},
412 { L
"AdapterDACType", CIM_STRING
},
413 { L
"AdapterRAM", CIM_UINT32
},
414 { L
"Availability", CIM_UINT16
},
415 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
416 { L
"ConfigManagerErrorCode", CIM_UINT32
},
417 { L
"CurrentBitsPerPixel", CIM_UINT32
},
418 { L
"CurrentHorizontalResolution", CIM_UINT32
},
419 { L
"CurrentRefreshRate", CIM_UINT32
},
420 { L
"CurrentScanMode", CIM_UINT16
},
421 { L
"CurrentVerticalResolution", CIM_UINT32
},
422 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
423 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
424 { L
"DriverDate", CIM_DATETIME
},
425 { L
"DriverVersion", CIM_STRING
},
426 { L
"InstalledDisplayDrivers", CIM_STRING
},
427 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
428 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
429 { L
"Status", CIM_STRING
},
430 { L
"VideoArchitecture", CIM_UINT16
},
431 { L
"VideoMemoryType", CIM_UINT16
},
432 { L
"VideoModeDescription", CIM_STRING
|COL_FLAG_DYNAMIC
},
433 { L
"VideoProcessor", CIM_STRING
|COL_FLAG_DYNAMIC
},
435 static const struct column col_winsat
[] =
437 { L
"CPUScore", CIM_REAL32
},
438 { L
"D3DScore", CIM_REAL32
},
439 { L
"DiskScore", CIM_REAL32
},
440 { L
"GraphicsScore", CIM_REAL32
},
441 { L
"MemoryScore", CIM_REAL32
},
442 { L
"TimeTaken", CIM_STRING
|COL_FLAG_KEY
},
443 { L
"WinSATAssessmentState", CIM_UINT32
},
444 { L
"WinSPRLevel", CIM_REAL32
},
447 #include "pshpack1.h"
448 struct record_associator
450 const WCHAR
*assocclass
;
452 const WCHAR
*associator
;
454 struct record_baseboard
456 const WCHAR
*manufacturer
;
459 const WCHAR
*product
;
460 const WCHAR
*serialnumber
;
462 const WCHAR
*version
;
466 const WCHAR
*currentlanguage
;
467 const WCHAR
*description
;
468 UINT8 ecmajorversion
;
469 UINT8 ecminorversion
;
470 const WCHAR
*identificationcode
;
471 const WCHAR
*manufacturer
;
473 const WCHAR
*releasedate
;
474 const WCHAR
*serialnumber
;
475 const WCHAR
*smbiosbiosversion
;
476 UINT16 smbiosmajorversion
;
477 UINT16 smbiosminorversion
;
478 UINT8 systembiosmajorversion
;
479 UINT8 systembiosminorversion
;
480 const WCHAR
*version
;
482 struct record_cdromdrive
484 const WCHAR
*device_id
;
486 const WCHAR
*mediatype
;
488 const WCHAR
*pnpdevice_id
;
490 struct record_computersystem
492 const WCHAR
*description
;
495 const WCHAR
*manufacturer
;
498 UINT32 num_logical_processors
;
499 UINT32 num_processors
;
500 UINT64 total_physical_memory
;
501 const WCHAR
*username
;
503 struct record_computersystemproduct
505 const WCHAR
*identifyingnumber
;
507 const WCHAR
*skunumber
;
510 const WCHAR
*version
;
512 struct record_datafile
515 const WCHAR
*version
;
517 struct record_desktopmonitor
520 UINT32 pixelsperxlogicalinch
;
522 struct record_directory
527 struct record_diskdrive
529 const WCHAR
*device_id
;
531 const WCHAR
*interfacetype
;
532 const WCHAR
*manufacturer
;
533 const WCHAR
*mediatype
;
535 const WCHAR
*pnpdevice_id
;
536 const WCHAR
*serialnumber
;
539 struct record_diskdrivetodiskpartition
541 const WCHAR
*antecedent
;
542 const WCHAR
*dependent
;
544 struct record_diskpartition
548 const WCHAR
*device_id
;
551 const WCHAR
*pnpdevice_id
;
553 UINT64 startingoffset
;
556 struct record_displaycontrollerconfig
559 const WCHAR
*caption
;
560 UINT32 horizontalresolution
;
562 UINT32 verticalresolution
;
564 struct record_ip4routetable
566 const WCHAR
*destination
;
567 INT32 interfaceindex
;
568 const WCHAR
*nexthop
;
570 struct record_logicaldisk
572 const WCHAR
*device_id
;
574 const WCHAR
*filesystem
;
578 const WCHAR
*volumename
;
579 const WCHAR
*volumeserialnumber
;
581 struct record_logicaldisktopartition
583 const WCHAR
*antecedent
;
584 const WCHAR
*dependent
;
586 struct record_networkadapter
588 const WCHAR
*adaptertype
;
589 UINT16 adaptertypeid
;
590 const WCHAR
*description
;
591 const WCHAR
*device_id
;
593 UINT32 interface_index
;
594 const WCHAR
*mac_address
;
595 const WCHAR
*manufacturer
;
597 UINT16 netconnection_status
;
599 const WCHAR
*pnpdevice_id
;
602 struct record_networkadapterconfig
604 const struct array
*defaultipgateway
;
605 const WCHAR
*description
;
607 const WCHAR
*dnshostname
;
608 const struct array
*dnsserversearchorder
;
610 const struct array
*ipaddress
;
611 UINT32 ipconnectionmetric
;
613 const struct array
*ipsubnet
;
614 const WCHAR
*mac_address
;
615 const WCHAR
*settingid
;
617 struct record_operatingsystem
619 const WCHAR
*buildnumber
;
620 const WCHAR
*caption
;
621 const WCHAR
*codeset
;
622 const WCHAR
*countrycode
;
623 const WCHAR
*csdversion
;
625 INT16 currenttimezone
;
626 UINT64 freephysicalmemory
;
627 const WCHAR
*installdate
;
628 const WCHAR
*lastbootuptime
;
629 const WCHAR
*localdatetime
;
631 const WCHAR
*manufacturer
;
633 UINT32 operatingsystemsku
;
634 const WCHAR
*osarchitecture
;
636 UINT32 osproductsuite
;
639 const WCHAR
*serialnumber
;
640 UINT16 servicepackmajor
;
641 UINT16 servicepackminor
;
643 const WCHAR
*systemdirectory
;
644 const WCHAR
*systemdrive
;
645 UINT64 totalvirtualmemorysize
;
646 UINT64 totalvisiblememorysize
;
647 const WCHAR
*version
;
654 const WCHAR
*parameter
;
658 struct record_physicalmedia
660 const WCHAR
*serialnumber
;
663 struct record_physicalmemory
665 const WCHAR
*banklabel
;
667 const WCHAR
*caption
;
668 UINT32 configuredclockspeed
;
669 const WCHAR
*devicelocator
;
672 const WCHAR
*partnumber
;
675 struct record_pnpentity
677 const WCHAR
*device_id
;
679 struct record_printer
682 const WCHAR
*device_id
;
683 const WCHAR
*drivername
;
684 UINT32 horizontalresolution
;
686 const WCHAR
*location
;
689 const WCHAR
*portname
;
691 struct record_process
693 const WCHAR
*caption
;
694 const WCHAR
*commandline
;
695 const WCHAR
*description
;
701 UINT64 workingsetsize
;
703 class_method
*get_owner
;
705 struct record_processor
709 const WCHAR
*caption
;
711 UINT32 currentclockspeed
;
713 const WCHAR
*description
;
714 const WCHAR
*device_id
;
717 const WCHAR
*manufacturer
;
718 UINT32 maxclockspeed
;
721 UINT32 num_logical_processors
;
722 const WCHAR
*processor_id
;
723 UINT16 processortype
;
725 const WCHAR
*unique_id
;
726 const WCHAR
*version
;
728 struct record_qualifier
736 const WCHAR
*strvalue
;
739 struct record_quickfixengineering
741 const WCHAR
*caption
;
742 const WCHAR
*hotfixid
;
744 struct record_service
748 const WCHAR
*displayname
;
751 const WCHAR
*servicetype
;
752 const WCHAR
*startmode
;
754 const WCHAR
*systemname
;
756 class_method
*pause_service
;
757 class_method
*resume_service
;
758 class_method
*start_service
;
759 class_method
*stop_service
;
763 const WCHAR
*accountname
;
764 const struct array
*binaryrepresentation
;
765 const WCHAR
*referenceddomainname
;
769 struct record_sounddevice
771 const WCHAR
*deviceid
;
772 const WCHAR
*manufacturer
;
774 const WCHAR
*pnpdeviceid
;
775 const WCHAR
*productname
;
779 struct record_stdregprov
781 class_method
*createkey
;
782 class_method
*enumkey
;
783 class_method
*enumvalues
;
784 class_method
*getstringvalue
;
786 struct record_systemsecurity
791 struct record_systemenclosure
793 const WCHAR
*caption
;
794 const struct array
*chassistypes
;
795 const WCHAR
*description
;
797 const WCHAR
*manufacturer
;
801 struct record_videocontroller
803 const WCHAR
*adapter_compatibility
;
804 const WCHAR
*adapter_dactype
;
807 const WCHAR
*caption
;
808 UINT32 config_errorcode
;
809 UINT32 current_bitsperpixel
;
810 UINT32 current_horizontalres
;
811 UINT32 current_refreshrate
;
812 UINT16 current_scanmode
;
813 UINT32 current_verticalres
;
814 const WCHAR
*description
;
815 const WCHAR
*device_id
;
816 const WCHAR
*driverdate
;
817 const WCHAR
*driverversion
;
818 const WCHAR
*installeddriver
;
820 const WCHAR
*pnpdevice_id
;
822 UINT16 videoarchitecture
;
823 UINT16 videomemorytype
;
824 const WCHAR
*videomodedescription
;
825 const WCHAR
*videoprocessor
;
834 const WCHAR
*timetaken
;
835 UINT32 winsatassessmentstate
;
840 static const struct record_associator data_associator
[] =
842 { L
"Win32_DiskDriveToDiskPartition", L
"Win32_DiskPartition", L
"Win32_DiskDrive" },
843 { L
"Win32_LogicalDiskToPartition", L
"Win32_LogicalDisk", L
"Win32_DiskPartition" },
845 static const struct record_param data_param
[] =
847 { L
"__SystemSecurity", L
"GetSD", -1, L
"ReturnValue", CIM_UINT32
},
848 { L
"__SystemSecurity", L
"GetSD", -1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
849 { L
"__SystemSecurity", L
"SetSD", 1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
850 { L
"__SystemSecurity", L
"SetSD", -1, L
"ReturnValue", CIM_UINT32
},
851 { L
"StdRegProv", L
"CreateKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
852 { L
"StdRegProv", L
"CreateKey", 1, L
"sSubKeyName", CIM_STRING
},
853 { L
"StdRegProv", L
"CreateKey", -1, L
"ReturnValue", CIM_UINT32
},
854 { L
"StdRegProv", L
"EnumKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
855 { L
"StdRegProv", L
"EnumKey", 1, L
"sSubKeyName", CIM_STRING
},
856 { L
"StdRegProv", L
"EnumKey", -1, L
"ReturnValue", CIM_UINT32
},
857 { L
"StdRegProv", L
"EnumKey", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
858 { L
"StdRegProv", L
"EnumValues", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
859 { L
"StdRegProv", L
"EnumValues", 1, L
"sSubKeyName", CIM_STRING
},
860 { L
"StdRegProv", L
"EnumValues", -1, L
"ReturnValue", CIM_UINT32
},
861 { L
"StdRegProv", L
"EnumValues", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
862 { L
"StdRegProv", L
"EnumValues", -1, L
"Types", CIM_SINT32
|CIM_FLAG_ARRAY
},
863 { L
"StdRegProv", L
"GetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
864 { L
"StdRegProv", L
"GetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
865 { L
"StdRegProv", L
"GetStringValue", 1, L
"sValueName", CIM_STRING
},
866 { L
"StdRegProv", L
"GetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
867 { L
"StdRegProv", L
"GetStringValue", -1, L
"sValue", CIM_STRING
},
868 { L
"Win32_Process", L
"GetOwner", -1, L
"ReturnValue", CIM_UINT32
},
869 { L
"Win32_Process", L
"GetOwner", -1, L
"User", CIM_STRING
},
870 { L
"Win32_Process", L
"GetOwner", -1, L
"Domain", CIM_STRING
},
871 { L
"Win32_Service", L
"PauseService", -1, L
"ReturnValue", CIM_UINT32
},
872 { L
"Win32_Service", L
"ResumeService", -1, L
"ReturnValue", CIM_UINT32
},
873 { L
"Win32_Service", L
"StartService", -1, L
"ReturnValue", CIM_UINT32
},
874 { L
"Win32_Service", L
"StopService", -1, L
"ReturnValue", CIM_UINT32
},
877 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
878 WBEM_FLAVOR_ORIGIN_PROPAGATED)
880 static const struct record_physicalmedia data_physicalmedia
[] =
882 { L
"WINEHDISK", L
"\\\\.\\PHYSICALDRIVE0" }
884 static const struct record_qualifier data_qualifier
[] =
886 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"User", CIM_SINT32
, FLAVOR_ID
, L
"ID", 0 },
887 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"Domain", CIM_SINT32
, FLAVOR_ID
, L
"ID", 1 }
889 static const struct record_quickfixengineering data_quickfixengineering
[] =
891 { L
"http://winehq.org", L
"KB1234567" },
894 static const struct record_stdregprov data_stdregprov
[] =
896 { reg_create_key
, reg_enum_key
, reg_enum_values
, reg_get_stringvalue
}
898 static UINT16 systemenclosure_chassistypes
[] =
902 static const struct array systemenclosure_chassistypes_array
=
904 sizeof(*systemenclosure_chassistypes
),
905 ARRAY_SIZE(systemenclosure_chassistypes
),
906 &systemenclosure_chassistypes
908 static const struct record_systemsecurity data_systemsecurity
[] =
910 { security_get_sd
, security_set_sd
}
912 static const struct record_winsat data_winsat
[] =
914 { 8.0f
, 8.0f
, 8.0f
, 8.0f
, 8.0f
, L
"MostRecentAssessment", 1 /* Valid */, 8.0f
},
917 /* check if row matches condition and update status */
918 static BOOL
match_row( const struct table
*table
, UINT row
, const struct expr
*cond
, enum fill_status
*status
)
925 *status
= FILL_STATUS_UNFILTERED
;
928 if (eval_cond( table
, row
, cond
, &val
, &type
) != S_OK
)
930 *status
= FILL_STATUS_FAILED
;
933 *status
= FILL_STATUS_FILTERED
;
937 static BOOL
resize_table( struct table
*table
, UINT row_count
, UINT row_size
)
939 if (!table
->num_rows_allocated
)
941 if (!(table
->data
= heap_alloc( row_count
* row_size
))) return FALSE
;
942 table
->num_rows_allocated
= row_count
;
945 if (row_count
> table
->num_rows_allocated
)
948 UINT count
= max( row_count
, table
->num_rows_allocated
* 2 );
949 if (!(data
= heap_realloc( table
->data
, count
* row_size
))) return FALSE
;
951 table
->num_rows_allocated
= count
;
956 #include "pshpack1.h"
957 struct smbios_prologue
970 SMBIOS_TYPE_BASEBOARD
,
981 struct smbios_baseboard
983 struct smbios_header hdr
;
992 struct smbios_header hdr
;
998 UINT64 characteristics
;
999 BYTE characteristics_ext
[2];
1000 BYTE system_bios_major_release
;
1001 BYTE system_bios_minor_release
;
1002 BYTE ec_firmware_major_release
;
1003 BYTE ec_firmware_minor_release
;
1006 struct smbios_chassis
1008 struct smbios_header hdr
;
1016 struct smbios_system
1018 struct smbios_header hdr
;
1025 #include "poppack.h"
1027 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1029 static const struct smbios_header
*find_smbios_entry( enum smbios_type type
, const char *buf
, UINT len
)
1031 const char *ptr
, *start
;
1032 const struct smbios_prologue
*prologue
;
1033 const struct smbios_header
*hdr
;
1035 if (len
< sizeof(struct smbios_prologue
)) return NULL
;
1036 prologue
= (const struct smbios_prologue
*)buf
;
1037 if (prologue
->length
> len
- sizeof(*prologue
) || prologue
->length
< sizeof(*hdr
)) return NULL
;
1039 start
= (const char *)(prologue
+ 1);
1040 hdr
= (const struct smbios_header
*)start
;
1044 if ((const char *)hdr
- start
>= prologue
->length
- sizeof(*hdr
)) return NULL
;
1048 WARN( "invalid entry\n" );
1052 if (hdr
->type
== type
)
1054 if ((const char *)hdr
- start
+ hdr
->length
> prologue
->length
) return NULL
;
1057 else /* skip other entries and their strings */
1059 for (ptr
= (const char *)hdr
+ hdr
->length
; ptr
- buf
< len
&& *ptr
; ptr
++)
1061 for (; ptr
- buf
< len
; ptr
++) if (!*ptr
) break;
1063 if (ptr
== (const char *)hdr
+ hdr
->length
) ptr
++;
1064 hdr
= (const struct smbios_header
*)(ptr
+ 1);
1071 static WCHAR
*get_smbios_string( BYTE id
, const char *buf
, UINT offset
, UINT buflen
)
1073 const char *ptr
= buf
+ offset
;
1076 if (!id
|| offset
>= buflen
) return NULL
;
1077 for (ptr
= buf
+ offset
; ptr
- buf
< buflen
&& *ptr
; ptr
++)
1079 if (++i
== id
) return heap_strdupAW( ptr
);
1080 for (; ptr
- buf
< buflen
; ptr
++) if (!*ptr
) break;
1085 static WCHAR
*get_baseboard_string( BYTE id
, const char *buf
, UINT len
)
1087 const struct smbios_header
*hdr
;
1088 const struct smbios_baseboard
*baseboard
;
1091 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BASEBOARD
, buf
, len
))) return NULL
;
1093 baseboard
= (const struct smbios_baseboard
*)hdr
;
1094 offset
= (const char *)baseboard
- buf
+ baseboard
->hdr
.length
;
1095 return get_smbios_string( id
, buf
, offset
, len
);
1098 static WCHAR
*get_baseboard_manufacturer( const char *buf
, UINT len
)
1100 WCHAR
*ret
= get_baseboard_string( 1, buf
, len
);
1101 if (!ret
) return heap_strdupW( L
"Intel Corporation" );
1105 static WCHAR
*get_baseboard_product( const char *buf
, UINT len
)
1107 WCHAR
*ret
= get_baseboard_string( 2, buf
, len
);
1108 if (!ret
) return heap_strdupW( L
"Base Board" );
1112 static WCHAR
*get_baseboard_serialnumber( const char *buf
, UINT len
)
1114 WCHAR
*ret
= get_baseboard_string( 4, buf
, len
);
1115 if (!ret
) return heap_strdupW( L
"None" );
1119 static WCHAR
*get_baseboard_version( const char *buf
, UINT len
)
1121 WCHAR
*ret
= get_baseboard_string( 3, buf
, len
);
1122 if (!ret
) return heap_strdupW( L
"1.0" );
1126 static enum fill_status
fill_baseboard( struct table
*table
, const struct expr
*cond
)
1128 struct record_baseboard
*rec
;
1129 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1133 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1135 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1136 if (!(buf
= heap_alloc( len
))) return FILL_STATUS_FAILED
;
1137 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1139 rec
= (struct record_baseboard
*)table
->data
;
1140 rec
->manufacturer
= get_baseboard_manufacturer( buf
, len
);
1141 rec
->model
= L
"Base Board";
1142 rec
->name
= L
"Base Board";
1143 rec
->product
= get_baseboard_product( buf
, len
);
1144 rec
->serialnumber
= get_baseboard_serialnumber( buf
, len
);
1145 rec
->tag
= L
"Base Board";
1146 rec
->version
= get_baseboard_version( buf
, len
);
1147 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1152 TRACE("created %u rows\n", row
);
1153 table
->num_rows
= row
;
1157 static UINT16
get_bios_smbiosmajorversion( const char *buf
, UINT len
)
1159 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1160 if (len
< sizeof(*prologue
)) return 2;
1161 return prologue
->major_version
;
1164 static UINT16
get_bios_smbiosminorversion( const char *buf
, UINT len
)
1166 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1167 if (len
< sizeof(*prologue
)) return 0;
1168 return prologue
->minor_version
;
1171 static WCHAR
*get_bios_string( BYTE id
, const char *buf
, UINT len
)
1173 const struct smbios_header
*hdr
;
1174 const struct smbios_bios
*bios
;
1177 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return NULL
;
1179 bios
= (const struct smbios_bios
*)hdr
;
1180 offset
= (const char *)bios
- buf
+ bios
->hdr
.length
;
1181 return get_smbios_string( id
, buf
, offset
, len
);
1184 static WCHAR
*get_bios_manufacturer( const char *buf
, UINT len
)
1186 WCHAR
*ret
= get_bios_string( 1, buf
, len
);
1187 if (!ret
) return heap_strdupW( L
"The Wine Project" );
1191 static WCHAR
*convert_bios_date( const WCHAR
*str
)
1193 static const WCHAR fmtW
[] = L
"%04u%02u%02u000000.000000+000";
1194 UINT year
, month
, day
, len
= lstrlenW( str
);
1195 const WCHAR
*p
= str
, *q
;
1198 while (len
&& iswspace( *p
)) { p
++; len
--; }
1199 while (len
&& iswspace( p
[len
- 1] )) { len
--; }
1202 while (len
&& is_digit( *q
)) { q
++; len
--; };
1203 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1204 month
= (p
[0] - '0') * 10 + p
[1] - '0';
1207 while (len
&& is_digit( *q
)) { q
++; len
--; };
1208 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1209 day
= (p
[0] - '0') * 10 + p
[1] - '0';
1212 while (len
&& is_digit( *q
)) { q
++; len
--; };
1213 if (q
- p
== 4) year
= (p
[0] - '0') * 1000 + (p
[1] - '0') * 100 + (p
[2] - '0') * 10 + p
[3] - '0';
1214 else if (q
- p
== 2) year
= 1900 + (p
[0] - '0') * 10 + p
[1] - '0';
1217 if (!(ret
= heap_alloc( sizeof(fmtW
) ))) return NULL
;
1218 swprintf( ret
, ARRAY_SIZE(fmtW
), fmtW
, year
, month
, day
);
1222 static WCHAR
*get_bios_releasedate( const char *buf
, UINT len
)
1224 WCHAR
*ret
, *date
= get_bios_string( 3, buf
, len
);
1225 if (!date
|| !(ret
= convert_bios_date( date
))) ret
= heap_strdupW( L
"20120608000000.000000+000" );
1230 static WCHAR
*get_bios_smbiosbiosversion( const char *buf
, UINT len
)
1232 WCHAR
*ret
= get_bios_string( 2, buf
, len
);
1233 if (!ret
) return heap_strdupW( L
"Wine" );
1237 static BYTE
get_bios_ec_firmware_major_release( const char *buf
, UINT len
)
1239 const struct smbios_header
*hdr
;
1240 const struct smbios_bios
*bios
;
1242 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1244 bios
= (const struct smbios_bios
*)hdr
;
1245 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_major_release
;
1249 static BYTE
get_bios_ec_firmware_minor_release( const char *buf
, UINT len
)
1251 const struct smbios_header
*hdr
;
1252 const struct smbios_bios
*bios
;
1254 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1256 bios
= (const struct smbios_bios
*)hdr
;
1257 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_minor_release
;
1261 static BYTE
get_bios_system_bios_major_release( const char *buf
, UINT len
)
1263 const struct smbios_header
*hdr
;
1264 const struct smbios_bios
*bios
;
1266 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1268 bios
= (const struct smbios_bios
*)hdr
;
1269 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_major_release
;
1273 static BYTE
get_bios_system_bios_minor_release( const char *buf
, UINT len
)
1275 const struct smbios_header
*hdr
;
1276 const struct smbios_bios
*bios
;
1278 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1280 bios
= (const struct smbios_bios
*)hdr
;
1281 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_minor_release
;
1285 static enum fill_status
fill_bios( struct table
*table
, const struct expr
*cond
)
1287 struct record_bios
*rec
;
1288 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1292 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1294 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1295 if (!(buf
= heap_alloc( len
))) return FILL_STATUS_FAILED
;
1296 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1298 rec
= (struct record_bios
*)table
->data
;
1299 rec
->currentlanguage
= NULL
;
1300 rec
->description
= L
"Default System BIOS";
1301 rec
->ecmajorversion
= get_bios_ec_firmware_major_release( buf
, len
);
1302 rec
->ecminorversion
= get_bios_ec_firmware_minor_release( buf
, len
);
1303 rec
->identificationcode
= NULL
;
1304 rec
->manufacturer
= get_bios_manufacturer( buf
, len
);
1305 rec
->name
= L
"Default System BIOS";
1306 rec
->releasedate
= get_bios_releasedate( buf
, len
);
1307 rec
->serialnumber
= L
"0";
1308 rec
->smbiosbiosversion
= get_bios_smbiosbiosversion( buf
, len
);
1309 rec
->smbiosmajorversion
= get_bios_smbiosmajorversion( buf
, len
);
1310 rec
->smbiosminorversion
= get_bios_smbiosminorversion( buf
, len
);
1311 rec
->systembiosmajorversion
= get_bios_system_bios_major_release( buf
, len
);
1312 rec
->systembiosminorversion
= get_bios_system_bios_minor_release( buf
, len
);
1313 rec
->version
= L
"WINE - 1";
1314 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1319 TRACE("created %u rows\n", row
);
1320 table
->num_rows
= row
;
1324 static enum fill_status
fill_cdromdrive( struct table
*table
, const struct expr
*cond
)
1326 WCHAR drive
[3], root
[] = L
"A:\\";
1327 struct record_cdromdrive
*rec
;
1328 UINT i
, row
= 0, offset
= 0;
1329 DWORD drives
= GetLogicalDrives();
1330 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1332 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1334 for (i
= 0; i
< 26; i
++)
1336 if (drives
& (1 << i
))
1339 if (GetDriveTypeW( root
) != DRIVE_CDROM
)
1342 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1344 rec
= (struct record_cdromdrive
*)(table
->data
+ offset
);
1345 rec
->device_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1346 swprintf( drive
, ARRAY_SIZE( drive
), L
"%c:", 'A' + i
);
1347 rec
->drive
= heap_strdupW( drive
);
1348 rec
->mediatype
= L
"CR-ROM";
1349 rec
->name
= L
"Wine CD_ROM ATA Device";
1350 rec
->pnpdevice_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1351 if (!match_row( table
, row
, cond
, &status
))
1353 free_row_values( table
, row
);
1356 offset
+= sizeof(*rec
);
1360 TRACE("created %u rows\n", row
);
1361 table
->num_rows
= row
;
1365 static UINT
get_processor_count(void)
1367 SYSTEM_BASIC_INFORMATION info
;
1369 if (NtQuerySystemInformation( SystemBasicInformation
, &info
, sizeof(info
), NULL
)) return 1;
1370 return info
.NumberOfProcessors
;
1373 static UINT
get_logical_processor_count( UINT
*num_physical
, UINT
*num_packages
)
1375 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*buf
, *entry
;
1376 UINT core_relation_count
= 0, package_relation_count
= 0;
1378 ULONG len
, offset
= 0;
1379 BOOL smt_enabled
= FALSE
;
1380 DWORD all
= RelationAll
;
1382 if (num_packages
) *num_packages
= 1;
1383 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), NULL
, 0, &len
);
1384 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) return get_processor_count();
1386 if (!(buf
= heap_alloc( len
))) return get_processor_count();
1387 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), buf
, len
, NULL
);
1388 if (status
!= STATUS_SUCCESS
)
1391 return get_processor_count();
1394 while (offset
< len
)
1396 entry
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*)((char *)buf
+ offset
);
1398 if (entry
->Relationship
== RelationProcessorCore
)
1400 core_relation_count
++;
1401 if (entry
->u
.Processor
.Flags
& LTP_PC_SMT
) smt_enabled
= TRUE
;
1403 else if (entry
->Relationship
== RelationProcessorPackage
)
1405 package_relation_count
++;
1407 offset
+= entry
->Size
;
1411 if (num_physical
) *num_physical
= core_relation_count
;
1412 if (num_packages
) *num_packages
= package_relation_count
;
1413 return smt_enabled
? core_relation_count
* 2 : core_relation_count
;
1416 static UINT64
get_total_physical_memory(void)
1418 MEMORYSTATUSEX status
;
1420 status
.dwLength
= sizeof(status
);
1421 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1422 return status
.ullTotalPhys
;
1425 static UINT64
get_available_physical_memory(void)
1427 MEMORYSTATUSEX status
;
1429 status
.dwLength
= sizeof(status
);
1430 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1431 return status
.ullAvailPhys
;
1434 static WCHAR
*get_computername(void)
1437 DWORD size
= MAX_COMPUTERNAME_LENGTH
+ 1;
1439 if (!(ret
= heap_alloc( size
* sizeof(WCHAR
) ))) return NULL
;
1440 GetComputerNameW( ret
, &size
);
1444 static WCHAR
*get_username(void)
1447 DWORD compsize
, usersize
;
1451 GetComputerNameW( NULL
, &compsize
);
1453 GetUserNameW( NULL
, &usersize
);
1454 size
= compsize
+ usersize
; /* two null terminators account for the \ */
1455 if (!(ret
= heap_alloc( size
* sizeof(WCHAR
) ))) return NULL
;
1456 GetComputerNameW( ret
, &compsize
);
1457 ret
[compsize
] = '\\';
1458 GetUserNameW( ret
+ compsize
+ 1, &usersize
);
1462 static enum fill_status
fill_compsys( struct table
*table
, const struct expr
*cond
)
1464 struct record_computersystem
*rec
;
1465 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1468 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1470 rec
= (struct record_computersystem
*)table
->data
;
1471 rec
->description
= L
"AT/AT COMPATIBLE";
1472 rec
->domain
= L
"WORKGROUP";
1473 rec
->domainrole
= 0; /* standalone workstation */
1474 rec
->manufacturer
= L
"The Wine Project";
1475 rec
->model
= L
"Wine";
1476 rec
->name
= get_computername();
1477 rec
->num_logical_processors
= get_logical_processor_count( NULL
, &rec
->num_processors
);
1478 rec
->total_physical_memory
= get_total_physical_memory();
1479 rec
->username
= get_username();
1480 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1483 TRACE("created %u rows\n", row
);
1484 table
->num_rows
= row
;
1488 static WCHAR
*get_compsysproduct_string( BYTE id
, const char *buf
, UINT len
)
1490 const struct smbios_header
*hdr
;
1491 const struct smbios_system
*system
;
1494 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
))) return NULL
;
1496 system
= (const struct smbios_system
*)hdr
;
1497 offset
= (const char *)system
- buf
+ system
->hdr
.length
;
1498 return get_smbios_string( id
, buf
, offset
, len
);
1501 static WCHAR
*get_compsysproduct_identifyingnumber( const char *buf
, UINT len
)
1503 WCHAR
*ret
= get_compsysproduct_string( 4, buf
, len
);
1504 if (!ret
) return heap_strdupW( L
"0" );
1508 static WCHAR
*get_compsysproduct_name( const char *buf
, UINT len
)
1510 WCHAR
*ret
= get_compsysproduct_string( 2, buf
, len
);
1511 if (!ret
) return heap_strdupW( L
"Wine" );
1515 static WCHAR
*get_compsysproduct_uuid( const char *buf
, UINT len
)
1517 static const BYTE none
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1518 const struct smbios_header
*hdr
;
1519 const struct smbios_system
*system
;
1523 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
)) || hdr
->length
< sizeof(*system
)) goto done
;
1524 system
= (const struct smbios_system
*)hdr
;
1525 if (!memcmp( system
->uuid
, none
, sizeof(none
) ) || !(ret
= heap_alloc( 37 * sizeof(WCHAR
) ))) goto done
;
1528 swprintf( ret
, 37, L
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr
[0], ptr
[1],
1529 ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7], ptr
[8], ptr
[9], ptr
[10], ptr
[11], ptr
[12], ptr
[13],
1532 if (!ret
) ret
= heap_strdupW( L
"deaddead-dead-dead-dead-deaddeaddead" );
1536 static WCHAR
*get_compsysproduct_vendor( const char *buf
, UINT len
)
1538 WCHAR
*ret
= get_compsysproduct_string( 1, buf
, len
);
1539 if (!ret
) return heap_strdupW( L
"The Wine Project" );
1543 static WCHAR
*get_compsysproduct_version( const char *buf
, UINT len
)
1545 WCHAR
*ret
= get_compsysproduct_string( 3, buf
, len
);
1546 if (!ret
) return heap_strdupW( L
"1.0" );
1550 static enum fill_status
fill_compsysproduct( struct table
*table
, const struct expr
*cond
)
1552 struct record_computersystemproduct
*rec
;
1553 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1557 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1559 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1560 if (!(buf
= heap_alloc( len
))) return FILL_STATUS_FAILED
;
1561 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1563 rec
= (struct record_computersystemproduct
*)table
->data
;
1564 rec
->identifyingnumber
= get_compsysproduct_identifyingnumber( buf
, len
);
1565 rec
->name
= get_compsysproduct_name( buf
, len
);
1566 rec
->skunumber
= NULL
;
1567 rec
->uuid
= get_compsysproduct_uuid( buf
, len
);
1568 rec
->vendor
= get_compsysproduct_vendor( buf
, len
);
1569 rec
->version
= get_compsysproduct_version( buf
, len
);
1570 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1575 TRACE("created %u rows\n", row
);
1576 table
->num_rows
= row
;
1588 static struct dirstack
*alloc_dirstack( UINT size
)
1590 struct dirstack
*dirstack
;
1592 if (!(dirstack
= heap_alloc( sizeof(*dirstack
) ))) return NULL
;
1593 if (!(dirstack
->dirs
= heap_alloc( sizeof(WCHAR
*) * size
)))
1595 heap_free( dirstack
);
1598 if (!(dirstack
->len_dirs
= heap_alloc( sizeof(UINT
) * size
)))
1600 heap_free( dirstack
->dirs
);
1601 heap_free( dirstack
);
1604 dirstack
->num_dirs
= 0;
1605 dirstack
->num_allocated
= size
;
1609 static void clear_dirstack( struct dirstack
*dirstack
)
1612 for (i
= 0; i
< dirstack
->num_dirs
; i
++) heap_free( dirstack
->dirs
[i
] );
1613 dirstack
->num_dirs
= 0;
1616 static void free_dirstack( struct dirstack
*dirstack
)
1618 clear_dirstack( dirstack
);
1619 heap_free( dirstack
->dirs
);
1620 heap_free( dirstack
->len_dirs
);
1621 heap_free( dirstack
);
1624 static BOOL
push_dir( struct dirstack
*dirstack
, WCHAR
*dir
, UINT len
)
1626 UINT size
, i
= dirstack
->num_dirs
;
1628 if (!dir
) return FALSE
;
1630 if (i
== dirstack
->num_allocated
)
1635 size
= dirstack
->num_allocated
* 2;
1636 if (!(tmp
= heap_realloc( dirstack
->dirs
, size
* sizeof(WCHAR
*) ))) return FALSE
;
1637 dirstack
->dirs
= tmp
;
1638 if (!(len_tmp
= heap_realloc( dirstack
->len_dirs
, size
* sizeof(UINT
) ))) return FALSE
;
1639 dirstack
->len_dirs
= len_tmp
;
1640 dirstack
->num_allocated
= size
;
1642 dirstack
->dirs
[i
] = dir
;
1643 dirstack
->len_dirs
[i
] = len
;
1644 dirstack
->num_dirs
++;
1648 static WCHAR
*pop_dir( struct dirstack
*dirstack
, UINT
*len
)
1650 if (!dirstack
->num_dirs
)
1655 dirstack
->num_dirs
--;
1656 *len
= dirstack
->len_dirs
[dirstack
->num_dirs
];
1657 return dirstack
->dirs
[dirstack
->num_dirs
];
1660 static const WCHAR
*peek_dir( struct dirstack
*dirstack
)
1662 if (!dirstack
->num_dirs
) return NULL
;
1663 return dirstack
->dirs
[dirstack
->num_dirs
- 1];
1666 static WCHAR
*build_glob( WCHAR drive
, const WCHAR
*path
, UINT len
)
1671 if (!(ret
= heap_alloc( (len
+ 6) * sizeof(WCHAR
) ))) return NULL
;
1677 memcpy( ret
+ i
, path
, len
* sizeof(WCHAR
) );
1686 static WCHAR
*build_name( WCHAR drive
, const WCHAR
*path
)
1688 UINT i
= 0, len
= 0;
1692 for (p
= path
; *p
; p
++)
1694 if (*p
== '\\') len
+= 2;
1697 if (!(ret
= heap_alloc( (len
+ 5) * sizeof(WCHAR
) ))) return NULL
;
1702 for (p
= path
; *p
; p
++)
1704 if (*p
!= '\\') ret
[i
++] = *p
;
1715 static WCHAR
*build_dirname( const WCHAR
*path
, UINT
*ret_len
)
1717 const WCHAR
*p
= path
, *start
;
1721 if (!iswalpha( p
[0] ) || p
[1] != ':' || p
[2] != '\\' || p
[3] != '\\' || !p
[4]) return NULL
;
1723 len
= lstrlenW( start
);
1724 p
= start
+ len
- 1;
1725 if (*p
== '\\') return NULL
;
1727 while (p
>= start
&& *p
!= '\\') { len
--; p
--; };
1728 while (p
>= start
&& *p
== '\\') { len
--; p
--; };
1730 if (!(ret
= heap_alloc( (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1731 for (i
= 0, p
= start
; p
< start
+ len
; p
++)
1733 if (p
[0] == '\\' && p
[1] == '\\')
1745 static BOOL
seen_dir( struct dirstack
*dirstack
, const WCHAR
*path
)
1748 for (i
= 0; i
< dirstack
->num_dirs
; i
++) if (!wcscmp( dirstack
->dirs
[i
], path
)) return TRUE
;
1752 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1753 static UINT
seed_dirs( struct dirstack
*dirstack
, const struct expr
*cond
, WCHAR root
, UINT
*count
)
1755 const struct expr
*left
, *right
;
1757 if (!cond
|| cond
->type
!= EXPR_COMPLEX
) return *count
= 0;
1759 left
= cond
->u
.expr
.left
;
1760 right
= cond
->u
.expr
.right
;
1761 if (cond
->u
.expr
.op
== OP_EQ
)
1765 const WCHAR
*str
= NULL
;
1767 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&&
1768 !wcscmp( left
->u
.propval
->name
, L
"Name" ) &&
1769 towupper( right
->u
.sval
[0] ) == towupper( root
))
1771 str
= right
->u
.sval
;
1773 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&&
1774 !wcscmp( right
->u
.propval
->name
, L
"Name" ) &&
1775 towupper( left
->u
.sval
[0] ) == towupper( root
))
1779 if (str
&& (path
= build_dirname( str
, &len
)))
1781 if (seen_dir( dirstack
, path
))
1786 else if (push_dir( dirstack
, path
, len
)) return ++*count
;
1791 else if (cond
->u
.expr
.op
== OP_OR
)
1793 UINT left_count
= 0, right_count
= 0;
1795 if (!(seed_dirs( dirstack
, left
, root
, &left_count
))) return *count
= 0;
1796 if (!(seed_dirs( dirstack
, right
, root
, &right_count
))) return *count
= 0;
1797 return *count
+= left_count
+ right_count
;
1802 static WCHAR
*append_path( const WCHAR
*path
, const WCHAR
*segment
, UINT
*len
)
1804 UINT len_path
= 0, len_segment
= lstrlenW( segment
);
1808 if (path
) len_path
= lstrlenW( path
);
1809 if (!(ret
= heap_alloc( (len_path
+ len_segment
+ 2) * sizeof(WCHAR
) ))) return NULL
;
1810 if (path
&& len_path
)
1812 memcpy( ret
, path
, len_path
* sizeof(WCHAR
) );
1813 ret
[len_path
] = '\\';
1814 *len
+= len_path
+ 1;
1816 memcpy( ret
+ *len
, segment
, len_segment
* sizeof(WCHAR
) );
1817 *len
+= len_segment
;
1822 static WCHAR
*get_file_version( const WCHAR
*filename
)
1824 VS_FIXEDFILEINFO
*info
;
1825 DWORD size
, len
= 4 * 5 + ARRAY_SIZE( L
"%u.%u.%u.%u" );
1829 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
1830 if (!(size
= GetFileVersionInfoSizeW( filename
, NULL
)) || !(block
= heap_alloc( size
)))
1835 if (!GetFileVersionInfoW( filename
, 0, size
, block
) ||
1836 !VerQueryValueW( block
, L
"\\", (void **)&info
, &size
))
1842 swprintf( ret
, len
, L
"%u.%u.%u.%u", info
->dwFileVersionMS
>> 16, info
->dwFileVersionMS
& 0xffff,
1843 info
->dwFileVersionLS
>> 16, info
->dwFileVersionLS
& 0xffff );
1848 static enum fill_status
fill_datafile( struct table
*table
, const struct expr
*cond
)
1850 struct record_datafile
*rec
;
1851 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
1852 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
1853 DWORD drives
= GetLogicalDrives();
1854 WIN32_FIND_DATAW data
;
1856 struct dirstack
*dirstack
;
1857 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1859 if (!resize_table( table
, 8, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1861 dirstack
= alloc_dirstack(2);
1863 for (i
= 0; i
< 26; i
++)
1865 if (!(drives
& (1 << i
))) continue;
1868 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
1870 num_expected_rows
= 0;
1871 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
1877 path
= pop_dir( dirstack
, &len
);
1878 if (!(glob
= build_glob( root
[0], path
, len
)))
1880 status
= FILL_STATUS_FAILED
;
1883 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
1887 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
1889 status
= FILL_STATUS_FAILED
;
1890 FindClose( handle
);
1893 if (!wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." )) continue;
1895 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
1897 status
= FILL_STATUS_FAILED
;
1898 FindClose( handle
);
1902 if (data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1904 if (push_dir( dirstack
, new_path
, len
)) continue;
1905 heap_free( new_path
);
1906 FindClose( handle
);
1907 status
= FILL_STATUS_FAILED
;
1910 rec
= (struct record_datafile
*)(table
->data
+ offset
);
1911 rec
->name
= build_name( root
[0], new_path
);
1912 rec
->version
= get_file_version( rec
->name
);
1913 heap_free( new_path
);
1914 if (!match_row( table
, row
, cond
, &status
))
1916 free_row_values( table
, row
);
1919 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
1922 FindClose( handle
);
1923 status
= FILL_STATUS_FILTERED
;
1926 offset
+= sizeof(*rec
);
1929 while (FindNextFileW( handle
, &data
));
1930 FindClose( handle
);
1932 if (!peek_dir( dirstack
)) break;
1937 free_dirstack( dirstack
);
1941 TRACE("created %u rows\n", row
);
1942 table
->num_rows
= row
;
1946 static UINT32
get_pixelsperxlogicalinch(void)
1948 HDC hdc
= GetDC( NULL
);
1951 if (!hdc
) return 96;
1952 ret
= GetDeviceCaps( hdc
, LOGPIXELSX
);
1953 ReleaseDC( NULL
, hdc
);
1957 static enum fill_status
fill_desktopmonitor( struct table
*table
, const struct expr
*cond
)
1959 struct record_desktopmonitor
*rec
;
1960 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1963 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1965 rec
= (struct record_desktopmonitor
*)table
->data
;
1966 rec
->name
= L
"Generic Non-PnP Monitor";
1967 rec
->pixelsperxlogicalinch
= get_pixelsperxlogicalinch();
1969 if (match_row( table
, row
, cond
, &status
)) row
++;
1971 TRACE("created %u rows\n", row
);
1972 table
->num_rows
= row
;
1976 static enum fill_status
fill_directory( struct table
*table
, const struct expr
*cond
)
1978 struct record_directory
*rec
;
1979 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
1980 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
1981 DWORD drives
= GetLogicalDrives();
1982 WIN32_FIND_DATAW data
;
1984 struct dirstack
*dirstack
;
1985 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1987 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1989 dirstack
= alloc_dirstack(2);
1991 for (i
= 0; i
< 26; i
++)
1993 if (!(drives
& (1 << i
))) continue;
1996 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
1998 num_expected_rows
= 0;
1999 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2005 path
= pop_dir( dirstack
, &len
);
2006 if (!(glob
= build_glob( root
[0], path
, len
)))
2008 status
= FILL_STATUS_FAILED
;
2011 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2015 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2017 FindClose( handle
);
2018 status
= FILL_STATUS_FAILED
;
2021 if (!(data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ||
2022 !wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." ))
2025 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2027 FindClose( handle
);
2028 status
= FILL_STATUS_FAILED
;
2032 if (!(push_dir( dirstack
, new_path
, len
)))
2034 heap_free( new_path
);
2035 FindClose( handle
);
2036 status
= FILL_STATUS_FAILED
;
2039 rec
= (struct record_directory
*)(table
->data
+ offset
);
2040 rec
->accessmask
= FILE_ALL_ACCESS
;
2041 rec
->name
= build_name( root
[0], new_path
);
2042 heap_free( new_path
);
2043 if (!match_row( table
, row
, cond
, &status
))
2045 free_row_values( table
, row
);
2048 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2051 FindClose( handle
);
2052 status
= FILL_STATUS_FILTERED
;
2055 offset
+= sizeof(*rec
);
2058 while (FindNextFileW( handle
, &data
));
2059 FindClose( handle
);
2061 if (!peek_dir( dirstack
)) break;
2066 free_dirstack( dirstack
);
2070 TRACE("created %u rows\n", row
);
2071 table
->num_rows
= row
;
2075 static UINT64
get_freespace( const WCHAR
*dir
, UINT64
*disksize
)
2077 WCHAR root
[] = L
"\\\\.\\A:";
2078 ULARGE_INTEGER free
;
2079 DISK_GEOMETRY_EX info
;
2081 DWORD bytes_returned
;
2083 free
.QuadPart
= 512 * 1024 * 1024;
2084 GetDiskFreeSpaceExW( dir
, NULL
, NULL
, &free
);
2087 handle
= CreateFileW( root
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2088 if (handle
!= INVALID_HANDLE_VALUE
)
2090 if (DeviceIoControl( handle
, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
, NULL
, 0, &info
, sizeof(info
), &bytes_returned
, NULL
))
2091 *disksize
= info
.DiskSize
.QuadPart
;
2092 CloseHandle( handle
);
2094 return free
.QuadPart
;
2096 static WCHAR
*get_diskdrive_serialnumber( WCHAR letter
)
2099 STORAGE_DEVICE_DESCRIPTOR
*desc
;
2100 HANDLE handle
= INVALID_HANDLE_VALUE
;
2101 STORAGE_PROPERTY_QUERY query
= {0};
2105 swprintf( drive
, ARRAY_SIZE(drive
), L
"\\\\.\\%c:", letter
);
2106 handle
= CreateFileW( drive
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2107 if (handle
== INVALID_HANDLE_VALUE
) goto done
;
2109 query
.PropertyId
= StorageDeviceProperty
;
2110 query
.QueryType
= PropertyStandardQuery
;
2112 size
= sizeof(*desc
) + 256;
2115 if (!(desc
= heap_alloc( size
))) break;
2116 if (DeviceIoControl( handle
, IOCTL_STORAGE_QUERY_PROPERTY
, &query
, sizeof(query
), desc
, size
, NULL
, NULL
))
2118 if (desc
->SerialNumberOffset
) ret
= heap_strdupAW( (const char *)desc
+ desc
->SerialNumberOffset
);
2124 if (GetLastError() != ERROR_MORE_DATA
) break;
2128 if (handle
!= INVALID_HANDLE_VALUE
) CloseHandle( handle
);
2129 if (!ret
) ret
= heap_strdupW( L
"WINEHDISK" );
2133 static enum fill_status
fill_diskdrive( struct table
*table
, const struct expr
*cond
)
2135 static const WCHAR fmtW
[] = L
"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2136 WCHAR device_id
[ARRAY_SIZE( fmtW
) + 10], root
[] = L
"A:\\";
2137 struct record_diskdrive
*rec
;
2138 UINT i
, row
= 0, offset
= 0, index
= 0, type
;
2139 UINT64 size
= 1024 * 1024 * 1024;
2140 DWORD drives
= GetLogicalDrives();
2141 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2143 if (!resize_table( table
, 2, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2145 for (i
= 0; i
< 26; i
++)
2147 if (drives
& (1 << i
))
2150 type
= GetDriveTypeW( root
);
2151 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2154 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2156 rec
= (struct record_diskdrive
*)(table
->data
+ offset
);
2157 swprintf( device_id
, ARRAY_SIZE( device_id
), fmtW
, index
);
2158 rec
->device_id
= heap_strdupW( device_id
);
2159 rec
->index
= index
++;
2160 rec
->interfacetype
= L
"IDE";
2161 rec
->manufacturer
= L
"(Standard disk drives)";
2162 rec
->mediatype
= (type
== DRIVE_FIXED
) ? L
"Fixed hard disk" : L
"Removable media";
2163 rec
->model
= L
"Wine Disk Drive";
2164 rec
->pnpdevice_id
= L
"IDE\\Disk\\VEN_WINE";
2165 rec
->serialnumber
= get_diskdrive_serialnumber( root
[0] );
2166 get_freespace( root
, &size
);
2168 if (!match_row( table
, row
, cond
, &status
))
2170 free_row_values( table
, row
);
2173 offset
+= sizeof(*rec
);
2177 TRACE("created %u rows\n", row
);
2178 table
->num_rows
= row
;
2188 static void free_associations( struct association
*assoc
, UINT count
)
2192 for (i
= 0; i
< count
; i
++)
2194 heap_free( assoc
[i
].ref
);
2195 heap_free( assoc
[i
].ref2
);
2200 static struct association
*get_diskdrivetodiskpartition_pairs( UINT
*count
)
2202 struct association
*ret
= NULL
;
2203 struct query
*query
, *query2
= NULL
;
2208 if (!(query
= create_query())) return NULL
;
2209 if ((hr
= parse_query( L
"SELECT * FROM Win32_DiskDrive", &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2210 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2212 if (!(query2
= create_query())) return FALSE
;
2213 if ((hr
= parse_query( L
"SELECT * FROM Win32_DiskPartition", &query2
->view
, &query2
->mem
)) != S_OK
) goto done
;
2214 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2216 if (!(ret
= heap_alloc_zero( query
->view
->result_count
* sizeof(*ret
) ))) goto done
;
2218 for (i
= 0; i
< query
->view
->result_count
; i
++)
2220 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2221 if (!(ret
[i
].ref
= heap_strdupW( V_BSTR(&val
) ))) goto done
;
2222 VariantClear( &val
);
2224 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2225 if (!(ret
[i
].ref2
= heap_strdupW( V_BSTR(&val
) ))) goto done
;
2226 VariantClear( &val
);
2229 *count
= query
->view
->result_count
;
2232 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2233 free_query( query
);
2234 free_query( query2
);
2238 static enum fill_status
fill_diskdrivetodiskpartition( struct table
*table
, const struct expr
*cond
)
2240 struct record_diskdrivetodiskpartition
*rec
;
2241 UINT i
, row
= 0, offset
= 0, count
= 0;
2242 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2243 struct association
*assoc
;
2245 if (!(assoc
= get_diskdrivetodiskpartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2248 free_associations( assoc
, count
);
2249 return FILL_STATUS_UNFILTERED
;
2251 if (!resize_table( table
, count
, sizeof(*rec
) ))
2253 free_associations( assoc
, count
);
2254 return FILL_STATUS_FAILED
;
2257 for (i
= 0; i
< count
; i
++)
2259 rec
= (struct record_diskdrivetodiskpartition
*)(table
->data
+ offset
);
2260 rec
->antecedent
= assoc
[i
].ref
;
2261 rec
->dependent
= assoc
[i
].ref2
;
2262 if (!match_row( table
, row
, cond
, &status
))
2264 free_row_values( table
, row
);
2267 offset
+= sizeof(*rec
);
2273 TRACE("created %u rows\n", row
);
2274 table
->num_rows
= row
;
2278 static WCHAR
*get_filesystem( const WCHAR
*root
)
2280 WCHAR buffer
[MAX_PATH
+ 1];
2282 if (GetVolumeInformationW( root
, NULL
, 0, NULL
, NULL
, NULL
, buffer
, MAX_PATH
+ 1 ))
2283 return heap_strdupW( buffer
);
2284 return heap_strdupW( L
"NTFS" );
2287 static enum fill_status
fill_diskpartition( struct table
*table
, const struct expr
*cond
)
2289 WCHAR device_id
[32], root
[] = L
"A:\\";
2290 struct record_diskpartition
*rec
;
2291 UINT i
, row
= 0, offset
= 0, type
, index
= 0;
2292 UINT64 size
= 1024 * 1024 * 1024;
2293 DWORD drives
= GetLogicalDrives();
2294 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2296 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2298 for (i
= 0; i
< 26; i
++)
2300 if (drives
& (1 << i
))
2303 type
= GetDriveTypeW( root
);
2304 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2307 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2309 rec
= (struct record_diskpartition
*)(table
->data
+ offset
);
2310 rec
->bootable
= (i
== 2) ? -1 : 0;
2311 rec
->bootpartition
= (i
== 2) ? -1 : 0;
2312 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"Disk #%u, Partition #0", index
);
2313 rec
->device_id
= heap_strdupW( device_id
);
2314 rec
->diskindex
= index
++;
2316 rec
->pnpdevice_id
= heap_strdupW( device_id
);
2317 get_freespace( root
, &size
);
2319 rec
->startingoffset
= 0;
2320 rec
->type
= get_filesystem( root
);
2321 if (!match_row( table
, row
, cond
, &status
))
2323 free_row_values( table
, row
);
2326 offset
+= sizeof(*rec
);
2330 TRACE("created %u rows\n", row
);
2331 table
->num_rows
= row
;
2335 static UINT32
get_bitsperpixel( UINT
*hres
, UINT
*vres
)
2337 HDC hdc
= GetDC( NULL
);
2340 if (!hdc
) return 32;
2341 ret
= GetDeviceCaps( hdc
, BITSPIXEL
);
2342 *hres
= GetDeviceCaps( hdc
, HORZRES
);
2343 *vres
= GetDeviceCaps( hdc
, VERTRES
);
2344 ReleaseDC( NULL
, hdc
);
2348 static enum fill_status
fill_displaycontrollerconfig( struct table
*table
, const struct expr
*cond
)
2350 struct record_displaycontrollerconfig
*rec
;
2351 UINT row
= 0, hres
= 1024, vres
= 768;
2352 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2354 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2356 rec
= (struct record_displaycontrollerconfig
*)table
->data
;
2357 rec
->bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
2358 rec
->caption
= L
"VideoController1";
2359 rec
->horizontalresolution
= hres
;
2360 rec
->name
= L
"VideoController1";
2361 rec
->verticalresolution
= vres
;
2362 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
2365 TRACE("created %u rows\n", row
);
2366 table
->num_rows
= row
;
2370 static WCHAR
*get_ip4_string( DWORD addr
)
2372 DWORD len
= sizeof("ddd.ddd.ddd.ddd");
2375 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
2376 swprintf( ret
, len
, L
"%u.%u.%u.%u", (addr
>> 24) & 0xff, (addr
>> 16) & 0xff, (addr
>> 8) & 0xff, addr
& 0xff );
2380 static enum fill_status
fill_ip4routetable( struct table
*table
, const struct expr
*cond
)
2382 struct record_ip4routetable
*rec
;
2383 UINT i
, row
= 0, offset
= 0, size
= 0;
2384 MIB_IPFORWARDTABLE
*forwards
;
2385 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2387 if (GetIpForwardTable( NULL
, &size
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
) return FILL_STATUS_FAILED
;
2388 if (!(forwards
= heap_alloc( size
))) return FILL_STATUS_FAILED
;
2389 if (GetIpForwardTable( forwards
, &size
, TRUE
))
2391 heap_free( forwards
);
2392 return FILL_STATUS_FAILED
;
2394 if (!resize_table( table
, max(forwards
->dwNumEntries
, 1), sizeof(*rec
) ))
2396 heap_free( forwards
);
2397 return FILL_STATUS_FAILED
;
2400 for (i
= 0; i
< forwards
->dwNumEntries
; i
++)
2402 rec
= (struct record_ip4routetable
*)(table
->data
+ offset
);
2404 rec
->destination
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardDest
) );
2405 rec
->interfaceindex
= forwards
->table
[i
].dwForwardIfIndex
;
2406 rec
->nexthop
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardNextHop
) );
2408 if (!match_row( table
, row
, cond
, &status
))
2410 free_row_values( table
, row
);
2413 offset
+= sizeof(*rec
);
2416 TRACE("created %u rows\n", row
);
2417 table
->num_rows
= row
;
2419 heap_free( forwards
);
2423 static WCHAR
*get_volumename( const WCHAR
*root
)
2425 WCHAR buf
[MAX_PATH
+ 1] = {0};
2426 GetVolumeInformationW( root
, buf
, ARRAY_SIZE( buf
), NULL
, NULL
, NULL
, NULL
, 0 );
2427 return heap_strdupW( buf
);
2429 static WCHAR
*get_volumeserialnumber( const WCHAR
*root
)
2434 GetVolumeInformationW( root
, NULL
, 0, &serial
, NULL
, NULL
, NULL
, 0 );
2435 swprintf( buffer
, ARRAY_SIZE( buffer
), L
"%08X", serial
);
2436 return heap_strdupW( buffer
);
2439 static enum fill_status
fill_logicaldisk( struct table
*table
, const struct expr
*cond
)
2441 WCHAR device_id
[3], root
[] = L
"A:\\";
2442 struct record_logicaldisk
*rec
;
2443 UINT i
, row
= 0, offset
= 0, type
;
2444 UINT64 size
= 1024 * 1024 * 1024;
2445 DWORD drives
= GetLogicalDrives();
2446 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2448 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2450 for (i
= 0; i
< 26; i
++)
2452 if (drives
& (1 << i
))
2455 type
= GetDriveTypeW( root
);
2456 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_CDROM
&& type
!= DRIVE_REMOVABLE
)
2459 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2461 rec
= (struct record_logicaldisk
*)(table
->data
+ offset
);
2462 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%c:", 'A' + i
);
2463 rec
->device_id
= heap_strdupW( device_id
);
2464 rec
->drivetype
= type
;
2465 rec
->filesystem
= get_filesystem( root
);
2466 rec
->freespace
= get_freespace( root
, &size
);
2467 rec
->name
= heap_strdupW( device_id
);
2469 rec
->volumename
= get_volumename( root
);
2470 rec
->volumeserialnumber
= get_volumeserialnumber( root
);
2471 if (!match_row( table
, row
, cond
, &status
))
2473 free_row_values( table
, row
);
2476 offset
+= sizeof(*rec
);
2480 TRACE("created %u rows\n", row
);
2481 table
->num_rows
= row
;
2485 static struct association
*get_logicaldisktopartition_pairs( UINT
*count
)
2487 struct association
*ret
= NULL
;
2488 struct query
*query
, *query2
= NULL
;
2493 if (!(query
= create_query())) return NULL
;
2494 if ((hr
= parse_query( L
"SELECT * FROM Win32_DiskPartition", &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2495 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2497 if (!(query2
= create_query())) return FALSE
;
2498 if ((hr
= parse_query( L
"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2
->view
,
2499 &query2
->mem
)) != S_OK
) goto done
;
2500 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2502 if (!(ret
= heap_alloc_zero( query
->view
->result_count
* sizeof(*ret
) ))) goto done
;
2504 /* assume fixed and removable disks are enumerated in the same order as partitions */
2505 for (i
= 0; i
< query
->view
->result_count
; i
++)
2507 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2508 if (!(ret
[i
].ref
= heap_strdupW( V_BSTR(&val
) ))) goto done
;
2509 VariantClear( &val
);
2511 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2512 if (!(ret
[i
].ref2
= heap_strdupW( V_BSTR(&val
) ))) goto done
;
2513 VariantClear( &val
);
2516 *count
= query
->view
->result_count
;
2519 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2520 free_query( query
);
2521 free_query( query2
);
2525 static enum fill_status
fill_logicaldisktopartition( struct table
*table
, const struct expr
*cond
)
2527 struct record_logicaldisktopartition
*rec
;
2528 UINT i
, row
= 0, offset
= 0, count
= 0;
2529 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2530 struct association
*assoc
;
2532 if (!(assoc
= get_logicaldisktopartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2535 free_associations( assoc
, count
);
2536 return FILL_STATUS_UNFILTERED
;
2538 if (!resize_table( table
, count
, sizeof(*rec
) ))
2540 free_associations( assoc
, count
);
2541 return FILL_STATUS_FAILED
;
2544 for (i
= 0; i
< count
; i
++)
2546 rec
= (struct record_logicaldisktopartition
*)(table
->data
+ offset
);
2547 rec
->antecedent
= assoc
[i
].ref
;
2548 rec
->dependent
= assoc
[i
].ref2
;
2549 if (!match_row( table
, row
, cond
, &status
))
2551 free_row_values( table
, row
);
2554 offset
+= sizeof(*rec
);
2560 TRACE("created %u rows\n", row
);
2561 table
->num_rows
= row
;
2565 static UINT16
get_connection_status( IF_OPER_STATUS status
)
2569 case IfOperStatusDown
:
2570 return 0; /* Disconnected */
2571 case IfOperStatusUp
:
2572 return 2; /* Connected */
2574 ERR("unhandled status %u\n", status
);
2579 static WCHAR
*get_mac_address( const BYTE
*addr
, DWORD len
)
2582 if (len
!= 6 || !(ret
= heap_alloc( 18 * sizeof(WCHAR
) ))) return NULL
;
2583 swprintf( ret
, 18, L
"%02x:%02x:%02x:%02x:%02x:%02x", addr
[0], addr
[1], addr
[2], addr
[3], addr
[4], addr
[5] );
2586 static const WCHAR
*get_adaptertype( DWORD type
, int *id
, int *physical
)
2590 case IF_TYPE_ETHERNET_CSMACD
:
2593 return L
"Ethernet 802.3";
2595 case IF_TYPE_IEEE80211
:
2600 case IF_TYPE_IEEE1394
:
2605 case IF_TYPE_TUNNEL
:
2617 static enum fill_status
fill_networkadapter( struct table
*table
, const struct expr
*cond
)
2619 WCHAR device_id
[11];
2620 struct record_networkadapter
*rec
;
2621 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
2622 UINT row
= 0, offset
= 0, count
= 0;
2623 DWORD size
= 0, ret
;
2624 int adaptertypeid
, physical
;
2625 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2627 ret
= GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, NULL
, &size
);
2628 if (ret
!= ERROR_BUFFER_OVERFLOW
) return FILL_STATUS_FAILED
;
2630 if (!(buffer
= heap_alloc( size
))) return FILL_STATUS_FAILED
;
2631 if (GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, buffer
, &size
))
2633 heap_free( buffer
);
2634 return FILL_STATUS_FAILED
;
2636 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2638 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
2640 if (!resize_table( table
, count
, sizeof(*rec
) ))
2642 heap_free( buffer
);
2643 return FILL_STATUS_FAILED
;
2645 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2647 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
2649 rec
= (struct record_networkadapter
*)(table
->data
+ offset
);
2650 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%u", aa
->u
.s
.IfIndex
);
2651 rec
->adaptertype
= get_adaptertype( aa
->IfType
, &adaptertypeid
, &physical
);
2652 rec
->adaptertypeid
= adaptertypeid
;
2653 rec
->description
= heap_strdupW( aa
->Description
);
2654 rec
->device_id
= heap_strdupW( device_id
);
2655 rec
->index
= aa
->u
.s
.IfIndex
;
2656 rec
->interface_index
= aa
->u
.s
.IfIndex
;
2657 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
2658 rec
->manufacturer
= L
"The Wine Project";
2659 rec
->name
= heap_strdupW( aa
->FriendlyName
);
2660 rec
->netconnection_status
= get_connection_status( aa
->OperStatus
);
2661 rec
->physicaladapter
= physical
;
2662 rec
->pnpdevice_id
= L
"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2663 rec
->speed
= 1000000;
2664 if (!match_row( table
, row
, cond
, &status
))
2666 free_row_values( table
, row
);
2669 offset
+= sizeof(*rec
);
2672 TRACE("created %u rows\n", row
);
2673 table
->num_rows
= row
;
2675 heap_free( buffer
);
2679 static WCHAR
*get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS
*addr
)
2681 const SOCKET_ADDRESS
*sa
= &addr
->Address
;
2682 WCHAR buf
[NI_MAXHOST
];
2684 if (!addr
) return NULL
;
2685 if (GetNameInfoW( sa
->lpSockaddr
, sa
->iSockaddrLength
, buf
, ARRAY_SIZE( buf
), NULL
,
2686 0, NI_NAMEREQD
)) return NULL
;
2687 return heap_strdupW( buf
);
2689 static struct array
*get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS
*list
)
2691 IP_ADAPTER_GATEWAY_ADDRESS
*gateway
;
2693 ULONG buflen
, i
= 0, count
= 0;
2694 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2696 if (!list
) return NULL
;
2697 for (gateway
= list
; gateway
; gateway
= gateway
->Next
) count
++;
2699 if (!(ret
= heap_alloc( sizeof(*ret
) ))) return NULL
;
2700 if (!(ptr
= heap_alloc( sizeof(*ptr
) * count
)))
2705 for (gateway
= list
; gateway
; gateway
= gateway
->Next
)
2707 buflen
= ARRAY_SIZE( buf
);
2708 if (WSAAddressToStringW( gateway
->Address
.lpSockaddr
, gateway
->Address
.iSockaddrLength
,
2709 NULL
, buf
, &buflen
) || !(ptr
[i
++] = heap_strdupW( buf
)))
2711 for (; i
> 0; i
--) heap_free( ptr
[i
- 1] );
2717 ret
->elem_size
= sizeof(*ptr
);
2722 static struct array
*get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS
*list
)
2724 IP_ADAPTER_DNS_SERVER_ADDRESS
*server
;
2726 ULONG buflen
, i
= 0, count
= 0;
2727 WCHAR
**ptr
, *p
, buf
[54]; /* max IPv6 address length */
2729 if (!list
) return NULL
;
2730 for (server
= list
; server
; server
= server
->Next
) count
++;
2732 if (!(ret
= heap_alloc( sizeof(*ret
) ))) return NULL
;
2733 if (!(ptr
= heap_alloc( sizeof(*ptr
) * count
)))
2738 for (server
= list
; server
; server
= server
->Next
)
2740 buflen
= ARRAY_SIZE( buf
);
2741 if (WSAAddressToStringW( server
->Address
.lpSockaddr
, server
->Address
.iSockaddrLength
,
2742 NULL
, buf
, &buflen
) || !(ptr
[i
++] = heap_strdupW( buf
)))
2744 for (; i
> 0; i
--) heap_free( ptr
[i
- 1] );
2749 if ((p
= wcsrchr( ptr
[i
- 1], ':' ))) *p
= 0;
2751 ret
->elem_size
= sizeof(*ptr
);
2756 static struct array
*get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
2758 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
2760 ULONG buflen
, i
= 0, count
= 0;
2761 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2763 if (!list
) return NULL
;
2764 for (address
= list
; address
; address
= address
->Next
) count
++;
2766 if (!(ret
= heap_alloc( sizeof(*ret
) ))) return NULL
;
2767 if (!(ptr
= heap_alloc( sizeof(*ptr
) * count
)))
2772 for (address
= list
; address
; address
= address
->Next
)
2774 buflen
= ARRAY_SIZE( buf
);
2775 if (WSAAddressToStringW( address
->Address
.lpSockaddr
, address
->Address
.iSockaddrLength
,
2776 NULL
, buf
, &buflen
) || !(ptr
[i
++] = heap_strdupW( buf
)))
2778 for (; i
> 0; i
--) heap_free( ptr
[i
- 1] );
2784 ret
->elem_size
= sizeof(*ptr
);
2789 static struct array
*get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
2791 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
2793 ULONG i
= 0, count
= 0;
2796 if (!list
) return NULL
;
2797 for (address
= list
; address
; address
= address
->Next
) count
++;
2799 if (!(ret
= heap_alloc( sizeof(*ret
) ))) return NULL
;
2800 if (!(ptr
= heap_alloc( sizeof(*ptr
) * count
)))
2805 for (address
= list
; address
; address
= address
->Next
)
2807 if (address
->Address
.lpSockaddr
->sa_family
== AF_INET
)
2809 WCHAR buf
[INET_ADDRSTRLEN
];
2811 ULONG buflen
= ARRAY_SIZE( buf
);
2813 memset( &addr
, 0, sizeof(addr
) );
2814 addr
.sin_family
= AF_INET
;
2815 if (ConvertLengthToIpv4Mask( address
->OnLinkPrefixLength
, &addr
.sin_addr
.S_un
.S_addr
) != NO_ERROR
2816 || WSAAddressToStringW( (SOCKADDR
*)&addr
, sizeof(addr
), NULL
, buf
, &buflen
))
2819 ptr
[i
] = heap_strdupW( buf
);
2824 swprintf( buf
, ARRAY_SIZE( buf
), L
"%u", address
->OnLinkPrefixLength
);
2825 ptr
[i
] = heap_strdupW( buf
);
2829 for (; i
> 0; i
--) heap_free( ptr
[i
- 1] );
2835 ret
->elem_size
= sizeof(*ptr
);
2840 static WCHAR
*get_settingid( UINT32 index
)
2844 memset( &guid
, 0, sizeof(guid
) );
2846 UuidToStringW( &guid
, &str
);
2847 ret
= heap_strdupW( str
);
2848 RpcStringFreeW( &str
);
2852 static enum fill_status
fill_networkadapterconfig( struct table
*table
, const struct expr
*cond
)
2854 struct record_networkadapterconfig
*rec
;
2855 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
2856 UINT row
= 0, offset
= 0, count
= 0;
2857 DWORD size
= 0, ret
;
2858 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2860 ret
= GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_GATEWAYS
, NULL
, NULL
, &size
);
2861 if (ret
!= ERROR_BUFFER_OVERFLOW
) return FILL_STATUS_FAILED
;
2863 if (!(buffer
= heap_alloc( size
))) return FILL_STATUS_FAILED
;
2864 if (GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_ALL_GATEWAYS
, NULL
, buffer
, &size
))
2866 heap_free( buffer
);
2867 return FILL_STATUS_FAILED
;
2869 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2871 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
2873 if (!resize_table( table
, count
, sizeof(*rec
) ))
2875 heap_free( buffer
);
2876 return FILL_STATUS_FAILED
;
2878 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2880 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
2882 rec
= (struct record_networkadapterconfig
*)(table
->data
+ offset
);
2883 rec
->defaultipgateway
= get_defaultipgateway( aa
->FirstGatewayAddress
);
2884 rec
->description
= heap_strdupW( aa
->Description
);
2885 rec
->dhcpenabled
= -1;
2886 rec
->dnshostname
= get_dnshostname( aa
->FirstUnicastAddress
);
2887 rec
->dnsserversearchorder
= get_dnsserversearchorder( aa
->FirstDnsServerAddress
);
2888 rec
->index
= aa
->u
.s
.IfIndex
;
2889 rec
->ipaddress
= get_ipaddress( aa
->FirstUnicastAddress
);
2890 rec
->ipconnectionmetric
= 20;
2891 rec
->ipenabled
= -1;
2892 rec
->ipsubnet
= get_ipsubnet( aa
->FirstUnicastAddress
);
2893 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
2894 rec
->settingid
= get_settingid( rec
->index
);
2895 if (!match_row( table
, row
, cond
, &status
))
2897 free_row_values( table
, row
);
2900 offset
+= sizeof(*rec
);
2903 TRACE("created %u rows\n", row
);
2904 table
->num_rows
= row
;
2906 heap_free( buffer
);
2910 static enum fill_status
fill_physicalmemory( struct table
*table
, const struct expr
*cond
)
2912 struct record_physicalmemory
*rec
;
2913 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2916 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2918 rec
= (struct record_physicalmemory
*)table
->data
;
2919 rec
->banklabel
= L
"BANK 0";
2920 rec
->capacity
= get_total_physical_memory();
2921 rec
->caption
= L
"Physical Memory";
2922 rec
->configuredclockspeed
= 1600;
2923 rec
->devicelocator
= L
"DIMM 0";
2924 rec
->formfactor
= 8; /* DIMM */
2925 rec
->memorytype
= 9; /* RAM */
2926 rec
->partnumber
= L
"";
2928 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
2931 TRACE("created %u rows\n", row
);
2932 table
->num_rows
= row
;
2936 static enum fill_status
fill_pnpentity( struct table
*table
, const struct expr
*cond
)
2938 struct record_pnpentity
*rec
;
2939 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2940 HDEVINFO device_info_set
;
2941 SP_DEVINFO_DATA devinfo
= {0};
2944 device_info_set
= SetupDiGetClassDevsW( NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
|DIGCF_PRESENT
);
2946 devinfo
.cbSize
= sizeof(devinfo
);
2949 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
2954 resize_table( table
, idx
, sizeof(*rec
) );
2955 table
->num_rows
= 0;
2956 rec
= (struct record_pnpentity
*)table
->data
;
2959 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
2961 WCHAR device_id
[MAX_PATH
];
2962 if (SetupDiGetDeviceInstanceIdW( device_info_set
, &devinfo
, device_id
,
2963 ARRAY_SIZE(device_id
), NULL
))
2965 rec
->device_id
= heap_strdupW( device_id
);
2968 if (!match_row( table
, table
->num_rows
- 1, cond
, &status
))
2970 free_row_values( table
, table
->num_rows
- 1 );
2978 SetupDiDestroyDeviceInfoList( device_info_set
);
2983 static enum fill_status
fill_printer( struct table
*table
, const struct expr
*cond
)
2985 struct record_printer
*rec
;
2986 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2987 PRINTER_INFO_2W
*info
;
2988 DWORD i
, offset
= 0, count
= 0, size
= 0, num_rows
= 0;
2991 EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &size
, &count
);
2992 if (!count
) return FILL_STATUS_UNFILTERED
;
2994 if (!(info
= heap_alloc( size
))) return FILL_STATUS_FAILED
;
2995 if (!EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, (BYTE
*)info
, size
, &size
, &count
))
2998 return FILL_STATUS_FAILED
;
3000 if (!resize_table( table
, count
, sizeof(*rec
) ))
3003 return FILL_STATUS_FAILED
;
3006 for (i
= 0; i
< count
; i
++)
3008 rec
= (struct record_printer
*)(table
->data
+ offset
);
3009 rec
->attributes
= info
[i
].Attributes
;
3010 swprintf( id
, ARRAY_SIZE( id
), L
"Printer%u", i
);
3011 rec
->device_id
= heap_strdupW( id
);
3012 rec
->drivername
= heap_strdupW( info
[i
].pDriverName
);
3013 rec
->horizontalresolution
= info
[i
].pDevMode
->u1
.s1
.dmPrintQuality
;
3015 rec
->location
= heap_strdupW( info
[i
].pLocation
);
3016 rec
->name
= heap_strdupW( info
[i
].pPrinterName
);
3018 rec
->portname
= heap_strdupW( info
[i
].pPortName
);
3019 if (!match_row( table
, i
, cond
, &status
))
3021 free_row_values( table
, i
);
3024 offset
+= sizeof(*rec
);
3027 TRACE("created %u rows\n", num_rows
);
3028 table
->num_rows
= num_rows
;
3034 static WCHAR
*get_cmdline( DWORD process_id
)
3036 if (process_id
== GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() );
3037 return NULL
; /* FIXME handle different process case */
3040 static enum fill_status
fill_process( struct table
*table
, const struct expr
*cond
)
3043 struct record_process
*rec
;
3044 PROCESSENTRY32W entry
;
3046 enum fill_status status
= FILL_STATUS_FAILED
;
3047 UINT row
= 0, offset
= 0;
3049 snap
= CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS
, 0 );
3050 if (snap
== INVALID_HANDLE_VALUE
) return FILL_STATUS_FAILED
;
3052 entry
.dwSize
= sizeof(entry
);
3053 if (!Process32FirstW( snap
, &entry
)) goto done
;
3054 if (!resize_table( table
, 8, sizeof(*rec
) )) goto done
;
3058 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
3060 status
= FILL_STATUS_FAILED
;
3064 rec
= (struct record_process
*)(table
->data
+ offset
);
3065 rec
->caption
= heap_strdupW( entry
.szExeFile
);
3066 rec
->commandline
= get_cmdline( entry
.th32ProcessID
);
3067 rec
->description
= heap_strdupW( entry
.szExeFile
);
3068 swprintf( handle
, ARRAY_SIZE( handle
), L
"%u", entry
.th32ProcessID
);
3069 rec
->handle
= heap_strdupW( handle
);
3070 rec
->name
= heap_strdupW( entry
.szExeFile
);
3071 rec
->process_id
= entry
.th32ProcessID
;
3072 rec
->pprocess_id
= entry
.th32ParentProcessID
;
3073 rec
->thread_count
= entry
.cntThreads
;
3074 rec
->workingsetsize
= 0;
3075 rec
->get_owner
= process_get_owner
;
3076 if (!match_row( table
, row
, cond
, &status
))
3078 free_row_values( table
, row
);
3081 offset
+= sizeof(*rec
);
3083 } while (Process32NextW( snap
, &entry
));
3085 TRACE("created %u rows\n", row
);
3086 table
->num_rows
= row
;
3089 CloseHandle( snap
);
3093 void do_cpuid( unsigned int ax
, int *p
)
3095 #if defined(__i386__) || defined(__x86_64__)
3102 static unsigned int get_processor_model( unsigned int reg0
, unsigned int *stepping
, unsigned int *family
)
3104 unsigned int model
, family_id
= (reg0
& (0x0f << 8)) >> 8;
3106 model
= (reg0
& (0x0f << 4)) >> 4;
3107 if (family_id
== 6 || family_id
== 15) model
|= (reg0
& (0x0f << 16)) >> 12;
3110 *family
= family_id
;
3111 if (family_id
== 15) *family
+= (reg0
& (0xff << 20)) >> 20;
3113 *stepping
= reg0
& 0x0f;
3116 static void regs_to_str( int *regs
, unsigned int len
, WCHAR
*buffer
)
3119 unsigned char *p
= (unsigned char *)regs
;
3121 for (i
= 0; i
< len
; i
++) { buffer
[i
] = *p
++; }
3124 static void get_processor_manufacturer( WCHAR
*manufacturer
, UINT len
)
3126 int tmp
, regs
[4] = {0, 0, 0, 0};
3128 do_cpuid( 0, regs
);
3129 tmp
= regs
[2]; /* swap edx and ecx */
3133 regs_to_str( regs
+ 1, min( 12, len
), manufacturer
);
3135 static const WCHAR
*get_osarchitecture(void)
3138 GetNativeSystemInfo( &info
);
3139 if (info
.u
.s
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"64-bit";
3142 static void get_processor_caption( WCHAR
*caption
, UINT len
)
3145 WCHAR manufacturer
[13];
3146 int regs
[4] = {0, 0, 0, 0};
3147 unsigned int family
, model
, stepping
;
3149 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3150 if (!wcscmp( get_osarchitecture(), L
"32-bit" )) arch
= L
"x86";
3151 else if (!wcscmp( manufacturer
, L
"AuthenticAMD" )) arch
= L
"AMD64";
3152 else arch
= L
"Intel64";
3154 do_cpuid( 1, regs
);
3156 model
= get_processor_model( regs
[0], &stepping
, &family
);
3157 swprintf( caption
, len
, L
"%s Family %u Model %u Stepping %u", arch
, family
, model
, stepping
);
3159 static void get_processor_version( WCHAR
*version
, UINT len
)
3161 int regs
[4] = {0, 0, 0, 0};
3162 unsigned int model
, stepping
;
3164 do_cpuid( 1, regs
);
3166 model
= get_processor_model( regs
[0], &stepping
, NULL
);
3167 swprintf( version
, len
, L
"Model %u Stepping %u", model
, stepping
);
3169 static UINT16
get_processor_revision(void)
3171 int regs
[4] = {0, 0, 0, 0};
3172 do_cpuid( 1, regs
);
3175 static void get_processor_id( WCHAR
*processor_id
, UINT len
)
3177 int regs
[4] = {0, 0, 0, 0};
3179 do_cpuid( 1, regs
);
3180 swprintf( processor_id
, len
, L
"%08X%08X", regs
[3], regs
[0] );
3182 static void get_processor_name( WCHAR
*name
)
3184 int regs
[4] = {0, 0, 0, 0};
3187 do_cpuid( 0x80000000, regs
);
3188 if (regs
[0] >= 0x80000004)
3190 do_cpuid( 0x80000002, regs
);
3191 regs_to_str( regs
, 16, name
);
3192 do_cpuid( 0x80000003, regs
);
3193 regs_to_str( regs
, 16, name
+ 16 );
3194 do_cpuid( 0x80000004, regs
);
3195 regs_to_str( regs
, 16, name
+ 32 );
3197 for (i
= lstrlenW(name
) - 1; i
>= 0 && name
[i
] == ' '; i
--) name
[i
] = 0;
3199 static UINT
get_processor_currentclockspeed( UINT index
)
3201 PROCESSOR_POWER_INFORMATION
*info
;
3202 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3205 if ((info
= heap_alloc( size
)))
3207 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3208 if (!status
) ret
= info
[index
].CurrentMhz
;
3213 static UINT
get_processor_maxclockspeed( UINT index
)
3215 PROCESSOR_POWER_INFORMATION
*info
;
3216 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3219 if ((info
= heap_alloc( size
)))
3221 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3222 if (!status
) ret
= info
[index
].MaxMhz
;
3228 static enum fill_status
fill_processor( struct table
*table
, const struct expr
*cond
)
3230 WCHAR caption
[100], device_id
[14], processor_id
[17], manufacturer
[13], name
[49] = {0}, version
[50];
3231 struct record_processor
*rec
;
3232 UINT i
, offset
= 0, num_rows
= 0, num_logical
, num_physical
, num_packages
;
3233 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3235 num_logical
= get_logical_processor_count( &num_physical
, &num_packages
);
3237 if (!resize_table( table
, num_packages
, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3239 get_processor_caption( caption
, ARRAY_SIZE( caption
) );
3240 get_processor_id( processor_id
, ARRAY_SIZE( processor_id
) );
3241 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3242 get_processor_name( name
);
3243 get_processor_version( version
, ARRAY_SIZE( version
) );
3245 for (i
= 0; i
< num_packages
; i
++)
3247 rec
= (struct record_processor
*)(table
->data
+ offset
);
3248 rec
->addresswidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3249 rec
->architecture
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 0 : 9;
3250 rec
->caption
= heap_strdupW( caption
);
3251 rec
->cpu_status
= 1; /* CPU Enabled */
3252 rec
->currentclockspeed
= get_processor_currentclockspeed( i
);
3253 rec
->datawidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3254 rec
->description
= heap_strdupW( caption
);
3255 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"CPU%u", i
);
3256 rec
->device_id
= heap_strdupW( device_id
);
3257 rec
->family
= 2; /* Unknown */
3259 rec
->manufacturer
= heap_strdupW( manufacturer
);
3260 rec
->maxclockspeed
= get_processor_maxclockspeed( i
);
3261 rec
->name
= heap_strdupW( name
);
3262 rec
->num_cores
= num_physical
/ num_packages
;
3263 rec
->num_logical_processors
= num_logical
/ num_packages
;
3264 rec
->processor_id
= heap_strdupW( processor_id
);
3265 rec
->processortype
= 3; /* central processor */
3266 rec
->revision
= get_processor_revision();
3267 rec
->unique_id
= NULL
;
3268 rec
->version
= heap_strdupW( version
);
3269 if (!match_row( table
, i
, cond
, &status
))
3271 free_row_values( table
, i
);
3274 offset
+= sizeof(*rec
);
3278 TRACE("created %u rows\n", num_rows
);
3279 table
->num_rows
= num_rows
;
3283 static WCHAR
*get_lastbootuptime(void)
3285 SYSTEM_TIMEOFDAY_INFORMATION ti
;
3289 if (!(ret
= heap_alloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3291 NtQuerySystemInformation( SystemTimeOfDayInformation
, &ti
, sizeof(ti
), NULL
);
3292 RtlTimeToTimeFields( &ti
.BootTime
, &tf
);
3293 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u+000", tf
.Year
, tf
.Month
, tf
.Day
, tf
.Hour
, tf
.Minute
,
3294 tf
.Second
, tf
.Milliseconds
* 1000 );
3297 static WCHAR
*get_localdatetime(void)
3299 TIME_ZONE_INFORMATION tzi
;
3305 Status
= GetTimeZoneInformation(&tzi
);
3307 if(Status
== TIME_ZONE_ID_INVALID
) return NULL
;
3309 if(Status
== TIME_ZONE_ID_DAYLIGHT
)
3310 Bias
+= tzi
.DaylightBias
;
3312 Bias
+= tzi
.StandardBias
;
3313 if (!(ret
= heap_alloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3316 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u%+03d", st
.wYear
, st
.wMonth
, st
.wDay
, st
.wHour
, st
.wMinute
,
3317 st
.wSecond
, st
.wMilliseconds
* 1000, -Bias
);
3320 static WCHAR
*get_systemdirectory(void)
3325 if (!(ret
= heap_alloc( MAX_PATH
* sizeof(WCHAR
) ))) return NULL
;
3326 Wow64DisableWow64FsRedirection( &redir
);
3327 GetSystemDirectoryW( ret
, MAX_PATH
);
3328 Wow64RevertWow64FsRedirection( redir
);
3331 static WCHAR
*get_systemdrive(void)
3333 WCHAR
*ret
= heap_alloc( 3 * sizeof(WCHAR
) ); /* "c:" */
3334 if (ret
&& GetEnvironmentVariableW( L
"SystemDrive", ret
, 3 )) return ret
;
3338 static WCHAR
*get_codeset(void)
3340 WCHAR
*ret
= heap_alloc( 11 * sizeof(WCHAR
) );
3341 if (ret
) swprintf( ret
, 11, L
"%u", GetACP() );
3344 static WCHAR
*get_countrycode(void)
3346 WCHAR
*ret
= heap_alloc( 6 * sizeof(WCHAR
) );
3347 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ICOUNTRY
, ret
, 6 );
3350 static WCHAR
*get_locale(void)
3352 WCHAR
*ret
= heap_alloc( 5 * sizeof(WCHAR
) );
3353 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, ret
, 5 );
3356 static WCHAR
*get_osbuildnumber( OSVERSIONINFOEXW
*ver
)
3358 WCHAR
*ret
= heap_alloc( 11 * sizeof(WCHAR
) );
3359 if (ret
) swprintf( ret
, 11, L
"%u", ver
->dwBuildNumber
);
3362 static WCHAR
*get_oscaption( OSVERSIONINFOEXW
*ver
)
3364 static const WCHAR windowsW
[] = L
"Microsoft Windows ";
3365 static const WCHAR win2000W
[] = L
"2000 Professional";
3366 static const WCHAR win2003W
[] = L
"Server 2003 Standard Edition";
3367 static const WCHAR winxpW
[] = L
"XP Professional";
3368 static const WCHAR winxp64W
[] = L
"XP Professional x64 Edition";
3369 static const WCHAR vistaW
[] = L
"Vista Ultimate";
3370 static const WCHAR win2008W
[] = L
"Server 2008 Standard";
3371 static const WCHAR win7W
[] = L
"7 Professional";
3372 static const WCHAR win2008r2W
[] = L
"Server 2008 R2 Standard";
3373 static const WCHAR win8W
[] = L
"8 Pro";
3374 static const WCHAR win81W
[] = L
"8.1 Pro";
3375 static const WCHAR win10W
[] = L
"10 Pro";
3376 int len
= ARRAY_SIZE( windowsW
) - 1;
3379 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) + sizeof(win2003W
) ))) return NULL
;
3380 memcpy( ret
, windowsW
, sizeof(windowsW
) );
3381 if (ver
->dwMajorVersion
== 10 && ver
->dwMinorVersion
== 0) memcpy( ret
+ len
, win10W
, sizeof(win10W
) );
3382 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 3) memcpy( ret
+ len
, win8W
, sizeof(win8W
) );
3383 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 2) memcpy( ret
+ len
, win81W
, sizeof(win81W
) );
3384 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 1)
3386 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, win7W
, sizeof(win7W
) );
3387 else memcpy( ret
+ len
, win2008r2W
, sizeof(win2008r2W
) );
3389 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 0)
3391 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, vistaW
, sizeof(vistaW
) );
3392 else memcpy( ret
+ len
, win2008W
, sizeof(win2008W
) );
3394 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 2)
3396 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, winxp64W
, sizeof(winxp64W
) );
3397 else memcpy( ret
+ len
, win2003W
, sizeof(win2003W
) );
3399 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 1) memcpy( ret
+ len
, winxpW
, sizeof(winxpW
) );
3400 else memcpy( ret
+ len
, win2000W
, sizeof(win2000W
) );
3403 static WCHAR
*get_osname( const WCHAR
*caption
)
3405 static const WCHAR partitionW
[] = L
"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3406 int len
= lstrlenW( caption
);
3409 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) + sizeof(partitionW
) ))) return NULL
;
3410 memcpy( ret
, caption
, len
* sizeof(WCHAR
) );
3411 memcpy( ret
+ len
, partitionW
, sizeof(partitionW
) );
3414 static WCHAR
*get_osserialnumber(void)
3420 if (!RegOpenKeyExW( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ
, &hkey
) &&
3421 !RegQueryValueExW( hkey
, L
"ProductId", NULL
, &type
, NULL
, &size
) && type
== REG_SZ
&&
3422 (ret
= heap_alloc( size
+ sizeof(WCHAR
) )))
3424 size
+= sizeof(WCHAR
);
3425 if (RegQueryValueExW( hkey
, L
"ProductId", NULL
, NULL
, (BYTE
*)ret
, &size
))
3431 if (hkey
) RegCloseKey( hkey
);
3432 if (!ret
) return heap_strdupW( L
"12345-OEM-1234567-12345" );
3435 static WCHAR
*get_osversion( OSVERSIONINFOEXW
*ver
)
3437 WCHAR
*ret
= heap_alloc( 33 * sizeof(WCHAR
) );
3438 if (ret
) swprintf( ret
, 33, L
"%u.%u.%u", ver
->dwMajorVersion
, ver
->dwMinorVersion
, ver
->dwBuildNumber
);
3441 static DWORD
get_operatingsystemsku(void)
3443 DWORD ret
= PRODUCT_UNDEFINED
;
3444 GetProductInfo( 6, 0, 0, 0, &ret
);
3447 static INT16
get_currenttimezone(void)
3449 TIME_ZONE_INFORMATION info
;
3450 DWORD status
= GetTimeZoneInformation( &info
);
3451 if (status
== TIME_ZONE_ID_INVALID
) return 0;
3452 if (status
== TIME_ZONE_ID_DAYLIGHT
) return -(info
.Bias
+ info
.DaylightBias
);
3453 return -(info
.Bias
+ info
.StandardBias
);
3456 static enum fill_status
fill_operatingsystem( struct table
*table
, const struct expr
*cond
)
3458 struct record_operatingsystem
*rec
;
3459 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3460 OSVERSIONINFOEXW ver
;
3463 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3465 ver
.dwOSVersionInfoSize
= sizeof(ver
);
3466 GetVersionExW( (OSVERSIONINFOW
*)&ver
);
3468 rec
= (struct record_operatingsystem
*)table
->data
;
3469 rec
->buildnumber
= get_osbuildnumber( &ver
);
3470 rec
->caption
= get_oscaption( &ver
);
3471 rec
->codeset
= get_codeset();
3472 rec
->countrycode
= get_countrycode();
3473 rec
->csdversion
= ver
.szCSDVersion
[0] ? heap_strdupW( ver
.szCSDVersion
) : NULL
;
3474 rec
->csname
= get_computername();
3475 rec
->currenttimezone
= get_currenttimezone();
3476 rec
->freephysicalmemory
= get_available_physical_memory() / 1024;
3477 rec
->installdate
= L
"20140101000000.000000+000";
3478 rec
->lastbootuptime
= get_lastbootuptime();
3479 rec
->localdatetime
= get_localdatetime();
3480 rec
->locale
= get_locale();
3481 rec
->manufacturer
= L
"The Wine Project";
3482 rec
->name
= get_osname( rec
->caption
);
3483 rec
->operatingsystemsku
= get_operatingsystemsku();
3484 rec
->osarchitecture
= get_osarchitecture();
3485 rec
->oslanguage
= GetSystemDefaultLangID();
3486 rec
->osproductsuite
= 2461140; /* Windows XP Professional */
3487 rec
->ostype
= 18; /* WINNT */
3489 rec
->serialnumber
= get_osserialnumber();
3490 rec
->servicepackmajor
= ver
.wServicePackMajor
;
3491 rec
->servicepackminor
= ver
.wServicePackMinor
;
3492 rec
->suitemask
= 272; /* Single User + Terminal */
3493 rec
->systemdirectory
= get_systemdirectory();
3494 rec
->systemdrive
= get_systemdrive();
3495 rec
->totalvirtualmemorysize
= get_total_physical_memory() / 1024;
3496 rec
->totalvisiblememorysize
= rec
->totalvirtualmemorysize
;
3497 rec
->version
= get_osversion( &ver
);
3498 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3501 TRACE("created %u rows\n", row
);
3502 table
->num_rows
= row
;
3506 static const WCHAR
*get_service_type( DWORD type
)
3508 if (type
& SERVICE_KERNEL_DRIVER
) return L
"Kernel Driver";
3509 else if (type
& SERVICE_FILE_SYSTEM_DRIVER
) return L
"File System Driver";
3510 else if (type
& SERVICE_WIN32_OWN_PROCESS
) return L
"Own Process";
3511 else if (type
& SERVICE_WIN32_SHARE_PROCESS
) return L
"Share Process";
3512 else ERR("unhandled type 0x%08x\n", type
);
3515 static const WCHAR
*get_service_state( DWORD state
)
3519 case SERVICE_STOPPED
: return L
"Stopped";
3520 case SERVICE_START_PENDING
: return L
"Start Pending";
3521 case SERVICE_STOP_PENDING
: return L
"Stop Pending";
3522 case SERVICE_RUNNING
: return L
"Running";
3524 ERR("unknown state %u\n", state
);
3528 static const WCHAR
*get_service_startmode( DWORD mode
)
3532 case SERVICE_BOOT_START
: return L
"Boot";
3533 case SERVICE_SYSTEM_START
: return L
"System";
3534 case SERVICE_AUTO_START
: return L
"Auto";
3535 case SERVICE_DEMAND_START
: return L
"Manual";
3536 case SERVICE_DISABLED
: return L
"Disabled";
3538 ERR("unknown mode 0x%x\n", mode
);
3542 static QUERY_SERVICE_CONFIGW
*query_service_config( SC_HANDLE manager
, const WCHAR
*name
)
3544 QUERY_SERVICE_CONFIGW
*config
= NULL
;
3548 if (!(service
= OpenServiceW( manager
, name
, SERVICE_QUERY_CONFIG
))) return NULL
;
3549 QueryServiceConfigW( service
, NULL
, 0, &size
);
3550 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) goto done
;
3551 if (!(config
= heap_alloc( size
))) goto done
;
3552 if (QueryServiceConfigW( service
, config
, size
, &size
)) goto done
;
3553 heap_free( config
);
3557 CloseServiceHandle( service
);
3561 static enum fill_status
fill_service( struct table
*table
, const struct expr
*cond
)
3563 struct record_service
*rec
;
3565 ENUM_SERVICE_STATUS_PROCESSW
*tmp
, *services
= NULL
;
3566 SERVICE_STATUS_PROCESS
*status
;
3567 WCHAR sysnameW
[MAX_COMPUTERNAME_LENGTH
+ 1];
3568 DWORD len
= ARRAY_SIZE( sysnameW
);
3569 UINT i
, row
= 0, offset
= 0, size
= 256, needed
, count
;
3570 enum fill_status fill_status
= FILL_STATUS_FAILED
;
3573 if (!(manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
))) return FILL_STATUS_FAILED
;
3574 if (!(services
= heap_alloc( size
))) goto done
;
3576 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3577 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3578 &count
, NULL
, NULL
);
3581 if (GetLastError() != ERROR_MORE_DATA
) goto done
;
3583 if (!(tmp
= heap_realloc( services
, size
))) goto done
;
3585 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3586 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3587 &count
, NULL
, NULL
);
3588 if (!ret
) goto done
;
3590 if (!resize_table( table
, count
, sizeof(*rec
) )) goto done
;
3592 GetComputerNameW( sysnameW
, &len
);
3593 fill_status
= FILL_STATUS_UNFILTERED
;
3595 for (i
= 0; i
< count
; i
++)
3597 QUERY_SERVICE_CONFIGW
*config
;
3599 if (!(config
= query_service_config( manager
, services
[i
].lpServiceName
))) continue;
3601 status
= &services
[i
].ServiceStatusProcess
;
3602 rec
= (struct record_service
*)(table
->data
+ offset
);
3603 rec
->accept_pause
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_PAUSE_CONTINUE
) ? -1 : 0;
3604 rec
->accept_stop
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_STOP
) ? -1 : 0;
3605 rec
->displayname
= heap_strdupW( services
[i
].lpDisplayName
);
3606 rec
->name
= heap_strdupW( services
[i
].lpServiceName
);
3607 rec
->process_id
= status
->dwProcessId
;
3608 rec
->servicetype
= get_service_type( status
->dwServiceType
);
3609 rec
->startmode
= get_service_startmode( config
->dwStartType
);
3610 rec
->state
= get_service_state( status
->dwCurrentState
);
3611 rec
->systemname
= heap_strdupW( sysnameW
);
3612 rec
->pause_service
= service_pause_service
;
3613 rec
->resume_service
= service_resume_service
;
3614 rec
->start_service
= service_start_service
;
3615 rec
->stop_service
= service_stop_service
;
3616 heap_free( config
);
3617 if (!match_row( table
, row
, cond
, &fill_status
))
3619 free_row_values( table
, row
);
3622 offset
+= sizeof(*rec
);
3626 TRACE("created %u rows\n", row
);
3627 table
->num_rows
= row
;
3630 CloseServiceHandle( manager
);
3631 heap_free( services
);
3635 static WCHAR
*get_accountname( LSA_TRANSLATED_NAME
*name
)
3637 if (!name
|| !name
->Name
.Buffer
) return NULL
;
3638 return heap_strdupW( name
->Name
.Buffer
);
3640 static struct array
*get_binaryrepresentation( PSID sid
, UINT len
)
3645 if (!(ret
= heap_alloc( sizeof(*ret
) ))) return NULL
;
3646 if (!(ptr
= heap_alloc( len
)))
3651 memcpy( ptr
, sid
, len
);
3652 ret
->elem_size
= sizeof(*ptr
);
3657 static WCHAR
*get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST
*domain
)
3659 if (!domain
|| !domain
->Domains
|| !domain
->Domains
->Name
.Buffer
) return NULL
;
3660 return heap_strdupW( domain
->Domains
->Name
.Buffer
);
3662 static const WCHAR
*find_sid_str( const struct expr
*cond
)
3664 const struct expr
*left
, *right
;
3665 const WCHAR
*ret
= NULL
;
3667 if (!cond
|| cond
->type
!= EXPR_COMPLEX
|| cond
->u
.expr
.op
!= OP_EQ
) return NULL
;
3669 left
= cond
->u
.expr
.left
;
3670 right
= cond
->u
.expr
.right
;
3671 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&& !wcsicmp( left
->u
.propval
->name
, L
"SID" ))
3673 ret
= right
->u
.sval
;
3675 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&& !wcsicmp( right
->u
.propval
->name
, L
"SID" ))
3682 static enum fill_status
fill_sid( struct table
*table
, const struct expr
*cond
)
3685 LSA_REFERENCED_DOMAIN_LIST
*domain
;
3686 LSA_TRANSLATED_NAME
*name
;
3688 LSA_OBJECT_ATTRIBUTES attrs
;
3690 struct record_sid
*rec
;
3693 if (!(str
= find_sid_str( cond
))) return FILL_STATUS_FAILED
;
3694 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3696 if (!ConvertStringSidToSidW( str
, &sid
)) return FILL_STATUS_FAILED
;
3697 len
= GetLengthSid( sid
);
3699 memset( &attrs
, 0, sizeof(attrs
) );
3700 attrs
.Length
= sizeof(attrs
);
3701 if (LsaOpenPolicy( NULL
, &attrs
, POLICY_ALL_ACCESS
, &handle
))
3704 return FILL_STATUS_FAILED
;
3706 if (LsaLookupSids( handle
, 1, &sid
, &domain
, &name
))
3710 return FILL_STATUS_FAILED
;
3713 rec
= (struct record_sid
*)table
->data
;
3714 rec
->accountname
= get_accountname( name
);
3715 rec
->binaryrepresentation
= get_binaryrepresentation( sid
, len
);
3716 rec
->referenceddomainname
= get_referenceddomainname( domain
);
3717 rec
->sid
= heap_strdupW( str
);
3718 rec
->sidlength
= len
;
3720 TRACE("created 1 row\n");
3721 table
->num_rows
= 1;
3723 LsaFreeMemory( domain
);
3724 LsaFreeMemory( name
);
3727 return FILL_STATUS_FILTERED
;
3730 static WCHAR
*get_systemenclosure_string( BYTE id
, const char *buf
, UINT len
)
3732 const struct smbios_header
*hdr
;
3733 const struct smbios_chassis
*chassis
;
3736 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
))) return NULL
;
3738 chassis
= (const struct smbios_chassis
*)hdr
;
3739 offset
= (const char *)chassis
- buf
+ chassis
->hdr
.length
;
3740 return get_smbios_string( id
, buf
, offset
, len
);
3743 static WCHAR
*get_systemenclosure_manufacturer( const char *buf
, UINT len
)
3745 WCHAR
*ret
= get_systemenclosure_string( 1, buf
, len
);
3746 if (!ret
) return heap_strdupW( L
"Wine" );
3750 static int get_systemenclosure_lockpresent( const char *buf
, UINT len
)
3752 const struct smbios_header
*hdr
;
3753 const struct smbios_chassis
*chassis
;
3755 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) return 0;
3757 chassis
= (const struct smbios_chassis
*)hdr
;
3758 return (chassis
->type
& 0x80) ? -1 : 0;
3761 static struct array
*dup_array( const struct array
*src
)
3764 if (!(dst
= heap_alloc( sizeof(*dst
) ))) return NULL
;
3765 if (!(dst
->ptr
= heap_alloc( src
->count
* src
->elem_size
)))
3770 memcpy( dst
->ptr
, src
->ptr
, src
->count
* src
->elem_size
);
3771 dst
->elem_size
= src
->elem_size
;
3772 dst
->count
= src
->count
;
3776 static struct array
*get_systemenclosure_chassistypes( const char *buf
, UINT len
)
3778 const struct smbios_header
*hdr
;
3779 const struct smbios_chassis
*chassis
;
3780 struct array
*ret
= NULL
;
3783 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) goto done
;
3784 chassis
= (const struct smbios_chassis
*)hdr
;
3786 if (!(ret
= heap_alloc( sizeof(*ret
) ))) goto done
;
3787 if (!(types
= heap_alloc( sizeof(*types
) )))
3792 types
[0] = chassis
->type
& ~0x80;
3794 ret
->elem_size
= sizeof(*types
);
3799 if (!ret
) ret
= dup_array( &systemenclosure_chassistypes_array
);
3803 static enum fill_status
fill_systemenclosure( struct table
*table
, const struct expr
*cond
)
3805 struct record_systemenclosure
*rec
;
3806 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3810 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3812 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
3813 if (!(buf
= heap_alloc( len
))) return FILL_STATUS_FAILED
;
3814 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
3816 rec
= (struct record_systemenclosure
*)table
->data
;
3817 rec
->caption
= L
"System Enclosure";
3818 rec
->chassistypes
= get_systemenclosure_chassistypes( buf
, len
);
3819 rec
->description
= L
"System Enclosure";
3820 rec
->lockpresent
= get_systemenclosure_lockpresent( buf
, len
);
3821 rec
->manufacturer
= get_systemenclosure_manufacturer( buf
, len
);
3822 rec
->name
= L
"System Enclosure";
3823 rec
->tag
= L
"System Enclosure 0";
3824 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3829 TRACE("created %u rows\n", row
);
3830 table
->num_rows
= row
;
3834 static WCHAR
*get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
3836 static const WCHAR fmtW
[] = L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
3837 UINT len
= sizeof(fmtW
) + 2;
3840 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
3841 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
3845 #define HW_VENDOR_AMD 0x1002
3846 #define HW_VENDOR_NVIDIA 0x10de
3847 #define HW_VENDOR_VMWARE 0x15ad
3848 #define HW_VENDOR_INTEL 0x8086
3850 static const WCHAR
*get_videocontroller_installeddriver( UINT vendorid
)
3852 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
3854 if (vendorid
== HW_VENDOR_AMD
) return L
"aticfx32.dll";
3855 else if (vendorid
== HW_VENDOR_NVIDIA
) return L
"nvd3dum.dll";
3856 else if (vendorid
== HW_VENDOR_INTEL
) return L
"igdudim32.dll";
3860 static BOOL
get_dxgi_adapter_desc( DXGI_ADAPTER_DESC
*desc
)
3862 IDXGIFactory
*factory
;
3863 IDXGIAdapter
*adapter
;
3866 memset( desc
, 0, sizeof(*desc
) );
3867 hr
= CreateDXGIFactory( &IID_IDXGIFactory
, (void **)&factory
);
3868 if (FAILED( hr
)) return FALSE
;
3870 hr
= IDXGIFactory_EnumAdapters( factory
, 0, &adapter
);
3873 IDXGIFactory_Release( factory
);
3877 hr
= IDXGIAdapter_GetDesc( adapter
, desc
);
3878 IDXGIAdapter_Release( adapter
);
3879 IDXGIFactory_Release( factory
);
3880 return SUCCEEDED( hr
);
3883 static enum fill_status
fill_videocontroller( struct table
*table
, const struct expr
*cond
)
3885 struct record_videocontroller
*rec
;
3886 DXGI_ADAPTER_DESC desc
;
3887 UINT row
= 0, hres
= 1024, vres
= 768, vidmem
= 512 * 1024 * 1024;
3888 const WCHAR
*name
= L
"VideoController1";
3889 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3892 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3894 if (get_dxgi_adapter_desc( &desc
))
3896 if (desc
.DedicatedVideoMemory
> UINT_MAX
) vidmem
= 0xfff00000;
3897 else vidmem
= desc
.DedicatedVideoMemory
;
3898 name
= desc
.Description
;
3901 rec
= (struct record_videocontroller
*)table
->data
;
3902 rec
->adapter_compatibility
= L
"(Standard display types)";
3903 rec
->adapter_dactype
= L
"Integrated RAMDAC";
3904 rec
->adapter_ram
= vidmem
;
3905 rec
->availability
= 3; /* Running or Full Power */
3906 rec
->config_errorcode
= 0; /* no error */
3907 rec
->caption
= heap_strdupW( name
);
3908 rec
->current_bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
3909 rec
->current_horizontalres
= hres
;
3910 rec
->current_refreshrate
= 0; /* default refresh rate */
3911 rec
->current_scanmode
= 2; /* Unknown */
3912 rec
->current_verticalres
= vres
;
3913 rec
->description
= heap_strdupW( name
);
3914 rec
->device_id
= L
"VideoController1";
3915 rec
->driverdate
= L
"20170101000000.000000+000";
3916 rec
->driverversion
= L
"1.0";
3917 rec
->installeddriver
= get_videocontroller_installeddriver( desc
.VendorId
);
3918 rec
->name
= heap_strdupW( name
);
3919 rec
->pnpdevice_id
= get_videocontroller_pnpdeviceid( &desc
);
3920 rec
->status
= L
"OK";
3921 rec
->videoarchitecture
= 2; /* Unknown */
3922 rec
->videomemorytype
= 2; /* Unknown */
3923 swprintf( mode
, ARRAY_SIZE( mode
), L
"%u x %u x %I64u colors", hres
, vres
, (UINT64
)1 << rec
->current_bitsperpixel
);
3924 rec
->videomodedescription
= heap_strdupW( mode
);
3925 rec
->videoprocessor
= heap_strdupW( name
);
3926 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3929 TRACE("created %u rows\n", row
);
3930 table
->num_rows
= row
;
3934 static WCHAR
*get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
3936 static const WCHAR fmtW
[] = L
"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
3937 UINT len
= sizeof(fmtW
) + 2;
3940 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
3941 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
3945 static enum fill_status
fill_sounddevice( struct table
*table
, const struct expr
*cond
)
3947 struct record_sounddevice
*rec
;
3948 DXGI_ADAPTER_DESC desc
;
3950 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3952 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3954 get_dxgi_adapter_desc( &desc
);
3956 rec
= (struct record_sounddevice
*)table
->data
;
3957 rec
->deviceid
= get_sounddevice_pnpdeviceid( &desc
);
3958 rec
->manufacturer
= L
"The Wine Project";
3959 rec
->name
= L
"Wine Audio Device";
3960 rec
->pnpdeviceid
= get_sounddevice_pnpdeviceid( &desc
);
3961 rec
->productname
= L
"Wine Audio Device";
3962 rec
->status
= L
"OK";
3963 rec
->statusinfo
= 3;
3964 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3967 TRACE("created %u rows\n", row
);
3968 table
->num_rows
= row
;
3972 #define C(c) sizeof(c)/sizeof(c[0]), c
3973 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
3974 static struct table builtin_classes
[] =
3976 { L
"__ASSOCIATORS", C(col_associator
), D(data_associator
) },
3977 { L
"__PARAMETERS", C(col_param
), D(data_param
) },
3978 { L
"__QUALIFIERS", C(col_qualifier
), D(data_qualifier
) },
3979 { L
"__SystemSecurity", C(col_systemsecurity
), D(data_systemsecurity
) },
3980 { L
"CIM_DataFile", C(col_datafile
), 0, 0, NULL
, fill_datafile
},
3981 { L
"CIM_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
3982 { L
"CIM_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
3983 { L
"StdRegProv", C(col_stdregprov
), D(data_stdregprov
) },
3984 { L
"Win32_BIOS", C(col_bios
), 0, 0, NULL
, fill_bios
},
3985 { L
"Win32_BaseBoard", C(col_baseboard
), 0, 0, NULL
, fill_baseboard
},
3986 { L
"Win32_CDROMDrive", C(col_cdromdrive
), 0, 0, NULL
, fill_cdromdrive
},
3987 { L
"Win32_ComputerSystem", C(col_compsys
), 0, 0, NULL
, fill_compsys
},
3988 { L
"Win32_ComputerSystemProduct", C(col_compsysproduct
), 0, 0, NULL
, fill_compsysproduct
},
3989 { L
"Win32_DesktopMonitor", C(col_desktopmonitor
), 0, 0, NULL
, fill_desktopmonitor
},
3990 { L
"Win32_Directory", C(col_directory
), 0, 0, NULL
, fill_directory
},
3991 { L
"Win32_DiskDrive", C(col_diskdrive
), 0, 0, NULL
, fill_diskdrive
},
3992 { L
"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition
), 0, 0, NULL
, fill_diskdrivetodiskpartition
},
3993 { L
"Win32_DiskPartition", C(col_diskpartition
), 0, 0, NULL
, fill_diskpartition
},
3994 { L
"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig
), 0, 0, NULL
, fill_displaycontrollerconfig
},
3995 { L
"Win32_IP4RouteTable", C(col_ip4routetable
), 0, 0, NULL
, fill_ip4routetable
},
3996 { L
"Win32_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
3997 { L
"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition
), 0, 0, NULL
, fill_logicaldisktopartition
},
3998 { L
"Win32_NetworkAdapter", C(col_networkadapter
), 0, 0, NULL
, fill_networkadapter
},
3999 { L
"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig
), 0, 0, NULL
, fill_networkadapterconfig
},
4000 { L
"Win32_OperatingSystem", C(col_operatingsystem
), 0, 0, NULL
, fill_operatingsystem
},
4001 { L
"Win32_PhysicalMedia", C(col_physicalmedia
), D(data_physicalmedia
) },
4002 { L
"Win32_PhysicalMemory", C(col_physicalmemory
), 0, 0, NULL
, fill_physicalmemory
},
4003 { L
"Win32_PnPEntity", C(col_pnpentity
), 0, 0, NULL
, fill_pnpentity
},
4004 { L
"Win32_Printer", C(col_printer
), 0, 0, NULL
, fill_printer
},
4005 { L
"Win32_Process", C(col_process
), 0, 0, NULL
, fill_process
},
4006 { L
"Win32_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4007 { L
"Win32_QuickFixEngineering", C(col_quickfixengineering
), D(data_quickfixengineering
) },
4008 { L
"Win32_SID", C(col_sid
), 0, 0, NULL
, fill_sid
},
4009 { L
"Win32_Service", C(col_service
), 0, 0, NULL
, fill_service
},
4010 { L
"Win32_SoundDevice", C(col_sounddevice
), 0, 0, NULL
, fill_sounddevice
},
4011 { L
"Win32_SystemEnclosure", C(col_systemenclosure
), 0, 0, NULL
, fill_systemenclosure
},
4012 { L
"Win32_VideoController", C(col_videocontroller
), 0, 0, NULL
, fill_videocontroller
},
4013 { L
"Win32_WinSAT", C(col_winsat
), D(data_winsat
) },
4018 void init_table_list( void )
4020 static struct list tables
= LIST_INIT( tables
);
4023 for (i
= 0; i
< ARRAY_SIZE(builtin_classes
); i
++) list_add_tail( &tables
, &builtin_classes
[i
].entry
);
4024 table_list
= &tables
;