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