golang 获取windows磁盘GUID

golang 获取windows磁盘GUID

package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

type PartitionStyle uint32

const (
	IOCTL_DISK_GET_DRIVE_LAYOUT_EX = 0x00070050

	PartitionStyleMbr PartitionStyle = 0
	PartitionStyleGpt PartitionStyle = 1
	PartitionStyleRaw PartitionStyle = 2
)

type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

type DRIVE_LAYOUT_INFORMATION_GPT struct {
	DiskId               GUID
	StartingUsableOffset uint64
	UsableLength         uint64
	MaxPartitionCount    uint32
}

type PARTITION_INFORMATION_MBR struct {
	PartitionType       byte
	BootIndicator       bool
	RecognizedPartition bool
	HiddenSectors       uint32
	PartitionId         GUID
}

type PARTITION_INFORMATION_GPT struct {
	PartitionType GUID
	PartitionId   GUID
	Attributes    uint64
	Name          [36]uint16
}

type PARTITION_INFORMATION_EX struct {
	PartitionStyle   PartitionStyle
	StartingOffset   int64
	PartitionLength  int64
	PartitionNumber  int32
	RewritePartition bool
	Rev01            bool
	Rev02            bool
	Rev03            bool
	PartitionInfo    [112]byte
}
type DRIVE_LAYOUT_INFORMATION_MBR struct {
	Signature uint32
	CheckSum  uint32
}

type DRIVE_LAYOUT_INFORMATION_EX_HEADER struct {
	PartitionStyle PartitionStyle
	PartitionCount uint32
}

func getDiskHandleByNum(num int) (syscall.Handle, error) {
	diskName := fmt.Sprintf(`\\.\PhysicalDrive%d`, num)
	disk, _ := syscall.UTF16PtrFromString(diskName)
	handle, err := syscall.CreateFile(
		disk,
		syscall.GENERIC_READ,
		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,
		nil,
		syscall.OPEN_EXISTING,
		0,
		0,
	)
	return handle, err
}
func GetSizeOf_DRIVE_LAYOUT_INFORMATION() int {
	a := unsafe.Sizeof(DRIVE_LAYOUT_INFORMATION_GPT{})
	b := unsafe.Sizeof(DRIVE_LAYOUT_INFORMATION_MBR{})
	if a > b {
		return int(a)
	} else {
		return int(b)
	}
}
func getAllPartitionInfo(diskHandle syscall.Handle) ([]byte, error) {
	var bytesReturned uint32
	buffer := make([]byte, 4096)
	err := syscall.DeviceIoControl(diskHandle, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0, &buffer[0], uint32(len(buffer)), &bytesReturned, nil)
	if err != nil {
		return nil, err
	}
	return buffer, nil
}

func guidToString(guid GUID) string {
	return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x",
		guid.Data1, guid.Data2, guid.Data3,
		(guid.Data4[0:2]), (guid.Data4[2:8]))
}

func GetDriveGUID(num int) string {
	var disk syscall.Handle
	disk, err := getDiskHandleByNum(num)
	if err != nil {
		fmt.Printf("Failed to get disk handle: %v\n", err)
		return ""
	}
	defer syscall.CloseHandle(disk)

	data, err := getAllPartitionInfo(disk)
	if err != nil {
		fmt.Printf("Failed to get partition info: %v\n", err)
		return ""
	}
	header := (*DRIVE_LAYOUT_INFORMATION_EX_HEADER)(unsafe.Pointer(&data[0]))
	next := data[int(unsafe.Sizeof(*header)):]
	entryOffset := GetSizeOf_DRIVE_LAYOUT_INFORMATION()
	entryData := next[entryOffset:]
	partitionEntry := (*PARTITION_INFORMATION_EX)(unsafe.Pointer(&entryData[0]))
	var guidStr string
	if partitionEntry.PartitionStyle == PartitionStyleGpt {
		info := (*PARTITION_INFORMATION_GPT)(unsafe.Pointer(&partitionEntry.PartitionInfo[0]))
		guidStr = guidToString(info.PartitionId)
	} else if partitionEntry.PartitionStyle == PartitionStyleMbr {
		partitionInfo := (*PARTITION_INFORMATION_MBR)(unsafe.Pointer(&partitionEntry.PartitionInfo[0]))
		guidStr = guidToString(partitionInfo.PartitionId)
	}
	return guidStr
}
func main() {
	fmt.Println("磁盘0的GUID为:", GetDriveGUID(0))
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值