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
25 #define WIN32_NO_STATUS
48 #include "wine/debug.h"
49 #include "wbemprox_private.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox
);
53 /* column definitions must be kept in sync with record structures below */
54 static const struct column col_associator
[] =
56 { L
"AssocClass", CIM_STRING
},
57 { L
"Class", CIM_STRING
},
58 { L
"Associator", CIM_STRING
}
60 static const struct column col_baseboard
[] =
62 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
63 { L
"Model", CIM_STRING
},
64 { L
"Name", CIM_STRING
},
65 { L
"Product", CIM_STRING
|COL_FLAG_DYNAMIC
},
66 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
67 { L
"Tag", CIM_STRING
|COL_FLAG_KEY
},
68 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
70 static const struct column col_bios
[] =
72 { L
"CurrentLanguage", CIM_STRING
},
73 { L
"Description", CIM_STRING
},
74 { L
"EmbeddedControllerMajorVersion", CIM_UINT8
},
75 { L
"EmbeddedControllerMinorVersion", CIM_UINT8
},
76 { L
"IdentificationCode", CIM_STRING
},
77 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
78 { L
"Name", CIM_STRING
},
79 { L
"ReleaseDate", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
80 { L
"SerialNumber", CIM_STRING
},
81 { L
"SMBIOSBIOSVersion", CIM_STRING
|COL_FLAG_DYNAMIC
},
82 { L
"SMBIOSMajorVersion", CIM_UINT16
},
83 { L
"SMBIOSMinorVersion", CIM_UINT16
},
84 { L
"SystemBiosMajorVersion", CIM_UINT8
},
85 { L
"SystemBiosMinorVersion", CIM_UINT8
},
86 { L
"Version", CIM_STRING
|COL_FLAG_KEY
},
88 static const struct column col_cdromdrive
[] =
90 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
91 { L
"Drive", CIM_STRING
|COL_FLAG_DYNAMIC
},
92 { L
"MediaType", CIM_STRING
},
93 { L
"Name", CIM_STRING
},
94 { L
"PNPDeviceID", CIM_STRING
},
96 static const struct column col_compsys
[] =
98 { L
"Description", CIM_STRING
},
99 { L
"Domain", CIM_STRING
},
100 { L
"DomainRole", CIM_UINT16
},
101 { L
"HypervisorPresent", CIM_BOOLEAN
},
102 { L
"Manufacturer", CIM_STRING
},
103 { L
"Model", CIM_STRING
},
104 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
105 { L
"NumberOfLogicalProcessors", CIM_UINT32
},
106 { L
"NumberOfProcessors", CIM_UINT32
},
107 { L
"SystemType", CIM_STRING
},
108 { L
"TotalPhysicalMemory", CIM_UINT64
},
109 { L
"UserName", CIM_STRING
|COL_FLAG_DYNAMIC
},
111 static const struct column col_compsysproduct
[] =
113 { L
"IdentifyingNumber", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
114 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
115 { L
"SKUNumber", CIM_STRING
},
116 { L
"UUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
117 { L
"Vendor", CIM_STRING
|COL_FLAG_DYNAMIC
},
118 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
120 static const struct column col_datafile
[] =
122 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
123 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
125 static const struct column col_desktopmonitor
[] =
127 { L
"Name", CIM_STRING
},
128 { L
"PixelsPerXLogicalInch", CIM_UINT32
},
130 static const struct column col_directory
[] =
132 { L
"AccessMask", CIM_UINT32
},
133 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
135 static const struct column col_diskdrive
[] =
137 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
138 { L
"Index", CIM_UINT32
},
139 { L
"InterfaceType", CIM_STRING
},
140 { L
"Manufacturer", CIM_STRING
},
141 { L
"MediaType", CIM_STRING
},
142 { L
"Model", CIM_STRING
},
143 { L
"PNPDeviceID", CIM_STRING
},
144 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
145 { L
"Size", CIM_UINT64
},
147 static const struct column col_diskdrivetodiskpartition
[] =
149 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
150 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
152 static const struct column col_diskpartition
[] =
154 { L
"Bootable", CIM_BOOLEAN
},
155 { L
"BootPartition", CIM_BOOLEAN
},
156 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
157 { L
"DiskIndex", CIM_UINT32
},
158 { L
"Index", CIM_UINT32
},
159 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
160 { L
"Size", CIM_UINT64
},
161 { L
"StartingOffset", CIM_UINT64
},
162 { L
"Type", CIM_STRING
|COL_FLAG_DYNAMIC
},
164 static const struct column col_displaycontrollerconfig
[] =
166 { L
"BitsPerPixel", CIM_UINT32
},
167 { L
"Caption", CIM_STRING
},
168 { L
"HorizontalResolution", CIM_UINT32
},
169 { L
"Name", CIM_STRING
|COL_FLAG_KEY
},
170 { L
"VerticalResolution", CIM_UINT32
},
172 static const struct column col_ip4routetable
[] =
174 { L
"Destination", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
175 { L
"InterfaceIndex", CIM_SINT32
|COL_FLAG_KEY
},
176 { L
"NextHop", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
178 static const struct column col_logicaldisk
[] =
180 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
181 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
182 { L
"DriveType", CIM_UINT32
},
183 { L
"FileSystem", CIM_STRING
|COL_FLAG_DYNAMIC
},
184 { L
"FreeSpace", CIM_UINT64
},
185 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
186 { L
"Size", CIM_UINT64
},
187 { L
"VolumeName", CIM_STRING
|COL_FLAG_DYNAMIC
},
188 { L
"VolumeSerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
190 static const struct column col_logicaldisktopartition
[] =
192 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
193 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
195 static const struct column col_networkadapter
[] =
197 { L
"AdapterType", CIM_STRING
},
198 { L
"AdapterTypeID", CIM_UINT16
},
199 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
200 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
201 { L
"GUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
202 { L
"Index", CIM_UINT32
},
203 { L
"InterfaceIndex", CIM_UINT32
},
204 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
205 { L
"Manufacturer", CIM_STRING
},
206 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
207 { L
"NetConnectionID", CIM_STRING
},
208 { L
"NetConnectionStatus", CIM_UINT16
},
209 { L
"NetEnabled", CIM_BOOLEAN
},
210 { L
"PhysicalAdapter", CIM_BOOLEAN
},
211 { L
"PNPDeviceID", CIM_STRING
},
212 { L
"ServiceName", CIM_STRING
|COL_FLAG_DYNAMIC
},
213 { L
"Speed", CIM_UINT64
},
215 static const struct column col_networkadapterconfig
[] =
217 { L
"DefaultIPGateway", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
218 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
219 { L
"DHCPEnabled", CIM_BOOLEAN
},
220 { L
"DNSDomain", CIM_STRING
},
221 { L
"DNSHostName", CIM_STRING
|COL_FLAG_DYNAMIC
},
222 { L
"DNSServerSearchOrder", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
223 { L
"Index", CIM_UINT32
|COL_FLAG_KEY
},
224 { L
"IPAddress", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
225 { L
"IPConnectionMetric", CIM_UINT32
},
226 { L
"IPEnabled", CIM_BOOLEAN
},
227 { L
"IPSubnet", CIM_STRING
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
228 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
229 { L
"SettingID", CIM_STRING
|COL_FLAG_DYNAMIC
},
231 static const struct column col_operatingsystem
[] =
233 { L
"BootDevice", CIM_STRING
},
234 { L
"BuildNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
235 { L
"BuildType", CIM_STRING
|COL_FLAG_DYNAMIC
},
236 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
237 { L
"CodeSet", CIM_STRING
|COL_FLAG_DYNAMIC
},
238 { L
"CountryCode", CIM_STRING
|COL_FLAG_DYNAMIC
},
239 { L
"CSDVersion", CIM_STRING
|COL_FLAG_DYNAMIC
},
240 { L
"CSName", CIM_STRING
|COL_FLAG_DYNAMIC
},
241 { L
"CurrentTimeZone", CIM_SINT16
},
242 { L
"FreePhysicalMemory", CIM_UINT64
},
243 { L
"FreeVirtualMemory", CIM_UINT64
},
244 { L
"InstallDate", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
245 { L
"LastBootUpTime", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
246 { L
"LocalDateTime", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
247 { L
"Locale", CIM_STRING
|COL_FLAG_DYNAMIC
},
248 { L
"Manufacturer", CIM_STRING
},
249 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
250 { L
"OperatingSystemSKU", CIM_UINT32
},
251 { L
"Organization", CIM_STRING
|COL_FLAG_DYNAMIC
},
252 { L
"OSArchitecture", CIM_STRING
},
253 { L
"OSLanguage", CIM_UINT32
},
254 { L
"OSProductSuite", CIM_UINT32
},
255 { L
"OSType", CIM_UINT16
},
256 { L
"Primary", CIM_BOOLEAN
},
257 { L
"ProductType", CIM_UINT32
},
258 { L
"RegisteredUser", CIM_STRING
|COL_FLAG_DYNAMIC
},
259 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
260 { L
"ServicePackMajorVersion", CIM_UINT16
},
261 { L
"ServicePackMinorVersion", CIM_UINT16
},
262 { L
"Status", CIM_STRING
},
263 { L
"SuiteMask", CIM_UINT32
},
264 { L
"SystemDirectory", CIM_STRING
|COL_FLAG_DYNAMIC
},
265 { L
"SystemDrive", CIM_STRING
|COL_FLAG_DYNAMIC
},
266 { L
"TotalVirtualMemorySize", CIM_UINT64
},
267 { L
"TotalVisibleMemorySize", CIM_UINT64
},
268 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
269 { L
"WindowsDirectory", CIM_STRING
|COL_FLAG_DYNAMIC
},
271 static const struct column col_pagefileusage
[] =
273 { L
"Name", CIM_STRING
},
275 static const struct column col_param
[] =
277 { L
"Class", CIM_STRING
},
278 { L
"Method", CIM_STRING
},
279 { L
"Direction", CIM_SINT32
},
280 { L
"Parameter", CIM_STRING
},
281 { L
"Type", CIM_UINT32
},
282 { L
"DefaultValue", CIM_UINT32
},
284 static const struct column col_physicalmedia
[] =
286 { L
"SerialNumber", CIM_STRING
},
287 { L
"Tag", CIM_STRING
},
289 static const struct column col_physicalmemory
[] =
291 { L
"BankLabel", CIM_STRING
},
292 { L
"Capacity", CIM_UINT64
},
293 { L
"Caption", CIM_STRING
},
294 { L
"ConfiguredClockSpeed", CIM_UINT32
},
295 { L
"DeviceLocator", CIM_STRING
},
296 { L
"FormFactor", CIM_UINT16
},
297 { L
"MemoryType", CIM_UINT16
},
298 { L
"PartNumber", CIM_STRING
},
299 { L
"SerialNumber", CIM_STRING
},
301 static const struct column col_pnpentity
[] =
303 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
},
304 { L
"Manufacturer", CIM_STRING
},
305 { L
"Name", CIM_STRING
},
307 static const struct column col_printer
[] =
309 { L
"Attributes", CIM_UINT32
},
310 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
311 { L
"DriverName", CIM_STRING
|COL_FLAG_DYNAMIC
},
312 { L
"HorizontalResolution", CIM_UINT32
},
313 { L
"Local", CIM_BOOLEAN
},
314 { L
"Location", CIM_STRING
|COL_FLAG_DYNAMIC
},
315 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
316 { L
"Network", CIM_BOOLEAN
},
317 { L
"PortName", CIM_STRING
|COL_FLAG_DYNAMIC
},
319 static const struct column col_process
[] =
321 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
322 { L
"CommandLine", CIM_STRING
|COL_FLAG_DYNAMIC
},
323 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
324 { L
"Handle", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
325 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
326 { L
"ParentProcessID", CIM_UINT32
},
327 { L
"ProcessID", CIM_UINT32
},
328 { L
"ThreadCount", CIM_UINT32
},
329 { L
"WorkingSetSize", CIM_UINT64
},
331 { L
"Create", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
332 { L
"GetOwner", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
334 static const struct column col_processor
[] =
336 { L
"AddressWidth", CIM_UINT16
},
337 { L
"Architecture", CIM_UINT16
},
338 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
339 { L
"CpuStatus", CIM_UINT16
},
340 { L
"CurrentClockSpeed", CIM_UINT32
},
341 { L
"DataWidth", CIM_UINT16
},
342 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
343 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
344 { L
"Family", CIM_UINT16
},
345 { L
"Level", CIM_UINT16
},
346 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
347 { L
"MaxClockSpeed", CIM_UINT32
},
348 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
349 { L
"NumberOfCores", CIM_UINT32
},
350 { L
"NumberOfLogicalProcessors", CIM_UINT32
},
351 { L
"ProcessorId", CIM_STRING
|COL_FLAG_DYNAMIC
},
352 { L
"ProcessorType", CIM_UINT16
},
353 { L
"Revision", CIM_UINT16
},
354 { L
"UniqueId", CIM_STRING
},
355 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
357 static const struct column col_qualifier
[] =
359 { L
"Class", CIM_STRING
},
360 { L
"Member", CIM_STRING
},
361 { L
"Type", CIM_UINT32
},
362 { L
"Flavor", CIM_SINT32
},
363 { L
"Name", CIM_STRING
},
364 { L
"IntegerValue", CIM_SINT32
},
365 { L
"StringValue", CIM_STRING
},
366 { L
"BoolValue", CIM_BOOLEAN
},
368 static const struct column col_quickfixengineering
[] =
370 { L
"Caption", CIM_STRING
},
371 { L
"Description", CIM_STRING
},
372 { L
"HotFixID", CIM_STRING
|COL_FLAG_KEY
},
373 { L
"InstalledBy", CIM_STRING
},
374 { L
"InstalledOn", CIM_STRING
},
376 static const struct column col_rawsmbiostables
[] =
378 { L
"SMBiosData", CIM_UINT8
|CIM_FLAG_ARRAY
},
380 static const struct column col_service
[] =
382 { L
"AcceptPause", CIM_BOOLEAN
},
383 { L
"AcceptStop", CIM_BOOLEAN
},
384 { L
"DisplayName", CIM_STRING
|COL_FLAG_DYNAMIC
},
385 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
386 { L
"ProcessID", CIM_UINT32
},
387 { L
"ServiceType", CIM_STRING
},
388 { L
"StartMode", CIM_STRING
},
389 { L
"State", CIM_STRING
},
390 { L
"SystemName", CIM_STRING
|COL_FLAG_DYNAMIC
},
392 { L
"PauseService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
393 { L
"ResumeService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
394 { L
"StartService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
395 { L
"StopService", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
397 static const struct column col_sid
[] =
399 { L
"AccountName", CIM_STRING
|COL_FLAG_DYNAMIC
},
400 { L
"BinaryRepresentation", CIM_UINT8
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
401 { L
"ReferencedDomainName", CIM_STRING
|COL_FLAG_DYNAMIC
},
402 { L
"SID", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
403 { L
"SidLength", CIM_UINT32
},
405 static const struct column col_softwarelicensingproduct
[] =
407 { L
"LicenseIsAddon", CIM_BOOLEAN
},
408 { L
"LicenseStatus", CIM_UINT32
},
410 static const struct column col_sounddevice
[] =
412 { L
"Caption", CIM_STRING
},
413 { L
"DeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
414 { L
"Manufacturer", CIM_STRING
},
415 { L
"Name", CIM_STRING
},
416 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
417 { L
"ProductName", CIM_STRING
},
418 { L
"Status", CIM_STRING
},
419 { L
"StatusInfo", CIM_UINT16
},
421 static const struct column col_stdregprov
[] =
423 { L
"CreateKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
424 { L
"EnumKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
425 { L
"EnumValues", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
426 { L
"GetBinaryValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
427 { L
"GetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
428 { L
"SetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
429 { L
"SetDWORDValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
430 { L
"DeleteKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
432 static const struct column col_systemenclosure
[] =
434 { L
"Caption", CIM_STRING
},
435 { L
"ChassisTypes", CIM_UINT16
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
436 { L
"Description", CIM_STRING
},
437 { L
"LockPresent", CIM_BOOLEAN
},
438 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
439 { L
"Name", CIM_STRING
},
440 { L
"Tag", CIM_STRING
},
442 static const struct column col_systemsecurity
[] =
444 { L
"GetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
445 { L
"SetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
447 static const struct column col_sysrestore
[] =
449 { L
"CreationTime", CIM_STRING
},
450 { L
"Description", CIM_STRING
},
451 { L
"EventType", CIM_UINT32
},
452 { L
"RestorePointType", CIM_UINT32
},
453 { L
"SequenceNumber", CIM_UINT32
},
455 { L
"CreateRestorePoint", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
456 { L
"Disable", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
457 { L
"Enable", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
458 { L
"GetLastRestoreStatus", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
459 { L
"Restore", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
461 static const struct column col_videocontroller
[] =
463 { L
"AdapterCompatibility", CIM_STRING
},
464 { L
"AdapterDACType", CIM_STRING
},
465 { L
"AdapterRAM", CIM_UINT32
},
466 { L
"Availability", CIM_UINT16
},
467 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
468 { L
"ConfigManagerErrorCode", CIM_UINT32
},
469 { L
"CurrentBitsPerPixel", CIM_UINT32
},
470 { L
"CurrentHorizontalResolution", CIM_UINT32
},
471 { L
"CurrentRefreshRate", CIM_UINT32
},
472 { L
"CurrentScanMode", CIM_UINT16
},
473 { L
"CurrentVerticalResolution", CIM_UINT32
},
474 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
475 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
476 { L
"DriverDate", CIM_DATETIME
},
477 { L
"DriverVersion", CIM_STRING
},
478 { L
"InstalledDisplayDrivers", CIM_STRING
},
479 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
480 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
481 { L
"Status", CIM_STRING
},
482 { L
"VideoArchitecture", CIM_UINT16
},
483 { L
"VideoMemoryType", CIM_UINT16
},
484 { L
"VideoModeDescription", CIM_STRING
|COL_FLAG_DYNAMIC
},
485 { L
"VideoProcessor", CIM_STRING
|COL_FLAG_DYNAMIC
},
488 static const struct column col_volume
[] =
490 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
491 { L
"DriveLetter", CIM_STRING
|COL_FLAG_DYNAMIC
},
494 static const struct column col_winsat
[] =
496 { L
"CPUScore", CIM_REAL32
},
497 { L
"D3DScore", CIM_REAL32
},
498 { L
"DiskScore", CIM_REAL32
},
499 { L
"GraphicsScore", CIM_REAL32
},
500 { L
"MemoryScore", CIM_REAL32
},
501 { L
"TimeTaken", CIM_STRING
|COL_FLAG_KEY
},
502 { L
"WinSATAssessmentState", CIM_UINT32
},
503 { L
"WinSPRLevel", CIM_REAL32
},
506 #include "pshpack1.h"
507 struct record_associator
509 const WCHAR
*assocclass
;
511 const WCHAR
*associator
;
513 struct record_baseboard
515 const WCHAR
*manufacturer
;
518 const WCHAR
*product
;
519 const WCHAR
*serialnumber
;
521 const WCHAR
*version
;
525 const WCHAR
*currentlanguage
;
526 const WCHAR
*description
;
527 UINT8 ecmajorversion
;
528 UINT8 ecminorversion
;
529 const WCHAR
*identificationcode
;
530 const WCHAR
*manufacturer
;
532 const WCHAR
*releasedate
;
533 const WCHAR
*serialnumber
;
534 const WCHAR
*smbiosbiosversion
;
535 UINT16 smbiosmajorversion
;
536 UINT16 smbiosminorversion
;
537 UINT8 systembiosmajorversion
;
538 UINT8 systembiosminorversion
;
539 const WCHAR
*version
;
541 struct record_cdromdrive
543 const WCHAR
*device_id
;
545 const WCHAR
*mediatype
;
547 const WCHAR
*pnpdevice_id
;
549 struct record_computersystem
551 const WCHAR
*description
;
554 int hypervisorpresent
;
555 const WCHAR
*manufacturer
;
558 UINT32 num_logical_processors
;
559 UINT32 num_processors
;
560 const WCHAR
*systemtype
;
561 UINT64 total_physical_memory
;
562 const WCHAR
*username
;
564 struct record_computersystemproduct
566 const WCHAR
*identifyingnumber
;
568 const WCHAR
*skunumber
;
571 const WCHAR
*version
;
573 struct record_datafile
576 const WCHAR
*version
;
578 struct record_desktopmonitor
581 UINT32 pixelsperxlogicalinch
;
583 struct record_directory
588 struct record_diskdrive
590 const WCHAR
*device_id
;
592 const WCHAR
*interfacetype
;
593 const WCHAR
*manufacturer
;
594 const WCHAR
*mediatype
;
596 const WCHAR
*pnpdevice_id
;
597 const WCHAR
*serialnumber
;
600 struct record_diskdrivetodiskpartition
602 const WCHAR
*antecedent
;
603 const WCHAR
*dependent
;
605 struct record_diskpartition
609 const WCHAR
*device_id
;
612 const WCHAR
*pnpdevice_id
;
614 UINT64 startingoffset
;
617 struct record_displaycontrollerconfig
620 const WCHAR
*caption
;
621 UINT32 horizontalresolution
;
623 UINT32 verticalresolution
;
625 struct record_ip4routetable
627 const WCHAR
*destination
;
628 INT32 interfaceindex
;
629 const WCHAR
*nexthop
;
631 struct record_logicaldisk
633 const WCHAR
*caption
;
634 const WCHAR
*device_id
;
636 const WCHAR
*filesystem
;
640 const WCHAR
*volumename
;
641 const WCHAR
*volumeserialnumber
;
643 struct record_logicaldisktopartition
645 const WCHAR
*antecedent
;
646 const WCHAR
*dependent
;
648 struct record_networkadapter
650 const WCHAR
*adaptertype
;
651 UINT16 adaptertypeid
;
652 const WCHAR
*description
;
653 const WCHAR
*device_id
;
656 UINT32 interface_index
;
657 const WCHAR
*mac_address
;
658 const WCHAR
*manufacturer
;
660 const WCHAR
*netconnection_id
;
661 UINT16 netconnection_status
;
664 const WCHAR
*pnpdevice_id
;
665 const WCHAR
*servicename
;
668 struct record_networkadapterconfig
670 const struct array
*defaultipgateway
;
671 const WCHAR
*description
;
673 const WCHAR
*dnsdomain
;
674 const WCHAR
*dnshostname
;
675 const struct array
*dnsserversearchorder
;
677 const struct array
*ipaddress
;
678 UINT32 ipconnectionmetric
;
680 const struct array
*ipsubnet
;
681 const WCHAR
*mac_address
;
682 const WCHAR
*settingid
;
684 struct record_operatingsystem
686 const WCHAR
*bootdevice
;
687 const WCHAR
*buildnumber
;
688 const WCHAR
*buildtype
;
689 const WCHAR
*caption
;
690 const WCHAR
*codeset
;
691 const WCHAR
*countrycode
;
692 const WCHAR
*csdversion
;
694 INT16 currenttimezone
;
695 UINT64 freephysicalmemory
;
696 UINT64 freevirtualmemory
;
697 const WCHAR
*installdate
;
698 const WCHAR
*lastbootuptime
;
699 const WCHAR
*localdatetime
;
701 const WCHAR
*manufacturer
;
703 UINT32 operatingsystemsku
;
704 const WCHAR
*organization
;
705 const WCHAR
*osarchitecture
;
707 UINT32 osproductsuite
;
711 const WCHAR
*registereduser
;
712 const WCHAR
*serialnumber
;
713 UINT16 servicepackmajor
;
714 UINT16 servicepackminor
;
717 const WCHAR
*systemdirectory
;
718 const WCHAR
*systemdrive
;
719 UINT64 totalvirtualmemorysize
;
720 UINT64 totalvisiblememorysize
;
721 const WCHAR
*version
;
722 const WCHAR
*windowsdirectory
;
724 struct record_pagefileusage
733 const WCHAR
*parameter
;
737 struct record_physicalmedia
739 const WCHAR
*serialnumber
;
742 struct record_physicalmemory
744 const WCHAR
*banklabel
;
746 const WCHAR
*caption
;
747 UINT32 configuredclockspeed
;
748 const WCHAR
*devicelocator
;
751 const WCHAR
*partnumber
;
754 struct record_pnpentity
756 const WCHAR
*device_id
;
757 const WCHAR
*manufacturer
;
760 struct record_printer
763 const WCHAR
*device_id
;
764 const WCHAR
*drivername
;
765 UINT32 horizontalresolution
;
767 const WCHAR
*location
;
770 const WCHAR
*portname
;
772 struct record_process
774 const WCHAR
*caption
;
775 const WCHAR
*commandline
;
776 const WCHAR
*description
;
782 UINT64 workingsetsize
;
784 class_method
*create
;
785 class_method
*get_owner
;
787 struct record_processor
791 const WCHAR
*caption
;
793 UINT32 currentclockspeed
;
795 const WCHAR
*description
;
796 const WCHAR
*device_id
;
799 const WCHAR
*manufacturer
;
800 UINT32 maxclockspeed
;
803 UINT32 num_logical_processors
;
804 const WCHAR
*processor_id
;
805 UINT16 processortype
;
807 const WCHAR
*unique_id
;
808 const WCHAR
*version
;
810 struct record_qualifier
818 const WCHAR
*strvalue
;
821 struct record_quickfixengineering
823 const WCHAR
*caption
;
824 const WCHAR
*description
;
825 const WCHAR
*hotfixid
;
826 const WCHAR
*installedby
;
827 const WCHAR
*installedon
;
829 struct record_rawsmbiostables
831 const struct array
*smbiosdata
;
833 struct record_service
837 const WCHAR
*displayname
;
840 const WCHAR
*servicetype
;
841 const WCHAR
*startmode
;
843 const WCHAR
*systemname
;
845 class_method
*pause_service
;
846 class_method
*resume_service
;
847 class_method
*start_service
;
848 class_method
*stop_service
;
852 const WCHAR
*accountname
;
853 const struct array
*binaryrepresentation
;
854 const WCHAR
*referenceddomainname
;
858 struct record_softwarelicensingproduct
860 int license_is_addon
;
861 UINT32 license_status
;
863 struct record_sounddevice
865 const WCHAR
*caption
;
866 const WCHAR
*deviceid
;
867 const WCHAR
*manufacturer
;
869 const WCHAR
*pnpdeviceid
;
870 const WCHAR
*productname
;
874 struct record_stdregprov
876 class_method
*createkey
;
877 class_method
*enumkey
;
878 class_method
*enumvalues
;
879 class_method
*getbinaryvalue
;
880 class_method
*getstringvalue
;
881 class_method
*setstringvalue
;
882 class_method
*setdwordvalue
;
883 class_method
*deletekey
;
885 struct record_sysrestore
887 const WCHAR
*creation_time
;
888 const WCHAR
*description
;
890 UINT32 restore_point_type
;
891 UINT32 sequence_number
;
892 class_method
*create_restore_point
;
893 class_method
*disable_restore
;
894 class_method
*enable_restore
;
895 class_method
*get_last_restore_status
;
896 class_method
*restore
;
898 struct record_systemsecurity
903 struct record_systemenclosure
905 const WCHAR
*caption
;
906 const struct array
*chassistypes
;
907 const WCHAR
*description
;
909 const WCHAR
*manufacturer
;
913 struct record_videocontroller
915 const WCHAR
*adapter_compatibility
;
916 const WCHAR
*adapter_dactype
;
919 const WCHAR
*caption
;
920 UINT32 config_errorcode
;
921 UINT32 current_bitsperpixel
;
922 UINT32 current_horizontalres
;
923 UINT32 current_refreshrate
;
924 UINT16 current_scanmode
;
925 UINT32 current_verticalres
;
926 const WCHAR
*description
;
927 const WCHAR
*device_id
;
928 const WCHAR
*driverdate
;
929 const WCHAR
*driverversion
;
930 const WCHAR
*installeddriver
;
932 const WCHAR
*pnpdevice_id
;
934 UINT16 videoarchitecture
;
935 UINT16 videomemorytype
;
936 const WCHAR
*videomodedescription
;
937 const WCHAR
*videoprocessor
;
942 const WCHAR
*deviceid
;
943 const WCHAR
*driveletter
;
953 const WCHAR
*timetaken
;
954 UINT32 winsatassessmentstate
;
959 static const struct record_associator data_associator
[] =
961 { L
"Win32_DiskDriveToDiskPartition", L
"Win32_DiskPartition", L
"Win32_DiskDrive" },
962 { L
"Win32_LogicalDiskToPartition", L
"Win32_LogicalDisk", L
"Win32_DiskPartition" },
964 static const struct record_pagefileusage data_pagefileusage
[] =
966 { L
"c:\\pagefile.sys", },
968 static const struct record_param data_param
[] =
970 { L
"__SystemSecurity", L
"GetSD", -1, L
"ReturnValue", CIM_UINT32
},
971 { L
"__SystemSecurity", L
"GetSD", -1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
972 { L
"__SystemSecurity", L
"SetSD", 1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
973 { L
"__SystemSecurity", L
"SetSD", -1, L
"ReturnValue", CIM_UINT32
},
974 { L
"StdRegProv", L
"CreateKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
975 { L
"StdRegProv", L
"CreateKey", 1, L
"sSubKeyName", CIM_STRING
},
976 { L
"StdRegProv", L
"CreateKey", -1, L
"ReturnValue", CIM_UINT32
},
977 { L
"StdRegProv", L
"DeleteKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
978 { L
"StdRegProv", L
"DeleteKey", 1, L
"sSubKeyName", CIM_STRING
},
979 { L
"StdRegProv", L
"DeleteKey", -1, L
"ReturnValue", CIM_UINT32
},
980 { L
"StdRegProv", L
"EnumKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
981 { L
"StdRegProv", L
"EnumKey", 1, L
"sSubKeyName", CIM_STRING
},
982 { L
"StdRegProv", L
"EnumKey", -1, L
"ReturnValue", CIM_UINT32
},
983 { L
"StdRegProv", L
"EnumKey", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
984 { L
"StdRegProv", L
"EnumValues", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
985 { L
"StdRegProv", L
"EnumValues", 1, L
"sSubKeyName", CIM_STRING
},
986 { L
"StdRegProv", L
"EnumValues", -1, L
"ReturnValue", CIM_UINT32
},
987 { L
"StdRegProv", L
"EnumValues", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
988 { L
"StdRegProv", L
"EnumValues", -1, L
"Types", CIM_SINT32
|CIM_FLAG_ARRAY
},
989 { L
"StdRegProv", L
"GetBinaryValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
990 { L
"StdRegProv", L
"GetBinaryValue", 1, L
"sSubKeyName", CIM_STRING
},
991 { L
"StdRegProv", L
"GetBinaryValue", 1, L
"sValueName", CIM_STRING
},
992 { L
"StdRegProv", L
"GetBinaryValue", -1, L
"ReturnValue", CIM_UINT32
},
993 { L
"StdRegProv", L
"GetBinaryValue", -1, L
"uValue", CIM_UINT8
|CIM_FLAG_ARRAY
},
994 { L
"StdRegProv", L
"GetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
995 { L
"StdRegProv", L
"GetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
996 { L
"StdRegProv", L
"GetStringValue", 1, L
"sValueName", CIM_STRING
},
997 { L
"StdRegProv", L
"GetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
998 { L
"StdRegProv", L
"GetStringValue", -1, L
"sValue", CIM_STRING
},
999 { L
"StdRegProv", L
"SetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
1000 { L
"StdRegProv", L
"SetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
1001 { L
"StdRegProv", L
"SetStringValue", 1, L
"sValueName", CIM_STRING
},
1002 { L
"StdRegProv", L
"SetStringValue", 1, L
"sValue", CIM_STRING
},
1003 { L
"StdRegProv", L
"SetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
1004 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
1005 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"sSubKeyName", CIM_STRING
},
1006 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"sValueName", CIM_STRING
},
1007 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"uValue", CIM_UINT32
},
1008 { L
"StdRegProv", L
"SetDWORDValue", -1, L
"ReturnValue", CIM_UINT32
},
1009 { L
"SystemRestore", L
"Disable", 1, L
"Drive", CIM_STRING
},
1010 { L
"SystemRestore", L
"Disable", -1, L
"ReturnValue", CIM_UINT32
},
1011 { L
"SystemRestore", L
"Enable", 1, L
"Drive", CIM_STRING
},
1012 { L
"SystemRestore", L
"Enable", -1, L
"ReturnValue", CIM_UINT32
},
1013 { L
"Win32_Process", L
"Create", 1, L
"CommandLine", CIM_STRING
},
1014 { L
"Win32_Process", L
"Create", 1, L
"CurrentDirectory", CIM_STRING
},
1015 { L
"Win32_Process", L
"Create", -1, L
"ProcessId", CIM_UINT32
},
1016 { L
"Win32_Process", L
"Create", -1, L
"ReturnValue", CIM_UINT32
},
1017 { L
"Win32_Process", L
"GetOwner", -1, L
"ReturnValue", CIM_UINT32
},
1018 { L
"Win32_Process", L
"GetOwner", -1, L
"User", CIM_STRING
},
1019 { L
"Win32_Process", L
"GetOwner", -1, L
"Domain", CIM_STRING
},
1020 { L
"Win32_Service", L
"PauseService", -1, L
"ReturnValue", CIM_UINT32
},
1021 { L
"Win32_Service", L
"ResumeService", -1, L
"ReturnValue", CIM_UINT32
},
1022 { L
"Win32_Service", L
"StartService", -1, L
"ReturnValue", CIM_UINT32
},
1023 { L
"Win32_Service", L
"StopService", -1, L
"ReturnValue", CIM_UINT32
},
1026 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1027 WBEM_FLAVOR_ORIGIN_PROPAGATED)
1029 static const struct record_physicalmedia data_physicalmedia
[] =
1031 { L
"WINEHDISK", L
"\\\\.\\PHYSICALDRIVE0" }
1034 static const struct record_rawsmbiostables data_rawsmbiostables
[] =
1039 static const struct record_qualifier data_qualifier
[] =
1041 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"User", CIM_SINT32
, FLAVOR_ID
, L
"ID", 0 },
1042 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"Domain", CIM_SINT32
, FLAVOR_ID
, L
"ID", 1 }
1045 static const struct record_quickfixengineering data_quickfixengineering
[] =
1047 { L
"http://winehq.org", L
"Update", L
"KB1234567", L
"", L
"22/2/2022" },
1050 static const struct record_softwarelicensingproduct data_softwarelicensingproduct
[] =
1055 static const struct record_stdregprov data_stdregprov
[] =
1061 reg_get_binaryvalue
,
1062 reg_get_stringvalue
,
1063 reg_set_stringvalue
,
1069 static const struct record_sysrestore data_sysrestore
[] =
1071 { NULL
, NULL
, 0, 0, 0, sysrestore_create
, sysrestore_disable
, sysrestore_enable
, sysrestore_get_last_status
,
1072 sysrestore_restore
}
1075 static UINT16 systemenclosure_chassistypes
[] =
1079 static const struct array systemenclosure_chassistypes_array
=
1081 sizeof(*systemenclosure_chassistypes
),
1082 ARRAY_SIZE(systemenclosure_chassistypes
),
1083 &systemenclosure_chassistypes
1085 static const struct record_systemsecurity data_systemsecurity
[] =
1087 { security_get_sd
, security_set_sd
}
1089 static const struct record_winsat data_winsat
[] =
1091 { 8.0f
, 8.0f
, 8.0f
, 8.0f
, 8.0f
, L
"MostRecentAssessment", 1 /* Valid */, 8.0f
},
1094 /* check if row matches condition and update status */
1095 static BOOL
match_row( const struct table
*table
, UINT row
, const struct expr
*cond
, enum fill_status
*status
)
1102 *status
= FILL_STATUS_UNFILTERED
;
1105 if (eval_cond( table
, row
, cond
, &val
, &type
) != S_OK
)
1107 *status
= FILL_STATUS_FAILED
;
1110 *status
= FILL_STATUS_FILTERED
;
1114 static BOOL
resize_table( struct table
*table
, UINT row_count
, UINT row_size
)
1116 if (!table
->num_rows_allocated
)
1118 if (!(table
->data
= malloc( row_count
* row_size
))) return FALSE
;
1119 table
->num_rows_allocated
= row_count
;
1122 if (row_count
> table
->num_rows_allocated
)
1125 UINT count
= max( row_count
, table
->num_rows_allocated
* 2 );
1126 if (!(data
= realloc( table
->data
, count
* row_size
))) return FALSE
;
1128 table
->num_rows_allocated
= count
;
1133 #include "pshpack1.h"
1134 struct smbios_prologue
1136 BYTE calling_method
;
1147 SMBIOS_TYPE_BASEBOARD
,
1148 SMBIOS_TYPE_CHASSIS
,
1151 struct smbios_header
1158 struct smbios_baseboard
1160 struct smbios_header hdr
;
1169 struct smbios_header hdr
;
1175 UINT64 characteristics
;
1176 BYTE characteristics_ext
[2];
1177 BYTE system_bios_major_release
;
1178 BYTE system_bios_minor_release
;
1179 BYTE ec_firmware_major_release
;
1180 BYTE ec_firmware_minor_release
;
1183 struct smbios_chassis
1185 struct smbios_header hdr
;
1193 struct smbios_system
1195 struct smbios_header hdr
;
1202 #include "poppack.h"
1204 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1206 static const struct smbios_header
*find_smbios_entry( enum smbios_type type
, const char *buf
, UINT len
)
1208 const char *ptr
, *start
;
1209 const struct smbios_prologue
*prologue
;
1210 const struct smbios_header
*hdr
;
1212 if (len
< sizeof(struct smbios_prologue
)) return NULL
;
1213 prologue
= (const struct smbios_prologue
*)buf
;
1214 if (prologue
->length
> len
- sizeof(*prologue
) || prologue
->length
< sizeof(*hdr
)) return NULL
;
1216 start
= (const char *)(prologue
+ 1);
1217 hdr
= (const struct smbios_header
*)start
;
1221 if ((const char *)hdr
- start
>= prologue
->length
- sizeof(*hdr
)) return NULL
;
1225 WARN( "invalid entry\n" );
1229 if (hdr
->type
== type
)
1231 if ((const char *)hdr
- start
+ hdr
->length
> prologue
->length
) return NULL
;
1234 else /* skip other entries and their strings */
1236 for (ptr
= (const char *)hdr
+ hdr
->length
; ptr
- buf
< len
&& *ptr
; ptr
++)
1238 for (; ptr
- buf
< len
; ptr
++) if (!*ptr
) break;
1240 if (ptr
== (const char *)hdr
+ hdr
->length
) ptr
++;
1241 hdr
= (const struct smbios_header
*)(ptr
+ 1);
1248 static WCHAR
*get_smbios_string_by_id( BYTE id
, const char *buf
, UINT offset
, UINT buflen
)
1250 const char *ptr
= buf
+ offset
;
1253 if (!id
|| offset
>= buflen
) return NULL
;
1254 for (ptr
= buf
+ offset
; ptr
- buf
< buflen
&& *ptr
; ptr
++)
1256 if (++i
== id
) return heap_strdupAW( ptr
);
1257 for (; ptr
- buf
< buflen
; ptr
++) if (!*ptr
) break;
1262 static WCHAR
*get_smbios_string( enum smbios_type type
, size_t field_offset
, const char *buf
, UINT len
)
1264 const struct smbios_header
*hdr
;
1267 if (!(hdr
= find_smbios_entry( type
, buf
, len
))) return NULL
;
1269 if (field_offset
+ sizeof(BYTE
) > hdr
->length
) return NULL
;
1271 offset
= (const char *)hdr
- buf
+ hdr
->length
;
1272 return get_smbios_string_by_id( ((const BYTE
*)hdr
)[field_offset
], buf
, offset
, len
);
1275 static WCHAR
*get_baseboard_manufacturer( const char *buf
, UINT len
)
1277 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_BASEBOARD
, offsetof(struct smbios_baseboard
, vendor
), buf
, len
);
1278 if (!ret
) return wcsdup( L
"Intel Corporation" );
1282 static WCHAR
*get_baseboard_product( const char *buf
, UINT len
)
1284 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_BASEBOARD
, offsetof(struct smbios_baseboard
, product
), buf
, len
);
1285 if (!ret
) return wcsdup( L
"Base Board" );
1289 static WCHAR
*get_baseboard_serialnumber( const char *buf
, UINT len
)
1291 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_BASEBOARD
, offsetof(struct smbios_baseboard
, serial
), buf
, len
);
1292 if (!ret
) return wcsdup( L
"None" );
1296 static WCHAR
*get_baseboard_version( const char *buf
, UINT len
)
1298 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_BASEBOARD
, offsetof(struct smbios_baseboard
, version
), buf
, len
);
1299 if (!ret
) return wcsdup( L
"1.0" );
1303 static enum fill_status
fill_baseboard( struct table
*table
, const struct expr
*cond
)
1305 struct record_baseboard
*rec
;
1306 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1310 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1312 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1313 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1314 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1316 rec
= (struct record_baseboard
*)table
->data
;
1317 rec
->manufacturer
= get_baseboard_manufacturer( buf
, len
);
1318 rec
->model
= L
"Base Board";
1319 rec
->name
= L
"Base Board";
1320 rec
->product
= get_baseboard_product( buf
, len
);
1321 rec
->serialnumber
= get_baseboard_serialnumber( buf
, len
);
1322 rec
->tag
= L
"Base Board";
1323 rec
->version
= get_baseboard_version( buf
, len
);
1324 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1329 TRACE("created %u rows\n", row
);
1330 table
->num_rows
= row
;
1334 static UINT16
get_bios_smbiosmajorversion( const char *buf
, UINT len
)
1336 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1337 if (len
< sizeof(*prologue
)) return 2;
1338 return prologue
->major_version
;
1341 static UINT16
get_bios_smbiosminorversion( const char *buf
, UINT len
)
1343 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1344 if (len
< sizeof(*prologue
)) return 0;
1345 return prologue
->minor_version
;
1347 static WCHAR
*get_bios_manufacturer( const char *buf
, UINT len
)
1349 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_BIOS
, offsetof(struct smbios_bios
, vendor
), buf
, len
);
1350 if (!ret
) return wcsdup( L
"The Wine Project" );
1354 static WCHAR
*convert_bios_date( const WCHAR
*str
)
1356 static const WCHAR fmtW
[] = L
"%04u%02u%02u000000.000000+000";
1357 UINT year
, month
, day
, len
= lstrlenW( str
);
1358 const WCHAR
*p
= str
, *q
;
1361 while (len
&& iswspace( *p
)) { p
++; len
--; }
1362 while (len
&& iswspace( p
[len
- 1] )) { len
--; }
1365 while (len
&& is_digit( *q
)) { q
++; len
--; };
1366 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1367 month
= (p
[0] - '0') * 10 + p
[1] - '0';
1370 while (len
&& is_digit( *q
)) { q
++; len
--; };
1371 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1372 day
= (p
[0] - '0') * 10 + p
[1] - '0';
1375 while (len
&& is_digit( *q
)) { q
++; len
--; };
1376 if (q
- p
== 4) year
= (p
[0] - '0') * 1000 + (p
[1] - '0') * 100 + (p
[2] - '0') * 10 + p
[3] - '0';
1377 else if (q
- p
== 2) year
= 1900 + (p
[0] - '0') * 10 + p
[1] - '0';
1380 if (!(ret
= malloc( sizeof(fmtW
) ))) return NULL
;
1381 swprintf( ret
, ARRAY_SIZE(fmtW
), fmtW
, year
, month
, day
);
1385 static WCHAR
*get_bios_releasedate( const char *buf
, UINT len
)
1387 WCHAR
*ret
, *date
= get_smbios_string( SMBIOS_TYPE_BIOS
, offsetof(struct smbios_bios
, date
), buf
, len
);
1388 if (!date
|| !(ret
= convert_bios_date( date
))) ret
= wcsdup( L
"20120608000000.000000+000" );
1393 static WCHAR
*get_bios_smbiosbiosversion( const char *buf
, UINT len
)
1395 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_BIOS
, offsetof(struct smbios_bios
, version
), buf
, len
);
1396 if (!ret
) return wcsdup( L
"Wine" );
1400 static BYTE
get_bios_ec_firmware_major_release( const char *buf
, UINT len
)
1402 const struct smbios_header
*hdr
;
1403 const struct smbios_bios
*bios
;
1405 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1407 bios
= (const struct smbios_bios
*)hdr
;
1408 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_major_release
;
1412 static BYTE
get_bios_ec_firmware_minor_release( const char *buf
, UINT len
)
1414 const struct smbios_header
*hdr
;
1415 const struct smbios_bios
*bios
;
1417 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1419 bios
= (const struct smbios_bios
*)hdr
;
1420 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_minor_release
;
1424 static BYTE
get_bios_system_bios_major_release( const char *buf
, UINT len
)
1426 const struct smbios_header
*hdr
;
1427 const struct smbios_bios
*bios
;
1429 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1431 bios
= (const struct smbios_bios
*)hdr
;
1432 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_major_release
;
1436 static BYTE
get_bios_system_bios_minor_release( const char *buf
, UINT len
)
1438 const struct smbios_header
*hdr
;
1439 const struct smbios_bios
*bios
;
1441 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1443 bios
= (const struct smbios_bios
*)hdr
;
1444 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_minor_release
;
1448 static enum fill_status
fill_bios( struct table
*table
, const struct expr
*cond
)
1450 struct record_bios
*rec
;
1451 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1455 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1457 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1458 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1459 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1461 rec
= (struct record_bios
*)table
->data
;
1462 rec
->currentlanguage
= NULL
;
1463 rec
->description
= L
"Default System BIOS";
1464 rec
->ecmajorversion
= get_bios_ec_firmware_major_release( buf
, len
);
1465 rec
->ecminorversion
= get_bios_ec_firmware_minor_release( buf
, len
);
1466 rec
->identificationcode
= NULL
;
1467 rec
->manufacturer
= get_bios_manufacturer( buf
, len
);
1468 rec
->name
= L
"Default System BIOS";
1469 rec
->releasedate
= get_bios_releasedate( buf
, len
);
1470 rec
->serialnumber
= L
"Serial number";
1471 rec
->smbiosbiosversion
= get_bios_smbiosbiosversion( buf
, len
);
1472 rec
->smbiosmajorversion
= get_bios_smbiosmajorversion( buf
, len
);
1473 rec
->smbiosminorversion
= get_bios_smbiosminorversion( buf
, len
);
1474 rec
->systembiosmajorversion
= get_bios_system_bios_major_release( buf
, len
);
1475 rec
->systembiosminorversion
= get_bios_system_bios_minor_release( buf
, len
);
1476 rec
->version
= L
"WINE - 1";
1477 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1482 TRACE("created %u rows\n", row
);
1483 table
->num_rows
= row
;
1487 static enum fill_status
fill_cdromdrive( struct table
*table
, const struct expr
*cond
)
1489 WCHAR drive
[3], root
[] = L
"A:\\";
1490 struct record_cdromdrive
*rec
;
1491 UINT i
, row
= 0, offset
= 0;
1492 DWORD drives
= GetLogicalDrives();
1493 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1495 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1497 for (i
= 0; i
< 26; i
++)
1499 if (drives
& (1 << i
))
1502 if (GetDriveTypeW( root
) != DRIVE_CDROM
)
1505 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1507 rec
= (struct record_cdromdrive
*)(table
->data
+ offset
);
1508 rec
->device_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1509 swprintf( drive
, ARRAY_SIZE( drive
), L
"%c:", 'A' + i
);
1510 rec
->drive
= wcsdup( drive
);
1511 rec
->mediatype
= L
"CR-ROM";
1512 rec
->name
= L
"Wine CD_ROM ATA Device";
1513 rec
->pnpdevice_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1514 if (!match_row( table
, row
, cond
, &status
))
1516 free_row_values( table
, row
);
1519 offset
+= sizeof(*rec
);
1523 TRACE("created %u rows\n", row
);
1524 table
->num_rows
= row
;
1528 static UINT
get_processor_count(void)
1530 SYSTEM_BASIC_INFORMATION info
;
1532 if (NtQuerySystemInformation( SystemBasicInformation
, &info
, sizeof(info
), NULL
)) return 1;
1533 return info
.NumberOfProcessors
;
1536 static UINT
get_logical_processor_count( UINT
*num_physical
, UINT
*num_packages
)
1538 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*buf
, *entry
;
1539 UINT core_relation_count
= 0, package_relation_count
= 0;
1541 ULONG len
, offset
= 0;
1542 BOOL smt_enabled
= FALSE
;
1543 DWORD all
= RelationAll
;
1545 if (num_packages
) *num_packages
= 1;
1546 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), NULL
, 0, &len
);
1547 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) return get_processor_count();
1549 if (!(buf
= malloc( len
))) return get_processor_count();
1550 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), buf
, len
, &len
);
1551 if (status
!= STATUS_SUCCESS
)
1554 return get_processor_count();
1557 while (offset
< len
)
1559 entry
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*)((char *)buf
+ offset
);
1561 if (entry
->Relationship
== RelationProcessorCore
)
1563 core_relation_count
++;
1564 if (entry
->Processor
.Flags
& LTP_PC_SMT
) smt_enabled
= TRUE
;
1566 else if (entry
->Relationship
== RelationProcessorPackage
)
1568 package_relation_count
++;
1570 offset
+= entry
->Size
;
1574 if (num_physical
) *num_physical
= core_relation_count
;
1575 if (num_packages
) *num_packages
= package_relation_count
;
1576 return smt_enabled
? core_relation_count
* 2 : core_relation_count
;
1579 static UINT64
get_total_physical_memory(void)
1581 MEMORYSTATUSEX status
;
1583 status
.dwLength
= sizeof(status
);
1584 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1585 return status
.ullTotalPhys
;
1588 static UINT64
get_available_physical_memory(void)
1590 MEMORYSTATUSEX status
;
1592 status
.dwLength
= sizeof(status
);
1593 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1594 return status
.ullAvailPhys
;
1597 static UINT64
get_total_virtual_memory(void)
1599 MEMORYSTATUSEX status
;
1601 status
.dwLength
= sizeof(status
);
1602 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1603 return status
.ullTotalVirtual
;
1606 static UINT64
get_available_virtual_memory(void)
1608 MEMORYSTATUSEX status
;
1610 status
.dwLength
= sizeof(status
);
1611 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1612 return status
.ullAvailVirtual
;
1615 static WCHAR
*get_computername(void)
1618 DWORD size
= MAX_COMPUTERNAME_LENGTH
+ 1;
1620 if (!(ret
= malloc( size
* sizeof(WCHAR
) ))) return NULL
;
1621 GetComputerNameW( ret
, &size
);
1625 static const WCHAR
*get_systemtype(void)
1628 GetNativeSystemInfo( &info
);
1629 if (info
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"x64 based PC";
1630 return L
"x86 based PC";
1633 static WCHAR
*get_username(void)
1636 DWORD compsize
, usersize
;
1640 GetComputerNameW( NULL
, &compsize
);
1642 GetUserNameW( NULL
, &usersize
);
1643 size
= compsize
+ usersize
; /* two null terminators account for the \ */
1644 if (!(ret
= malloc( size
* sizeof(WCHAR
) ))) return NULL
;
1645 GetComputerNameW( ret
, &compsize
);
1646 ret
[compsize
] = '\\';
1647 GetUserNameW( ret
+ compsize
+ 1, &usersize
);
1651 static WCHAR
*get_compsysproduct_name( const char *buf
, UINT len
)
1653 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_SYSTEM
, offsetof(struct smbios_system
, product
), buf
, len
);
1654 if (!ret
) return wcsdup( L
"Wine" );
1658 static WCHAR
*get_compsysproduct_vendor( const char *buf
, UINT len
)
1660 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_SYSTEM
, offsetof(struct smbios_system
, vendor
), buf
, len
);
1661 if (!ret
) return wcsdup( L
"The Wine Project" );
1665 static enum fill_status
fill_compsys( struct table
*table
, const struct expr
*cond
)
1667 struct record_computersystem
*rec
;
1668 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1672 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1674 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1675 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1676 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1678 rec
= (struct record_computersystem
*)table
->data
;
1679 rec
->description
= L
"AT/AT COMPATIBLE";
1680 rec
->domain
= L
"WORKGROUP";
1681 rec
->domainrole
= 0; /* standalone workstation */
1682 rec
->hypervisorpresent
= 0;
1683 rec
->manufacturer
= get_compsysproduct_vendor( buf
, len
);
1684 rec
->model
= get_compsysproduct_name( buf
, len
);
1685 rec
->name
= get_computername();
1686 rec
->num_logical_processors
= get_logical_processor_count( NULL
, &rec
->num_processors
);
1687 rec
->systemtype
= get_systemtype();
1688 rec
->total_physical_memory
= get_total_physical_memory();
1689 rec
->username
= get_username();
1690 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1695 TRACE("created %u rows\n", row
);
1696 table
->num_rows
= row
;
1700 static WCHAR
*get_compsysproduct_identifyingnumber( const char *buf
, UINT len
)
1702 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_SYSTEM
, offsetof(struct smbios_system
, serial
), buf
, len
);
1703 if (!ret
) return wcsdup( L
"0" );
1707 static WCHAR
*get_compsysproduct_uuid( const char *buf
, UINT len
)
1709 static const BYTE none
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1710 const struct smbios_header
*hdr
;
1711 const struct smbios_system
*system
;
1715 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
)) || hdr
->length
< sizeof(*system
)) goto done
;
1716 system
= (const struct smbios_system
*)hdr
;
1717 if (!memcmp( system
->uuid
, none
, sizeof(none
) ) || !(ret
= malloc( 37 * sizeof(WCHAR
) ))) goto done
;
1720 swprintf( ret
, 37, L
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr
[0], ptr
[1],
1721 ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7], ptr
[8], ptr
[9], ptr
[10], ptr
[11], ptr
[12], ptr
[13],
1724 if (!ret
) ret
= wcsdup( L
"deaddead-dead-dead-dead-deaddeaddead" );
1728 static WCHAR
*get_compsysproduct_version( const char *buf
, UINT len
)
1730 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_SYSTEM
, offsetof(struct smbios_system
, version
), buf
, len
);
1731 if (!ret
) return wcsdup( L
"1.0" );
1735 static enum fill_status
fill_compsysproduct( struct table
*table
, const struct expr
*cond
)
1737 struct record_computersystemproduct
*rec
;
1738 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1742 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1744 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1745 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1746 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1748 rec
= (struct record_computersystemproduct
*)table
->data
;
1749 rec
->identifyingnumber
= get_compsysproduct_identifyingnumber( buf
, len
);
1750 rec
->name
= get_compsysproduct_name( buf
, len
);
1751 rec
->skunumber
= NULL
;
1752 rec
->uuid
= get_compsysproduct_uuid( buf
, len
);
1753 rec
->vendor
= get_compsysproduct_vendor( buf
, len
);
1754 rec
->version
= get_compsysproduct_version( buf
, len
);
1755 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1760 TRACE("created %u rows\n", row
);
1761 table
->num_rows
= row
;
1773 static struct dirstack
*alloc_dirstack( UINT size
)
1775 struct dirstack
*dirstack
;
1777 if (!(dirstack
= malloc( sizeof(*dirstack
) ))) return NULL
;
1778 if (!(dirstack
->dirs
= malloc( sizeof(WCHAR
*) * size
)))
1783 if (!(dirstack
->len_dirs
= malloc( sizeof(UINT
) * size
)))
1785 free( dirstack
->dirs
);
1789 dirstack
->num_dirs
= 0;
1790 dirstack
->num_allocated
= size
;
1794 static void clear_dirstack( struct dirstack
*dirstack
)
1797 for (i
= 0; i
< dirstack
->num_dirs
; i
++) free( dirstack
->dirs
[i
] );
1798 dirstack
->num_dirs
= 0;
1801 static void free_dirstack( struct dirstack
*dirstack
)
1803 clear_dirstack( dirstack
);
1804 free( dirstack
->dirs
);
1805 free( dirstack
->len_dirs
);
1809 static BOOL
push_dir( struct dirstack
*dirstack
, WCHAR
*dir
, UINT len
)
1811 UINT size
, i
= dirstack
->num_dirs
;
1813 if (!dir
) return FALSE
;
1815 if (i
== dirstack
->num_allocated
)
1820 size
= dirstack
->num_allocated
* 2;
1821 if (!(tmp
= realloc( dirstack
->dirs
, size
* sizeof(WCHAR
*) ))) return FALSE
;
1822 dirstack
->dirs
= tmp
;
1823 if (!(len_tmp
= realloc( dirstack
->len_dirs
, size
* sizeof(UINT
) ))) return FALSE
;
1824 dirstack
->len_dirs
= len_tmp
;
1825 dirstack
->num_allocated
= size
;
1827 dirstack
->dirs
[i
] = dir
;
1828 dirstack
->len_dirs
[i
] = len
;
1829 dirstack
->num_dirs
++;
1833 static WCHAR
*pop_dir( struct dirstack
*dirstack
, UINT
*len
)
1835 if (!dirstack
->num_dirs
)
1840 dirstack
->num_dirs
--;
1841 *len
= dirstack
->len_dirs
[dirstack
->num_dirs
];
1842 return dirstack
->dirs
[dirstack
->num_dirs
];
1845 static const WCHAR
*peek_dir( struct dirstack
*dirstack
)
1847 if (!dirstack
->num_dirs
) return NULL
;
1848 return dirstack
->dirs
[dirstack
->num_dirs
- 1];
1851 static WCHAR
*build_glob( WCHAR drive
, const WCHAR
*path
, UINT len
)
1856 if (!(ret
= malloc( (len
+ 6) * sizeof(WCHAR
) ))) return NULL
;
1862 memcpy( ret
+ i
, path
, len
* sizeof(WCHAR
) );
1871 static WCHAR
*build_name( WCHAR drive
, const WCHAR
*path
)
1873 UINT i
= 0, len
= 0;
1877 for (p
= path
; *p
; p
++)
1879 if (*p
== '\\') len
+= 2;
1882 if (!(ret
= malloc( (len
+ 5) * sizeof(WCHAR
) ))) return NULL
;
1887 for (p
= path
; *p
; p
++)
1889 if (*p
!= '\\') ret
[i
++] = *p
;
1900 static WCHAR
*build_dirname( const WCHAR
*path
, UINT
*ret_len
)
1902 const WCHAR
*p
= path
, *start
;
1906 if (!iswalpha( p
[0] ) || p
[1] != ':' || p
[2] != '\\' || p
[3] != '\\' || !p
[4]) return NULL
;
1908 len
= lstrlenW( start
);
1909 p
= start
+ len
- 1;
1910 if (*p
== '\\') return NULL
;
1912 while (p
>= start
&& *p
!= '\\') { len
--; p
--; };
1913 while (p
>= start
&& *p
== '\\') { len
--; p
--; };
1915 if (!(ret
= malloc( (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1916 for (i
= 0, p
= start
; p
< start
+ len
; p
++)
1918 if (p
[0] == '\\' && p
[1] == '\\')
1930 static BOOL
seen_dir( struct dirstack
*dirstack
, const WCHAR
*path
)
1933 for (i
= 0; i
< dirstack
->num_dirs
; i
++) if (!wcscmp( dirstack
->dirs
[i
], path
)) return TRUE
;
1937 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1938 static UINT
seed_dirs( struct dirstack
*dirstack
, const struct expr
*cond
, WCHAR root
, UINT
*count
)
1940 const struct expr
*left
, *right
;
1942 if (!cond
|| cond
->type
!= EXPR_COMPLEX
) return *count
= 0;
1944 left
= cond
->u
.expr
.left
;
1945 right
= cond
->u
.expr
.right
;
1946 if (cond
->u
.expr
.op
== OP_EQ
)
1950 const WCHAR
*str
= NULL
;
1952 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&&
1953 !wcscmp( left
->u
.propval
->name
, L
"Name" ) &&
1954 towupper( right
->u
.sval
[0] ) == towupper( root
))
1956 str
= right
->u
.sval
;
1958 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&&
1959 !wcscmp( right
->u
.propval
->name
, L
"Name" ) &&
1960 towupper( left
->u
.sval
[0] ) == towupper( root
))
1964 if (str
&& (path
= build_dirname( str
, &len
)))
1966 if (seen_dir( dirstack
, path
))
1971 else if (push_dir( dirstack
, path
, len
)) return ++*count
;
1976 else if (cond
->u
.expr
.op
== OP_OR
)
1978 UINT left_count
= 0, right_count
= 0;
1980 if (!(seed_dirs( dirstack
, left
, root
, &left_count
))) return *count
= 0;
1981 if (!(seed_dirs( dirstack
, right
, root
, &right_count
))) return *count
= 0;
1982 return *count
+= left_count
+ right_count
;
1987 static WCHAR
*append_path( const WCHAR
*path
, const WCHAR
*segment
, UINT
*len
)
1989 UINT len_path
= 0, len_segment
= lstrlenW( segment
);
1993 if (path
) len_path
= lstrlenW( path
);
1994 if (!(ret
= malloc( (len_path
+ len_segment
+ 2) * sizeof(WCHAR
) ))) return NULL
;
1995 if (path
&& len_path
)
1997 memcpy( ret
, path
, len_path
* sizeof(WCHAR
) );
1998 ret
[len_path
] = '\\';
1999 *len
+= len_path
+ 1;
2001 memcpy( ret
+ *len
, segment
, len_segment
* sizeof(WCHAR
) );
2002 *len
+= len_segment
;
2007 static WCHAR
*get_file_version( const WCHAR
*filename
)
2009 VS_FIXEDFILEINFO
*info
;
2011 DWORD len
= 4 * 5 + ARRAY_SIZE( L
"%u.%u.%u.%u" );
2015 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
2016 if (!(size
= GetFileVersionInfoSizeW( filename
, NULL
)) || !(block
= malloc( size
)))
2021 if (!GetFileVersionInfoW( filename
, 0, size
, block
) ||
2022 !VerQueryValueW( block
, L
"\\", (void **)&info
, &size
))
2028 swprintf( ret
, len
, L
"%u.%u.%u.%u", info
->dwFileVersionMS
>> 16, info
->dwFileVersionMS
& 0xffff,
2029 info
->dwFileVersionLS
>> 16, info
->dwFileVersionLS
& 0xffff );
2034 static enum fill_status
fill_datafile( struct table
*table
, const struct expr
*cond
)
2036 struct record_datafile
*rec
;
2037 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
2038 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
2039 DWORD drives
= GetLogicalDrives();
2040 WIN32_FIND_DATAW data
;
2042 struct dirstack
*dirstack
;
2043 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2045 if (!resize_table( table
, 8, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2047 dirstack
= alloc_dirstack(2);
2049 for (i
= 0; i
< 26; i
++)
2051 if (!(drives
& (1 << i
))) continue;
2054 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
2056 num_expected_rows
= 0;
2057 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2063 path
= pop_dir( dirstack
, &len
);
2064 if (!(glob
= build_glob( root
[0], path
, len
)))
2066 status
= FILL_STATUS_FAILED
;
2069 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2073 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2075 status
= FILL_STATUS_FAILED
;
2076 FindClose( handle
);
2079 if (!wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." )) continue;
2081 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2083 status
= FILL_STATUS_FAILED
;
2084 FindClose( handle
);
2088 if (data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
2090 if (push_dir( dirstack
, new_path
, len
)) continue;
2092 FindClose( handle
);
2093 status
= FILL_STATUS_FAILED
;
2096 rec
= (struct record_datafile
*)(table
->data
+ offset
);
2097 rec
->name
= build_name( root
[0], new_path
);
2098 rec
->version
= get_file_version( rec
->name
);
2100 if (!match_row( table
, row
, cond
, &status
))
2102 free_row_values( table
, row
);
2105 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2108 FindClose( handle
);
2109 status
= FILL_STATUS_FILTERED
;
2112 offset
+= sizeof(*rec
);
2115 while (FindNextFileW( handle
, &data
));
2116 FindClose( handle
);
2118 if (!peek_dir( dirstack
)) break;
2123 free_dirstack( dirstack
);
2127 TRACE("created %u rows\n", row
);
2128 table
->num_rows
= row
;
2132 static UINT32
get_pixelsperxlogicalinch(void)
2134 HDC hdc
= GetDC( NULL
);
2137 if (!hdc
) return 96;
2138 ret
= GetDeviceCaps( hdc
, LOGPIXELSX
);
2139 ReleaseDC( NULL
, hdc
);
2143 static enum fill_status
fill_desktopmonitor( struct table
*table
, const struct expr
*cond
)
2145 struct record_desktopmonitor
*rec
;
2146 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2149 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2151 rec
= (struct record_desktopmonitor
*)table
->data
;
2152 rec
->name
= L
"Generic Non-PnP Monitor";
2153 rec
->pixelsperxlogicalinch
= get_pixelsperxlogicalinch();
2155 if (match_row( table
, row
, cond
, &status
)) row
++;
2157 TRACE("created %u rows\n", row
);
2158 table
->num_rows
= row
;
2162 static enum fill_status
fill_directory( struct table
*table
, const struct expr
*cond
)
2164 struct record_directory
*rec
;
2165 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
2166 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
2167 DWORD drives
= GetLogicalDrives();
2168 WIN32_FIND_DATAW data
;
2170 struct dirstack
*dirstack
;
2171 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2173 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2175 dirstack
= alloc_dirstack(2);
2177 for (i
= 0; i
< 26; i
++)
2179 if (!(drives
& (1 << i
))) continue;
2182 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
2184 num_expected_rows
= 0;
2185 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2191 path
= pop_dir( dirstack
, &len
);
2192 if (!(glob
= build_glob( root
[0], path
, len
)))
2194 status
= FILL_STATUS_FAILED
;
2197 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2201 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2203 FindClose( handle
);
2204 status
= FILL_STATUS_FAILED
;
2207 if (!(data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ||
2208 !wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." ))
2211 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2213 FindClose( handle
);
2214 status
= FILL_STATUS_FAILED
;
2218 if (!(push_dir( dirstack
, new_path
, len
)))
2221 FindClose( handle
);
2222 status
= FILL_STATUS_FAILED
;
2225 rec
= (struct record_directory
*)(table
->data
+ offset
);
2226 rec
->accessmask
= FILE_ALL_ACCESS
;
2227 rec
->name
= build_name( root
[0], new_path
);
2229 if (!match_row( table
, row
, cond
, &status
))
2231 free_row_values( table
, row
);
2234 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2237 FindClose( handle
);
2238 status
= FILL_STATUS_FILTERED
;
2241 offset
+= sizeof(*rec
);
2244 while (FindNextFileW( handle
, &data
));
2245 FindClose( handle
);
2247 if (!peek_dir( dirstack
)) break;
2252 free_dirstack( dirstack
);
2256 TRACE("created %u rows\n", row
);
2257 table
->num_rows
= row
;
2261 static UINT64
get_freespace( const WCHAR
*dir
, UINT64
*disksize
)
2263 WCHAR root
[] = L
"\\\\.\\A:";
2264 ULARGE_INTEGER free
;
2265 DISK_GEOMETRY_EX info
;
2267 DWORD bytes_returned
;
2269 free
.QuadPart
= 512 * 1024 * 1024;
2270 GetDiskFreeSpaceExW( dir
, NULL
, NULL
, &free
);
2273 handle
= CreateFileW( root
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2274 if (handle
!= INVALID_HANDLE_VALUE
)
2276 if (DeviceIoControl( handle
, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
, NULL
, 0, &info
, sizeof(info
), &bytes_returned
, NULL
))
2277 *disksize
= info
.DiskSize
.QuadPart
;
2278 CloseHandle( handle
);
2280 return free
.QuadPart
;
2282 static WCHAR
*get_diskdrive_serialnumber( WCHAR letter
)
2285 STORAGE_DEVICE_DESCRIPTOR
*desc
;
2286 HANDLE handle
= INVALID_HANDLE_VALUE
;
2287 STORAGE_PROPERTY_QUERY query
= {0};
2291 swprintf( drive
, ARRAY_SIZE(drive
), L
"\\\\.\\%c:", letter
);
2292 handle
= CreateFileW( drive
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2293 if (handle
== INVALID_HANDLE_VALUE
) goto done
;
2295 query
.PropertyId
= StorageDeviceProperty
;
2296 query
.QueryType
= PropertyStandardQuery
;
2298 size
= sizeof(*desc
) + 256;
2301 if (!(desc
= malloc( size
))) break;
2302 if (DeviceIoControl( handle
, IOCTL_STORAGE_QUERY_PROPERTY
, &query
, sizeof(query
), desc
, size
, NULL
, NULL
))
2304 if (desc
->SerialNumberOffset
) ret
= heap_strdupAW( (const char *)desc
+ desc
->SerialNumberOffset
);
2310 if (GetLastError() != ERROR_MORE_DATA
) break;
2314 if (handle
!= INVALID_HANDLE_VALUE
) CloseHandle( handle
);
2315 if (!ret
) ret
= wcsdup( L
"WINEHDISK" );
2319 static enum fill_status
fill_diskdrive( struct table
*table
, const struct expr
*cond
)
2321 static const WCHAR fmtW
[] = L
"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2322 WCHAR device_id
[ARRAY_SIZE( fmtW
) + 10], root
[] = L
"A:\\";
2323 struct record_diskdrive
*rec
;
2324 UINT i
, row
= 0, offset
= 0, index
= 0, type
;
2325 UINT64 size
= 1024 * 1024 * 1024;
2326 DWORD drives
= GetLogicalDrives();
2327 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2329 if (!resize_table( table
, 2, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2331 for (i
= 0; i
< 26; i
++)
2333 if (drives
& (1 << i
))
2336 type
= GetDriveTypeW( root
);
2337 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2340 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2342 rec
= (struct record_diskdrive
*)(table
->data
+ offset
);
2343 swprintf( device_id
, ARRAY_SIZE( device_id
), fmtW
, index
);
2344 rec
->device_id
= wcsdup( device_id
);
2345 rec
->index
= index
++;
2346 rec
->interfacetype
= L
"IDE";
2347 rec
->manufacturer
= L
"(Standard disk drives)";
2348 rec
->mediatype
= (type
== DRIVE_FIXED
) ? L
"Fixed hard disk" : L
"Removable media";
2349 rec
->model
= L
"Wine Disk Drive";
2350 rec
->pnpdevice_id
= L
"IDE\\Disk\\VEN_WINE";
2351 rec
->serialnumber
= get_diskdrive_serialnumber( root
[0] );
2352 get_freespace( root
, &size
);
2354 if (!match_row( table
, row
, cond
, &status
))
2356 free_row_values( table
, row
);
2359 offset
+= sizeof(*rec
);
2363 TRACE("created %u rows\n", row
);
2364 table
->num_rows
= row
;
2374 static void free_associations( struct association
*assoc
, UINT count
)
2378 for (i
= 0; i
< count
; i
++)
2380 free( assoc
[i
].ref
);
2381 free( assoc
[i
].ref2
);
2386 static struct association
*get_diskdrivetodiskpartition_pairs( UINT
*count
)
2388 struct association
*ret
= NULL
;
2389 struct query
*query
, *query2
= NULL
;
2394 if (!(query
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return NULL
;
2395 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskDrive",
2396 &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2397 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2399 if (!(query2
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return FALSE
;
2400 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskPartition",
2401 &query2
->view
, &query2
->mem
)) != S_OK
) goto done
;
2402 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2404 if (!(ret
= calloc( query
->view
->result_count
, sizeof(*ret
) ))) goto done
;
2406 for (i
= 0; i
< query
->view
->result_count
; i
++)
2408 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2409 if (!(ret
[i
].ref
= wcsdup( V_BSTR(&val
) ))) goto done
;
2410 VariantClear( &val
);
2412 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2413 if (!(ret
[i
].ref2
= wcsdup( V_BSTR(&val
) ))) goto done
;
2414 VariantClear( &val
);
2417 *count
= query
->view
->result_count
;
2420 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2421 free_query( query
);
2422 free_query( query2
);
2426 static enum fill_status
fill_diskdrivetodiskpartition( struct table
*table
, const struct expr
*cond
)
2428 struct record_diskdrivetodiskpartition
*rec
;
2429 UINT i
, row
= 0, offset
= 0, count
= 0;
2430 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2431 struct association
*assoc
;
2433 if (!(assoc
= get_diskdrivetodiskpartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2436 free_associations( assoc
, count
);
2437 return FILL_STATUS_UNFILTERED
;
2439 if (!resize_table( table
, count
, sizeof(*rec
) ))
2441 free_associations( assoc
, count
);
2442 return FILL_STATUS_FAILED
;
2445 for (i
= 0; i
< count
; i
++)
2447 rec
= (struct record_diskdrivetodiskpartition
*)(table
->data
+ offset
);
2448 rec
->antecedent
= assoc
[i
].ref
;
2449 rec
->dependent
= assoc
[i
].ref2
;
2450 if (!match_row( table
, row
, cond
, &status
))
2452 free_row_values( table
, row
);
2455 offset
+= sizeof(*rec
);
2461 TRACE("created %u rows\n", row
);
2462 table
->num_rows
= row
;
2466 static WCHAR
*get_filesystem( const WCHAR
*root
)
2468 WCHAR buffer
[MAX_PATH
+ 1];
2470 if (GetVolumeInformationW( root
, NULL
, 0, NULL
, NULL
, NULL
, buffer
, MAX_PATH
+ 1 ))
2471 return wcsdup( buffer
);
2472 return wcsdup( L
"NTFS" );
2475 static enum fill_status
fill_diskpartition( struct table
*table
, const struct expr
*cond
)
2477 WCHAR device_id
[32], root
[] = L
"A:\\";
2478 struct record_diskpartition
*rec
;
2479 UINT i
, row
= 0, offset
= 0, type
, index
= 0;
2480 UINT64 size
= 1024 * 1024 * 1024;
2481 DWORD drives
= GetLogicalDrives();
2482 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2484 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2486 for (i
= 0; i
< 26; i
++)
2488 if (drives
& (1 << i
))
2491 type
= GetDriveTypeW( root
);
2492 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2495 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2497 rec
= (struct record_diskpartition
*)(table
->data
+ offset
);
2498 rec
->bootable
= (i
== 2) ? -1 : 0;
2499 rec
->bootpartition
= (i
== 2) ? -1 : 0;
2500 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"Disk #%u, Partition #0", index
);
2501 rec
->device_id
= wcsdup( device_id
);
2502 rec
->diskindex
= index
++;
2504 rec
->pnpdevice_id
= wcsdup( device_id
);
2505 get_freespace( root
, &size
);
2507 rec
->startingoffset
= 0;
2508 rec
->type
= get_filesystem( root
);
2509 if (!match_row( table
, row
, cond
, &status
))
2511 free_row_values( table
, row
);
2514 offset
+= sizeof(*rec
);
2518 TRACE("created %u rows\n", row
);
2519 table
->num_rows
= row
;
2523 static UINT32
get_bitsperpixel( UINT
*hres
, UINT
*vres
)
2525 HDC hdc
= GetDC( NULL
);
2528 if (!hdc
) return 32;
2529 ret
= GetDeviceCaps( hdc
, BITSPIXEL
);
2530 *hres
= GetDeviceCaps( hdc
, HORZRES
);
2531 *vres
= GetDeviceCaps( hdc
, VERTRES
);
2532 ReleaseDC( NULL
, hdc
);
2536 static enum fill_status
fill_displaycontrollerconfig( struct table
*table
, const struct expr
*cond
)
2538 struct record_displaycontrollerconfig
*rec
;
2539 UINT row
= 0, hres
= 1024, vres
= 768;
2540 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2542 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2544 rec
= (struct record_displaycontrollerconfig
*)table
->data
;
2545 rec
->bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
2546 rec
->caption
= L
"VideoController1";
2547 rec
->horizontalresolution
= hres
;
2548 rec
->name
= L
"VideoController1";
2549 rec
->verticalresolution
= vres
;
2550 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
2553 TRACE("created %u rows\n", row
);
2554 table
->num_rows
= row
;
2558 static WCHAR
*get_ip4_string( DWORD addr
)
2560 DWORD len
= sizeof("ddd.ddd.ddd.ddd");
2563 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
2564 swprintf( ret
, len
, L
"%u.%u.%u.%u", (addr
>> 24) & 0xff, (addr
>> 16) & 0xff, (addr
>> 8) & 0xff, addr
& 0xff );
2568 static enum fill_status
fill_ip4routetable( struct table
*table
, const struct expr
*cond
)
2570 struct record_ip4routetable
*rec
;
2571 UINT i
, row
= 0, offset
= 0;
2573 MIB_IPFORWARDTABLE
*forwards
;
2574 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2576 if (GetIpForwardTable( NULL
, &size
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
) return FILL_STATUS_FAILED
;
2577 if (!(forwards
= malloc( size
))) return FILL_STATUS_FAILED
;
2578 if (GetIpForwardTable( forwards
, &size
, TRUE
))
2581 return FILL_STATUS_FAILED
;
2583 if (!resize_table( table
, max(forwards
->dwNumEntries
, 1), sizeof(*rec
) ))
2586 return FILL_STATUS_FAILED
;
2589 for (i
= 0; i
< forwards
->dwNumEntries
; i
++)
2591 rec
= (struct record_ip4routetable
*)(table
->data
+ offset
);
2593 rec
->destination
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardDest
) );
2594 rec
->interfaceindex
= forwards
->table
[i
].dwForwardIfIndex
;
2595 rec
->nexthop
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardNextHop
) );
2597 if (!match_row( table
, row
, cond
, &status
))
2599 free_row_values( table
, row
);
2602 offset
+= sizeof(*rec
);
2605 TRACE("created %u rows\n", row
);
2606 table
->num_rows
= row
;
2612 static WCHAR
*get_volumename( const WCHAR
*root
)
2614 WCHAR buf
[MAX_PATH
+ 1] = {0};
2615 GetVolumeInformationW( root
, buf
, ARRAY_SIZE( buf
), NULL
, NULL
, NULL
, NULL
, 0 );
2616 return wcsdup( buf
);
2618 static WCHAR
*get_volumeserialnumber( const WCHAR
*root
)
2623 GetVolumeInformationW( root
, NULL
, 0, &serial
, NULL
, NULL
, NULL
, 0 );
2624 swprintf( buffer
, ARRAY_SIZE( buffer
), L
"%08X", serial
);
2625 return wcsdup( buffer
);
2628 static enum fill_status
fill_logicaldisk( struct table
*table
, const struct expr
*cond
)
2630 WCHAR device_id
[3], root
[] = L
"A:\\";
2631 struct record_logicaldisk
*rec
;
2632 UINT i
, row
= 0, offset
= 0, type
;
2633 UINT64 size
= 1024 * 1024 * 1024;
2634 DWORD drives
= GetLogicalDrives();
2635 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2637 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2639 for (i
= 0; i
< 26; i
++)
2641 if (drives
& (1 << i
))
2644 type
= GetDriveTypeW( root
);
2645 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_CDROM
&& type
!= DRIVE_REMOVABLE
)
2648 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2650 rec
= (struct record_logicaldisk
*)(table
->data
+ offset
);
2651 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%c:", 'A' + i
);
2652 rec
->caption
= wcsdup( device_id
);
2653 rec
->device_id
= wcsdup( device_id
);
2654 rec
->drivetype
= type
;
2655 rec
->filesystem
= get_filesystem( root
);
2656 rec
->freespace
= get_freespace( root
, &size
);
2657 rec
->name
= wcsdup( device_id
);
2659 rec
->volumename
= get_volumename( root
);
2660 rec
->volumeserialnumber
= get_volumeserialnumber( root
);
2661 if (!match_row( table
, row
, cond
, &status
))
2663 free_row_values( table
, row
);
2666 offset
+= sizeof(*rec
);
2670 TRACE("created %u rows\n", row
);
2671 table
->num_rows
= row
;
2675 static struct association
*get_logicaldisktopartition_pairs( UINT
*count
)
2677 struct association
*ret
= NULL
;
2678 struct query
*query
, *query2
= NULL
;
2683 if (!(query
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return NULL
;
2684 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskPartition",
2685 &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2686 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2688 if (!(query2
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return FALSE
;
2689 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
,
2690 L
"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2
->view
,
2691 &query2
->mem
)) != S_OK
) goto done
;
2692 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2694 if (!(ret
= calloc( query
->view
->result_count
, sizeof(*ret
) ))) goto done
;
2696 /* assume fixed and removable disks are enumerated in the same order as partitions */
2697 for (i
= 0; i
< query
->view
->result_count
; i
++)
2699 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2700 if (!(ret
[i
].ref
= wcsdup( V_BSTR(&val
) ))) goto done
;
2701 VariantClear( &val
);
2703 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2704 if (!(ret
[i
].ref2
= wcsdup( V_BSTR(&val
) ))) goto done
;
2705 VariantClear( &val
);
2708 *count
= query
->view
->result_count
;
2711 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2712 free_query( query
);
2713 free_query( query2
);
2717 static enum fill_status
fill_logicaldisktopartition( struct table
*table
, const struct expr
*cond
)
2719 struct record_logicaldisktopartition
*rec
;
2720 UINT i
, row
= 0, offset
= 0, count
= 0;
2721 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2722 struct association
*assoc
;
2724 if (!(assoc
= get_logicaldisktopartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2727 free_associations( assoc
, count
);
2728 return FILL_STATUS_UNFILTERED
;
2730 if (!resize_table( table
, count
, sizeof(*rec
) ))
2732 free_associations( assoc
, count
);
2733 return FILL_STATUS_FAILED
;
2736 for (i
= 0; i
< count
; i
++)
2738 rec
= (struct record_logicaldisktopartition
*)(table
->data
+ offset
);
2739 rec
->antecedent
= assoc
[i
].ref
;
2740 rec
->dependent
= assoc
[i
].ref2
;
2741 if (!match_row( table
, row
, cond
, &status
))
2743 free_row_values( table
, row
);
2746 offset
+= sizeof(*rec
);
2752 TRACE("created %u rows\n", row
);
2753 table
->num_rows
= row
;
2757 static UINT16
get_connection_status( IF_OPER_STATUS status
)
2761 case IfOperStatusDown
:
2762 return 0; /* Disconnected */
2763 case IfOperStatusUp
:
2764 return 2; /* Connected */
2766 ERR("unhandled status %u\n", status
);
2771 static WCHAR
*get_mac_address( const BYTE
*addr
, DWORD len
)
2774 if (len
!= 6 || !(ret
= malloc( 18 * sizeof(WCHAR
) ))) return NULL
;
2775 swprintf( ret
, 18, L
"%02x:%02x:%02x:%02x:%02x:%02x", addr
[0], addr
[1], addr
[2], addr
[3], addr
[4], addr
[5] );
2778 static const WCHAR
*get_adaptertype( DWORD type
, int *id
, int *physical
)
2782 case IF_TYPE_ETHERNET_CSMACD
:
2785 return L
"Ethernet 802.3";
2787 case IF_TYPE_IEEE80211
:
2792 case IF_TYPE_IEEE1394
:
2797 case IF_TYPE_TUNNEL
:
2809 #define GUID_SIZE 39
2810 static WCHAR
*guid_to_str( const GUID
*ptr
)
2813 if (!(ret
= malloc( GUID_SIZE
* sizeof(WCHAR
) ))) return NULL
;
2814 swprintf( ret
, GUID_SIZE
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2815 ptr
->Data1
, ptr
->Data2
, ptr
->Data3
, ptr
->Data4
[0], ptr
->Data4
[1], ptr
->Data4
[2],
2816 ptr
->Data4
[3], ptr
->Data4
[4], ptr
->Data4
[5], ptr
->Data4
[6], ptr
->Data4
[7] );
2820 static WCHAR
*get_networkadapter_guid( const IF_LUID
*luid
)
2823 if (ConvertInterfaceLuidToGuid( luid
, &guid
)) return NULL
;
2824 return guid_to_str( &guid
);
2827 static IP_ADAPTER_ADDRESSES
*get_network_adapters(void)
2829 ULONG err
, size
= 4096;
2830 IP_ADAPTER_ADDRESSES
*tmp
, *ret
;
2832 if (!(ret
= malloc( size
))) return NULL
;
2833 err
= GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_GATEWAYS
, NULL
, ret
, &size
);
2834 while (err
== ERROR_BUFFER_OVERFLOW
)
2836 if (!(tmp
= realloc( ret
, size
))) break;
2838 err
= GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_GATEWAYS
, NULL
, ret
, &size
);
2840 if (err
== ERROR_SUCCESS
) return ret
;
2845 static enum fill_status
fill_networkadapter( struct table
*table
, const struct expr
*cond
)
2847 WCHAR device_id
[11];
2848 struct record_networkadapter
*rec
;
2849 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
2850 UINT row
= 0, offset
= 0, count
= 0;
2851 int adaptertypeid
, physical
;
2852 UINT16 connection_status
;
2853 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2855 if (!(buffer
= get_network_adapters())) return FILL_STATUS_FAILED
;
2857 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2859 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
2861 if (!resize_table( table
, count
, sizeof(*rec
) ))
2864 return FILL_STATUS_FAILED
;
2866 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2868 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
2870 connection_status
= get_connection_status( aa
->OperStatus
);
2872 rec
= (struct record_networkadapter
*)(table
->data
+ offset
);
2873 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%u", aa
->IfIndex
);
2874 rec
->adaptertype
= get_adaptertype( aa
->IfType
, &adaptertypeid
, &physical
);
2875 rec
->adaptertypeid
= adaptertypeid
;
2876 rec
->description
= wcsdup( aa
->Description
);
2877 rec
->device_id
= wcsdup( device_id
);
2878 rec
->guid
= get_networkadapter_guid( &aa
->Luid
);
2879 rec
->index
= aa
->IfIndex
;
2880 rec
->interface_index
= aa
->IfIndex
;
2881 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
2882 rec
->manufacturer
= L
"The Wine Project";
2883 rec
->netconnection_id
= NULL
; /* FIXME Windows seems to fill this when it's connected and in use */
2884 rec
->name
= wcsdup( aa
->FriendlyName
);
2885 rec
->netenabled
= connection_status
? -1 : 0;
2886 rec
->netconnection_status
= connection_status
;
2887 rec
->physicaladapter
= physical
;
2888 rec
->pnpdevice_id
= L
"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2889 rec
->servicename
= wcsdup( aa
->FriendlyName
);
2890 rec
->speed
= 1000000;
2891 if (!match_row( table
, row
, cond
, &status
))
2893 free_row_values( table
, row
);
2896 offset
+= sizeof(*rec
);
2899 TRACE("created %u rows\n", row
);
2900 table
->num_rows
= row
;
2906 static WCHAR
*get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS
*addr
)
2908 const SOCKET_ADDRESS
*sa
= &addr
->Address
;
2909 WCHAR buf
[NI_MAXHOST
];
2911 if (!addr
) return NULL
;
2912 if (GetNameInfoW( sa
->lpSockaddr
, sa
->iSockaddrLength
, buf
, ARRAY_SIZE( buf
), NULL
,
2913 0, NI_NAMEREQD
)) return NULL
;
2914 return wcsdup( buf
);
2916 static struct array
*get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS
*list
)
2918 IP_ADAPTER_GATEWAY_ADDRESS
*gateway
;
2920 ULONG buflen
, i
= 0, count
= 0;
2921 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2923 if (!list
) return NULL
;
2924 for (gateway
= list
; gateway
; gateway
= gateway
->Next
) count
++;
2926 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2927 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2932 for (gateway
= list
; gateway
; gateway
= gateway
->Next
)
2934 buflen
= ARRAY_SIZE( buf
);
2935 if (WSAAddressToStringW( gateway
->Address
.lpSockaddr
, gateway
->Address
.iSockaddrLength
,
2936 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2938 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2944 ret
->elem_size
= sizeof(*ptr
);
2949 static struct array
*get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS
*list
)
2951 IP_ADAPTER_DNS_SERVER_ADDRESS
*server
;
2953 ULONG buflen
, i
= 0, count
= 0;
2954 WCHAR
**ptr
, *p
, buf
[54]; /* max IPv6 address length */
2956 if (!list
) return NULL
;
2957 for (server
= list
; server
; server
= server
->Next
) count
++;
2959 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2960 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2965 for (server
= list
; server
; server
= server
->Next
)
2967 buflen
= ARRAY_SIZE( buf
);
2968 if (WSAAddressToStringW( server
->Address
.lpSockaddr
, server
->Address
.iSockaddrLength
,
2969 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2971 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2976 if ((p
= wcsrchr( ptr
[i
- 1], ':' ))) *p
= 0;
2978 ret
->elem_size
= sizeof(*ptr
);
2983 static struct array
*get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
2985 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
2987 ULONG buflen
, i
= 0, count
= 0;
2988 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2990 if (!list
) return NULL
;
2991 for (address
= list
; address
; address
= address
->Next
) count
++;
2993 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2994 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2999 for (address
= list
; address
; address
= address
->Next
)
3001 buflen
= ARRAY_SIZE( buf
);
3002 if (WSAAddressToStringW( address
->Address
.lpSockaddr
, address
->Address
.iSockaddrLength
,
3003 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
3005 for (; i
> 0; i
--) free( ptr
[i
- 1] );
3011 ret
->elem_size
= sizeof(*ptr
);
3016 static struct array
*get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
3018 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
3020 ULONG i
= 0, count
= 0;
3023 if (!list
) return NULL
;
3024 for (address
= list
; address
; address
= address
->Next
) count
++;
3026 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
3027 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
3032 for (address
= list
; address
; address
= address
->Next
)
3034 if (address
->Address
.lpSockaddr
->sa_family
== AF_INET
)
3036 WCHAR buf
[INET_ADDRSTRLEN
];
3038 ULONG buflen
= ARRAY_SIZE( buf
);
3040 memset( &addr
, 0, sizeof(addr
) );
3041 addr
.sin_family
= AF_INET
;
3042 if (ConvertLengthToIpv4Mask( address
->OnLinkPrefixLength
, &addr
.sin_addr
.S_un
.S_addr
) != NO_ERROR
3043 || WSAAddressToStringW( (SOCKADDR
*)&addr
, sizeof(addr
), NULL
, buf
, &buflen
))
3046 ptr
[i
] = wcsdup( buf
);
3051 swprintf( buf
, ARRAY_SIZE( buf
), L
"%u", address
->OnLinkPrefixLength
);
3052 ptr
[i
] = wcsdup( buf
);
3056 for (; i
> 0; i
--) free( ptr
[i
- 1] );
3062 ret
->elem_size
= sizeof(*ptr
);
3067 static WCHAR
*get_settingid( UINT32 index
)
3070 memset( &guid
, 0, sizeof(guid
) );
3072 return guid_to_str( &guid
);
3075 static enum fill_status
fill_networkadapterconfig( struct table
*table
, const struct expr
*cond
)
3077 struct record_networkadapterconfig
*rec
;
3078 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
3079 UINT row
= 0, offset
= 0, count
= 0;
3080 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3082 if (!(buffer
= get_network_adapters())) return FILL_STATUS_FAILED
;
3084 for (aa
= buffer
; aa
; aa
= aa
->Next
)
3086 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
3088 if (!resize_table( table
, count
, sizeof(*rec
) ))
3091 return FILL_STATUS_FAILED
;
3093 for (aa
= buffer
; aa
; aa
= aa
->Next
)
3095 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
3097 rec
= (struct record_networkadapterconfig
*)(table
->data
+ offset
);
3098 rec
->defaultipgateway
= get_defaultipgateway( aa
->FirstGatewayAddress
);
3099 rec
->description
= wcsdup( aa
->Description
);
3100 rec
->dhcpenabled
= -1;
3101 rec
->dnsdomain
= L
"";
3102 rec
->dnshostname
= get_dnshostname( aa
->FirstUnicastAddress
);
3103 rec
->dnsserversearchorder
= get_dnsserversearchorder( aa
->FirstDnsServerAddress
);
3104 rec
->index
= aa
->IfIndex
;
3105 rec
->ipaddress
= get_ipaddress( aa
->FirstUnicastAddress
);
3106 rec
->ipconnectionmetric
= 20;
3107 rec
->ipenabled
= -1;
3108 rec
->ipsubnet
= get_ipsubnet( aa
->FirstUnicastAddress
);
3109 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
3110 rec
->settingid
= get_settingid( rec
->index
);
3111 if (!match_row( table
, row
, cond
, &status
))
3113 free_row_values( table
, row
);
3116 offset
+= sizeof(*rec
);
3119 TRACE("created %u rows\n", row
);
3120 table
->num_rows
= row
;
3126 static enum fill_status
fill_physicalmemory( struct table
*table
, const struct expr
*cond
)
3128 struct record_physicalmemory
*rec
;
3129 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3132 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3134 rec
= (struct record_physicalmemory
*)table
->data
;
3135 rec
->banklabel
= L
"BANK 0";
3136 rec
->capacity
= get_total_physical_memory();
3137 rec
->caption
= L
"Physical Memory";
3138 rec
->configuredclockspeed
= 1600;
3139 rec
->devicelocator
= L
"DIMM 0";
3140 rec
->formfactor
= 8; /* DIMM */
3141 rec
->memorytype
= 9; /* RAM */
3142 rec
->partnumber
= L
"";
3144 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3147 TRACE("created %u rows\n", row
);
3148 table
->num_rows
= row
;
3152 static enum fill_status
fill_pnpentity( struct table
*table
, const struct expr
*cond
)
3154 struct record_pnpentity
*rec
;
3155 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3156 HDEVINFO device_info_set
;
3157 SP_DEVINFO_DATA devinfo
= {0};
3160 device_info_set
= SetupDiGetClassDevsW( NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
|DIGCF_PRESENT
);
3162 devinfo
.cbSize
= sizeof(devinfo
);
3165 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
3170 resize_table( table
, idx
, sizeof(*rec
) );
3171 table
->num_rows
= 0;
3172 rec
= (struct record_pnpentity
*)table
->data
;
3175 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
3177 WCHAR device_id
[MAX_PATH
];
3178 if (SetupDiGetDeviceInstanceIdW( device_info_set
, &devinfo
, device_id
,
3179 ARRAY_SIZE(device_id
), NULL
))
3181 rec
->device_id
= wcsdup( device_id
);
3182 rec
->manufacturer
= L
"The Wine Project";
3183 rec
->name
= L
"Wine PnP Device";
3186 if (!match_row( table
, table
->num_rows
- 1, cond
, &status
))
3188 free_row_values( table
, table
->num_rows
- 1 );
3196 SetupDiDestroyDeviceInfoList( device_info_set
);
3201 static enum fill_status
fill_printer( struct table
*table
, const struct expr
*cond
)
3203 struct record_printer
*rec
;
3204 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3205 PRINTER_INFO_2W
*info
;
3206 DWORD i
, offset
= 0, count
= 0, size
= 0;
3210 EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &size
, &count
);
3211 if (!count
) return FILL_STATUS_UNFILTERED
;
3213 if (!(info
= malloc( size
))) return FILL_STATUS_FAILED
;
3214 if (!EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, (BYTE
*)info
, size
, &size
, &count
))
3217 return FILL_STATUS_FAILED
;
3219 if (!resize_table( table
, count
, sizeof(*rec
) ))
3222 return FILL_STATUS_FAILED
;
3225 for (i
= 0; i
< count
; i
++)
3227 rec
= (struct record_printer
*)(table
->data
+ offset
);
3228 rec
->attributes
= info
[i
].Attributes
;
3229 swprintf( id
, ARRAY_SIZE( id
), L
"Printer%u", i
);
3230 rec
->device_id
= wcsdup( id
);
3231 rec
->drivername
= wcsdup( info
[i
].pDriverName
);
3232 rec
->horizontalresolution
= info
[i
].pDevMode
->dmPrintQuality
;
3234 rec
->location
= wcsdup( info
[i
].pLocation
);
3235 rec
->name
= wcsdup( info
[i
].pPrinterName
);
3237 rec
->portname
= wcsdup( info
[i
].pPortName
);
3238 if (!match_row( table
, i
, cond
, &status
))
3240 free_row_values( table
, i
);
3243 offset
+= sizeof(*rec
);
3246 TRACE("created %u rows\n", num_rows
);
3247 table
->num_rows
= num_rows
;
3253 static WCHAR
*get_cmdline( DWORD process_id
)
3255 if (process_id
== GetCurrentProcessId()) return wcsdup( GetCommandLineW() );
3256 return NULL
; /* FIXME handle different process case */
3259 static enum fill_status
fill_process( struct table
*table
, const struct expr
*cond
)
3262 struct record_process
*rec
;
3263 PROCESSENTRY32W entry
;
3265 enum fill_status status
= FILL_STATUS_FAILED
;
3266 UINT row
= 0, offset
= 0;
3268 snap
= CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS
, 0 );
3269 if (snap
== INVALID_HANDLE_VALUE
) return FILL_STATUS_FAILED
;
3271 entry
.dwSize
= sizeof(entry
);
3272 if (!Process32FirstW( snap
, &entry
)) goto done
;
3273 if (!resize_table( table
, 8, sizeof(*rec
) )) goto done
;
3277 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
3279 status
= FILL_STATUS_FAILED
;
3283 rec
= (struct record_process
*)(table
->data
+ offset
);
3284 rec
->caption
= wcsdup( entry
.szExeFile
);
3285 rec
->commandline
= get_cmdline( entry
.th32ProcessID
);
3286 rec
->description
= wcsdup( entry
.szExeFile
);
3287 swprintf( handle
, ARRAY_SIZE( handle
), L
"%u", entry
.th32ProcessID
);
3288 rec
->handle
= wcsdup( handle
);
3289 rec
->name
= wcsdup( entry
.szExeFile
);
3290 rec
->process_id
= entry
.th32ProcessID
;
3291 rec
->pprocess_id
= entry
.th32ParentProcessID
;
3292 rec
->thread_count
= entry
.cntThreads
;
3293 rec
->workingsetsize
= 0;
3295 rec
->create
= process_create
;
3296 rec
->get_owner
= process_get_owner
;
3297 if (!match_row( table
, row
, cond
, &status
))
3299 free_row_values( table
, row
);
3302 offset
+= sizeof(*rec
);
3304 } while (Process32NextW( snap
, &entry
));
3306 TRACE("created %u rows\n", row
);
3307 table
->num_rows
= row
;
3310 CloseHandle( snap
);
3314 void do_cpuid( unsigned int ax
, int *p
)
3316 #if defined(__i386__) || defined(__x86_64__)
3323 static unsigned int get_processor_model( unsigned int reg0
, unsigned int *stepping
, unsigned int *family
)
3325 unsigned int model
, family_id
= (reg0
& (0x0f << 8)) >> 8;
3327 model
= (reg0
& (0x0f << 4)) >> 4;
3328 if (family_id
== 6 || family_id
== 15) model
|= (reg0
& (0x0f << 16)) >> 12;
3331 *family
= family_id
;
3332 if (family_id
== 15) *family
+= (reg0
& (0xff << 20)) >> 20;
3334 *stepping
= reg0
& 0x0f;
3337 static void regs_to_str( int *regs
, unsigned int len
, WCHAR
*buffer
)
3340 unsigned char *p
= (unsigned char *)regs
;
3342 for (i
= 0; i
< len
; i
++) { buffer
[i
] = *p
++; }
3345 static void get_processor_manufacturer( WCHAR
*manufacturer
, UINT len
)
3347 int tmp
, regs
[4] = {0, 0, 0, 0};
3349 do_cpuid( 0, regs
);
3350 tmp
= regs
[2]; /* swap edx and ecx */
3354 regs_to_str( regs
+ 1, min( 12, len
), manufacturer
);
3356 static const WCHAR
*get_osarchitecture(void)
3359 GetNativeSystemInfo( &info
);
3360 if (info
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"64-bit";
3363 static void get_processor_caption( WCHAR
*caption
, UINT len
)
3366 WCHAR manufacturer
[13];
3367 int regs
[4] = {0, 0, 0, 0};
3368 unsigned int family
, model
, stepping
;
3370 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3371 if (!wcscmp( get_osarchitecture(), L
"32-bit" )) arch
= L
"x86";
3372 else if (!wcscmp( manufacturer
, L
"AuthenticAMD" )) arch
= L
"AMD64";
3373 else arch
= L
"Intel64";
3375 do_cpuid( 1, regs
);
3377 model
= get_processor_model( regs
[0], &stepping
, &family
);
3378 swprintf( caption
, len
, L
"%s Family %u Model %u Stepping %u", arch
, family
, model
, stepping
);
3380 static void get_processor_version( WCHAR
*version
, UINT len
)
3382 int regs
[4] = {0, 0, 0, 0};
3383 unsigned int model
, stepping
;
3385 do_cpuid( 1, regs
);
3387 model
= get_processor_model( regs
[0], &stepping
, NULL
);
3388 swprintf( version
, len
, L
"Model %u Stepping %u", model
, stepping
);
3390 static UINT16
get_processor_revision(void)
3392 int regs
[4] = {0, 0, 0, 0};
3393 do_cpuid( 1, regs
);
3396 static void get_processor_id( WCHAR
*processor_id
, UINT len
)
3398 int regs
[4] = {0, 0, 0, 0};
3400 do_cpuid( 1, regs
);
3401 swprintf( processor_id
, len
, L
"%08X%08X", regs
[3], regs
[0] );
3403 static void get_processor_name( WCHAR
*name
)
3405 int regs
[4] = {0, 0, 0, 0};
3408 do_cpuid( 0x80000000, regs
);
3409 if (regs
[0] >= 0x80000004)
3411 do_cpuid( 0x80000002, regs
);
3412 regs_to_str( regs
, 16, name
);
3413 do_cpuid( 0x80000003, regs
);
3414 regs_to_str( regs
, 16, name
+ 16 );
3415 do_cpuid( 0x80000004, regs
);
3416 regs_to_str( regs
, 16, name
+ 32 );
3418 for (i
= lstrlenW(name
) - 1; i
>= 0 && name
[i
] == ' '; i
--) name
[i
] = 0;
3420 static UINT
get_processor_currentclockspeed( UINT index
)
3422 PROCESSOR_POWER_INFORMATION
*info
;
3423 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3426 if ((info
= malloc( size
)))
3428 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3429 if (!status
) ret
= info
[index
].CurrentMhz
;
3434 static UINT
get_processor_maxclockspeed( UINT index
)
3436 PROCESSOR_POWER_INFORMATION
*info
;
3437 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3440 if ((info
= malloc( size
)))
3442 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3443 if (!status
) ret
= info
[index
].MaxMhz
;
3449 static enum fill_status
fill_processor( struct table
*table
, const struct expr
*cond
)
3451 WCHAR caption
[100], device_id
[14], processor_id
[17], manufacturer
[13], name
[49] = {0}, version
[50];
3452 struct record_processor
*rec
;
3453 UINT i
, offset
= 0, num_rows
= 0, num_logical
, num_physical
, num_packages
;
3454 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3456 num_logical
= get_logical_processor_count( &num_physical
, &num_packages
);
3458 if (!resize_table( table
, num_packages
, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3460 get_processor_caption( caption
, ARRAY_SIZE( caption
) );
3461 get_processor_id( processor_id
, ARRAY_SIZE( processor_id
) );
3462 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3463 get_processor_name( name
);
3464 get_processor_version( version
, ARRAY_SIZE( version
) );
3466 for (i
= 0; i
< num_packages
; i
++)
3468 rec
= (struct record_processor
*)(table
->data
+ offset
);
3469 rec
->addresswidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3470 rec
->architecture
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 0 : 9;
3471 rec
->caption
= wcsdup( caption
);
3472 rec
->cpu_status
= 1; /* CPU Enabled */
3473 rec
->currentclockspeed
= get_processor_currentclockspeed( i
);
3474 rec
->datawidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3475 rec
->description
= wcsdup( caption
);
3476 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"CPU%u", i
);
3477 rec
->device_id
= wcsdup( device_id
);
3478 rec
->family
= 2; /* Unknown */
3480 rec
->manufacturer
= wcsdup( manufacturer
);
3481 rec
->maxclockspeed
= get_processor_maxclockspeed( i
);
3482 rec
->name
= wcsdup( name
);
3483 rec
->num_cores
= num_physical
/ num_packages
;
3484 rec
->num_logical_processors
= num_logical
/ num_packages
;
3485 rec
->processor_id
= wcsdup( processor_id
);
3486 rec
->processortype
= 3; /* central processor */
3487 rec
->revision
= get_processor_revision();
3488 rec
->unique_id
= NULL
;
3489 rec
->version
= wcsdup( version
);
3490 if (!match_row( table
, i
, cond
, &status
))
3492 free_row_values( table
, i
);
3495 offset
+= sizeof(*rec
);
3499 TRACE("created %u rows\n", num_rows
);
3500 table
->num_rows
= num_rows
;
3504 static INT16
get_currenttimezone(void)
3506 TIME_ZONE_INFORMATION info
;
3507 DWORD status
= GetTimeZoneInformation( &info
);
3508 if (status
== TIME_ZONE_ID_INVALID
) return 0;
3509 if (status
== TIME_ZONE_ID_DAYLIGHT
) return -(info
.Bias
+ info
.DaylightBias
);
3510 return -(info
.Bias
+ info
.StandardBias
);
3513 static WCHAR
*get_lastbootuptime(void)
3515 SYSTEM_TIMEOFDAY_INFORMATION ti
;
3519 if (!(ret
= malloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3521 NtQuerySystemInformation( SystemTimeOfDayInformation
, &ti
, sizeof(ti
), NULL
);
3522 RtlTimeToTimeFields( &ti
.BootTime
, &tf
);
3523 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u+000", tf
.Year
, tf
.Month
, tf
.Day
, tf
.Hour
, tf
.Minute
,
3524 tf
.Second
, tf
.Milliseconds
* 1000 );
3527 static WCHAR
*get_localdatetime(void)
3529 TIME_ZONE_INFORMATION tzi
;
3535 Status
= GetTimeZoneInformation(&tzi
);
3537 if(Status
== TIME_ZONE_ID_INVALID
) return NULL
;
3539 if(Status
== TIME_ZONE_ID_DAYLIGHT
)
3540 Bias
+= tzi
.DaylightBias
;
3542 Bias
+= tzi
.StandardBias
;
3543 if (!(ret
= malloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3546 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u%+03d", st
.wYear
, st
.wMonth
, st
.wDay
, st
.wHour
, st
.wMinute
,
3547 st
.wSecond
, st
.wMilliseconds
* 1000, -Bias
);
3550 static WCHAR
*get_systemdirectory(void)
3555 if (!(ret
= malloc( MAX_PATH
* sizeof(WCHAR
) ))) return NULL
;
3556 Wow64DisableWow64FsRedirection( &redir
);
3557 GetSystemDirectoryW( ret
, MAX_PATH
);
3558 Wow64RevertWow64FsRedirection( redir
);
3561 static WCHAR
*get_systemdrive(void)
3563 WCHAR
*ret
= malloc( 3 * sizeof(WCHAR
) ); /* "c:" */
3564 if (ret
&& GetEnvironmentVariableW( L
"SystemDrive", ret
, 3 )) return ret
;
3568 static WCHAR
*get_codeset(void)
3570 WCHAR
*ret
= malloc( 11 * sizeof(WCHAR
) );
3571 if (ret
) swprintf( ret
, 11, L
"%u", GetACP() );
3574 static WCHAR
*get_countrycode(void)
3576 WCHAR
*ret
= malloc( 6 * sizeof(WCHAR
) );
3577 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ICOUNTRY
, ret
, 6 );
3580 static WCHAR
*get_locale(void)
3582 WCHAR
*ret
= malloc( 5 * sizeof(WCHAR
) );
3583 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, ret
, 5 );
3587 static WCHAR
*get_reg_str( HKEY root
, const WCHAR
*path
, const WCHAR
*value
)
3593 if (!RegOpenKeyExW( root
, path
, 0, KEY_READ
, &hkey
) &&
3594 !RegQueryValueExW( hkey
, value
, NULL
, &type
, NULL
, &size
) && type
== REG_SZ
&&
3595 (ret
= malloc( size
+ sizeof(WCHAR
) )))
3597 size
+= sizeof(WCHAR
);
3598 if (RegQueryValueExW( hkey
, value
, NULL
, NULL
, (BYTE
*)ret
, &size
))
3604 if (hkey
) RegCloseKey( hkey
);
3608 static WCHAR
*get_organization(void)
3610 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
3611 L
"RegisteredOrganization" );
3614 static WCHAR
*get_osbuildnumber( OSVERSIONINFOEXW
*ver
)
3616 WCHAR
*ret
= malloc( 11 * sizeof(WCHAR
) );
3617 if (ret
) swprintf( ret
, 11, L
"%u", ver
->dwBuildNumber
);
3621 static WCHAR
*get_osbuildtype(void)
3623 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"CurrentType" );
3626 static WCHAR
*get_oscaption( OSVERSIONINFOEXW
*ver
)
3628 static const WCHAR windowsW
[] = L
"Microsoft Windows ";
3629 static const WCHAR win2000W
[] = L
"2000 Professional";
3630 static const WCHAR win2003W
[] = L
"Server 2003 Standard Edition";
3631 static const WCHAR winxpW
[] = L
"XP Professional";
3632 static const WCHAR winxp64W
[] = L
"XP Professional x64 Edition";
3633 static const WCHAR vistaW
[] = L
"Vista Ultimate";
3634 static const WCHAR win2008W
[] = L
"Server 2008 Standard";
3635 static const WCHAR win7W
[] = L
"7 Professional";
3636 static const WCHAR win2008r2W
[] = L
"Server 2008 R2 Standard";
3637 static const WCHAR win8W
[] = L
"8 Pro";
3638 static const WCHAR win81W
[] = L
"8.1 Pro";
3639 static const WCHAR win10W
[] = L
"10 Pro";
3640 static const WCHAR win11W
[] = L
"11 Pro";
3641 int len
= ARRAY_SIZE( windowsW
) - 1;
3644 if (!(ret
= malloc( len
* sizeof(WCHAR
) + sizeof(win2003W
) ))) return NULL
;
3645 memcpy( ret
, windowsW
, sizeof(windowsW
) );
3646 if (ver
->dwMajorVersion
== 10 && ver
->dwMinorVersion
== 0)
3648 if (ver
->dwBuildNumber
>= 22000) memcpy( ret
+ len
, win11W
, sizeof(win11W
) );
3649 else memcpy( ret
+ len
, win10W
, sizeof(win10W
) );
3651 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 3) memcpy( ret
+ len
, win81W
, sizeof(win81W
) );
3652 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 2) memcpy( ret
+ len
, win8W
, sizeof(win8W
) );
3653 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 1)
3655 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, win7W
, sizeof(win7W
) );
3656 else memcpy( ret
+ len
, win2008r2W
, sizeof(win2008r2W
) );
3658 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 0)
3660 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, vistaW
, sizeof(vistaW
) );
3661 else memcpy( ret
+ len
, win2008W
, sizeof(win2008W
) );
3663 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 2)
3665 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, winxp64W
, sizeof(winxp64W
) );
3666 else memcpy( ret
+ len
, win2003W
, sizeof(win2003W
) );
3668 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 1) memcpy( ret
+ len
, winxpW
, sizeof(winxpW
) );
3669 else memcpy( ret
+ len
, win2000W
, sizeof(win2000W
) );
3673 static WCHAR
*get_osname( const WCHAR
*caption
)
3675 static const WCHAR partitionW
[] = L
"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3676 int len
= lstrlenW( caption
);
3679 if (!(ret
= malloc( len
* sizeof(WCHAR
) + sizeof(partitionW
) ))) return NULL
;
3680 memcpy( ret
, caption
, len
* sizeof(WCHAR
) );
3681 memcpy( ret
+ len
, partitionW
, sizeof(partitionW
) );
3685 static WCHAR
*get_osserialnumber(void)
3687 WCHAR
*ret
= get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"ProductId" );
3688 if (!ret
) ret
= wcsdup( L
"12345-OEM-1234567-12345" );
3692 static WCHAR
*get_osversion( OSVERSIONINFOEXW
*ver
)
3694 WCHAR
*ret
= malloc( 33 * sizeof(WCHAR
) );
3695 if (ret
) swprintf( ret
, 33, L
"%u.%u.%u", ver
->dwMajorVersion
, ver
->dwMinorVersion
, ver
->dwBuildNumber
);
3699 static DWORD
get_operatingsystemsku(void)
3701 DWORD ret
= PRODUCT_UNDEFINED
;
3702 GetProductInfo( 6, 0, 0, 0, &ret
);
3706 static WCHAR
*get_registereduser(void)
3708 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"RegisteredOwner" );
3711 static WCHAR
*get_windowsdirectory(void)
3713 WCHAR dir
[MAX_PATH
];
3714 if (!GetWindowsDirectoryW( dir
, ARRAY_SIZE(dir
) )) return NULL
;
3715 return wcsdup( dir
);
3718 static WCHAR
*get_osinstalldate(void)
3720 HANDLE handle
= CreateFileW( L
"c:\\", GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
3721 FILE_FLAG_BACKUP_SEMANTICS
, NULL
);
3722 if (handle
!= INVALID_HANDLE_VALUE
)
3724 FILETIME ft
= { 0 };
3727 GetFileTime( handle
, &ft
, NULL
, NULL
);
3728 CloseHandle( handle
);
3729 if ((ret
= malloc( 26 * sizeof(WCHAR
) )))
3731 SYSTEMTIME st
= { 0 };
3732 FileTimeToSystemTime( &ft
, &st
);
3733 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u+000", st
.wYear
, st
.wMonth
, st
.wDay
, st
.wHour
,
3734 st
.wMinute
, st
.wSecond
, st
.wMilliseconds
* 1000 );
3738 return wcsdup( L
"20230101000000.000000+000" );
3741 static enum fill_status
fill_operatingsystem( struct table
*table
, const struct expr
*cond
)
3743 struct record_operatingsystem
*rec
;
3744 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3745 RTL_OSVERSIONINFOEXW ver
;
3748 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3750 ver
.dwOSVersionInfoSize
= sizeof(ver
);
3751 RtlGetVersion( &ver
);
3753 rec
= (struct record_operatingsystem
*)table
->data
;
3754 rec
->bootdevice
= L
"\\Device\\HarddiskVolume1";
3755 rec
->buildnumber
= get_osbuildnumber( &ver
);
3756 rec
->buildtype
= get_osbuildtype();
3757 rec
->caption
= get_oscaption( &ver
);
3758 rec
->codeset
= get_codeset();
3759 rec
->countrycode
= get_countrycode();
3760 rec
->csdversion
= ver
.szCSDVersion
[0] ? wcsdup( ver
.szCSDVersion
) : NULL
;
3761 rec
->csname
= get_computername();
3762 rec
->currenttimezone
= get_currenttimezone();
3763 rec
->freephysicalmemory
= get_available_physical_memory() / 1024;
3764 rec
->freevirtualmemory
= get_available_virtual_memory() / 1024;
3765 rec
->installdate
= get_osinstalldate();
3766 rec
->lastbootuptime
= get_lastbootuptime();
3767 rec
->localdatetime
= get_localdatetime();
3768 rec
->locale
= get_locale();
3769 rec
->manufacturer
= L
"The Wine Project";
3770 rec
->name
= get_osname( rec
->caption
);
3771 rec
->operatingsystemsku
= get_operatingsystemsku();
3772 rec
->organization
= get_organization();
3773 rec
->osarchitecture
= get_osarchitecture();
3774 rec
->oslanguage
= GetSystemDefaultLangID();
3775 rec
->osproductsuite
= 2461140; /* Windows XP Professional */
3776 rec
->ostype
= 18; /* WINNT */
3778 rec
->producttype
= 1;
3779 rec
->registereduser
= get_registereduser();
3780 rec
->serialnumber
= get_osserialnumber();
3781 rec
->servicepackmajor
= ver
.wServicePackMajor
;
3782 rec
->servicepackminor
= ver
.wServicePackMinor
;
3783 rec
->status
= L
"OK";
3784 rec
->suitemask
= 272; /* Single User + Terminal */
3785 rec
->systemdirectory
= get_systemdirectory();
3786 rec
->systemdrive
= get_systemdrive();
3787 rec
->totalvirtualmemorysize
= get_total_virtual_memory() / 1024;
3788 rec
->totalvisiblememorysize
= get_total_physical_memory() / 1024;
3789 rec
->version
= get_osversion( &ver
);
3790 rec
->windowsdirectory
= get_windowsdirectory();
3791 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3794 TRACE("created %u rows\n", row
);
3795 table
->num_rows
= row
;
3799 static const WCHAR
*get_service_type( DWORD type
)
3801 if (type
& SERVICE_KERNEL_DRIVER
) return L
"Kernel Driver";
3802 else if (type
& SERVICE_FILE_SYSTEM_DRIVER
) return L
"File System Driver";
3803 else if (type
& SERVICE_WIN32_OWN_PROCESS
) return L
"Own Process";
3804 else if (type
& SERVICE_WIN32_SHARE_PROCESS
) return L
"Share Process";
3805 else ERR( "unhandled type %#lx\n", type
);
3808 static const WCHAR
*get_service_state( DWORD state
)
3812 case SERVICE_STOPPED
: return L
"Stopped";
3813 case SERVICE_START_PENDING
: return L
"Start Pending";
3814 case SERVICE_STOP_PENDING
: return L
"Stop Pending";
3815 case SERVICE_RUNNING
: return L
"Running";
3817 ERR( "unknown state %lu\n", state
);
3821 static const WCHAR
*get_service_startmode( DWORD mode
)
3825 case SERVICE_BOOT_START
: return L
"Boot";
3826 case SERVICE_SYSTEM_START
: return L
"System";
3827 case SERVICE_AUTO_START
: return L
"Auto";
3828 case SERVICE_DEMAND_START
: return L
"Manual";
3829 case SERVICE_DISABLED
: return L
"Disabled";
3831 ERR( "unknown mode %#lx\n", mode
);
3835 static QUERY_SERVICE_CONFIGW
*query_service_config( SC_HANDLE manager
, const WCHAR
*name
)
3837 QUERY_SERVICE_CONFIGW
*config
= NULL
;
3841 if (!(service
= OpenServiceW( manager
, name
, SERVICE_QUERY_CONFIG
))) return NULL
;
3842 QueryServiceConfigW( service
, NULL
, 0, &size
);
3843 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) goto done
;
3844 if (!(config
= malloc( size
))) goto done
;
3845 if (QueryServiceConfigW( service
, config
, size
, &size
)) goto done
;
3850 CloseServiceHandle( service
);
3854 static enum fill_status
fill_service( struct table
*table
, const struct expr
*cond
)
3856 struct record_service
*rec
;
3858 ENUM_SERVICE_STATUS_PROCESSW
*tmp
, *services
= NULL
;
3859 SERVICE_STATUS_PROCESS
*status
;
3860 WCHAR sysnameW
[MAX_COMPUTERNAME_LENGTH
+ 1];
3861 DWORD len
= ARRAY_SIZE( sysnameW
), needed
, count
;
3862 UINT i
, row
= 0, offset
= 0, size
= 256;
3863 enum fill_status fill_status
= FILL_STATUS_FAILED
;
3866 if (!(manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
))) return FILL_STATUS_FAILED
;
3867 if (!(services
= malloc( size
))) goto done
;
3869 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3870 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3871 &count
, NULL
, NULL
);
3874 if (GetLastError() != ERROR_MORE_DATA
) goto done
;
3876 if (!(tmp
= realloc( services
, size
))) goto done
;
3878 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3879 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3880 &count
, NULL
, NULL
);
3881 if (!ret
) goto done
;
3883 if (!resize_table( table
, count
, sizeof(*rec
) )) goto done
;
3885 GetComputerNameW( sysnameW
, &len
);
3886 fill_status
= FILL_STATUS_UNFILTERED
;
3888 for (i
= 0; i
< count
; i
++)
3890 QUERY_SERVICE_CONFIGW
*config
;
3892 if (!(config
= query_service_config( manager
, services
[i
].lpServiceName
))) continue;
3894 status
= &services
[i
].ServiceStatusProcess
;
3895 rec
= (struct record_service
*)(table
->data
+ offset
);
3896 rec
->accept_pause
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_PAUSE_CONTINUE
) ? -1 : 0;
3897 rec
->accept_stop
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_STOP
) ? -1 : 0;
3898 rec
->displayname
= wcsdup( services
[i
].lpDisplayName
);
3899 rec
->name
= wcsdup( services
[i
].lpServiceName
);
3900 rec
->process_id
= status
->dwProcessId
;
3901 rec
->servicetype
= get_service_type( status
->dwServiceType
);
3902 rec
->startmode
= get_service_startmode( config
->dwStartType
);
3903 rec
->state
= get_service_state( status
->dwCurrentState
);
3904 rec
->systemname
= wcsdup( sysnameW
);
3905 rec
->pause_service
= service_pause_service
;
3906 rec
->resume_service
= service_resume_service
;
3907 rec
->start_service
= service_start_service
;
3908 rec
->stop_service
= service_stop_service
;
3910 if (!match_row( table
, row
, cond
, &fill_status
))
3912 free_row_values( table
, row
);
3915 offset
+= sizeof(*rec
);
3919 TRACE("created %u rows\n", row
);
3920 table
->num_rows
= row
;
3923 CloseServiceHandle( manager
);
3928 static WCHAR
*get_accountname( LSA_TRANSLATED_NAME
*name
)
3930 if (!name
|| !name
->Name
.Buffer
) return NULL
;
3931 return wcsdup( name
->Name
.Buffer
);
3933 static struct array
*get_binaryrepresentation( PSID sid
, UINT len
)
3938 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
3939 if (!(ptr
= malloc( len
)))
3944 memcpy( ptr
, sid
, len
);
3945 ret
->elem_size
= sizeof(*ptr
);
3950 static WCHAR
*get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST
*domain
)
3952 if (!domain
|| !domain
->Domains
|| !domain
->Domains
->Name
.Buffer
) return NULL
;
3953 return wcsdup( domain
->Domains
->Name
.Buffer
);
3955 static const WCHAR
*find_sid_str( const struct expr
*cond
)
3957 const struct expr
*left
, *right
;
3958 const WCHAR
*ret
= NULL
;
3960 if (!cond
|| cond
->type
!= EXPR_COMPLEX
|| cond
->u
.expr
.op
!= OP_EQ
) return NULL
;
3962 left
= cond
->u
.expr
.left
;
3963 right
= cond
->u
.expr
.right
;
3964 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&& !wcsicmp( left
->u
.propval
->name
, L
"SID" ))
3966 ret
= right
->u
.sval
;
3968 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&& !wcsicmp( right
->u
.propval
->name
, L
"SID" ))
3975 static enum fill_status
fill_sid( struct table
*table
, const struct expr
*cond
)
3978 LSA_REFERENCED_DOMAIN_LIST
*domain
;
3979 LSA_TRANSLATED_NAME
*name
;
3981 LSA_OBJECT_ATTRIBUTES attrs
;
3983 struct record_sid
*rec
;
3986 if (!(str
= find_sid_str( cond
))) return FILL_STATUS_FAILED
;
3987 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3989 if (!ConvertStringSidToSidW( str
, &sid
)) return FILL_STATUS_FAILED
;
3990 len
= GetLengthSid( sid
);
3992 memset( &attrs
, 0, sizeof(attrs
) );
3993 attrs
.Length
= sizeof(attrs
);
3994 if (LsaOpenPolicy( NULL
, &attrs
, POLICY_ALL_ACCESS
, &handle
))
3997 return FILL_STATUS_FAILED
;
3999 if (LsaLookupSids( handle
, 1, &sid
, &domain
, &name
))
4003 return FILL_STATUS_FAILED
;
4006 rec
= (struct record_sid
*)table
->data
;
4007 rec
->accountname
= get_accountname( name
);
4008 rec
->binaryrepresentation
= get_binaryrepresentation( sid
, len
);
4009 rec
->referenceddomainname
= get_referenceddomainname( domain
);
4010 rec
->sid
= wcsdup( str
);
4011 rec
->sidlength
= len
;
4013 TRACE("created 1 row\n");
4014 table
->num_rows
= 1;
4016 LsaFreeMemory( domain
);
4017 LsaFreeMemory( name
);
4020 return FILL_STATUS_FILTERED
;
4023 static WCHAR
*get_systemenclosure_manufacturer( const char *buf
, UINT len
)
4025 WCHAR
*ret
= get_smbios_string( SMBIOS_TYPE_CHASSIS
, offsetof(struct smbios_chassis
, vendor
), buf
, len
);
4026 if (!ret
) return wcsdup( L
"Wine" );
4030 static int get_systemenclosure_lockpresent( const char *buf
, UINT len
)
4032 const struct smbios_header
*hdr
;
4033 const struct smbios_chassis
*chassis
;
4035 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) return 0;
4037 chassis
= (const struct smbios_chassis
*)hdr
;
4038 return (chassis
->type
& 0x80) ? -1 : 0;
4041 static struct array
*dup_array( const struct array
*src
)
4044 if (!(dst
= malloc( sizeof(*dst
) ))) return NULL
;
4045 if (!(dst
->ptr
= malloc( src
->count
* src
->elem_size
)))
4050 memcpy( dst
->ptr
, src
->ptr
, src
->count
* src
->elem_size
);
4051 dst
->elem_size
= src
->elem_size
;
4052 dst
->count
= src
->count
;
4056 static struct array
*get_systemenclosure_chassistypes( const char *buf
, UINT len
)
4058 const struct smbios_header
*hdr
;
4059 const struct smbios_chassis
*chassis
;
4060 struct array
*ret
= NULL
;
4063 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) goto done
;
4064 chassis
= (const struct smbios_chassis
*)hdr
;
4066 if (!(ret
= malloc( sizeof(*ret
) ))) goto done
;
4067 if (!(types
= malloc( sizeof(*types
) )))
4072 types
[0] = chassis
->type
& ~0x80;
4074 ret
->elem_size
= sizeof(*types
);
4079 if (!ret
) ret
= dup_array( &systemenclosure_chassistypes_array
);
4083 static enum fill_status
fill_systemenclosure( struct table
*table
, const struct expr
*cond
)
4085 struct record_systemenclosure
*rec
;
4086 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4090 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4092 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
4093 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
4094 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
4096 rec
= (struct record_systemenclosure
*)table
->data
;
4097 rec
->caption
= L
"System Enclosure";
4098 rec
->chassistypes
= get_systemenclosure_chassistypes( buf
, len
);
4099 rec
->description
= L
"System Enclosure";
4100 rec
->lockpresent
= get_systemenclosure_lockpresent( buf
, len
);
4101 rec
->manufacturer
= get_systemenclosure_manufacturer( buf
, len
);
4102 rec
->name
= L
"System Enclosure";
4103 rec
->tag
= L
"System Enclosure 0";
4104 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4109 TRACE("created %u rows\n", row
);
4110 table
->num_rows
= row
;
4114 static WCHAR
*get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
4116 static const WCHAR fmtW
[] = L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
4117 UINT len
= sizeof(fmtW
) + 2;
4120 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4121 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
4125 #define HW_VENDOR_AMD 0x1002
4126 #define HW_VENDOR_NVIDIA 0x10de
4127 #define HW_VENDOR_VMWARE 0x15ad
4128 #define HW_VENDOR_INTEL 0x8086
4130 static const WCHAR
*get_videocontroller_installeddriver( UINT vendorid
)
4132 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
4134 if (vendorid
== HW_VENDOR_AMD
) return L
"aticfx32.dll";
4135 else if (vendorid
== HW_VENDOR_NVIDIA
) return L
"nvd3dum.dll";
4136 else if (vendorid
== HW_VENDOR_INTEL
) return L
"igdudim32.dll";
4140 static BOOL
get_dxgi_adapter_desc( DXGI_ADAPTER_DESC
*desc
)
4142 IDXGIFactory
*factory
;
4143 IDXGIAdapter
*adapter
;
4146 memset( desc
, 0, sizeof(*desc
) );
4147 hr
= CreateDXGIFactory( &IID_IDXGIFactory
, (void **)&factory
);
4148 if (FAILED( hr
)) return FALSE
;
4150 hr
= IDXGIFactory_EnumAdapters( factory
, 0, &adapter
);
4153 IDXGIFactory_Release( factory
);
4157 hr
= IDXGIAdapter_GetDesc( adapter
, desc
);
4158 IDXGIAdapter_Release( adapter
);
4159 IDXGIFactory_Release( factory
);
4160 return SUCCEEDED( hr
);
4163 static enum fill_status
fill_videocontroller( struct table
*table
, const struct expr
*cond
)
4165 struct record_videocontroller
*rec
;
4166 DXGI_ADAPTER_DESC desc
;
4167 UINT row
= 0, hres
= 1024, vres
= 768, vidmem
= 512 * 1024 * 1024;
4168 const WCHAR
*name
= L
"VideoController1";
4169 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4172 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4174 if (get_dxgi_adapter_desc( &desc
))
4176 if (desc
.DedicatedVideoMemory
> UINT_MAX
) vidmem
= 0xfff00000;
4177 else vidmem
= desc
.DedicatedVideoMemory
;
4178 name
= desc
.Description
;
4181 rec
= (struct record_videocontroller
*)table
->data
;
4182 rec
->adapter_compatibility
= L
"(Standard display types)";
4183 rec
->adapter_dactype
= L
"Integrated RAMDAC";
4184 rec
->adapter_ram
= vidmem
;
4185 rec
->availability
= 3; /* Running or Full Power */
4186 rec
->config_errorcode
= 0; /* no error */
4187 rec
->caption
= wcsdup( name
);
4188 rec
->current_bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
4189 rec
->current_horizontalres
= hres
;
4190 rec
->current_refreshrate
= 0; /* default refresh rate */
4191 rec
->current_scanmode
= 2; /* Unknown */
4192 rec
->current_verticalres
= vres
;
4193 rec
->description
= wcsdup( name
);
4194 rec
->device_id
= L
"VideoController1";
4195 rec
->driverdate
= L
"20230420000000.000000-000";
4196 rec
->driverversion
= L
"31.0.14051.5006";
4197 rec
->installeddriver
= get_videocontroller_installeddriver( desc
.VendorId
);
4198 rec
->name
= wcsdup( name
);
4199 rec
->pnpdevice_id
= get_videocontroller_pnpdeviceid( &desc
);
4200 rec
->status
= L
"OK";
4201 rec
->videoarchitecture
= 2; /* Unknown */
4202 rec
->videomemorytype
= 2; /* Unknown */
4203 swprintf( mode
, ARRAY_SIZE( mode
), L
"%u x %u x %I64u colors", hres
, vres
, (UINT64
)1 << rec
->current_bitsperpixel
);
4204 rec
->videomodedescription
= wcsdup( mode
);
4205 rec
->videoprocessor
= wcsdup( name
);
4206 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4209 TRACE("created %u rows\n", row
);
4210 table
->num_rows
= row
;
4214 static WCHAR
*get_volume_driveletter( const WCHAR
*volume
)
4219 if (!GetVolumePathNamesForVolumeNameW( volume
, NULL
, 0, &len
) && GetLastError() != ERROR_MORE_DATA
) return NULL
;
4220 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4221 if (!GetVolumePathNamesForVolumeNameW( volume
, ret
, len
, &len
) || !wcschr( ret
, ':' ))
4226 wcschr( ret
, ':' )[1] = 0;
4230 static enum fill_status
fill_volume( struct table
*table
, const struct expr
*cond
)
4232 struct record_volume
*rec
;
4233 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4234 UINT row
= 0, offset
= 0;
4235 WCHAR path
[MAX_PATH
];
4238 if (!resize_table( table
, 2, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4240 handle
= FindFirstVolumeW( path
, ARRAY_SIZE(path
) );
4241 while (handle
!= INVALID_HANDLE_VALUE
)
4243 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4245 rec
= (struct record_volume
*)(table
->data
+ offset
);
4246 rec
->deviceid
= wcsdup( path
);
4247 rec
->driveletter
= get_volume_driveletter( path
);
4249 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4252 offset
+= sizeof(*rec
);
4256 if (!FindNextVolumeW( handle
, path
, ARRAY_SIZE(path
) ))
4258 FindVolumeClose( handle
);
4259 handle
= INVALID_HANDLE_VALUE
;
4263 TRACE("created %u rows\n", row
);
4264 table
->num_rows
= row
;
4268 static WCHAR
*get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
4270 static const WCHAR fmtW
[] = L
"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
4271 UINT len
= sizeof(fmtW
) + 2;
4274 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4275 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
4279 static enum fill_status
fill_sounddevice( struct table
*table
, const struct expr
*cond
)
4281 struct record_sounddevice
*rec
;
4282 DXGI_ADAPTER_DESC desc
;
4284 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4286 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4288 get_dxgi_adapter_desc( &desc
);
4290 rec
= (struct record_sounddevice
*)table
->data
;
4291 rec
->caption
= L
"Wine Audio Device";
4292 rec
->deviceid
= get_sounddevice_pnpdeviceid( &desc
);
4293 rec
->manufacturer
= L
"The Wine Project";
4294 rec
->name
= L
"Wine Audio Device";
4295 rec
->pnpdeviceid
= get_sounddevice_pnpdeviceid( &desc
);
4296 rec
->productname
= L
"Wine Audio Device";
4297 rec
->status
= L
"OK";
4298 rec
->statusinfo
= 3;
4299 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4302 TRACE("created %u rows\n", row
);
4303 table
->num_rows
= row
;
4307 #define C(c) sizeof(c)/sizeof(c[0]), c
4308 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
4309 static struct table cimv2_builtin_classes
[] =
4311 { L
"__ASSOCIATORS", C(col_associator
), D(data_associator
) },
4312 { L
"__PARAMETERS", C(col_param
), D(data_param
) },
4313 { L
"__QUALIFIERS", C(col_qualifier
), D(data_qualifier
) },
4314 { L
"__SystemSecurity", C(col_systemsecurity
), D(data_systemsecurity
) },
4315 { L
"CIM_DataFile", C(col_datafile
), 0, 0, NULL
, fill_datafile
},
4316 { L
"CIM_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
4317 { L
"CIM_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4318 { L
"SoftwareLicensingProduct", C(col_softwarelicensingproduct
), D(data_softwarelicensingproduct
) },
4319 { L
"StdRegProv", C(col_stdregprov
), D(data_stdregprov
) },
4320 { L
"SystemRestore", C(col_sysrestore
), D(data_sysrestore
) },
4321 { L
"Win32_BIOS", C(col_bios
), 0, 0, NULL
, fill_bios
},
4322 { L
"Win32_BaseBoard", C(col_baseboard
), 0, 0, NULL
, fill_baseboard
},
4323 { L
"Win32_CDROMDrive", C(col_cdromdrive
), 0, 0, NULL
, fill_cdromdrive
},
4324 { L
"Win32_ComputerSystem", C(col_compsys
), 0, 0, NULL
, fill_compsys
},
4325 { L
"Win32_ComputerSystemProduct", C(col_compsysproduct
), 0, 0, NULL
, fill_compsysproduct
},
4326 { L
"Win32_DesktopMonitor", C(col_desktopmonitor
), 0, 0, NULL
, fill_desktopmonitor
},
4327 { L
"Win32_Directory", C(col_directory
), 0, 0, NULL
, fill_directory
},
4328 { L
"Win32_DiskDrive", C(col_diskdrive
), 0, 0, NULL
, fill_diskdrive
},
4329 { L
"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition
), 0, 0, NULL
, fill_diskdrivetodiskpartition
},
4330 { L
"Win32_DiskPartition", C(col_diskpartition
), 0, 0, NULL
, fill_diskpartition
},
4331 { L
"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig
), 0, 0, NULL
, fill_displaycontrollerconfig
},
4332 { L
"Win32_IP4RouteTable", C(col_ip4routetable
), 0, 0, NULL
, fill_ip4routetable
},
4333 { L
"Win32_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
4334 { L
"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition
), 0, 0, NULL
, fill_logicaldisktopartition
},
4335 { L
"Win32_NetworkAdapter", C(col_networkadapter
), 0, 0, NULL
, fill_networkadapter
},
4336 { L
"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig
), 0, 0, NULL
, fill_networkadapterconfig
},
4337 { L
"Win32_OperatingSystem", C(col_operatingsystem
), 0, 0, NULL
, fill_operatingsystem
},
4338 { L
"Win32_PageFileUsage", C(col_pagefileusage
), D(data_pagefileusage
) },
4339 { L
"Win32_PhysicalMedia", C(col_physicalmedia
), D(data_physicalmedia
) },
4340 { L
"Win32_PhysicalMemory", C(col_physicalmemory
), 0, 0, NULL
, fill_physicalmemory
},
4341 { L
"Win32_PnPEntity", C(col_pnpentity
), 0, 0, NULL
, fill_pnpentity
},
4342 { L
"Win32_Printer", C(col_printer
), 0, 0, NULL
, fill_printer
},
4343 { L
"Win32_Process", C(col_process
), 0, 0, NULL
, fill_process
},
4344 { L
"Win32_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4345 { L
"Win32_QuickFixEngineering", C(col_quickfixengineering
), D(data_quickfixengineering
) },
4346 { L
"Win32_SID", C(col_sid
), 0, 0, NULL
, fill_sid
},
4347 { L
"Win32_Service", C(col_service
), 0, 0, NULL
, fill_service
},
4348 { L
"Win32_SoundDevice", C(col_sounddevice
), 0, 0, NULL
, fill_sounddevice
},
4349 { L
"Win32_SystemEnclosure", C(col_systemenclosure
), 0, 0, NULL
, fill_systemenclosure
},
4350 { L
"Win32_VideoController", C(col_videocontroller
), 0, 0, NULL
, fill_videocontroller
},
4351 { L
"Win32_Volume", C(col_volume
), 0, 0, NULL
, fill_volume
},
4352 { L
"Win32_WinSAT", C(col_winsat
), D(data_winsat
) },
4355 static struct table wmi_builtin_classes
[] =
4357 { L
"MSSMBios_RawSMBiosTables", C(col_rawsmbiostables
), D(data_rawsmbiostables
) },
4365 struct table
*classes
;
4366 unsigned int table_count
;
4368 builtin_namespaces
[WBEMPROX_NAMESPACE_LAST
] =
4370 {L
"cimv2", cimv2_builtin_classes
, ARRAY_SIZE(cimv2_builtin_classes
)},
4371 {L
"Microsoft\\Windows\\Storage", NULL
, 0},
4372 {L
"StandardCimv2", NULL
, 0},
4373 {L
"wmi", wmi_builtin_classes
, ARRAY_SIZE(wmi_builtin_classes
)},
4376 void init_table_list( void )
4378 static struct list tables
[WBEMPROX_NAMESPACE_LAST
];
4381 for (ns
= 0; ns
< ARRAY_SIZE(builtin_namespaces
); ns
++)
4383 list_init( &tables
[ns
] );
4384 for (i
= 0; i
< builtin_namespaces
[ns
].table_count
; i
++)
4385 list_add_tail( &tables
[ns
], &builtin_namespaces
[ns
].classes
[i
].entry
);
4386 table_list
[ns
] = &tables
[ns
];
4390 enum wbm_namespace
get_namespace_from_string( const WCHAR
*namespace )
4394 if (!wcsicmp( namespace, L
"default" )) return WBEMPROX_NAMESPACE_CIMV2
;
4396 for (i
= 0; i
< WBEMPROX_NAMESPACE_LAST
; ++i
)
4397 if (!wcsicmp( namespace, builtin_namespaces
[i
].name
)) return i
;
4399 return WBEMPROX_NAMESPACE_LAST
;