using Insight.Domain.Interfaces; using Insight.Domain.Network; using Insight.Domain.Network.Agent.Messages; using System.Management; using System.Runtime.Versioning; namespace Insight.Agent.Network.Handlers; [SupportedOSPlatform("windows")] public class DriveHandler : IMessageHandler { public async ValueTask HandleAsync(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage { switch (message) { case InventoryRequest: { var result = new Collection(); result.AddRange(GetDrives()); await sender.SendAsync(result, cancellationToken); break; } } } private static List GetDrives() { using var searcher = new ManagementObjectSearcher { Scope = new ManagementScope(@"root\cimv2"), Query = new ObjectQuery("select index, name, caption, model, manufacturer, serialNumber, size, status, interfacetype, firmwarerevision, deviceid, pnpdeviceid from win32_diskdrive") }; if (searcher.TryGet(out var collection) is false) { searcher.Query = new ObjectQuery("select * from win32_diskdrive"); if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL"); } var drives = new List(); using (collection) { foreach (ManagementObject @object in collection.Cast()) { var drive = new Drive(); var properties = @object.GetPropertyHashes(); drive.Index = @object.GetValue(properties, "index"); drive.Id = @object.GetValue(properties, "deviceid")?.Trim(); drive.Name = @object.GetValue(properties, "model")?.Trim(); drive.Manufacturer = @object.GetValue(properties, "manufacturer")?.Trim(); drive.SerialNumber = @object.GetValue(properties, "serialnumber")?.Trim(); drive.Size = @object.GetValue(properties, "size"); drive.Status = @object.GetValue(properties, "status")?.Trim(); drive.InterfaceType = @object.GetValue(properties, "interfacetype")?.Trim(); drive.FirmwareRevision = @object.GetValue(properties, "firmwarerevision")?.Trim(); drive.PNPDeviceID = @object.GetValue(properties, "pnpdeviceid")?.Trim(); drive.Volumes = new List(); var diskpartition = @object.GetRelated("win32_diskpartition"); using (diskpartition) { foreach (ManagementObject dp in diskpartition.Cast()) { var volume = new Volume(); var dpProperties = dp.GetPropertyHashes(); volume.NumberOfBlocks = dp.GetValue(dpProperties, "numberofblocks"); volume.BootPartition = dp.GetValue(dpProperties, "bootpartition"); volume.PrimaryPartition = dp.GetValue(dpProperties, "primarypartition"); volume.Size = dp.GetValue(dpProperties, "size"); volume.Index = dp.GetValue(dpProperties, "index"); volume.Type = dp.GetValue(dpProperties, "type")?.Trim(); volume.Bootable = dp.GetValue(dpProperties, "bootable"); volume.BlockSize = dp.GetValue(dpProperties, "blocksize"); volume.StartingOffset = dp.GetValue(dpProperties, "startingoffset"); var logicaldisk = dp.GetRelated("win32_logicaldisk"); using (logicaldisk) { foreach (ManagementObject ld in logicaldisk.Cast()) { var ldProperties = ld.GetPropertyHashes(); volume.Id = ld.GetValue(ldProperties, "deviceid")?.Trim(); volume.Name = ld.GetValue(ldProperties, "volumename")?.Trim(); volume.SerialNumber = ld.GetValue(ldProperties, "volumeserialnumber")?.Trim(); volume.DriveType = (DriveType)ld.GetValue(ldProperties, "drivetype"); volume.FileSystem = ld.GetValue(ldProperties, "filesystem")?.Trim(); volume.Compressed = ld.GetValue(ldProperties, "compressed"); volume.Size = ld.GetValue(ldProperties, "size"); volume.FreeSpace = ld.GetValue(ldProperties, "freespace"); volume.ProviderName = ld.GetValue(ldProperties, "providername")?.Trim(); } } drive.Volumes.Add(volume); } } drives.Add(drive); } } return drives; } private static List GetVolumes() { using var searcher = new ManagementObjectSearcher { Scope = new ManagementScope(@"root\cimv2"), Query = new ObjectQuery("select deviceid, volumename, volumeserialnumber, drivetype, filesystem, compressed, size, freeSpace, providername from win32_logicaldisk") }; // per device query // "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition" if (searcher.TryGet(out var collection) is false) { searcher.Query = new ObjectQuery("select * from win32_logicaldisk"); if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL"); } var volumes = new List(); using (collection) { foreach (ManagementObject @object in collection.Cast()) { var volume = new Volume(); var properties = @object.GetPropertyHashes(); //volume.DeviceId = @object.GetValue(properties, "deviceid")?.Trim(); //volume.VolumeName = @object.GetValue(properties, "volumename")?.Trim(); //volume.VolumeSerialNumber = @object.GetValue(properties, "volumeserialnumber")?.Trim(); volume.DriveType = (DriveType)@object.GetValue(properties, "drivetype"); volume.FileSystem = @object.GetValue(properties, "filesystem")?.Trim(); volume.Compressed = @object.GetValue(properties, "compressed"); volume.Size = @object.GetValue(properties, "size"); volume.FreeSpace = @object.GetValue(properties, "freespace"); volume.ProviderName = @object.GetValue(properties, "providername")?.Trim(); if (volume.Id is not null) { searcher.Query = new ObjectQuery("associators of {win32_logicaldisk.deviceid='" + volume.Id + "'} where assocclass=win32_logicaldisktopartition"); if (searcher.TryGet(out var collection2)) { using (collection2) { foreach (ManagementObject @object2 in collection2) { var properties2 = @object2.GetPropertyHashes(); volume.Index = @object2.GetValue(properties2, "index"); //volume.DiskIndex = @object2.GetValue(properties2, "diskindex"); volume.Type = @object2.GetValue(properties2, "type")?.Trim(); volume.Bootable = @object2.GetValue(properties2, "bootable"); volume.PrimaryPartition = @object2.GetValue(properties2, "primarypartition"); volume.BootPartition = @object2.GetValue(properties2, "bootpartition"); volume.BlockSize = @object2.GetValue(properties2, "blocksize"); volume.NumberOfBlocks = @object2.GetValue(properties2, "numberofblocks"); volume.StartingOffset = @object2.GetValue(properties2, "startingoffset"); } } } } volumes.Add(volume); } } return volumes; } }