Subversion Repositories ALCASAR

Rev

Rev 2976 | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
2770 rexy 1
<?php
2
/**
3
 * WINNT System Class
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PSI WINNT OS class
9
 * @author    Michael Cramer <BigMichi1@users.sourceforge.net>
10
 * @copyright 2009 phpSysInfo
11
 * @license   http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
12
 * @version   SVN: $Id: class.WINNT.inc.php 699 2012-09-15 11:57:13Z namiltd $
13
 * @link      http://phpsysinfo.sourceforge.net
14
 */
15
 /**
16
 * WINNT sysinfo class
17
 * get all the required information from WINNT systems
18
 * information are retrieved through the WMI interface
19
 *
20
 * @category  PHP
21
 * @package   PSI WINNT OS class
22
 * @author    Michael Cramer <BigMichi1@users.sourceforge.net>
23
 * @copyright 2009 phpSysInfo
24
 * @license   http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
25
 * @version   Release: 3.0
26
 * @link      http://phpsysinfo.sourceforge.net
27
 */
28
class WINNT extends OS
29
{
30
    /**
3037 rexy 31
     * holds codepage for chcp
32
     *
33
     * @var int
34
     */
35
    private static $_cp = null;
36
 
37
    /**
2770 rexy 38
     * holds the data from WMI Win32_OperatingSystem
39
     *
40
     * @var array
41
     */
3037 rexy 42
    private static $_Win32_OperatingSystem = null;
325 richard 43
 
2770 rexy 44
    /**
45
     * holds the data from WMI Win32_ComputerSystem
46
     *
47
     * @var array
48
     */
49
    private $_Win32_ComputerSystem = null;
325 richard 50
 
2770 rexy 51
    /**
52
     * holds the data from WMI Win32_Processor
53
     *
54
     * @var array
55
     */
3037 rexy 56
    private static $_Win32_Processor = null;
325 richard 57
 
3037 rexy 58
    /**
59
     * holds the data from WMI Win32_PhysicalMemory
60
     *
61
     * @var array
62
     */
63
    private static $_Win32_PhysicalMemory = null;
64
 
2770 rexy 65
     /**
66
     * holds the data from WMI Win32_PerfFormattedData_PerfOS_Processor
67
     *
68
     * @var array
69
     */
70
    private $_Win32_PerfFormattedData_PerfOS_Processor = null;
325 richard 71
 
2770 rexy 72
    /**
73
     * holds the data from systeminfo command
74
     *
75
     * @var string
76
     */
77
    private $_systeminfo = null;
325 richard 78
 
2770 rexy 79
    /**
2976 rexy 80
     * holds the COM object that we pull WMI root\CIMv2 data from
2770 rexy 81
     *
82
     * @var Object
83
     */
3037 rexy 84
    private static $_wmi = null;
325 richard 85
 
2770 rexy 86
    /**
2976 rexy 87
     * holds the COM object that we pull all the EnumKey and RegRead data from
2770 rexy 88
     *
89
     * @var Object
90
     */
91
    private $_reg = null;
92
 
93
    /**
2976 rexy 94
     * holds result of 'cmd /c ver'
2770 rexy 95
     *
2976 rexy 96
     * @var string
2770 rexy 97
     */
2976 rexy 98
    private $_ver = "";
2770 rexy 99
 
100
    /**
3037 rexy 101
     * holds system manufacturer
102
     *
103
     * @var string
104
     */
105
    private $_Manufacturer = "";
106
 
107
    /**
108
     * holds system model
109
     *
110
     * @var string
111
     */
112
    private $_Model = "";
113
 
114
    /**
2770 rexy 115
     * holds all devices, which are in the system
116
     *
117
     * @var array
118
     */
3037 rexy 119
    private $_wmidevices = null;
2770 rexy 120
 
121
    /**
122
     * holds all disks, which are in the system
123
     *
124
     * @var array
125
     */
2976 rexy 126
    private $_wmidisks = array();
2770 rexy 127
 
128
    /**
129
     * store language encoding of the system to convert some output to utf-8
130
     *
131
     * @var string
132
     */
133
    private $_codepage = null;
134
 
135
    /**
136
     * store language of the system
137
     *
138
     * @var string
139
     */
140
    private $_syslang = null;
141
 
142
    /**
3037 rexy 143
     * value of checking run as administrator
144
     *
145
     * @var boolean
146
     */
147
    private static $_asadmin = null;
148
 
149
    /**
150
     * returns codepage for chcp
151
     *
152
     * @return int
153
     */
154
    public static function getcp()
155
    {
156
        return self::$_cp;
157
    }
158
 
159
    /**
160
     * returns the COM object that we pull WMI root\CIMv2 data from
161
     *
162
     * @return Object
163
     */
164
    public static function getcimv2wmi()
165
    {
166
        return self::$_wmi;
167
    }
168
 
169
    /**
2770 rexy 170
     * reads the data from WMI Win32_OperatingSystem
171
     *
172
     * @return array
173
     */
3037 rexy 174
    public static function _get_Win32_OperatingSystem()
2770 rexy 175
    {
3037 rexy 176
        if (self::$_Win32_OperatingSystem === null) self::$_Win32_OperatingSystem = self::getWMI(self::$_wmi, 'Win32_OperatingSystem', array('CodeSet', 'Locale', 'LastBootUpTime', 'LocalDateTime', 'Version', 'ServicePackMajorVersion', 'Caption', 'TotalVisibleMemorySize', 'FreePhysicalMemory'));
177
        return self::$_Win32_OperatingSystem;
325 richard 178
    }
179
 
2770 rexy 180
    /**
181
     * reads the data from WMI Win32_ComputerSystem
182
     *
183
     * @return array
184
     */
185
    private function _get_Win32_ComputerSystem()
325 richard 186
    {
3037 rexy 187
        if ($this->_Win32_ComputerSystem === null) $this->_Win32_ComputerSystem = self::getWMI(self::$_wmi, 'Win32_ComputerSystem', array('Name', 'Manufacturer', 'Model', 'SystemFamily'));
2770 rexy 188
        return $this->_Win32_ComputerSystem;
189
    }
190
 
191
    /**
192
     * reads the data from WMI Win32_Processor
193
     *
194
     * @return array
195
     */
3037 rexy 196
    public static function _get_Win32_Processor()
2770 rexy 197
    {
3037 rexy 198
        if (self::$_Win32_Processor === null) self::$_Win32_Processor = self::getWMI(self::$_wmi, 'Win32_Processor', array('DeviceID', 'LoadPercentage', 'AddressWidth', 'Name', 'L2CacheSize', 'L3CacheSize', 'CurrentClockSpeed', 'ExtClock', 'NumberOfCores', 'NumberOfLogicalProcessors', 'MaxClockSpeed', 'Manufacturer', 'Architecture', 'Caption', 'CurrentVoltage'));
199
        return self::$_Win32_Processor;
2770 rexy 200
    }
201
 
202
    /**
3037 rexy 203
     * reads the data from WMI Win32_PhysicalMemory
204
     *
205
     * @return array
206
     */
207
    public static function _get_Win32_PhysicalMemory()
208
    {
209
        if (self::$_Win32_PhysicalMemory === null) self::$_Win32_PhysicalMemory = self::getWMI(self::$_wmi, 'Win32_PhysicalMemory', array('PartNumber', 'DeviceLocator', 'Capacity', 'Manufacturer', 'SerialNumber', 'Speed', 'ConfiguredClockSpeed', 'ConfiguredVoltage', 'MemoryType', 'SMBIOSMemoryType', 'FormFactor', 'DataWidth', 'TotalWidth', 'BankLabel', 'MinVoltage', 'MaxVoltage'));
210
        return self::$_Win32_PhysicalMemory;
211
    }
212
 
213
    /**
2770 rexy 214
     * reads the data from WMI Win32_PerfFormattedData_PerfOS_Processor
215
     *
216
     * @return array
217
     */
218
    private function _get_Win32_PerfFormattedData_PerfOS_Processor()
219
    {
220
        if ($this->_Win32_PerfFormattedData_PerfOS_Processor === null) {
221
            $this->_Win32_PerfFormattedData_PerfOS_Processor = array();
222
            $buffer = $this->_get_Win32_OperatingSystem();
223
            if ($buffer && isset($buffer[0]) && isset($buffer[0]['Version']) && version_compare($buffer[0]['Version'], "5.1", ">=")) { // minimal windows 2003 or windows XP
3037 rexy 224
                $cpubuffer = self::getWMI(self::$_wmi, 'Win32_PerfFormattedData_PerfOS_Processor', array('Name', 'PercentProcessorTime'));
225
                foreach ($cpubuffer as $cpu) {
2770 rexy 226
                    if (isset($cpu['Name']) && isset($cpu['PercentProcessorTime'])) {
227
                        $this->_Win32_PerfFormattedData_PerfOS_Processor['cpu'.$cpu['Name']] = $cpu['PercentProcessorTime'];
228
                    }
229
                }
325 richard 230
            }
231
        }
232
 
2770 rexy 233
        return $this->_Win32_PerfFormattedData_PerfOS_Processor;
325 richard 234
    }
235
 
2770 rexy 236
    /**
237
     * reads the data from systeminfo
238
     *
239
     * @return string
240
     */
241
    private function _get_systeminfo()
242
    {
2976 rexy 243
        if (!defined('PSI_EMU_HOSTNAME')) {
244
            if ($this->_systeminfo === null) CommonFunctions::executeProgram('systeminfo', '', $this->_systeminfo, false);
245
            return $this->_systeminfo;
246
        } else {
247
            return '';
248
        }
325 richard 249
    }
250
 
2770 rexy 251
    /**
3037 rexy 252
     * checks WINNT and 'run as Administrator' mode
253
     *
254
     * @return boolean
255
     */
256
    public static function isAdmin()
257
    {
258
        if (self::$_asadmin == null) {
259
            if (PSI_OS == 'WINNT') {
260
                $strBuf = '';
261
                CommonFunctions::executeProgram('sfc', '2>&1', $strBuf, false); // 'net session' for detection does not work if "Server" (LanmanServer) service is stopped
262
                if (preg_match('/^\/SCANNOW\s/m', preg_replace('/(\x00)/', '', $strBuf))) { // SCANNOW checking - also if Unicode
263
                    self::$_asadmin = true;
264
                } else {
265
                    self::$_asadmin = false;
266
                }
267
            } else {
268
                self::$_asadmin = false;
269
            }
270
        }
271
 
272
        return self::$_asadmin;
273
    }
274
 
275
    /**
276
     * function for getting a list of values in the specified context
277
     * optionally filter this list, based on the list from third parameter
278
     *
279
     * @param $wmi object holds the COM object that we pull the WMI data from
280
     * @param string $strClass name of the class where the values are stored
281
     * @param array  $strValue filter out only needed values, if not set all values of the class are returned
282
     *
283
     * @return array content of the class stored in an array
284
     */
285
    public static function getWMI($wmi, $strClass, $strValue = array())
286
    {
287
        $arrData = array();
288
        if (gettype($wmi) === "object") {
289
            $value = "";
290
            try {
291
                $objWEBM = $wmi->Get($strClass);
292
                $arrProp = $objWEBM->Properties_;
293
                $arrWEBMCol = $objWEBM->Instances_();
294
                foreach ($arrWEBMCol as $objItem) {
295
                    if (is_array($arrProp)) {
296
                        reset($arrProp);
297
                    }
298
                    $arrInstance = array();
299
                    foreach ($arrProp as $propItem) {
300
                        $value = $objItem->{$propItem->Name}; //instead exploitable eval("\$value = \$objItem->".$propItem->Name.";");
301
                        if (empty($strValue)) {
302
                            if (is_string($value)) $arrInstance[$propItem->Name] = trim($value);
303
                            else $arrInstance[$propItem->Name] = $value;
304
                        } else {
305
                            if (in_array($propItem->Name, $strValue)) {
306
                                if (is_string($value)) $arrInstance[$propItem->Name] = trim($value);
307
                                else $arrInstance[$propItem->Name] = $value;
308
                            }
309
                        }
310
                    }
311
                    $arrData[] = $arrInstance;
312
                }
313
            } catch (Exception $e) {
314
                if (PSI_DEBUG && (($message = trim($e->getMessage())) !== "<b>Source:</b> SWbemServicesEx<br/><b>Description:</b> Not found")) {
315
                    $error = PSI_Error::singleton();
316
                    $error->addError("getWMI()", preg_replace('/<br\/>/', "\n", preg_replace('/<b>|<\/b>/', '', $message)));
317
                }
318
            }
319
        } elseif ((gettype($wmi) === "string") && (PSI_OS == 'Linux')) {
320
            $delimeter = '@@@DELIM@@@';
321
            if (CommonFunctions::executeProgram('wmic', '--delimiter="'.$delimeter.'" '.$wmi.' '.$strClass.'" 2>/dev/null', $strBuf, true) && preg_match("/^CLASS:\s/", $strBuf)) {
322
                if (self::$_cp) {
323
                    if (self::$_cp == 932) {
324
                        $codename = ' (SJIS)';
325
                    } elseif (self::$_cp == 949) {
326
                        $codename = ' (EUC-KR)';
327
                    } elseif (self::$_cp == 950) {
328
                        $codename = ' (BIG-5)';
329
                    } else {
330
                        $codename = '';
331
                    }
332
                    self::convertCP($strBuf, 'windows-'.self::$_cp.$codename);
333
                }
334
                $lines = preg_split('/\n/', $strBuf, -1, PREG_SPLIT_NO_EMPTY);
335
                if (count($lines) >=3) {
336
                    unset($lines[0]);
337
                    $names = preg_split('/'.$delimeter.'/', $lines[1], -1, PREG_SPLIT_NO_EMPTY);
338
                    $namesc = count($names);
339
                    unset($lines[1]);
340
                    foreach ($lines as $line) {
341
                        $arrInstance = array();
342
                        $values = preg_split('/'.$delimeter.'/', $line, -1);
343
                        if (count($values) == $namesc) {
344
                            foreach ($values as $id=>$value) {
345
                                if (empty($strValue)) {
346
                                    if ($value !== "(null)") $arrInstance[$names[$id]] = trim($value);
347
                                    else $arrInstance[$names[$id]] = null;
348
                                } else {
349
                                    if (in_array($names[$id], $strValue)) {
350
                                        if ($value !== "(null)") $arrInstance[$names[$id]] = trim($value);
351
                                        else $arrInstance[$names[$id]] = null;
352
                                    }
353
                                }
354
                            }
355
                            $arrData[] = $arrInstance;
356
                        }
357
                    }
358
                }
359
            }
360
        }
361
 
362
        return $arrData;
363
    }
364
 
365
    /**
366
     * readReg function
367
     *
368
     * @return boolean command successfull or not
369
     */
370
    public static function readReg($reg, $strName, &$strBuffer, $booErrorRep = true, $dword = false, $bits64 = false)
371
    {
372
        $strBuffer = '';
373
 
374
        if ($reg === false) {
375
            if (defined('PSI_EMU_HOSTNAME')) {
376
                return false;
377
            }
378
            $last = strrpos($strName, "\\");
379
            $keyname = substr($strName, $last + 1);
380
            if ($bits64) {
381
                $param = ' /reg:64';
382
            } else {
383
                $param = '';
384
            }
385
            if ($dword) {
386
                $valtype = "DWORD";
387
            } else {
388
                $valtype = "SZ|EXPAND_SZ";
389
            }
390
            if (self::$_cp) {
391
                if (CommonFunctions::executeProgram('cmd', '/c chcp '.self::$_cp.' >nul & reg query "'.substr($strName, 0, $last).'" /v '.$keyname.$param.' 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match("/^\s*".$keyname."\s+REG_(".$valtype.")\s+(.+)\s*$/mi", $strBuf, $buffer2)) {
392
                    if ($dword) {
393
                        $strBuffer = strval(hexdec($buffer2[2]));
394
                    } else {
395
                        $strBuffer = $buffer2[2];
396
                    }
397
                } else {
398
                    return false;
399
                }
400
            } else {
401
                if (CommonFunctions::executeProgram('reg', 'query "'.substr($strName, 0, $last).'" /v '.$keyname.$param.' 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match("/^\s*".$keyname."\s+REG_(".$valtype.")\s+(.+)\s*$/mi", $strBuf, $buffer2)) {
402
                    if ($dword) {
403
                        $strBuffer = strval(hexdec($buffer2[2]));
404
                    } else {
405
                        $strBuffer = $buffer2[2];
406
                    }
407
                } else {
408
                    return false;
409
                }
410
            }
411
        } elseif (gettype($reg) === "object") {
412
            $_hkey = array('HKEY_CLASSES_ROOT'=>0x80000000, 'HKEY_CURRENT_USER'=>0x80000001, 'HKEY_LOCAL_MACHINE'=>0x80000002, 'HKEY_USERS'=>0x80000003, 'HKEY_PERFORMANCE_DATA'=>0x80000004, 'HKEY_PERFORMANCE_TEXT'=>0x80000050, 'HKEY_PERFORMANCE_NLSTEXT'=>0x80000060, 'HKEY_CURRENT_CONFIG'=>0x80000005, 'HKEY_DYN_DATA'=>0x80000006);
413
            $first = strpos($strName, "\\");
414
            $last = strrpos($strName, "\\");
415
            $hkey = substr($strName, 0, $first);
416
            if (isset($_hkey[$hkey])) {
417
                $sub_keys = new VARIANT();
418
                try {
419
                    if ($dword) {
420
                        $reg->Get("StdRegProv")->GetDWORDValue(strval($_hkey[$hkey]), substr($strName, $first+1, $last-$first-1), substr($strName, $last+1), $sub_keys);
421
                    } else {
422
                        $reg->Get("StdRegProv")->GetStringValue(strval($_hkey[$hkey]), substr($strName, $first+1, $last-$first-1), substr($strName, $last+1), $sub_keys);
423
                    }
424
                } catch (Exception $e) {
425
                    if ($booErrorRep) {
426
                        $error = PSI_Error::singleton();
427
                        $error->addError("GetStringValue()", preg_replace('/<br\/>/', "\n", preg_replace('/<b>|<\/b>/', '', $e->getMessage())));
428
                    }
429
 
430
                    return false;
431
                }
432
                if (variant_get_type($sub_keys) !== VT_NULL) {
433
                    $strBuffer = strval($sub_keys);
434
                } else {
435
                    return false;
436
                }
437
            } else {
438
                return false;
439
            }
440
        }
441
 
442
        return true;
443
    }
444
 
445
    /**
446
     * enumKey function
447
     *
448
     * @return boolean command successfull or not
449
     */
450
    public static function enumKey($reg, $strName, &$arrBuffer, $booErrorRep = true)
451
    {
452
        $arrBuffer = array();
453
 
454
        if ($reg === false) {
455
            if (defined('PSI_EMU_HOSTNAME')) {
456
                return false;
457
            }
458
            if (self::$_cp) {
459
                if (CommonFunctions::executeProgram('cmd', '/c chcp '.self::$_cp.' >nul & reg query "'.$strName.'" 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match_all("/^".preg_replace("/\\\\/", "\\\\\\\\", $strName)."\\\\(.*)/mi", $strBuf, $buffer2)) {
460
                    foreach ($buffer2[1] as $sub_key) {
461
                        $arrBuffer[] = trim($sub_key);
462
                    }
463
                } else {
464
                    return false;
465
                }
466
            } else {
467
                if (CommonFunctions::executeProgram('reg', 'query "'.$strName.'" 2>&1', $strBuf, $booErrorRep) && (strlen($strBuf) > 0) && preg_match_all("/^".preg_replace("/\\\\/", "\\\\\\\\", $strName)."\\\\(.*)/mi", $strBuf, $buffer2)) {
468
                    foreach ($buffer2[1] as $sub_key) {
469
                        $arrBuffer[] = trim($sub_key);
470
                    }
471
                } else {
472
                    return false;
473
                }
474
            }
475
        } elseif (gettype($reg) === "object") {
476
            $_hkey = array('HKEY_CLASSES_ROOT'=>0x80000000, 'HKEY_CURRENT_USER'=>0x80000001, 'HKEY_LOCAL_MACHINE'=>0x80000002, 'HKEY_USERS'=>0x80000003, 'HKEY_PERFORMANCE_DATA'=>0x80000004, 'HKEY_PERFORMANCE_TEXT'=>0x80000050, 'HKEY_PERFORMANCE_NLSTEXT'=>0x80000060, 'HKEY_CURRENT_CONFIG'=>0x80000005, 'HKEY_DYN_DATA'=>0x80000006);
477
            $first = strpos($strName, "\\");
478
            $hkey = substr($strName, 0, $first);
479
            if (isset($_hkey[$hkey])) {
480
                $sub_keys = new VARIANT();
481
                try {
482
                   $reg->Get("StdRegProv")->EnumKey(strval($_hkey[$hkey]), substr($strName, $first+1), $sub_keys);
483
                } catch (Exception $e) {
484
                    if ($booErrorRep) {
485
                        $error = PSI_Error::singleton();
486
                        $error->addError("enumKey()", preg_replace('/<br\/>/', "\n", preg_replace('/<b>|<\/b>/', '', $e->getMessage())));;
487
                    }
488
 
489
                    return false;
490
                }
491
                if (variant_get_type($sub_keys) !== VT_NULL) {
492
                    foreach ($sub_keys as $sub_key) {
493
                        $arrBuffer[] = $sub_key;
494
                    }
495
                } else {
496
                    return false;
497
                }
498
            } else {
499
                return false;
500
            }
501
        }
502
 
503
        return true;
504
    }
505
 
506
    /**
507
     * initWMI function
508
     *
509
     * @return string, object or false
510
     */
511
    public static function initWMI($namespace, $booErrorRep = false)
512
    {
513
        $wmi = false;
514
        if (self::$_wmi !== false) { // WMI not disabled
515
            try {
516
                if (PSI_OS == 'Linux') {
517
                    if (defined('PSI_EMU_HOSTNAME'))
518
                        $wmi = '--namespace="'.$namespace.'" -U '.PSI_EMU_USER.'%'.PSI_EMU_PASSWORD.' //'.PSI_EMU_HOSTNAME.' "select * from';
519
                } elseif (PSI_OS == 'WINNT') {
520
                    $objLocator = new COM('WbemScripting.SWbemLocator');
521
                    if (defined('PSI_EMU_HOSTNAME'))
522
                        $wmi = $objLocator->ConnectServer(PSI_EMU_HOSTNAME, $namespace, PSI_EMU_USER, PSI_EMU_PASSWORD);
523
                    else
524
                        $wmi = $objLocator->ConnectServer('', $namespace);
525
                }
526
            } catch (Exception $e) {
527
                if ($booErrorRep) {
528
                    $error = PSI_Error::singleton();
529
                    $error->addError("WMI connect ".$namespace." error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed or credentials.");
530
                }
531
            }
532
        }
533
 
534
        return $wmi;
535
    }
536
 
537
    /**
538
     * convertCP function
539
     *
540
     * @return void
541
     */
542
    public static function convertCP(&$strBuf, $encoding)
543
    {
544
        if (defined('PSI_SYSTEM_CODEPAGE') && (PSI_SYSTEM_CODEPAGE != null) && ($encoding != null) && ($encoding != PSI_SYSTEM_CODEPAGE)) {
545
            $systemcp = PSI_SYSTEM_CODEPAGE;
546
            if (preg_match("/^windows-\d+ \((.+)\)$/", $systemcp, $buf)) {
547
                $systemcp = $buf[1];
548
            }
549
            if (preg_match("/^windows-\d+ \((.+)\)$/", $encoding, $buf)) {
550
                $encoding = $buf[1];
551
            }
552
            $enclist = mb_list_encodings();
553
            if (in_array($encoding, $enclist) && in_array($systemcp, $enclist)) {
554
                $strBuf = mb_convert_encoding($strBuf, $encoding, $systemcp);
555
            } elseif (function_exists("iconv")) {
556
                if (($iconvout=iconv($systemcp, $encoding.'//IGNORE', $strBuf))!==false) {
557
                    $strBuf = $iconvout;
558
                }
559
            } elseif (function_exists("libiconv") && (($iconvout=libiconv($systemcp, $encoding, $strBuf))!==false)) {
560
                $strBuf = $iconvout;
561
            }
562
        }
563
    }
564
 
565
    /**
2770 rexy 566
     * build the global Error object and create the WMI connection
567
     */
568
    public function __construct($blockname = false)
569
    {
570
        parent::__construct($blockname);
2976 rexy 571
        if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('cmd', '/c ver 2>nul', $ver_value, false) && (($ver_value = trim($ver_value)) !== "")) {
572
            $this->_ver = $ver_value;
2770 rexy 573
        }
2976 rexy 574
        if (($this->_ver !== "") && preg_match("/ReactOS\r?\n\S+\s+.+/", $this->_ver)) {
3037 rexy 575
            self::$_wmi = false; // No WMI info on ReactOS yet
2976 rexy 576
            $this->_reg = false; // No EnumKey and ReadReg on ReactOS yet
577
        } else {
578
            if (PSI_OS == 'WINNT') {
579
                if (defined('PSI_EMU_HOSTNAME')) {
580
                    try {
581
                        $objLocator = new COM('WbemScripting.SWbemLocator');
582
                        $wmi = $objLocator->ConnectServer('', 'root\CIMv2');
3037 rexy 583
                        $buffer = self::getWMI($wmi, 'Win32_OperatingSystem', array('CodeSet'));
2976 rexy 584
                        if (!$buffer) {
585
                            $reg = $objLocator->ConnectServer('', 'root\default');
3037 rexy 586
                            if (self::readReg($reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage\\ACP", $strBuf, false)) {
2976 rexy 587
                                $buffer[0]['CodeSet'] = $strBuf;
588
                            }
589
                        }
3037 rexy 590
                        if ($buffer && isset($buffer[0]) && isset($buffer[0]['CodeSet'])) {
591
                            $codeset = $buffer[0]['CodeSet'];
592
                            if ($codeset == 932) {
593
                                 $codename = ' (SJIS)';
594
                            } elseif ($codeset == 949) {
595
                                 $codename = ' (EUC-KR)';
596
                            } elseif ($codeset == 950) {
597
                                $codename = ' (BIG-5)';
598
                            } else {
599
                                $codename = '';
2976 rexy 600
                            }
3037 rexy 601
                            define('PSI_SYSTEM_CODEPAGE', 'windows-'.$codeset.$codename);
602
                        } else {
603
                            define('PSI_SYSTEM_CODEPAGE', null);
604
                            if (PSI_DEBUG) {
605
                                $this->error->addError("__construct()", "PhpSysInfo can not detect PSI_SYSTEM_CODEPAGE");
606
                            }
2976 rexy 607
                        }
608
                    } catch (Exception $e) {
609
                        define('PSI_SYSTEM_CODEPAGE', null);
610
                        if (PSI_DEBUG) {
611
                            $this->error->addError("WMI connect error", "PhpSysInfo can not connect to the WMI interface for security reasons.\nCheck an authentication mechanism for the directory where phpSysInfo is installed");
612
                        }
613
                    }
614
                } else {
615
                    define('PSI_SYSTEM_CODEPAGE', null);
616
                }
617
            }
3037 rexy 618
            self::$_wmi = self::initWMI('root\CIMv2', true);
2976 rexy 619
            if (PSI_OS == 'WINNT') {
3037 rexy 620
                $this->_reg = self::initWMI('root\default', PSI_DEBUG);
2976 rexy 621
                if (gettype($this->_reg) === "object") {
622
                    $this->_reg->Security_->ImpersonationLevel = 3;
623
                }
624
            } else {
625
                $this->_reg = false; // No EnumKey and ReadReg on Linux
626
            }
2770 rexy 627
        }
325 richard 628
 
2770 rexy 629
        $this->_getCodeSet();
630
    }
325 richard 631
 
2770 rexy 632
    /**
633
     * store the codepage of the os for converting some strings to utf-8
634
     *
635
     * @return void
636
     */
637
    private function _getCodeSet()
638
    {
639
        $buffer = $this->_get_Win32_OperatingSystem();
640
        if (!$buffer) {
3037 rexy 641
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage\\ACP", $strBuf, false)) {
2770 rexy 642
                $buffer[0]['CodeSet'] = $strBuf;
643
            }
3037 rexy 644
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\Language\\Default", $strBuf, false)) {
2770 rexy 645
                $buffer[0]['Locale'] = $strBuf;
646
            }
647
        }
648
        if ($buffer && isset($buffer[0])) {
649
            if (isset($buffer[0]['CodeSet'])) {
650
                $codeset = $buffer[0]['CodeSet'];
651
                if ($codeset == 932) {
652
                    $codename = ' (SJIS)';
653
                } elseif ($codeset == 949) {
654
                    $codename = ' (EUC-KR)';
655
                } elseif ($codeset == 950) {
656
                    $codename = ' (BIG-5)';
657
                } else {
658
                    $codename = '';
659
                }
3037 rexy 660
                self::$_cp = $codeset;
2770 rexy 661
                $this->_codepage = 'windows-'.$codeset.$codename;
662
            }
663
            if (isset($buffer[0]['Locale']) && (($locale = hexdec($buffer[0]['Locale']))>0)) {
664
                $lang = "";
665
                if (is_readable(PSI_APP_ROOT.'/data/languages.ini') && ($langdata = @parse_ini_file(PSI_APP_ROOT.'/data/languages.ini', true))) {
666
                    if (isset($langdata['WINNT'][$locale])) {
667
                        $lang = $langdata['WINNT'][$locale];
668
                    }
669
                }
670
                if ($lang == "") {
671
                    $lang = 'Unknown';
672
                }
673
                $this->_syslang = $lang.' ('.$locale.')';
674
            }
675
        }
676
    }
325 richard 677
 
2770 rexy 678
    /**
679
     * retrieve different device types from the system based on selector
680
     *
681
     * @param string $strType type of the devices that should be returned
682
     *
683
     * @return array list of devices of the specified type
684
     */
685
    private function _devicelist($strType)
686
    {
3037 rexy 687
        if ($this->_wmidevices === null) {
688
            $this->_wmidevices = array();
2770 rexy 689
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
3037 rexy 690
                $this->_wmidevices = self::getWMI(self::$_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID', 'Manufacturer', 'PNPClass'));
2770 rexy 691
                if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
3037 rexy 692
                    $this->_wmidisks = self::getWMI(self::$_wmi, 'Win32_DiskDrive', array('PNPDeviceID', 'Size', 'SerialNumber'));
2770 rexy 693
                } else {
3037 rexy 694
                    $this->_wmidisks = self::getWMI(self::$_wmi, 'Win32_DiskDrive', array('PNPDeviceID', 'Size'));
2770 rexy 695
                }
696
            } else {
3037 rexy 697
                $this->_wmidevices = self::getWMI(self::$_wmi, 'Win32_PnPEntity', array('Name', 'PNPDeviceID'));
2770 rexy 698
            }
2976 rexy 699
 
700
            if (empty($this->_wmidevices)) {
3037 rexy 701
                $lstdevs = array();
702
                $services = array();
703
                foreach (array('PCI', 'USB') as $type) {
704
                    $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\".$type;
705
                    if (self::enumKey($this->_reg, $hkey, $vendevs, false)) {
706
                        foreach ($vendevs as $vendev) if (self::enumKey($this->_reg, $hkey."\\".$vendev, $ids, false)) {
707
                            foreach ($ids as $id) {
708
                                if ($type === 'PCI') { // enumerate all PCI devices
709
                                    $lstdevs[$type."\\".$vendev."\\".$id] = true;
710
                                } elseif (self::readReg($this->_reg, $hkey."\\".$vendev."\\".$id."\\Service", $service, false)) {
711
                                    $services[$service] = true; // ever used USB services
712
                                    break;
713
                                }
714
                            }
715
                        }
716
                    }
717
                }
718
 
719
                $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services";
720
                foreach ($services as $service=>$tmp) if (self::readReg($this->_reg, $hkey."\\".$service."\\Enum\\Count", $count, false, true) && ($count > 0)) {
721
                    for ($i = 0; $i < $count; $i++) if (self::readReg($this->_reg, $hkey."\\".$service."\\Enum\\".$i, $id, false) && preg_match("/^USB/", $id)) {
722
                        $lstdevs[$id] = true; // used USB devices
723
                    }
724
                }
725
 
726
                $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\";
727
                foreach ($lstdevs as $lstdev=>$tmp) {
728
                    if (self::readReg($this->_reg, $hkey.$lstdev."\\DeviceDesc", $nameBuf, false)) {
729
                        $namesplit = preg_split('/;/', $nameBuf, -1, PREG_SPLIT_NO_EMPTY);
730
                        if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && self::readReg($this->_reg, $hkey.$lstdev."\\Mfg", $mfgBuf, false)) {
731
                            $mfgsplit = preg_split('/;/', $mfgBuf, -1, PREG_SPLIT_NO_EMPTY);
732
                            $this->_wmidevices[] = array('Name'=>$namesplit[count($namesplit)-1], 'PNPDeviceID'=>$lstdev, 'Manufacturer'=>$mfgsplit[count($mfgsplit)-1]);
733
                        } else {
734
                            $this->_wmidevices[] = array('Name'=>$namesplit[count($namesplit)-1], 'PNPDeviceID'=>$lstdev);
735
                        }
736
                    }
737
                }
738
 
2976 rexy 739
                $hkey = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi";
740
                $id = 0;
3037 rexy 741
                if (self::enumKey($this->_reg, $hkey, $portBuf, false)) {
2976 rexy 742
                    foreach ($portBuf as $scsiport) {
3037 rexy 743
                        if (self::enumKey($this->_reg, $hkey."\\".$scsiport, $busBuf, false)) {
2976 rexy 744
                            foreach ($busBuf as $scsibus) {
3037 rexy 745
                                if (self::enumKey($this->_reg, $hkey."\\".$scsiport."\\".$scsibus, $tarBuf, false)) {
2976 rexy 746
                                    foreach ($tarBuf as $scsitar) if (!strncasecmp($scsitar, "Target Id ", strlen("Target Id "))) {
3037 rexy 747
                                        if (self::enumKey($this->_reg, $hkey."\\".$scsiport."\\".$scsibus."\\".$scsitar, $logBuf, false)) {
2976 rexy 748
                                            foreach ($logBuf as $scsilog) if (!strncasecmp($scsilog, "Logical Unit Id ", strlen("Logical Unit Id "))) {
749
                                               $hkey2 = $hkey."\\".$scsiport."\\".$scsibus."\\".$scsitar."\\".$scsilog."\\";
3037 rexy 750
                                               if ((self::readReg($this->_reg, $hkey2."DeviceType", $typeBuf, false) || self::readReg($this->_reg, $hkey2."Type", $typeBuf, false))
2976 rexy 751
                                                  && (($typeBuf=strtolower(trim($typeBuf))) !== "")) {
752
                                                  if ((($typeBuf == 'diskperipheral') || ($typeBuf == 'cdromperipheral'))
3037 rexy 753
                                                     && self::readReg($this->_reg, $hkey2."Identifier", $ideBuf, false)) {
2976 rexy 754
                                                      $this->_wmidevices[] = array('Name'=>$ideBuf, 'PNPDeviceID'=>'SCSI\\'.$id);
755
                                                      if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
3037 rexy 756
                                                         && self::readReg($this->_reg, $hkey2."SerialNumber", $serBuf, false)
2976 rexy 757
                                                         && (($serBuf=trim($serBuf)) !== "")) {
758
                                                          $this->_wmidisks[] = array('PNPDeviceID'=>'SCSI\\'.$id, 'SerialNumber'=>$serBuf);
759
                                                      }
760
                                                      $id++;
761
                                                  }
762
                                               }
763
                                            }
764
                                        }
765
                                    }
766
                                }
767
                            }
768
                        }
769
                    }
770
                }
771
            }
2770 rexy 772
        }
