当前位置: 首页 > news >正文

golang实现windows获取加密盘符的总大小

golang实现windows获取加密盘符的总大小

package mainimport ("fmt""syscall""unsafe"
)type PartitionStyle uint32const (IOCTL_DISK_GET_DRIVE_LAYOUT_EX         = 0x00070050FILE_DEVICE_MASS_STORAGE        uint32 = 0x0000002dIOCTL_STORAGE_BASE              uint32 = FILE_DEVICE_MASS_STORAGEFILE_ANY_ACCESS                 uint16 = 0FILE_SPECIAL_ACCESS             uint16 = FILE_ANY_ACCESSFILE_READ_ACCESS                uint16 = 0x0001FILE_WRITE_ACCESS               uint16 = 0x0002METHOD_BUFFERED                 uint8  = 0METHOD_IN_DIRECT                uint8  = 1METHOD_OUT_DIRECT               uint8  = 2METHOD_NEITHER                  uint8  = 3IOCTL_STORAGE_GET_DEVICE_NUMBER uint32 = (IOCTL_STORAGE_BASE << 16) | uint32(FILE_ANY_ACCESS<<14) | uint32(0x0420<<2) | uint32(METHOD_BUFFERED)PartitionStyleMbr PartitionStyle = 0PartitionStyleGpt PartitionStyle = 1PartitionStyleRaw PartitionStyle = 2FILE_DEVICE_DISK  uint32         = 0x7
)type GUID struct {Data1 uint32Data2 uint16Data3 uint16Data4 [8]byte
}type DRIVE_LAYOUT_INFORMATION_GPT struct {DiskId               GUIDStartingUsableOffset uint64UsableLength         uint64MaxPartitionCount    uint32
}type PARTITION_INFORMATION_MBR struct {PartitionType       byteBootIndicator       boolRecognizedPartition boolHiddenSectors       uint32PartitionId         GUID
}type PARTITION_INFORMATION_GPT struct {PartitionType GUIDPartitionId   GUIDAttributes    uint64Name          [36]uint16
}type PARTITION_INFORMATION_EX struct {PartitionStyle   PartitionStyleStartingOffset   int64PartitionLength  int64DeviceNumber     int32RewritePartition boolRev01            boolRev02            boolRev03            boolPartitionInfo    [112]byte
}
type DRIVE_LAYOUT_INFORMATION_MBR struct {Signature uint32CheckSum  uint32
}type DRIVE_LAYOUT_INFORMATION_EX_HEADER struct {PartitionStyle PartitionStylePartitionCount uint32
}func getDiskHandleByNum(num uint32) (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 uint32buffer := 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
}type STORAGE_DEVICE_NUMBER struct {DeviceType      uint32DeviceNumber    uint32PartitionNumber uint32
}// formatFileSize 将文件大小转换为易读的格式
func FormatFileSize(size int64) string {// 定义文件大小单位units := []string{"B", "KB", "MB", "GB", "TB", "PB"}// 处理文件大小为0的情况if size == 0 {return "0 B"}// 计算文件大小所在单位的索引unitIndex := 0for size >= 1024 && unitIndex < len(units)-1 {size /= 1024unitIndex++}// 格式化文件大小return fmt.Sprintf("%d%s", size, units[unitIndex])
}
func GetDriveBasicInfo(drive string) (STORAGE_DEVICE_NUMBER, error) {var disk_num STORAGE_DEVICE_NUMBERvar err errorfilepath, _ := syscall.UTF16PtrFromString(`\\.\` + drive + ":")handle, err := syscall.CreateFile(filepath,syscall.GENERIC_READ,syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,nil,syscall.OPEN_EXISTING,0,0)if ^uintptr(0) == uintptr(handle) {fmt.Printf("CreateFile() failed, errmsg = %s\n", err.Error())return disk_num, nil}var size uint32 = uint32(unsafe.Sizeof(disk_num))var ret_size uint32 = 0var outbuf *byte = (*byte)(unsafe.Pointer(&disk_num))syscall.DeviceIoControl(handle,IOCTL_STORAGE_GET_DEVICE_NUMBER,nil, 0,outbuf, size,&ret_size, nil)syscall.CloseHandle(handle)return disk_num, nil
}
func GetDriveTotal(drive string) int64 {dinfo, err := GetDriveBasicInfo(drive)if err != nil {fmt.Println("dinfo", dinfo, err)return 0}DeviceNumber := dinfo.DeviceNumberdisk, err := getDiskHandleByNum(DeviceNumber)if err != nil {if err == syscall.ERROR_FILE_NOT_FOUND {// 物理磁盘号不存在,结束枚举fmt.Println("err", err)return 0}}defer syscall.CloseHandle(disk)data, err := getAllPartitionInfo(disk)if err != nil {fmt.Errorf("Failed to get partition info: %v\n", err)return 0}header := (*DRIVE_LAYOUT_INFORMATION_EX_HEADER)(unsafe.Pointer(&data[0]))next := data[int(unsafe.Sizeof(*header)):]entryOffset := GetSizeOf_DRIVE_LAYOUT_INFORMATION()entryData := next[entryOffset:]entrySize := unsafe.Sizeof(PARTITION_INFORMATION_EX{})for i := 0; i < int(header.PartitionCount); i++ {if len(entryData) < int(entrySize) {break}partitionEntry := (*PARTITION_INFORMATION_EX)(unsafe.Pointer(&entryData[0]))entryData = entryData[entrySize:]if partitionEntry.DeviceNumber == int32(dinfo.PartitionNumber) {return partitionEntry.PartitionLength}}return 0
}func main() {total := GetDriveTotal("C")fmt.Println("total", total, FormatFileSize(total))}

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 科创中心“核”动力|趋动科技:AI算力界的领跑者
  • windows C++-通过 C++/WinRT 创作 COM 组件(四)
  • 【二分查找】--- 进阶题目赏析
  • C#MVC返回DataTable到前端展示。
  • Ubuntu+QT编译QTXlsx库
  • 机器学习:knn算法实现图像识别
  • Spring Cloud全解析:配置中心之springCloudConfig配置存储
  • Linux系统-系统信息网络目录文件的相关命令
  • 微服务基础知识
  • 8.19Qt作业
  • C语言内存操作函数
  • 力扣第 411 场周赛题解
  • 西安旅游系统--论文pf
  • 每日快讯 | 京东健康:2024年上半年营收283亿元
  • vue+fastadmin跨域请求问题
  • 「译」Node.js Streams 基础
  • 【Linux系统编程】快速查找errno错误码信息
  • Docker: 容器互访的三种方式
  • HashMap ConcurrentHashMap
  • Java深入 - 深入理解Java集合
  • Laravel 菜鸟晋级之路
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Logstash 参考指南(目录)
  • QQ浏览器x5内核的兼容性问题
  • RxJS: 简单入门
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 给初学者:JavaScript 中数组操作注意点
  • 基于axios的vue插件,让http请求更简单
  • 目录与文件属性:编写ls
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 一些css基础学习笔记
  • 自动记录MySQL慢查询快照脚本
  • C# - 为值类型重定义相等性
  • postgresql行列转换函数
  • Semaphore
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • $jQuery 重写Alert样式方法
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (vue)el-tabs选中最后一项后更新数据后无法展开
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (十)c52学习之旅-定时器实验
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (一) storm的集群安装与配置
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)Linux整合apache和tomcat构建Web服务器
  • .NET 8 跨平台高性能边缘采集网关
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法