Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows support: block #156

Merged
merged 1 commit into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion block_stub.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build !linux,!darwin
// +build !linux,!darwin,!windows
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.
Expand Down
233 changes: 233 additions & 0 deletions block_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.
//

package ghw

import (
"strings"

"github.com/StackExchange/wmi"
)

const wqlDiskDrive = "SELECT Caption, CreationClassName, Description, DeviceID, Index, InterfaceType, Manufacturer, MediaType, Model, Name, Partitions, SerialNumber, Size, TotalCylinders, TotalHeads, TotalSectors, TotalTracks, TracksPerCylinder FROM Win32_DiskDrive"

type win32DiskDrive struct {
Caption string
CreationClassName string
Description string
DeviceID string
Index uint32 // Used to link with partition
InterfaceType string
Manufacturer string
MediaType string
Model string
Name string
Partitions int32
SerialNumber string
Size uint64
TotalCylinders int64
TotalHeads int32
TotalSectors int64
TotalTracks int64
TracksPerCylinder int32
}

const wqlDiskPartition = "SELECT Access, BlockSize, Caption, CreationClassName, Description, DeviceID, DiskIndex, Index, Name, Size, SystemName, Type FROM Win32_DiskPartition"

type win32DiskPartition struct {
Access uint16
BlockSize uint64
Caption string
CreationClassName string
Description string
DeviceID string
DiskIndex uint32 // Used to link with Disk Drive
Index uint32
Name string
Size int64
SystemName string
Type string
}

const wqlLogicalDiskToPartition = "SELECT Antecedent, Dependent FROM Win32_LogicalDiskToPartition"

type win32LogicalDiskToPartition struct {
Antecedent string
Dependent string
}

const wqlLogicalDisk = "SELECT Caption, CreationClassName, Description, DeviceID, FileSystem, FreeSpace, Name, Size, SystemName FROM Win32_LogicalDisk"

type win32LogicalDisk struct {
Caption string
CreationClassName string
Description string
DeviceID string
FileSystem string
FreeSpace uint64
Name string
Size uint64
SystemName string
}