2976 rexy 773
 
2770 rexy 774
        $list = array();
775
        foreach ($this->_wmidevices as $device) {
776
            if (substr($device['PNPDeviceID'], 0, strpos($device['PNPDeviceID'], "\\") + 1) == ($strType."\\")) {
777
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
778
                    if (!isset($device['PNPClass']) || ($device['PNPClass']===$strType) || ($device['PNPClass']==='System')) {
779
                        $device['PNPClass'] = null;
780
                    }
2976 rexy 781
                    if (!isset($device['Manufacturer']) || preg_match('/^\(.*\)$/', $device['Manufacturer']) || (($device['PNPClass']==='USB') && preg_match('/\sUSB\s/', $device['Manufacturer']))) {
2770 rexy 782
                        $device['Manufacturer'] = null;
783
                    }
784
                    $device['Capacity'] = null;
785
                    if (($strType==='IDE')||($strType==='SCSI')) {
786
                        foreach ($this->_wmidisks as $disk) {
787
                            if (($disk['PNPDeviceID'] === $device['PNPDeviceID']) && isset($disk['Size'])) {
788
                                $device['Capacity'] = $disk['Size'];
789
                                break;
790
                            }
791
                        }
792
                    }
793
                    $device['Serial'] = null;
794
                    if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
795
                        if ($strType==='USB') {
3037 rexy 796
//                            if (preg_match('/\\\\([^\\\\][^&\\\\][^\\\\]+)$/', $device['PNPDeviceID'], $buf)) { // second character !== &
2770 rexy 797
                            if (preg_match('/\\\\(\w+)$/', $device['PNPDeviceID'], $buf)) {
798
                                $device['Serial'] = $buf[1];
799
                            }
800
                        } elseif (($strType==='IDE')||($strType==='SCSI')) {
801
                            foreach ($this->_wmidisks as $disk) {
802
                                if (($disk['PNPDeviceID'] === $device['PNPDeviceID']) && isset($disk['SerialNumber'])) {
803
                                    $device['Serial'] = $disk['SerialNumber'];
804
                                    break;
805
                                }
806
                            }
807
                        }
808
                    }
809
                    $list[] = array('Name'=>$device['Name'], 'Manufacturer'=>$device['Manufacturer'], 'Product'=>$device['PNPClass'], 'Capacity'=>$device['Capacity'], 'Serial'=>$device['Serial']);
810
                } else {
811
                    $list[] = array('Name'=>$device['Name']);
812
                }
