diff --git a/lib/filesystem.js b/lib/filesystem.js index f2c17d2..30c781b 100644 --- a/lib/filesystem.js +++ b/lib/filesystem.js @@ -293,7 +293,9 @@ function parseDevices(lines) { model: '', serial: '', removable: false, - protocol: '' + protocol: '', + group: '', + device: '' }; } parts[0] = parts[0].trim().toUpperCase().replace(/ +/g, ''); @@ -391,6 +393,105 @@ function raidMatchLinux(data) { return result; } +function getDevicesLinux(data) { + const result = []; + data.forEach(element => { + if (element.type.startsWith('disk')) { + result.push(element.name); + } + }); + return result; +} + +function matchDevicesLinux(data) { + let result = data; + try { + const devices = getDevicesLinux(data); + result = result.map(blockdevice => { + if (blockdevice.type.startsWith('part') || blockdevice.type.startsWith('disk')) { + devices.forEach(element => { + if (blockdevice.name.startsWith(element)) { + blockdevice.device = '/dev/' + element; + } + }); + } + return blockdevice; + }); + } catch (e) { + util.noop(); + } + return result; +} + +function getDevicesMac(data) { + const result = []; + data.forEach(element => { + if (element.type.startsWith('disk')) { + result.push({ name: element.name, model: element.model, device: element.name }); + } + if (element.type.startsWith('virtual')) { + let device = ''; + result.forEach(e => { + if (e.model === element.model) { + device = e.device; + } + }); + if (device) { + result.push({ name: element.name, model: element.model, device }); + } + } + }); + return result; +} + +function matchDevicesMac(data) { + let result = data; + try { + const devices = getDevicesMac(data); + result = result.map(blockdevice => { + if (blockdevice.type.startsWith('part') || blockdevice.type.startsWith('disk') || blockdevice.type.startsWith('virtual')) { + devices.forEach(element => { + if (blockdevice.name.startsWith(element.name)) { + blockdevice.device = element.device; + } + }); + } + return blockdevice; + }); + } catch (e) { + util.noop(); + } + return result; +} + +function getDevicesWin(diskDrives) { + const result = []; + diskDrives.forEach(element => { + const lines = element.split('\r\n'); + const device = util.getValue(lines, 'DeviceID', ':'); + let partitions = element.split('@{DeviceID='); + if (partitions.length > 1) { + partitions = partitions.slice(1); + partitions.forEach(partition => { + result.push({ name: partition.split(';').toUpperCase(), device }); + }); + } + }); + return result; +} + +function matchDevicesWin(data, diskDrives) { + const devices = getDevicesWin(diskDrives); + data.map(element => { + const filteresDevices = devices.filter((e) => { return e.name === element.name.toUpperCase(); }); + if (filteresDevices.length > 0) { + element.device = filteresDevices[0].device; + } + return element; + }); + return data; +} + function blkStdoutToObject(stdout) { return stdout.toString() .replace(/NAME=/g, '{"name":') @@ -424,6 +525,7 @@ function blockDevices(callback) { let lines = blkStdoutToObject(stdout).split('\n'); data = parseBlk(lines); data = raidMatchLinux(data); + data = matchDevicesLinux(data); if (callback) { callback(data); } @@ -449,6 +551,7 @@ function blockDevices(callback) { let lines = stdout.toString().split('\n'); // parse lines into temp array of devices data = parseDevices(lines); + data = matchDevicesMac(data); } if (callback) { callback(data); @@ -465,31 +568,39 @@ function blockDevices(callback) { try { // util.wmic('logicaldisk get Caption,Description,DeviceID,DriveType,FileSystem,FreeSpace,Name,Size,VolumeName,VolumeSerialNumber /value').then((stdout, error) => { // util.powerShell('Get-CimInstance Win32_logicaldisk | select Caption,DriveType,Name,FileSystem,Size,VolumeSerialNumber,VolumeName | fl').then((stdout, error) => { - util.powerShell('Get-CimInstance -ClassName Win32_LogicalDisk | select Caption,DriveType,Name,FileSystem,Size,VolumeSerialNumber,VolumeName | fl').then((stdout, error) => { - if (!error) { - let devices = stdout.toString().split(/\n\s*\n/); - devices.forEach(function (device) { - let lines = device.split('\r\n'); - let drivetype = util.getValue(lines, 'drivetype', ':'); - if (drivetype) { - data.push({ - name: util.getValue(lines, 'name', ':'), - identifier: util.getValue(lines, 'caption', ':'), - type: 'disk', - fsType: util.getValue(lines, 'filesystem', ':').toLowerCase(), - mount: util.getValue(lines, 'caption', ':'), - size: util.getValue(lines, 'size', ':'), - physical: (drivetype >= 0 && drivetype <= 6) ? drivetypes[drivetype] : drivetypes[0], - uuid: util.getValue(lines, 'volumeserialnumber', ':'), - label: util.getValue(lines, 'volumename', ':'), - model: '', - serial: util.getValue(lines, 'volumeserialnumber', ':'), - removable: drivetype === '2', - protocol: '' - }); - } - }); - } + const workload = []; + workload.push(util.powerShell('Get-CimInstance -ClassName Win32_LogicalDisk | select Caption,DriveType,Name,FileSystem,Size,VolumeSerialNumber,VolumeName | fl')); + workload.push(util.powerShell('Get-WmiObject -Class Win32_diskdrive | Select-Object -Property PNPDeviceId,DeviceID, Model, Size, @{L=\'Partitions\'; E={$_.GetRelated(\'Win32_DiskPartition\').GetRelated(\'Win32_LogicalDisk\') | Select-Object -Property DeviceID, VolumeName, Size, FreeSpace}} | fl')); + util.promiseAll( + workload + ).then((res) => { + let logicalDisks = res.results[0].toString().split(/\n\s*\n/); + let diskDrives = res.results[1].toString().split(/\n\s*\n/); + logicalDisks.forEach(function (device) { + let lines = device.split('\r\n'); + let drivetype = util.getValue(lines, 'drivetype', ':'); + if (drivetype) { + data.push({ + name: util.getValue(lines, 'name', ':'), + identifier: util.getValue(lines, 'caption', ':'), + type: 'disk', + fsType: util.getValue(lines, 'filesystem', ':').toLowerCase(), + mount: util.getValue(lines, 'caption', ':'), + size: util.getValue(lines, 'size', ':'), + physical: (drivetype >= 0 && drivetype <= 6) ? drivetypes[drivetype] : drivetypes[0], + uuid: util.getValue(lines, 'volumeserialnumber', ':'), + label: util.getValue(lines, 'volumename', ':'), + model: '', + serial: util.getValue(lines, 'volumeserialnumber', ':'), + removable: drivetype === '2', + protocol: '', + group: '', + device: '' + }); + } + }); + // match devices + data = matchDevicesWin(data, diskDrives); if (callback) { callback(data); } @@ -1232,7 +1343,7 @@ function diskLayout(callback) { if (_windows) { try { const workload = []; - workload.push(util.powerShell('Get-CimInstance Win32_DiskDrive | select Caption,Size,Status,PNPDeviceId,BytesPerSector,TotalCylinders,TotalHeads,TotalSectors,TotalTracks,TracksPerCylinder,SectorsPerTrack,FirmwareRevision,SerialNumber,InterfaceType | fl')); + workload.push(util.powerShell('Get-CimInstance Win32_DiskDrive | select Caption,Size,Status,PNPDeviceId,DeviceId,BytesPerSector,TotalCylinders,TotalHeads,TotalSectors,TotalTracks,TracksPerCylinder,SectorsPerTrack,FirmwareRevision,SerialNumber,InterfaceType | fl')); workload.push(util.powerShell('Get-PhysicalDisk | select BusType,MediaType,FriendlyName,Model,SerialNumber,Size | fl')); if (util.smartMonToolsInstalled()) { try { @@ -1256,7 +1367,7 @@ function diskLayout(callback) { const status = util.getValue(lines, 'Status', ':').trim().toLowerCase(); if (size) { result.push({ - device: util.getValue(lines, 'PNPDeviceId', ':'), + device: util.getValue(lines, 'DeviceId', ':'), // changed from PNPDeviceId to DeviceID (be be able to match devices) type: device.indexOf('SSD') > -1 ? 'SSD' : 'HD', // just a starting point ... better: MSFT_PhysicalDisk - Media Type ... see below name: util.getValue(lines, 'Caption', ':'), vendor: getVendorFromModel(util.getValue(lines, 'Caption', ':', true).trim()), diff --git a/lib/index.d.ts b/lib/index.d.ts index de71e45..000087a 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -457,6 +457,7 @@ export namespace Systeminformation { removable: boolean; protocol: string; group?: string; + device?: string; } interface FsStatsData {