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

news2024/11/15 16:24:51

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

package main

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

type PartitionStyle uint32

const (
	IOCTL_DISK_GET_DRIVE_LAYOUT_EX         = 0x00070050
	FILE_DEVICE_MASS_STORAGE        uint32 = 0x0000002d
	IOCTL_STORAGE_BASE              uint32 = FILE_DEVICE_MASS_STORAGE
	FILE_ANY_ACCESS                 uint16 = 0
	FILE_SPECIAL_ACCESS             uint16 = FILE_ANY_ACCESS
	FILE_READ_ACCESS                uint16 = 0x0001
	FILE_WRITE_ACCESS               uint16 = 0x0002
	METHOD_BUFFERED                 uint8  = 0
	METHOD_IN_DIRECT                uint8  = 1
	METHOD_OUT_DIRECT               uint8  = 2
	METHOD_NEITHER                  uint8  = 3
	IOCTL_STORAGE_GET_DEVICE_NUMBER uint32 = (IOCTL_STORAGE_BASE << 16) | uint32(FILE_ANY_ACCESS<<14) | uint32(0x0420<<2) | uint32(METHOD_BUFFERED)

	PartitionStyleMbr PartitionStyle = 0
	PartitionStyleGpt PartitionStyle = 1
	PartitionStyleRaw PartitionStyle = 2
	FILE_DEVICE_DISK  uint32         = 0x7
)

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
	DeviceNumber     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 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 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
}

type STORAGE_DEVICE_NUMBER struct {
	DeviceType      uint32
	DeviceNumber    uint32
	PartitionNumber uint32
}

// formatFileSize 将文件大小转换为易读的格式
func FormatFileSize(size int64) string {
	// 定义文件大小单位
	units := []string{"B", "KB", "MB", "GB", "TB", "PB"}

	// 处理文件大小为0的情况
	if size == 0 {
		return "0 B"
	}

	// 计算文件大小所在单位的索引
	unitIndex := 0
	for size >= 1024 && unitIndex < len(units)-1 {
		size /= 1024
		unitIndex++
	}

	// 格式化文件大小
	return fmt.Sprintf("%d%s", size, units[unitIndex])
}
func GetDriveBasicInfo(drive string) (STORAGE_DEVICE_NUMBER, error) {
	var disk_num STORAGE_DEVICE_NUMBER
	var err error
	filepath, _ := 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 = 0
	var 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.DeviceNumber
	disk, 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))

}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2056937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【生物特征识别论文分享】基于深度学习的掌纹掌静脉识别

&#xff08;待更新&#xff09;基于深度学习的生物特征识别&#xff08;手掌静脉、手背静脉、手指静脉、掌纹、人脸等&#xff09;论文模型总结 。具体方法包括&#xff1a;基于特征表征、基于传统网络设计与优化、基于轻量级网络设计与优化、基于Transformer设计与优化、基于…

Isaac Sim仿真平台学习(2)基础知识

目录 0.前言 1.isaac sim的组建 1.Isaac Lab的资料 2.PhysX 3.RTX 4.Digital Twins 5.Replicator 6.Omnigraph 0.前言 难得更新阿&#xff0c;今天黑猴发布了没有去玩&#xff0c;跑来更新博客&#xff0c;本来想着按宇树的go2开发指南去试试RL的&#xff0c;但可惜没成…

39_WAF的概念、功能,ModSecurity部署配置、LAMP环境部署、Ubuntu搭建DVWA靶机测试、测试WAF防御、OWASP规则集的部署

一、WAF的概念 WAF&#xff08; Web Application Firewall &#xff09;&#xff0c;即Web应用防火墙 通过执行一系列HTTP/HTTPS&#xff08;应用层的协议&#xff09;的安全策略为Web应用提供保护的一种网络安全产品。增加攻击者的难度和成本&#xff0c;但不是100%安全。工…

XRAY~漏洞扫描工具

有人说&#xff1a;“所有的漏扫工具都是人写出来的&#xff0c;既然是工具&#xff0c;肯定没有人厉害&#xff0c;但是&#xff0c;漏扫可以大大减少你的工作量” 4、⭐ XRAY xray 是一款功能强大的安全评估工具&#xff0c;由多名经验丰富的一线安全从业者呕心打造而成&…

五、2 移位操作符赋值操作符

1、移位操作符 2、赋值操作符 “ ”赋值&#xff0c;“ ”判断是否相等 1&#xff09;连续赋值 2&#xff09;复合赋值符

关于栈(顺序栈)的知识讲解

1.1 什么是栈 栈是只能在一端进行插入和删除操作的线性表(又称为堆栈)&#xff0c;进行插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。 特点&#xff1a;栈是先进后出FILO(First In Last Out) (LIFO(Last In First Out)) 1.2 顺序栈 1.2.1 特性 逻辑结构&#xff1…

推荐4款高效的视频剪辑神器。

很多人一开始&#xff0c;面对各种视频剪辑软件时会不知所措。不知道该选择哪一个&#xff0c;也知道如何使用。但是这几个软件&#xff0c;对于不太熟悉视频剪辑的朋友们来说简直就是神器&#xff0c;简单易上手&#xff0c;功能做的也非常的专业。 1、福昕剪辑软件 直达链接…

