2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
27 #define WIN32_NO_STATUS
50 #include "wine/debug.h"
51 #include "wbemprox_private.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox
);
55 /* column definitions must be kept in sync with record structures below */
56 static const struct column col_associator
[] =
58 { L
"AssocClass", CIM_STRING
},
59 { L
"Class", CIM_STRING
},
60 { L
"Associator", CIM_STRING
}
62 static const struct column col_baseboard
[] =
64 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
65 { L
"Model", CIM_STRING
},
66 { L
"Name", CIM_STRING
},
67 { L
"Product", CIM_STRING
|COL_FLAG_DYNAMIC
},
68 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
69 { L
"Tag", CIM_STRING
|COL_FLAG_KEY
},
70 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
72 static const struct column col_bios
[] =
74 { L
"CurrentLanguage", CIM_STRING
},
75 { L
"Description", CIM_STRING
},
76 { L
"EmbeddedControllerMajorVersion", CIM_UINT8
},
77 { L
"EmbeddedControllerMinorVersion", CIM_UINT8
},
78 { L
"IdentificationCode", CIM_STRING
},
79 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
80 { L
"Name", CIM_STRING
},
81 { L
"ReleaseDate", CIM_DATETIME
|COL_FLAG_DYNAMIC
},
82 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
83 { L
"SMBIOSBIOSVersion", CIM_STRING
|COL_FLAG_DYNAMIC
},
84 { L
"SMBIOSMajorVersion", CIM_UINT16
},
85 { L
"SMBIOSMinorVersion", CIM_UINT16
},
86 { L
"SystemBiosMajorVersion", CIM_UINT8
},
87 { L
"SystemBiosMinorVersion", CIM_UINT8
},
88 { L
"Version", CIM_STRING
|COL_FLAG_KEY
},
90 static const struct column col_cdromdrive
[] =
92 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
93 { L
"Drive", CIM_STRING
|COL_FLAG_DYNAMIC
},
94 { L
"MediaType", CIM_STRING
},
95 { L
"Name", CIM_STRING
},
96 { L
"PNPDeviceID", CIM_STRING
},
98 static const struct column col_compsys
[] =
100 { L
"Description", CIM_STRING
},
101 { L
"Domain", CIM_STRING
},
102 { L
"DomainRole", CIM_UINT16
},
103 { L
"HypervisorPresent", CIM_BOOLEAN
},
104 { L
"Manufacturer", CIM_STRING
},
105 { L
"Model", CIM_STRING
},
106 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
107 { L
"NumberOfLogicalProcessors", CIM_UINT32
},
108 { L
"NumberOfProcessors", CIM_UINT32
},
109 { L
"SystemType", CIM_STRING
},
110 { L
"TotalPhysicalMemory", CIM_UINT64
},
111 { L
"UserName", CIM_STRING
|COL_FLAG_DYNAMIC
},
113 static const struct column col_compsysproduct
[] =
115 { L
"IdentifyingNumber", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
116 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
117 { L
"SKUNumber", CIM_STRING
},
118 { L
"UUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
119 { L
"Vendor", CIM_STRING
|COL_FLAG_DYNAMIC
},
120 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
122 static const struct column col_datafile
[] =
124 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
125 { L
"Version", CIM_STRING
|COL_FLAG_DYNAMIC
},
127 static const struct column col_desktopmonitor
[] =
129 { L
"Name", CIM_STRING
},
130 { L
"PixelsPerXLogicalInch", CIM_UINT32
},
132 static const struct column col_directory
[] =
134 { L
"AccessMask", CIM_UINT32
},
135 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
137 static const struct column col_diskdrive
[] =
139 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
140 { L
"Index", CIM_UINT32
},
141 { L
"InterfaceType", CIM_STRING
},
142 { L
"Manufacturer", CIM_STRING
},
143 { L
"MediaType", CIM_STRING
},
144 { L
"Model", CIM_STRING
},
145 { L
"PNPDeviceID", CIM_STRING
},
146 { L
"SerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
147 { L
"Size", CIM_UINT64
},
149 static const struct column col_diskdrivetodiskpartition
[] =
151 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
152 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
154 static const struct column col_diskpartition
[] =
156 { L
"Bootable", CIM_BOOLEAN
},
157 { L
"BootPartition", CIM_BOOLEAN
},
158 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
159 { L
"DiskIndex", CIM_UINT32
},
160 { L
"Index", CIM_UINT32
},
161 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
162 { L
"Size", CIM_UINT64
},
163 { L
"StartingOffset", CIM_UINT64
},
164 { L
"Type", CIM_STRING
|COL_FLAG_DYNAMIC
},
166 static const struct column col_displaycontrollerconfig
[] =
168 { L
"BitsPerPixel", CIM_UINT32
},
169 { L
"Caption", CIM_STRING
},
170 { L
"HorizontalResolution", CIM_UINT32
},
171 { L
"Name", CIM_STRING
|COL_FLAG_KEY
},
172 { L
"VerticalResolution", CIM_UINT32
},
174 static const struct column col_ip4routetable
[] =
176 { L
"Destination", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
177 { L
"InterfaceIndex", CIM_SINT32
|COL_FLAG_KEY
},
178 { L
"NextHop", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
180 static const struct column col_logicaldisk
[] =
182 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
183 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
184 { L
"DriveType", CIM_UINT32
},
185 { L
"FileSystem", CIM_STRING
|COL_FLAG_DYNAMIC
},
186 { L
"FreeSpace", CIM_UINT64
},
187 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
188 { L
"Size", CIM_UINT64
},
189 { L
"VolumeName", CIM_STRING
|COL_FLAG_DYNAMIC
},
190 { L
"VolumeSerialNumber", CIM_STRING
|COL_FLAG_DYNAMIC
},
192 static const struct column col_logicaldisktopartition
[] =
194 { L
"Antecedent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
195 { L
"Dependent", CIM_REFERENCE
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
197 static const struct column col_networkadapter
[] =
199 { L
"AdapterType", CIM_STRING
},
200 { L
"AdapterTypeID", CIM_UINT16
},
201 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
202 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
203 { L
"GUID", CIM_STRING
|COL_FLAG_DYNAMIC
},
204 { L
"Index", CIM_UINT32
},
205 { L
"InterfaceIndex", CIM_UINT32
},
206 { L
"MACAddress", CIM_STRING
|COL_FLAG_DYNAMIC
},
207 { L
"Manufacturer", CIM_STRING
},
208 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
209 { L
"NetConnectionStatus", CIM_UINT16
},
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
},
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
},
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
"DeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
413 { L
"Manufacturer", CIM_STRING
},
414 { L
"Name", CIM_STRING
},
415 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
416 { L
"ProductName", CIM_STRING
},
417 { L
"Status", CIM_STRING
},
418 { L
"StatusInfo", CIM_UINT16
},
420 static const struct column col_stdregprov
[] =
422 { L
"CreateKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
423 { L
"EnumKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
424 { L
"EnumValues", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
425 { L
"GetBinaryValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
426 { L
"GetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
427 { L
"SetStringValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
428 { L
"SetDWORDValue", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
429 { L
"DeleteKey", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
431 static const struct column col_systemenclosure
[] =
433 { L
"Caption", CIM_STRING
},
434 { L
"ChassisTypes", CIM_UINT16
|CIM_FLAG_ARRAY
|COL_FLAG_DYNAMIC
},
435 { L
"Description", CIM_STRING
},
436 { L
"LockPresent", CIM_BOOLEAN
},
437 { L
"Manufacturer", CIM_STRING
|COL_FLAG_DYNAMIC
},
438 { L
"Name", CIM_STRING
},
439 { L
"Tag", CIM_STRING
},
441 static const struct column col_systemsecurity
[] =
443 { L
"GetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
444 { L
"SetSD", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
446 static const struct column col_sysrestore
[] =
448 { L
"CreationTime", CIM_STRING
},
449 { L
"Description", CIM_STRING
},
450 { L
"EventType", CIM_UINT32
},
451 { L
"RestorePointType", CIM_UINT32
},
452 { L
"SequenceNumber", CIM_UINT32
},
454 { L
"CreateRestorePoint", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
455 { L
"Disable", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
456 { L
"Enable", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
457 { L
"GetLastRestoreStatus", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
458 { L
"Restore", CIM_FLAG_ARRAY
|COL_FLAG_METHOD
},
460 static const struct column col_videocontroller
[] =
462 { L
"AdapterCompatibility", CIM_STRING
},
463 { L
"AdapterDACType", CIM_STRING
},
464 { L
"AdapterRAM", CIM_UINT32
},
465 { L
"Availability", CIM_UINT16
},
466 { L
"Caption", CIM_STRING
|COL_FLAG_DYNAMIC
},
467 { L
"ConfigManagerErrorCode", CIM_UINT32
},
468 { L
"CurrentBitsPerPixel", CIM_UINT32
},
469 { L
"CurrentHorizontalResolution", CIM_UINT32
},
470 { L
"CurrentRefreshRate", CIM_UINT32
},
471 { L
"CurrentScanMode", CIM_UINT16
},
472 { L
"CurrentVerticalResolution", CIM_UINT32
},
473 { L
"Description", CIM_STRING
|COL_FLAG_DYNAMIC
},
474 { L
"DeviceId", CIM_STRING
|COL_FLAG_KEY
},
475 { L
"DriverDate", CIM_DATETIME
},
476 { L
"DriverVersion", CIM_STRING
},
477 { L
"InstalledDisplayDrivers", CIM_STRING
},
478 { L
"Name", CIM_STRING
|COL_FLAG_DYNAMIC
},
479 { L
"PNPDeviceID", CIM_STRING
|COL_FLAG_DYNAMIC
},
480 { L
"Status", CIM_STRING
},
481 { L
"VideoArchitecture", CIM_UINT16
},
482 { L
"VideoMemoryType", CIM_UINT16
},
483 { L
"VideoModeDescription", CIM_STRING
|COL_FLAG_DYNAMIC
},
484 { L
"VideoProcessor", CIM_STRING
|COL_FLAG_DYNAMIC
},
487 static const struct column col_volume
[] =
489 { L
"DeviceId", CIM_STRING
|COL_FLAG_DYNAMIC
|COL_FLAG_KEY
},
490 { L
"DriveLetter", CIM_STRING
|COL_FLAG_DYNAMIC
},
493 static const struct column col_winsat
[] =
495 { L
"CPUScore", CIM_REAL32
},
496 { L
"D3DScore", CIM_REAL32
},
497 { L
"DiskScore", CIM_REAL32
},
498 { L
"GraphicsScore", CIM_REAL32
},
499 { L
"MemoryScore", CIM_REAL32
},
500 { L
"TimeTaken", CIM_STRING
|COL_FLAG_KEY
},
501 { L
"WinSATAssessmentState", CIM_UINT32
},
502 { L
"WinSPRLevel", CIM_REAL32
},
505 #include "pshpack1.h"
506 struct record_associator
508 const WCHAR
*assocclass
;
510 const WCHAR
*associator
;
512 struct record_baseboard
514 const WCHAR
*manufacturer
;
517 const WCHAR
*product
;
518 const WCHAR
*serialnumber
;
520 const WCHAR
*version
;
524 const WCHAR
*currentlanguage
;
525 const WCHAR
*description
;
526 UINT8 ecmajorversion
;
527 UINT8 ecminorversion
;
528 const WCHAR
*identificationcode
;
529 const WCHAR
*manufacturer
;
531 const WCHAR
*releasedate
;
532 const WCHAR
*serialnumber
;
533 const WCHAR
*smbiosbiosversion
;
534 UINT16 smbiosmajorversion
;
535 UINT16 smbiosminorversion
;
536 UINT8 systembiosmajorversion
;
537 UINT8 systembiosminorversion
;
538 const WCHAR
*version
;
540 struct record_cdromdrive
542 const WCHAR
*device_id
;
544 const WCHAR
*mediatype
;
546 const WCHAR
*pnpdevice_id
;
548 struct record_computersystem
550 const WCHAR
*description
;
553 int hypervisorpresent
;
554 const WCHAR
*manufacturer
;
557 UINT32 num_logical_processors
;
558 UINT32 num_processors
;
559 const WCHAR
*systemtype
;
560 UINT64 total_physical_memory
;
561 const WCHAR
*username
;
563 struct record_computersystemproduct
565 const WCHAR
*identifyingnumber
;
567 const WCHAR
*skunumber
;
570 const WCHAR
*version
;
572 struct record_datafile
575 const WCHAR
*version
;
577 struct record_desktopmonitor
580 UINT32 pixelsperxlogicalinch
;
582 struct record_directory
587 struct record_diskdrive
589 const WCHAR
*device_id
;
591 const WCHAR
*interfacetype
;
592 const WCHAR
*manufacturer
;
593 const WCHAR
*mediatype
;
595 const WCHAR
*pnpdevice_id
;
596 const WCHAR
*serialnumber
;
599 struct record_diskdrivetodiskpartition
601 const WCHAR
*antecedent
;
602 const WCHAR
*dependent
;
604 struct record_diskpartition
608 const WCHAR
*device_id
;
611 const WCHAR
*pnpdevice_id
;
613 UINT64 startingoffset
;
616 struct record_displaycontrollerconfig
619 const WCHAR
*caption
;
620 UINT32 horizontalresolution
;
622 UINT32 verticalresolution
;
624 struct record_ip4routetable
626 const WCHAR
*destination
;
627 INT32 interfaceindex
;
628 const WCHAR
*nexthop
;
630 struct record_logicaldisk
632 const WCHAR
*caption
;
633 const WCHAR
*device_id
;
635 const WCHAR
*filesystem
;
639 const WCHAR
*volumename
;
640 const WCHAR
*volumeserialnumber
;
642 struct record_logicaldisktopartition
644 const WCHAR
*antecedent
;
645 const WCHAR
*dependent
;
647 struct record_networkadapter
649 const WCHAR
*adaptertype
;
650 UINT16 adaptertypeid
;
651 const WCHAR
*description
;
652 const WCHAR
*device_id
;
655 UINT32 interface_index
;
656 const WCHAR
*mac_address
;
657 const WCHAR
*manufacturer
;
659 UINT16 netconnection_status
;
661 const WCHAR
*pnpdevice_id
;
662 const WCHAR
*servicename
;
665 struct record_networkadapterconfig
667 const struct array
*defaultipgateway
;
668 const WCHAR
*description
;
670 const WCHAR
*dnsdomain
;
671 const WCHAR
*dnshostname
;
672 const struct array
*dnsserversearchorder
;
674 const struct array
*ipaddress
;
675 UINT32 ipconnectionmetric
;
677 const struct array
*ipsubnet
;
678 const WCHAR
*mac_address
;
679 const WCHAR
*settingid
;
681 struct record_operatingsystem
683 const WCHAR
*bootdevice
;
684 const WCHAR
*buildnumber
;
685 const WCHAR
*buildtype
;
686 const WCHAR
*caption
;
687 const WCHAR
*codeset
;
688 const WCHAR
*countrycode
;
689 const WCHAR
*csdversion
;
691 INT16 currenttimezone
;
692 UINT64 freephysicalmemory
;
693 UINT64 freevirtualmemory
;
694 const WCHAR
*installdate
;
695 const WCHAR
*lastbootuptime
;
696 const WCHAR
*localdatetime
;
698 const WCHAR
*manufacturer
;
700 UINT32 operatingsystemsku
;
701 const WCHAR
*organization
;
702 const WCHAR
*osarchitecture
;
704 UINT32 osproductsuite
;
708 const WCHAR
*registereduser
;
709 const WCHAR
*serialnumber
;
710 UINT16 servicepackmajor
;
711 UINT16 servicepackminor
;
714 const WCHAR
*systemdirectory
;
715 const WCHAR
*systemdrive
;
716 UINT64 totalvirtualmemorysize
;
717 UINT64 totalvisiblememorysize
;
718 const WCHAR
*version
;
719 const WCHAR
*windowsdirectory
;
721 struct record_pagefileusage
730 const WCHAR
*parameter
;
734 struct record_physicalmedia
736 const WCHAR
*serialnumber
;
739 struct record_physicalmemory
741 const WCHAR
*banklabel
;
743 const WCHAR
*caption
;
744 UINT32 configuredclockspeed
;
745 const WCHAR
*devicelocator
;
748 const WCHAR
*partnumber
;
751 struct record_pnpentity
753 const WCHAR
*device_id
;
754 const WCHAR
*manufacturer
;
757 struct record_printer
760 const WCHAR
*device_id
;
761 const WCHAR
*drivername
;
762 UINT32 horizontalresolution
;
764 const WCHAR
*location
;
767 const WCHAR
*portname
;
769 struct record_process
771 const WCHAR
*caption
;
772 const WCHAR
*commandline
;
773 const WCHAR
*description
;
779 UINT64 workingsetsize
;
781 class_method
*create
;
782 class_method
*get_owner
;
784 struct record_processor
788 const WCHAR
*caption
;
790 UINT32 currentclockspeed
;
792 const WCHAR
*description
;
793 const WCHAR
*device_id
;
796 const WCHAR
*manufacturer
;
797 UINT32 maxclockspeed
;
800 UINT32 num_logical_processors
;
801 const WCHAR
*processor_id
;
802 UINT16 processortype
;
804 const WCHAR
*unique_id
;
805 const WCHAR
*version
;
807 struct record_qualifier
815 const WCHAR
*strvalue
;
818 struct record_quickfixengineering
820 const WCHAR
*caption
;
821 const WCHAR
*description
;
822 const WCHAR
*hotfixid
;
823 const WCHAR
*installedby
;
824 const WCHAR
*installedon
;
826 struct record_rawsmbiostables
828 const struct array
*smbiosdata
;
830 struct record_service
834 const WCHAR
*displayname
;
837 const WCHAR
*servicetype
;
838 const WCHAR
*startmode
;
840 const WCHAR
*systemname
;
842 class_method
*pause_service
;
843 class_method
*resume_service
;
844 class_method
*start_service
;
845 class_method
*stop_service
;
849 const WCHAR
*accountname
;
850 const struct array
*binaryrepresentation
;
851 const WCHAR
*referenceddomainname
;
855 struct record_softwarelicensingproduct
857 int license_is_addon
;
858 UINT32 license_status
;
860 struct record_sounddevice
862 const WCHAR
*deviceid
;
863 const WCHAR
*manufacturer
;
865 const WCHAR
*pnpdeviceid
;
866 const WCHAR
*productname
;
870 struct record_stdregprov
872 class_method
*createkey
;
873 class_method
*enumkey
;
874 class_method
*enumvalues
;
875 class_method
*getbinaryvalue
;
876 class_method
*getstringvalue
;
877 class_method
*setstringvalue
;
878 class_method
*setdwordvalue
;
879 class_method
*deletekey
;
881 struct record_sysrestore
883 const WCHAR
*creation_time
;
884 const WCHAR
*description
;
886 UINT32 restore_point_type
;
887 UINT32 sequence_number
;
888 class_method
*create_restore_point
;
889 class_method
*disable_restore
;
890 class_method
*enable_restore
;
891 class_method
*get_last_restore_status
;
892 class_method
*restore
;
894 struct record_systemsecurity
899 struct record_systemenclosure
901 const WCHAR
*caption
;
902 const struct array
*chassistypes
;
903 const WCHAR
*description
;
905 const WCHAR
*manufacturer
;
909 struct record_videocontroller
911 const WCHAR
*adapter_compatibility
;
912 const WCHAR
*adapter_dactype
;
915 const WCHAR
*caption
;
916 UINT32 config_errorcode
;
917 UINT32 current_bitsperpixel
;
918 UINT32 current_horizontalres
;
919 UINT32 current_refreshrate
;
920 UINT16 current_scanmode
;
921 UINT32 current_verticalres
;
922 const WCHAR
*description
;
923 const WCHAR
*device_id
;
924 const WCHAR
*driverdate
;
925 const WCHAR
*driverversion
;
926 const WCHAR
*installeddriver
;
928 const WCHAR
*pnpdevice_id
;
930 UINT16 videoarchitecture
;
931 UINT16 videomemorytype
;
932 const WCHAR
*videomodedescription
;
933 const WCHAR
*videoprocessor
;
938 const WCHAR
*deviceid
;
939 const WCHAR
*driveletter
;
949 const WCHAR
*timetaken
;
950 UINT32 winsatassessmentstate
;
955 static const struct record_associator data_associator
[] =
957 { L
"Win32_DiskDriveToDiskPartition", L
"Win32_DiskPartition", L
"Win32_DiskDrive" },
958 { L
"Win32_LogicalDiskToPartition", L
"Win32_LogicalDisk", L
"Win32_DiskPartition" },
960 static const struct record_pagefileusage data_pagefileusage
[] =
962 { L
"c:\\pagefile.sys", },
964 static const struct record_param data_param
[] =
966 { L
"__SystemSecurity", L
"GetSD", -1, L
"ReturnValue", CIM_UINT32
},
967 { L
"__SystemSecurity", L
"GetSD", -1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
968 { L
"__SystemSecurity", L
"SetSD", 1, L
"SD", CIM_UINT8
|CIM_FLAG_ARRAY
},
969 { L
"__SystemSecurity", L
"SetSD", -1, L
"ReturnValue", CIM_UINT32
},
970 { L
"StdRegProv", L
"CreateKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
971 { L
"StdRegProv", L
"CreateKey", 1, L
"sSubKeyName", CIM_STRING
},
972 { L
"StdRegProv", L
"CreateKey", -1, L
"ReturnValue", CIM_UINT32
},
973 { L
"StdRegProv", L
"DeleteKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
974 { L
"StdRegProv", L
"DeleteKey", 1, L
"sSubKeyName", CIM_STRING
},
975 { L
"StdRegProv", L
"DeleteKey", -1, L
"ReturnValue", CIM_UINT32
},
976 { L
"StdRegProv", L
"EnumKey", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
977 { L
"StdRegProv", L
"EnumKey", 1, L
"sSubKeyName", CIM_STRING
},
978 { L
"StdRegProv", L
"EnumKey", -1, L
"ReturnValue", CIM_UINT32
},
979 { L
"StdRegProv", L
"EnumKey", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
980 { L
"StdRegProv", L
"EnumValues", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
981 { L
"StdRegProv", L
"EnumValues", 1, L
"sSubKeyName", CIM_STRING
},
982 { L
"StdRegProv", L
"EnumValues", -1, L
"ReturnValue", CIM_UINT32
},
983 { L
"StdRegProv", L
"EnumValues", -1, L
"sNames", CIM_STRING
|CIM_FLAG_ARRAY
},
984 { L
"StdRegProv", L
"EnumValues", -1, L
"Types", CIM_SINT32
|CIM_FLAG_ARRAY
},
985 { L
"StdRegProv", L
"GetBinaryValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
986 { L
"StdRegProv", L
"GetBinaryValue", 1, L
"sSubKeyName", CIM_STRING
},
987 { L
"StdRegProv", L
"GetBinaryValue", 1, L
"sValueName", CIM_STRING
},
988 { L
"StdRegProv", L
"GetBinaryValue", -1, L
"ReturnValue", CIM_UINT32
},
989 { L
"StdRegProv", L
"GetBinaryValue", -1, L
"uValue", CIM_UINT8
|CIM_FLAG_ARRAY
},
990 { L
"StdRegProv", L
"GetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
991 { L
"StdRegProv", L
"GetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
992 { L
"StdRegProv", L
"GetStringValue", 1, L
"sValueName", CIM_STRING
},
993 { L
"StdRegProv", L
"GetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
994 { L
"StdRegProv", L
"GetStringValue", -1, L
"sValue", CIM_STRING
},
995 { L
"StdRegProv", L
"SetStringValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
996 { L
"StdRegProv", L
"SetStringValue", 1, L
"sSubKeyName", CIM_STRING
},
997 { L
"StdRegProv", L
"SetStringValue", 1, L
"sValueName", CIM_STRING
},
998 { L
"StdRegProv", L
"SetStringValue", 1, L
"sValue", CIM_STRING
},
999 { L
"StdRegProv", L
"SetStringValue", -1, L
"ReturnValue", CIM_UINT32
},
1000 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"hDefKey", CIM_SINT32
, 0x80000002 },
1001 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"sSubKeyName", CIM_STRING
},
1002 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"sValueName", CIM_STRING
},
1003 { L
"StdRegProv", L
"SetDWORDValue", 1, L
"uValue", CIM_UINT32
},
1004 { L
"StdRegProv", L
"SetDWORDValue", -1, L
"ReturnValue", CIM_UINT32
},
1005 { L
"SystemRestore", L
"Disable", 1, L
"Drive", CIM_STRING
},
1006 { L
"SystemRestore", L
"Disable", -1, L
"ReturnValue", CIM_UINT32
},
1007 { L
"SystemRestore", L
"Enable", 1, L
"Drive", CIM_STRING
},
1008 { L
"SystemRestore", L
"Enable", -1, L
"ReturnValue", CIM_UINT32
},
1009 { L
"Win32_Process", L
"Create", 1, L
"CommandLine", CIM_STRING
},
1010 { L
"Win32_Process", L
"Create", 1, L
"CurrentDirectory", CIM_STRING
},
1011 { L
"Win32_Process", L
"Create", -1, L
"ProcessId", CIM_UINT32
},
1012 { L
"Win32_Process", L
"Create", -1, L
"ReturnValue", CIM_UINT32
},
1013 { L
"Win32_Process", L
"GetOwner", -1, L
"ReturnValue", CIM_UINT32
},
1014 { L
"Win32_Process", L
"GetOwner", -1, L
"User", CIM_STRING
},
1015 { L
"Win32_Process", L
"GetOwner", -1, L
"Domain", CIM_STRING
},
1016 { L
"Win32_Service", L
"PauseService", -1, L
"ReturnValue", CIM_UINT32
},
1017 { L
"Win32_Service", L
"ResumeService", -1, L
"ReturnValue", CIM_UINT32
},
1018 { L
"Win32_Service", L
"StartService", -1, L
"ReturnValue", CIM_UINT32
},
1019 { L
"Win32_Service", L
"StopService", -1, L
"ReturnValue", CIM_UINT32
},
1022 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\
1023 WBEM_FLAVOR_ORIGIN_PROPAGATED)
1025 static const struct record_physicalmedia data_physicalmedia
[] =
1027 { L
"WINEHDISK", L
"\\\\.\\PHYSICALDRIVE0" }
1030 static const struct record_rawsmbiostables data_rawsmbiostables
[] =
1035 static const struct record_qualifier data_qualifier
[] =
1037 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"User", CIM_SINT32
, FLAVOR_ID
, L
"ID", 0 },
1038 { L
"__WIN32_PROCESS_GETOWNER_OUT", L
"Domain", CIM_SINT32
, FLAVOR_ID
, L
"ID", 1 }
1041 static const struct record_quickfixengineering data_quickfixengineering
[] =
1043 { L
"http://winehq.org", L
"Update", L
"KB1234567", L
"", L
"22/2/2022" },
1046 static const struct record_softwarelicensingproduct data_softwarelicensingproduct
[] =
1051 static const struct record_stdregprov data_stdregprov
[] =
1057 reg_get_binaryvalue
,
1058 reg_get_stringvalue
,
1059 reg_set_stringvalue
,
1065 static const struct record_sysrestore data_sysrestore
[] =
1067 { NULL
, NULL
, 0, 0, 0, sysrestore_create
, sysrestore_disable
, sysrestore_enable
, sysrestore_get_last_status
,
1068 sysrestore_restore
}
1071 static UINT16 systemenclosure_chassistypes
[] =
1075 static const struct array systemenclosure_chassistypes_array
=
1077 sizeof(*systemenclosure_chassistypes
),
1078 ARRAY_SIZE(systemenclosure_chassistypes
),
1079 &systemenclosure_chassistypes
1081 static const struct record_systemsecurity data_systemsecurity
[] =
1083 { security_get_sd
, security_set_sd
}
1085 static const struct record_winsat data_winsat
[] =
1087 { 8.0f
, 8.0f
, 8.0f
, 8.0f
, 8.0f
, L
"MostRecentAssessment", 1 /* Valid */, 8.0f
},
1090 /* check if row matches condition and update status */
1091 static BOOL
match_row( const struct table
*table
, UINT row
, const struct expr
*cond
, enum fill_status
*status
)
1098 *status
= FILL_STATUS_UNFILTERED
;
1101 if (eval_cond( table
, row
, cond
, &val
, &type
) != S_OK
)
1103 *status
= FILL_STATUS_FAILED
;
1106 *status
= FILL_STATUS_FILTERED
;
1110 static BOOL
resize_table( struct table
*table
, UINT row_count
, UINT row_size
)
1112 if (!table
->num_rows_allocated
)
1114 if (!(table
->data
= malloc( row_count
* row_size
))) return FALSE
;
1115 table
->num_rows_allocated
= row_count
;
1118 if (row_count
> table
->num_rows_allocated
)
1121 UINT count
= max( row_count
, table
->num_rows_allocated
* 2 );
1122 if (!(data
= realloc( table
->data
, count
* row_size
))) return FALSE
;
1124 table
->num_rows_allocated
= count
;
1129 #include "pshpack1.h"
1130 struct smbios_prologue
1132 BYTE calling_method
;
1143 SMBIOS_TYPE_BASEBOARD
,
1144 SMBIOS_TYPE_CHASSIS
,
1147 struct smbios_header
1154 struct smbios_baseboard
1156 struct smbios_header hdr
;
1165 struct smbios_header hdr
;
1171 UINT64 characteristics
;
1172 BYTE characteristics_ext
[2];
1173 BYTE system_bios_major_release
;
1174 BYTE system_bios_minor_release
;
1175 BYTE ec_firmware_major_release
;
1176 BYTE ec_firmware_minor_release
;
1179 struct smbios_chassis
1181 struct smbios_header hdr
;
1189 struct smbios_system
1191 struct smbios_header hdr
;
1198 #include "poppack.h"
1200 #define RSMB (('R' << 24) | ('S' << 16) | ('M' << 8) | 'B')
1202 static const struct smbios_header
*find_smbios_entry( enum smbios_type type
, const char *buf
, UINT len
)
1204 const char *ptr
, *start
;
1205 const struct smbios_prologue
*prologue
;
1206 const struct smbios_header
*hdr
;
1208 if (len
< sizeof(struct smbios_prologue
)) return NULL
;
1209 prologue
= (const struct smbios_prologue
*)buf
;
1210 if (prologue
->length
> len
- sizeof(*prologue
) || prologue
->length
< sizeof(*hdr
)) return NULL
;
1212 start
= (const char *)(prologue
+ 1);
1213 hdr
= (const struct smbios_header
*)start
;
1217 if ((const char *)hdr
- start
>= prologue
->length
- sizeof(*hdr
)) return NULL
;
1221 WARN( "invalid entry\n" );
1225 if (hdr
->type
== type
)
1227 if ((const char *)hdr
- start
+ hdr
->length
> prologue
->length
) return NULL
;
1230 else /* skip other entries and their strings */
1232 for (ptr
= (const char *)hdr
+ hdr
->length
; ptr
- buf
< len
&& *ptr
; ptr
++)
1234 for (; ptr
- buf
< len
; ptr
++) if (!*ptr
) break;
1236 if (ptr
== (const char *)hdr
+ hdr
->length
) ptr
++;
1237 hdr
= (const struct smbios_header
*)(ptr
+ 1);
1244 static WCHAR
*get_smbios_string( BYTE id
, const char *buf
, UINT offset
, UINT buflen
)
1246 const char *ptr
= buf
+ offset
;
1249 if (!id
|| offset
>= buflen
) return NULL
;
1250 for (ptr
= buf
+ offset
; ptr
- buf
< buflen
&& *ptr
; ptr
++)
1252 if (++i
== id
) return heap_strdupAW( ptr
);
1253 for (; ptr
- buf
< buflen
; ptr
++) if (!*ptr
) break;
1258 static WCHAR
*get_baseboard_string( BYTE id
, const char *buf
, UINT len
)
1260 const struct smbios_header
*hdr
;
1261 const struct smbios_baseboard
*baseboard
;
1264 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BASEBOARD
, buf
, len
))) return NULL
;
1266 baseboard
= (const struct smbios_baseboard
*)hdr
;
1267 offset
= (const char *)baseboard
- buf
+ baseboard
->hdr
.length
;
1268 return get_smbios_string( id
, buf
, offset
, len
);
1271 static WCHAR
*get_baseboard_manufacturer( const char *buf
, UINT len
)
1273 WCHAR
*ret
= get_baseboard_string( 1, buf
, len
);
1274 if (!ret
) return wcsdup( L
"Intel Corporation" );
1278 static WCHAR
*get_baseboard_product( const char *buf
, UINT len
)
1280 WCHAR
*ret
= get_baseboard_string( 2, buf
, len
);
1281 if (!ret
) return wcsdup( L
"Base Board" );
1285 static WCHAR
*get_baseboard_serialnumber( const char *buf
, UINT len
)
1287 WCHAR
*ret
= get_baseboard_string( 4, buf
, len
);
1288 if (!ret
) return wcsdup( L
"None" );
1292 static WCHAR
*get_baseboard_version( const char *buf
, UINT len
)
1294 WCHAR
*ret
= get_baseboard_string( 3, buf
, len
);
1295 if (!ret
) return wcsdup( L
"1.0" );
1299 static enum fill_status
fill_baseboard( struct table
*table
, const struct expr
*cond
)
1301 struct record_baseboard
*rec
;
1302 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1306 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1308 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1309 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1310 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1312 rec
= (struct record_baseboard
*)table
->data
;
1313 rec
->manufacturer
= get_baseboard_manufacturer( buf
, len
);
1314 rec
->model
= L
"Base Board";
1315 rec
->name
= L
"Base Board";
1316 rec
->product
= get_baseboard_product( buf
, len
);
1317 rec
->serialnumber
= get_baseboard_serialnumber( buf
, len
);
1318 rec
->tag
= L
"Base Board";
1319 rec
->version
= get_baseboard_version( buf
, len
);
1320 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1325 TRACE("created %u rows\n", row
);
1326 table
->num_rows
= row
;
1330 static UINT16
get_bios_smbiosmajorversion( const char *buf
, UINT len
)
1332 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1333 if (len
< sizeof(*prologue
)) return 2;
1334 return prologue
->major_version
;
1337 static UINT16
get_bios_smbiosminorversion( const char *buf
, UINT len
)
1339 const struct smbios_prologue
*prologue
= (const struct smbios_prologue
*)buf
;
1340 if (len
< sizeof(*prologue
)) return 0;
1341 return prologue
->minor_version
;
1344 static WCHAR
*get_bios_string( BYTE id
, const char *buf
, UINT len
)
1346 const struct smbios_header
*hdr
;
1347 const struct smbios_bios
*bios
;
1350 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return NULL
;
1352 bios
= (const struct smbios_bios
*)hdr
;
1353 offset
= (const char *)bios
- buf
+ bios
->hdr
.length
;
1354 return get_smbios_string( id
, buf
, offset
, len
);
1357 static WCHAR
*get_bios_manufacturer( const char *buf
, UINT len
)
1359 WCHAR
*ret
= get_bios_string( 1, buf
, len
);
1360 if (!ret
) return wcsdup( L
"The Wine Project" );
1364 static WCHAR
*convert_bios_date( const WCHAR
*str
)
1366 static const WCHAR fmtW
[] = L
"%04u%02u%02u000000.000000+000";
1367 UINT year
, month
, day
, len
= lstrlenW( str
);
1368 const WCHAR
*p
= str
, *q
;
1371 while (len
&& iswspace( *p
)) { p
++; len
--; }
1372 while (len
&& iswspace( p
[len
- 1] )) { len
--; }
1375 while (len
&& is_digit( *q
)) { q
++; len
--; };
1376 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1377 month
= (p
[0] - '0') * 10 + p
[1] - '0';
1380 while (len
&& is_digit( *q
)) { q
++; len
--; };
1381 if (q
- p
!= 2 || !len
|| *q
!= '/') return NULL
;
1382 day
= (p
[0] - '0') * 10 + p
[1] - '0';
1385 while (len
&& is_digit( *q
)) { q
++; len
--; };
1386 if (q
- p
== 4) year
= (p
[0] - '0') * 1000 + (p
[1] - '0') * 100 + (p
[2] - '0') * 10 + p
[3] - '0';
1387 else if (q
- p
== 2) year
= 1900 + (p
[0] - '0') * 10 + p
[1] - '0';
1390 if (!(ret
= malloc( sizeof(fmtW
) ))) return NULL
;
1391 swprintf( ret
, ARRAY_SIZE(fmtW
), fmtW
, year
, month
, day
);
1395 static WCHAR
*get_bios_releasedate( const char *buf
, UINT len
)
1397 WCHAR
*ret
, *date
= get_bios_string( 3, buf
, len
);
1398 if (!date
|| !(ret
= convert_bios_date( date
))) ret
= wcsdup( L
"20120608000000.000000+000" );
1403 static WCHAR
*get_bios_serialnumber( const char *buf
, UINT len
)
1405 WCHAR
*ret
= get_bios_string( 4, buf
, len
);
1406 if (!ret
) return wcsdup( L
"0" );
1410 static WCHAR
*get_bios_smbiosbiosversion( const char *buf
, UINT len
)
1412 WCHAR
*ret
= get_bios_string( 2, buf
, len
);
1413 if (!ret
) return wcsdup( L
"Wine" );
1417 static BYTE
get_bios_ec_firmware_major_release( const char *buf
, UINT len
)
1419 const struct smbios_header
*hdr
;
1420 const struct smbios_bios
*bios
;
1422 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1424 bios
= (const struct smbios_bios
*)hdr
;
1425 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_major_release
;
1429 static BYTE
get_bios_ec_firmware_minor_release( const char *buf
, UINT len
)
1431 const struct smbios_header
*hdr
;
1432 const struct smbios_bios
*bios
;
1434 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1436 bios
= (const struct smbios_bios
*)hdr
;
1437 if (bios
->hdr
.length
>= 0x18) return bios
->ec_firmware_minor_release
;
1441 static BYTE
get_bios_system_bios_major_release( const char *buf
, UINT len
)
1443 const struct smbios_header
*hdr
;
1444 const struct smbios_bios
*bios
;
1446 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1448 bios
= (const struct smbios_bios
*)hdr
;
1449 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_major_release
;
1453 static BYTE
get_bios_system_bios_minor_release( const char *buf
, UINT len
)
1455 const struct smbios_header
*hdr
;
1456 const struct smbios_bios
*bios
;
1458 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_BIOS
, buf
, len
))) return 0xFF;
1460 bios
= (const struct smbios_bios
*)hdr
;
1461 if (bios
->hdr
.length
>= 0x18) return bios
->system_bios_minor_release
;
1465 static enum fill_status
fill_bios( struct table
*table
, const struct expr
*cond
)
1467 struct record_bios
*rec
;
1468 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1472 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1474 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1475 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1476 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1478 rec
= (struct record_bios
*)table
->data
;
1479 rec
->currentlanguage
= NULL
;
1480 rec
->description
= L
"Default System BIOS";
1481 rec
->ecmajorversion
= get_bios_ec_firmware_major_release( buf
, len
);
1482 rec
->ecminorversion
= get_bios_ec_firmware_minor_release( buf
, len
);
1483 rec
->identificationcode
= NULL
;
1484 rec
->manufacturer
= get_bios_manufacturer( buf
, len
);
1485 rec
->name
= L
"Default System BIOS";
1486 rec
->releasedate
= get_bios_releasedate( buf
, len
);
1487 rec
->serialnumber
= get_bios_serialnumber( buf
, len
);
1488 rec
->smbiosbiosversion
= get_bios_smbiosbiosversion( buf
, len
);
1489 rec
->smbiosmajorversion
= get_bios_smbiosmajorversion( buf
, len
);
1490 rec
->smbiosminorversion
= get_bios_smbiosminorversion( buf
, len
);
1491 rec
->systembiosmajorversion
= get_bios_system_bios_major_release( buf
, len
);
1492 rec
->systembiosminorversion
= get_bios_system_bios_minor_release( buf
, len
);
1493 rec
->version
= L
"WINE - 1";
1494 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1499 TRACE("created %u rows\n", row
);
1500 table
->num_rows
= row
;
1504 static enum fill_status
fill_cdromdrive( struct table
*table
, const struct expr
*cond
)
1506 WCHAR drive
[3], root
[] = L
"A:\\";
1507 struct record_cdromdrive
*rec
;
1508 UINT i
, row
= 0, offset
= 0;
1509 DWORD drives
= GetLogicalDrives();
1510 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1512 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1514 for (i
= 0; i
< 26; i
++)
1516 if (drives
& (1 << i
))
1519 if (GetDriveTypeW( root
) != DRIVE_CDROM
)
1522 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1524 rec
= (struct record_cdromdrive
*)(table
->data
+ offset
);
1525 rec
->device_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1526 swprintf( drive
, ARRAY_SIZE( drive
), L
"%c:", 'A' + i
);
1527 rec
->drive
= wcsdup( drive
);
1528 rec
->mediatype
= L
"CR-ROM";
1529 rec
->name
= L
"Wine CD_ROM ATA Device";
1530 rec
->pnpdevice_id
= L
"IDE\\CDROMWINE_CD-ROM_____________________________1.0_____\\5&3A2A5854&0&1.0.0";
1531 if (!match_row( table
, row
, cond
, &status
))
1533 free_row_values( table
, row
);
1536 offset
+= sizeof(*rec
);
1540 TRACE("created %u rows\n", row
);
1541 table
->num_rows
= row
;
1545 static UINT
get_processor_count(void)
1547 SYSTEM_BASIC_INFORMATION info
;
1549 if (NtQuerySystemInformation( SystemBasicInformation
, &info
, sizeof(info
), NULL
)) return 1;
1550 return info
.NumberOfProcessors
;
1553 static UINT
get_logical_processor_count( UINT
*num_physical
, UINT
*num_packages
)
1555 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*buf
, *entry
;
1556 UINT core_relation_count
= 0, package_relation_count
= 0;
1558 ULONG len
, offset
= 0;
1559 BOOL smt_enabled
= FALSE
;
1560 DWORD all
= RelationAll
;
1562 if (num_packages
) *num_packages
= 1;
1563 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), NULL
, 0, &len
);
1564 if (status
!= STATUS_INFO_LENGTH_MISMATCH
) return get_processor_count();
1566 if (!(buf
= malloc( len
))) return get_processor_count();
1567 status
= NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx
, &all
, sizeof(all
), buf
, len
, &len
);
1568 if (status
!= STATUS_SUCCESS
)
1571 return get_processor_count();
1574 while (offset
< len
)
1576 entry
= (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*)((char *)buf
+ offset
);
1578 if (entry
->Relationship
== RelationProcessorCore
)
1580 core_relation_count
++;
1581 if (entry
->u
.Processor
.Flags
& LTP_PC_SMT
) smt_enabled
= TRUE
;
1583 else if (entry
->Relationship
== RelationProcessorPackage
)
1585 package_relation_count
++;
1587 offset
+= entry
->Size
;
1591 if (num_physical
) *num_physical
= core_relation_count
;
1592 if (num_packages
) *num_packages
= package_relation_count
;
1593 return smt_enabled
? core_relation_count
* 2 : core_relation_count
;
1596 static UINT64
get_total_physical_memory(void)
1598 MEMORYSTATUSEX status
;
1600 status
.dwLength
= sizeof(status
);
1601 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1602 return status
.ullTotalPhys
;
1605 static UINT64
get_available_physical_memory(void)
1607 MEMORYSTATUSEX status
;
1609 status
.dwLength
= sizeof(status
);
1610 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1611 return status
.ullAvailPhys
;
1614 static UINT64
get_available_virtual_memory(void)
1616 MEMORYSTATUSEX status
;
1618 status
.dwLength
= sizeof(status
);
1619 if (!GlobalMemoryStatusEx( &status
)) return 1024 * 1024 * 1024;
1620 return status
.ullAvailVirtual
;
1623 static WCHAR
*get_computername(void)
1626 DWORD size
= MAX_COMPUTERNAME_LENGTH
+ 1;
1628 if (!(ret
= malloc( size
* sizeof(WCHAR
) ))) return NULL
;
1629 GetComputerNameW( ret
, &size
);
1633 static const WCHAR
*get_systemtype(void)
1636 GetNativeSystemInfo( &info
);
1637 if (info
.u
.s
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"x64 based PC";
1638 return L
"x86 based PC";
1641 static WCHAR
*get_username(void)
1644 DWORD compsize
, usersize
;
1648 GetComputerNameW( NULL
, &compsize
);
1650 GetUserNameW( NULL
, &usersize
);
1651 size
= compsize
+ usersize
; /* two null terminators account for the \ */
1652 if (!(ret
= malloc( size
* sizeof(WCHAR
) ))) return NULL
;
1653 GetComputerNameW( ret
, &compsize
);
1654 ret
[compsize
] = '\\';
1655 GetUserNameW( ret
+ compsize
+ 1, &usersize
);
1659 static WCHAR
*get_compsysproduct_string( BYTE id
, const char *buf
, UINT len
)
1661 const struct smbios_header
*hdr
;
1662 const struct smbios_system
*system
;
1665 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
))) return NULL
;
1667 system
= (const struct smbios_system
*)hdr
;
1668 offset
= (const char *)system
- buf
+ system
->hdr
.length
;
1669 return get_smbios_string( id
, buf
, offset
, len
);
1672 static WCHAR
*get_compsysproduct_name( const char *buf
, UINT len
)
1674 WCHAR
*ret
= get_compsysproduct_string( 2, buf
, len
);
1675 if (!ret
) return wcsdup( L
"Wine" );
1679 static WCHAR
*get_compsysproduct_vendor( const char *buf
, UINT len
)
1681 WCHAR
*ret
= get_compsysproduct_string( 1, buf
, len
);
1682 if (!ret
) return wcsdup( L
"The Wine Project" );
1686 static enum fill_status
fill_compsys( struct table
*table
, const struct expr
*cond
)
1688 struct record_computersystem
*rec
;
1689 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1693 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1695 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1696 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1697 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1699 rec
= (struct record_computersystem
*)table
->data
;
1700 rec
->description
= L
"AT/AT COMPATIBLE";
1701 rec
->domain
= L
"WORKGROUP";
1702 rec
->domainrole
= 0; /* standalone workstation */
1703 rec
->hypervisorpresent
= 0;
1704 rec
->manufacturer
= get_compsysproduct_vendor( buf
, len
);
1705 rec
->model
= get_compsysproduct_name( buf
, len
);
1706 rec
->name
= get_computername();
1707 rec
->num_logical_processors
= get_logical_processor_count( NULL
, &rec
->num_processors
);
1708 rec
->systemtype
= get_systemtype();
1709 rec
->total_physical_memory
= get_total_physical_memory();
1710 rec
->username
= get_username();
1711 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1716 TRACE("created %u rows\n", row
);
1717 table
->num_rows
= row
;
1721 static WCHAR
*get_compsysproduct_identifyingnumber( const char *buf
, UINT len
)
1723 WCHAR
*ret
= get_compsysproduct_string( 4, buf
, len
);
1724 if (!ret
) return wcsdup( L
"0" );
1728 static WCHAR
*get_compsysproduct_uuid( const char *buf
, UINT len
)
1730 static const BYTE none
[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1731 const struct smbios_header
*hdr
;
1732 const struct smbios_system
*system
;
1736 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_SYSTEM
, buf
, len
)) || hdr
->length
< sizeof(*system
)) goto done
;
1737 system
= (const struct smbios_system
*)hdr
;
1738 if (!memcmp( system
->uuid
, none
, sizeof(none
) ) || !(ret
= malloc( 37 * sizeof(WCHAR
) ))) goto done
;
1741 swprintf( ret
, 37, L
"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ptr
[0], ptr
[1],
1742 ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7], ptr
[8], ptr
[9], ptr
[10], ptr
[11], ptr
[12], ptr
[13],
1745 if (!ret
) ret
= wcsdup( L
"deaddead-dead-dead-dead-deaddeaddead" );
1749 static WCHAR
*get_compsysproduct_version( const char *buf
, UINT len
)
1751 WCHAR
*ret
= get_compsysproduct_string( 3, buf
, len
);
1752 if (!ret
) return wcsdup( L
"1.0" );
1756 static enum fill_status
fill_compsysproduct( struct table
*table
, const struct expr
*cond
)
1758 struct record_computersystemproduct
*rec
;
1759 enum fill_status status
= FILL_STATUS_UNFILTERED
;
1763 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
1765 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
1766 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
1767 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
1769 rec
= (struct record_computersystemproduct
*)table
->data
;
1770 rec
->identifyingnumber
= get_compsysproduct_identifyingnumber( buf
, len
);
1771 rec
->name
= get_compsysproduct_name( buf
, len
);
1772 rec
->skunumber
= NULL
;
1773 rec
->uuid
= get_compsysproduct_uuid( buf
, len
);
1774 rec
->vendor
= get_compsysproduct_vendor( buf
, len
);
1775 rec
->version
= get_compsysproduct_version( buf
, len
);
1776 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
1781 TRACE("created %u rows\n", row
);
1782 table
->num_rows
= row
;
1794 static struct dirstack
*alloc_dirstack( UINT size
)
1796 struct dirstack
*dirstack
;
1798 if (!(dirstack
= malloc( sizeof(*dirstack
) ))) return NULL
;
1799 if (!(dirstack
->dirs
= malloc( sizeof(WCHAR
*) * size
)))
1804 if (!(dirstack
->len_dirs
= malloc( sizeof(UINT
) * size
)))
1806 free( dirstack
->dirs
);
1810 dirstack
->num_dirs
= 0;
1811 dirstack
->num_allocated
= size
;
1815 static void clear_dirstack( struct dirstack
*dirstack
)
1818 for (i
= 0; i
< dirstack
->num_dirs
; i
++) free( dirstack
->dirs
[i
] );
1819 dirstack
->num_dirs
= 0;
1822 static void free_dirstack( struct dirstack
*dirstack
)
1824 clear_dirstack( dirstack
);
1825 free( dirstack
->dirs
);
1826 free( dirstack
->len_dirs
);
1830 static BOOL
push_dir( struct dirstack
*dirstack
, WCHAR
*dir
, UINT len
)
1832 UINT size
, i
= dirstack
->num_dirs
;
1834 if (!dir
) return FALSE
;
1836 if (i
== dirstack
->num_allocated
)
1841 size
= dirstack
->num_allocated
* 2;
1842 if (!(tmp
= realloc( dirstack
->dirs
, size
* sizeof(WCHAR
*) ))) return FALSE
;
1843 dirstack
->dirs
= tmp
;
1844 if (!(len_tmp
= realloc( dirstack
->len_dirs
, size
* sizeof(UINT
) ))) return FALSE
;
1845 dirstack
->len_dirs
= len_tmp
;
1846 dirstack
->num_allocated
= size
;
1848 dirstack
->dirs
[i
] = dir
;
1849 dirstack
->len_dirs
[i
] = len
;
1850 dirstack
->num_dirs
++;
1854 static WCHAR
*pop_dir( struct dirstack
*dirstack
, UINT
*len
)
1856 if (!dirstack
->num_dirs
)
1861 dirstack
->num_dirs
--;
1862 *len
= dirstack
->len_dirs
[dirstack
->num_dirs
];
1863 return dirstack
->dirs
[dirstack
->num_dirs
];
1866 static const WCHAR
*peek_dir( struct dirstack
*dirstack
)
1868 if (!dirstack
->num_dirs
) return NULL
;
1869 return dirstack
->dirs
[dirstack
->num_dirs
- 1];
1872 static WCHAR
*build_glob( WCHAR drive
, const WCHAR
*path
, UINT len
)
1877 if (!(ret
= malloc( (len
+ 6) * sizeof(WCHAR
) ))) return NULL
;
1883 memcpy( ret
+ i
, path
, len
* sizeof(WCHAR
) );
1892 static WCHAR
*build_name( WCHAR drive
, const WCHAR
*path
)
1894 UINT i
= 0, len
= 0;
1898 for (p
= path
; *p
; p
++)
1900 if (*p
== '\\') len
+= 2;
1903 if (!(ret
= malloc( (len
+ 5) * sizeof(WCHAR
) ))) return NULL
;
1908 for (p
= path
; *p
; p
++)
1910 if (*p
!= '\\') ret
[i
++] = *p
;
1921 static WCHAR
*build_dirname( const WCHAR
*path
, UINT
*ret_len
)
1923 const WCHAR
*p
= path
, *start
;
1927 if (!iswalpha( p
[0] ) || p
[1] != ':' || p
[2] != '\\' || p
[3] != '\\' || !p
[4]) return NULL
;
1929 len
= lstrlenW( start
);
1930 p
= start
+ len
- 1;
1931 if (*p
== '\\') return NULL
;
1933 while (p
>= start
&& *p
!= '\\') { len
--; p
--; };
1934 while (p
>= start
&& *p
== '\\') { len
--; p
--; };
1936 if (!(ret
= malloc( (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1937 for (i
= 0, p
= start
; p
< start
+ len
; p
++)
1939 if (p
[0] == '\\' && p
[1] == '\\')
1951 static BOOL
seen_dir( struct dirstack
*dirstack
, const WCHAR
*path
)
1954 for (i
= 0; i
< dirstack
->num_dirs
; i
++) if (!wcscmp( dirstack
->dirs
[i
], path
)) return TRUE
;
1958 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */
1959 static UINT
seed_dirs( struct dirstack
*dirstack
, const struct expr
*cond
, WCHAR root
, UINT
*count
)
1961 const struct expr
*left
, *right
;
1963 if (!cond
|| cond
->type
!= EXPR_COMPLEX
) return *count
= 0;
1965 left
= cond
->u
.expr
.left
;
1966 right
= cond
->u
.expr
.right
;
1967 if (cond
->u
.expr
.op
== OP_EQ
)
1971 const WCHAR
*str
= NULL
;
1973 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&&
1974 !wcscmp( left
->u
.propval
->name
, L
"Name" ) &&
1975 towupper( right
->u
.sval
[0] ) == towupper( root
))
1977 str
= right
->u
.sval
;
1979 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&&
1980 !wcscmp( right
->u
.propval
->name
, L
"Name" ) &&
1981 towupper( left
->u
.sval
[0] ) == towupper( root
))
1985 if (str
&& (path
= build_dirname( str
, &len
)))
1987 if (seen_dir( dirstack
, path
))
1992 else if (push_dir( dirstack
, path
, len
)) return ++*count
;
1997 else if (cond
->u
.expr
.op
== OP_OR
)
1999 UINT left_count
= 0, right_count
= 0;
2001 if (!(seed_dirs( dirstack
, left
, root
, &left_count
))) return *count
= 0;
2002 if (!(seed_dirs( dirstack
, right
, root
, &right_count
))) return *count
= 0;
2003 return *count
+= left_count
+ right_count
;
2008 static WCHAR
*append_path( const WCHAR
*path
, const WCHAR
*segment
, UINT
*len
)
2010 UINT len_path
= 0, len_segment
= lstrlenW( segment
);
2014 if (path
) len_path
= lstrlenW( path
);
2015 if (!(ret
= malloc( (len_path
+ len_segment
+ 2) * sizeof(WCHAR
) ))) return NULL
;
2016 if (path
&& len_path
)
2018 memcpy( ret
, path
, len_path
* sizeof(WCHAR
) );
2019 ret
[len_path
] = '\\';
2020 *len
+= len_path
+ 1;
2022 memcpy( ret
+ *len
, segment
, len_segment
* sizeof(WCHAR
) );
2023 *len
+= len_segment
;
2028 static WCHAR
*get_file_version( const WCHAR
*filename
)
2030 VS_FIXEDFILEINFO
*info
;
2032 DWORD len
= 4 * 5 + ARRAY_SIZE( L
"%u.%u.%u.%u" );
2036 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
2037 if (!(size
= GetFileVersionInfoSizeW( filename
, NULL
)) || !(block
= malloc( size
)))
2042 if (!GetFileVersionInfoW( filename
, 0, size
, block
) ||
2043 !VerQueryValueW( block
, L
"\\", (void **)&info
, &size
))
2049 swprintf( ret
, len
, L
"%u.%u.%u.%u", info
->dwFileVersionMS
>> 16, info
->dwFileVersionMS
& 0xffff,
2050 info
->dwFileVersionLS
>> 16, info
->dwFileVersionLS
& 0xffff );
2055 static enum fill_status
fill_datafile( struct table
*table
, const struct expr
*cond
)
2057 struct record_datafile
*rec
;
2058 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
2059 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
2060 DWORD drives
= GetLogicalDrives();
2061 WIN32_FIND_DATAW data
;
2063 struct dirstack
*dirstack
;
2064 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2066 if (!resize_table( table
, 8, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2068 dirstack
= alloc_dirstack(2);
2070 for (i
= 0; i
< 26; i
++)
2072 if (!(drives
& (1 << i
))) continue;
2075 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
2077 num_expected_rows
= 0;
2078 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2084 path
= pop_dir( dirstack
, &len
);
2085 if (!(glob
= build_glob( root
[0], path
, len
)))
2087 status
= FILL_STATUS_FAILED
;
2090 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2094 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2096 status
= FILL_STATUS_FAILED
;
2097 FindClose( handle
);
2100 if (!wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." )) continue;
2102 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2104 status
= FILL_STATUS_FAILED
;
2105 FindClose( handle
);
2109 if (data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
2111 if (push_dir( dirstack
, new_path
, len
)) continue;
2113 FindClose( handle
);
2114 status
= FILL_STATUS_FAILED
;
2117 rec
= (struct record_datafile
*)(table
->data
+ offset
);
2118 rec
->name
= build_name( root
[0], new_path
);
2119 rec
->version
= get_file_version( rec
->name
);
2121 if (!match_row( table
, row
, cond
, &status
))
2123 free_row_values( table
, row
);
2126 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2129 FindClose( handle
);
2130 status
= FILL_STATUS_FILTERED
;
2133 offset
+= sizeof(*rec
);
2136 while (FindNextFileW( handle
, &data
));
2137 FindClose( handle
);
2139 if (!peek_dir( dirstack
)) break;
2144 free_dirstack( dirstack
);
2148 TRACE("created %u rows\n", row
);
2149 table
->num_rows
= row
;
2153 static UINT32
get_pixelsperxlogicalinch(void)
2155 HDC hdc
= GetDC( NULL
);
2158 if (!hdc
) return 96;
2159 ret
= GetDeviceCaps( hdc
, LOGPIXELSX
);
2160 ReleaseDC( NULL
, hdc
);
2164 static enum fill_status
fill_desktopmonitor( struct table
*table
, const struct expr
*cond
)
2166 struct record_desktopmonitor
*rec
;
2167 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2170 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2172 rec
= (struct record_desktopmonitor
*)table
->data
;
2173 rec
->name
= L
"Generic Non-PnP Monitor";
2174 rec
->pixelsperxlogicalinch
= get_pixelsperxlogicalinch();
2176 if (match_row( table
, row
, cond
, &status
)) row
++;
2178 TRACE("created %u rows\n", row
);
2179 table
->num_rows
= row
;
2183 static enum fill_status
fill_directory( struct table
*table
, const struct expr
*cond
)
2185 struct record_directory
*rec
;
2186 UINT i
, len
, row
= 0, offset
= 0, num_expected_rows
;
2187 WCHAR
*glob
= NULL
, *path
= NULL
, *new_path
, root
[] = L
"A:\\";
2188 DWORD drives
= GetLogicalDrives();
2189 WIN32_FIND_DATAW data
;
2191 struct dirstack
*dirstack
;
2192 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2194 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2196 dirstack
= alloc_dirstack(2);
2198 for (i
= 0; i
< 26; i
++)
2200 if (!(drives
& (1 << i
))) continue;
2203 if (GetDriveTypeW( root
) != DRIVE_FIXED
) continue;
2205 num_expected_rows
= 0;
2206 if (!seed_dirs( dirstack
, cond
, root
[0], &num_expected_rows
)) clear_dirstack( dirstack
);
2212 path
= pop_dir( dirstack
, &len
);
2213 if (!(glob
= build_glob( root
[0], path
, len
)))
2215 status
= FILL_STATUS_FAILED
;
2218 if ((handle
= FindFirstFileW( glob
, &data
)) != INVALID_HANDLE_VALUE
)
2222 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
2224 FindClose( handle
);
2225 status
= FILL_STATUS_FAILED
;
2228 if (!(data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ||
2229 !wcscmp( data
.cFileName
, L
"." ) || !wcscmp( data
.cFileName
, L
".." ))
2232 if (!(new_path
= append_path( path
, data
.cFileName
, &len
)))
2234 FindClose( handle
);
2235 status
= FILL_STATUS_FAILED
;
2239 if (!(push_dir( dirstack
, new_path
, len
)))
2242 FindClose( handle
);
2243 status
= FILL_STATUS_FAILED
;
2246 rec
= (struct record_directory
*)(table
->data
+ offset
);
2247 rec
->accessmask
= FILE_ALL_ACCESS
;
2248 rec
->name
= build_name( root
[0], new_path
);
2250 if (!match_row( table
, row
, cond
, &status
))
2252 free_row_values( table
, row
);
2255 else if (num_expected_rows
&& row
== num_expected_rows
- 1)
2258 FindClose( handle
);
2259 status
= FILL_STATUS_FILTERED
;
2262 offset
+= sizeof(*rec
);
2265 while (FindNextFileW( handle
, &data
));
2266 FindClose( handle
);
2268 if (!peek_dir( dirstack
)) break;
2273 free_dirstack( dirstack
);
2277 TRACE("created %u rows\n", row
);
2278 table
->num_rows
= row
;
2282 static UINT64
get_freespace( const WCHAR
*dir
, UINT64
*disksize
)
2284 WCHAR root
[] = L
"\\\\.\\A:";
2285 ULARGE_INTEGER free
;
2286 DISK_GEOMETRY_EX info
;
2288 DWORD bytes_returned
;
2290 free
.QuadPart
= 512 * 1024 * 1024;
2291 GetDiskFreeSpaceExW( dir
, NULL
, NULL
, &free
);
2294 handle
= CreateFileW( root
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2295 if (handle
!= INVALID_HANDLE_VALUE
)
2297 if (DeviceIoControl( handle
, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
, NULL
, 0, &info
, sizeof(info
), &bytes_returned
, NULL
))
2298 *disksize
= info
.DiskSize
.QuadPart
;
2299 CloseHandle( handle
);
2301 return free
.QuadPart
;
2303 static WCHAR
*get_diskdrive_serialnumber( WCHAR letter
)
2306 STORAGE_DEVICE_DESCRIPTOR
*desc
;
2307 HANDLE handle
= INVALID_HANDLE_VALUE
;
2308 STORAGE_PROPERTY_QUERY query
= {0};
2312 swprintf( drive
, ARRAY_SIZE(drive
), L
"\\\\.\\%c:", letter
);
2313 handle
= CreateFileW( drive
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
2314 if (handle
== INVALID_HANDLE_VALUE
) goto done
;
2316 query
.PropertyId
= StorageDeviceProperty
;
2317 query
.QueryType
= PropertyStandardQuery
;
2319 size
= sizeof(*desc
) + 256;
2322 if (!(desc
= malloc( size
))) break;
2323 if (DeviceIoControl( handle
, IOCTL_STORAGE_QUERY_PROPERTY
, &query
, sizeof(query
), desc
, size
, NULL
, NULL
))
2325 if (desc
->SerialNumberOffset
) ret
= heap_strdupAW( (const char *)desc
+ desc
->SerialNumberOffset
);
2331 if (GetLastError() != ERROR_MORE_DATA
) break;
2335 if (handle
!= INVALID_HANDLE_VALUE
) CloseHandle( handle
);
2336 if (!ret
) ret
= wcsdup( L
"WINEHDISK" );
2340 static enum fill_status
fill_diskdrive( struct table
*table
, const struct expr
*cond
)
2342 static const WCHAR fmtW
[] = L
"\\\\\\\\.\\\\PHYSICALDRIVE%u";
2343 WCHAR device_id
[ARRAY_SIZE( fmtW
) + 10], root
[] = L
"A:\\";
2344 struct record_diskdrive
*rec
;
2345 UINT i
, row
= 0, offset
= 0, index
= 0, type
;
2346 UINT64 size
= 1024 * 1024 * 1024;
2347 DWORD drives
= GetLogicalDrives();
2348 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2350 if (!resize_table( table
, 2, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2352 for (i
= 0; i
< 26; i
++)
2354 if (drives
& (1 << i
))
2357 type
= GetDriveTypeW( root
);
2358 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2361 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2363 rec
= (struct record_diskdrive
*)(table
->data
+ offset
);
2364 swprintf( device_id
, ARRAY_SIZE( device_id
), fmtW
, index
);
2365 rec
->device_id
= wcsdup( device_id
);
2366 rec
->index
= index
++;
2367 rec
->interfacetype
= L
"IDE";
2368 rec
->manufacturer
= L
"(Standard disk drives)";
2369 rec
->mediatype
= (type
== DRIVE_FIXED
) ? L
"Fixed hard disk" : L
"Removable media";
2370 rec
->model
= L
"Wine Disk Drive";
2371 rec
->pnpdevice_id
= L
"IDE\\Disk\\VEN_WINE";
2372 rec
->serialnumber
= get_diskdrive_serialnumber( root
[0] );
2373 get_freespace( root
, &size
);
2375 if (!match_row( table
, row
, cond
, &status
))
2377 free_row_values( table
, row
);
2380 offset
+= sizeof(*rec
);
2384 TRACE("created %u rows\n", row
);
2385 table
->num_rows
= row
;
2395 static void free_associations( struct association
*assoc
, UINT count
)
2399 for (i
= 0; i
< count
; i
++)
2401 free( assoc
[i
].ref
);
2402 free( assoc
[i
].ref2
);
2407 static struct association
*get_diskdrivetodiskpartition_pairs( UINT
*count
)
2409 struct association
*ret
= NULL
;
2410 struct query
*query
, *query2
= NULL
;
2415 if (!(query
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return NULL
;
2416 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskDrive",
2417 &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2418 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2420 if (!(query2
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return FALSE
;
2421 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskPartition",
2422 &query2
->view
, &query2
->mem
)) != S_OK
) goto done
;
2423 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2425 if (!(ret
= calloc( query
->view
->result_count
, sizeof(*ret
) ))) goto done
;
2427 for (i
= 0; i
< query
->view
->result_count
; i
++)
2429 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2430 if (!(ret
[i
].ref
= wcsdup( V_BSTR(&val
) ))) goto done
;
2431 VariantClear( &val
);
2433 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2434 if (!(ret
[i
].ref2
= wcsdup( V_BSTR(&val
) ))) goto done
;
2435 VariantClear( &val
);
2438 *count
= query
->view
->result_count
;
2441 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2442 free_query( query
);
2443 free_query( query2
);
2447 static enum fill_status
fill_diskdrivetodiskpartition( struct table
*table
, const struct expr
*cond
)
2449 struct record_diskdrivetodiskpartition
*rec
;
2450 UINT i
, row
= 0, offset
= 0, count
= 0;
2451 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2452 struct association
*assoc
;
2454 if (!(assoc
= get_diskdrivetodiskpartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2457 free_associations( assoc
, count
);
2458 return FILL_STATUS_UNFILTERED
;
2460 if (!resize_table( table
, count
, sizeof(*rec
) ))
2462 free_associations( assoc
, count
);
2463 return FILL_STATUS_FAILED
;
2466 for (i
= 0; i
< count
; i
++)
2468 rec
= (struct record_diskdrivetodiskpartition
*)(table
->data
+ offset
);
2469 rec
->antecedent
= assoc
[i
].ref
;
2470 rec
->dependent
= assoc
[i
].ref2
;
2471 if (!match_row( table
, row
, cond
, &status
))
2473 free_row_values( table
, row
);
2476 offset
+= sizeof(*rec
);
2482 TRACE("created %u rows\n", row
);
2483 table
->num_rows
= row
;
2487 static WCHAR
*get_filesystem( const WCHAR
*root
)
2489 WCHAR buffer
[MAX_PATH
+ 1];
2491 if (GetVolumeInformationW( root
, NULL
, 0, NULL
, NULL
, NULL
, buffer
, MAX_PATH
+ 1 ))
2492 return wcsdup( buffer
);
2493 return wcsdup( L
"NTFS" );
2496 static enum fill_status
fill_diskpartition( struct table
*table
, const struct expr
*cond
)
2498 WCHAR device_id
[32], root
[] = L
"A:\\";
2499 struct record_diskpartition
*rec
;
2500 UINT i
, row
= 0, offset
= 0, type
, index
= 0;
2501 UINT64 size
= 1024 * 1024 * 1024;
2502 DWORD drives
= GetLogicalDrives();
2503 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2505 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2507 for (i
= 0; i
< 26; i
++)
2509 if (drives
& (1 << i
))
2512 type
= GetDriveTypeW( root
);
2513 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_REMOVABLE
)
2516 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2518 rec
= (struct record_diskpartition
*)(table
->data
+ offset
);
2519 rec
->bootable
= (i
== 2) ? -1 : 0;
2520 rec
->bootpartition
= (i
== 2) ? -1 : 0;
2521 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"Disk #%u, Partition #0", index
);
2522 rec
->device_id
= wcsdup( device_id
);
2523 rec
->diskindex
= index
++;
2525 rec
->pnpdevice_id
= wcsdup( device_id
);
2526 get_freespace( root
, &size
);
2528 rec
->startingoffset
= 0;
2529 rec
->type
= get_filesystem( root
);
2530 if (!match_row( table
, row
, cond
, &status
))
2532 free_row_values( table
, row
);
2535 offset
+= sizeof(*rec
);
2539 TRACE("created %u rows\n", row
);
2540 table
->num_rows
= row
;
2544 static UINT32
get_bitsperpixel( UINT
*hres
, UINT
*vres
)
2546 HDC hdc
= GetDC( NULL
);
2549 if (!hdc
) return 32;
2550 ret
= GetDeviceCaps( hdc
, BITSPIXEL
);
2551 *hres
= GetDeviceCaps( hdc
, HORZRES
);
2552 *vres
= GetDeviceCaps( hdc
, VERTRES
);
2553 ReleaseDC( NULL
, hdc
);
2557 static enum fill_status
fill_displaycontrollerconfig( struct table
*table
, const struct expr
*cond
)
2559 struct record_displaycontrollerconfig
*rec
;
2560 UINT row
= 0, hres
= 1024, vres
= 768;
2561 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2563 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2565 rec
= (struct record_displaycontrollerconfig
*)table
->data
;
2566 rec
->bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
2567 rec
->caption
= L
"VideoController1";
2568 rec
->horizontalresolution
= hres
;
2569 rec
->name
= L
"VideoController1";
2570 rec
->verticalresolution
= vres
;
2571 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
2574 TRACE("created %u rows\n", row
);
2575 table
->num_rows
= row
;
2579 static WCHAR
*get_ip4_string( DWORD addr
)
2581 DWORD len
= sizeof("ddd.ddd.ddd.ddd");
2584 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
2585 swprintf( ret
, len
, L
"%u.%u.%u.%u", (addr
>> 24) & 0xff, (addr
>> 16) & 0xff, (addr
>> 8) & 0xff, addr
& 0xff );
2589 static enum fill_status
fill_ip4routetable( struct table
*table
, const struct expr
*cond
)
2591 struct record_ip4routetable
*rec
;
2592 UINT i
, row
= 0, offset
= 0;
2594 MIB_IPFORWARDTABLE
*forwards
;
2595 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2597 if (GetIpForwardTable( NULL
, &size
, TRUE
) != ERROR_INSUFFICIENT_BUFFER
) return FILL_STATUS_FAILED
;
2598 if (!(forwards
= malloc( size
))) return FILL_STATUS_FAILED
;
2599 if (GetIpForwardTable( forwards
, &size
, TRUE
))
2602 return FILL_STATUS_FAILED
;
2604 if (!resize_table( table
, max(forwards
->dwNumEntries
, 1), sizeof(*rec
) ))
2607 return FILL_STATUS_FAILED
;
2610 for (i
= 0; i
< forwards
->dwNumEntries
; i
++)
2612 rec
= (struct record_ip4routetable
*)(table
->data
+ offset
);
2614 rec
->destination
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardDest
) );
2615 rec
->interfaceindex
= forwards
->table
[i
].dwForwardIfIndex
;
2616 rec
->nexthop
= get_ip4_string( ntohl(forwards
->table
[i
].dwForwardNextHop
) );
2618 if (!match_row( table
, row
, cond
, &status
))
2620 free_row_values( table
, row
);
2623 offset
+= sizeof(*rec
);
2626 TRACE("created %u rows\n", row
);
2627 table
->num_rows
= row
;
2633 static WCHAR
*get_volumename( const WCHAR
*root
)
2635 WCHAR buf
[MAX_PATH
+ 1] = {0};
2636 GetVolumeInformationW( root
, buf
, ARRAY_SIZE( buf
), NULL
, NULL
, NULL
, NULL
, 0 );
2637 return wcsdup( buf
);
2639 static WCHAR
*get_volumeserialnumber( const WCHAR
*root
)
2644 GetVolumeInformationW( root
, NULL
, 0, &serial
, NULL
, NULL
, NULL
, 0 );
2645 swprintf( buffer
, ARRAY_SIZE( buffer
), L
"%08X", serial
);
2646 return wcsdup( buffer
);
2649 static enum fill_status
fill_logicaldisk( struct table
*table
, const struct expr
*cond
)
2651 WCHAR device_id
[3], root
[] = L
"A:\\";
2652 struct record_logicaldisk
*rec
;
2653 UINT i
, row
= 0, offset
= 0, type
;
2654 UINT64 size
= 1024 * 1024 * 1024;
2655 DWORD drives
= GetLogicalDrives();
2656 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2658 if (!resize_table( table
, 4, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2660 for (i
= 0; i
< 26; i
++)
2662 if (drives
& (1 << i
))
2665 type
= GetDriveTypeW( root
);
2666 if (type
!= DRIVE_FIXED
&& type
!= DRIVE_CDROM
&& type
!= DRIVE_REMOVABLE
)
2669 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
2671 rec
= (struct record_logicaldisk
*)(table
->data
+ offset
);
2672 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%c:", 'A' + i
);
2673 rec
->caption
= wcsdup( device_id
);
2674 rec
->device_id
= wcsdup( device_id
);
2675 rec
->drivetype
= type
;
2676 rec
->filesystem
= get_filesystem( root
);
2677 rec
->freespace
= get_freespace( root
, &size
);
2678 rec
->name
= wcsdup( device_id
);
2680 rec
->volumename
= get_volumename( root
);
2681 rec
->volumeserialnumber
= get_volumeserialnumber( root
);
2682 if (!match_row( table
, row
, cond
, &status
))
2684 free_row_values( table
, row
);
2687 offset
+= sizeof(*rec
);
2691 TRACE("created %u rows\n", row
);
2692 table
->num_rows
= row
;
2696 static struct association
*get_logicaldisktopartition_pairs( UINT
*count
)
2698 struct association
*ret
= NULL
;
2699 struct query
*query
, *query2
= NULL
;
2704 if (!(query
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return NULL
;
2705 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
, L
"SELECT * FROM Win32_DiskPartition",
2706 &query
->view
, &query
->mem
)) != S_OK
) goto done
;
2707 if ((hr
= execute_view( query
->view
)) != S_OK
) goto done
;
2709 if (!(query2
= create_query( WBEMPROX_NAMESPACE_CIMV2
))) return FALSE
;
2710 if ((hr
= parse_query( WBEMPROX_NAMESPACE_CIMV2
,
2711 L
"SELECT * FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3", &query2
->view
,
2712 &query2
->mem
)) != S_OK
) goto done
;
2713 if ((hr
= execute_view( query2
->view
)) != S_OK
) goto done
;
2715 if (!(ret
= calloc( query
->view
->result_count
, sizeof(*ret
) ))) goto done
;
2717 /* assume fixed and removable disks are enumerated in the same order as partitions */
2718 for (i
= 0; i
< query
->view
->result_count
; i
++)
2720 if ((hr
= get_propval( query
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2721 if (!(ret
[i
].ref
= wcsdup( V_BSTR(&val
) ))) goto done
;
2722 VariantClear( &val
);
2724 if ((hr
= get_propval( query2
->view
, i
, L
"__PATH", &val
, NULL
, NULL
)) != S_OK
) goto done
;
2725 if (!(ret
[i
].ref2
= wcsdup( V_BSTR(&val
) ))) goto done
;
2726 VariantClear( &val
);
2729 *count
= query
->view
->result_count
;
2732 if (!ret
) free_associations( ret
, query
->view
->result_count
);
2733 free_query( query
);
2734 free_query( query2
);
2738 static enum fill_status
fill_logicaldisktopartition( struct table
*table
, const struct expr
*cond
)
2740 struct record_logicaldisktopartition
*rec
;
2741 UINT i
, row
= 0, offset
= 0, count
= 0;
2742 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2743 struct association
*assoc
;
2745 if (!(assoc
= get_logicaldisktopartition_pairs( &count
))) return FILL_STATUS_FAILED
;
2748 free_associations( assoc
, count
);
2749 return FILL_STATUS_UNFILTERED
;
2751 if (!resize_table( table
, count
, sizeof(*rec
) ))
2753 free_associations( assoc
, count
);
2754 return FILL_STATUS_FAILED
;
2757 for (i
= 0; i
< count
; i
++)
2759 rec
= (struct record_logicaldisktopartition
*)(table
->data
+ offset
);
2760 rec
->antecedent
= assoc
[i
].ref
;
2761 rec
->dependent
= assoc
[i
].ref2
;
2762 if (!match_row( table
, row
, cond
, &status
))
2764 free_row_values( table
, row
);
2767 offset
+= sizeof(*rec
);
2773 TRACE("created %u rows\n", row
);
2774 table
->num_rows
= row
;
2778 static UINT16
get_connection_status( IF_OPER_STATUS status
)
2782 case IfOperStatusDown
:
2783 return 0; /* Disconnected */
2784 case IfOperStatusUp
:
2785 return 2; /* Connected */
2787 ERR("unhandled status %u\n", status
);
2792 static WCHAR
*get_mac_address( const BYTE
*addr
, DWORD len
)
2795 if (len
!= 6 || !(ret
= malloc( 18 * sizeof(WCHAR
) ))) return NULL
;
2796 swprintf( ret
, 18, L
"%02x:%02x:%02x:%02x:%02x:%02x", addr
[0], addr
[1], addr
[2], addr
[3], addr
[4], addr
[5] );
2799 static const WCHAR
*get_adaptertype( DWORD type
, int *id
, int *physical
)
2803 case IF_TYPE_ETHERNET_CSMACD
:
2806 return L
"Ethernet 802.3";
2808 case IF_TYPE_IEEE80211
:
2813 case IF_TYPE_IEEE1394
:
2818 case IF_TYPE_TUNNEL
:
2830 #define GUID_SIZE 39
2831 static WCHAR
*guid_to_str( const GUID
*ptr
)
2834 if (!(ret
= malloc( GUID_SIZE
* sizeof(WCHAR
) ))) return NULL
;
2835 swprintf( ret
, GUID_SIZE
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2836 ptr
->Data1
, ptr
->Data2
, ptr
->Data3
, ptr
->Data4
[0], ptr
->Data4
[1], ptr
->Data4
[2],
2837 ptr
->Data4
[3], ptr
->Data4
[4], ptr
->Data4
[5], ptr
->Data4
[6], ptr
->Data4
[7] );
2841 static WCHAR
*get_networkadapter_guid( const IF_LUID
*luid
)
2844 if (ConvertInterfaceLuidToGuid( luid
, &guid
)) return NULL
;
2845 return guid_to_str( &guid
);
2848 static enum fill_status
fill_networkadapter( struct table
*table
, const struct expr
*cond
)
2850 WCHAR device_id
[11];
2851 struct record_networkadapter
*rec
;
2852 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
2853 UINT row
= 0, offset
= 0, count
= 0;
2854 DWORD size
= 0, ret
;
2855 int adaptertypeid
, physical
;
2856 enum fill_status status
= FILL_STATUS_UNFILTERED
;
2858 ret
= GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, NULL
, &size
);
2859 if (ret
!= ERROR_BUFFER_OVERFLOW
) return FILL_STATUS_FAILED
;
2861 if (!(buffer
= malloc( size
))) return FILL_STATUS_FAILED
;
2862 if (GetAdaptersAddresses( AF_UNSPEC
, 0, NULL
, buffer
, &size
))
2865 return FILL_STATUS_FAILED
;
2867 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2869 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
2871 if (!resize_table( table
, count
, sizeof(*rec
) ))
2874 return FILL_STATUS_FAILED
;
2876 for (aa
= buffer
; aa
; aa
= aa
->Next
)
2878 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
2880 rec
= (struct record_networkadapter
*)(table
->data
+ offset
);
2881 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"%u", aa
->u
.s
.IfIndex
);
2882 rec
->adaptertype
= get_adaptertype( aa
->IfType
, &adaptertypeid
, &physical
);
2883 rec
->adaptertypeid
= adaptertypeid
;
2884 rec
->description
= wcsdup( aa
->Description
);
2885 rec
->device_id
= wcsdup( device_id
);
2886 rec
->guid
= get_networkadapter_guid( &aa
->Luid
);
2887 rec
->index
= aa
->u
.s
.IfIndex
;
2888 rec
->interface_index
= aa
->u
.s
.IfIndex
;
2889 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
2890 rec
->manufacturer
= L
"The Wine Project";
2891 rec
->name
= wcsdup( aa
->FriendlyName
);
2892 rec
->netconnection_status
= get_connection_status( aa
->OperStatus
);
2893 rec
->physicaladapter
= physical
;
2894 rec
->pnpdevice_id
= L
"PCI\\VEN_8086&DEV_100E&SUBSYS_001E8086&REV_02\\3&267A616A&1&18";
2895 rec
->servicename
= wcsdup( aa
->FriendlyName
);
2896 rec
->speed
= 1000000;
2897 if (!match_row( table
, row
, cond
, &status
))
2899 free_row_values( table
, row
);
2902 offset
+= sizeof(*rec
);
2905 TRACE("created %u rows\n", row
);
2906 table
->num_rows
= row
;
2912 static WCHAR
*get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS
*addr
)
2914 const SOCKET_ADDRESS
*sa
= &addr
->Address
;
2915 WCHAR buf
[NI_MAXHOST
];
2917 if (!addr
) return NULL
;
2918 if (GetNameInfoW( sa
->lpSockaddr
, sa
->iSockaddrLength
, buf
, ARRAY_SIZE( buf
), NULL
,
2919 0, NI_NAMEREQD
)) return NULL
;
2920 return wcsdup( buf
);
2922 static struct array
*get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS
*list
)
2924 IP_ADAPTER_GATEWAY_ADDRESS
*gateway
;
2926 ULONG buflen
, i
= 0, count
= 0;
2927 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2929 if (!list
) return NULL
;
2930 for (gateway
= list
; gateway
; gateway
= gateway
->Next
) count
++;
2932 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2933 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2938 for (gateway
= list
; gateway
; gateway
= gateway
->Next
)
2940 buflen
= ARRAY_SIZE( buf
);
2941 if (WSAAddressToStringW( gateway
->Address
.lpSockaddr
, gateway
->Address
.iSockaddrLength
,
2942 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2944 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2950 ret
->elem_size
= sizeof(*ptr
);
2955 static struct array
*get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS
*list
)
2957 IP_ADAPTER_DNS_SERVER_ADDRESS
*server
;
2959 ULONG buflen
, i
= 0, count
= 0;
2960 WCHAR
**ptr
, *p
, buf
[54]; /* max IPv6 address length */
2962 if (!list
) return NULL
;
2963 for (server
= list
; server
; server
= server
->Next
) count
++;
2965 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
2966 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
2971 for (server
= list
; server
; server
= server
->Next
)
2973 buflen
= ARRAY_SIZE( buf
);
2974 if (WSAAddressToStringW( server
->Address
.lpSockaddr
, server
->Address
.iSockaddrLength
,
2975 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
2977 for (; i
> 0; i
--) free( ptr
[i
- 1] );
2982 if ((p
= wcsrchr( ptr
[i
- 1], ':' ))) *p
= 0;
2984 ret
->elem_size
= sizeof(*ptr
);
2989 static struct array
*get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
2991 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
2993 ULONG buflen
, i
= 0, count
= 0;
2994 WCHAR
**ptr
, buf
[54]; /* max IPv6 address length */
2996 if (!list
) return NULL
;
2997 for (address
= list
; address
; address
= address
->Next
) count
++;
2999 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
3000 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
3005 for (address
= list
; address
; address
= address
->Next
)
3007 buflen
= ARRAY_SIZE( buf
);
3008 if (WSAAddressToStringW( address
->Address
.lpSockaddr
, address
->Address
.iSockaddrLength
,
3009 NULL
, buf
, &buflen
) || !(ptr
[i
++] = wcsdup( buf
)))
3011 for (; i
> 0; i
--) free( ptr
[i
- 1] );
3017 ret
->elem_size
= sizeof(*ptr
);
3022 static struct array
*get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH
*list
)
3024 IP_ADAPTER_UNICAST_ADDRESS_LH
*address
;
3026 ULONG i
= 0, count
= 0;
3029 if (!list
) return NULL
;
3030 for (address
= list
; address
; address
= address
->Next
) count
++;
3032 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
3033 if (!(ptr
= malloc( sizeof(*ptr
) * count
)))
3038 for (address
= list
; address
; address
= address
->Next
)
3040 if (address
->Address
.lpSockaddr
->sa_family
== AF_INET
)
3042 WCHAR buf
[INET_ADDRSTRLEN
];
3044 ULONG buflen
= ARRAY_SIZE( buf
);
3046 memset( &addr
, 0, sizeof(addr
) );
3047 addr
.sin_family
= AF_INET
;
3048 if (ConvertLengthToIpv4Mask( address
->OnLinkPrefixLength
, &addr
.sin_addr
.S_un
.S_addr
) != NO_ERROR
3049 || WSAAddressToStringW( (SOCKADDR
*)&addr
, sizeof(addr
), NULL
, buf
, &buflen
))
3052 ptr
[i
] = wcsdup( buf
);
3057 swprintf( buf
, ARRAY_SIZE( buf
), L
"%u", address
->OnLinkPrefixLength
);
3058 ptr
[i
] = wcsdup( buf
);
3062 for (; i
> 0; i
--) free( ptr
[i
- 1] );
3068 ret
->elem_size
= sizeof(*ptr
);
3073 static WCHAR
*get_settingid( UINT32 index
)
3076 memset( &guid
, 0, sizeof(guid
) );
3078 return guid_to_str( &guid
);
3081 static enum fill_status
fill_networkadapterconfig( struct table
*table
, const struct expr
*cond
)
3083 struct record_networkadapterconfig
*rec
;
3084 IP_ADAPTER_ADDRESSES
*aa
, *buffer
;
3085 UINT row
= 0, offset
= 0, count
= 0;
3086 DWORD size
= 0, ret
;
3087 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3089 ret
= GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_GATEWAYS
, NULL
, NULL
, &size
);
3090 if (ret
!= ERROR_BUFFER_OVERFLOW
) return FILL_STATUS_FAILED
;
3092 if (!(buffer
= malloc( size
))) return FILL_STATUS_FAILED
;
3093 if (GetAdaptersAddresses( AF_UNSPEC
, GAA_FLAG_INCLUDE_GATEWAYS
, NULL
, buffer
, &size
))
3096 return FILL_STATUS_FAILED
;
3098 for (aa
= buffer
; aa
; aa
= aa
->Next
)
3100 if (aa
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
) count
++;
3102 if (!resize_table( table
, count
, sizeof(*rec
) ))
3105 return FILL_STATUS_FAILED
;
3107 for (aa
= buffer
; aa
; aa
= aa
->Next
)
3109 if (aa
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
) continue;
3111 rec
= (struct record_networkadapterconfig
*)(table
->data
+ offset
);
3112 rec
->defaultipgateway
= get_defaultipgateway( aa
->FirstGatewayAddress
);
3113 rec
->description
= wcsdup( aa
->Description
);
3114 rec
->dhcpenabled
= -1;
3115 rec
->dnsdomain
= L
"";
3116 rec
->dnshostname
= get_dnshostname( aa
->FirstUnicastAddress
);
3117 rec
->dnsserversearchorder
= get_dnsserversearchorder( aa
->FirstDnsServerAddress
);
3118 rec
->index
= aa
->u
.s
.IfIndex
;
3119 rec
->ipaddress
= get_ipaddress( aa
->FirstUnicastAddress
);
3120 rec
->ipconnectionmetric
= 20;
3121 rec
->ipenabled
= -1;
3122 rec
->ipsubnet
= get_ipsubnet( aa
->FirstUnicastAddress
);
3123 rec
->mac_address
= get_mac_address( aa
->PhysicalAddress
, aa
->PhysicalAddressLength
);
3124 rec
->settingid
= get_settingid( rec
->index
);
3125 if (!match_row( table
, row
, cond
, &status
))
3127 free_row_values( table
, row
);
3130 offset
+= sizeof(*rec
);
3133 TRACE("created %u rows\n", row
);
3134 table
->num_rows
= row
;
3140 static enum fill_status
fill_physicalmemory( struct table
*table
, const struct expr
*cond
)
3142 struct record_physicalmemory
*rec
;
3143 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3146 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3148 rec
= (struct record_physicalmemory
*)table
->data
;
3149 rec
->banklabel
= L
"BANK 0";
3150 rec
->capacity
= get_total_physical_memory();
3151 rec
->caption
= L
"Physical Memory";
3152 rec
->configuredclockspeed
= 1600;
3153 rec
->devicelocator
= L
"DIMM 0";
3154 rec
->formfactor
= 8; /* DIMM */
3155 rec
->memorytype
= 9; /* RAM */
3156 rec
->partnumber
= L
"";
3158 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3161 TRACE("created %u rows\n", row
);
3162 table
->num_rows
= row
;
3166 static enum fill_status
fill_pnpentity( struct table
*table
, const struct expr
*cond
)
3168 struct record_pnpentity
*rec
;
3169 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3170 HDEVINFO device_info_set
;
3171 SP_DEVINFO_DATA devinfo
= {0};
3174 device_info_set
= SetupDiGetClassDevsW( NULL
, NULL
, NULL
, DIGCF_ALLCLASSES
|DIGCF_PRESENT
);
3176 devinfo
.cbSize
= sizeof(devinfo
);
3179 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
3184 resize_table( table
, idx
, sizeof(*rec
) );
3185 table
->num_rows
= 0;
3186 rec
= (struct record_pnpentity
*)table
->data
;
3189 while (SetupDiEnumDeviceInfo( device_info_set
, idx
++, &devinfo
))
3191 WCHAR device_id
[MAX_PATH
];
3192 if (SetupDiGetDeviceInstanceIdW( device_info_set
, &devinfo
, device_id
,
3193 ARRAY_SIZE(device_id
), NULL
))
3195 rec
->device_id
= wcsdup( device_id
);
3196 rec
->manufacturer
= L
"The Wine Project";
3197 rec
->name
= L
"Wine PnP Device";
3200 if (!match_row( table
, table
->num_rows
- 1, cond
, &status
))
3202 free_row_values( table
, table
->num_rows
- 1 );
3210 SetupDiDestroyDeviceInfoList( device_info_set
);
3215 static enum fill_status
fill_printer( struct table
*table
, const struct expr
*cond
)
3217 struct record_printer
*rec
;
3218 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3219 PRINTER_INFO_2W
*info
;
3220 DWORD i
, offset
= 0, count
= 0, size
= 0;
3224 EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, NULL
, 0, &size
, &count
);
3225 if (!count
) return FILL_STATUS_UNFILTERED
;
3227 if (!(info
= malloc( size
))) return FILL_STATUS_FAILED
;
3228 if (!EnumPrintersW( PRINTER_ENUM_LOCAL
, NULL
, 2, (BYTE
*)info
, size
, &size
, &count
))
3231 return FILL_STATUS_FAILED
;
3233 if (!resize_table( table
, count
, sizeof(*rec
) ))
3236 return FILL_STATUS_FAILED
;
3239 for (i
= 0; i
< count
; i
++)
3241 rec
= (struct record_printer
*)(table
->data
+ offset
);
3242 rec
->attributes
= info
[i
].Attributes
;
3243 swprintf( id
, ARRAY_SIZE( id
), L
"Printer%u", i
);
3244 rec
->device_id
= wcsdup( id
);
3245 rec
->drivername
= wcsdup( info
[i
].pDriverName
);
3246 rec
->horizontalresolution
= info
[i
].pDevMode
->u1
.s1
.dmPrintQuality
;
3248 rec
->location
= wcsdup( info
[i
].pLocation
);
3249 rec
->name
= wcsdup( info
[i
].pPrinterName
);
3251 rec
->portname
= wcsdup( info
[i
].pPortName
);
3252 if (!match_row( table
, i
, cond
, &status
))
3254 free_row_values( table
, i
);
3257 offset
+= sizeof(*rec
);
3260 TRACE("created %u rows\n", num_rows
);
3261 table
->num_rows
= num_rows
;
3267 static WCHAR
*get_cmdline( DWORD process_id
)
3269 if (process_id
== GetCurrentProcessId()) return wcsdup( GetCommandLineW() );
3270 return NULL
; /* FIXME handle different process case */
3273 static enum fill_status
fill_process( struct table
*table
, const struct expr
*cond
)
3276 struct record_process
*rec
;
3277 PROCESSENTRY32W entry
;
3279 enum fill_status status
= FILL_STATUS_FAILED
;
3280 UINT row
= 0, offset
= 0;
3282 snap
= CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS
, 0 );
3283 if (snap
== INVALID_HANDLE_VALUE
) return FILL_STATUS_FAILED
;
3285 entry
.dwSize
= sizeof(entry
);
3286 if (!Process32FirstW( snap
, &entry
)) goto done
;
3287 if (!resize_table( table
, 8, sizeof(*rec
) )) goto done
;
3291 if (!resize_table( table
, row
+ 1, sizeof(*rec
) ))
3293 status
= FILL_STATUS_FAILED
;
3297 rec
= (struct record_process
*)(table
->data
+ offset
);
3298 rec
->caption
= wcsdup( entry
.szExeFile
);
3299 rec
->commandline
= get_cmdline( entry
.th32ProcessID
);
3300 rec
->description
= wcsdup( entry
.szExeFile
);
3301 swprintf( handle
, ARRAY_SIZE( handle
), L
"%u", entry
.th32ProcessID
);
3302 rec
->handle
= wcsdup( handle
);
3303 rec
->name
= wcsdup( entry
.szExeFile
);
3304 rec
->process_id
= entry
.th32ProcessID
;
3305 rec
->pprocess_id
= entry
.th32ParentProcessID
;
3306 rec
->thread_count
= entry
.cntThreads
;
3307 rec
->workingsetsize
= 0;
3309 rec
->create
= process_create
;
3310 rec
->get_owner
= process_get_owner
;
3311 if (!match_row( table
, row
, cond
, &status
))
3313 free_row_values( table
, row
);
3316 offset
+= sizeof(*rec
);
3318 } while (Process32NextW( snap
, &entry
));
3320 TRACE("created %u rows\n", row
);
3321 table
->num_rows
= row
;
3324 CloseHandle( snap
);
3328 void do_cpuid( unsigned int ax
, int *p
)
3330 #if defined(__i386__) || defined(__x86_64__)
3337 static unsigned int get_processor_model( unsigned int reg0
, unsigned int *stepping
, unsigned int *family
)
3339 unsigned int model
, family_id
= (reg0
& (0x0f << 8)) >> 8;
3341 model
= (reg0
& (0x0f << 4)) >> 4;
3342 if (family_id
== 6 || family_id
== 15) model
|= (reg0
& (0x0f << 16)) >> 12;
3345 *family
= family_id
;
3346 if (family_id
== 15) *family
+= (reg0
& (0xff << 20)) >> 20;
3348 *stepping
= reg0
& 0x0f;
3351 static void regs_to_str( int *regs
, unsigned int len
, WCHAR
*buffer
)
3354 unsigned char *p
= (unsigned char *)regs
;
3356 for (i
= 0; i
< len
; i
++) { buffer
[i
] = *p
++; }
3359 static void get_processor_manufacturer( WCHAR
*manufacturer
, UINT len
)
3361 int tmp
, regs
[4] = {0, 0, 0, 0};
3363 do_cpuid( 0, regs
);
3364 tmp
= regs
[2]; /* swap edx and ecx */
3368 regs_to_str( regs
+ 1, min( 12, len
), manufacturer
);
3370 static const WCHAR
*get_osarchitecture(void)
3373 GetNativeSystemInfo( &info
);
3374 if (info
.u
.s
.wProcessorArchitecture
== PROCESSOR_ARCHITECTURE_AMD64
) return L
"64-bit";
3377 static void get_processor_caption( WCHAR
*caption
, UINT len
)
3380 WCHAR manufacturer
[13];
3381 int regs
[4] = {0, 0, 0, 0};
3382 unsigned int family
, model
, stepping
;
3384 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3385 if (!wcscmp( get_osarchitecture(), L
"32-bit" )) arch
= L
"x86";
3386 else if (!wcscmp( manufacturer
, L
"AuthenticAMD" )) arch
= L
"AMD64";
3387 else arch
= L
"Intel64";
3389 do_cpuid( 1, regs
);
3391 model
= get_processor_model( regs
[0], &stepping
, &family
);
3392 swprintf( caption
, len
, L
"%s Family %u Model %u Stepping %u", arch
, family
, model
, stepping
);
3394 static void get_processor_version( WCHAR
*version
, UINT len
)
3396 int regs
[4] = {0, 0, 0, 0};
3397 unsigned int model
, stepping
;
3399 do_cpuid( 1, regs
);
3401 model
= get_processor_model( regs
[0], &stepping
, NULL
);
3402 swprintf( version
, len
, L
"Model %u Stepping %u", model
, stepping
);
3404 static UINT16
get_processor_revision(void)
3406 int regs
[4] = {0, 0, 0, 0};
3407 do_cpuid( 1, regs
);
3410 static void get_processor_id( WCHAR
*processor_id
, UINT len
)
3412 int regs
[4] = {0, 0, 0, 0};
3414 do_cpuid( 1, regs
);
3415 swprintf( processor_id
, len
, L
"%08X%08X", regs
[3], regs
[0] );
3417 static void get_processor_name( WCHAR
*name
)
3419 int regs
[4] = {0, 0, 0, 0};
3422 do_cpuid( 0x80000000, regs
);
3423 if (regs
[0] >= 0x80000004)
3425 do_cpuid( 0x80000002, regs
);
3426 regs_to_str( regs
, 16, name
);
3427 do_cpuid( 0x80000003, regs
);
3428 regs_to_str( regs
, 16, name
+ 16 );
3429 do_cpuid( 0x80000004, regs
);
3430 regs_to_str( regs
, 16, name
+ 32 );
3432 for (i
= lstrlenW(name
) - 1; i
>= 0 && name
[i
] == ' '; i
--) name
[i
] = 0;
3434 static UINT
get_processor_currentclockspeed( 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
].CurrentMhz
;
3448 static UINT
get_processor_maxclockspeed( UINT index
)
3450 PROCESSOR_POWER_INFORMATION
*info
;
3451 UINT ret
= 1000, size
= get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION
);
3454 if ((info
= malloc( size
)))
3456 status
= NtPowerInformation( ProcessorInformation
, NULL
, 0, info
, size
);
3457 if (!status
) ret
= info
[index
].MaxMhz
;
3463 static enum fill_status
fill_processor( struct table
*table
, const struct expr
*cond
)
3465 WCHAR caption
[100], device_id
[14], processor_id
[17], manufacturer
[13], name
[49] = {0}, version
[50];
3466 struct record_processor
*rec
;
3467 UINT i
, offset
= 0, num_rows
= 0, num_logical
, num_physical
, num_packages
;
3468 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3470 num_logical
= get_logical_processor_count( &num_physical
, &num_packages
);
3472 if (!resize_table( table
, num_packages
, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3474 get_processor_caption( caption
, ARRAY_SIZE( caption
) );
3475 get_processor_id( processor_id
, ARRAY_SIZE( processor_id
) );
3476 get_processor_manufacturer( manufacturer
, ARRAY_SIZE( manufacturer
) );
3477 get_processor_name( name
);
3478 get_processor_version( version
, ARRAY_SIZE( version
) );
3480 for (i
= 0; i
< num_packages
; i
++)
3482 rec
= (struct record_processor
*)(table
->data
+ offset
);
3483 rec
->addresswidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3484 rec
->architecture
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 0 : 9;
3485 rec
->caption
= wcsdup( caption
);
3486 rec
->cpu_status
= 1; /* CPU Enabled */
3487 rec
->currentclockspeed
= get_processor_currentclockspeed( i
);
3488 rec
->datawidth
= !wcscmp( get_osarchitecture(), L
"32-bit" ) ? 32 : 64;
3489 rec
->description
= wcsdup( caption
);
3490 swprintf( device_id
, ARRAY_SIZE( device_id
), L
"CPU%u", i
);
3491 rec
->device_id
= wcsdup( device_id
);
3492 rec
->family
= 2; /* Unknown */
3494 rec
->manufacturer
= wcsdup( manufacturer
);
3495 rec
->maxclockspeed
= get_processor_maxclockspeed( i
);
3496 rec
->name
= wcsdup( name
);
3497 rec
->num_cores
= num_physical
/ num_packages
;
3498 rec
->num_logical_processors
= num_logical
/ num_packages
;
3499 rec
->processor_id
= wcsdup( processor_id
);
3500 rec
->processortype
= 3; /* central processor */
3501 rec
->revision
= get_processor_revision();
3502 rec
->unique_id
= NULL
;
3503 rec
->version
= wcsdup( version
);
3504 if (!match_row( table
, i
, cond
, &status
))
3506 free_row_values( table
, i
);
3509 offset
+= sizeof(*rec
);
3513 TRACE("created %u rows\n", num_rows
);
3514 table
->num_rows
= num_rows
;
3518 static INT16
get_currenttimezone(void)
3520 TIME_ZONE_INFORMATION info
;
3521 DWORD status
= GetTimeZoneInformation( &info
);
3522 if (status
== TIME_ZONE_ID_INVALID
) return 0;
3523 if (status
== TIME_ZONE_ID_DAYLIGHT
) return -(info
.Bias
+ info
.DaylightBias
);
3524 return -(info
.Bias
+ info
.StandardBias
);
3527 static WCHAR
*get_lastbootuptime(void)
3529 SYSTEM_TIMEOFDAY_INFORMATION ti
;
3533 if (!(ret
= malloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3535 NtQuerySystemInformation( SystemTimeOfDayInformation
, &ti
, sizeof(ti
), NULL
);
3536 RtlTimeToTimeFields( &ti
.BootTime
, &tf
);
3537 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u+000", tf
.Year
, tf
.Month
, tf
.Day
, tf
.Hour
, tf
.Minute
,
3538 tf
.Second
, tf
.Milliseconds
* 1000 );
3541 static WCHAR
*get_localdatetime(void)
3543 TIME_ZONE_INFORMATION tzi
;
3549 Status
= GetTimeZoneInformation(&tzi
);
3551 if(Status
== TIME_ZONE_ID_INVALID
) return NULL
;
3553 if(Status
== TIME_ZONE_ID_DAYLIGHT
)
3554 Bias
+= tzi
.DaylightBias
;
3556 Bias
+= tzi
.StandardBias
;
3557 if (!(ret
= malloc( 26 * sizeof(WCHAR
) ))) return NULL
;
3560 swprintf( ret
, 26, L
"%04u%02u%02u%02u%02u%02u.%06u%+03d", st
.wYear
, st
.wMonth
, st
.wDay
, st
.wHour
, st
.wMinute
,
3561 st
.wSecond
, st
.wMilliseconds
* 1000, -Bias
);
3564 static WCHAR
*get_systemdirectory(void)
3569 if (!(ret
= malloc( MAX_PATH
* sizeof(WCHAR
) ))) return NULL
;
3570 Wow64DisableWow64FsRedirection( &redir
);
3571 GetSystemDirectoryW( ret
, MAX_PATH
);
3572 Wow64RevertWow64FsRedirection( redir
);
3575 static WCHAR
*get_systemdrive(void)
3577 WCHAR
*ret
= malloc( 3 * sizeof(WCHAR
) ); /* "c:" */
3578 if (ret
&& GetEnvironmentVariableW( L
"SystemDrive", ret
, 3 )) return ret
;
3582 static WCHAR
*get_codeset(void)
3584 WCHAR
*ret
= malloc( 11 * sizeof(WCHAR
) );
3585 if (ret
) swprintf( ret
, 11, L
"%u", GetACP() );
3588 static WCHAR
*get_countrycode(void)
3590 WCHAR
*ret
= malloc( 6 * sizeof(WCHAR
) );
3591 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ICOUNTRY
, ret
, 6 );
3594 static WCHAR
*get_locale(void)
3596 WCHAR
*ret
= malloc( 5 * sizeof(WCHAR
) );
3597 if (ret
) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT
, LOCALE_ILANGUAGE
, ret
, 5 );
3601 static WCHAR
*get_reg_str( HKEY root
, const WCHAR
*path
, const WCHAR
*value
)
3607 if (!RegOpenKeyExW( root
, path
, 0, KEY_READ
, &hkey
) &&
3608 !RegQueryValueExW( hkey
, value
, NULL
, &type
, NULL
, &size
) && type
== REG_SZ
&&
3609 (ret
= malloc( size
+ sizeof(WCHAR
) )))
3611 size
+= sizeof(WCHAR
);
3612 if (RegQueryValueExW( hkey
, value
, NULL
, NULL
, (BYTE
*)ret
, &size
))
3618 if (hkey
) RegCloseKey( hkey
);
3622 static WCHAR
*get_organization(void)
3624 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
3625 L
"RegisteredOrganization" );
3628 static WCHAR
*get_osbuildnumber( OSVERSIONINFOEXW
*ver
)
3630 WCHAR
*ret
= malloc( 11 * sizeof(WCHAR
) );
3631 if (ret
) swprintf( ret
, 11, L
"%u", ver
->dwBuildNumber
);
3635 static WCHAR
*get_oscaption( OSVERSIONINFOEXW
*ver
)
3637 static const WCHAR windowsW
[] = L
"Microsoft Windows ";
3638 static const WCHAR win2000W
[] = L
"2000 Professional";
3639 static const WCHAR win2003W
[] = L
"Server 2003 Standard Edition";
3640 static const WCHAR winxpW
[] = L
"XP Professional";
3641 static const WCHAR winxp64W
[] = L
"XP Professional x64 Edition";
3642 static const WCHAR vistaW
[] = L
"Vista Ultimate";
3643 static const WCHAR win2008W
[] = L
"Server 2008 Standard";
3644 static const WCHAR win7W
[] = L
"7 Professional";
3645 static const WCHAR win2008r2W
[] = L
"Server 2008 R2 Standard";
3646 static const WCHAR win8W
[] = L
"8 Pro";
3647 static const WCHAR win81W
[] = L
"8.1 Pro";
3648 static const WCHAR win10W
[] = L
"10 Pro";
3649 static const WCHAR win11W
[] = L
"11 Pro";
3650 int len
= ARRAY_SIZE( windowsW
) - 1;
3653 if (!(ret
= malloc( len
* sizeof(WCHAR
) + sizeof(win2003W
) ))) return NULL
;
3654 memcpy( ret
, windowsW
, sizeof(windowsW
) );
3655 if (ver
->dwMajorVersion
== 10 && ver
->dwMinorVersion
== 0)
3657 if (ver
->dwBuildNumber
>= 22000) memcpy( ret
+ len
, win11W
, sizeof(win11W
) );
3658 else memcpy( ret
+ len
, win10W
, sizeof(win10W
) );
3660 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 3) memcpy( ret
+ len
, win81W
, sizeof(win81W
) );
3661 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 2) memcpy( ret
+ len
, win8W
, sizeof(win8W
) );
3662 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 1)
3664 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, win7W
, sizeof(win7W
) );
3665 else memcpy( ret
+ len
, win2008r2W
, sizeof(win2008r2W
) );
3667 else if (ver
->dwMajorVersion
== 6 && ver
->dwMinorVersion
== 0)
3669 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, vistaW
, sizeof(vistaW
) );
3670 else memcpy( ret
+ len
, win2008W
, sizeof(win2008W
) );
3672 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 2)
3674 if (ver
->wProductType
== VER_NT_WORKSTATION
) memcpy( ret
+ len
, winxp64W
, sizeof(winxp64W
) );
3675 else memcpy( ret
+ len
, win2003W
, sizeof(win2003W
) );
3677 else if (ver
->dwMajorVersion
== 5 && ver
->dwMinorVersion
== 1) memcpy( ret
+ len
, winxpW
, sizeof(winxpW
) );
3678 else memcpy( ret
+ len
, win2000W
, sizeof(win2000W
) );
3682 static WCHAR
*get_osname( const WCHAR
*caption
)
3684 static const WCHAR partitionW
[] = L
"|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1";
3685 int len
= lstrlenW( caption
);
3688 if (!(ret
= malloc( len
* sizeof(WCHAR
) + sizeof(partitionW
) ))) return NULL
;
3689 memcpy( ret
, caption
, len
* sizeof(WCHAR
) );
3690 memcpy( ret
+ len
, partitionW
, sizeof(partitionW
) );
3694 static WCHAR
*get_osserialnumber(void)
3696 WCHAR
*ret
= get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"ProductId" );
3697 if (!ret
) ret
= wcsdup( L
"12345-OEM-1234567-12345" );
3701 static WCHAR
*get_osversion( OSVERSIONINFOEXW
*ver
)
3703 WCHAR
*ret
= malloc( 33 * sizeof(WCHAR
) );
3704 if (ret
) swprintf( ret
, 33, L
"%u.%u.%u", ver
->dwMajorVersion
, ver
->dwMinorVersion
, ver
->dwBuildNumber
);
3708 static DWORD
get_operatingsystemsku(void)
3710 DWORD ret
= PRODUCT_UNDEFINED
;
3711 GetProductInfo( 6, 0, 0, 0, &ret
);
3715 static WCHAR
*get_registereduser(void)
3717 return get_reg_str( HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion", L
"RegisteredOwner" );
3720 static WCHAR
*get_windowsdirectory(void)
3722 WCHAR dir
[MAX_PATH
];
3723 if (!GetWindowsDirectoryW( dir
, ARRAY_SIZE(dir
) )) return NULL
;
3724 return wcsdup( dir
);
3727 static enum fill_status
fill_operatingsystem( struct table
*table
, const struct expr
*cond
)
3729 struct record_operatingsystem
*rec
;
3730 enum fill_status status
= FILL_STATUS_UNFILTERED
;
3731 RTL_OSVERSIONINFOEXW ver
;
3734 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3736 ver
.dwOSVersionInfoSize
= sizeof(ver
);
3737 RtlGetVersion( &ver
);
3739 rec
= (struct record_operatingsystem
*)table
->data
;
3740 rec
->bootdevice
= L
"\\Device\\HarddiskVolume1";
3741 rec
->buildnumber
= get_osbuildnumber( &ver
);
3742 rec
->buildtype
= L
"Wine build";
3743 rec
->caption
= get_oscaption( &ver
);
3744 rec
->codeset
= get_codeset();
3745 rec
->countrycode
= get_countrycode();
3746 rec
->csdversion
= ver
.szCSDVersion
[0] ? wcsdup( ver
.szCSDVersion
) : NULL
;
3747 rec
->csname
= get_computername();
3748 rec
->currenttimezone
= get_currenttimezone();
3749 rec
->freephysicalmemory
= get_available_physical_memory() / 1024;
3750 rec
->freevirtualmemory
= get_available_virtual_memory() / 1024;
3751 rec
->installdate
= L
"20140101000000.000000+000";
3752 rec
->lastbootuptime
= get_lastbootuptime();
3753 rec
->localdatetime
= get_localdatetime();
3754 rec
->locale
= get_locale();
3755 rec
->manufacturer
= L
"The Wine Project";
3756 rec
->name
= get_osname( rec
->caption
);
3757 rec
->operatingsystemsku
= get_operatingsystemsku();
3758 rec
->organization
= get_organization();
3759 rec
->osarchitecture
= get_osarchitecture();
3760 rec
->oslanguage
= GetSystemDefaultLangID();
3761 rec
->osproductsuite
= 2461140; /* Windows XP Professional */
3762 rec
->ostype
= 18; /* WINNT */
3764 rec
->producttype
= 1;
3765 rec
->registereduser
= get_registereduser();
3766 rec
->serialnumber
= get_osserialnumber();
3767 rec
->servicepackmajor
= ver
.wServicePackMajor
;
3768 rec
->servicepackminor
= ver
.wServicePackMinor
;
3769 rec
->status
= L
"OK";
3770 rec
->suitemask
= 272; /* Single User + Terminal */
3771 rec
->systemdirectory
= get_systemdirectory();
3772 rec
->systemdrive
= get_systemdrive();
3773 rec
->totalvirtualmemorysize
= get_total_physical_memory() / 1024;
3774 rec
->totalvisiblememorysize
= rec
->totalvirtualmemorysize
;
3775 rec
->version
= get_osversion( &ver
);
3776 rec
->windowsdirectory
= get_windowsdirectory();
3777 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
3780 TRACE("created %u rows\n", row
);
3781 table
->num_rows
= row
;
3785 static const WCHAR
*get_service_type( DWORD type
)
3787 if (type
& SERVICE_KERNEL_DRIVER
) return L
"Kernel Driver";
3788 else if (type
& SERVICE_FILE_SYSTEM_DRIVER
) return L
"File System Driver";
3789 else if (type
& SERVICE_WIN32_OWN_PROCESS
) return L
"Own Process";
3790 else if (type
& SERVICE_WIN32_SHARE_PROCESS
) return L
"Share Process";
3791 else ERR( "unhandled type %#lx\n", type
);
3794 static const WCHAR
*get_service_state( DWORD state
)
3798 case SERVICE_STOPPED
: return L
"Stopped";
3799 case SERVICE_START_PENDING
: return L
"Start Pending";
3800 case SERVICE_STOP_PENDING
: return L
"Stop Pending";
3801 case SERVICE_RUNNING
: return L
"Running";
3803 ERR( "unknown state %lu\n", state
);
3807 static const WCHAR
*get_service_startmode( DWORD mode
)
3811 case SERVICE_BOOT_START
: return L
"Boot";
3812 case SERVICE_SYSTEM_START
: return L
"System";
3813 case SERVICE_AUTO_START
: return L
"Auto";
3814 case SERVICE_DEMAND_START
: return L
"Manual";
3815 case SERVICE_DISABLED
: return L
"Disabled";
3817 ERR( "unknown mode %#lx\n", mode
);
3821 static QUERY_SERVICE_CONFIGW
*query_service_config( SC_HANDLE manager
, const WCHAR
*name
)
3823 QUERY_SERVICE_CONFIGW
*config
= NULL
;
3827 if (!(service
= OpenServiceW( manager
, name
, SERVICE_QUERY_CONFIG
))) return NULL
;
3828 QueryServiceConfigW( service
, NULL
, 0, &size
);
3829 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
) goto done
;
3830 if (!(config
= malloc( size
))) goto done
;
3831 if (QueryServiceConfigW( service
, config
, size
, &size
)) goto done
;
3836 CloseServiceHandle( service
);
3840 static enum fill_status
fill_service( struct table
*table
, const struct expr
*cond
)
3842 struct record_service
*rec
;
3844 ENUM_SERVICE_STATUS_PROCESSW
*tmp
, *services
= NULL
;
3845 SERVICE_STATUS_PROCESS
*status
;
3846 WCHAR sysnameW
[MAX_COMPUTERNAME_LENGTH
+ 1];
3847 DWORD len
= ARRAY_SIZE( sysnameW
), needed
, count
;
3848 UINT i
, row
= 0, offset
= 0, size
= 256;
3849 enum fill_status fill_status
= FILL_STATUS_FAILED
;
3852 if (!(manager
= OpenSCManagerW( NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
))) return FILL_STATUS_FAILED
;
3853 if (!(services
= malloc( size
))) goto done
;
3855 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3856 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3857 &count
, NULL
, NULL
);
3860 if (GetLastError() != ERROR_MORE_DATA
) goto done
;
3862 if (!(tmp
= realloc( services
, size
))) goto done
;
3864 ret
= EnumServicesStatusExW( manager
, SC_ENUM_PROCESS_INFO
, SERVICE_TYPE_ALL
,
3865 SERVICE_STATE_ALL
, (BYTE
*)services
, size
, &needed
,
3866 &count
, NULL
, NULL
);
3867 if (!ret
) goto done
;
3869 if (!resize_table( table
, count
, sizeof(*rec
) )) goto done
;
3871 GetComputerNameW( sysnameW
, &len
);
3872 fill_status
= FILL_STATUS_UNFILTERED
;
3874 for (i
= 0; i
< count
; i
++)
3876 QUERY_SERVICE_CONFIGW
*config
;
3878 if (!(config
= query_service_config( manager
, services
[i
].lpServiceName
))) continue;
3880 status
= &services
[i
].ServiceStatusProcess
;
3881 rec
= (struct record_service
*)(table
->data
+ offset
);
3882 rec
->accept_pause
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_PAUSE_CONTINUE
) ? -1 : 0;
3883 rec
->accept_stop
= (status
->dwControlsAccepted
& SERVICE_ACCEPT_STOP
) ? -1 : 0;
3884 rec
->displayname
= wcsdup( services
[i
].lpDisplayName
);
3885 rec
->name
= wcsdup( services
[i
].lpServiceName
);
3886 rec
->process_id
= status
->dwProcessId
;
3887 rec
->servicetype
= get_service_type( status
->dwServiceType
);
3888 rec
->startmode
= get_service_startmode( config
->dwStartType
);
3889 rec
->state
= get_service_state( status
->dwCurrentState
);
3890 rec
->systemname
= wcsdup( sysnameW
);
3891 rec
->pause_service
= service_pause_service
;
3892 rec
->resume_service
= service_resume_service
;
3893 rec
->start_service
= service_start_service
;
3894 rec
->stop_service
= service_stop_service
;
3896 if (!match_row( table
, row
, cond
, &fill_status
))
3898 free_row_values( table
, row
);
3901 offset
+= sizeof(*rec
);
3905 TRACE("created %u rows\n", row
);
3906 table
->num_rows
= row
;
3909 CloseServiceHandle( manager
);
3914 static WCHAR
*get_accountname( LSA_TRANSLATED_NAME
*name
)
3916 if (!name
|| !name
->Name
.Buffer
) return NULL
;
3917 return wcsdup( name
->Name
.Buffer
);
3919 static struct array
*get_binaryrepresentation( PSID sid
, UINT len
)
3924 if (!(ret
= malloc( sizeof(*ret
) ))) return NULL
;
3925 if (!(ptr
= malloc( len
)))
3930 memcpy( ptr
, sid
, len
);
3931 ret
->elem_size
= sizeof(*ptr
);
3936 static WCHAR
*get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST
*domain
)
3938 if (!domain
|| !domain
->Domains
|| !domain
->Domains
->Name
.Buffer
) return NULL
;
3939 return wcsdup( domain
->Domains
->Name
.Buffer
);
3941 static const WCHAR
*find_sid_str( const struct expr
*cond
)
3943 const struct expr
*left
, *right
;
3944 const WCHAR
*ret
= NULL
;
3946 if (!cond
|| cond
->type
!= EXPR_COMPLEX
|| cond
->u
.expr
.op
!= OP_EQ
) return NULL
;
3948 left
= cond
->u
.expr
.left
;
3949 right
= cond
->u
.expr
.right
;
3950 if (left
->type
== EXPR_PROPVAL
&& right
->type
== EXPR_SVAL
&& !wcsicmp( left
->u
.propval
->name
, L
"SID" ))
3952 ret
= right
->u
.sval
;
3954 else if (left
->type
== EXPR_SVAL
&& right
->type
== EXPR_PROPVAL
&& !wcsicmp( right
->u
.propval
->name
, L
"SID" ))
3961 static enum fill_status
fill_sid( struct table
*table
, const struct expr
*cond
)
3964 LSA_REFERENCED_DOMAIN_LIST
*domain
;
3965 LSA_TRANSLATED_NAME
*name
;
3967 LSA_OBJECT_ATTRIBUTES attrs
;
3969 struct record_sid
*rec
;
3972 if (!(str
= find_sid_str( cond
))) return FILL_STATUS_FAILED
;
3973 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
3975 if (!ConvertStringSidToSidW( str
, &sid
)) return FILL_STATUS_FAILED
;
3976 len
= GetLengthSid( sid
);
3978 memset( &attrs
, 0, sizeof(attrs
) );
3979 attrs
.Length
= sizeof(attrs
);
3980 if (LsaOpenPolicy( NULL
, &attrs
, POLICY_ALL_ACCESS
, &handle
))
3983 return FILL_STATUS_FAILED
;
3985 if (LsaLookupSids( handle
, 1, &sid
, &domain
, &name
))
3989 return FILL_STATUS_FAILED
;
3992 rec
= (struct record_sid
*)table
->data
;
3993 rec
->accountname
= get_accountname( name
);
3994 rec
->binaryrepresentation
= get_binaryrepresentation( sid
, len
);
3995 rec
->referenceddomainname
= get_referenceddomainname( domain
);
3996 rec
->sid
= wcsdup( str
);
3997 rec
->sidlength
= len
;
3999 TRACE("created 1 row\n");
4000 table
->num_rows
= 1;
4002 LsaFreeMemory( domain
);
4003 LsaFreeMemory( name
);
4006 return FILL_STATUS_FILTERED
;
4009 static WCHAR
*get_systemenclosure_string( BYTE id
, const char *buf
, UINT len
)
4011 const struct smbios_header
*hdr
;
4012 const struct smbios_chassis
*chassis
;
4015 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
))) return NULL
;
4017 chassis
= (const struct smbios_chassis
*)hdr
;
4018 offset
= (const char *)chassis
- buf
+ chassis
->hdr
.length
;
4019 return get_smbios_string( id
, buf
, offset
, len
);
4022 static WCHAR
*get_systemenclosure_manufacturer( const char *buf
, UINT len
)
4024 WCHAR
*ret
= get_systemenclosure_string( 1, buf
, len
);
4025 if (!ret
) return wcsdup( L
"Wine" );
4029 static int get_systemenclosure_lockpresent( const char *buf
, UINT len
)
4031 const struct smbios_header
*hdr
;
4032 const struct smbios_chassis
*chassis
;
4034 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) return 0;
4036 chassis
= (const struct smbios_chassis
*)hdr
;
4037 return (chassis
->type
& 0x80) ? -1 : 0;
4040 static struct array
*dup_array( const struct array
*src
)
4043 if (!(dst
= malloc( sizeof(*dst
) ))) return NULL
;
4044 if (!(dst
->ptr
= malloc( src
->count
* src
->elem_size
)))
4049 memcpy( dst
->ptr
, src
->ptr
, src
->count
* src
->elem_size
);
4050 dst
->elem_size
= src
->elem_size
;
4051 dst
->count
= src
->count
;
4055 static struct array
*get_systemenclosure_chassistypes( const char *buf
, UINT len
)
4057 const struct smbios_header
*hdr
;
4058 const struct smbios_chassis
*chassis
;
4059 struct array
*ret
= NULL
;
4062 if (!(hdr
= find_smbios_entry( SMBIOS_TYPE_CHASSIS
, buf
, len
)) || hdr
->length
< sizeof(*chassis
)) goto done
;
4063 chassis
= (const struct smbios_chassis
*)hdr
;
4065 if (!(ret
= malloc( sizeof(*ret
) ))) goto done
;
4066 if (!(types
= malloc( sizeof(*types
) )))
4071 types
[0] = chassis
->type
& ~0x80;
4073 ret
->elem_size
= sizeof(*types
);
4078 if (!ret
) ret
= dup_array( &systemenclosure_chassistypes_array
);
4082 static enum fill_status
fill_systemenclosure( struct table
*table
, const struct expr
*cond
)
4084 struct record_systemenclosure
*rec
;
4085 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4089 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4091 len
= GetSystemFirmwareTable( RSMB
, 0, NULL
, 0 );
4092 if (!(buf
= malloc( len
))) return FILL_STATUS_FAILED
;
4093 GetSystemFirmwareTable( RSMB
, 0, buf
, len
);
4095 rec
= (struct record_systemenclosure
*)table
->data
;
4096 rec
->caption
= L
"System Enclosure";
4097 rec
->chassistypes
= get_systemenclosure_chassistypes( buf
, len
);
4098 rec
->description
= L
"System Enclosure";
4099 rec
->lockpresent
= get_systemenclosure_lockpresent( buf
, len
);
4100 rec
->manufacturer
= get_systemenclosure_manufacturer( buf
, len
);
4101 rec
->name
= L
"System Enclosure";
4102 rec
->tag
= L
"System Enclosure 0";
4103 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4108 TRACE("created %u rows\n", row
);
4109 table
->num_rows
= row
;
4113 static WCHAR
*get_videocontroller_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
4115 static const WCHAR fmtW
[] = L
"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X\\0&DEADBEEF&0&DEAD";
4116 UINT len
= sizeof(fmtW
) + 2;
4119 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4120 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
4124 #define HW_VENDOR_AMD 0x1002
4125 #define HW_VENDOR_NVIDIA 0x10de
4126 #define HW_VENDOR_VMWARE 0x15ad
4127 #define HW_VENDOR_INTEL 0x8086
4129 static const WCHAR
*get_videocontroller_installeddriver( UINT vendorid
)
4131 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */
4133 if (vendorid
== HW_VENDOR_AMD
) return L
"aticfx32.dll";
4134 else if (vendorid
== HW_VENDOR_NVIDIA
) return L
"nvd3dum.dll";
4135 else if (vendorid
== HW_VENDOR_INTEL
) return L
"igdudim32.dll";
4139 static BOOL
get_dxgi_adapter_desc( DXGI_ADAPTER_DESC
*desc
)
4141 IDXGIFactory
*factory
;
4142 IDXGIAdapter
*adapter
;
4145 memset( desc
, 0, sizeof(*desc
) );
4146 hr
= CreateDXGIFactory( &IID_IDXGIFactory
, (void **)&factory
);
4147 if (FAILED( hr
)) return FALSE
;
4149 hr
= IDXGIFactory_EnumAdapters( factory
, 0, &adapter
);
4152 IDXGIFactory_Release( factory
);
4156 hr
= IDXGIAdapter_GetDesc( adapter
, desc
);
4157 IDXGIAdapter_Release( adapter
);
4158 IDXGIFactory_Release( factory
);
4159 return SUCCEEDED( hr
);
4162 static enum fill_status
fill_videocontroller( struct table
*table
, const struct expr
*cond
)
4164 struct record_videocontroller
*rec
;
4165 DXGI_ADAPTER_DESC desc
;
4166 UINT row
= 0, hres
= 1024, vres
= 768, vidmem
= 512 * 1024 * 1024;
4167 const WCHAR
*name
= L
"VideoController1";
4168 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4171 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4173 if (get_dxgi_adapter_desc( &desc
))
4175 if (desc
.DedicatedVideoMemory
> UINT_MAX
) vidmem
= 0xfff00000;
4176 else vidmem
= desc
.DedicatedVideoMemory
;
4177 name
= desc
.Description
;
4180 rec
= (struct record_videocontroller
*)table
->data
;
4181 rec
->adapter_compatibility
= L
"(Standard display types)";
4182 rec
->adapter_dactype
= L
"Integrated RAMDAC";
4183 rec
->adapter_ram
= vidmem
;
4184 rec
->availability
= 3; /* Running or Full Power */
4185 rec
->config_errorcode
= 0; /* no error */
4186 rec
->caption
= wcsdup( name
);
4187 rec
->current_bitsperpixel
= get_bitsperpixel( &hres
, &vres
);
4188 rec
->current_horizontalres
= hres
;
4189 rec
->current_refreshrate
= 0; /* default refresh rate */
4190 rec
->current_scanmode
= 2; /* Unknown */
4191 rec
->current_verticalres
= vres
;
4192 rec
->description
= wcsdup( name
);
4193 rec
->device_id
= L
"VideoController1";
4194 rec
->driverdate
= L
"20220118000000.000000-000";
4195 rec
->driverversion
= L
"30.0.14023.3004";
4196 rec
->installeddriver
= get_videocontroller_installeddriver( desc
.VendorId
);
4197 rec
->name
= wcsdup( name
);
4198 rec
->pnpdevice_id
= get_videocontroller_pnpdeviceid( &desc
);
4199 rec
->status
= L
"OK";
4200 rec
->videoarchitecture
= 2; /* Unknown */
4201 rec
->videomemorytype
= 2; /* Unknown */
4202 swprintf( mode
, ARRAY_SIZE( mode
), L
"%u x %u x %I64u colors", hres
, vres
, (UINT64
)1 << rec
->current_bitsperpixel
);
4203 rec
->videomodedescription
= wcsdup( mode
);
4204 rec
->videoprocessor
= wcsdup( name
);
4205 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4208 TRACE("created %u rows\n", row
);
4209 table
->num_rows
= row
;
4213 static WCHAR
*get_volume_driveletter( const WCHAR
*volume
)
4218 if (!GetVolumePathNamesForVolumeNameW( volume
, NULL
, 0, &len
) && GetLastError() != ERROR_MORE_DATA
) return NULL
;
4219 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4220 if (!GetVolumePathNamesForVolumeNameW( volume
, ret
, len
, &len
) || !wcschr( ret
, ':' ))
4225 wcschr( ret
, ':' )[1] = 0;
4229 static enum fill_status
fill_volume( struct table
*table
, const struct expr
*cond
)
4231 struct record_volume
*rec
;
4232 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4233 UINT row
= 0, offset
= 0;
4234 WCHAR path
[MAX_PATH
];
4237 if (!resize_table( table
, 2, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4239 handle
= FindFirstVolumeW( path
, ARRAY_SIZE(path
) );
4240 while (handle
!= INVALID_HANDLE_VALUE
)
4242 if (!resize_table( table
, row
+ 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4244 rec
= (struct record_volume
*)(table
->data
+ offset
);
4245 rec
->deviceid
= wcsdup( path
);
4246 rec
->driveletter
= get_volume_driveletter( path
);
4248 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4251 offset
+= sizeof(*rec
);
4255 if (!FindNextVolumeW( handle
, path
, ARRAY_SIZE(path
) ))
4257 FindVolumeClose( handle
);
4258 handle
= INVALID_HANDLE_VALUE
;
4262 TRACE("created %u rows\n", row
);
4263 table
->num_rows
= row
;
4267 static WCHAR
*get_sounddevice_pnpdeviceid( DXGI_ADAPTER_DESC
*desc
)
4269 static const WCHAR fmtW
[] = L
"HDAUDIO\\FUNC_01&VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%04X\\0&DEADBEEF&0&DEAD";
4270 UINT len
= sizeof(fmtW
) + 2;
4273 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
4274 swprintf( ret
, len
, fmtW
, desc
->VendorId
, desc
->DeviceId
, desc
->SubSysId
, desc
->Revision
);
4278 static enum fill_status
fill_sounddevice( struct table
*table
, const struct expr
*cond
)
4280 struct record_sounddevice
*rec
;
4281 DXGI_ADAPTER_DESC desc
;
4283 enum fill_status status
= FILL_STATUS_UNFILTERED
;
4285 if (!resize_table( table
, 1, sizeof(*rec
) )) return FILL_STATUS_FAILED
;
4287 get_dxgi_adapter_desc( &desc
);
4289 rec
= (struct record_sounddevice
*)table
->data
;
4290 rec
->deviceid
= get_sounddevice_pnpdeviceid( &desc
);
4291 rec
->manufacturer
= L
"The Wine Project";
4292 rec
->name
= L
"Wine Audio Device";
4293 rec
->pnpdeviceid
= get_sounddevice_pnpdeviceid( &desc
);
4294 rec
->productname
= L
"Wine Audio Device";
4295 rec
->status
= L
"OK";
4296 rec
->statusinfo
= 3;
4297 if (!match_row( table
, row
, cond
, &status
)) free_row_values( table
, row
);
4300 TRACE("created %u rows\n", row
);
4301 table
->num_rows
= row
;
4305 #define C(c) sizeof(c)/sizeof(c[0]), c
4306 #define D(d) sizeof(d)/sizeof(d[0]), 0, (BYTE *)d
4307 static struct table cimv2_builtin_classes
[] =
4309 { L
"__ASSOCIATORS", C(col_associator
), D(data_associator
) },
4310 { L
"__PARAMETERS", C(col_param
), D(data_param
) },
4311 { L
"__QUALIFIERS", C(col_qualifier
), D(data_qualifier
) },
4312 { L
"__SystemSecurity", C(col_systemsecurity
), D(data_systemsecurity
) },
4313 { L
"CIM_DataFile", C(col_datafile
), 0, 0, NULL
, fill_datafile
},
4314 { L
"CIM_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
4315 { L
"CIM_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4316 { L
"SoftwareLicensingProduct", C(col_softwarelicensingproduct
), D(data_softwarelicensingproduct
) },
4317 { L
"StdRegProv", C(col_stdregprov
), D(data_stdregprov
) },
4318 { L
"SystemRestore", C(col_sysrestore
), D(data_sysrestore
) },
4319 { L
"Win32_BIOS", C(col_bios
), 0, 0, NULL
, fill_bios
},
4320 { L
"Win32_BaseBoard", C(col_baseboard
), 0, 0, NULL
, fill_baseboard
},
4321 { L
"Win32_CDROMDrive", C(col_cdromdrive
), 0, 0, NULL
, fill_cdromdrive
},
4322 { L
"Win32_ComputerSystem", C(col_compsys
), 0, 0, NULL
, fill_compsys
},
4323 { L
"Win32_ComputerSystemProduct", C(col_compsysproduct
), 0, 0, NULL
, fill_compsysproduct
},
4324 { L
"Win32_DesktopMonitor", C(col_desktopmonitor
), 0, 0, NULL
, fill_desktopmonitor
},
4325 { L
"Win32_Directory", C(col_directory
), 0, 0, NULL
, fill_directory
},
4326 { L
"Win32_DiskDrive", C(col_diskdrive
), 0, 0, NULL
, fill_diskdrive
},
4327 { L
"Win32_DiskDriveToDiskPartition", C(col_diskdrivetodiskpartition
), 0, 0, NULL
, fill_diskdrivetodiskpartition
},
4328 { L
"Win32_DiskPartition", C(col_diskpartition
), 0, 0, NULL
, fill_diskpartition
},
4329 { L
"Win32_DisplayControllerConfiguration", C(col_displaycontrollerconfig
), 0, 0, NULL
, fill_displaycontrollerconfig
},
4330 { L
"Win32_IP4RouteTable", C(col_ip4routetable
), 0, 0, NULL
, fill_ip4routetable
},
4331 { L
"Win32_LogicalDisk", C(col_logicaldisk
), 0, 0, NULL
, fill_logicaldisk
},
4332 { L
"Win32_LogicalDiskToPartition", C(col_logicaldisktopartition
), 0, 0, NULL
, fill_logicaldisktopartition
},
4333 { L
"Win32_NetworkAdapter", C(col_networkadapter
), 0, 0, NULL
, fill_networkadapter
},
4334 { L
"Win32_NetworkAdapterConfiguration", C(col_networkadapterconfig
), 0, 0, NULL
, fill_networkadapterconfig
},
4335 { L
"Win32_OperatingSystem", C(col_operatingsystem
), 0, 0, NULL
, fill_operatingsystem
},
4336 { L
"Win32_PageFileUsage", C(col_pagefileusage
), D(data_pagefileusage
) },
4337 { L
"Win32_PhysicalMedia", C(col_physicalmedia
), D(data_physicalmedia
) },
4338 { L
"Win32_PhysicalMemory", C(col_physicalmemory
), 0, 0, NULL
, fill_physicalmemory
},
4339 { L
"Win32_PnPEntity", C(col_pnpentity
), 0, 0, NULL
, fill_pnpentity
},
4340 { L
"Win32_Printer", C(col_printer
), 0, 0, NULL
, fill_printer
},
4341 { L
"Win32_Process", C(col_process
), 0, 0, NULL
, fill_process
},
4342 { L
"Win32_Processor", C(col_processor
), 0, 0, NULL
, fill_processor
},
4343 { L
"Win32_QuickFixEngineering", C(col_quickfixengineering
), D(data_quickfixengineering
) },
4344 { L
"Win32_SID", C(col_sid
), 0, 0, NULL
, fill_sid
},
4345 { L
"Win32_Service", C(col_service
), 0, 0, NULL
, fill_service
},
4346 { L
"Win32_SoundDevice", C(col_sounddevice
), 0, 0, NULL
, fill_sounddevice
},
4347 { L
"Win32_SystemEnclosure", C(col_systemenclosure
), 0, 0, NULL
, fill_systemenclosure
},
4348 { L
"Win32_VideoController", C(col_videocontroller
), 0, 0, NULL
, fill_videocontroller
},
4349 { L
"Win32_Volume", C(col_volume
), 0, 0, NULL
, fill_volume
},
4350 { L
"Win32_WinSAT", C(col_winsat
), D(data_winsat
) },
4353 static struct table wmi_builtin_classes
[] =
4355 { L
"MSSMBios_RawSMBiosTables", C(col_rawsmbiostables
), D(data_rawsmbiostables
) },
4363 struct table
*classes
;
4364 unsigned int table_count
;
4366 builtin_namespaces
[WBEMPROX_NAMESPACE_LAST
] =
4368 {L
"cimv2", cimv2_builtin_classes
, ARRAY_SIZE(cimv2_builtin_classes
)},
4369 {L
"Microsoft\\Windows\\Storage", NULL
, 0},
4370 {L
"wmi", wmi_builtin_classes
, ARRAY_SIZE(wmi_builtin_classes
)},
4373 void init_table_list( void )
4375 static struct list tables
[WBEMPROX_NAMESPACE_LAST
];
4378 for (ns
= 0; ns
< ARRAY_SIZE(builtin_namespaces
); ns
++)
4380 list_init( &tables
[ns
] );
4381 for (i
= 0; i
< builtin_namespaces
[ns
].table_count
; i
++)
4382 list_add_tail( &tables
[ns
], &builtin_namespaces
[ns
].classes
[i
].entry
);
4383 table_list
[ns
] = &tables
[ns
];
4387 enum wbm_namespace
get_namespace_from_string( const WCHAR
*namespace )
4391 if (!wcsicmp( namespace, L
"default" )) return WBEMPROX_NAMESPACE_CIMV2
;
4393 for (i
= 0; i
< WBEMPROX_NAMESPACE_LAST
; ++i
)
4394 if (!wcsicmp( namespace, builtin_namespaces
[i
].name
)) return i
;
4396 return WBEMPROX_NAMESPACE_LAST
;