813
            }
814
        }
325 richard 815
 
2770 rexy 816
        return $list;
325 richard 817
    }
818
 
2770 rexy 819
    /**
820
     * Host Name
821
     *
822
     * @return void
823
     */
824
    private function _hostname()
825
    {
3037 rexy 826
        if (PSI_USE_VHOST && !defined('PSI_EMU_HOSTNAME')) {
2770 rexy 827
            if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
828
        } else {
829
            $buffer = $this->_get_Win32_ComputerSystem();
3037 rexy 830
            if (!$buffer && self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName\\ComputerName", $strBuf, false) && (strlen($strBuf) > 0)) {
2770 rexy 831
                    $buffer[0]['Name'] = $strBuf;
832
            }
833
            if ($buffer) {
834
                $result = $buffer[0]['Name'];
835
                $ip = gethostbyname($result);
836
                if ($ip != $result) {
837
                    if ((version_compare("10.0.0.0", $ip, "<=") && version_compare($ip, "10.255.255.255", "<=")) ||
838
                        (version_compare("172.16.0.0", $ip, "<=") && version_compare($ip, "172.31.255.255", "<=")) ||
839
                        (version_compare("192.168.0.0", $ip, "<=") && version_compare($ip, "192.168.255.255", "<=")) ||
840
                        (version_compare("127.0.0.0", $ip, "<=") && version_compare($ip, "127.255.255.255", "<=")) ||
841
                        (version_compare("169.254.1.0", $ip, "<=") && version_compare($ip, "169.254.254.255", "<=")) ||
842
                        (version_compare("255.255.255.255", $ip, "=="))) {
843
                        $this->sys->setHostname($result); // internal ip
844
                    } else {
2976 rexy 845
                        $hostname = gethostbyaddr($ip);
846
                        if ($hostname !== false)
847
                            $this->sys->setHostname($hostname);
848
                        else
849
                            $this->sys->setHostname($result);
2770 rexy 850
                    }
2976 rexy 851
                } else {
852
                    $this->sys->setHostname($result);
2770 rexy 853
                }
2976 rexy 854
            } elseif (defined('PSI_EMU_HOSTNAME')) {
855
                $this->sys->setHostname(PSI_EMU_HOSTNAME);
856
            } elseif (CommonFunctions::readenv('COMPUTERNAME', $hnm)) {
857
                $this->sys->setHostname($hnm);
2770 rexy 858
            }
859
        }
860
    }
