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