diff --git a/disk/disk_windows.go b/disk/disk_windows.go index 326bc1f..f717a89 100644 --- a/disk/disk_windows.go +++ b/disk/disk_windows.go @@ -32,6 +32,15 @@ type Win32_PerfFormattedData struct { AvgDisksecPerRead uint64 AvgDisksecPerWrite uint64 } +type Win32_DiskDrive struct { + DeviceID string + FirmwareRevision string + InterfaceType string + SerialNumber string +} +type Win32_DiskPartition struct { + DeviceID string +} const WaitMSec = 500 @@ -157,7 +166,7 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC continue } - ret[d.Name] = IOCountersStat{ + tmpIO := IOCountersStat{ Name: d.Name, ReadCount: uint64(d.AvgDiskReadQueueLength), WriteCount: d.AvgDiskWriteQueueLength, @@ -166,6 +175,27 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC ReadTime: d.AvgDisksecPerRead, WriteTime: d.AvgDisksecPerWrite, } + tmpIO.SerialNumber = GetDiskSerialNumber(d.Name) + ret[d.Name] = d } return ret, nil } + +// return disk serial number(not volume serial number) of given device or empty string on error. Name of device is drive letter, eg. C: +func GetDiskSerialNumber(name string) string { + return GetDiskSerialNumberWithContext(context.Background(), name) +} + +func GetDiskSerialNumberWithContext(ctx context.Context, name string) string { + var diskPart []Win32_DiskPartition + var diskDrive []Win32_DiskDrive + err := common.WMIQueryWithContext(ctx, "Associators of {Win32_LogicalDisk.DeviceID='"+name+"'} where AssocClass=Win32_LogicalDiskToPartition", &diskPart) + if err != nil || len(diskPart) <= 0 { + return "" + } + err = common.WMIQueryWithContext(ctx, "Associators of {Win32_DiskPartition.DeviceID='"+diskPart[0].DeviceID+"'} where AssocClass=Win32_DiskDriveToDiskPartition", &diskDrive) + if err != nil || len(diskDrive) <= 0 { + return "" + } + return diskDrive[0].SerialNumber +}