325 richard 861
 
2770 rexy 862
    /**
3037 rexy 863
     * Virtualizer info
864
     *
865
     * @return void
866
     */
867
    protected function _virtualizer()
868
    {
869
        if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
870
            $cpuvirt = $this->sys->getVirtualizer(); // previous info from _cpuinfo()
871
 
872
            $vendor_array = array();
873
            if ($this->_Model != "") {
874
                $vendor_array[] = $this->_Model;
875
            }
876
            if ($this->_Manufacturer != "") {
877
                if ($this->_Model != "") {
878
                    $vendor_array[] = $this->_Manufacturer." ".$this->_Model;
879
                } else {
880
                    $vendor_array[] = $this->_Manufacturer;
881
                }
882
            }
883
            $novm = true;
884
            if (count($vendor_array)>0) {
885
                $virt = CommonFunctions::decodevirtualizer($vendor_array);
886
                if ($virt !== null) {
887
                    $this->sys->setVirtualizer($virt);
888
                    $novm = false;
889
                }
890
            }
891
            if ($novm) {
892
                // Detect QEMU cpu
893
                if (isset($cpuvirt["cpuid:QEMU"])) {
894
                    $this->sys->setVirtualizer('qemu'); // QEMU
895
                }
896
            }
897
        }
898
    }
899
 
900
    /**
2770 rexy 901
     * UpTime
902
     * time the system is running
903
     *
904
     * @return void
905
     */
906
    private function _uptime()
907
    {
908
        $result = 0;
909
        date_default_timezone_set('UTC');
910
        $buffer = $this->_get_Win32_OperatingSystem();
911
        if ($buffer && ($buffer[0]['LastBootUpTime'] !== null)) {
912
            $local = $buffer[0]['LocalDateTime'];
913
            $boot = $buffer[0]['LastBootUpTime'];
325 richard 914
 
2770 rexy 915
            $lyear = intval(substr($local, 0, 4));
916
            $lmonth = intval(substr($local, 4, 2));
917
            $lday = intval(substr($local, 6, 2));
918
            $lhour = intval(substr($local, 8, 2));
919
            $lminute = intval(substr($local, 10, 2));
920
            $lseconds = intval(substr($local, 12, 2));
921
            $loffset = intval(substr($boot, 21, 4));
325 richard 922
 
2770 rexy 923
            $byear = intval(substr($boot, 0, 4));
924
            $bmonth = intval(substr($boot, 4, 2));
925
            $bday = intval(substr($boot, 6, 2));
926
            $bhour = intval(substr($boot, 8, 2));
927
            $bminute = intval(substr($boot, 10, 2));
928
            $bseconds = intval(substr($boot, 12, 2));
929
            $boffset = intval(substr($boot, 21, 4));
325 richard 930
 
2770 rexy 931
            if (version_compare($buffer[0]['Version'], "5.1", "<")) { // fix LastBootUpTime on Windows 2000 and older
932
                $boffset += $boffset;
933
            }
325 richard 934
 
2770 rexy 935
            $localtime = mktime($lhour, $lminute, $lseconds, $lmonth, $lday, $lyear) - $loffset*60;
936
            $boottime = mktime($bhour, $bminute, $bseconds, $bmonth, $bday, $byear) - $boffset*60;
325 richard 937
 
2770 rexy 938
            $result = $localtime - $boottime;
325 richard 939
 
2770 rexy 940
            $this->sys->setUptime($result);
3037 rexy 941
        } elseif (!defined('PSI_EMU_HOSTNAME') && (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") && CommonFunctions::executeProgram('uptime', '', $strBuf, false) && (strlen($strBuf) > 0) && preg_match("/^System Up Time:\s+(\d+) days, (\d+) Hours, (\d+) Minutes, (\d+) Seconds/", $strBuf, $ar_buf)) {
2770 rexy 942
            $sec = $ar_buf[4];
943
            $min = $ar_buf[3];
944
            $hours = $ar_buf[2];
945
            $days = $ar_buf[1];
946
            $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60 + $sec);
947
        }
325 richard 948
    }
2770 rexy 949
 
950
    /**
951
     * Number of Users
952
     *
953
     * @return void
954
     */
955
    protected function _users()
956
    {
2976 rexy 957
        if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('quser', '', $strBuf, false) && (strlen($strBuf) > 0)) {
2770 rexy 958
                $lines = preg_split('/\n/', $strBuf);
959
                $users = count($lines)-1;
960
        } else {
961
            $users = 0;
3037 rexy 962
            $buffer = self::getWMI(self::$_wmi, 'Win32_Process', array('Caption'));
2770 rexy 963
            foreach ($buffer as $process) {
964
                if (strtoupper($process['Caption']) == strtoupper('explorer.exe')) {
965
                    $users++;
966
                }
967
            }
968
        }
969
        $this->sys->setUsers($users);
325 richard 970
    }
971
 
2770 rexy 972
    /**
973
     * Distribution
974
     *
975
     * @return void
976
     */
977
    private function _distro()
978
    {
979
        $buffer = $this->_get_Win32_OperatingSystem();
980
        if ($buffer) {
981
            $ver = $buffer[0]['Version'];
3037 rexy 982
            if (($this->_ver !== "") && preg_match("/^Microsoft [^\[]*\s*\[\D*\s*(".$ver."\.\d+).*\]/", $this->_ver, $ar_temp)) {
983
                $kernel = $ar_temp[1];
984
            } else {
985
                $kernel = $ver;
986
            }
2770 rexy 987
            if ($buffer[0]['ServicePackMajorVersion'] > 0) {
988
                $kernel .= ' SP'.$buffer[0]['ServicePackMajorVersion'];
989
            }
3037 rexy 990
            if ($allCpus = $this->_get_Win32_Processor()) {
991
                $addresswidth = 0;
992
                if (isset($allCpus[0]['AddressWidth']) && (($addresswidth = $allCpus[0]['AddressWidth']) > 0)) {
993
                    $kernel .= ' ('.$addresswidth.'-bit)';
994
                }
995
                if (isset($allCpus[0]['Architecture'])) {
996
                    switch ($allCpus[0]['Architecture']) {
997
                    case 0: $kernel .= ' x86'; break;
998
                    case 1: $kernel .= ' MIPS'; break;
999
                    case 2: $kernel .= ' Alpha'; break;
1000
                    case 3: $kernel .= ' PowerPC'; break;
1001
                    case 5: $kernel .= ' ARM'; break;
1002
                    case 6: $kernel .= ' ia64'; break;
1003
                    case 9: if ($addresswidth == 32) {
1004
                                $kernel .= ' x86';
1005
                            } else {
1006
                                $kernel .= ' x64';
1007
                            }
1008
                            break;
1009
                    case 12: if ($addresswidth == 32) {
1010
                                 $kernel .= ' ARM';
1011
                             } else {
1012
                                 $kernel .= ' ARM64';
1013
                             }
1014
                    }
1015
                }
2770 rexy 1016
            }
3037 rexy 1017
            $this->sys->setKernel($kernel);
1018
            $distribution = $buffer[0]['Caption'];
1019
            if (version_compare($ver, "10.0", ">=") && !preg_match('/server/i', $buffer[0]['Caption']) && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) {
1020
                $karray = preg_split('/\./', $ver);
1021
                if (isset($karray[2]) && isset($list['win10'][$karray[2]])) {
1022
                    $distribution .= ' ('.$list['win10'][$karray[2]].')';
1023
                }
1024
            }
1025
            $this->sys->setDistribution($distribution);
2770 rexy 1026
            if (version_compare($ver, "5.1", "<"))
1027
                $icon = 'Win2000.png';
1028
            elseif (version_compare($ver, "5.1", ">=") && version_compare($ver, "6.0", "<"))
1029
                $icon = 'WinXP.png';
1030
            elseif (version_compare($ver, "6.0", ">=") && version_compare($ver, "6.2", "<"))
1031
                $icon = 'WinVista.png';
3037 rexy 1032
            elseif (version_compare($ver, "6.2", ">=") && version_compare($ver, "10.0.21996", "<"))
1033
                $icon = 'Win8.png';
2770 rexy 1034
            else
3037 rexy 1035
                $icon = 'Win11.png';
2770 rexy 1036
            $this->sys->setDistributionIcon($icon);
2976 rexy 1037
        } elseif ($this->_ver !== "") {
1038
                if (preg_match("/ReactOS\r?\n\S+\s+(.+)/", $this->_ver, $ar_temp)) {
1039
                    if (preg_match("/^(\d+\.\d+\.\d+[\S]*)(.+)$/", trim($ar_temp[1]), $ver_temp)) {
1040
                        $this->sys->setDistribution("ReactOS ".trim($ver_temp[1]));
1041
                        $this->sys->setKernel(trim($ver_temp[2]));
1042
                    } else {
1043
                        $this->sys->setDistribution("ReactOS");
1044
                        $this->sys->setKernel($ar_temp[1]);
1045
                    }
2770 rexy 1046
                    $this->sys->setDistributionIcon('ReactOS.png');
3037 rexy 1047
                } elseif (preg_match("/^(Microsoft [^\[]*)\s*\[\D*\s*([\.\d]+)\]/", $this->_ver, $ar_temp)) {
1048
                    $ver = $ar_temp[2];
1049
                    $kernel = $ver;
1050
                    if (($this->_reg === false) && self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $strBuf, false, false, true) && (strlen($strBuf) > 0)) { // only if reg query via cmd
1051
                        if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $tmpBuf, false)) {
1052
                            $kernel .= ' (64-bit)';
1053
                        }
2770 rexy 1054
                        if (preg_match("/^Microsoft /", $strBuf)) {
3037 rexy 1055
                            $distribution = $strBuf;
2770 rexy 1056
                        } else {
3037 rexy 1057
                            $distribution = "Microsoft ".$strBuf;
2770 rexy 1058
                        }
3037 rexy 1059
                    } elseif (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProductName", $strBuf, false) && (strlen($strBuf) > 0)) {
1060
                        if (preg_match("/^Microsoft /", $strBuf)) {
1061
                            $distribution = $strBuf;
1062
                        } else {
1063
                            $distribution = "Microsoft ".$strBuf;
1064
                        }
2770 rexy 1065
                    } else {
3037 rexy 1066
                        $distribution = $ar_temp[1];
2770 rexy 1067
                    }
