vc 判断某个盘符是否为移动硬盘盘符

2023-11-15

在使用GetDriveType获取磁盘类型时,一般小容量的U盘直接返回DRIVE_REMOVABLE,倒是不用再进行下一步的判断,而大容量U盘和移动硬盘的盘符返回值和本地硬盘盘符返回值都是DRIVE_FIXED,需要再进行判断,如果是IDE硬盘的话,则盘符所属的磁盘为本地磁盘,否则为可移动磁盘。下面的函数可判断一个磁盘是否为IDE硬盘的分区,传递的磁盘盘符参数形式为C:的形式:

BOOL IsIDE(CString   DriveName)   
{   
	本段程序的前提是DriveName是已经过GetDriveType的判断是本地磁盘,否则报错,作用是判断是否是真正的本地磁盘   
	//111111111111111111111111111111111111111/   
	///获得某分区(目的地址)的信息/   
	HANDLE   hDeviceDest   =   NULL;   
	DWORD   nBytesRead   =   0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度   
	DWORD   nBufferSize   =   sizeof(PARTITION_INFORMATION);   
	PPARTITION_INFORMATION   lpPartInfo   =   (PPARTITION_INFORMATION)malloc(nBufferSize);   
	if(lpPartInfo   ==   NULL)   
	{   
		//MessageBox("缓冲区分配出错!","失败!",MB_OK);   
		return   FALSE;   
	}   
	memset(lpPartInfo,   0,   nBufferSize);//将缓冲区lpPartInfo的内容设为nDiskBufferSize个NULL   
	//CString   DriveName="J:";//为判断提供接口   
	DriveName=_T("\\\\.\\")+DriveName;   

	hDeviceDest   =   CreateFile(LPCTSTR(DriveName),//注意一定要是\\\\.\\的形式,CreateFile的要求   ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}   
		GENERIC_READ,   
		FILE_SHARE_READ   |   FILE_SHARE_WRITE,   
		NULL,   OPEN_EXISTING,   
		0,   NULL);   

	if(hDeviceDest   ==   NULL)   
	{   
		//MessageBox("CreateFile出错!","失败!",MB_OK);   
		return   FALSE;   
	}   
	/获得该分区信息/   
	BOOL   ret1=DeviceIoControl(   
		hDeviceDest,   
		IOCTL_DISK_GET_PARTITION_INFO,   
		NULL,   
		0,   
		(LPVOID)   lpPartInfo,   
		(DWORD)   nBufferSize,   
		(LPDWORD)   &nBytesRead,   
		NULL//指向一个异步的结构体   
		);   

	if   (!ret1)   
	{   
		LPVOID   lpMsgBuf;   
		FormatMessage(     
			FORMAT_MESSAGE_ALLOCATE_BUFFER   |     
			FORMAT_MESSAGE_FROM_SYSTEM   |     
			FORMAT_MESSAGE_IGNORE_INSERTS,   
			NULL,   
			GetLastError(),   
			MAKELANGID(LANG_NEUTRAL,   SUBLANG_DEFAULT),   //   Default   language   
			(LPTSTR)   &lpMsgBuf,   
			0,   
			NULL     
			);   
		//::MessageBox( NULL,(LPCTSTR)lpMsgBuf,   _T("Error"),   MB_OK   |   MB_ICONINFORMATION   );   
		LocalFree(   lpMsgBuf   );   
		//MessageBox("DeviceIoControl出错!","失败!",MB_OK);   
		return     FALSE;   
	}   
	///导出该分区信息///   
	LARGE_INTEGER   StartingOffset=lpPartInfo->StartingOffset;   
	LONGLONG   QuadPart=StartingOffset.QuadPart;//取上面的值之一情形,支持64位整型   
	LARGE_INTEGER   PartitionLength=lpPartInfo->PartitionLength;   
	LONGLONG   QuadPart1=PartitionLength.QuadPart;//取上面的值之一情形,支持64位整型   
	DWORD   HiddenSectors=lpPartInfo->HiddenSectors;   
	DWORD   PartitionNumber=lpPartInfo->PartitionNumber;   
	BYTE     PartitionType=lpPartInfo->PartitionType;   
	BOOLEAN   BootIndicator=lpPartInfo->BootIndicator;   
	BOOLEAN   RecognizedPartition=lpPartInfo->RecognizedPartition;   
	BOOLEAN   RewritePartition=lpPartInfo->RewritePartition;   

	free(lpPartInfo);   
	CloseHandle(hDeviceDest);   

	/查询注册表中COUNT(Disk)的值//   
	UINT   IDESeqNum;//IDE的序号   
	BOOL   FindIDE=FALSE;   

	HKEY   hKEY;   
	RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum"),   0,   KEY_READ,   &hKEY);     
	///接收DWORD型/   

	DWORD   Type;//仅仅用于接收数据类型   
	DWORD   dwValue;   
	DWORD   dwBufLen   =   sizeof(DWORD);   
	long   ret2=::RegQueryValueEx(hKEY,   _T("Count"),   NULL,   &Type,   (BYTE*)&dwValue,   &dwBufLen);   
	if(ret2!=ERROR_SUCCESS)   
	{   
		//MessageBox("找不到磁盘的个数","提示",MB_OK);   
		return   FALSE;//失败   
	}   
	for   (UINT   k=0;   k<dwValue;   k++)   
	{       
		///接收字符型/   
		TCHAR   str[256];   
		DWORD     sl   =   256;       
		CString   nDisk;   
		nDisk.Format(_T("%u"),k);   
		RegQueryValueEx(hKEY,     nDisk,     NULL,     NULL,     (LPBYTE)str,     &sl);   //注意第三项必须设为NULL,否则接收到的字符数据出错     
		CString   temp=str;   
		if   (temp.Left(3)== _T("IDE") )  
		{   
			IDESeqNum=k;//IDE的序号   
			FindIDE=TRUE;   
		}   

	}   
	if   (!FindIDE)       
		return   FALSE;       //     IDESeqNum=0;   
	RegCloseKey(hKEY);       

	CString   temp;   
	temp.Format(_T("%u"),IDESeqNum);   
	temp=_T("\\\\.\\PHYSICALDRIVE")+temp;//为下一步检测作准备   
	//22222222222222222222222222222222222222222   /   


	HANDLE   hDevice   =   NULL;   
	DWORD   nDiskBytesRead   =   0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度   
	DWORD   nDiskBufferSize   =   sizeof(DRIVE_LAYOUT_INFORMATION)   +   sizeof(PARTITION_INFORMATION)*104;//26*4   
	PDRIVE_LAYOUT_INFORMATION   lpDiskPartInfo   =   (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);   

	if(lpDiskPartInfo   ==   NULL)   
	{   
		//MessageBox("缓冲区分配出错!","失败!",MB_OK);   
		return   FALSE;   
	}   
	memset(lpDiskPartInfo,   0,   nDiskBufferSize);//将缓冲区lpDiskPartInfo的内容设为nDiskBufferSize个NULL   

	//获得所有分区的信息///   
	hDevice   =   CreateFile(LPCTSTR(temp),//注意一定要是\\\\.\\的形式,CreateFile的要求   ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}   
		GENERIC_READ,   
		FILE_SHARE_READ   |   FILE_SHARE_WRITE,   
		NULL,   OPEN_EXISTING,   
		0,   NULL);   

	if(hDevice   ==   NULL)   
	{   
		//MessageBox("CreateFile出错!","失败!",MB_OK);   
		return   FALSE;   
	}   

	/获得某磁盘上的所有分区信息/   
	BOOL   ret=DeviceIoControl(   
		hDevice,   
		IOCTL_DISK_GET_DRIVE_LAYOUT,   
		NULL,   
		0,   
		(LPVOID)   lpDiskPartInfo,   
		(DWORD)   nDiskBufferSize,   
		(LPDWORD)   &nDiskBytesRead,   
		NULL   
		);   

	if   (!ret)   
	{   
		LPVOID   lpMsgBuf;   
		FormatMessage(     
			FORMAT_MESSAGE_ALLOCATE_BUFFER   |     
			FORMAT_MESSAGE_FROM_SYSTEM   |     
			FORMAT_MESSAGE_IGNORE_INSERTS,   
			NULL,   
			GetLastError(),   
			MAKELANGID(LANG_NEUTRAL,   SUBLANG_DEFAULT),   //   Default   language   
			(LPTSTR)   &lpMsgBuf,   
			0,   
			NULL     
			);   
		//MessageBox(   (LPCTSTR)lpMsgBuf,   "Error",   MB_OK   |   MB_ICONINFORMATION   );   
		LocalFree(   lpMsgBuf   );   
		//MessageBox("DeviceIoControl出错!","失败!",MB_OK);   
		return   FALSE;   
	}   

	//导出分区信息///   
	DWORD   PartitionCount=lpDiskPartInfo->PartitionCount;     //永远是实际的分区数的4倍,不能用的分区将会显示类型PARTITION_ENTRY_UNUSED,即分区类型为0   
	///依次获取导出某分区信息,并与目的驱动器进行比较///   
	for   (UINT   i=0;   i<PartitionCount;   i=i+4)//+4是因为只有下标为4的整数倍的值才是正确的引用   
	{   
		PARTITION_INFORMATION   DiskPartInfo=lpDiskPartInfo->PartitionEntry[i];//0为C:,4为D:,8为e:,12为F   

		LARGE_INTEGER   DiskStartingOffset   =   DiskPartInfo.StartingOffset;   
		LONGLONG   DiskQuadPart   =   DiskStartingOffset.QuadPart; //取上面的值之一情形,支持64位整型   
		LARGE_INTEGER   DiskPartitionLength   =   DiskPartInfo.PartitionLength;   
		LONGLONG   DiskQuadPart1   =   DiskPartitionLength.QuadPart; //取上面的值之一情形,支持64位整型   
		DWORD   DiskHiddenSectors   =   DiskPartInfo.HiddenSectors;   
		DWORD   DiskPartitionNumber   =   DiskPartInfo.PartitionNumber;   
		BYTE     DiskPartitionType   =   DiskPartInfo.PartitionType;   
		BOOLEAN   DiskBootIndicator   =   DiskPartInfo.BootIndicator;   
		BOOLEAN   DiskRecognizedPartition   =   DiskPartInfo.RecognizedPartition;   
		BOOLEAN   DiskRewritePartition   =   DiskPartInfo.RewritePartition;   
		if     ((DiskQuadPart==QuadPart)   &&   (DiskQuadPart1==QuadPart1)   
			&&   (DiskHiddenSectors==HiddenSectors)   &&   (DiskPartitionNumber==PartitionNumber)   
			&&   (DiskPartitionType==PartitionType   )   &&   (DiskBootIndicator==BootIndicator)   
			&&   (DiskRecognizedPartition==RecognizedPartition)   &&   (DiskRewritePartition==RewritePartition))   
		{   
			free(lpDiskPartInfo);   
			CloseHandle(hDevice);   
			//::MessageBox(NULL,_T("属于本地驱动器!"),_T("提示"),MB_OK);   
			return   TRUE;   
		}   
	}   
	free(lpDiskPartInfo);   
	CloseHandle(hDevice);   
	//::MessageBox(NULL,_T("非本地驱动器!"),_T("提示"),MB_OK);//改为return   IDCANCEL;   
	return   FALSE;
}


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vc 判断某个盘符是否为移动硬盘盘符 的相关文章

  • 调用不通过空指针访问成员的非静态方法是否合法/定义良好的 C++?

    我最近遇到了以下代码 class Foo public void bar other stuff void Foo bar if this do some stuff without accessing any data members r
  • WPF 网格布局

    是否可以在 WPF 中使用 Grid 来设计类似的东西 设计列很容易 但是行呢 或者有没有更好的解决方案 比如另一个容器 将每个矩形想象为模块 GroupBox 创建一个包含两列的外部网格 在此网格中 放置另外两个网格 每列一个 这将导致所
  • 分组为连续整数范围

    我检查了其他帖子 包括使用 Linq 按可变整数范围进行分组 https stackoverflow com questions 1375997 group by variable integer range using linq 但我没有
  • android:widgetLayout 和 android:layout 之间的区别?

    我得到一些奇怪的配置 其中 widgetLayout 配置列表项的内部空间 而布局配置整个项目列表和屏幕背景 有人能真正解释一下什么是 widgetLayout 吗 android layout 整个首选项的布局 包括标题 摘要和小部件 a
  • 如何使用 BufferedReader 对象从 Java 中的一行读取多个整数值?

    我正在使用 BufferedReader 类读取 Java 程序中的输入 我想读取用户的输入 该用户可以在带空格的单行中输入多个整数数据 我想读取整数数组中的所有这些数据 输入格式 用户首先输入他 她想要输入的数字数量 然后在下一行中使用多
  • 具有键唯一性和按位置排序的 MFC 字典集合

    看着表上http msdn microsoft com en us library y1z022s1 28v vs 80 29 aspx core collection shape features http msdn microsoft
  • Android - 状态栏阻止全屏

    我的应用程序启动时可以全屏正确运行 然而 在最小化然后返回应用程序后 状态栏会弹出 并将我的视图向下推一点 如何防止状态栏移动我的视图 这是我的布局
  • 以编程方式向 LinearLayout 添加边框

    我该如何添加以编程方式LinearLayout 的边框 假设我们创建了这个布局 LinearLayout TitleLayout new LinearLayout getApplicationContext TitleLayout setO
  • 网格布局:创建 CSS,以便元素在调整相邻元素大小时保持位置

    我想在网格布局中构建一个简单的图像库 并且我正在使用类似的东西悬停时缩放 http www javascript fx com navigation imagezoom general help help html缩放悬停图像 但我宁愿使用
  • 将 2 个字节转换为整数

    我收到一个 2 个字节的端口号 最低有效字节在前 我想将其转换为整数 以便我可以使用它 我做了这个 char buf 2 Where the received bytes are char port 2 port 0 buf 1 port
  • 无法在 JavaScript for 循环中读取 null 的属性“长度”

    我正在尝试制作一个像 Stack Overflow 那样的 Markdown 编辑器 如果我实际上没有在文本区域中键入星号和包含短语的 http 我会收到标题中列出的此错误 如果我只输入包含星号的短语 则错误指的是这一行 if linkif
  • MFC编辑控件更新

    我尝试使用它添加的变量来更新编辑控件的文本 这是一个CString但我失败了 m sNrAuto some text UpdateData TRUE 我也尝试过使用UpdateWindow 但编辑控件仍为空白 我知道我可以使用SetWind
  • 如何检查 BOOL 是否为空?

    有没有办法在将值分配给 BOOL 之前检查该值是否为 NULL Nil 例如 我在 NSDictionary 中有一个值可以是 TRUE FALSE NULL mySTUser current user following results
  • 在流体设计中将元素的宽度调整为其高度的百分比,反之亦然? [复制]

    这个问题在这里已经有答案了 我正在制作响应式设计 无论屏幕尺寸是什么 它都必须保持其元素的比例 高度与宽度 所以我不知道任何元素的像素大小 并且我只能以 工作 我可以将宽度或高度设置为浏览器大小的百分比 但我不知道如何设置其他属性值 仅使用
  • json_encode 返回 NULL?

    由于某种原因 项目 描述 返回NULL使用以下代码 这是我的数据库的架构 CREATE TABLE staff id int 11 NOT NULL AUTO INCREMENT name longtext COLL
  • minHeight 有什么作用吗?

    在附图中 我希望按钮列与图像的高度相匹配 但我也希望按钮列有一个最小高度 它正确匹配图像的高度 但不遵守 minHeight 并且会使按钮向下滑动 我正在为按钮列设置这些属性
  • 如何将十六进制颜色字符串解析为整数

    我正在 Robolectric 中编写一些代码 即IntegerResourceLoader 下面的方法抛出一个RuntimeException when rawValue是诸如0xFFFF0000 Override public Obje
  • C# 和 SQL Server:如果字符串值为空,如何在命令参数中插入 DBNull.Value?

    我已经搜索了几个小时 但找不到解决方案 我正在将一些字符串插入 SQL 但是有时 我用来执行此操作的方法可能包含空字符串 即 因此我想在 SQL Server 中插入一个空值 首先我测试我的方法以确保我能够插入DBNull Value通过使
  • 将 null 转换为对象?

    我今天遇到了这段代码 AsyncInvoke OnTimeMessageTimer object null ElapsedEventArgs null 有没有什么问题 有时 当方法重载时 您需要这样做 以告诉编译器您正在调用哪一个 null
  • JavaScript 中是否存在整数类型?

    我刚刚开始学习 Javascript 我立即对 Mozilla 中看似矛盾的陈述感到困惑JavaScript 重新介绍 JS 教程 https developer mozilla org en US docs Web JavaScript

