Skip to content

Commit 7ff58b7

Browse files
committed
Move WMI Volume and Partition functions to cim package
1 parent c552565 commit 7ff58b7

File tree

3 files changed

+164
-59
lines changed

3 files changed

+164
-59
lines changed

pkg/cim/volume.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,23 @@ import (
77
"fmt"
88
"strconv"
99

10+
"github.com/go-ole/go-ole"
1011
"github.com/microsoft/wmi/pkg/base/query"
1112
"github.com/microsoft/wmi/pkg/errors"
1213
"github.com/microsoft/wmi/server2019/root/microsoft/windows/storage"
14+
"k8s.io/klog/v2"
15+
)
16+
17+
const (
18+
FileSystemUnknown = 0
19+
)
20+
21+
var (
22+
VolumeSelectorListForFileSystemType = []string{"FileSystemType"}
23+
VolumeSelectorListForStats = []string{"UniqueId", "SizeRemaining", "Size"}
24+
VolumeSelectorListUniqueID = []string{"UniqueId"}
25+
26+
PartitionSelectorListObjectID = []string{"ObjectId"}
1327
)
1428

1529
// QueryVolumeByUniqueID retrieves a specific volume by its unique identifier,
@@ -78,6 +92,68 @@ func ListVolumes(selectorList []string) ([]*storage.MSFT_Volume, error) {
7892
return volumes, nil
7993
}
8094

95+
// FormatVolume formats the specified volume.
96+
//
97+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/format-msft-volume
98+
// for the WMI method definition.
99+
func FormatVolume(volume *storage.MSFT_Volume, params ...interface{}) (int, error) {
100+
result, err := volume.InvokeMethodWithReturn("Format", params...)
101+
return int(result), err
102+
}
103+
104+
// FlushVolume flushes the cached data in the volume's file system to disk.
105+
//
106+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-volume-flush
107+
// for the WMI method definition.
108+
func FlushVolume(volume *storage.MSFT_Volume) (int, error) {
109+
result, err := volume.Flush()
110+
return int(result), err
111+
}
112+
113+
// GetVolumeUniqueID returns the unique ID (object ID) of a volume.
114+
func GetVolumeUniqueID(volume *storage.MSFT_Volume) (string, error) {
115+
return volume.GetPropertyUniqueId()
116+
}
117+
118+
// GetVolumeFileSystemType returns the file system type of a volume.
119+
func GetVolumeFileSystemType(volume *storage.MSFT_Volume) (int32, error) {
120+
fsType, err := volume.GetProperty("FileSystemType")
121+
if err != nil {
122+
return 0, err
123+
}
124+
return fsType.(int32), nil
125+
}
126+
127+
// GetVolumeSize returns the size of a volume.
128+
func GetVolumeSize(volume *storage.MSFT_Volume) (int64, error) {
129+
volumeSizeVal, err := volume.GetProperty("Size")
130+
if err != nil {
131+
return -1, err
132+
}
133+
134+
volumeSize, err := strconv.ParseInt(volumeSizeVal.(string), 10, 64)
135+
if err != nil {
136+
return -1, err
137+
}
138+
139+
return volumeSize, err
140+
}
141+
142+
// GetVolumeSizeRemaining returns the remaining size of a volume.
143+
func GetVolumeSizeRemaining(volume *storage.MSFT_Volume) (int64, error) {
144+
volumeSizeRemainingVal, err := volume.GetProperty("SizeRemaining")
145+
if err != nil {
146+
return -1, err
147+
}
148+
149+
volumeSizeRemaining, err := strconv.ParseInt(volumeSizeRemainingVal.(string), 10, 64)
150+
if err != nil {
151+
return -1, err
152+
}
153+
154+
return volumeSizeRemaining, err
155+
}
156+
81157
// ListPartitionsOnDisk retrieves all partitions or a partition with the specified number on a disk.
82158
//
83159
// The equivalent WMI query is:
@@ -262,6 +338,55 @@ func SetPartitionState(part *storage.MSFT_Partition, online bool) (int, string,
262338
return int(result), status, err
263339
}
264340