1068
                    $this->sys->setKernel($kernel);
3037 rexy 1069
                    if (version_compare($ver, "10.0", ">=") && !preg_match('/server/i', $this->sys->getDistribution()) && ($list = @parse_ini_file(PSI_APP_ROOT."/data/osnames.ini", true))) {
1070
                        if (version_compare($ver, "10.0.21996", ">=") && version_compare($ver, "11.0", "<")) {
1071
                            $distribution = preg_replace("/Windows 10/", "Windows 11", $distribution); // fix Windows 11 detection
1072
                        }
1073
                        $karray = preg_split('/\./', $ver);
1074
                        if (isset($karray[2]) && isset($list['win10'][$karray[2]])) {
1075
                            $distribution .= ' ('.$list['win10'][$karray[2]].')';
1076
                        }
1077
                    }
1078
                    $this->sys->setDistribution($distribution);
1079
                    if (version_compare($ver, "5.1", "<"))
2770 rexy 1080
                        $icon = 'Win2000.png';
3037 rexy 1081
                    elseif (version_compare($ver, "5.1", ">=") && version_compare($ver, "6.0", "<"))
1082
                        $icon = 'WinXP.png';
1083
                    elseif (version_compare($ver, "6.0", ">=") && version_compare($ver, "6.2", "<"))
2770 rexy 1084
                        $icon = 'WinVista.png';
3037 rexy 1085
                    elseif (version_compare($ver, "6.2", ">=") && version_compare($ver, "10.0.21996", "<"))
2770 rexy 1086
                        $icon = 'Win8.png';
1087
                    else
3037 rexy 1088
                        $icon = 'Win11.png';
2770 rexy 1089
                    $this->sys->setDistributionIcon($icon);
1090
                } else {
2976 rexy 1091
                    $this->sys->setDistribution("WINNT");
1092
                    $this->sys->setDistributionIcon('WINNT.png');
2770 rexy 1093
                }
1094
        } else {
2976 rexy 1095
            $this->sys->setDistribution("WINNT");
1096
            $this->sys->setDistributionIcon('WINNT.png');
2770 rexy 1097
        }
1098
    }
325 richard 1099
 
2770 rexy 1100
    /**
1101
     * Processor Load
1102
     * optionally create a loadbar
1103
     *
1104
     * @return void
1105
     */
1106
    private function _loadavg()
1107
    {
1108
        if (($cpubuffer = $this->_get_Win32_PerfFormattedData_PerfOS_Processor()) && isset($cpubuffer['cpu_Total'])) {
1109
            $this->sys->setLoad($cpubuffer['cpu_Total']);
1110
            if (PSI_LOAD_BAR) {
1111
                $this->sys->setLoadPercent($cpubuffer['cpu_Total']);
1112
            }
1113
        } elseif ($buffer = $this->_get_Win32_Processor()) {
1114
            $loadok = true;
1115
            $sum = 0;
1116
            foreach ($buffer as $load) {
1117
                $value = $load['LoadPercentage'];
1118
                if ($value !== null) {
1119
                    $sum += $value;
1120
                } else {
1121
                    $loadok = false;
1122
                    break;
1123
                }
1124
            }
1125
            if ($loadok) {
1126
                $percent = $sum / count($buffer);
1127
                $this->sys->setLoad($percent);
1128
                if (PSI_LOAD_BAR) {
1129
                    $this->sys->setLoadPercent($percent);
1130
                }
1131
            }
1132
        }
1133
    }
325 richard 1134
 
2770 rexy 1135
    /**
1136
     * CPU information
1137
     *
1138
     * @return void
1139
     */
1140
    private function _cpuinfo()
1141
    {
1142
        $allCpus = $this->_get_Win32_Processor();
3037 rexy 1143
        if (empty($allCpus)) {
2770 rexy 1144
            $hkey = "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
3037 rexy 1145
            if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) {
2770 rexy 1146
                foreach ($arrBuf as $coreCount) {
3037 rexy 1147
                    if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\ProcessorNameString", $strBuf, false)) {
2770 rexy 1148
                        $allCpus[$coreCount]['Name'] = $strBuf;
1149
                    }
3037 rexy 1150
                    if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\~MHz", $strBuf, false)) {
2770 rexy 1151
                        if (preg_match("/^0x([0-9a-f]+)$/i", $strBuf, $hexvalue)) {
1152
                            $allCpus[$coreCount]['CurrentClockSpeed'] = hexdec($hexvalue[1]);
1153
                        }
1154
                    }
3037 rexy 1155
                    if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\VendorIdentifier", $strBuf, false)) {
2770 rexy 1156
                        $allCpus[$coreCount]['Manufacturer'] = $strBuf;
1157
                    }
3037 rexy 1158
                    if (self::readReg($this->_reg, $hkey."\\".$coreCount."\\Identifier", $strBuf, false)) {
1159
                        $allCpus[$coreCount]['Caption'] = $strBuf;
1160
                    }
2770 rexy 1161
                }
1162
            }
1163
        }
325 richard 1164
 
2770 rexy 1165
        $globalcpus = 0;
1166
        foreach ($allCpus as $oneCpu) {
1167
            $cpuCount = 1;
1168
            if (isset($oneCpu['NumberOfLogicalProcessors'])) {
1169
                $cpuCount = $oneCpu['NumberOfLogicalProcessors'];
1170
            } elseif (isset($oneCpu['NumberOfCores'])) {
1171
                $cpuCount = $oneCpu['NumberOfCores'];
1172
            }
1173
            $globalcpus+=$cpuCount;
1174
        }
325 richard 1175
 
3037 rexy 1176
        $cpulist = null;
2770 rexy 1177
        foreach ($allCpus as $oneCpu) {
1178
            $cpuCount = 1;
1179
            if (isset($oneCpu['NumberOfLogicalProcessors'])) {
1180
                $cpuCount = $oneCpu['NumberOfLogicalProcessors'];
1181
            } elseif (isset($oneCpu['NumberOfCores'])) {
1182
                $cpuCount = $oneCpu['NumberOfCores'];
1183
            }
1184
            for ($i = 0; $i < $cpuCount; $i++) {
1185
                $cpu = new CpuDevice();
1186
                if (isset($oneCpu['Name'])) $cpu->setModel($oneCpu['Name']);
1187
                if (isset($oneCpu['L3CacheSize']) && ($oneCpu['L3CacheSize'] > 0)) {
1188
                    $cpu->setCache($oneCpu['L3CacheSize'] * 1024);
3037 rexy 1189
                } elseif (isset($oneCpu['L2CacheSize']) && ($oneCpu['L2CacheSize'] > 0)) {
2770 rexy 1190
                    $cpu->setCache($oneCpu['L2CacheSize'] * 1024);
1191
                }
3037 rexy 1192
                if (isset($oneCpu['CurrentVoltage']) && ($oneCpu['CurrentVoltage'] > 0)) {
1193
                    $cpu->setVoltage($oneCpu['CurrentVoltage']/10);
1194
                }
1195
                if (isset($oneCpu['CurrentClockSpeed']) && ($oneCpu['CurrentClockSpeed'] > 0)) {
2770 rexy 1196
                    $cpu->setCpuSpeed($oneCpu['CurrentClockSpeed']);
3037 rexy 1197
                    if (isset($oneCpu['MaxClockSpeed']) && ($oneCpu['CurrentClockSpeed'] <= $oneCpu['MaxClockSpeed'])) $cpu->setCpuSpeedMax($oneCpu['MaxClockSpeed']);
2770 rexy 1198
                }
3037 rexy 1199
                if (isset($oneCpu['ExtClock']) && ($oneCpu['ExtClock'] > 0)) {
1200
                    $cpu->setBusSpeed($oneCpu['ExtClock']);
1201
                }
1202
                if (isset($oneCpu['Manufacturer'])) {
1203
                    $cpumanufacturer = $oneCpu['Manufacturer'];
1204
                    $cpu->setVendorId($cpumanufacturer);
1205
                    if ($cpumanufacturer === "QEMU") {
1206
                        if (isset($oneCpu['Caption'])) {
1207
                            $impl = '';
1208
                            if (preg_match('/^ARMv8 \(64-bit\) Family 8 Model ([0-9a-fA-F]+) Revision[ ]+([0-9a-fA-F]+)$/', $oneCpu['Caption'], $partvar)) {
1209
                                switch (strtolower($partvar[1])) {
1210
                                case '51':
1211
                                    $impl = '0x0'; break; // Qemu
1212
                                case 'd03':
1213
                                case 'd07':
1214
                                case 'd08':
1215
                                    $impl = '0x41'; break; // ARM Limited
1216
                                case '1':
1217
                                    $impl = '0x46'; // Fujitsu Ltd.
1218
                                }
1219
                            } elseif (preg_match('/^ARM Family 7 Model ([0-9a-fA-F]+) Revision[ ]+([0-9a-fA-F]+)$/', $oneCpu['Caption'], $partvar)) {
1220
                                switch (strtolower($partvar[1])) {
1221
                                case 'c07':
1222
                                case 'c0f':
1223
                                        $impl = '0x41'; // ARM Limited
1224
                                }
1225
                            }
1226
                            if ($impl !== '') {
1227
                                if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true);
1228
                                if ($cpulist) {
1229
                                    if ((isset($cpulist['cpu'][$cpufromlist = strtolower($impl.',0x'.$partvar[1].',0x'.$partvar[2])]))
1230
                                       || isset($cpulist['cpu'][$cpufromlist = strtolower($impl.',0x'.$partvar[1])])) {
1231
                                        if (($cpumodel = $cpu->getModel()) !== '') {
1232
                                            $cpu->setModel($cpumodel.' - '.$cpulist['cpu'][$cpufromlist]);
1233
                                        } else {
1234
                                            $cpu->setModel($cpulist['cpu'][$cpufromlist]);
1235
                                        }
1236
                                    }
1237
                                }
1238
                            }
1239
                        }
1240
                        if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
1241
                            $this->sys->setVirtualizer("cpuid:QEMU", false);
1242
                        }
1243
                    }
1244
                }
2770 rexy 1245
                if (PSI_LOAD_BAR) {
1246
                    if (($cpubuffer = $this->_get_Win32_PerfFormattedData_PerfOS_Processor()) && (count($cpubuffer) == ($globalcpus+1)) && isset($cpubuffer['cpu'.$i])) {
1247
                           $cpu->setLoad($cpubuffer['cpu'.$i]);
1248
                    } elseif ((count($allCpus) == $globalcpus) && isset($oneCpu['LoadPercentage'])) {
1249
                        $cpu->setLoad($oneCpu['LoadPercentage']);
1250
                    }
1251
                }
1252
                $this->sys->setCpus($cpu);
1253
            }
1254
        }
1255
    }
325 richard 1256
 
2770 rexy 1257
    /**
1258
     * Machine information
1259
     *
1260
     * @return void
1261
     */
1262
    private function _machine()
1263
    {
1264
        $buffer = $this->_get_Win32_ComputerSystem();
3037 rexy 1265
        $bufferp = self::getWMI(self::$_wmi, 'Win32_BaseBoard', array('Product'));
1266
        $bufferb = self::getWMI(self::$_wmi, 'Win32_BIOS', array('SMBIOSBIOSVersion', 'ReleaseDate'));
2976 rexy 1267
 
1268
        if (!$buffer) {
3037 rexy 1269
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\systemManufacturer", $strBuf, false)) {
2976 rexy 1270
                $buffer[0]['Manufacturer'] = $strBuf;
1271
            }
3037 rexy 1272
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\SystemProductName", $strBuf, false)) {
2976 rexy 1273
                $buffer[0]['Model'] = $strBuf;
1274
            }
3037 rexy 1275
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\SystemFamily", $strBuf, false)) {
2976 rexy 1276
                $buffer[0]['SystemFamily'] = $strBuf;
1277
            }
1278
        }
1279
        if (!$bufferp) {
3037 rexy 1280
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BaseBoardProduct", $strBuf, false)) {
2976 rexy 1281
                $bufferp[0]['Product'] = $strBuf;
1282
            }