func (ctx *context) blockFillInfo(info *BlockInfo) error {
win32DiskDriveDescriptions, err := getDiskDrives()
if err != nil {
return err
}

win32DiskPartitionDescriptions, err := getDiskPartitions()
if err != nil {
return err
}

win32LogicalDiskToPartitionDescriptions, err := getLogicalDisksToPartitions()
if err != nil {
return err
}

win32LogicalDiskDescriptions, err := getLogicalDisks()
if err != nil {
return err
}

// Converting into standard structures
disks := make([]*Disk, 0)
for _, diskdrive := range win32DiskDriveDescriptions {
disk := &Disk{
Name: diskdrive.Name,
SizeBytes: diskdrive.Size,
PhysicalBlockSizeBytes: 0,
DriveType: toDriveType(diskdrive.MediaType),
StorageController: toStorageController(diskdrive.InterfaceType),
BusType: toBusType(diskdrive.InterfaceType),
BusPath: UNKNOWN, // TODO: add information
Vendor: UNKNOWN, // TODO: add information
Model: diskdrive.Caption,
SerialNumber: diskdrive.SerialNumber,
WWN: UNKNOWN, // TODO: add information
Partitions: make([]*Partition, 0),
}
for _, diskpartition := range win32DiskPartitionDescriptions {
// Finding disk partition linked to current disk drive
if diskdrive.Index == diskpartition.DiskIndex {
disk.PhysicalBlockSizeBytes = diskpartition.BlockSize
// Finding logical partition linked to current disk partition
for _, logicaldisk := range win32LogicalDiskDescriptions {
for _, logicaldisktodiskpartition := range win32LogicalDiskToPartitionDescriptions {
var desiredAntecedent = "\\\\" + diskpartition.SystemName + "\\root\\cimv2:" + diskpartition.CreationClassName + ".DeviceID=\"" + diskpartition.DeviceID + "\""
var desiredDependent = "\\\\" + logicaldisk.SystemName + "\\root\\cimv2:" + logicaldisk.CreationClassName + ".DeviceID=\"" + logicaldisk.DeviceID + "\""
if logicaldisktodiskpartition.Antecedent == desiredAntecedent && logicaldisktodiskpartition.Dependent == desiredDependent {
// Appending Partition
p := &Partition{
Name: logicaldisk.Caption,
Label: logicaldisk.Caption,
SizeBytes: logicaldisk.Size,
MountPoint: logicaldisk.DeviceID,
Type: diskpartition.Type,
IsReadOnly: toReadOnly(diskpartition.Access), // TODO: add information
}
disk.Partitions = append(disk.Partitions, p)
break
}
}
}
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an idea on how we can remove the above Go code by just using a JOIN in the WQL statement... but we can work on that together in a followup patch :)

disks = append(disks, disk)
}

info.Disks = disks
var tpb uint64
for _, d := range info.Disks {
tpb += d.SizeBytes
}
info.TotalPhysicalBytes = tpb
return nil
}

func getDiskDrives() ([]win32DiskDrive, error) {
// Getting disks drives data from WMI
var win3232DiskDriveDescriptions []win32DiskDrive
if err := wmi.Query(wqlDiskDrive, &win3232DiskDriveDescriptions); err != nil {
return nil, err
}
return win3232DiskDriveDescriptions, nil
}

func getDiskPartitions() ([]win32DiskPartition, error) {
// Getting disk partitions from WMI
var win32DiskPartitionDescriptions []win32DiskPartition
if err := wmi.Query(wqlDiskPartition, &win32DiskPartitionDescriptions); err != nil {
return nil, err
}
return win32DiskPartitionDescriptions, nil
}

func getLogicalDisksToPartitions() ([]win32LogicalDiskToPartition, error) {
// Getting links between logical disks and partitions from WMI
var win32LogicalDiskToPartitionDescriptions []win32LogicalDiskToPartition
if err := wmi.Query(wqlLogicalDiskToPartition, &win32LogicalDiskToPartitionDescriptions); err != nil {
return nil, err
}
return win32LogicalDiskToPartitionDescriptions, nil
}

func getLogicalDisks() ([]win32LogicalDisk, error) {
// Getting logical disks from WMI
var win32LogicalDiskDescriptions []win32LogicalDisk
if err := wmi.Query(wqlLogicalDisk, &win32LogicalDiskDescriptions); err != nil {
return nil, err
}
return win32LogicalDiskDescriptions, nil
}

// TODO: improve
func toDriveType(mediaType string) DriveType {
var driveType DriveType
mediaType = strings.ToLower(mediaType)
if strings.Contains(mediaType, "fixed") || strings.Contains(mediaType, "ssd") {
driveType = DRIVE_TYPE_SSD
} else if strings.ContainsAny(mediaType, "hdd") {
driveType = DRIVE_TYPE_HDD
} else {
driveType = DRIVE_TYPE_UNKNOWN
}
return driveType
}

// TODO: improve
func toStorageController(interfaceType string) StorageController {
var storageController StorageController
switch interfaceType {
case "SCSI":
storageController = STORAGE_CONTROLLER_SCSI
case "IDE":
storageController = STORAGE_CONTROLLER_IDE
default:
storageController = STORAGE_CONTROLLER_UNKNOWN
}
return storageController
}

// TODO: improve
func toBusType(interfaceType string) BusType {
var busType BusType
switch interfaceType {
case "SCSI":
busType = BUS_TYPE_SCSI
case "IDE":
busType = BUS_TYPE_IDE
default:
busType = BUS_TYPE_UNKNOWN
}
return busType
}

// TODO: improve
func toReadOnly(access uint16) bool {
// See Access property from: https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskpartition
return access == 0x1
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module github.com/jaypipes/ghw
go 1.12

require (
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d
github.com/ghodss/yaml v1.0.0
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jaypipes/pcidb v0.5.0
github.com/pkg/errors v0.8.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jaypipes/pcidb v0.5.0 h1:4W5gZ+G7QxydevI8/MmmKdnIPJpURqJ2JNXTzfLxF5c=
Expand Down