1 /* 2 * Copyright 2012 Hans Leidekker for CodeWeavers 3 * 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. 8 * 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. 13 * 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 17 */ 18 19 #define COBJMACROS 20 #define NONAMELESSUNION 21 #define NONAMELESSSTRUCT 22 23 #include "config.h" 24 #include <stdarg.h> 25 #include <fcntl.h> 26 #ifdef HAVE_UNISTD_H 27 # include <unistd.h> 28 #endif 29 #ifdef HAVE_ARPA_INET_H 30 # include <arpa/inet.h> 31 #endif 32 33 #include "ntstatus.h" 34 #define WIN32_NO_STATUS 35 #include "windef.h" 36 #include "winbase.h" 37 #ifdef __MINGW32__ 38 # include "winsock2.h" 39 # include "ws2tcpip.h" 40 # define WS_AF_INET AF_INET 41 # define WS_AF_UNSPEC AF_UNSPEC 42 # define WS_NI_MAXHOST NI_MAXHOST 43 # define WS_NI_NAMEREQD NI_NAMEREQD 44 #else 45 # define USE_WS_PREFIX 46 # include "winsock2.h" 47 # include "ws2tcpip.h" 48 #endif 49 #include "initguid.h" 50 #include "wbemcli.h" 51 #include "wbemprov.h" 52 #include "iphlpapi.h" 53 #include "netioapi.h" 54 #include "tlhelp32.h" 55 #ifndef __REACTOS__ 56 #include "d3d10.h" 57 #endif 58 #include "winternl.h" 59 #include "winioctl.h" 60 #include "winsvc.h" 61 #include "winver.h" 62 #include "sddl.h" 63 #include "ntsecapi.h" 64 #ifdef __REACTOS__ 65 #include <wingdi.h> 66 #include <winreg.h> 67 #endif 68 #include "winspool.h" 69 #include "setupapi.h" 70 71 #include "wine/debug.h" 72 #include "wbemprox_private.h" 73 74 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); 75 76 static const WCHAR class_baseboardW[] = 77 {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0}; 78 static const WCHAR class_biosW[] = 79 {'W','i','n','3','2','_','B','I','O','S',0}; 80 static const WCHAR class_cdromdriveW[] = 81 {'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0}; 82 static const WCHAR class_compsysW[] = 83 {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0}; 84 static const WCHAR class_compsysproductW[] = 85 {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m','P','r','o','d','u','c','t',0}; 86 static const WCHAR class_datafileW[] = 87 {'C','I','M','_','D','a','t','a','F','i','l','e',0}; 88 static const WCHAR class_desktopmonitorW[] = 89 {'W','i','n','3','2','_','D','e','s','k','t','o','p','M','o','n','i','t','o','r',0}; 90 static const WCHAR class_directoryW[] = 91 {'W','i','n','3','2','_','D','i','r','e','c','t','o','r','y',0}; 92 static const WCHAR class_diskdriveW[] = 93 {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0}; 94 static const WCHAR class_diskpartitionW[] = 95 {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0}; 96 static const WCHAR class_ip4routetableW[] = 97 {'W','i','n','3','2','_','I','P','4','R','o','u','t','e','T','a','b','l','e',0}; 98 static const WCHAR class_logicaldiskW[] = 99 {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0}; 100 static const WCHAR class_logicaldisk2W[] = 101 {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0}; 102 static const WCHAR class_networkadapterW[] = 103 {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0}; 104 static const WCHAR class_networkadapterconfigW[] = 105 {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r', 106 'C','o','n','f','i','g','u','r','a','t','i','o','n',0}; 107 static const WCHAR class_osW[] = 108 {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; 109 static const WCHAR class_paramsW[] = 110 {'_','_','P','A','R','A','M','E','T','E','R','S',0}; 111 static const WCHAR class_physicalmediaW[] = 112 {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0}; 113 static const WCHAR class_physicalmemoryW[] = 114 {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; 115 static const WCHAR class_pnpentityW[] = 116 {'W','i','n','3','2','_','P','n','P','E','n','t','i','t','y',0}; 117 static const WCHAR class_printerW[] = 118 {'W','i','n','3','2','_','P','r','i','n','t','e','r',0}; 119 static const WCHAR class_process_getowner_outW[] = 120 {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W', 121 'N','E','R','_','O','U','T',0}; 122 static const WCHAR class_processorW[] = 123 {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; 124 static const WCHAR class_processor2W[] = 125 {'C','I','M','_','P','r','o','c','e','s','s','o','r',0}; 126 static const WCHAR class_qualifiersW[] = 127 {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; 128 static const WCHAR class_sidW[] = 129 {'W','i','n','3','2','_','S','I','D',0}; 130 static const WCHAR class_sounddeviceW[] = 131 {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0}; 132 static const WCHAR class_systemenclosureW[] = 133 {'W','i','n','3','2','_','S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0}; 134 #ifndef __REACTOS__ 135 static const WCHAR class_videocontrollerW[] = 136 {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0}; 137 #endif 138 139 static const WCHAR prop_accountnameW[] = 140 {'A','c','c','o','u','n','t','N','a','m','e',0}; 141 static const WCHAR prop_acceptpauseW[] = 142 {'A','c','c','e','p','t','P','a','u','s','e',0}; 143 static const WCHAR prop_acceptstopW[] = 144 {'A','c','c','e','p','t','S','t','o','p',0}; 145 static const WCHAR prop_accessmaskW[] = 146 {'A','c','c','e','s','s','M','a','s','k',0}; 147 #ifndef __REACTOS__ 148 static const WCHAR prop_adapterdactypeW[] = 149 {'A','d','a','p','t','e','r','D','A','C','T','y','p','e',0}; 150 static const WCHAR prop_adapterramW[] = 151 {'A','d','a','p','t','e','r','R','A','M',0}; 152 #endif 153 static const WCHAR prop_adaptertypeW[] = 154 {'A','d','a','p','t','e','r','T','y','p','e',0}; 155 static const WCHAR prop_addresswidthW[] = 156 {'A','d','d','r','e','s','s','W','i','d','t','h',0}; 157 static const WCHAR prop_architectureW[] = 158 {'A','r','c','h','i','t','e','c','t','u','r','e',0}; 159 static const WCHAR prop_attributesW[] = 160 {'A','t','t','r','i','b','u','t','e','s',0}; 161 #ifndef __REACTOS__ 162 static const WCHAR prop_availabilityW[] = 163 {'A','v','a','i','l','a','b','i','l','i','t','y',0}; 164 #endif 165 static const WCHAR prop_binaryrepresentationW[] = 166 {'B','i','n','a','r','y','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0}; 167 static const WCHAR prop_bootableW[] = 168 {'B','o','o','t','a','b','l','e',0}; 169 static const WCHAR prop_bootpartitionW[] = 170 {'B','o','o','t','P','a','r','t','i','t','i','o','n',0}; 171 static const WCHAR prop_buildnumberW[] = 172 {'B','u','i','l','d','N','u','m','b','e','r',0}; 173 static const WCHAR prop_capacityW[] = 174 {'C','a','p','a','c','i','t','y',0}; 175 static const WCHAR prop_captionW[] = 176 {'C','a','p','t','i','o','n',0}; 177 static const WCHAR prop_chassistypesW[] = 178 {'C','h','a','s','s','i','s','T','y','p','e','s',0}; 179 static const WCHAR prop_classW[] = 180 {'C','l','a','s','s',0}; 181 static const WCHAR prop_codesetW[] = 182 {'C','o','d','e','S','e','t',0}; 183 static const WCHAR prop_commandlineW[] = 184 {'C','o','m','m','a','n','d','L','i','n','e',0}; 185 static const WCHAR prop_configmanagererrorcodeW[] = 186 {'C','o','n','f','i','g','M','a','n','a','g','e','r','E','r','r','o','r','C','o','d','e',0}; 187 static const WCHAR prop_countrycodeW[] = 188 {'C','o','u','n','t','r','y','C','o','d','e',0}; 189 static const WCHAR prop_cpustatusW[] = 190 {'C','p','u','S','t','a','t','u','s',0}; 191 static const WCHAR prop_csdversionW[] = 192 {'C','S','D','V','e','r','s','i','o','n',0}; 193 #ifndef __REACTOS__ 194 static const WCHAR prop_currentbitsperpixelW[] = 195 {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0}; 196 #endif 197 static const WCHAR prop_currentclockspeedW[] = 198 {'C','u','r','r','e','n','t','C','l','o','c','k','S','p','e','e','d',0}; 199 #ifndef __REACTOS__ 200 static const WCHAR prop_currenthorizontalresW[] = 201 {'C','u','r','r','e','n','t','H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0}; 202 static const WCHAR prop_currentrefreshrateW[] = 203 {'C','u','r','r','e','n','t','R','e','f','r','e','s','h','R','a','t','e',0}; 204 static const WCHAR prop_currentscanmodeW[] = 205 {'C','u','r','r','e','n','t','S','c','a','n','M','o','d','e',0}; 206 static const WCHAR prop_currentverticalresW[] = 207 {'C','u','r','r','e','n','t','V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0}; 208 #endif 209 static const WCHAR prop_datawidthW[] = 210 {'D','a','t','a','W','i','d','t','h',0}; 211 static const WCHAR prop_defaultipgatewayW[] = 212 {'D','e','f','a','u','l','t','I','P','G','a','t','e','w','a','y',0}; 213 static const WCHAR prop_defaultvalueW[] = 214 {'D','e','f','a','u','l','t','V','a','l','u','e',0}; 215 static const WCHAR prop_descriptionW[] = 216 {'D','e','s','c','r','i','p','t','i','o','n',0}; 217 static const WCHAR prop_destinationW[] = 218 {'D','e','s','t','i','n','a','t','i','o','n',0}; 219 static const WCHAR prop_deviceidW[] = 220 {'D','e','v','i','c','e','I','d',0}; 221 static const WCHAR prop_dhcpenabledW[] = 222 {'D','H','C','P','E','n','a','b','l','e','d',0}; 223 static const WCHAR prop_directionW[] = 224 {'D','i','r','e','c','t','i','o','n',0}; 225 static const WCHAR prop_displaynameW[] = 226 {'D','i','s','p','l','a','y','N','a','m','e',0}; 227 static const WCHAR prop_diskindexW[] = 228 {'D','i','s','k','I','n','d','e','x',0}; 229 static const WCHAR prop_dnshostnameW[] = 230 {'D','N','S','H','o','s','t','N','a','m','e',0}; 231 static const WCHAR prop_dnsserversearchorderW[] = 232 {'D','N','S','S','e','r','v','e','r','S','e','a','r','c','h','O','r','d','e','r',0}; 233 static const WCHAR prop_domainW[] = 234 {'D','o','m','a','i','n',0}; 235 static const WCHAR prop_domainroleW[] = 236 {'D','o','m','a','i','n','R','o','l','e',0}; 237 static const WCHAR prop_driveW[] = 238 {'D','r','i','v','e',0}; 239 static const WCHAR prop_driverdateW[] = 240 {'D','r','i','v','e','r','D','a','t','e',0}; 241 static const WCHAR prop_drivernameW[] = 242 {'D','r','i','v','e','r','N','a','m','e',0}; 243 #ifndef __REACTOS__ 244 static const WCHAR prop_driverversionW[] = 245 {'D','r','i','v','e','r','V','e','r','s','i','o','n',0}; 246 #endif 247 static const WCHAR prop_drivetypeW[] = 248 {'D','r','i','v','e','T','y','p','e',0}; 249 static const WCHAR prop_familyW[] = 250 {'F','a','m','i','l','y',0}; 251 static const WCHAR prop_filesystemW[] = 252 {'F','i','l','e','S','y','s','t','e','m',0}; 253 static const WCHAR prop_flavorW[] = 254 {'F','l','a','v','o','r',0}; 255 static const WCHAR prop_freespaceW[] = 256 {'F','r','e','e','S','p','a','c','e',0}; 257 static const WCHAR prop_freephysicalmemoryW[] = 258 {'F','r','e','e','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; 259 static const WCHAR prop_handleW[] = 260 {'H','a','n','d','l','e',0}; 261 static const WCHAR prop_horizontalresolutionW[] = 262 {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0}; 263 static const WCHAR prop_idW[] = 264 {'I','D',0}; 265 static const WCHAR prop_identificationcodeW[] = 266 {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0}; 267 static const WCHAR prop_identifyingnumberW[] = 268 {'I','d','e','n','t','i','f','y','i','n','g','N','u','m','b','e','r',0}; 269 static const WCHAR prop_indexW[] = 270 {'I','n','d','e','x',0}; 271 static const WCHAR prop_installdateW[] = 272 {'I','n','s','t','a','l','l','D','a','t','e',0}; 273 static const WCHAR prop_installeddisplaydriversW[]= 274 {'I','n','s','t','a','l','l','e','d','D','i','s','p','l','a','y','D','r','i','v','e','r','s',0}; 275 static const WCHAR prop_interfaceindexW[] = 276 {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0}; 277 static const WCHAR prop_interfacetypeW[] = 278 {'I','n','t','e','r','f','a','c','e','T','y','p','e',0}; 279 static const WCHAR prop_intvalueW[] = 280 {'I','n','t','e','g','e','r','V','a','l','u','e',0}; 281 static const WCHAR prop_ipaddressW[] = 282 {'I','P','A','d','d','r','e','s','s',0}; 283 static const WCHAR prop_ipconnectionmetricW[] = 284 {'I','P','C','o','n','n','e','c','t','i','o','n','M','e','t','r','i','c',0}; 285 static const WCHAR prop_ipenabledW[] = 286 {'I','P','E','n','a','b','l','e','d',0}; 287 static const WCHAR prop_ipsubnet[] = 288 {'I','P','S','u','b','n','e','t',0}; 289 static const WCHAR prop_lastbootuptimeW[] = 290 {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0}; 291 static const WCHAR prop_levelW[] = 292 {'L','e','v','e','l',0}; 293 static const WCHAR prop_localW[] = 294 {'L','o','c','a','l',0}; 295 static const WCHAR prop_localdatetimeW[] = 296 {'L','o','c','a','l','D','a','t','e','T','i','m','e',0}; 297 static const WCHAR prop_localeW[] = 298 {'L','o','c','a','l','e',0}; 299 static const WCHAR prop_locationW[] = 300 {'L','o','c','a','t','i','o','n',0}; 301 static const WCHAR prop_lockpresentW[] = 302 {'L','o','c','k','P','r','e','s','e','n','t',0}; 303 static const WCHAR prop_macaddressW[] = 304 {'M','A','C','A','d','d','r','e','s','s',0}; 305 static const WCHAR prop_manufacturerW[] = 306 {'M','a','n','u','f','a','c','t','u','r','e','r',0}; 307 static const WCHAR prop_maxclockspeedW[] = 308 {'M','a','x','C','l','o','c','k','S','p','e','e','d',0}; 309 static const WCHAR prop_mediatypeW[] = 310 {'M','e','d','i','a','T','y','p','e',0}; 311 static const WCHAR prop_memberW[] = 312 {'M','e','m','b','e','r',0}; 313 static const WCHAR prop_memorytypeW[] = 314 {'M','e','m','o','r','y','T','y','p','e',0}; 315 static const WCHAR prop_methodW[] = 316 {'M','e','t','h','o','d',0}; 317 static const WCHAR prop_modelW[] = 318 {'M','o','d','e','l',0}; 319 static const WCHAR prop_netconnectionstatusW[] = 320 {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0}; 321 static const WCHAR prop_networkW[] = 322 {'N','e','t','w','o','r','k',0}; 323 static const WCHAR prop_nexthopW[] = 324 {'N','e','x','t','H','o','p',0}; 325 static const WCHAR prop_numcoresW[] = 326 {'N','u','m','b','e','r','O','f','C','o','r','e','s',0}; 327 static const WCHAR prop_numlogicalprocessorsW[] = 328 {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0}; 329 static const WCHAR prop_numprocessorsW[] = 330 {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0}; 331 static const WCHAR prop_osarchitectureW[] = 332 {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0}; 333 static const WCHAR prop_oslanguageW[] = 334 {'O','S','L','a','n','g','u','a','g','e',0}; 335 static const WCHAR prop_osproductsuiteW[] = 336 {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0}; 337 static const WCHAR prop_ostypeW[] = 338 {'O','S','T','y','p','e',0}; 339 static const WCHAR prop_parameterW[] = 340 {'P','a','r','a','m','e','t','e','r',0}; 341 static const WCHAR prop_physicaladapterW[] = 342 {'P','h','y','s','i','c','a','l','A','d','a','p','t','e','r',0}; 343 static const WCHAR prop_pixelsperxlogicalinchW[] = 344 {'P','i','x','e','l','s','P','e','r','X','L','o','g','i','c','a','l','I','n','c','h',0}; 345 static const WCHAR prop_pnpdeviceidW[] = 346 {'P','N','P','D','e','v','i','c','e','I','D',0}; 347 static const WCHAR prop_portnameW[] = 348 {'P','o','r','t','N','a','m','e',0}; 349 static const WCHAR prop_pprocessidW[] = 350 {'P','a','r','e','n','t','P','r','o','c','e','s','s','I','D',0}; 351 static const WCHAR prop_primaryW[] = 352 {'P','r','i','m','a','r','y',0}; 353 static const WCHAR prop_processidW[] = 354 {'P','r','o','c','e','s','s','I','D',0}; 355 static const WCHAR prop_processoridW[] = 356 {'P','r','o','c','e','s','s','o','r','I','d',0}; 357 static const WCHAR prop_processortypeW[] = 358 {'P','r','o','c','e','s','s','o','r','T','y','p','e',0}; 359 static const WCHAR prop_productW[] = 360 {'P','r','o','d','u','c','t',0}; 361 static const WCHAR prop_productnameW[] = 362 {'P','r','o','d','u','c','t','N','a','m','e',0}; 363 static const WCHAR prop_referenceddomainnameW[] = 364 {'R','e','f','e','r','e','n','c','e','d','D','o','m','a','i','n','N','a','m','e',0}; 365 static const WCHAR prop_releasedateW[] = 366 {'R','e','l','e','a','s','e','D','a','t','e',0}; 367 static const WCHAR prop_revisionW[] = 368 {'R','e','v','i','s','i','o','n',0}; 369 static const WCHAR prop_serialnumberW[] = 370 {'S','e','r','i','a','l','N','u','m','b','e','r',0}; 371 static const WCHAR prop_servicepackmajorW[] = 372 {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0}; 373 static const WCHAR prop_servicepackminorW[] = 374 {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0}; 375 static const WCHAR prop_servicetypeW[] = 376 {'S','e','r','v','i','c','e','T','y','p','e',0}; 377 static const WCHAR prop_settingidW[] = 378 {'S','e','t','t','i','n','g','I','D',0}; 379 static const WCHAR prop_skunumberW[] = 380 {'S','K','U','N','u','m','b','e','r',0}; 381 static const WCHAR prop_smbiosbiosversionW[] = 382 {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0}; 383 static const WCHAR prop_smbiosmajorversionW[] = 384 {'S','M','B','I','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0}; 385 static const WCHAR prop_smbiosminorversionW[] = 386 {'S','M','B','I','O','S','M','i','n','o','r','V','e','r','s','i','o','n',0}; 387 static const WCHAR prop_startmodeW[] = 388 {'S','t','a','r','t','M','o','d','e',0}; 389 static const WCHAR prop_sidW[] = 390 {'S','I','D',0}; 391 static const WCHAR prop_sidlengthW[] = 392 {'S','i','d','L','e','n','g','t','h',0}; 393 static const WCHAR prop_sizeW[] = 394 {'S','i','z','e',0}; 395 static const WCHAR prop_speedW[] = 396 {'S','p','e','e','d',0}; 397 static const WCHAR prop_startingoffsetW[] = 398 {'S','t','a','r','t','i','n','g','O','f','f','s','e','t',0}; 399 static const WCHAR prop_stateW[] = 400 {'S','t','a','t','e',0}; 401 static const WCHAR prop_statusW[] = 402 {'S','t','a','t','u','s',0}; 403 static const WCHAR prop_statusinfoW[] = 404 {'S','t','a','t','u','s','I','n','f','o',0}; 405 static const WCHAR prop_strvalueW[] = 406 {'S','t','r','i','n','g','V','a','l','u','e',0}; 407 static const WCHAR prop_suitemaskW[] = 408 {'S','u','i','t','e','M','a','s','k',0}; 409 static const WCHAR prop_systemdirectoryW[] = 410 {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0}; 411 static const WCHAR prop_systemnameW[] = 412 {'S','y','s','t','e','m','N','a','m','e',0}; 413 static const WCHAR prop_tagW[] = 414 {'T','a','g',0}; 415 static const WCHAR prop_threadcountW[] = 416 {'T','h','r','e','a','d','C','o','u','n','t',0}; 417 static const WCHAR prop_totalphysicalmemoryW[] = 418 {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; 419 static const WCHAR prop_totalvirtualmemorysizeW[] = 420 {'T','o','t','a','l','V','i','r','t','u','a','l','M','e','m','o','r','y','S','i','z','e',0}; 421 static const WCHAR prop_totalvisiblememorysizeW[] = 422 {'T','o','t','a','l','V','i','s','i','b','l','e','M','e','m','o','r','y','S','i','z','e',0}; 423 static const WCHAR prop_typeW[] = 424 {'T','y','p','e',0}; 425 static const WCHAR prop_uniqueidW[] = 426 {'U','n','i','q','u','e','I','d',0}; 427 static const WCHAR prop_usernameW[] = 428 {'U','s','e','r','N','a','m','e',0}; 429 static const WCHAR prop_uuidW[] = 430 {'U','U','I','D',0}; 431 static const WCHAR prop_varianttypeW[] = 432 {'V','a','r','i','a','n','t','T','y','p','e',0}; 433 static const WCHAR prop_vendorW[] = 434 {'V','e','n','d','o','r',0}; 435 static const WCHAR prop_versionW[] = 436 {'V','e','r','s','i','o','n',0}; 437 #ifndef __REACTOS__ 438 static const WCHAR prop_videoarchitectureW[] = 439 {'V','i','d','e','o','A','r','c','h','i','t','e','c','t','u','r','e',0}; 440 static const WCHAR prop_videomemorytypeW[] = 441 {'V','i','d','e','o','M','e','m','o','r','y','T','y','p','e',0}; 442 static const WCHAR prop_videomodedescriptionW[] = 443 {'V','i','d','e','o','M','o','d','e','D','e','s','c','r','i','p','t','i','o','n',0}; 444 static const WCHAR prop_videoprocessorW[] = 445 {'V','i','d','e','o','P','r','o','c','e','s','s','o','r',0}; 446 #endif /* !__REACTOS__ */ 447 static const WCHAR prop_volumenameW[] = 448 {'V','o','l','u','m','e','N','a','m','e',0}; 449 static const WCHAR prop_volumeserialnumberW[] = 450 {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0}; 451 static const WCHAR prop_workingsetsizeW[] = 452 {'W','o','r','k','i','n','g','S','e','t','S','i','z','e',0}; 453 454 /* column definitions must be kept in sync with record structures below */ 455 static const struct column col_baseboard[] = 456 { 457 { prop_manufacturerW, CIM_STRING }, 458 { prop_modelW, CIM_STRING }, 459 { prop_nameW, CIM_STRING }, 460 { prop_productW, CIM_STRING }, 461 { prop_serialnumberW, CIM_STRING }, 462 { prop_tagW, CIM_STRING|COL_FLAG_KEY }, 463 { prop_versionW, CIM_STRING } 464 }; 465 static const struct column col_bios[] = 466 { 467 { prop_descriptionW, CIM_STRING }, 468 { prop_identificationcodeW, CIM_STRING }, 469 { prop_manufacturerW, CIM_STRING }, 470 { prop_nameW, CIM_STRING }, 471 { prop_releasedateW, CIM_DATETIME }, 472 { prop_serialnumberW, CIM_STRING }, 473 { prop_smbiosbiosversionW, CIM_STRING }, 474 { prop_smbiosmajorversionW, CIM_UINT16, VT_I4 }, 475 { prop_smbiosminorversionW, CIM_UINT16, VT_I4 }, 476 { prop_versionW, CIM_STRING|COL_FLAG_KEY } 477 }; 478 static const struct column col_cdromdrive[] = 479 { 480 { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, 481 { prop_driveW, CIM_STRING|COL_FLAG_DYNAMIC }, 482 { prop_mediatypeW, CIM_STRING }, 483 { prop_nameW, CIM_STRING }, 484 { prop_pnpdeviceidW, CIM_STRING } 485 }; 486 static const struct column col_compsys[] = 487 { 488 { prop_descriptionW, CIM_STRING }, 489 { prop_domainW, CIM_STRING }, 490 { prop_domainroleW, CIM_UINT16, VT_I4 }, 491 { prop_manufacturerW, CIM_STRING }, 492 { prop_modelW, CIM_STRING }, 493 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 494 { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 }, 495 { prop_numprocessorsW, CIM_UINT32, VT_I4 }, 496 { prop_totalphysicalmemoryW, CIM_UINT64 }, 497 { prop_usernameW, CIM_STRING|COL_FLAG_DYNAMIC } 498 }; 499 static const struct column col_compsysproduct[] = 500 { 501 { prop_identifyingnumberW, CIM_STRING|COL_FLAG_KEY }, 502 { prop_nameW, CIM_STRING|COL_FLAG_KEY }, 503 { prop_skunumberW, CIM_STRING }, 504 { prop_uuidW, CIM_STRING|COL_FLAG_DYNAMIC }, 505 { prop_vendorW, CIM_STRING }, 506 { prop_versionW, CIM_STRING|COL_FLAG_KEY } 507 }; 508 static const struct column col_datafile[] = 509 { 510 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 511 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } 512 }; 513 static const struct column col_desktopmonitor[] = 514 { 515 { prop_pixelsperxlogicalinchW, CIM_UINT32 } 516 }; 517 static const struct column col_directory[] = 518 { 519 { prop_accessmaskW, CIM_UINT32 }, 520 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY } 521 }; 522 static const struct column col_diskdrive[] = 523 { 524 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 525 { prop_indexW, CIM_UINT32, VT_I4 }, 526 { prop_interfacetypeW, CIM_STRING }, 527 { prop_manufacturerW, CIM_STRING }, 528 { prop_mediatypeW, CIM_STRING }, 529 { prop_modelW, CIM_STRING }, 530 { prop_pnpdeviceidW, CIM_STRING }, 531 { prop_serialnumberW, CIM_STRING }, 532 { prop_sizeW, CIM_UINT64 } 533 }; 534 static const struct column col_diskpartition[] = 535 { 536 { prop_bootableW, CIM_BOOLEAN }, 537 { prop_bootpartitionW, CIM_BOOLEAN }, 538 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 539 { prop_diskindexW, CIM_UINT32, VT_I4 }, 540 { prop_indexW, CIM_UINT32, VT_I4 }, 541 { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, 542 { prop_sizeW, CIM_UINT64 }, 543 { prop_startingoffsetW, CIM_UINT64 }, 544 { prop_typeW, CIM_STRING|COL_FLAG_DYNAMIC } 545 }; 546 static const struct column col_ip4routetable[] = 547 { 548 { prop_destinationW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 549 { prop_interfaceindexW, CIM_SINT32|COL_FLAG_KEY }, 550 { prop_nexthopW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 551 }; 552 static const struct column col_logicaldisk[] = 553 { 554 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 555 { prop_drivetypeW, CIM_UINT32, VT_I4 }, 556 { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC }, 557 { prop_freespaceW, CIM_UINT64 }, 558 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 559 { prop_sizeW, CIM_UINT64 }, 560 { prop_volumenameW, CIM_STRING|COL_FLAG_DYNAMIC }, 561 { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC } 562 }; 563 static const struct column col_networkadapter[] = 564 { 565 { prop_adaptertypeW, CIM_STRING }, 566 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 567 { prop_indexW, CIM_UINT32, VT_I4 }, 568 { prop_interfaceindexW, CIM_UINT32, VT_I4 }, 569 { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC }, 570 { prop_manufacturerW, CIM_STRING }, 571 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 572 { prop_netconnectionstatusW, CIM_UINT16, VT_I4 }, 573 { prop_physicaladapterW, CIM_BOOLEAN }, 574 { prop_pnpdeviceidW, CIM_STRING }, 575 { prop_speedW, CIM_UINT64 } 576 }; 577 static const struct column col_networkadapterconfig[] = 578 { 579 { prop_defaultipgatewayW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, 580 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, 581 { prop_dhcpenabledW, CIM_BOOLEAN }, 582 { prop_dnshostnameW, CIM_STRING|COL_FLAG_DYNAMIC }, 583 { prop_dnsserversearchorderW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, 584 { prop_indexW, CIM_UINT32|COL_FLAG_KEY, VT_I4 }, 585 { prop_ipaddressW, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, 586 { prop_ipconnectionmetricW, CIM_UINT32, VT_I4 }, 587 { prop_ipenabledW, CIM_BOOLEAN }, 588 { prop_ipsubnet, CIM_STRING|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, 589 { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC }, 590 { prop_settingidW, CIM_STRING|COL_FLAG_DYNAMIC } 591 }; 592 static const struct column col_os[] = 593 { 594 { prop_buildnumberW, CIM_STRING|COL_FLAG_DYNAMIC }, 595 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, 596 { prop_codesetW, CIM_STRING|COL_FLAG_DYNAMIC }, 597 { prop_countrycodeW, CIM_STRING|COL_FLAG_DYNAMIC }, 598 { prop_csdversionW, CIM_STRING|COL_FLAG_DYNAMIC }, 599 { prop_freephysicalmemoryW, CIM_UINT64 }, 600 { prop_installdateW, CIM_DATETIME }, 601 { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, 602 { prop_localdatetimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, 603 { prop_localeW, CIM_STRING|COL_FLAG_DYNAMIC }, 604 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 605 { prop_osarchitectureW, CIM_STRING }, 606 { prop_oslanguageW, CIM_UINT32, VT_I4 }, 607 { prop_osproductsuiteW, CIM_UINT32, VT_I4 }, 608 { prop_ostypeW, CIM_UINT16, VT_I4 }, 609 { prop_primaryW, CIM_BOOLEAN }, 610 { prop_serialnumberW, CIM_STRING }, 611 { prop_servicepackmajorW, CIM_UINT16, VT_I4 }, 612 { prop_servicepackminorW, CIM_UINT16, VT_I4 }, 613 { prop_suitemaskW, CIM_UINT32, VT_I4 }, 614 { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC }, 615 { prop_totalvirtualmemorysizeW, CIM_UINT64 }, 616 { prop_totalvisiblememorysizeW, CIM_UINT64 }, 617 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } 618 }; 619 static const struct column col_param[] = 620 { 621 { prop_classW, CIM_STRING }, 622 { prop_methodW, CIM_STRING }, 623 { prop_directionW, CIM_SINT32 }, 624 { prop_parameterW, CIM_STRING }, 625 { prop_typeW, CIM_UINT32 }, 626 { prop_varianttypeW, CIM_UINT32 }, 627 { prop_defaultvalueW, CIM_UINT32 } 628 }; 629 static const struct column col_physicalmedia[] = 630 { 631 { prop_serialnumberW, CIM_STRING }, 632 { prop_tagW, CIM_STRING } 633 }; 634 static const struct column col_physicalmemory[] = 635 { 636 { prop_capacityW, CIM_UINT64 }, 637 { prop_memorytypeW, CIM_UINT16, VT_I4 } 638 }; 639 static const struct column col_pnpentity[] = 640 { 641 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, 642 }; 643 static const struct column col_printer[] = 644 { 645 { prop_attributesW, CIM_UINT32 }, 646 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 647 { prop_drivernameW, CIM_STRING|COL_FLAG_DYNAMIC }, 648 { prop_horizontalresolutionW, CIM_UINT32 }, 649 { prop_localW, CIM_BOOLEAN }, 650 { prop_locationW, CIM_STRING|COL_FLAG_DYNAMIC }, 651 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 652 { prop_networkW, CIM_BOOLEAN }, 653 { prop_portnameW, CIM_STRING|COL_FLAG_DYNAMIC }, 654 }; 655 static const struct column col_process[] = 656 { 657 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, 658 { prop_commandlineW, CIM_STRING|COL_FLAG_DYNAMIC }, 659 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, 660 { prop_handleW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 661 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 662 { prop_pprocessidW, CIM_UINT32, VT_I4 }, 663 { prop_processidW, CIM_UINT32, VT_I4 }, 664 { prop_threadcountW, CIM_UINT32, VT_I4 }, 665 { prop_workingsetsizeW, CIM_UINT64 }, 666 /* methods */ 667 { method_getownerW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } 668 }; 669 static const struct column col_processor[] = 670 { 671 { prop_addresswidthW, CIM_UINT16, VT_I4 }, 672 { prop_architectureW, CIM_UINT16, VT_I4 }, 673 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, 674 { prop_cpustatusW, CIM_UINT16 }, 675 { prop_currentclockspeedW, CIM_UINT32, VT_I4 }, 676 { prop_datawidthW, CIM_UINT16, VT_I4 }, 677 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, 678 { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 679 { prop_familyW, CIM_UINT16, VT_I4 }, 680 { prop_levelW, CIM_UINT16, VT_I4 }, 681 { prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC }, 682 { prop_maxclockspeedW, CIM_UINT32, VT_I4 }, 683 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 684 { prop_numcoresW, CIM_UINT32, VT_I4 }, 685 { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 }, 686 { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC }, 687 { prop_processortypeW, CIM_UINT16, VT_I4 }, 688 { prop_revisionW, CIM_UINT16, VT_I4 }, 689 { prop_uniqueidW, CIM_STRING }, 690 { prop_versionW, CIM_STRING|COL_FLAG_DYNAMIC } 691 }; 692 static const struct column col_qualifier[] = 693 { 694 { prop_classW, CIM_STRING }, 695 { prop_memberW, CIM_STRING }, 696 { prop_typeW, CIM_UINT32 }, 697 { prop_flavorW, CIM_SINT32 }, 698 { prop_nameW, CIM_STRING }, 699 { prop_intvalueW, CIM_SINT32 }, 700 { prop_strvalueW, CIM_STRING } 701 }; 702 static const struct column col_service[] = 703 { 704 { prop_acceptpauseW, CIM_BOOLEAN }, 705 { prop_acceptstopW, CIM_BOOLEAN }, 706 { prop_displaynameW, CIM_STRING|COL_FLAG_DYNAMIC }, 707 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 708 { prop_processidW, CIM_UINT32 }, 709 { prop_servicetypeW, CIM_STRING }, 710 { prop_startmodeW, CIM_STRING }, 711 { prop_stateW, CIM_STRING }, 712 { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC }, 713 /* methods */ 714 { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 715 { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 716 { method_startserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 717 { method_stopserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } 718 }; 719 static const struct column col_sid[] = 720 { 721 { prop_accountnameW, CIM_STRING|COL_FLAG_DYNAMIC }, 722 { prop_binaryrepresentationW, CIM_UINT8|CIM_FLAG_ARRAY|COL_FLAG_DYNAMIC }, 723 { prop_referenceddomainnameW, CIM_STRING|COL_FLAG_DYNAMIC }, 724 { prop_sidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, 725 { prop_sidlengthW, CIM_UINT32 } 726 }; 727 static const struct column col_sounddevice[] = 728 { 729 { prop_nameW, CIM_STRING }, 730 { prop_productnameW, CIM_STRING }, 731 { prop_statusinfoW, CIM_UINT16, VT_I4 } 732 }; 733 static const struct column col_stdregprov[] = 734 { 735 { method_createkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 736 { method_enumkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 737 { method_enumvaluesW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 738 { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } 739 }; 740 static const struct column col_systemenclosure[] = 741 { 742 { prop_captionW, CIM_STRING }, 743 { prop_chassistypesW, CIM_UINT16|CIM_FLAG_ARRAY, VT_I4|VT_ARRAY }, 744 { prop_descriptionW, CIM_STRING }, 745 { prop_lockpresentW, CIM_BOOLEAN }, 746 { prop_manufacturerW, CIM_STRING }, 747 { prop_nameW, CIM_STRING }, 748 { prop_tagW, CIM_STRING }, 749 }; 750 static const struct column col_systemsecurity[] = 751 { 752 { method_getsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 753 { method_setsdW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, 754 }; 755 756 #ifndef __REACTOS__ 757 static const struct column col_videocontroller[] = 758 { 759 { prop_adapterdactypeW, CIM_STRING }, 760 { prop_adapterramW, CIM_UINT32, VT_I4 }, 761 { prop_availabilityW, CIM_UINT16 }, 762 { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, 763 { prop_configmanagererrorcodeW, CIM_UINT32, VT_I4 }, 764 { prop_currentbitsperpixelW, CIM_UINT32, VT_I4 }, 765 { prop_currenthorizontalresW, CIM_UINT32, VT_I4 }, 766 { prop_currentrefreshrateW, CIM_UINT32, VT_I4 }, 767 { prop_currentscanmodeW, CIM_UINT16, VT_I4 }, 768 { prop_currentverticalresW, CIM_UINT32, VT_I4 }, 769 { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, 770 { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, 771 { prop_driverdateW, CIM_DATETIME }, 772 { prop_driverversionW, CIM_STRING }, 773 { prop_installeddisplaydriversW,CIM_STRING }, 774 { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, 775 { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, 776 { prop_statusW, CIM_STRING }, 777 { prop_videoarchitectureW, CIM_UINT16, VT_I4 }, 778 { prop_videomemorytypeW, CIM_UINT16, VT_I4 }, 779 { prop_videomodedescriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, 780 { prop_videoprocessorW, CIM_STRING|COL_FLAG_DYNAMIC }, 781 }; 782 #endif 783 784 static const WCHAR baseboard_manufacturerW[] = 785 {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0}; 786 static const WCHAR baseboard_serialnumberW[] = 787 {'N','o','n','e',0}; 788 static const WCHAR baseboard_tagW[] = 789 {'B','a','s','e',' ','B','o','a','r','d',0}; 790 static const WCHAR baseboard_versionW[] = 791 {'1','.','0',0}; 792 static const WCHAR bios_descriptionW[] = 793 {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0}; 794 static const WCHAR bios_manufacturerW[] = 795 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; 796 static const WCHAR bios_nameW[] = 797 {'W','I','N','E',' ','B','I','O','S',0}; 798 static const WCHAR bios_releasedateW[] = 799 {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; 800 static const WCHAR bios_serialnumberW[] = 801 {'0',0}; 802 static const WCHAR bios_smbiosbiosversionW[] = 803 {'W','i','n','e',0}; 804 static const WCHAR bios_versionW[] = 805 {'W','I','N','E',' ',' ',' ','-',' ','1',0}; 806 static const WCHAR cdromdrive_mediatypeW[] = 807 {'C','D','-','R','O','M',0}; 808 static const WCHAR cdromdrive_nameW[] = 809 {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0}; 810 static const WCHAR cdromdrive_pnpdeviceidW[]= 811 {'I','D','E','\\','C','D','R','O','M','W','I','N','E','_','C','D','-','R','O','M', 812 '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_', 813 '_','_','_','_','_','_','_','1','.','0','_','_','_','_','_','\\','5','&','3','A','2', 814 'A','5','8','5','4','&','0','&','1','.','0','.','0',0}; 815 static const WCHAR compsys_descriptionW[] = 816 {'A','T','/','A','T',' ','C','O','M','P','A','T','I','B','L','E',0}; 817 static const WCHAR compsys_domainW[] = 818 {'W','O','R','K','G','R','O','U','P',0}; 819 static const WCHAR compsys_manufacturerW[] = 820 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; 821 static const WCHAR compsys_modelW[] = 822 {'W','i','n','e',0}; 823 static const WCHAR compsysproduct_identifyingnumberW[] = 824 {'0',0}; 825 static const WCHAR compsysproduct_nameW[] = 826 {'W','i','n','e',0}; 827 static const WCHAR compsysproduct_uuidW[] = 828 {'d','e','a','d','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-','d','e','a','d','-', 829 'd','e','a','d','d','e','a','d','d','e','a','d',0}; 830 static const WCHAR compsysproduct_vendorW[] = 831 {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; 832 static const WCHAR compsysproduct_versionW[] = 833 {'1','.','0',0}; 834 static const WCHAR diskdrive_interfacetypeW[] = 835 {'I','D','E',0}; 836 static const WCHAR diskdrive_manufacturerW[] = 837 {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0}; 838 static const WCHAR diskdrive_mediatype_fixedW[] = 839 {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0}; 840 static const WCHAR diskdrive_mediatype_removableW[] = 841 {'R','e','m','o','v','a','b','l','e',' ','m','e','d','i','a',0}; 842 static const WCHAR diskdrive_modelW[] = 843 {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0}; 844 static const WCHAR diskdrive_pnpdeviceidW[] = 845 {'I','D','E','\\','D','i','s','k','\\','V','E','N','_','W','I','N','E',0}; 846 static const WCHAR diskdrive_serialW[] = 847 {'W','I','N','E','H','D','I','S','K',0}; 848 static const WCHAR networkadapter_pnpdeviceidW[]= 849 {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&', 850 'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\', 851 '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0}; 852 static const WCHAR os_32bitW[] = 853 {'3','2','-','b','i','t',0}; 854 static const WCHAR os_64bitW[] = 855 {'6','4','-','b','i','t',0}; 856 static const WCHAR os_installdateW[] = 857 {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; 858 static const WCHAR os_serialnumberW[] = 859 {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0}; 860 static const WCHAR physicalmedia_tagW[] = 861 {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0}; 862 static const WCHAR sounddevice_productnameW[] = 863 {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0}; 864 static const WCHAR systemenclosure_systemenclosureW[] = 865 {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',0}; 866 static const WCHAR systemenclosure_tagW[] = 867 {'S','y','s','t','e','m',' ','E','n','c','l','o','s','u','r','e',' ','0',0}; 868 static const WCHAR systemenclosure_manufacturerW[] = 869 {'W','i','n','e',0}; 870 #ifndef __REACTOS__ 871 static const WCHAR videocontroller_dactypeW[] = 872 {'I','n','t','e','g','r','a','t','e','d',' ','R','A','M','D','A','C',0}; 873 static const WCHAR videocontroller_deviceidW[] = 874 {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0}; 875 static const WCHAR videocontroller_driverdateW[] = 876 {'2','0','1','7','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; 877 static const WCHAR videocontroller_driverversionW[] = 878 {'1','.','0',0}; 879 static const WCHAR videocontroller_statusW[] = 880 {'O','K',0}; 881 #endif 882 883 #include "pshpack1.h" 884 struct record_baseboard 885 { 886 const WCHAR *manufacturer; 887 const WCHAR *model; 888 const WCHAR *name; 889 const WCHAR *product; 890 const WCHAR *serialnumber; 891 const WCHAR *tag; 892 const WCHAR *version; 893 }; 894 struct record_bios 895 { 896 const WCHAR *description; 897 const WCHAR *identificationcode; 898 const WCHAR *manufacturer; 899 const WCHAR *name; 900 const WCHAR *releasedate; 901 const WCHAR *serialnumber; 902 const WCHAR *smbiosbiosversion; 903 UINT16 smbiosmajorversion; 904 UINT16 smbiosminorversion; 905 const WCHAR *version; 906 }; 907 struct record_cdromdrive 908 { 909 const WCHAR *device_id; 910 const WCHAR *drive; 911 const WCHAR *mediatype; 912 const WCHAR *name; 913 const WCHAR *pnpdevice_id; 914 }; 915 struct record_computersystem 916 { 917 const WCHAR *description; 918 const WCHAR *domain; 919 UINT16 domainrole; 920 const WCHAR *manufacturer; 921 const WCHAR *model; 922 const WCHAR *name; 923 UINT32 num_logical_processors; 924 UINT32 num_processors; 925 UINT64 total_physical_memory; 926 const WCHAR *username; 927 }; 928 struct record_computersystemproduct 929 { 930 const WCHAR *identifyingnumber; 931 const WCHAR *name; 932 const WCHAR *skunumber; 933 const WCHAR *uuid; 934 const WCHAR *vendor; 935 const WCHAR *version; 936 }; 937 struct record_datafile 938 { 939 const WCHAR *name; 940 const WCHAR *version; 941 }; 942 struct record_desktopmonitor 943 { 944 UINT32 pixelsperxlogicalinch; 945 }; 946 struct record_directory 947 { 948 UINT32 accessmask; 949 const WCHAR *name; 950 }; 951 struct record_diskdrive 952 { 953 const WCHAR *device_id; 954 UINT32 index; 955 const WCHAR *interfacetype; 956 const WCHAR *manufacturer; 957 const WCHAR *mediatype; 958 const WCHAR *model; 959 const WCHAR *pnpdevice_id; 960 const WCHAR *serialnumber; 961 UINT64 size; 962 }; 963 struct record_diskpartition 964 { 965 int bootable; 966 int bootpartition; 967 const WCHAR *device_id; 968 UINT32 diskindex; 969 UINT32 index; 970 const WCHAR *pnpdevice_id; 971 UINT64 size; 972 UINT64 startingoffset; 973 const WCHAR *type; 974 }; 975 struct record_ip4routetable 976 { 977 const WCHAR *destination; 978 INT32 interfaceindex; 979 const WCHAR *nexthop; 980 }; 981 struct record_logicaldisk 982 { 983 const WCHAR *device_id; 984 UINT32 drivetype; 985 const WCHAR *filesystem; 986 UINT64 freespace; 987 const WCHAR *name; 988 UINT64 size; 989 const WCHAR *volumename; 990 const WCHAR *volumeserialnumber; 991 }; 992 struct record_networkadapter 993 { 994 const WCHAR *adaptertype; 995 const WCHAR *device_id; 996 UINT32 index; 997 UINT32 interface_index; 998 const WCHAR *mac_address; 999 const WCHAR *manufacturer; 1000 const WCHAR *name; 1001 UINT16 netconnection_status; 1002 int physicaladapter; 1003 const WCHAR *pnpdevice_id; 1004 UINT64 speed; 1005 }; 1006 struct record_networkadapterconfig 1007 { 1008 const struct array *defaultipgateway; 1009 const WCHAR *description; 1010 int dhcpenabled; 1011 const WCHAR *dnshostname; 1012 const struct array *dnsserversearchorder; 1013 UINT32 index; 1014 const struct array *ipaddress; 1015 UINT32 ipconnectionmetric; 1016 int ipenabled; 1017 const struct array *ipsubnet; 1018 const WCHAR *mac_address; 1019 const WCHAR *settingid; 1020 }; 1021 struct record_operatingsystem 1022 { 1023 const WCHAR *buildnumber; 1024 const WCHAR *caption; 1025 const WCHAR *codeset; 1026 const WCHAR *countrycode; 1027 const WCHAR *csdversion; 1028 UINT64 freephysicalmemory; 1029 const WCHAR *installdate; 1030 const WCHAR *lastbootuptime; 1031 const WCHAR *localdatetime; 1032 const WCHAR *locale; 1033 const WCHAR *name; 1034 const WCHAR *osarchitecture; 1035 UINT32 oslanguage; 1036 UINT32 osproductsuite; 1037 UINT16 ostype; 1038 int primary; 1039 const WCHAR *serialnumber; 1040 UINT16 servicepackmajor; 1041 UINT16 servicepackminor; 1042 UINT32 suitemask; 1043 const WCHAR *systemdirectory; 1044 UINT64 totalvirtualmemorysize; 1045 UINT64 totalvisiblememorysize; 1046 const WCHAR *version; 1047 }; 1048 struct record_param 1049 { 1050 const WCHAR *class; 1051 const WCHAR *method; 1052 INT32 direction; 1053 const WCHAR *parameter; 1054 UINT32 type; 1055 UINT32 varianttype; 1056 UINT32 defaultvalue; 1057 }; 1058 struct record_physicalmedia 1059 { 1060 const WCHAR *serialnumber; 1061 const WCHAR *tag; 1062 }; 1063 struct record_physicalmemory 1064 { 1065 UINT64 capacity; 1066 UINT16 memorytype; 1067 }; 1068 struct record_pnpentity 1069 { 1070 const WCHAR *device_id; 1071 }; 1072 struct record_printer 1073 { 1074 UINT32 attributes; 1075 const WCHAR *device_id; 1076 const WCHAR *drivername; 1077 UINT32 horizontalresolution; 1078 int local; 1079 const WCHAR *location; 1080 const WCHAR *name; 1081 int network; 1082 const WCHAR *portname; 1083 }; 1084 struct record_process 1085 { 1086 const WCHAR *caption; 1087 const WCHAR *commandline; 1088 const WCHAR *description; 1089 const WCHAR *handle; 1090 const WCHAR *name; 1091 UINT32 pprocess_id; 1092 UINT32 process_id; 1093 UINT32 thread_count; 1094 UINT64 workingsetsize; 1095 /* methods */ 1096 class_method *get_owner; 1097 }; 1098 struct record_processor 1099 { 1100 UINT16 addresswidth; 1101 UINT16 architecture; 1102 const WCHAR *caption; 1103 UINT16 cpu_status; 1104 UINT32 currentclockspeed; 1105 UINT16 datawidth; 1106 const WCHAR *description; 1107 const WCHAR *device_id; 1108 UINT16 family; 1109 UINT16 level; 1110 const WCHAR *manufacturer; 1111 UINT32 maxclockspeed; 1112 const WCHAR *name; 1113 UINT32 num_cores; 1114 UINT32 num_logical_processors; 1115 const WCHAR *processor_id; 1116 UINT16 processortype; 1117 UINT16 revision; 1118 const WCHAR *unique_id; 1119 const WCHAR *version; 1120 }; 1121 struct record_qualifier 1122 { 1123 const WCHAR *class; 1124 const WCHAR *member; 1125 UINT32 type; 1126 INT32 flavor; 1127 const WCHAR *name; 1128 INT32 intvalue; 1129 const WCHAR *strvalue; 1130 }; 1131 struct record_service 1132 { 1133 int accept_pause; 1134 int accept_stop; 1135 const WCHAR *displayname; 1136 const WCHAR *name; 1137 UINT32 process_id; 1138 const WCHAR *servicetype; 1139 const WCHAR *startmode; 1140 const WCHAR *state; 1141 const WCHAR *systemname; 1142 /* methods */ 1143 class_method *pause_service; 1144 class_method *resume_service; 1145 class_method *start_service; 1146 class_method *stop_service; 1147 }; 1148 struct record_sid 1149 { 1150 const WCHAR *accountname; 1151 const struct array *binaryrepresentation; 1152 const WCHAR *referenceddomainname; 1153 const WCHAR *sid; 1154 UINT32 sidlength; 1155 }; 1156 struct record_sounddevice 1157 { 1158 const WCHAR *name; 1159 const WCHAR *productname; 1160 UINT16 statusinfo; 1161 }; 1162 struct record_stdregprov 1163 { 1164 class_method *createkey; 1165 class_method *enumkey; 1166 class_method *enumvalues; 1167 class_method *getstringvalue; 1168 }; 1169 struct record_systemsecurity 1170 { 1171 class_method *getsd; 1172 class_method *setsd; 1173 }; 1174 struct record_systemenclosure 1175 { 1176 const WCHAR *caption; 1177 const struct array *chassistypes; 1178 const WCHAR *description; 1179 int lockpresent; 1180 const WCHAR *manufacturer; 1181 const WCHAR *name; 1182 const WCHAR *tag; 1183 }; 1184 struct record_videocontroller 1185 { 1186 const WCHAR *adapter_dactype; 1187 UINT32 adapter_ram; 1188 UINT16 availability; 1189 const WCHAR *caption; 1190 UINT32 config_errorcode; 1191 UINT32 current_bitsperpixel; 1192 UINT32 current_horizontalres; 1193 UINT32 current_refreshrate; 1194 UINT16 current_scanmode; 1195 UINT32 current_verticalres; 1196 const WCHAR *description; 1197 const WCHAR *device_id; 1198 const WCHAR *driverdate; 1199 const WCHAR *driverversion; 1200 const WCHAR *installeddriver; 1201 const WCHAR *name; 1202 const WCHAR *pnpdevice_id; 1203 const WCHAR *status; 1204 UINT16 videoarchitecture; 1205 UINT16 videomemorytype; 1206 const WCHAR *videomodedescription; 1207 const WCHAR *videoprocessor; 1208 }; 1209 #include "poppack.h" 1210 1211 static const struct record_baseboard data_baseboard[] = 1212 { 1213 { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_versionW } 1214 }; 1215 static const struct record_bios data_bios[] = 1216 { 1217 { bios_descriptionW, NULL, bios_manufacturerW, bios_nameW, bios_releasedateW, bios_serialnumberW, 1218 bios_smbiosbiosversionW, 1, 0, bios_versionW } 1219 }; 1220 static const struct record_param data_param[] = 1221 { 1222 { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1223 { class_processW, method_getownerW, -1, param_userW, CIM_STRING }, 1224 { class_processW, method_getownerW, -1, param_domainW, CIM_STRING }, 1225 { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1226 { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1227 { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1228 { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1229 { class_stdregprovW, method_createkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, 1230 { class_stdregprovW, method_createkeyW, 1, param_subkeynameW, CIM_STRING }, 1231 { class_stdregprovW, method_createkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1232 { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, 1233 { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING }, 1234 { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1235 { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY }, 1236 { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, 1237 { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING }, 1238 { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1239 { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY }, 1240 { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY }, 1241 { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, 1242 { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING }, 1243 { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING }, 1244 { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1245 { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING }, 1246 { class_systemsecurityW, method_getsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1247 { class_systemsecurityW, method_getsdW, -1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY }, 1248 { class_systemsecurityW, method_setsdW, 1, param_sdW, CIM_UINT8|CIM_FLAG_ARRAY }, 1249 { class_systemsecurityW, method_setsdW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, 1250 }; 1251 1252 #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\ 1253 WBEM_FLAVOR_ORIGIN_PROPAGATED) 1254 1255 static const struct record_physicalmedia data_physicalmedia[] = 1256 { 1257 { diskdrive_serialW, physicalmedia_tagW } 1258 }; 1259 static const struct record_qualifier data_qualifier[] = 1260 { 1261 { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 }, 1262 { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 } 1263 }; 1264 static const struct record_sounddevice data_sounddevice[] = 1265 { 1266 { sounddevice_productnameW, sounddevice_productnameW, 3 /* enabled */ } 1267 }; 1268 static const struct record_stdregprov data_stdregprov[] = 1269 { 1270 { reg_create_key, reg_enum_key, reg_enum_values, reg_get_stringvalue } 1271 }; 1272 static UINT16 systemenclosure_chassistypes[] = 1273 { 1274 1, 1275 }; 1276 static const struct array systemenclosure_chassistypes_array = 1277 { 1278 ARRAY_SIZE(systemenclosure_chassistypes), 1279 &systemenclosure_chassistypes 1280 }; 1281 static const struct record_systemenclosure data_systemenclosure[] = 1282 { 1283 { 1284 systemenclosure_systemenclosureW, 1285 &systemenclosure_chassistypes_array, 1286 systemenclosure_systemenclosureW, 1287 FALSE, 1288 systemenclosure_manufacturerW, 1289 systemenclosure_systemenclosureW, 1290 systemenclosure_tagW, 1291 } 1292 }; 1293 static const struct record_systemsecurity data_systemsecurity[] = 1294 { 1295 { security_get_sd, security_set_sd } 1296 }; 1297 1298 /* check if row matches condition and update status */ 1299 static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status ) 1300 { 1301 LONGLONG val; 1302 UINT type; 1303 1304 if (!cond) 1305 { 1306 *status = FILL_STATUS_UNFILTERED; 1307 return TRUE; 1308 } 1309 if (eval_cond( table, row, cond, &val, &type ) != S_OK) 1310 { 1311 *status = FILL_STATUS_FAILED; 1312 return FALSE; 1313 } 1314 *status = FILL_STATUS_FILTERED; 1315 return val != 0; 1316 } 1317 1318 static BOOL resize_table( struct table *table, UINT row_count, UINT row_size ) 1319 { 1320 if (!table->num_rows_allocated) 1321 { 1322 if (!(table->data = heap_alloc( row_count * row_size ))) return FALSE; 1323 table->num_rows_allocated = row_count; 1324 return TRUE; 1325 } 1326 if (row_count > table->num_rows_allocated) 1327 { 1328 BYTE *data; 1329 UINT count = max( row_count, table->num_rows_allocated * 2 ); 1330 if (!(data = heap_realloc( table->data, count * row_size ))) return FALSE; 1331 table->data = data; 1332 table->num_rows_allocated = count; 1333 } 1334 return TRUE; 1335 } 1336 1337 static enum fill_status fill_cdromdrive( struct table *table, const struct expr *cond ) 1338 { 1339 static const WCHAR fmtW[] = {'%','c',':',0}; 1340 WCHAR drive[3], root[] = {'A',':','\\',0}; 1341 struct record_cdromdrive *rec; 1342 UINT i, row = 0, offset = 0; 1343 DWORD drives = GetLogicalDrives(); 1344 enum fill_status status = FILL_STATUS_UNFILTERED; 1345 1346 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 1347 1348 for (i = 0; i < 26; i++) 1349 { 1350 if (drives & (1 << i)) 1351 { 1352 root[0] = 'A' + i; 1353 if (GetDriveTypeW( root ) != DRIVE_CDROM) 1354 continue; 1355 1356 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 1357 1358 rec = (struct record_cdromdrive *)(table->data + offset); 1359 rec->device_id = cdromdrive_pnpdeviceidW; 1360 sprintfW( drive, fmtW, 'A' + i ); 1361 rec->drive = heap_strdupW( drive ); 1362 rec->mediatype = cdromdrive_mediatypeW; 1363 rec->name = cdromdrive_nameW; 1364 rec->pnpdevice_id = cdromdrive_pnpdeviceidW; 1365 if (!match_row( table, row, cond, &status )) 1366 { 1367 free_row_values( table, row ); 1368 continue; 1369 } 1370 offset += sizeof(*rec); 1371 row++; 1372 } 1373 } 1374 TRACE("created %u rows\n", row); 1375 table->num_rows = row; 1376 return status; 1377 } 1378 1379 static UINT get_processor_count(void) 1380 { 1381 SYSTEM_BASIC_INFORMATION info; 1382 1383 if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1; 1384 return info.NumberOfProcessors; 1385 } 1386 1387 static UINT get_logical_processor_count( UINT *num_cores ) 1388 { 1389 SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info; 1390 UINT i, j, count = 0; 1391 NTSTATUS status; 1392 ULONG len; 1393 1394 if (num_cores) *num_cores = get_processor_count(); 1395 status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len ); 1396 if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count(); 1397 1398 if (!(info = heap_alloc( len ))) return get_processor_count(); 1399 status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len ); 1400 if (status != STATUS_SUCCESS) 1401 { 1402 heap_free( info ); 1403 return get_processor_count(); 1404 } 1405 if (num_cores) *num_cores = 0; 1406 for (i = 0; i < len / sizeof(*info); i++) 1407 { 1408 if (info[i].Relationship == RelationProcessorCore) 1409 { 1410 for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++; 1411 } 1412 else if (info[i].Relationship == RelationProcessorPackage && num_cores) 1413 { 1414 for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) (*num_cores)++; 1415 } 1416 } 1417 heap_free( info ); 1418 return count; 1419 } 1420 1421 static UINT64 get_total_physical_memory(void) 1422 { 1423 MEMORYSTATUSEX status; 1424 1425 status.dwLength = sizeof(status); 1426 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024; 1427 return status.ullTotalPhys; 1428 } 1429 1430 static UINT64 get_available_physical_memory(void) 1431 { 1432 MEMORYSTATUSEX status; 1433 1434 status.dwLength = sizeof(status); 1435 if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024; 1436 return status.ullAvailPhys; 1437 } 1438 1439 static WCHAR *get_computername(void) 1440 { 1441 WCHAR *ret; 1442 DWORD size = MAX_COMPUTERNAME_LENGTH + 1; 1443 1444 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL; 1445 GetComputerNameW( ret, &size ); 1446 return ret; 1447 } 1448 1449 static WCHAR *get_username(void) 1450 { 1451 WCHAR *ret; 1452 DWORD compsize, usersize; 1453 DWORD size; 1454 1455 compsize = 0; 1456 GetComputerNameW( NULL, &compsize ); 1457 usersize = 0; 1458 GetUserNameW( NULL, &usersize ); 1459 size = compsize + usersize; /* two null terminators account for the \ */ 1460 if (!(ret = heap_alloc( size * sizeof(WCHAR) ))) return NULL; 1461 GetComputerNameW( ret, &compsize ); 1462 ret[compsize] = '\\'; 1463 GetUserNameW( ret + compsize + 1, &usersize ); 1464 return ret; 1465 } 1466 1467 static enum fill_status fill_compsys( struct table *table, const struct expr *cond ) 1468 { 1469 struct record_computersystem *rec; 1470 enum fill_status status = FILL_STATUS_UNFILTERED; 1471 UINT row = 0; 1472 1473 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 1474 1475 rec = (struct record_computersystem *)table->data; 1476 rec->description = compsys_descriptionW; 1477 rec->domain = compsys_domainW; 1478 rec->domainrole = 0; /* standalone workstation */ 1479 rec->manufacturer = compsys_manufacturerW; 1480 rec->model = compsys_modelW; 1481 rec->name = get_computername(); 1482 rec->num_logical_processors = get_logical_processor_count( NULL ); 1483 rec->num_processors = get_processor_count(); 1484 rec->total_physical_memory = get_total_physical_memory(); 1485 rec->username = get_username(); 1486 if (!match_row( table, row, cond, &status )) free_row_values( table, row ); 1487 else row++; 1488 1489 TRACE("created %u rows\n", row); 1490 table->num_rows = row; 1491 return status; 1492 } 1493 1494 static WCHAR *get_compsysproduct_uuid(void) 1495 { 1496 #ifdef __APPLE__ 1497 unsigned char uuid[16]; 1498 const struct timespec timeout = {1, 0}; 1499 if (!gethostuuid( uuid, &timeout )) 1500 { 1501 static const WCHAR fmtW[] = 1502 {'%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-', 1503 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X', 1504 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',0}; 1505 WCHAR *ret = heap_alloc( 37 * sizeof(WCHAR) ); 1506 if (!ret) return NULL; 1507 sprintfW( ret, fmtW, uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], 1508 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ); 1509 return ret; 1510 } 1511 #endif 1512 #ifdef __linux__ 1513 int file; 1514 if ((file = open( "/var/lib/dbus/machine-id", O_RDONLY )) != -1) 1515 { 1516 unsigned char buf[32]; 1517 if (read( file, buf, sizeof(buf) ) == sizeof(buf)) 1518 { 1519 unsigned int i, j; 1520 WCHAR *ret, *p; 1521 1522 close( file ); 1523 if (!(p = ret = heap_alloc( 37 * sizeof(WCHAR) ))) return NULL; 1524 for (i = 0, j = 0; i < 8; i++) p[i] = toupperW( buf[j++] ); 1525 p[8] = '-'; 1526 for (i = 9; i < 13; i++) p[i] = toupperW( buf[j++] ); 1527 p[13] = '-'; 1528 for (i = 14; i < 18; i++) p[i] = toupperW( buf[j++] ); 1529 p[18] = '-'; 1530 for (i = 19; i < 23; i++) p[i] = toupperW( buf[j++] ); 1531 p[23] = '-'; 1532 for (i = 24; i < 36; i++) p[i] = toupperW( buf[j++] ); 1533 ret[i] = 0; 1534 return ret; 1535 } 1536 close( file ); 1537 } 1538 #endif 1539 return heap_strdupW( compsysproduct_uuidW ); 1540 } 1541 1542 static enum fill_status fill_compsysproduct( struct table *table, const struct expr *cond ) 1543 { 1544 struct record_computersystemproduct *rec; 1545 enum fill_status status = FILL_STATUS_UNFILTERED; 1546 UINT row = 0; 1547 1548 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 1549 1550 rec = (struct record_computersystemproduct *)table->data; 1551 rec->identifyingnumber = compsysproduct_identifyingnumberW; 1552 rec->name = compsysproduct_nameW; 1553 rec->skunumber = NULL; 1554 rec->uuid = get_compsysproduct_uuid(); 1555 rec->vendor = compsysproduct_vendorW; 1556 rec->version = compsysproduct_versionW; 1557 if (!match_row( table, row, cond, &status )) free_row_values( table, row ); 1558 else row++; 1559 1560 TRACE("created %u rows\n", row); 1561 table->num_rows = row; 1562 return status; 1563 } 1564 1565 struct dirstack 1566 { 1567 WCHAR **dirs; 1568 UINT *len_dirs; 1569 UINT num_dirs; 1570 UINT num_allocated; 1571 }; 1572 1573 static struct dirstack *alloc_dirstack( UINT size ) 1574 { 1575 struct dirstack *dirstack; 1576 1577 if (!(dirstack = heap_alloc( sizeof(*dirstack) ))) return NULL; 1578 if (!(dirstack->dirs = heap_alloc( sizeof(WCHAR *) * size ))) 1579 { 1580 heap_free( dirstack ); 1581 return NULL; 1582 } 1583 if (!(dirstack->len_dirs = heap_alloc( sizeof(UINT) * size ))) 1584 { 1585 heap_free( dirstack->dirs ); 1586 heap_free( dirstack ); 1587 return NULL; 1588 } 1589 dirstack->num_dirs = 0; 1590 dirstack->num_allocated = size; 1591 return dirstack; 1592 } 1593 1594 static void clear_dirstack( struct dirstack *dirstack ) 1595 { 1596 UINT i; 1597 for (i = 0; i < dirstack->num_dirs; i++) heap_free( dirstack->dirs[i] ); 1598 dirstack->num_dirs = 0; 1599 } 1600 1601 static void free_dirstack( struct dirstack *dirstack ) 1602 { 1603 clear_dirstack( dirstack ); 1604 heap_free( dirstack->dirs ); 1605 heap_free( dirstack->len_dirs ); 1606 heap_free( dirstack ); 1607 } 1608 1609 static BOOL push_dir( struct dirstack *dirstack, WCHAR *dir, UINT len ) 1610 { 1611 UINT size, i = dirstack->num_dirs; 1612 1613 if (!dir) return FALSE; 1614 1615 if (i == dirstack->num_allocated) 1616 { 1617 WCHAR **tmp; 1618 UINT *len_tmp; 1619 1620 size = dirstack->num_allocated * 2; 1621 if (!(tmp = heap_realloc( dirstack->dirs, size * sizeof(WCHAR *) ))) return FALSE; 1622 dirstack->dirs = tmp; 1623 if (!(len_tmp = heap_realloc( dirstack->len_dirs, size * sizeof(UINT) ))) return FALSE; 1624 dirstack->len_dirs = len_tmp; 1625 dirstack->num_allocated = size; 1626 } 1627 dirstack->dirs[i] = dir; 1628 dirstack->len_dirs[i] = len; 1629 dirstack->num_dirs++; 1630 return TRUE; 1631 } 1632 1633 static WCHAR *pop_dir( struct dirstack *dirstack, UINT *len ) 1634 { 1635 if (!dirstack->num_dirs) 1636 { 1637 *len = 0; 1638 return NULL; 1639 } 1640 dirstack->num_dirs--; 1641 *len = dirstack->len_dirs[dirstack->num_dirs]; 1642 return dirstack->dirs[dirstack->num_dirs]; 1643 } 1644 1645 static const WCHAR *peek_dir( struct dirstack *dirstack ) 1646 { 1647 if (!dirstack->num_dirs) return NULL; 1648 return dirstack->dirs[dirstack->num_dirs - 1]; 1649 } 1650 1651 static WCHAR *build_glob( WCHAR drive, const WCHAR *path, UINT len ) 1652 { 1653 UINT i = 0; 1654 WCHAR *ret; 1655 1656 if (!(ret = heap_alloc( (len + 6) * sizeof(WCHAR) ))) return NULL; 1657 ret[i++] = drive; 1658 ret[i++] = ':'; 1659 ret[i++] = '\\'; 1660 if (path && len) 1661 { 1662 memcpy( ret + i, path, len * sizeof(WCHAR) ); 1663 i += len; 1664 ret[i++] = '\\'; 1665 } 1666 ret[i++] = '*'; 1667 ret[i] = 0; 1668 return ret; 1669 } 1670 1671 static WCHAR *build_name( WCHAR drive, const WCHAR *path ) 1672 { 1673 UINT i = 0, len = 0; 1674 const WCHAR *p; 1675 WCHAR *ret; 1676 1677 for (p = path; *p; p++) 1678 { 1679 if (*p == '\\') len += 2; 1680 else len++; 1681 }; 1682 if (!(ret = heap_alloc( (len + 5) * sizeof(WCHAR) ))) return NULL; 1683 ret[i++] = drive; 1684 ret[i++] = ':'; 1685 ret[i++] = '\\'; 1686 ret[i++] = '\\'; 1687 for (p = path; *p; p++) 1688 { 1689 if (*p != '\\') ret[i++] = *p; 1690 else 1691 { 1692 ret[i++] = '\\'; 1693 ret[i++] = '\\'; 1694 } 1695 } 1696 ret[i] = 0; 1697 return ret; 1698 } 1699 1700 static WCHAR *build_dirname( const WCHAR *path, UINT *ret_len ) 1701 { 1702 const WCHAR *p = path, *start; 1703 UINT len, i; 1704 WCHAR *ret; 1705 1706 if (!isalphaW( p[0] ) || p[1] != ':' || p[2] != '\\' || p[3] != '\\' || !p[4]) return NULL; 1707 start = path + 4; 1708 len = strlenW( start ); 1709 p = start + len - 1; 1710 if (*p == '\\') return NULL; 1711 1712 while (p >= start && *p != '\\') { len--; p--; }; 1713 while (p >= start && *p == '\\') { len--; p--; }; 1714 1715 if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL; 1716 for (i = 0, p = start; p < start + len; p++) 1717 { 1718 if (p[0] == '\\' && p[1] == '\\') 1719 { 1720 ret[i++] = '\\'; 1721 p++; 1722 } 1723 else ret[i++] = *p; 1724 } 1725 ret[i] = 0; 1726 *ret_len = i; 1727 return ret; 1728 } 1729 1730 static BOOL seen_dir( struct dirstack *dirstack, const WCHAR *path ) 1731 { 1732 UINT i; 1733 for (i = 0; i < dirstack->num_dirs; i++) if (!strcmpW( dirstack->dirs[i], path )) return TRUE; 1734 return FALSE; 1735 } 1736 1737 /* optimize queries of the form WHERE Name='...' [OR Name='...']* */ 1738 static UINT seed_dirs( struct dirstack *dirstack, const struct expr *cond, WCHAR root, UINT *count ) 1739 { 1740 const struct expr *left, *right; 1741 1742 if (!cond || cond->type != EXPR_COMPLEX) return *count = 0; 1743 1744 left = cond->u.expr.left; 1745 right = cond->u.expr.right; 1746 if (cond->u.expr.op == OP_EQ) 1747 { 1748 UINT len; 1749 WCHAR *path; 1750 const WCHAR *str = NULL; 1751 1752 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && 1753 !strcmpW( left->u.propval->name, prop_nameW ) && 1754 toupperW( right->u.sval[0] ) == toupperW( root )) 1755 { 1756 str = right->u.sval; 1757 } 1758 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && 1759 !strcmpW( right->u.propval->name, prop_nameW ) && 1760 toupperW( left->u.sval[0] ) == toupperW( root )) 1761 { 1762 str = left->u.sval; 1763 } 1764 if (str && (path = build_dirname( str, &len ))) 1765 { 1766 if (seen_dir( dirstack, path )) 1767 { 1768 heap_free( path ); 1769 return ++*count; 1770 } 1771 else if (push_dir( dirstack, path, len )) return ++*count; 1772 heap_free( path ); 1773 return *count = 0; 1774 } 1775 } 1776 else if (cond->u.expr.op == OP_OR) 1777 { 1778 UINT left_count = 0, right_count = 0; 1779 1780 if (!(seed_dirs( dirstack, left, root, &left_count ))) return *count = 0; 1781 if (!(seed_dirs( dirstack, right, root, &right_count ))) return *count = 0; 1782 return *count += left_count + right_count; 1783 } 1784 return *count = 0; 1785 } 1786 1787 static WCHAR *append_path( const WCHAR *path, const WCHAR *segment, UINT *len ) 1788 { 1789 UINT len_path = 0, len_segment = strlenW( segment ); 1790 WCHAR *ret; 1791 1792 *len = 0; 1793 if (path) len_path = strlenW( path ); 1794 if (!(ret = heap_alloc( (len_path + len_segment + 2) * sizeof(WCHAR) ))) return NULL; 1795 if (path && len_path) 1796 { 1797 memcpy( ret, path, len_path * sizeof(WCHAR) ); 1798 ret[len_path] = '\\'; 1799 *len += len_path + 1; 1800 } 1801 memcpy( ret + *len, segment, len_segment * sizeof(WCHAR) ); 1802 *len += len_segment; 1803 ret[*len] = 0; 1804 return ret; 1805 } 1806 1807 static WCHAR *get_file_version( const WCHAR *filename ) 1808 { 1809 static const WCHAR slashW[] = {'\\',0}, fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; 1810 VS_FIXEDFILEINFO *info; 1811 DWORD size; 1812 void *block; 1813 WCHAR *ret; 1814 1815 if (!(ret = heap_alloc( (4 * 5 + ARRAY_SIZE( fmtW )) * sizeof(WCHAR) ))) return NULL; 1816 if (!(size = GetFileVersionInfoSizeW( filename, NULL )) || !(block = heap_alloc( size ))) 1817 { 1818 heap_free( ret ); 1819 return NULL; 1820 } 1821 if (!GetFileVersionInfoW( filename, 0, size, block ) || 1822 !VerQueryValueW( block, slashW, (void **)&info, &size )) 1823 { 1824 heap_free( block ); 1825 heap_free( ret ); 1826 return NULL; 1827 } 1828 sprintfW( ret, fmtW, info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xffff, 1829 info->dwFileVersionLS >> 16, info->dwFileVersionLS & 0xffff ); 1830 heap_free( block ); 1831 return ret; 1832 } 1833 1834 static enum fill_status fill_datafile( struct table *table, const struct expr *cond ) 1835 { 1836 static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0}; 1837 struct record_datafile *rec; 1838 UINT i, len, row = 0, offset = 0, num_expected_rows; 1839 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0}; 1840 DWORD drives = GetLogicalDrives(); 1841 WIN32_FIND_DATAW data; 1842 HANDLE handle; 1843 struct dirstack *dirstack; 1844 enum fill_status status = FILL_STATUS_UNFILTERED; 1845 1846 if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED; 1847 1848 dirstack = alloc_dirstack(2); 1849 1850 for (i = 0; i < 26; i++) 1851 { 1852 if (!(drives & (1 << i))) continue; 1853 1854 root[0] = 'A' + i; 1855 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue; 1856 1857 num_expected_rows = 0; 1858 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack ); 1859 1860 for (;;) 1861 { 1862 heap_free( glob ); 1863 heap_free( path ); 1864 path = pop_dir( dirstack, &len ); 1865 if (!(glob = build_glob( root[0], path, len ))) 1866 { 1867 status = FILL_STATUS_FAILED; 1868 goto done; 1869 } 1870 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE) 1871 { 1872 do 1873 { 1874 if (!resize_table( table, row + 1, sizeof(*rec) )) 1875 { 1876 status = FILL_STATUS_FAILED; 1877 FindClose( handle ); 1878 goto done; 1879 } 1880 if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue; 1881 new_path = append_path( path, data.cFileName, &len ); 1882 1883 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 1884 { 1885 if (push_dir( dirstack, new_path, len )) continue; 1886 heap_free( new_path ); 1887 FindClose( handle ); 1888 status = FILL_STATUS_FAILED; 1889 goto done; 1890 } 1891 rec = (struct record_datafile *)(table->data + offset); 1892 rec->name = build_name( root[0], new_path ); 1893 rec->version = get_file_version( rec->name ); 1894 if (!match_row( table, row, cond, &status )) 1895 { 1896 free_row_values( table, row ); 1897 continue; 1898 } 1899 else if (num_expected_rows && row == num_expected_rows - 1) 1900 { 1901 row++; 1902 FindClose( handle ); 1903 status = FILL_STATUS_FILTERED; 1904 goto done; 1905 } 1906 offset += sizeof(*rec); 1907 row++; 1908 } 1909 while (FindNextFileW( handle, &data )); 1910 FindClose( handle ); 1911 } 1912 if (!peek_dir( dirstack )) break; 1913 } 1914 } 1915 1916 done: 1917 free_dirstack( dirstack ); 1918 heap_free( glob ); 1919 heap_free( path ); 1920 1921 TRACE("created %u rows\n", row); 1922 table->num_rows = row; 1923 return status; 1924 } 1925 1926 static UINT32 get_pixelsperxlogicalinch(void) 1927 { 1928 HDC hdc = GetDC( NULL ); 1929 UINT32 ret; 1930 1931 if (!hdc) return 96; 1932 ret = GetDeviceCaps( hdc, LOGPIXELSX ); 1933 ReleaseDC( NULL, hdc ); 1934 return ret; 1935 } 1936 1937 static enum fill_status fill_desktopmonitor( struct table *table, const struct expr *cond ) 1938 { 1939 struct record_desktopmonitor *rec; 1940 enum fill_status status = FILL_STATUS_UNFILTERED; 1941 UINT row = 0; 1942 1943 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 1944 1945 rec = (struct record_desktopmonitor *)table->data; 1946 rec->pixelsperxlogicalinch = get_pixelsperxlogicalinch(); 1947 1948 if (match_row( table, row, cond, &status )) row++; 1949 1950 TRACE("created %u rows\n", row); 1951 table->num_rows = row; 1952 return status; 1953 } 1954 1955 static enum fill_status fill_directory( struct table *table, const struct expr *cond ) 1956 { 1957 static const WCHAR dotW[] = {'.',0}, dotdotW[] = {'.','.',0}; 1958 struct record_directory *rec; 1959 UINT i, len, row = 0, offset = 0, num_expected_rows; 1960 WCHAR *glob = NULL, *path = NULL, *new_path, root[] = {'A',':','\\',0}; 1961 DWORD drives = GetLogicalDrives(); 1962 WIN32_FIND_DATAW data; 1963 HANDLE handle; 1964 struct dirstack *dirstack; 1965 enum fill_status status = FILL_STATUS_UNFILTERED; 1966 1967 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED; 1968 1969 dirstack = alloc_dirstack(2); 1970 1971 for (i = 0; i < 26; i++) 1972 { 1973 if (!(drives & (1 << i))) continue; 1974 1975 root[0] = 'A' + i; 1976 if (GetDriveTypeW( root ) != DRIVE_FIXED) continue; 1977 1978 num_expected_rows = 0; 1979 if (!seed_dirs( dirstack, cond, root[0], &num_expected_rows )) clear_dirstack( dirstack ); 1980 1981 for (;;) 1982 { 1983 heap_free( glob ); 1984 heap_free( path ); 1985 path = pop_dir( dirstack, &len ); 1986 if (!(glob = build_glob( root[0], path, len ))) 1987 { 1988 status = FILL_STATUS_FAILED; 1989 goto done; 1990 } 1991 if ((handle = FindFirstFileW( glob, &data )) != INVALID_HANDLE_VALUE) 1992 { 1993 do 1994 { 1995 if (!resize_table( table, row + 1, sizeof(*rec) )) 1996 { 1997 FindClose( handle ); 1998 status = FILL_STATUS_FAILED; 1999 goto done; 2000 } 2001 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || 2002 !strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) 2003 continue; 2004 2005 new_path = append_path( path, data.cFileName, &len ); 2006 if (!(push_dir( dirstack, new_path, len ))) 2007 { 2008 heap_free( new_path ); 2009 FindClose( handle ); 2010 status = FILL_STATUS_FAILED; 2011 goto done; 2012 } 2013 rec = (struct record_directory *)(table->data + offset); 2014 rec->accessmask = FILE_ALL_ACCESS; 2015 rec->name = build_name( root[0], new_path ); 2016 if (!match_row( table, row, cond, &status )) 2017 { 2018 free_row_values( table, row ); 2019 continue; 2020 } 2021 else if (num_expected_rows && row == num_expected_rows - 1) 2022 { 2023 row++; 2024 FindClose( handle ); 2025 status = FILL_STATUS_FILTERED; 2026 goto done; 2027 } 2028 offset += sizeof(*rec); 2029 row++; 2030 } 2031 while (FindNextFileW( handle, &data )); 2032 FindClose( handle ); 2033 } 2034 if (!peek_dir( dirstack )) break; 2035 } 2036 } 2037 2038 done: 2039 free_dirstack( dirstack ); 2040 heap_free( glob ); 2041 heap_free( path ); 2042 2043 TRACE("created %u rows\n", row); 2044 table->num_rows = row; 2045 return status; 2046 } 2047 2048 static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize ) 2049 { 2050 WCHAR root[] = {'\\','\\','.','\\','A',':',0}; 2051 ULARGE_INTEGER free; 2052 DISK_GEOMETRY_EX info; 2053 HANDLE handle; 2054 DWORD bytes_returned; 2055 2056 free.QuadPart = 512 * 1024 * 1024; 2057 GetDiskFreeSpaceExW( dir, NULL, NULL, &free ); 2058 2059 root[4] = dir[0]; 2060 handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); 2061 if (handle != INVALID_HANDLE_VALUE) 2062 { 2063 if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), &bytes_returned, NULL )) 2064 *disksize = info.DiskSize.QuadPart; 2065 CloseHandle( handle ); 2066 } 2067 return free.QuadPart; 2068 } 2069 2070 static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond ) 2071 { 2072 static const WCHAR fmtW[] = 2073 {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','%','u',0}; 2074 WCHAR device_id[ARRAY_SIZE( fmtW ) + 10], root[] = {'A',':','\\',0}; 2075 struct record_diskdrive *rec; 2076 UINT i, row = 0, offset = 0, index = 0, type; 2077 UINT64 size = 1024 * 1024 * 1024; 2078 DWORD drives = GetLogicalDrives(); 2079 enum fill_status status = FILL_STATUS_UNFILTERED; 2080 2081 if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED; 2082 2083 for (i = 0; i < 26; i++) 2084 { 2085 if (drives & (1 << i)) 2086 { 2087 root[0] = 'A' + i; 2088 type = GetDriveTypeW( root ); 2089 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE) 2090 continue; 2091 2092 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 2093 2094 rec = (struct record_diskdrive *)(table->data + offset); 2095 sprintfW( device_id, fmtW, index ); 2096 rec->device_id = heap_strdupW( device_id ); 2097 rec->index = index; 2098 rec->interfacetype = diskdrive_interfacetypeW; 2099 rec->manufacturer = diskdrive_manufacturerW; 2100 if (type == DRIVE_FIXED) 2101 rec->mediatype = diskdrive_mediatype_fixedW; 2102 else 2103 rec->mediatype = diskdrive_mediatype_removableW; 2104 rec->model = diskdrive_modelW; 2105 rec->pnpdevice_id = diskdrive_pnpdeviceidW; 2106 rec->serialnumber = diskdrive_serialW; 2107 get_freespace( root, &size ); 2108 rec->size = size; 2109 if (!match_row( table, row, cond, &status )) 2110 { 2111 free_row_values( table, row ); 2112 continue; 2113 } 2114 offset += sizeof(*rec); 2115 index++; 2116 row++; 2117 } 2118 } 2119 TRACE("created %u rows\n", row); 2120 table->num_rows = row; 2121 return status; 2122 } 2123 2124 static WCHAR *get_filesystem( const WCHAR *root ) 2125 { 2126 static const WCHAR ntfsW[] = {'N','T','F','S',0}; 2127 WCHAR buffer[MAX_PATH + 1]; 2128 2129 if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 )) 2130 return heap_strdupW( buffer ); 2131 return heap_strdupW( ntfsW ); 2132 } 2133 2134 static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond ) 2135 { 2136 static const WCHAR fmtW[] = 2137 {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0}; 2138 WCHAR device_id[32], root[] = {'A',':','\\',0}; 2139 struct record_diskpartition *rec; 2140 UINT i, row = 0, offset = 0, type, index = 0; 2141 UINT64 size = 1024 * 1024 * 1024; 2142 DWORD drives = GetLogicalDrives(); 2143 enum fill_status status = FILL_STATUS_UNFILTERED; 2144 2145 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED; 2146 2147 for (i = 0; i < 26; i++) 2148 { 2149 if (drives & (1 << i)) 2150 { 2151 root[0] = 'A' + i; 2152 type = GetDriveTypeW( root ); 2153 if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE) 2154 continue; 2155 2156 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 2157 2158 rec = (struct record_diskpartition *)(table->data + offset); 2159 rec->bootable = (i == 2) ? -1 : 0; 2160 rec->bootpartition = (i == 2) ? -1 : 0; 2161 sprintfW( device_id, fmtW, index ); 2162 rec->device_id = heap_strdupW( device_id ); 2163 rec->diskindex = index; 2164 rec->index = 0; 2165 rec->pnpdevice_id = heap_strdupW( device_id ); 2166 get_freespace( root, &size ); 2167 rec->size = size; 2168 rec->startingoffset = 0; 2169 rec->type = get_filesystem( root ); 2170 if (!match_row( table, row, cond, &status )) 2171 { 2172 free_row_values( table, row ); 2173 continue; 2174 } 2175 offset += sizeof(*rec); 2176 row++; 2177 index++; 2178 } 2179 } 2180 TRACE("created %u rows\n", row); 2181 table->num_rows = row; 2182 return status; 2183 } 2184 2185 static WCHAR *get_ip4_string( DWORD addr ) 2186 { 2187 static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; 2188 WCHAR *ret; 2189 2190 if (!(ret = heap_alloc( sizeof("ddd.ddd.ddd.ddd") * sizeof(WCHAR) ))) return NULL; 2191 sprintfW( ret, fmtW, (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff ); 2192 return ret; 2193 } 2194 2195 static enum fill_status fill_ip4routetable( struct table *table, const struct expr *cond ) 2196 { 2197 struct record_ip4routetable *rec; 2198 UINT i, row = 0, offset = 0, size = 0; 2199 MIB_IPFORWARDTABLE *forwards; 2200 enum fill_status status = FILL_STATUS_UNFILTERED; 2201 2202 if (GetIpForwardTable( NULL, &size, TRUE ) != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED; 2203 if (!(forwards = heap_alloc( size ))) return FILL_STATUS_FAILED; 2204 if (GetIpForwardTable( forwards, &size, TRUE )) 2205 { 2206 heap_free( forwards ); 2207 return FILL_STATUS_FAILED; 2208 } 2209 if (!resize_table( table, max(forwards->dwNumEntries, 1), sizeof(*rec) )) 2210 { 2211 heap_free( forwards ); 2212 return FILL_STATUS_FAILED; 2213 } 2214 2215 for (i = 0; i < forwards->dwNumEntries; i++) 2216 { 2217 rec = (struct record_ip4routetable *)(table->data + offset); 2218 2219 rec->destination = get_ip4_string( ntohl(forwards->table[i].dwForwardDest) ); 2220 rec->interfaceindex = forwards->table[i].dwForwardIfIndex; 2221 rec->nexthop = get_ip4_string( ntohl(forwards->table[i].dwForwardNextHop) ); 2222 2223 if (!match_row( table, row, cond, &status )) 2224 { 2225 free_row_values( table, row ); 2226 continue; 2227 } 2228 offset += sizeof(*rec); 2229 row++; 2230 } 2231 TRACE("created %u rows\n", row); 2232 table->num_rows = row; 2233 2234 heap_free( forwards ); 2235 return status; 2236 } 2237 2238 static WCHAR *get_volumename( const WCHAR *root ) 2239 { 2240 WCHAR buf[MAX_PATH + 1] = {0}; 2241 GetVolumeInformationW( root, buf, ARRAY_SIZE( buf ), NULL, NULL, NULL, NULL, 0 ); 2242 return heap_strdupW( buf ); 2243 } 2244 static WCHAR *get_volumeserialnumber( const WCHAR *root ) 2245 { 2246 static const WCHAR fmtW[] = {'%','0','8','X',0}; 2247 DWORD serial = 0; 2248 WCHAR buffer[9]; 2249 2250 GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 ); 2251 sprintfW( buffer, fmtW, serial ); 2252 return heap_strdupW( buffer ); 2253 } 2254 2255 static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond ) 2256 { 2257 static const WCHAR fmtW[] = {'%','c',':',0}; 2258 WCHAR device_id[3], root[] = {'A',':','\\',0}; 2259 struct record_logicaldisk *rec; 2260 UINT i, row = 0, offset = 0, type; 2261 UINT64 size = 1024 * 1024 * 1024; 2262 DWORD drives = GetLogicalDrives(); 2263 enum fill_status status = FILL_STATUS_UNFILTERED; 2264 2265 if (!resize_table( table, 4, sizeof(*rec) )) return FILL_STATUS_FAILED; 2266 2267 for (i = 0; i < 26; i++) 2268 { 2269 if (drives & (1 << i)) 2270 { 2271 root[0] = 'A' + i; 2272 type = GetDriveTypeW( root ); 2273 if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE) 2274 continue; 2275 2276 if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 2277 2278 rec = (struct record_logicaldisk *)(table->data + offset); 2279 sprintfW( device_id, fmtW, 'A' + i ); 2280 rec->device_id = heap_strdupW( device_id ); 2281 rec->drivetype = type; 2282 rec->filesystem = get_filesystem( root ); 2283 rec->freespace = get_freespace( root, &size ); 2284 rec->name = heap_strdupW( device_id ); 2285 rec->size = size; 2286 rec->volumename = get_volumename( root ); 2287 rec->volumeserialnumber = get_volumeserialnumber( root ); 2288 if (!match_row( table, row, cond, &status )) 2289 { 2290 free_row_values( table, row ); 2291 continue; 2292 } 2293 offset += sizeof(*rec); 2294 row++; 2295 } 2296 } 2297 TRACE("created %u rows\n", row); 2298 table->num_rows = row; 2299 return status; 2300 } 2301 2302 static UINT16 get_connection_status( IF_OPER_STATUS status ) 2303 { 2304 switch (status) 2305 { 2306 case IfOperStatusDown: 2307 return 0; /* Disconnected */ 2308 case IfOperStatusUp: 2309 return 2; /* Connected */ 2310 default: 2311 ERR("unhandled status %u\n", status); 2312 break; 2313 } 2314 return 0; 2315 } 2316 static WCHAR *get_mac_address( const BYTE *addr, DWORD len ) 2317 { 2318 static const WCHAR fmtW[] = 2319 {'%','0','2','x',':','%','0','2','x',':','%','0','2','x',':', 2320 '%','0','2','x',':','%','0','2','x',':','%','0','2','x',0}; 2321 WCHAR *ret; 2322 2323 if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL; 2324 sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] ); 2325 return ret; 2326 } 2327 static const WCHAR *get_adaptertype( DWORD type, int *physical ) 2328 { 2329 static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0}; 2330 static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0}; 2331 static const WCHAR firewireW[] = {'1','3','9','4',0}; 2332 static const WCHAR tunnelW[] = {'T','u','n','n','e','l',0}; 2333 2334 switch (type) 2335 { 2336 case IF_TYPE_ETHERNET_CSMACD: *physical = -1; return ethernetW; 2337 case IF_TYPE_IEEE80211: *physical = -1; return wirelessW; 2338 case IF_TYPE_IEEE1394: *physical = -1; return firewireW; 2339 case IF_TYPE_TUNNEL: *physical = 0; return tunnelW; 2340 default: *physical = 0; return NULL; 2341 } 2342 } 2343 2344 static enum fill_status fill_networkadapter( struct table *table, const struct expr *cond ) 2345 { 2346 static const WCHAR fmtW[] = {'%','u',0}; 2347 WCHAR device_id[11]; 2348 struct record_networkadapter *rec; 2349 IP_ADAPTER_ADDRESSES *aa, *buffer; 2350 UINT row = 0, offset = 0, count = 0; 2351 DWORD size = 0, ret; 2352 int physical; 2353 enum fill_status status = FILL_STATUS_UNFILTERED; 2354 2355 ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ); 2356 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; 2357 2358 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; 2359 if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size )) 2360 { 2361 heap_free( buffer ); 2362 return FILL_STATUS_FAILED; 2363 } 2364 for (aa = buffer; aa; aa = aa->Next) 2365 { 2366 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++; 2367 } 2368 if (!resize_table( table, count, sizeof(*rec) )) 2369 { 2370 heap_free( buffer ); 2371 return FILL_STATUS_FAILED; 2372 } 2373 for (aa = buffer; aa; aa = aa->Next) 2374 { 2375 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; 2376 2377 rec = (struct record_networkadapter *)(table->data + offset); 2378 sprintfW( device_id, fmtW, aa->u.s.IfIndex ); 2379 rec->adaptertype = get_adaptertype( aa->IfType, &physical ); 2380 rec->device_id = heap_strdupW( device_id ); 2381 rec->index = aa->u.s.IfIndex; 2382 rec->interface_index = aa->u.s.IfIndex; 2383 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); 2384 rec->manufacturer = compsys_manufacturerW; 2385 rec->name = heap_strdupW( aa->FriendlyName ); 2386 rec->netconnection_status = get_connection_status( aa->OperStatus ); 2387 rec->physicaladapter = physical; 2388 rec->pnpdevice_id = networkadapter_pnpdeviceidW; 2389 rec->speed = 1000000; 2390 if (!match_row( table, row, cond, &status )) 2391 { 2392 free_row_values( table, row ); 2393 continue; 2394 } 2395 offset += sizeof(*rec); 2396 row++; 2397 } 2398 TRACE("created %u rows\n", row); 2399 table->num_rows = row; 2400 2401 heap_free( buffer ); 2402 return status; 2403 } 2404 2405 static WCHAR *get_dnshostname( IP_ADAPTER_UNICAST_ADDRESS *addr ) 2406 { 2407 const SOCKET_ADDRESS *sa = &addr->Address; 2408 WCHAR buf[NI_MAXHOST]; 2409 2410 if (!addr) return NULL; 2411 if (GetNameInfoW( sa->lpSockaddr, sa->iSockaddrLength, buf, ARRAY_SIZE( buf ), NULL, 2412 0, NI_NAMEREQD )) return NULL; 2413 return heap_strdupW( buf ); 2414 } 2415 static struct array *get_defaultipgateway( IP_ADAPTER_GATEWAY_ADDRESS *list ) 2416 { 2417 IP_ADAPTER_GATEWAY_ADDRESS *gateway; 2418 struct array *ret; 2419 ULONG buflen, i = 0, count = 0; 2420 WCHAR **ptr, buf[54]; /* max IPv6 address length */ 2421 2422 if (!list) return NULL; 2423 for (gateway = list; gateway; gateway = gateway->Next) count++; 2424 2425 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; 2426 if (!(ptr = heap_alloc( sizeof(*ptr) * count ))) 2427 { 2428 heap_free( ret ); 2429 return NULL; 2430 } 2431 for (gateway = list; gateway; gateway = gateway->Next) 2432 { 2433 buflen = ARRAY_SIZE( buf ); 2434 if (WSAAddressToStringW( gateway->Address.lpSockaddr, gateway->Address.iSockaddrLength, 2435 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf ))) 2436 { 2437 for (; i > 0; i--) heap_free( ptr[i - 1] ); 2438 heap_free( ptr ); 2439 heap_free( ret ); 2440 return NULL; 2441 } 2442 } 2443 ret->count = count; 2444 ret->ptr = ptr; 2445 return ret; 2446 } 2447 static struct array *get_dnsserversearchorder( IP_ADAPTER_DNS_SERVER_ADDRESS *list ) 2448 { 2449 IP_ADAPTER_DNS_SERVER_ADDRESS *server; 2450 struct array *ret; 2451 ULONG buflen, i = 0, count = 0; 2452 WCHAR **ptr, *p, buf[54]; /* max IPv6 address length */ 2453 2454 if (!list) return NULL; 2455 for (server = list; server; server = server->Next) count++; 2456 2457 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; 2458 if (!(ptr = heap_alloc( sizeof(*ptr) * count ))) 2459 { 2460 heap_free( ret ); 2461 return NULL; 2462 } 2463 for (server = list; server; server = server->Next) 2464 { 2465 buflen = ARRAY_SIZE( buf ); 2466 if (WSAAddressToStringW( server->Address.lpSockaddr, server->Address.iSockaddrLength, 2467 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf ))) 2468 { 2469 for (; i > 0; i--) heap_free( ptr[i - 1] ); 2470 heap_free( ptr ); 2471 heap_free( ret ); 2472 return NULL; 2473 } 2474 if ((p = strrchrW( ptr[i - 1], ':' ))) *p = 0; 2475 } 2476 ret->count = count; 2477 ret->ptr = ptr; 2478 return ret; 2479 } 2480 2481 #ifndef __REACTOS__ 2482 2483 static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list ) 2484 { 2485 IP_ADAPTER_UNICAST_ADDRESS_LH *address; 2486 struct array *ret; 2487 ULONG buflen, i = 0, count = 0; 2488 WCHAR **ptr, buf[54]; /* max IPv6 address length */ 2489 2490 if (!list) return NULL; 2491 for (address = list; address; address = address->Next) count++; 2492 2493 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; 2494 if (!(ptr = heap_alloc( sizeof(*ptr) * count ))) 2495 { 2496 heap_free( ret ); 2497 return NULL; 2498 } 2499 for (address = list; address; address = address->Next) 2500 { 2501 buflen = ARRAY_SIZE( buf ); 2502 if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength, 2503 NULL, buf, &buflen) || !(ptr[i++] = heap_strdupW( buf ))) 2504 { 2505 for (; i > 0; i--) heap_free( ptr[i - 1] ); 2506 heap_free( ptr ); 2507 heap_free( ret ); 2508 return NULL; 2509 } 2510 } 2511 ret->count = count; 2512 ret->ptr = ptr; 2513 return ret; 2514 } 2515 static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list ) 2516 { 2517 IP_ADAPTER_UNICAST_ADDRESS_LH *address; 2518 struct array *ret; 2519 ULONG i = 0, count = 0; 2520 WCHAR **ptr; 2521 2522 if (!list) return NULL; 2523 for (address = list; address; address = address->Next) count++; 2524 2525 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL; 2526 if (!(ptr = heap_alloc( sizeof(*ptr) * count ))) 2527 { 2528 heap_free( ret ); 2529 return NULL; 2530 } 2531 for (address = list; address; address = address->Next) 2532 { 2533 if (address->Address.lpSockaddr->sa_family == WS_AF_INET) 2534 { 2535 WCHAR buf[INET_ADDRSTRLEN]; 2536 SOCKADDR_IN addr; 2537 ULONG buflen = ARRAY_SIZE( buf ); 2538 2539 memset( &addr, 0, sizeof(addr) ); 2540 addr.sin_family = WS_AF_INET; 2541 if (ConvertLengthToIpv4Mask( address->OnLinkPrefixLength, &addr.sin_addr.S_un.S_addr ) != NO_ERROR 2542 || WSAAddressToStringW( (SOCKADDR*)&addr, sizeof(addr), NULL, buf, &buflen)) 2543 ptr[i] = NULL; 2544 else 2545 ptr[i] = heap_strdupW( buf ); 2546 } 2547 else 2548 { 2549 static const WCHAR fmtW[] = {'%','u',0}; 2550 WCHAR buf[11]; 2551 2552 sprintfW(buf, fmtW, address->OnLinkPrefixLength); 2553 ptr[i] = heap_strdupW( buf ); 2554 } 2555 if (!ptr[i++]) 2556 { 2557 for (; i > 0; i--) heap_free( ptr[i - 1] ); 2558 heap_free( ptr ); 2559 heap_free( ret ); 2560 return NULL; 2561 } 2562 } 2563 ret->count = count; 2564 ret->ptr = ptr; 2565 return ret; 2566 } 2567 2568 #endif /* !__REACTOS__ */ 2569 2570 static WCHAR *get_settingid( UINT32 index ) 2571 { 2572 GUID guid; 2573 WCHAR *ret, *str; 2574 memset( &guid, 0, sizeof(guid) ); 2575 guid.Data1 = index; 2576 UuidToStringW( &guid, &str ); 2577 ret = heap_strdupW( str ); 2578 RpcStringFreeW( &str ); 2579 return ret; 2580 } 2581 2582 static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond ) 2583 { 2584 struct record_networkadapterconfig *rec; 2585 IP_ADAPTER_ADDRESSES *aa, *buffer; 2586 UINT row = 0, offset = 0, count = 0; 2587 DWORD size = 0, ret; 2588 enum fill_status status = FILL_STATUS_UNFILTERED; 2589 2590 ret = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, NULL, &size ); 2591 if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; 2592 2593 if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; 2594 if (GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS, NULL, buffer, &size )) 2595 { 2596 heap_free( buffer ); 2597 return FILL_STATUS_FAILED; 2598 } 2599 for (aa = buffer; aa; aa = aa->Next) 2600 { 2601 if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++; 2602 } 2603 if (!resize_table( table, count, sizeof(*rec) )) 2604 { 2605 heap_free( buffer ); 2606 return FILL_STATUS_FAILED; 2607 } 2608 for (aa = buffer; aa; aa = aa->Next) 2609 { 2610 if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; 2611 2612 rec = (struct record_networkadapterconfig *)(table->data + offset); 2613 rec->defaultipgateway = get_defaultipgateway( aa->FirstGatewayAddress ); 2614 rec->description = heap_strdupW( aa->Description ); 2615 rec->dhcpenabled = -1; 2616 rec->dnshostname = get_dnshostname( aa->FirstUnicastAddress ); 2617 rec->dnsserversearchorder = get_dnsserversearchorder( aa->FirstDnsServerAddress ); 2618 rec->index = aa->u.s.IfIndex; 2619 #ifndef __REACTOS__ 2620 rec->ipaddress = get_ipaddress( aa->FirstUnicastAddress ); 2621 #endif 2622 rec->ipconnectionmetric = 20; 2623 rec->ipenabled = -1; 2624 #ifndef __REACTOS__ 2625 rec->ipsubnet = get_ipsubnet( aa->FirstUnicastAddress ); 2626 #endif 2627 rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); 2628 rec->settingid = get_settingid( rec->index ); 2629 if (!match_row( table, row, cond, &status )) 2630 { 2631 free_row_values( table, row ); 2632 continue; 2633 } 2634 offset += sizeof(*rec); 2635 row++; 2636 } 2637 TRACE("created %u rows\n", row); 2638 table->num_rows = row; 2639 2640 heap_free( buffer ); 2641 return status; 2642 } 2643 2644 static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond ) 2645 { 2646 struct record_physicalmemory *rec; 2647 enum fill_status status = FILL_STATUS_UNFILTERED; 2648 UINT row = 0; 2649 2650 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 2651 2652 rec = (struct record_physicalmemory *)table->data; 2653 rec->capacity = get_total_physical_memory(); 2654 rec->memorytype = 9; /* RAM */ 2655 if (!match_row( table, row, cond, &status )) free_row_values( table, row ); 2656 else row++; 2657 2658 TRACE("created %u rows\n", row); 2659 table->num_rows = row; 2660 return status; 2661 } 2662 2663 static enum fill_status fill_pnpentity( struct table *table, const struct expr *cond ) 2664 { 2665 struct record_pnpentity *rec; 2666 enum fill_status status = FILL_STATUS_UNFILTERED; 2667 HDEVINFO device_info_set; 2668 SP_DEVINFO_DATA devinfo = {0}; 2669 DWORD idx; 2670 2671 device_info_set = SetupDiGetClassDevsW( NULL, NULL, NULL, DIGCF_ALLCLASSES|DIGCF_PRESENT ); 2672 2673 devinfo.cbSize = sizeof(devinfo); 2674 2675 idx = 0; 2676 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo )) 2677 { 2678 /* noop */ 2679 } 2680 2681 resize_table( table, idx, sizeof(*rec) ); 2682 table->num_rows = 0; 2683 rec = (struct record_pnpentity *)table->data; 2684 2685 idx = 0; 2686 while (SetupDiEnumDeviceInfo( device_info_set, idx++, &devinfo )) 2687 { 2688 WCHAR device_id[MAX_PATH]; 2689 if (SetupDiGetDeviceInstanceIdW( device_info_set, &devinfo, device_id, 2690 ARRAY_SIZE(device_id), NULL )) 2691 { 2692 rec->device_id = heap_strdupW( device_id ); 2693 2694 table->num_rows++; 2695 if (!match_row( table, table->num_rows - 1, cond, &status )) 2696 { 2697 free_row_values( table, table->num_rows - 1 ); 2698 table->num_rows--; 2699 } 2700 else 2701 rec++; 2702 } 2703 } 2704 2705 SetupDiDestroyDeviceInfoList( device_info_set ); 2706 2707 return status; 2708 } 2709 2710 static enum fill_status fill_printer( struct table *table, const struct expr *cond ) 2711 { 2712 static const WCHAR fmtW[] = {'P','r','i','n','t','e','r','%','d',0}; 2713 struct record_printer *rec; 2714 enum fill_status status = FILL_STATUS_UNFILTERED; 2715 PRINTER_INFO_2W *info; 2716 DWORD i, offset = 0, count = 0, size = 0, num_rows = 0; 2717 WCHAR id[20]; 2718 2719 EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &size, &count ); 2720 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FILL_STATUS_FAILED; 2721 2722 if (!(info = heap_alloc( size ))) return FILL_STATUS_FAILED; 2723 if (!EnumPrintersW( PRINTER_ENUM_LOCAL, NULL, 2, (BYTE *)info, size, &size, &count )) 2724 { 2725 heap_free( info ); 2726 return FILL_STATUS_FAILED; 2727 } 2728 if (!resize_table( table, count, sizeof(*rec) )) 2729 { 2730 heap_free( info ); 2731 return FILL_STATUS_FAILED; 2732 } 2733 2734 for (i = 0; i < count; i++) 2735 { 2736 rec = (struct record_printer *)(table->data + offset); 2737 rec->attributes = info[i].Attributes; 2738 sprintfW( id, fmtW, i ); 2739 rec->device_id = heap_strdupW( id ); 2740 rec->drivername = heap_strdupW( info[i].pDriverName ); 2741 rec->horizontalresolution = info[i].pDevMode->u1.s1.dmPrintQuality; 2742 rec->local = -1; 2743 rec->location = heap_strdupW( info[i].pLocation ); 2744 rec->name = heap_strdupW( info[i].pPrinterName ); 2745 rec->network = 0; 2746 rec->portname = heap_strdupW( info[i].pPortName ); 2747 if (!match_row( table, i, cond, &status )) 2748 { 2749 free_row_values( table, i ); 2750 continue; 2751 } 2752 offset += sizeof(*rec); 2753 num_rows++; 2754 } 2755 TRACE("created %u rows\n", num_rows); 2756 table->num_rows = num_rows; 2757 2758 heap_free( info ); 2759 return status; 2760 } 2761 2762 static WCHAR *get_cmdline( DWORD process_id ) 2763 { 2764 if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() ); 2765 return NULL; /* FIXME handle different process case */ 2766 } 2767 2768 static enum fill_status fill_process( struct table *table, const struct expr *cond ) 2769 { 2770 static const WCHAR fmtW[] = {'%','u',0}; 2771 WCHAR handle[11]; 2772 struct record_process *rec; 2773 PROCESSENTRY32W entry; 2774 HANDLE snap; 2775 enum fill_status status = FILL_STATUS_FAILED; 2776 UINT row = 0, offset = 0; 2777 2778 snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); 2779 if (snap == INVALID_HANDLE_VALUE) return FILL_STATUS_FAILED; 2780 2781 entry.dwSize = sizeof(entry); 2782 if (!Process32FirstW( snap, &entry )) goto done; 2783 if (!resize_table( table, 8, sizeof(*rec) )) goto done; 2784 2785 do 2786 { 2787 if (!resize_table( table, row + 1, sizeof(*rec) )) goto done; 2788 2789 rec = (struct record_process *)(table->data + offset); 2790 rec->caption = heap_strdupW( entry.szExeFile ); 2791 rec->commandline = get_cmdline( entry.th32ProcessID ); 2792 rec->description = heap_strdupW( entry.szExeFile ); 2793 sprintfW( handle, fmtW, entry.th32ProcessID ); 2794 rec->handle = heap_strdupW( handle ); 2795 rec->name = heap_strdupW( entry.szExeFile ); 2796 rec->process_id = entry.th32ProcessID; 2797 rec->pprocess_id = entry.th32ParentProcessID; 2798 rec->thread_count = entry.cntThreads; 2799 rec->workingsetsize = 0; 2800 rec->get_owner = process_get_owner; 2801 if (!match_row( table, row, cond, &status )) 2802 { 2803 free_row_values( table, row ); 2804 continue; 2805 } 2806 offset += sizeof(*rec); 2807 row++; 2808 } while (Process32NextW( snap, &entry )); 2809 2810 TRACE("created %u rows\n", row); 2811 table->num_rows = row; 2812 status = FILL_STATUS_UNFILTERED; 2813 2814 done: 2815 CloseHandle( snap ); 2816 return status; 2817 } 2818 2819 static inline void do_cpuid( unsigned int ax, unsigned int *p ) 2820 { 2821 #ifdef __i386__ 2822 #ifdef _MSC_VER 2823 __cpuid(p, ax); 2824 #else 2825 __asm__("pushl %%ebx\n\t" 2826 "cpuid\n\t" 2827 "movl %%ebx, %%esi\n\t" 2828 "popl %%ebx" 2829 : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3]) 2830 : "0" (ax)); 2831 #endif 2832 #endif 2833 } 2834 static const WCHAR *get_osarchitecture(void) 2835 { 2836 SYSTEM_INFO info; 2837 GetNativeSystemInfo( &info ); 2838 if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW; 2839 return os_32bitW; 2840 } 2841 static void get_processor_caption( WCHAR *caption ) 2842 { 2843 static const WCHAR fmtW[] = 2844 {'%','s',' ','F','a','m','i','l','y',' ','%','u',' ', 2845 'M','o','d','e','l',' ','%','u',' ','S','t','e','p','p','i','n','g',' ','%','u',0}; 2846 static const WCHAR x86W[] = {'x','8','6',0}; 2847 static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0}; 2848 const WCHAR *arch = (get_osarchitecture() == os_32bitW) ? x86W : intel64W; 2849 unsigned int regs[4] = {0, 0, 0, 0}; 2850 2851 do_cpuid( 1, regs ); 2852 sprintfW( caption, fmtW, arch, (regs[0] & (15 << 8)) >> 8, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 ); 2853 } 2854 static void get_processor_version( WCHAR *version ) 2855 { 2856 static const WCHAR fmtW[] = 2857 {'M','o','d','e','l',' ','%','u',',',' ','S','t','e','p','p','i','n','g',' ','%','u',0}; 2858 unsigned int regs[4] = {0, 0, 0, 0}; 2859 2860 do_cpuid( 1, regs ); 2861 sprintfW( version, fmtW, (regs[0] & (15 << 4)) >> 4, regs[0] & 15 ); 2862 } 2863 static UINT16 get_processor_revision(void) 2864 { 2865 unsigned int regs[4] = {0, 0, 0, 0}; 2866 do_cpuid( 1, regs ); 2867 return regs[0]; 2868 } 2869 static void get_processor_id( WCHAR *processor_id ) 2870 { 2871 static const WCHAR fmtW[] = {'%','0','8','X','%','0','8','X',0}; 2872 unsigned int regs[4] = {0, 0, 0, 0}; 2873 2874 do_cpuid( 1, regs ); 2875 sprintfW( processor_id, fmtW, regs[3], regs[0] ); 2876 } 2877 static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer ) 2878 { 2879 unsigned int i; 2880 unsigned char *p = (unsigned char *)regs; 2881 2882 for (i = 0; i < len; i++) { buffer[i] = *p++; } 2883 buffer[i] = 0; 2884 } 2885 static void get_processor_manufacturer( WCHAR *manufacturer ) 2886 { 2887 unsigned int tmp, regs[4] = {0, 0, 0, 0}; 2888 2889 do_cpuid( 0, regs ); 2890 tmp = regs[2]; /* swap edx and ecx */ 2891 regs[2] = regs[3]; 2892 regs[3] = tmp; 2893 2894 regs_to_str( regs + 1, 12, manufacturer ); 2895 } 2896 static void get_processor_name( WCHAR *name ) 2897 { 2898 unsigned int regs[4] = {0, 0, 0, 0}; 2899 2900 do_cpuid( 0x80000000, regs ); 2901 if (regs[0] >= 0x80000004) 2902 { 2903 do_cpuid( 0x80000002, regs ); 2904 regs_to_str( regs, 16, name ); 2905 do_cpuid( 0x80000003, regs ); 2906 regs_to_str( regs, 16, name + 16 ); 2907 do_cpuid( 0x80000004, regs ); 2908 regs_to_str( regs, 16, name + 32 ); 2909 } 2910 } 2911 static UINT get_processor_currentclockspeed( UINT index ) 2912 { 2913 PROCESSOR_POWER_INFORMATION *info; 2914 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION); 2915 NTSTATUS status; 2916 2917 if ((info = heap_alloc( size ))) 2918 { 2919 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size ); 2920 if (!status) ret = info[index].CurrentMhz; 2921 heap_free( info ); 2922 } 2923 return ret; 2924 } 2925 static UINT get_processor_maxclockspeed( UINT index ) 2926 { 2927 PROCESSOR_POWER_INFORMATION *info; 2928 UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION); 2929 NTSTATUS status; 2930 2931 if ((info = heap_alloc( size ))) 2932 { 2933 status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size ); 2934 if (!status) ret = info[index].MaxMhz; 2935 heap_free( info ); 2936 } 2937 return ret; 2938 } 2939 2940 static enum fill_status fill_processor( struct table *table, const struct expr *cond ) 2941 { 2942 static const WCHAR fmtW[] = {'C','P','U','%','u',0}; 2943 WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50]; 2944 struct record_processor *rec; 2945 UINT i, offset = 0, num_rows = 0, num_cores, num_logical_processors, count = get_processor_count(); 2946 enum fill_status status = FILL_STATUS_UNFILTERED; 2947 2948 if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED; 2949 2950 get_processor_caption( caption ); 2951 get_processor_id( processor_id ); 2952 get_processor_manufacturer( manufacturer ); 2953 get_processor_name( name ); 2954 get_processor_version( version ); 2955 2956 num_logical_processors = get_logical_processor_count( &num_cores ) / count; 2957 num_cores /= count; 2958 2959 for (i = 0; i < count; i++) 2960 { 2961 rec = (struct record_processor *)(table->data + offset); 2962 rec->addresswidth = get_osarchitecture() == os_32bitW ? 32 : 64; 2963 rec->architecture = get_osarchitecture() == os_32bitW ? 0 : 9; 2964 rec->caption = heap_strdupW( caption ); 2965 rec->cpu_status = 1; /* CPU Enabled */ 2966 rec->currentclockspeed = get_processor_currentclockspeed( i ); 2967 rec->datawidth = get_osarchitecture() == os_32bitW ? 32 : 64; 2968 rec->description = heap_strdupW( caption ); 2969 sprintfW( device_id, fmtW, i ); 2970 rec->device_id = heap_strdupW( device_id ); 2971 rec->family = 2; /* Unknown */ 2972 rec->level = 15; 2973 rec->manufacturer = heap_strdupW( manufacturer ); 2974 rec->maxclockspeed = get_processor_maxclockspeed( i ); 2975 rec->name = heap_strdupW( name ); 2976 rec->num_cores = num_cores; 2977 rec->num_logical_processors = num_logical_processors; 2978 rec->processor_id = heap_strdupW( processor_id ); 2979 rec->processortype = 3; /* central processor */ 2980 rec->revision = get_processor_revision(); 2981 rec->unique_id = NULL; 2982 rec->version = heap_strdupW( version ); 2983 if (!match_row( table, i, cond, &status )) 2984 { 2985 free_row_values( table, i ); 2986 continue; 2987 } 2988 offset += sizeof(*rec); 2989 num_rows++; 2990 } 2991 2992 TRACE("created %u rows\n", num_rows); 2993 table->num_rows = num_rows; 2994 return status; 2995 } 2996 2997 static WCHAR *get_lastbootuptime(void) 2998 { 2999 static const WCHAR fmtW[] = 3000 {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u', 3001 '.','%','0','6','u','+','0','0','0',0}; 3002 SYSTEM_TIMEOFDAY_INFORMATION ti; 3003 TIME_FIELDS tf; 3004 WCHAR *ret; 3005 3006 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL; 3007 3008 NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL ); 3009 RtlTimeToTimeFields( &ti.liKeBootTime, &tf ); 3010 sprintfW( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 ); 3011 return ret; 3012 } 3013 static WCHAR *get_localdatetime(void) 3014 { 3015 static const WCHAR fmtW[] = 3016 {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u', 3017 '.','%','0','6','u','%','+','0','3','d',0}; 3018 TIME_ZONE_INFORMATION tzi; 3019 SYSTEMTIME st; 3020 WCHAR *ret; 3021 DWORD Status; 3022 LONG Bias; 3023 3024 Status = GetTimeZoneInformation(&tzi); 3025 3026 if(Status == TIME_ZONE_ID_INVALID) return NULL; 3027 Bias = tzi.Bias; 3028 if(Status == TIME_ZONE_ID_DAYLIGHT) 3029 Bias+= tzi.DaylightBias; 3030 else 3031 Bias+= tzi.StandardBias; 3032 if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL; 3033 3034 GetLocalTime(&st); 3035 sprintfW( ret, fmtW, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000, -Bias); 3036 return ret; 3037 } 3038 static WCHAR *get_systemdirectory(void) 3039 { 3040 void *redir; 3041 WCHAR *ret; 3042 3043 if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL; 3044 Wow64DisableWow64FsRedirection( &redir ); 3045 GetSystemDirectoryW( ret, MAX_PATH ); 3046 Wow64RevertWow64FsRedirection( redir ); 3047 return ret; 3048 } 3049 static WCHAR *get_codeset(void) 3050 { 3051 static const WCHAR fmtW[] = {'%','u',0}; 3052 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) ); 3053 if (ret) sprintfW( ret, fmtW, GetACP() ); 3054 return ret; 3055 } 3056 static WCHAR *get_countrycode(void) 3057 { 3058 WCHAR *ret = heap_alloc( 6 * sizeof(WCHAR) ); 3059 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, ret, 6 ); 3060 return ret; 3061 } 3062 static WCHAR *get_locale(void) 3063 { 3064 WCHAR *ret = heap_alloc( 5 * sizeof(WCHAR) ); 3065 if (ret) GetLocaleInfoW( LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, ret, 5 ); 3066 return ret; 3067 } 3068 static WCHAR *get_osbuildnumber( OSVERSIONINFOEXW *ver ) 3069 { 3070 static const WCHAR fmtW[] = {'%','u',0}; 3071 WCHAR *ret = heap_alloc( 11 * sizeof(WCHAR) ); 3072 if (ret) sprintfW( ret, fmtW, ver->dwBuildNumber ); 3073 return ret; 3074 } 3075 static WCHAR *get_oscaption( OSVERSIONINFOEXW *ver ) 3076 { 3077 static const WCHAR windowsW[] = 3078 {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' '}; 3079 static const WCHAR win2000W[] = 3080 {'2','0','0','0',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; 3081 static const WCHAR win2003W[] = 3082 {'S','e','r','v','e','r',' ','2','0','0','3',' ','S','t','a','n','d','a','r','d',' ','E','d','i','t','i','o','n',0}; 3083 static const WCHAR winxpW[] = 3084 {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; 3085 static const WCHAR winxp64W[] = 3086 {'X','P',' ','P','r','o','f','e','s','s','i','o','n','a','l',' ','x','6','4',' ','E','d','i','t','i','o','n',0}; 3087 static const WCHAR vistaW[] = 3088 {'V','i','s','t','a',' ','U','l','t','i','m','a','t','e',0}; 3089 static const WCHAR win2008W[] = 3090 {'S','e','r','v','e','r',' ','2','0','0','8',' ','S','t','a','n','d','a','r','d',0}; 3091 static const WCHAR win7W[] = 3092 {'7',' ','P','r','o','f','e','s','s','i','o','n','a','l',0}; 3093 static const WCHAR win2008r2W[] = 3094 {'S','e','r','v','e','r',' ','2','0','0','8',' ','R','2',' ','S','t','a','n','d','a','r','d',0}; 3095 static const WCHAR win8W[] = 3096 {'8',' ','P','r','o',0}; 3097 static const WCHAR win81W[] = 3098 {'8','.','1',' ','P','r','o',0}; 3099 static const WCHAR win10W[] = 3100 {'1','0',' ','P','r','o',0}; 3101 int len = ARRAY_SIZE( windowsW ); 3102 WCHAR *ret; 3103 3104 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(win2003W) ))) return NULL; 3105 memcpy( ret, windowsW, sizeof(windowsW) ); 3106 if (ver->dwMajorVersion == 10 && ver->dwMinorVersion == 0) memcpy( ret + len, win10W, sizeof(win10W) ); 3107 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 3) memcpy( ret + len, win8W, sizeof(win8W) ); 3108 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 2) memcpy( ret + len, win81W, sizeof(win81W) ); 3109 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 1) 3110 { 3111 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, win7W, sizeof(win7W) ); 3112 else memcpy( ret + len, win2008r2W, sizeof(win2008r2W) ); 3113 } 3114 else if (ver->dwMajorVersion == 6 && ver->dwMinorVersion == 0) 3115 { 3116 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, vistaW, sizeof(vistaW) ); 3117 else memcpy( ret + len, win2008W, sizeof(win2008W) ); 3118 } 3119 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 2) 3120 { 3121 if (ver->wProductType == VER_NT_WORKSTATION) memcpy( ret + len, winxp64W, sizeof(winxp64W) ); 3122 else memcpy( ret + len, win2003W, sizeof(win2003W) ); 3123 } 3124 else if (ver->dwMajorVersion == 5 && ver->dwMinorVersion == 1) memcpy( ret + len, winxpW, sizeof(winxpW) ); 3125 else memcpy( ret + len, win2000W, sizeof(win2000W) ); 3126 return ret; 3127 } 3128 static WCHAR *get_osname( const WCHAR *caption ) 3129 { 3130 static const WCHAR partitionW[] = 3131 {'|','C',':','\\','W','I','N','D','O','W','S','|','\\','D','e','v','i','c','e','\\', 3132 'H','a','r','d','d','i','s','k','0','\\','P','a','r','t','i','t','i','o','n','1',0}; 3133 int len = strlenW( caption ); 3134 WCHAR *ret; 3135 3136 if (!(ret = heap_alloc( len * sizeof(WCHAR) + sizeof(partitionW) ))) return NULL; 3137 memcpy( ret, caption, len * sizeof(WCHAR) ); 3138 memcpy( ret + len, partitionW, sizeof(partitionW) ); 3139 return ret; 3140 } 3141 static WCHAR *get_osversion( OSVERSIONINFOEXW *ver ) 3142 { 3143 static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u',0}; 3144 WCHAR *ret = heap_alloc( 33 * sizeof(WCHAR) ); 3145 if (ret) sprintfW( ret, fmtW, ver->dwMajorVersion, ver->dwMinorVersion, ver->dwBuildNumber ); 3146 return ret; 3147 } 3148 3149 static enum fill_status fill_os( struct table *table, const struct expr *cond ) 3150 { 3151 struct record_operatingsystem *rec; 3152 enum fill_status status = FILL_STATUS_UNFILTERED; 3153 OSVERSIONINFOEXW ver; 3154 UINT row = 0; 3155 3156 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 3157 3158 ver.dwOSVersionInfoSize = sizeof(ver); 3159 GetVersionExW( (OSVERSIONINFOW *)&ver ); 3160 3161 rec = (struct record_operatingsystem *)table->data; 3162 rec->buildnumber = get_osbuildnumber( &ver ); 3163 rec->caption = get_oscaption( &ver ); 3164 rec->codeset = get_codeset(); 3165 rec->countrycode = get_countrycode(); 3166 rec->csdversion = ver.szCSDVersion[0] ? heap_strdupW( ver.szCSDVersion ) : NULL; 3167 rec->freephysicalmemory = get_available_physical_memory() / 1024; 3168 rec->installdate = os_installdateW; 3169 rec->lastbootuptime = get_lastbootuptime(); 3170 rec->localdatetime = get_localdatetime(); 3171 rec->locale = get_locale(); 3172 rec->name = get_osname( rec->caption ); 3173 rec->osarchitecture = get_osarchitecture(); 3174 rec->oslanguage = GetSystemDefaultLangID(); 3175 rec->osproductsuite = 2461140; /* Windows XP Professional */ 3176 rec->ostype = 18; /* WINNT */ 3177 rec->primary = -1; 3178 rec->serialnumber = os_serialnumberW; 3179 rec->servicepackmajor = ver.wServicePackMajor; 3180 rec->servicepackminor = ver.wServicePackMinor; 3181 rec->suitemask = 272; /* Single User + Terminal */ 3182 rec->systemdirectory = get_systemdirectory(); 3183 rec->totalvirtualmemorysize = get_total_physical_memory() / 1024; 3184 rec->totalvisiblememorysize = rec->totalvirtualmemorysize; 3185 rec->version = get_osversion( &ver ); 3186 if (!match_row( table, row, cond, &status )) free_row_values( table, row ); 3187 else row++; 3188 3189 TRACE("created %u rows\n", row); 3190 table->num_rows = row; 3191 return status; 3192 } 3193 3194 static const WCHAR *get_service_type( DWORD type ) 3195 { 3196 static const WCHAR filesystem_driverW[] = 3197 {'F','i','l','e',' ','S','y','s','t','e','m',' ','D','r','i','v','e','r',0}; 3198 static const WCHAR kernel_driverW[] = 3199 {'K','e','r','n','e','l',' ','D','r','i','v','e','r',0}; 3200 static const WCHAR own_processW[] = 3201 {'O','w','n',' ','P','r','o','c','e','s','s',0}; 3202 static const WCHAR share_processW[] = 3203 {'S','h','a','r','e',' ','P','r','o','c','e','s','s',0}; 3204 3205 if (type & SERVICE_KERNEL_DRIVER) return kernel_driverW; 3206 else if (type & SERVICE_FILE_SYSTEM_DRIVER) return filesystem_driverW; 3207 else if (type & SERVICE_WIN32_OWN_PROCESS) return own_processW; 3208 else if (type & SERVICE_WIN32_SHARE_PROCESS) return share_processW; 3209 else ERR("unhandled type 0x%08x\n", type); 3210 return NULL; 3211 } 3212 static const WCHAR *get_service_state( DWORD state ) 3213 { 3214 static const WCHAR runningW[] = 3215 {'R','u','n','n','i','n','g',0}; 3216 static const WCHAR start_pendingW[] = 3217 {'S','t','a','r','t',' ','P','e','n','d','i','n','g',0}; 3218 static const WCHAR stop_pendingW[] = 3219 {'S','t','o','p',' ','P','e','n','d','i','n','g',0}; 3220 static const WCHAR stoppedW[] = 3221 {'S','t','o','p','p','e','d',0}; 3222 static const WCHAR unknownW[] = 3223 {'U','n','k','n','o','w','n',0}; 3224 3225 switch (state) 3226 { 3227 case SERVICE_STOPPED: return stoppedW; 3228 case SERVICE_START_PENDING: return start_pendingW; 3229 case SERVICE_STOP_PENDING: return stop_pendingW; 3230 case SERVICE_RUNNING: return runningW; 3231 default: 3232 ERR("unknown state %u\n", state); 3233 return unknownW; 3234 } 3235 } 3236 static const WCHAR *get_service_startmode( DWORD mode ) 3237 { 3238 static const WCHAR bootW[] = {'B','o','o','t',0}; 3239 static const WCHAR systemW[] = {'S','y','s','t','e','m',0}; 3240 static const WCHAR autoW[] = {'A','u','t','o',0}; 3241 static const WCHAR manualW[] = {'M','a','n','u','a','l',0}; 3242 static const WCHAR disabledW[] = {'D','i','s','a','b','l','e','d',0}; 3243 static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',0}; 3244 3245 switch (mode) 3246 { 3247 case SERVICE_BOOT_START: return bootW; 3248 case SERVICE_SYSTEM_START: return systemW; 3249 case SERVICE_AUTO_START: return autoW; 3250 case SERVICE_DEMAND_START: return manualW; 3251 case SERVICE_DISABLED: return disabledW; 3252 default: 3253 ERR("unknown mode 0x%x\n", mode); 3254 return unknownW; 3255 } 3256 } 3257 static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name ) 3258 { 3259 QUERY_SERVICE_CONFIGW *config = NULL; 3260 SC_HANDLE service; 3261 DWORD size; 3262 3263 if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL; 3264 QueryServiceConfigW( service, NULL, 0, &size ); 3265 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; 3266 if (!(config = heap_alloc( size ))) goto done; 3267 if (QueryServiceConfigW( service, config, size, &size )) goto done; 3268 heap_free( config ); 3269 config = NULL; 3270 3271 done: 3272 CloseServiceHandle( service ); 3273 return config; 3274 } 3275 3276 static enum fill_status fill_service( struct table *table, const struct expr *cond ) 3277 { 3278 struct record_service *rec; 3279 SC_HANDLE manager; 3280 ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL; 3281 SERVICE_STATUS_PROCESS *status; 3282 WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1]; 3283 DWORD len = ARRAY_SIZE( sysnameW ); 3284 UINT i, row = 0, offset = 0, size = 256, needed, count; 3285 enum fill_status fill_status = FILL_STATUS_FAILED; 3286 BOOL ret; 3287 3288 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return FILL_STATUS_FAILED; 3289 if (!(services = heap_alloc( size ))) goto done; 3290 3291 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, 3292 SERVICE_STATE_ALL, (BYTE *)services, size, &needed, 3293 &count, NULL, NULL ); 3294 if (!ret) 3295 { 3296 if (GetLastError() != ERROR_MORE_DATA) goto done; 3297 size = needed; 3298 if (!(tmp = heap_realloc( services, size ))) goto done; 3299 services = tmp; 3300 ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, 3301 SERVICE_STATE_ALL, (BYTE *)services, size, &needed, 3302 &count, NULL, NULL ); 3303 if (!ret) goto done; 3304 } 3305 if (!resize_table( table, count, sizeof(*rec) )) goto done; 3306 3307 GetComputerNameW( sysnameW, &len ); 3308 fill_status = FILL_STATUS_UNFILTERED; 3309 3310 for (i = 0; i < count; i++) 3311 { 3312 QUERY_SERVICE_CONFIGW *config; 3313 3314 if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue; 3315 3316 status = &services[i].ServiceStatusProcess; 3317 rec = (struct record_service *)(table->data + offset); 3318 rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0; 3319 rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0; 3320 rec->displayname = heap_strdupW( services[i].lpDisplayName ); 3321 rec->name = heap_strdupW( services[i].lpServiceName ); 3322 rec->process_id = status->dwProcessId; 3323 rec->servicetype = get_service_type( status->dwServiceType ); 3324 rec->startmode = get_service_startmode( config->dwStartType ); 3325 rec->state = get_service_state( status->dwCurrentState ); 3326 rec->systemname = heap_strdupW( sysnameW ); 3327 rec->pause_service = service_pause_service; 3328 rec->resume_service = service_resume_service; 3329 rec->start_service = service_start_service; 3330 rec->stop_service = service_stop_service; 3331 heap_free( config ); 3332 if (!match_row( table, row, cond, &fill_status )) 3333 { 3334 free_row_values( table, row ); 3335 continue; 3336 } 3337 offset += sizeof(*rec); 3338 row++; 3339 } 3340 3341 TRACE("created %u rows\n", row); 3342 table->num_rows = row; 3343 3344 done: 3345 CloseServiceHandle( manager ); 3346 heap_free( services ); 3347 return fill_status; 3348 } 3349 3350 static WCHAR *get_accountname( LSA_TRANSLATED_NAME *name ) 3351 { 3352 if (!name || !name->Name.Buffer) return NULL; 3353 return heap_strdupW( name->Name.Buffer ); 3354 } 3355 static struct array *get_binaryrepresentation( PSID sid, UINT len ) 3356 { 3357 struct array *array = heap_alloc( sizeof(struct array) ); 3358 if (array) 3359 { 3360 UINT8 *ret = heap_alloc( len ); 3361 if (ret) 3362 { 3363 memcpy( ret, sid, len ); 3364 array->count = len; 3365 array->ptr = ret; 3366 return array; 3367 } 3368 heap_free( array ); 3369 } 3370 return NULL; 3371 } 3372 static WCHAR *get_referenceddomainname( LSA_REFERENCED_DOMAIN_LIST *domain ) 3373 { 3374 if (!domain || !domain->Domains || !domain->Domains->Name.Buffer) return NULL; 3375 return heap_strdupW( domain->Domains->Name.Buffer ); 3376 } 3377 static const WCHAR *find_sid_str( const struct expr *cond ) 3378 { 3379 const struct expr *left, *right; 3380 const WCHAR *ret = NULL; 3381 3382 if (!cond || cond->type != EXPR_COMPLEX || cond->u.expr.op != OP_EQ) return NULL; 3383 3384 left = cond->u.expr.left; 3385 right = cond->u.expr.right; 3386 if (left->type == EXPR_PROPVAL && right->type == EXPR_SVAL && !strcmpiW( left->u.propval->name, prop_sidW )) 3387 { 3388 ret = right->u.sval; 3389 } 3390 else if (left->type == EXPR_SVAL && right->type == EXPR_PROPVAL && !strcmpiW( right->u.propval->name, prop_sidW )) 3391 { 3392 ret = left->u.sval; 3393 } 3394 return ret; 3395 } 3396 3397 static enum fill_status fill_sid( struct table *table, const struct expr *cond ) 3398 { 3399 PSID sid; 3400 LSA_REFERENCED_DOMAIN_LIST *domain; 3401 LSA_TRANSLATED_NAME *name; 3402 LSA_HANDLE handle; 3403 LSA_OBJECT_ATTRIBUTES attrs; 3404 const WCHAR *str; 3405 struct record_sid *rec; 3406 UINT len; 3407 3408 if (!(str = find_sid_str( cond ))) return FILL_STATUS_FAILED; 3409 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 3410 3411 if (!ConvertStringSidToSidW( str, &sid )) return FILL_STATUS_FAILED; 3412 len = GetLengthSid( sid ); 3413 3414 memset( &attrs, 0, sizeof(attrs) ); 3415 attrs.Length = sizeof(attrs); 3416 if (LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle )) 3417 { 3418 LocalFree( sid ); 3419 return FILL_STATUS_FAILED; 3420 } 3421 if (LsaLookupSids( handle, 1, &sid, &domain, &name )) 3422 { 3423 LocalFree( sid ); 3424 LsaClose( handle ); 3425 return FILL_STATUS_FAILED; 3426 } 3427 3428 rec = (struct record_sid *)table->data; 3429 rec->accountname = get_accountname( name ); 3430 rec->binaryrepresentation = get_binaryrepresentation( sid, len ); 3431 rec->referenceddomainname = get_referenceddomainname( domain ); 3432 rec->sid = heap_strdupW( str ); 3433 rec->sidlength = len; 3434 3435 TRACE("created 1 row\n"); 3436 table->num_rows = 1; 3437 3438 LsaFreeMemory( domain ); 3439 LsaFreeMemory( name ); 3440 LocalFree( sid ); 3441 LsaClose( handle ); 3442 return FILL_STATUS_FILTERED; 3443 } 3444 3445 #ifndef __REACTOS__ 3446 3447 static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres ) 3448 { 3449 HDC hdc = GetDC( NULL ); 3450 UINT32 ret; 3451 3452 if (!hdc) return 32; 3453 ret = GetDeviceCaps( hdc, BITSPIXEL ); 3454 *hres = GetDeviceCaps( hdc, HORZRES ); 3455 *vres = GetDeviceCaps( hdc, VERTRES ); 3456 ReleaseDC( NULL, hdc ); 3457 return ret; 3458 } 3459 static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc ) 3460 { 3461 static const WCHAR fmtW[] = 3462 {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X', 3463 '&','S','U','B','S','Y','S','_','%','0','8','X','&','R','E','V','_','%','0','2','X','\\', 3464 '0','&','D','E','A','D','B','E','E','F','&','0','&','D','E','A','D',0}; 3465 WCHAR *ret; 3466 3467 if (!(ret = heap_alloc( sizeof(fmtW) + 2 * sizeof(WCHAR) ))) return NULL; 3468 sprintfW( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision ); 3469 return ret; 3470 } 3471 3472 #define HW_VENDOR_AMD 0x1002 3473 #define HW_VENDOR_NVIDIA 0x10de 3474 #define HW_VENDOR_VMWARE 0x15ad 3475 #define HW_VENDOR_INTEL 0x8086 3476 3477 static const WCHAR *get_installeddriver( UINT vendorid ) 3478 { 3479 static const WCHAR driver_amdW[] = {'a','t','i','c','f','x','3','2','.','d','l','l',0}; 3480 static const WCHAR driver_intelW[] = {'i','g','d','u','m','d','i','m','3','2','.','d','l','l',0}; 3481 static const WCHAR driver_nvidiaW[] = {'n','v','d','3','d','u','m','.','d','l','l',0}; 3482 static const WCHAR driver_wineW[] = {'w','i','n','e','.','d','l','l',0}; 3483 3484 /* FIXME: wined3d has a better table, but we cannot access this information through dxgi */ 3485 3486 if (vendorid == HW_VENDOR_AMD) 3487 return driver_amdW; 3488 else if (vendorid == HW_VENDOR_NVIDIA) 3489 return driver_nvidiaW; 3490 else if (vendorid == HW_VENDOR_INTEL) 3491 return driver_intelW; 3492 return driver_wineW; 3493 } 3494 3495 static enum fill_status fill_videocontroller( struct table *table, const struct expr *cond ) 3496 { 3497 static const WCHAR fmtW[] = {'%','u',' ','x',' ','%','u',' ','x',' ','%','I','6','4','u',' ','c','o','l','o','r','s',0}; 3498 struct record_videocontroller *rec; 3499 HRESULT hr; 3500 IDXGIFactory *factory = NULL; 3501 IDXGIAdapter *adapter = NULL; 3502 DXGI_ADAPTER_DESC desc; 3503 UINT row = 0, hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024; 3504 const WCHAR *name = videocontroller_deviceidW; 3505 enum fill_status status = FILL_STATUS_UNFILTERED; 3506 WCHAR mode[44]; 3507 3508 if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; 3509 3510 memset (&desc, 0, sizeof(desc)); 3511 hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory ); 3512 if (FAILED(hr)) goto done; 3513 3514 hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter ); 3515 if (FAILED(hr)) goto done; 3516 3517 hr = IDXGIAdapter_GetDesc( adapter, &desc ); 3518 if (SUCCEEDED(hr)) 3519 { 3520 vidmem = desc.DedicatedVideoMemory; 3521 name = desc.Description; 3522 } 3523 3524 done: 3525 rec = (struct record_videocontroller *)table->data; 3526 rec->adapter_dactype = videocontroller_dactypeW; 3527 rec->adapter_ram = vidmem; 3528 rec->availability = 3; /* Running or Full Power */ 3529 rec->config_errorcode = 0; /* no error */ 3530 rec->caption = heap_strdupW( name ); 3531 rec->current_bitsperpixel = get_bits_per_pixel( &hres, &vres ); 3532 rec->current_horizontalres = hres; 3533 rec->current_refreshrate = 0; /* default refresh rate */ 3534 rec->current_scanmode = 2; /* Unknown */ 3535 rec->current_verticalres = vres; 3536 rec->description = heap_strdupW( name ); 3537 rec->device_id = videocontroller_deviceidW; 3538 rec->driverdate = videocontroller_driverdateW; 3539 rec->driverversion = videocontroller_driverversionW; 3540 rec->installeddriver = get_installeddriver( desc.VendorId ); 3541 rec->name = heap_strdupW( name ); 3542 rec->pnpdevice_id = get_pnpdeviceid( &desc ); 3543 rec->status = videocontroller_statusW; 3544 rec->videoarchitecture = 2; /* Unknown */ 3545 rec->videomemorytype = 2; /* Unknown */ 3546 wsprintfW( mode, fmtW, hres, vres, (UINT64)1 << rec->current_bitsperpixel ); 3547 rec->videomodedescription = heap_strdupW( mode ); 3548 rec->videoprocessor = heap_strdupW( name ); 3549 if (!match_row( table, row, cond, &status )) free_row_values( table, row ); 3550 else row++; 3551 3552 TRACE("created %u rows\n", row); 3553 table->num_rows = row; 3554 3555 if (adapter) IDXGIAdapter_Release( adapter ); 3556 if (factory) IDXGIFactory_Release( factory ); 3557 return status; 3558 } 3559 3560 #endif /* !__REACTOS__ */ 3561 3562 static struct table builtin_classes[] = 3563 { 3564 { class_baseboardW, ARRAY_SIZE(col_baseboard), col_baseboard, ARRAY_SIZE(data_baseboard), 0, (BYTE *)data_baseboard }, 3565 { class_biosW, ARRAY_SIZE(col_bios), col_bios, ARRAY_SIZE(data_bios), 0, (BYTE *)data_bios }, 3566 { class_cdromdriveW, ARRAY_SIZE(col_cdromdrive), col_cdromdrive, 0, 0, NULL, fill_cdromdrive }, 3567 { class_compsysW, ARRAY_SIZE(col_compsys), col_compsys, 0, 0, NULL, fill_compsys }, 3568 { class_compsysproductW, ARRAY_SIZE(col_compsysproduct), col_compsysproduct, 0, 0, NULL, fill_compsysproduct }, 3569 { class_datafileW, ARRAY_SIZE(col_datafile), col_datafile, 0, 0, NULL, fill_datafile }, 3570 { class_desktopmonitorW, ARRAY_SIZE(col_desktopmonitor), col_desktopmonitor, 0, 0, NULL, fill_desktopmonitor }, 3571 { class_directoryW, ARRAY_SIZE(col_directory), col_directory, 0, 0, NULL, fill_directory }, 3572 { class_diskdriveW, ARRAY_SIZE(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive }, 3573 { class_diskpartitionW, ARRAY_SIZE(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition }, 3574 { class_ip4routetableW, ARRAY_SIZE(col_ip4routetable), col_ip4routetable, 0, 0, NULL, fill_ip4routetable }, 3575 { class_logicaldiskW, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk }, 3576 { class_logicaldisk2W, ARRAY_SIZE(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk }, 3577 { class_networkadapterW, ARRAY_SIZE(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter }, 3578 { class_networkadapterconfigW, ARRAY_SIZE(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, fill_networkadapterconfig }, 3579 { class_osW, ARRAY_SIZE(col_os), col_os, 0, 0, NULL, fill_os }, 3580 { class_paramsW, ARRAY_SIZE(col_param), col_param, ARRAY_SIZE(data_param), 0, (BYTE *)data_param }, 3581 { class_physicalmediaW, ARRAY_SIZE(col_physicalmedia), col_physicalmedia, ARRAY_SIZE(data_physicalmedia), 0, (BYTE *)data_physicalmedia }, 3582 { class_physicalmemoryW, ARRAY_SIZE(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory }, 3583 { class_pnpentityW, ARRAY_SIZE(col_pnpentity), col_pnpentity, 0, 0, NULL, fill_pnpentity }, 3584 { class_printerW, ARRAY_SIZE(col_printer), col_printer, 0, 0, NULL, fill_printer }, 3585 { class_processW, ARRAY_SIZE(col_process), col_process, 0, 0, NULL, fill_process }, 3586 { class_processorW, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor }, 3587 { class_processor2W, ARRAY_SIZE(col_processor), col_processor, 0, 0, NULL, fill_processor }, 3588 { class_qualifiersW, ARRAY_SIZE(col_qualifier), col_qualifier, ARRAY_SIZE(data_qualifier), 0, (BYTE *)data_qualifier }, 3589 { class_serviceW, ARRAY_SIZE(col_service), col_service, 0, 0, NULL, fill_service }, 3590 { class_sidW, ARRAY_SIZE(col_sid), col_sid, 0, 0, NULL, fill_sid }, 3591 { class_sounddeviceW, ARRAY_SIZE(col_sounddevice), col_sounddevice, ARRAY_SIZE(data_sounddevice), 0, (BYTE *)data_sounddevice }, 3592 { class_stdregprovW, ARRAY_SIZE(col_stdregprov), col_stdregprov, ARRAY_SIZE(data_stdregprov), 0, (BYTE *)data_stdregprov }, 3593 { class_systemsecurityW, ARRAY_SIZE(col_systemsecurity), col_systemsecurity, ARRAY_SIZE(data_systemsecurity), 0, (BYTE *)data_systemsecurity }, 3594 { class_systemenclosureW, ARRAY_SIZE(col_systemenclosure), col_systemenclosure, ARRAY_SIZE(data_systemenclosure), 0, (BYTE *)data_systemenclosure }, 3595 #ifndef __REACTOS__ 3596 /* Requires dxgi.dll */ 3597 { class_videocontrollerW, ARRAY_SIZE(col_videocontroller), col_videocontroller, 0, 0, NULL, fill_videocontroller } 3598 #endif 3599 }; 3600 3601 void init_table_list( void ) 3602 { 3603 static struct list tables = LIST_INIT( tables ); 3604 UINT i; 3605 3606 for (i = 0; i < ARRAY_SIZE(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry ); 3607 table_list = &tables; 3608 } 3609