高性能 Web 服务器:让网页瞬间绽放的魔法引擎(下)

目录 一.Nginx 反向代理功能 1.缓存功能 2.http 反向代理负载均衡 二.实现 Nginx 四层负载均衡 三.实现 FastCGI 1.为什么会有FastCGI&#xff1f; 2.什么是PHP-FPM&#xff1f; 3.FastCGI配置指令 4.Nginx与php-fpm在同一服务器 5.Nginx配置转发 6. php的动态扩展模…

关于c++多线程中的互斥锁mutex

关于c多线程中的互斥锁mutex c中的多线程线程的基本概念C 标准库中的线程支持 多线程与主线程与join换一种方式理解线程互斥锁第一种第二种 子线程与互斥锁混合锁--看这个应该就明白了&#xff08;这个主要使用的是嵌套锁&#xff09;定义一个类创建线程 这个示例主要使用并列锁…

SAP负库存

业务示例 在系统中&#xff0c;对于一些物料而言&#xff0c;不能立即将收到的交货输入为收货。如果要使发货无论如何都是可以过帐的&#xff0c;则需要允许这些物料的负库存。 负库存 发货数量大于预订数量时&#xff0c;过帐该发货就会出现负库存。如果由于组织原因&#…

【人工智能】Transformers之Pipeline(十一):零样本图片分类(zero-shot-image-classification)

目录 一、引言 二、零样本图像分类&#xff08;zero-shot-image-classification&#xff09; 2.1 概述 2.2 技术原理 2.3 应用场景 2.4 pipeline参数 2.4.1 pipeline对象实例化参数 2.4.2 pipeline对象使用参数 2.4 pipeline实战 2.5 模型排名 三、总结 一、引言 …

嵌入式软件--PCB DAY 1

一、入门 1.什么是PCB 随着技术的进步&#xff0c;我们已经可以将一个电子设备的主要功能全部集成在一块单独的电路板上。这种电路板可以由相关的机械设备像印刷一样生产出来。因此我们现在的电路板可以被称为印刷电路板(Printed Circuit Board&#xff09;。 2.什么是PCBA …

洛谷B3981题解

题目描述 &#xff08;你不需要看懂这张图片&#xff1b;但如果你看懂了&#xff0c;会觉得它很有趣。&#xff09; JavaScript 是一种功能强大且灵活的编程语言&#xff0c;也是现代 Web 开发的三大支柱之一 (另外两个是 HTML 和 CSS)。灵活的 JavaScript 包含“自动类型转换…

C++实现——红黑树

目录 1.红黑树 1.1红黑树的概念 1.2红黑树的性质 1.3红黑树节点的定义 1.4红黑树的插入操作 1.5红黑树的验证 1.6红黑树的删除 1.7红黑树与AVL树的比较 1.8红黑树的应用 1.红黑树 1.1红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位…

系统架构:分而治之

系统架构&#xff1a;分而治之 引言“分而治之”在架构中的应用模块化设计分层化架构微服务架构 分而治之的优势降低复杂性提高灵活性和可扩展性增强可维护性促进团队协作 分而治之的劣势复杂性转移性能开销开发和运维的复杂性数据一致性挑战 结论 引言 “分而治之”是一种分析…

修改Patroni ttl和retry_timeout

参数解释 修改 & 查看 https://www.cnblogs.com/linyouyi/p/15714010.html

58.区间和

58.区间和 //卡码网题号58.区间和 /* //如果我查询m次&#xff0c;每次查询的范围都是从0到n-1&#xff0c;那么该算法的时间复杂度是O(n*m)&#xff0c; //如果查询次数非常大的话&#xff0c;这个时间复杂度也是非常大的。 #include<iostream> #include<vector> …

失易得数据恢复体验,2024精选数据恢复工具推荐!

数据丢失的风险无处不在&#xff0c;可能是由于硬件故障、软件错误、病毒感染或人为操作失误等原因。在这种情况下&#xff0c;数据恢复工具就显得尤为重要。本文将介绍几款市场上广受好评的数据恢复工具&#xff0c;帮助您在数据丢失后能够迅速找回宝贵的信息。 一、Foxit数据…

Windows客户端加入域环境时提示指定的服务器无法运行请求的操作

工作中小毛小病之&#xff1a;如下图 问题出在域控制器上&#xff0c;检查域控制器的各项域服务是否正常&#xff0c;确认windows防火墙关闭&#xff0c;一般能解决这个问题&#xff1b; 如果之前一切正常&#xff0c;只是某台电脑重装系统或者新电脑加入域出现这个情况&#…

LCD 显示字符

1.0 字符显示 使用显示图片的方式显示字符会浪费存储空间&#xff0c;显示字符的时候字符的笔画是一个固定的颜色&#xff0c;因此不用使用显示图片的方式&#xff0c;可以使用1 表示字符的本身&#xff0c;0 表示字符的背景&#xff0c;使用这种方式显示字符节省存储空间。 注…