1283
        }
1284
        if (!$bufferb) {
3037 rexy 1285
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSVersion", $strBuf, false)) {
2976 rexy 1286
                $bufferb[0]['SMBIOSBIOSVersion'] = $strBuf;
1287
            }
3037 rexy 1288
            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS\\BIOSReleaseDate", $strBuf, false)) {
2976 rexy 1289
                $bufferb[0]['ReleaseDate'] = $strBuf;
1290
            }
1291
        }
3037 rexy 1292
 
1293
        if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
1294
            if (isset($buffer[0]['Manufacturer'])) {
1295
                $this->_Manufacturer = $buffer[0]['Manufacturer'];
1296
            }
1297
            if (isset($buffer[0]['Model'])) {
1298
                $this->_Model = $buffer[0]['Model'];
1299
            }
1300
        }
1301
 
2976 rexy 1302
        $buf = "";
1303
        $model = "";
1304
        if ($buffer && isset($buffer[0])) {
1305
            if (isset($buffer[0]['Manufacturer']) && !preg_match("/^To be filled by O\.E\.M\.$|^System manufacturer$|^Not Specified$/i", $buf2=trim($buffer[0]['Manufacturer'])) && ($buf2 !== "")) {
2770 rexy 1306
                $buf .= ' '.$buf2;
1307
            }
325 richard 1308
 
2976 rexy 1309
            if (isset($buffer[0]['Model']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Product Name$|^Not Specified$/i", $buf2=trim($buffer[0]['Model'])) && ($buf2 !== "")) {
1310
                $model = $buf2;
2770 rexy 1311
                $buf .= ' '.$buf2;
1312
            }
2976 rexy 1313
        }
1314
        if ($bufferp && isset($bufferp[0])) {
1315
            if (isset($bufferp[0]['Product']) && !preg_match("/^To be filled by O\.E\.M\.$|^BaseBoard Product Name$|^Not Specified$|^Default string$/i", $buf2=trim($bufferp[0]['Product'])) && ($buf2 !== "")) {
1316
                if ($buf2 !== $model) {
1317
                    $buf .= '/'.$buf2;
1318
                } elseif (isset($buffer[0]['SystemFamily']) && !preg_match("/^To be filled by O\.E\.M\.$|^System Family$|^Not Specified$/i", $buf2=trim($buffer[0]['SystemFamily'])) && ($buf2 !== "")) {
1319
                    $buf .= '/'.$buf2;
1320
                }
2770 rexy 1321
            }
1322
        }
2976 rexy 1323
        if ($bufferb && isset($bufferb[0])) {
1324
            $bver = "";
1325
            $brel = "";
1326
            if (isset($bufferb[0]['SMBIOSBIOSVersion']) && (($buf2=trim($bufferb[0]['SMBIOSBIOSVersion'])) !== "")) {
1327
                $bver .= ' '.$buf2;
1328
            }
1329
            if (isset($bufferb[0]['ReleaseDate'])) {
1330
                if (preg_match("/^(\d{4})(\d{2})(\d{2})\d{6}\.\d{6}\+\d{3}$/", $bufferb[0]['ReleaseDate'], $dateout)) {
1331
                    $brel .= ' '.$dateout[2].'/'.$dateout[3].'/'.$dateout[1];
1332
                } elseif (preg_match("/^\d{2}\/\d{2}\/\d{4}$/", $bufferb[0]['ReleaseDate'])) {
1333
                    $brel .= ' '.$bufferb[0]['ReleaseDate'];
1334
                }
1335
            }
1336
            if ((trim($bver) !== "") || (trim($brel) !== "")) {
1337
                $buf .= ', BIOS'.$bver.$brel;
1338
            }
1339
        }
1340
 
1341
        if (trim($buf) != "") {
1342
            $this->sys->setMachine(trim($buf));
1343
        }
2770 rexy 1344
    }
325 richard 1345
 
2770 rexy 1346
    /**
1347
     * Hardwaredevices
1348
     *
1349
     * @return void
1350
     */
1351
    private function _hardware()
1352
    {
1353
        foreach ($this->_devicelist('PCI') as $pciDev) {
1354
            $dev = new HWDevice();
1355
            $dev->setName($pciDev['Name']);
1356
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
2976 rexy 1357
                if (($pciDev['Manufacturer'] !== null) && preg_match("/^@[^\.]+\.inf,%([^%]+)%$/i", trim($pciDev['Manufacturer']), $mbuff)) {
1358
                   $dev->setManufacturer($mbuff[1]);
1359
                } else {
1360
                    $dev->setManufacturer($pciDev['Manufacturer']);
1361
                }
2770 rexy 1362
                $dev->setProduct($pciDev['Product']);
1363
            }
1364
            $this->sys->setPciDevices($dev);
1365
        }
325 richard 1366
 
2770 rexy 1367
        foreach ($this->_devicelist('IDE') as $ideDev) {
1368
            $dev = new HWDevice();
1369
            $dev->setName($ideDev['Name']);
1370
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1371
                $dev->setCapacity($ideDev['Capacity']);
1372
                if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
1373
                    $dev->setSerial($ideDev['Serial']);
1374
                }
1375
            }
1376
            $this->sys->setIdeDevices($dev);
1377
        }
325 richard 1378
 
2770 rexy 1379
        foreach ($this->_devicelist('SCSI') as $scsiDev) {
1380
            $dev = new HWDevice();
1381
            $dev->setName($scsiDev['Name']);
1382
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1383
                $dev->setCapacity($scsiDev['Capacity']);
1384
                if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
1385
                    $dev->setSerial($scsiDev['Serial']);
1386
                }
1387
            }
1388
            $this->sys->setScsiDevices($dev);
1389
        }
325 richard 1390
 
2770 rexy 1391
        foreach ($this->_devicelist('USB') as $usbDev) {
1392
            $dev = new HWDevice();
1393
            $dev->setName($usbDev['Name']);
1394
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1395
                $dev->setManufacturer($usbDev['Manufacturer']);
1396
                $dev->setProduct($usbDev['Product']);
1397
                if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
1398
                    $dev->setSerial($usbDev['Serial']);
1399
                }
1400
            }
1401
            $this->sys->setUsbDevices($dev);
1402
        }
1403
    }
325 richard 1404
 
2770 rexy 1405
    /**
1406
     * Network devices
1407
     *
1408
     * @return void
1409
     */
1410
    private function _network()
1411
    {
3037 rexy 1412
        if (self::$_wmi) {
2770 rexy 1413
            $buffer = $this->_get_Win32_OperatingSystem();
1414
            if ($buffer && isset($buffer[0]) && isset($buffer[0]['Version']) && version_compare($buffer[0]['Version'], "6.2", ">=")) { // minimal windows 2012 or windows 8
3037 rexy 1415
                $allDevices = self::getWMI(self::$_wmi, 'Win32_PerfRawData_Tcpip_NetworkAdapter', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded', 'CurrentBandwidth'));
2770 rexy 1416
            } else {
3037 rexy 1417
                $allDevices = self::getWMI(self::$_wmi, 'Win32_PerfRawData_Tcpip_NetworkInterface', array('Name', 'BytesSentPersec', 'BytesTotalPersec', 'BytesReceivedPersec', 'PacketsReceivedErrors', 'PacketsReceivedDiscarded', 'CurrentBandwidth'));
2770 rexy 1418
            }
1419
            if ($allDevices) {
1420
                $aliases = array();
1421
                $hkey = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";
3037 rexy 1422
                if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) {
2770 rexy 1423
                    foreach ($arrBuf as $netID) {
3037 rexy 1424
                        if (self::readReg($this->_reg, $hkey."\\".$netID."\\Connection\\PnPInstanceId", $strInstanceID, false)) {
1425
                            if (self::readReg($this->_reg, "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\".$strInstanceID."\\FriendlyName", $strName, false)) {
2976 rexy 1426
                                $cname = str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strName); //convert to canonical
2770 rexy 1427
                                if (!isset($aliases[$cname])) { // duplicate checking
1428
                                    $aliases[$cname]['id'] = $netID;
1429
                                    $aliases[$cname]['name'] = $strName;
3037 rexy 1430
                                    if (self::readReg($this->_reg, $hkey."\\".$netID."\\Connection\\Name", $strCName, false)
2976 rexy 1431
                                       && (str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strCName) !== $cname)) {
2770 rexy 1432
                                        $aliases[$cname]['netname'] = $strCName;
1433
                                    }
1434
                                } else {
1435
                                    $aliases[$cname]['id'] = '';
1436
                                }
1437
                            }
1438
                        }
1439
                    }
1440
                }
325 richard 1441
 
2770 rexy 1442
                $aliases2 = array();
1443
                $hkey = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
3037 rexy 1444
                if (self::enumKey($this->_reg, $hkey, $arrBuf, false)) {
2770 rexy 1445
                    foreach ($arrBuf as $netCount) {
3037 rexy 1446
                        if (self::readReg($this->_reg, $hkey."\\".$netCount."\\Description", $strName, false)
1447
                            && self::readReg($this->_reg, $hkey."\\".$netCount."\\ServiceName", $strGUID, false)) {
2976 rexy 1448
                            $cname = str_replace(array('(', ')', '#', '/'), array('[', ']', '_', '_'), $strName); //convert to canonical
2770 rexy 1449
                            if (!isset($aliases2[$cname])) { // duplicate checking
1450
                                $aliases2[$cname]['id'] = $strGUID;
1451
                                $aliases2[$cname]['name'] = $strName;
1452
                            } else {
1453
                                $aliases2[$cname]['id'] = '';
1454
                            }
1455
                        }
1456
                    }
1457
                }
325 richard 1458
 
3037 rexy 1459
                $allNetworkAdapterConfigurations = self::getWMI(self::$_wmi, 'Win32_NetworkAdapterConfiguration', array('SettingID', /*'Description',*/ 'MACAddress', 'IPAddress'));
2770 rexy 1460
                foreach ($allDevices as $device) if (!preg_match('/^WAN Miniport \[/', $device['Name'])) {
1461
                    $dev = new NetDevice();
1462
                    $name = $device['Name'];
325 richard 1463
 
2770 rexy 1464
                    if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $name)) {
1465
                        $dev->setName("Microsoft ISATAP Adapter");
1466
                    } else {
1467
                        if (preg_match('/\s-\s([^-]*)$/', $name, $ar_name)) {
1468
                            $name=substr($name, 0, strlen($name)-strlen($ar_name[0]));
1469
                        }
1470
                        $dev->setName($name);
1471
                    }
325 richard 1472
 
2770 rexy 1473
                    $macexist = false;
1474
                    if (((($ali=$aliases) && isset($ali[$name])) || (($ali=$aliases2) && isset($ali[$name]))) && isset($ali[$name]['id']) && ($ali[$name]['id'] !== "")) {
1475
                        foreach ($allNetworkAdapterConfigurations as $NetworkAdapterConfiguration) {
1476
                            if ($ali[$name]['id']==$NetworkAdapterConfiguration['SettingID']) {
1477
                                $mininame = $ali[$name]['name'];
1478
                                if (preg_match('/^isatap\.({[A-Fa-f0-9\-]*})/', $mininame))
1479
                                    $mininame="Microsoft ISATAP Adapter";
1480
                                elseif (preg_match('/\s-\s([^-]*)$/', $mininame, $ar_name))
1481
                                    $name=substr($mininame, 0, strlen($mininame)-strlen($ar_name[0]));
1482
                                $dev->setName($mininame);
3037 rexy 1483
                                if (isset($NetworkAdapterConfiguration['MACAddress']) && trim($NetworkAdapterConfiguration['MACAddress']) !== "") $macexist = true;
2770 rexy 1484
                                if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) {
1485
                                    if (isset($ali[$name]['netname'])) $dev->setInfo(str_replace(';', ':', $ali[$name]['netname']));
1486
                                    if ((!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR)
3037 rexy 1487
                                       && $macexist) $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').str_replace(':', '-', strtoupper(trim($NetworkAdapterConfiguration['MACAddress']))));
2770 rexy 1488
                                    if (isset($NetworkAdapterConfiguration['IPAddress']))
1489
                                        foreach ($NetworkAdapterConfiguration['IPAddress'] as $ipaddres)
1490
                                            if (($ipaddres != "0.0.0.0") && ($ipaddres != "::") && !preg_match('/^fe80::/i', $ipaddres))
1491
                                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ipaddres));
1492
                                }
325 richard 1493
 
2770 rexy 1494
                                break;
1495
                            }
1496
                        }
1497
                    }
1498
 