随机推荐

  • 程序员疯抢的 Java 面试宝典(PDF 版)限时开源,别把大厂想的那么难,关键是你准备得如何

    Java 面试 2022 届高校毕业生规模预计 1076 万人 同比增加 167 万人 对于 22 届的同学们来说 今年下半年大规模进行的秋招是获得全职 Offer 的最重要的途径 对于程序员来说 大家都知道校招难度相对于社招来说会有所降低
  • Windows IIS服务器建站/网站配置全图文流程(新手必备!) 一条龙

    阿里ECS云服务器购买配置全教程 本文提供全图文流程 中文翻译 Chinar 坚持将简单的生活方式 带给世人 拥有更好的阅读体验 高分辨率用户请根据需求调整网页缩放比例 Chinar 心分享 心创新 助力快速完成服务器的购买 配置 以及网站
  • vite 和 webpack 优缺点对比

    Vite 和 Webpack 都是前端构建工具 它们有一些相似之处 也有一些不同之处 下面是 Vite 和 Webpack 的优缺点对比 Vite 的优点 快速的开发者体验 Vite 可以实现快速的冷启动和热更新 使开发者可以迅速地获取反馈
  • [QT编程系列-21]:基本框架 - QT常见数据结构:QString、QList、QVector、QMap、QHash、QSet、QPair详解

    目录 1 QString 2 QList 3 QVector 4 QMap 5 QHash 6 QSet 7 QPair 1 QString QString是Qt中用于存储和操作字符串的类 它提供了丰富的字符串处理方法和功能 以下是QStr
  • 基于改进SEIR模型的病毒传播动力学建模与疫情预测分析(以COVID-19新冠病毒为例,超详细,带matlab源码)

    文章目录 前言 一 数学基础知识 符号定义 二 传统SEIR模型的建立与求解 1 经典的SEIR传播动力学模型建立 2 根据经典的SEIR模型列出微分方程并求解 三 SEIR模型第一次修正 1 模型建立 2 模型求解 四 SEIR模型的第二
  • C++项目实战-makefile

    makefile简介 一个工程中的源文件不计其数 一个项目有有很多的文件 现在的项目基本都是按模块进行划分的 而这些模块存放在若干目录中 makefile中定义了一系列的规则 这些规则定义了一系列如何编译程序的操作 比如哪些文件需要编译 哪
  • 如何使用git send-email

    How to Use git send email 建议使用git send email发送补丁 更多关于发送补丁的信息请参考Community 本文介绍如何使用git send email 安装 send email 你的git可能已经安
  • PLSQL Developer设置

    PLSQL Developer设置 解决用PLSQL Developer查询时数据大小超过100M的提示问题 Tools gt Preferences gt SQL Window Maximum Result Set size 0 is u
  • error 1962

    今天电脑出了一点小毛病 报错 error 1962 No operation system found 由于很多的资料还有项目在里边存着 而且只有一个c盘 这可怎么解决 对于一个英文不好的中国人来说 这可是个麻烦事 静下心 仔细琢磨还是能够
  • C++11新特性

    1 列表初始化 2 变量类型推导 3 范围for循环 4 final与override 5 智能指针 6 新增加容器 静态数组array forward list以及unordered系列 7 默认成员函数控制 8 右值引用 9 lambd
  • gcc -lpthread

    转自 http www cnblogs com suntp p 6473751 html 如果用gcc编译使用了POSIX thread的程序时 通常需要加额外的选项 以便使用thread safe的库及头文件 一些老的书里说直接增加链接选
  • 《机器学习的随机矩阵方法》

    机器学习的随机矩阵方法 作者 Romain Couillet 和Zhenyu Liao 出版商 剑桥大学出版社 第 1 版 2022 年 10 月 31 日 语言 英语 精装版 408 页 ISBN 10 1009123238 ISBN 1
  • chrome浏览器https证书不安全页面打开设置

    访问https协议的页面浏览器都会加载此页面所需要的证书 在证书不被信任 即证书不是有正规CA机构颁发的话 通常是由自己通过证书生成工具或命令生成的 chrome浏览器会提示页面不安全而不会直接访问该页面 此时有两种选择 选择安全方式 不再
  • 面试题创作0005,请说明Linux 和 AI的关系(联系和区别)

    请说明Linux 和 AI的关系 联系和区别 可以在AI的业务应用 平台服务提供 平台设备商 集成电路开发等各个跟AI相关的行业来寻找联系和区别
  • MATLAB——矩阵与阵列

    变量及操作 变量命名规则 赋值语句 运算符和表达式 矩阵产生与表示 直接输入法创建矩阵 向量法创建矩阵 函数法创建矩阵 特殊矩阵 矩阵元素的引用 矩阵单个元素与行列提取 向量标识方式 矩阵基本操作 矩阵提取子块 合并短阵 转置与展开 提取子
  • Lion闭源大语言模型的对抗蒸馏框架实践

    Lion闭源大语言模型的对抗蒸馏框架实践 概述 对抗蒸馏框架概述 我们基于高级闭源LLM的基础上提炼一个学生LLM 该LLM具有三个角色 教师 裁判和生成器 有三个迭代阶段 模仿阶段 对于一组指令 将学生的响应与老师的响应对齐 区分阶段 识
  • ESP8266-NodeMCU(一)

    ESP8266 NodeMCU开发板的驱动有CH340和CP210等等 本文使用ESP8266 NodeMCU CH340驱动版本 一 开发板详解 NodeMCU是一个开源的IoT物联网硬件开发板 由于它支持WIFI功能且使用方法十分类似A
  • RAM处理器的8种寻址方式

    什么是寻址 寻址是指找到存储数据或指令的地址 然后读取其中的内容 寻址方式就是处理器根据指令中给出的地址信息来寻找有效地址的方式 是确定本条指令的数据地址以及下一条要执行的指令地址的方法 ARM处理器采用的RISC架构 CPU本身是不能直接
  • MyBatis resultMap collection标签 返回基本类型集合 如:List<Long> List<String> List<Integer>等

    class xxDTO private Long id private Set
  • vc 判断某个盘符是否为移动硬盘盘符

    在使用GetDriveType获取磁盘类型时 一般小容量的U盘直接返回DRIVE REMOVABLE 倒是不用再进行下一步的判断 而大容量U盘和移动硬盘的盘符返回值和本地硬盘盘符返回值都是DRIVE FIXED 需要再进行判断 如果是IDE