341+
// GetPartitionSupportedSize retrieves the minimum and maximum sizes that the partition can be resized to using the ResizePartition method.
342+
//
343+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-partition-getsupportedsizes
344+
// for the WMI method definition.
345+
func GetPartitionSupportedSize(part *storage.MSFT_Partition) (result int, sizeMin, sizeMax int64, status string, err error) {
346+
sizeMin = -1
347+
sizeMax = -1
348+
349+
var sizeMinVar, sizeMaxVar ole.VARIANT
350+
invokeResult, err := part.InvokeMethodWithReturn("GetSupportedSize", &sizeMinVar, &sizeMaxVar, &status)
351+
if invokeResult != 0 || err != nil {
352+
result = int(invokeResult)
353+
}
354+
klog.V(5).Infof("got sizeMin (%v) sizeMax (%v) from partition (%v), status: %s", sizeMinVar, sizeMaxVar, part, status)
355+
356+
sizeMin, err = strconv.ParseInt(sizeMinVar.ToString(), 10, 64)
357+
if err != nil {
358+
return
359+
}
360+
361+
sizeMax, err = strconv.ParseInt(sizeMaxVar.ToString(), 10, 64)
362+
return
363+
}
364+
365+
// ResizePartition resizes a partition.
366+
//
367+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-partition-resize
368+
// for the WMI method definition.
369+
func ResizePartition(part *storage.MSFT_Partition, size int64) (int, string, error) {
370+
var status string
371+
result, err := part.InvokeMethodWithReturn("Resize", strconv.Itoa(int(size)), &status)
372+
return int(result), status, err
373+
}
374+
375+
// GetPartitionSize returns the size of a partition.
376+
func GetPartitionSize(part *storage.MSFT_Partition) (int64, error) {
377+
sizeProp, err := part.GetProperty("Size")
378+
if err != nil {
379+
return -1, err
380+
}
381+
382+
size, err := strconv.ParseInt(sizeProp.(string), 10, 64)
383+
if err != nil {
384+
return -1, err
385+
}
386+
387+
return size, err
388+
}
389+
265390
// FilterForPartitionOnDisk creates a WMI query filter to query a disk by its number.
266391
func FilterForPartitionOnDisk(diskNumber uint32) *query.WmiQueryFilter {
267392
return query.NewWmiQueryFilter("DiskNumber", strconv.Itoa(int(diskNumber)), query.Equals)

pkg/cim/wmi.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/go-ole/go-ole"
1010
"github.com/go-ole/go-ole/oleutil"
1111
"github.com/microsoft/wmi/pkg/base/query"
12-
"github.com/microsoft/wmi/pkg/errors"
12+
wmierrors "github.com/microsoft/wmi/pkg/errors"
1313
cim "github.com/microsoft/wmi/pkg/wmiinstance"
1414
"k8s.io/klog/v2"
1515
)
@@ -61,7 +61,7 @@ func QueryFromWMI(namespace string, query *query.WmiQuery, handler InstanceHandl
6161
}
6262

6363
if len(instances) == 0 {
64-
return errors.NotFound
64+
return wmierrors.NotFound
6565
}
6666

6767
var cont bool
@@ -95,7 +95,7 @@ func executeClassMethodParam(classInst *cim.WmiInstance, method *cim.WmiMethod,
9595

9696
iDispatchInstance := classInst.GetIDispatch()
9797
if iDispatchInstance == nil {
98-
return nil, errors.Wrapf(errors.InvalidInput, "InvalidInstance")
98+
return nil, wmierrors.Wrapf(wmierrors.InvalidInput, "InvalidInstance")
9999
}
100100
rawResult, err := iDispatchInstance.GetProperty("Methods_")
101101
if err != nil {
@@ -235,10 +235,15 @@ func InvokeCimMethod(namespace, class, methodName string, inputParameters map[st
235235
return int(result.ReturnValue), outputParameters, nil
236236
}
237237

238+
// IsNotFound returns true if it's a "not found" error.
239+
func IsNotFound(err error) bool {
240+
return wmierrors.IsNotFound(err)
241+
}
242+
238243
// IgnoreNotFound returns nil if the error is nil or a "not found" error,
239244
// otherwise returns the original error.
240245
func IgnoreNotFound(err error) error {
241-
if err == nil || errors.IsNotFound(err) {
246+
if err == nil || IsNotFound(err) {
242247
return nil
243248
}
244249
return err

0 commit comments

Comments
 (0)