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