1499
                    if ($macexist
1500
//                        || ($device['CurrentBandwidth'] >= 1000000)
1501
                        || ($device['BytesTotalPersec'] != 0)
1502
                        || ($device['BytesSentPersec'] != 0)
1503
                        || ($device['BytesReceivedPersec'] != 0)
1504
                        || ($device['PacketsReceivedErrors'] != 0)
1505
                        || ($device['PacketsReceivedDiscarded'] != 0)) { // hide unused
1506
                        if (defined('PSI_SHOW_NETWORK_INFOS') && PSI_SHOW_NETWORK_INFOS) {
1507
                            if (($speedinfo = $device['CurrentBandwidth']) >= 1000000) {
1508
                                if ($speedinfo > 1000000000) {
1509
                                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').round($speedinfo/1000000000, 2)."Gb/s");
1510
                                } else {
1511
                                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').round($speedinfo/1000000, 2)."Mb/s");
1512
                                }
1513
                            }
1514
                        }
1515
 
1516
                        // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_perfrawdata_tcpip_networkinterface.asp
1517
                        // there is a possible bug in the wmi interfaceabout uint32 and uint64: http://www.ureader.com/message/1244948.aspx, so that
1518
                        // magative numbers would occour, try to calculate the nagative value from total - positive number
1519
                        $txbytes = $device['BytesSentPersec'];
1520
                        $rxbytes = $device['BytesReceivedPersec'];
1521
                        if (($txbytes < 0) && ($rxbytes < 0)) {
1522
                            $txbytes += 4294967296;
1523
                            $rxbytes += 4294967296;
1524
                        } elseif ($txbytes < 0) {
1525
                            if ($device['BytesTotalPersec'] > $rxbytes)
1526
                               $txbytes = $device['BytesTotalPersec'] - $rxbytes;
1527
                            else
1528
                               $txbytes += 4294967296;
1529
                        } elseif ($rxbytes < 0) {
1530
                            if ($device['BytesTotalPersec'] > $txbytes)
1531
                               $rxbytes = $device['BytesTotalPersec'] - $txbytes;
1532
                            else
1533
                               $rxbytes += 4294967296;
1534
                        }
1535
                        $dev->setTxBytes($txbytes);
1536
                        $dev->setRxBytes($rxbytes);
1537
                        $dev->setErrors($device['PacketsReceivedErrors']);
1538
                        $dev->setDrops($device['PacketsReceivedDiscarded']);
1539
 
1540
                        $this->sys->setNetDevices($dev);
1541
                    }
1542
                }
1543
            }
1544
        } elseif (($buffer = $this->_get_systeminfo()) && preg_match('/^(\s+)\[\d+\]:[^\r\n]+\r\n\s+[^\s\[]/m', $buffer, $matches, PREG_OFFSET_CAPTURE)) {
1545
            $netbuf = substr($buffer, $matches[0][1]);
1546
            if (preg_match('/^[^\s]/m', $netbuf, $matches2, PREG_OFFSET_CAPTURE)) {
1547
                $netbuf = substr($netbuf, 0, $matches2[0][1]);
1548
            }
1549
            $netstrs = preg_split('/^'.$matches[1][0].'\[\d+\]:/m', $netbuf, -1, PREG_SPLIT_NO_EMPTY);
1550
            $devnr = 0;
1551
            foreach ($netstrs as $netstr) {
1552
                $netstrls = preg_split('/\r\n/', $netstr, -1, PREG_SPLIT_NO_EMPTY);
1553
                if (sizeof($netstrls)>1) {
1554
                    $dev = new NetDevice();
1555
                    foreach ($netstrls as $nr=>$netstrl) {
1556
                        if ($nr === 0) {
1557
                            $name = trim($netstrl);
1558
                            if ($name !== "") {
1559
                                $dev->setName($name);
1560
                            } else {
1561
                                $dev->setName('dev'.$devnr);
1562
                                $devnr++;
1563
                            }
1564
                        } elseif (preg_match('/\[\d+\]:\s+(.+)/', $netstrl, $netinfo)) {
1565
                            $ipaddres = trim($netinfo[1]);
1566
                            if (($ipaddres!="0.0.0.0") && !preg_match('/^fe80::/i', $ipaddres))
1567
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ipaddres));
1568
                        }
1569
                    }
1570
                    $this->sys->setNetDevices($dev);
1571
                }
1572
            }
1573
        }
1574
    }
1575
 
1576
    /**
1577
     * Physical memory information and Swap Space information
1578
     *
1579
     * @link http://msdn2.microsoft.com/En-US/library/aa394239.aspx
1580
     * @link http://msdn2.microsoft.com/en-us/library/aa394246.aspx
1581
     * @return void
1582
     */
1583
    private function _memory()
1584
    {
3037 rexy 1585
        if (self::$_wmi) {
2770 rexy 1586
            $buffer = $this->_get_Win32_OperatingSystem();
1587
            if ($buffer) {
1588
                $this->sys->setMemTotal($buffer[0]['TotalVisibleMemorySize'] * 1024);
1589
                $this->sys->setMemFree($buffer[0]['FreePhysicalMemory'] * 1024);
1590
                $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
1591
            }
3037 rexy 1592
            $buffer = self::getWMI(self::$_wmi, 'Win32_PageFileUsage');
2770 rexy 1593
            foreach ($buffer as $swapdevice) {
1594
                $dev = new DiskDevice();
1595
                $dev->setName("SWAP");
1596
                $dev->setMountPoint($swapdevice['Name']);
1597
                $dev->setTotal($swapdevice['AllocatedBaseSize'] * 1024 * 1024);
1598
                $dev->setUsed($swapdevice['CurrentUsage'] * 1024 * 1024);
1599
                $dev->setFree($dev->getTotal() - $dev->getUsed());
1600
                $dev->setFsType('swap');
1601
                $this->sys->setSwapDevices($dev);
1602
            }
1603
        } elseif (($buffer = $this->_get_systeminfo()) && preg_match("/:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+\s([\d \xFF]+)\sMB\r\n/m", $buffer, $buffer2)) {
1604
//           && (preg_match("/:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+:\s([\d \xFF]+)\sMB\r\n.+\s([\d \xFF]+)\sMB\r\n.*:\s+(\S+)\r\n/m", $buffer, $buffer2)) {
1605
            $this->sys->setMemTotal(preg_replace('/(\s)|(\xFF)/', '', $buffer2[1]) * 1024 * 1024);
1606
            $this->sys->setMemFree(preg_replace('/(\s)|(\xFF)/', '', $buffer2[2]) * 1024 * 1024);
1607
            $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
1608
        }
1609
    }
1610
 
1611
    /**
1612
     * filesystem information
1613
     *
1614
     * @return void
1615
     */
1616
    private function _filesystems()
1617
    {
1618
        $typearray = array('Unknown', 'No Root Directory', 'Removable Disk', 'Local Disk', 'Network Drive', 'Compact Disc', 'RAM Disk');
1619
        $floppyarray = array('Unknown', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', '5 1/4 in.', 'Other', 'HD', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '5 1/4 in.', '3 1/2 in.', '3 1/2 in.', '8 in.');
3037 rexy 1620
        $buffer = self::getWMI(self::$_wmi, 'Win32_LogicalDisk', array('Name', 'Size', 'FreeSpace', 'FileSystem', 'DriveType', 'MediaType'));
2770 rexy 1621
        foreach ($buffer as $filesystem) {
1622
            $dev = new DiskDevice();
1623
            $dev->setMountPoint($filesystem['Name']);
3037 rexy 1624
            if (isset($filesystem['FileSystem'])) {
1625
                $dev->setFsType($filesystem['FileSystem']);
1626
            }
2770 rexy 1627
            if ($filesystem['Size'] > 0) {
1628
                $dev->setTotal($filesystem['Size']);
1629
                $dev->setFree($filesystem['FreeSpace']);
1630
                $dev->setUsed($filesystem['Size'] - $filesystem['FreeSpace']);
1631
            }
1632
            if ($filesystem['MediaType'] != "" && $filesystem['DriveType'] == 2) {
1633
                $dev->setName($typearray[$filesystem['DriveType']]." (".$floppyarray[$filesystem['MediaType']].")");
1634
            } else {
1635
                $dev->setName($typearray[$filesystem['DriveType']]);
1636
            }
1637
            $this->sys->setDiskDevices($dev);
1638
        }
3037 rexy 1639
        if (!$buffer && !defined('PSI_EMU_HOSTNAME')) {
1640
            $letters = array();
1641
            if (CommonFunctions::executeProgram('fsutil', 'fsinfo drives 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/^Drives:\s*(.+)$/i', $out_value, $disks)) {
1642
                $diskarr = preg_split('/ /', $disks[1], -1, PREG_SPLIT_NO_EMPTY);
1643
                foreach ($diskarr as $disk) if (preg_match('/^(\w):\\\\$/', $disk, $diskletter)) {
1644
                    $letters[] = $diskletter[1];
1645
                }
1646
            }
1647
            if (count($letters) == 0) for ($letter='A'; $letter!='AA'; $letter++) {
1648
                $letters[] = $letter;
1649
            }
1650
            if ((substr($this->sys->getDistribution(), 0, 7)=="ReactOS") && CommonFunctions::executeProgram('cmd', '/c free 2>nul', $out_value, false)) {
1651
                foreach ($letters as $letter) if (CommonFunctions::executeProgram('cmd', '/c free '.$letter.': 2>nul', $out_value, false)) {
2770 rexy 1652
                    $values = preg_replace('/[^\d\n]/', '', $out_value);
1653
                    if (preg_match('/\n(\d+)\n(\d+)\n(\d+)$/', $values, $out_dig)) {
1654
                        $size = $out_dig[1];
1655
                        $used = $out_dig[2];
1656
                        $free = $out_dig[3];
1657
                        if ($used + $free == $size) {
1658
                            $dev = new DiskDevice();
1659
                            $dev->setMountPoint($letter.":");
3037 rexy 1660
                            if (CommonFunctions::executeProgram('fsutil', 'fsinfo volumeinfo '.$letter.':\ 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/\nFile System Name\s*:\s*(\S+)/im', $out_value, $fsname)) {
1661
                                $dev->setFsType($fsname[1]);
1662
                            } else {
1663
                                $dev->setFsType('Unknown');
1664
                            }
2770 rexy 1665
                            $dev->setName('Unknown');
1666
                            $dev->setTotal($size);
1667
                            $dev->setUsed($used);
1668
                            $dev->setFree($free);
1669
                            $this->sys->setDiskDevices($dev);
1670
                        }
1671
                    }
1672
                }
3037 rexy 1673
            } else {
1674
                if (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") {
1675
                    $disksep = ':\\';
1676
                } else {
1677
                    $disksep = ':';
1678
                }
1679
                foreach ($letters as $letter) {
1680
                    $size = disk_total_space($letter.':\\');
1681
                    $free = disk_free_space($letter.':\\');
1682
                    if (($size !== false) && ($free !== false) && ($size >= 0) && ($free >= 0) && ($size >= $free)) {
1683
                        $dev = new DiskDevice();
1684
                        $dev->setMountPoint($letter.":");
1685
                        if (CommonFunctions::executeProgram('fsutil', 'fsinfo volumeinfo '.$letter.$disksep.' 2>nul', $out_value, false) && ($out_value !== '') && preg_match('/\nFile System Name\s*:\s*(\S+)/im', $out_value, $fsname)) {
1686
                            $dev->setFsType($fsname[1]);
1687
                        } else {
1688
                            $dev->setFsType('Unknown');
1689
                        }
1690
                        $dev->setName('Unknown');
1691
                        $dev->setTotal($size);
1692
                        $dev->setUsed($size - $free);
1693
                        $dev->setFree($free);
1694
                       $this->sys->setDiskDevices($dev);
1695
                    }
1696
                }
2770 rexy 1697
            }
1698
        }
1699
    }
1700
 
1701
    /**
1702
     * get os specific encoding
1703
     *
1704
     * @see OS::getEncoding()
1705
     *
1706
     * @return string
1707
     */
1708
    public function getEncoding()
1709
    {
1710
        return $this->_codepage;
1711
    }
1712
 
1713
    /**
1714
     * get os specific language
1715
     *
1716
     * @see OS::getLanguage()
1717
     *
1718
     * @return string
1719
     */
1720
    public function getLanguage()
1721
    {
1722
        return $this->_syslang;
1723
    }
1724
 
1725
    public function _processes()
1726
    {
1727
        $processes['*'] = 0;
2976 rexy 1728
        if (!defined('PSI_EMU_HOSTNAME') && CommonFunctions::executeProgram('qprocess', '*', $strBuf, false) && (strlen($strBuf) > 0)) {
2770 rexy 1729
            $lines = preg_split('/\n/', $strBuf);
1730
            $processes['*'] = (count($lines)-1) - 3 ; //correction for process "qprocess *"
1731
        }
1732
        if ($processes['*'] <= 0) {
3037 rexy 1733
            $buffer = self::getWMI(self::$_wmi, 'Win32_Process', array('Caption'));
2770 rexy 1734
            $processes['*'] = count($buffer);
1735
        }
1736
        $processes[' '] = $processes['*'];
1737
        $this->sys->setProcesses($processes);
1738
    }
1739
 
1740
    /**
2976 rexy 1741
     * MEM information
1742
     *
1743
     * @return void
1744
     */
1745
    private function _meminfo()
1746
    {
3037 rexy 1747
        $allMems = self::_get_Win32_PhysicalMemory();
2976 rexy 1748
        if ($allMems) {
1749
            $reg = false;
1750
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
3037 rexy 1751
                $arrMems = self::getWMI(self::$_wmi, 'Win32_PhysicalMemoryArray', array('MemoryErrorCorrection'));
2976 rexy 1752
                $reg = (count($arrMems) == 1) && isset($arrMems[0]['MemoryErrorCorrection']) && ($arrMems[0]['MemoryErrorCorrection'] == 6);
1753
            }
1754
            foreach ($allMems as $mem) {
1755
                $dev = new HWDevice();
1756
                $name = '';
1757
                if (isset($mem['PartNumber']) && !preg_match("/^PartNum\d+$/", $part = $mem['PartNumber']) && ($part != '') && ($part != 'None') && ($part != 'N/A') && ($part != 'NOT AVAILABLE')) {
1758
                    $name = $part;
1759
                 }
1760
                if (isset($mem['DeviceLocator']) && (($dloc = $mem['DeviceLocator']) != '') && ($dloc != 'None') && ($dloc != 'N/A')) {
1761
                    if ($name != '') {
1762
                        $name .= ' - '.$dloc;
1763
                    } else {
1764
                        $name = $dloc;
1765
                    }
1766
                }
1767
                if (isset($mem['BankLabel']) && (($bank = $mem['BankLabel']) != '') && ($bank != 'None') && ($bank != 'N/A')) {
1768
                    if ($name != '') {
1769
                        $name .= ' in '.$bank;
1770
                    } else {
1771
                        $name = 'Physical Memory in '.$bank;
1772
                    }
1773
                }
1774
                if ($name != '') {
1775
                    $dev->setName(trim($name));
1776
                } else {
1777
                    $dev->setName('Physical Memory');
1778
                }
1779
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1780
                    if (isset($mem['Manufacturer']) && !preg_match("/^([A-F\d]{4}|[A-F\d]{12}|[A-F\d]{16})$/", $manufacturer = $mem['Manufacturer']) && !preg_match("/^Manufacturer\d+$/", $manufacturer) && !preg_match("/^Mfg \d+$/", $manufacturer) && ($manufacturer != '') && ($manufacturer != 'None') && ($manufacturer != 'N/A') && ($manufacturer != 'UNKNOWN')) {
1781
                        $dev->setManufacturer($manufacturer);
1782
                    }
1783
                    if (isset($mem['Capacity'])) {
1784
                        $dev->setCapacity($mem['Capacity']);
1785
                    }
1786
                    $memtype = '';
1787
                    if (isset($mem['MemoryType']) && (($memval = $mem['MemoryType']) != 0)) {
1788
                        switch ($memval) {
3037 rexy 1789
//                        case 0: $memtype = 'Unknown'; break;
1790
//                        case 1: $memtype = 'Other'; break;
1791
                        case 2: $memtype = 'DRAM'; break;
1792
                        case 3: $memtype = 'Synchronous DRAM'; break;
1793
                        case 4: $memtype = 'Cache DRAM'; break;
1794
                        case 5: $memtype = 'EDO'; break;
1795
                        case 6: $memtype = 'EDRAM'; break;
1796
                        case 7: $memtype = 'VRAM'; break;
1797
                        case 8: $memtype = 'SRAM'; break;
1798
                        case 9: $memtype = 'RAM'; break;
1799
                        case 10: $memtype = 'ROM'; break;
1800
                        case 11: $memtype = 'Flash'; break;
1801
                        case 12: $memtype = 'EEPROM'; break;
1802
                        case 13: $memtype = 'FEPROM'; break;
1803
                        case 14: $memtype = 'EPROM'; break;
1804
                        case 15: $memtype = 'CDRAM'; break;
1805
                        case 16: $memtype = '3DRAM'; break;
1806
                        case 17: $memtype = 'SDRAM'; break;
1807
                        case 18: $memtype = 'SGRAM'; break;
1808
                        case 19: $memtype = 'RDRAM'; break;
1809
                        case 20: $memtype = 'DDR'; break;
1810
                        case 21: $memtype = 'DDR2'; break;
1811
                        case 22: $memtype = 'DDR2 FB-DIMM'; break;
1812
                        case 24: $memtype = 'DDR3'; break;
1813
                        case 25: $memtype = 'FBD2'; break;
1814
                        case 26: $memtype = 'DDR4';
2976 rexy 1815
                        }
1816
                    } elseif (isset($mem['SMBIOSMemoryType'])) {
1817
                        switch ($mem['SMBIOSMemoryType']) {
3037 rexy 1818
//                        case 0: $memtype = 'Invalid'; break;
1819
//                        case 1: $memtype = 'Other'; break;
1820
//                        case 2: $memtype = 'Unknown'; break;
1821
                        case 3: $memtype = 'DRAM'; break;
1822
                        case 4: $memtype = 'EDRAM'; break;
1823
                        case 5: $memtype = 'VRAM'; break;
1824
                        case 6: $memtype = 'SRAM'; break;
1825
                        case 7: $memtype = 'RAM'; break;
1826
                        case 8: $memtype = 'ROM'; break;
1827
                        case 9: $memtype = 'FLASH'; break;
1828
                        case 10: $memtype = 'EEPROM'; break;
1829
                        case 11: $memtype = 'FEPROM'; break;
1830
                        case 12: $memtype = 'EPROM'; break;
1831
                        case 13: $memtype = 'CDRAM'; break;
1832
                        case 14: $memtype = '3DRAM'; break;
1833
                        case 15: $memtype = 'SDRAM'; break;
1834
                        case 16: $memtype = 'SGRAM'; break;
1835
                        case 17: $memtype = 'RDRAM'; break;
1836
                        case 18: $memtype = 'DDR'; break;
1837
                        case 19: $memtype = 'DDR2'; break;
1838
                        case 20: $memtype = 'DDR2 FB-DIMM'; break;
1839
                        case 24: $memtype = 'DDR3'; break;
1840
                        case 25: $memtype = 'FBD2'; break;
1841
                        case 26: $memtype = 'DDR4'; break;
1842
                        case 27: $memtype = 'LPDDR'; break;
1843
                        case 28: $memtype = 'LPDDR2'; break;
1844
                        case 29: $memtype = 'LPDDR3'; break;
1845
                        case 30: $memtype = 'DDR3'; break;
1846
                        case 31: $memtype = 'FBD2'; break;
1847
                        case 32: $memtype = 'Logical non-volatile device'; break;
1848
                        case 33: $memtype = 'HBM2'; break;
1849
                        case 34: $memtype = 'DDR5'; break;
1850
                        case 35: $memtype = 'LPDDR5';
2976 rexy 1851
                        }
1852
                    }
1853
                    if (isset($mem['Speed']) && (($speed = $mem['Speed']) > 0) && (preg_match('/^(DDR\d*)(.*)/', $memtype, $dr) || preg_match('/^(SDR)AM(.*)/', $memtype, $dr))) {
1854
                        if (isset($mem['MinVoltage']) && isset($mem['MaxVoltage']) && (($minv = $mem['MinVoltage']) > 0) && (($maxv = $mem['MaxVoltage']) > 0) && ($minv < $maxv)) {
1855
                            $lv = 'L';
1856
                        } else {
1857
                            $lv = '';
1858
                        }
1859
                        if (isset($dr[2])) {
1860
                            $memtype = $dr[1].$lv.'-'.$speed.' '.$dr[2];
1861
                        } else {
1862
                            $memtype = $dr[1].$lv.'-'.$speed;
1863
                        }
1864
                    }
1865
                    if (isset($mem['FormFactor'])) {
1866
                        switch ($mem['FormFactor']) {
3037 rexy 1867
//                        case 0: $memtype .= ' Unknown'; break;
1868
//                        case 1: $memtype .= ' Other'; break;
1869
                        case 2: $memtype .= ' SIP'; break;
1870
                        case 3: $memtype .= ' DIP'; break;
1871
                        case 4: $memtype .= ' ZIP'; break;
1872
                        case 5: $memtype .= ' SOJ'; break;
1873
                        case 6: $memtype .= ' Proprietary'; break;
1874
                        case 7: $memtype .= ' SIMM'; break;
1875
                        case 8: $memtype .= ' DIMM'; break;
1876
                        case 9: $memtype .= ' TSOPO'; break;
1877
                        case 10: $memtype .= ' PGA'; break;
1878
                        case 11: $memtype .= ' RIM'; break;
1879
                        case 12: $memtype .= ' SODIMM'; break;
1880
                        case 13: $memtype .= ' SRIMM'; break;
1881
                        case 14: $memtype .= ' SMD'; break;
1882
                        case 15: $memtype .= ' SSMP'; break;
1883
                        case 16: $memtype .= ' QFP'; break;
1884
                        case 17: $memtype .= ' TQFP'; break;
1885
                        case 18: $memtype .= ' SOIC'; break;
1886
                        case 19: $memtype .= ' LCC'; break;
1887
                        case 20: $memtype .= ' PLCC'; break;
1888
                        case 21: $memtype .= ' BGA'; break;
1889
                        case 22: $memtype .= ' FPBGA'; break;
1890
                        case 23: $memtype .= ' LGA';
2976 rexy 1891
                        }
1892
                    }
1893
                    if (isset($mem['DataWidth']) && isset($mem['TotalWidth']) && (($dataw = $mem['DataWidth']) > 0) && (($totalw = $mem['TotalWidth']) > 0) && ($dataw < $totalw)) {
1894
                        $memtype .= ' ECC';
1895
                    }
1896
                    if ($reg) {
1897
                        $memtype .= ' REG';
1898
                    }
1899
                    if (($memtype = trim($memtype)) != '') {
1900
                        $dev->setProduct($memtype);
1901
                    }
1902
                    if (isset($mem['ConfiguredClockSpeed']) && (($clock = $mem['ConfiguredClockSpeed']) > 0)) {
1903
                        $dev->setSpeed($clock);
1904
                    }
1905
                    if (isset($mem['ConfiguredVoltage']) && (($voltage = $mem['ConfiguredVoltage']) > 0)) {
1906
                        $dev->setVoltage($voltage/1000);
1907
                    }
1908
                    if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL &&
1909
                       isset($mem['SerialNumber']) && !preg_match("/^SerNum\d+$/", $serial = $mem['SerialNumber']) && ($serial != '') && ($serial != 'None')) {
1910
                        $dev->setSerial($serial);
1911
                    }
1912
                }
1913
                $this->sys->setMemDevices($dev);
1914
            }
1915
        }
1916
    }
1917
 
1918
    /**
2770 rexy 1919
     * get the information
1920
     *
1921
     * @see PSI_Interface_OS::build()
1922
     *
3037 rexy 1923
     * @return void
2770 rexy 1924
     */
1925
    public function build()
1926
    {
3037 rexy 1927
        $this->_distro(); // share getDistribution()
1928
        if (substr($this->sys->getDistribution(), 0, 7)=="ReactOS") {
1929
            $this->error->addWarning("The ReactOS version of phpSysInfo is a work in progress, some things currently don't work");
2770 rexy 1930
        }
1931
        if (!$this->blockname || $this->blockname==='vitals') {
1932
            $this->_hostname();
1933
            $this->_users();
1934
            $this->_uptime();
1935
            $this->_loadavg();
1936
            $this->_processes();
1937
        }
1938
        if (!$this->blockname || $this->blockname==='hardware') {
1939
            $this->_machine();
1940
            $this->_cpuinfo();
3037 rexy 1941
            $this->_virtualizer();
2976 rexy 1942
            $this->_meminfo();
2770 rexy 1943
            $this->_hardware();
1944
        }
3037 rexy 1945
        if (!$this->blockname || $this->blockname==='memory') {
1946
            $this->_memory();
1947
        }
2770 rexy 1948
        if (!$this->blockname || $this->blockname==='filesystem') {
1949
            $this->_filesystems();
1950
        }
3037 rexy 1951
        if (!$this->blockname || $this->blockname==='network') {
1952
            $this->_network();
2770 rexy 1953
        }
1954
    }
1955
}