如何对没有盘符的分区/卷进行信息查询?

路杨 2016-06-07 07:50:09
问题的提出是对于 windows 下没有分配盘符的磁盘分区,比如 ESP 区。 想读出其信息,比如 文件格式(FAT32?),大小,卷标等等。

目前我可以通过 FindFirstVolume, FindNextVolume 循环获取所有的分区的信息(包含没有分配盘符的分区,但是没有 ESP区)。并且用 QueryDosDevice 获取成为 \Device\HarddiskVolume1 字样的数据。

但是,问题来了。怎么样进一步?

通过 GetVolumePathNamesForVolumeName 我可以转化 \Device\HarddiskVolume1 成盘符,但是只能获取有盘符的。

本来GetVolumeInformation 可以获取我想要的 文件格 和 卷标,但是 GetVolumeInformation 的第一个参数是 “C:\” 字样的Path.

请大家帮忙开拓思路。 40分送上。

PS: VC6 + Win10 ,好痛苦,很多高级功能都用不上。。。。。。
...全文
1465 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
路杨 2016-06-08
  • 打赏
  • 举报
回复
TRACE 输出
VolumeName=\\?\Volume{4b82a9cd-f62c-4e78-8117-0682014b76b1}\
strNewVolumeName: Volume{4b82a9cd-f62c-4e78-8117-0682014b76b1}

---Found a device:  \Device\HarddiskVolume4 
---Volume name: \\?\Volume{4b82a9cd-f62c-4e78-8117-0682014b76b1}\ 
---Volume Path: C:\ 
---

---Next----: \\?\Volume{e6a20ef8-8568-44c8-9884-85529888078c}\
VolumeName=\\?\Volume{e6a20ef8-8568-44c8-9884-85529888078c}\
strNewVolumeName: Volume{e6a20ef8-8568-44c8-9884-85529888078c}

---Found a device:  \Device\HarddiskVolume5 
---Volume name: \\?\Volume{e6a20ef8-8568-44c8-9884-85529888078c}\ 
---Volume Path: D:\ 
---

---Next----: \\?\Volume{9c891708-4505-4306-997b-9187a0eefeca}\
VolumeName=\\?\Volume{9c891708-4505-4306-997b-9187a0eefeca}\
strNewVolumeName: Volume{9c891708-4505-4306-997b-9187a0eefeca}

---Found a device:  \Device\HarddiskVolume6 
---Volume name: \\?\Volume{9c891708-4505-4306-997b-9187a0eefeca}\ 
---Volume Path: E:\ 
---

---Next----: \\?\Volume{06425352-b0da-4862-b565-f09c46b4496d}\
VolumeName=\\?\Volume{06425352-b0da-4862-b565-f09c46b4496d}\
strNewVolumeName: Volume{06425352-b0da-4862-b565-f09c46b4496d}

---Found a device:  \Device\HarddiskVolume1 
---Volume name: \\?\Volume{06425352-b0da-4862-b565-f09c46b4496d}\ 
---Volume Path:  
---

---Next----: \\?\Volume{31bf2ce1-8982-4652-96bc-a641d0f78dfd}\
VolumeName=\\?\Volume{31bf2ce1-8982-4652-96bc-a641d0f78dfd}\
strNewVolumeName: Volume{31bf2ce1-8982-4652-96bc-a641d0f78dfd}

---Found a device:  \Device\HarddiskVolume7 
---Volume name: \\?\Volume{31bf2ce1-8982-4652-96bc-a641d0f78dfd}\ 
---Volume Path:  
---
NO MORE FILES! END ! Error code : 18
缺少 \Device\HarddiskVolume2 -》 EPS 分区 缺少 \Device\HarddiskVolume3-》 MSR 分区
路杨 2016-06-08
  • 打赏
  • 举报
回复
我的代码: 来自微软的概念代码改造, 只看 TRACE 宏输出足以。

BOOL CMyDriveListBox::initVolumes()
{
    HANDLE FindHandle           = INVALID_HANDLE_VALUE;
	DWORD  Error                = ERROR_SUCCESS;
	DWORD  CharCount            = 0;
    BOOL   Success              = true;
	ES_VOLUME_INFO VolumeInfo;
	
	
	CString VolumeName =_T("");
    FindHandle = FindFirstVolume((LPTSTR)VolumeName.GetBuffer(MAX_PATH), MAX_PATH);
	if (FindHandle == INVALID_HANDLE_VALUE)
    {
        
        TRACE1("FindFirstVolume failed with error code %d\n", GetLastError());
        return false ;
    }
	
	while ( Success )
	{
		this->ClearVolumeInfo(&VolumeInfo);
		TRACE1("VolumeName=%s\n", VolumeName); /* \\?\Volume{4b82a9cd-f62c-4e78-8117-0682014b76b1}\  */
		VolumeName.Format(_T("%s"), VolumeName);
		int lvo = VolumeName.GetLength();
		// TRACE1("path.Right(1): %s\n", VolumeName.Right(1));
		if (  
			(VolumeName.Mid(0,4)).Compare(_T("\\\\?\\")) !=0 
			|| (VolumeName.Right(1)).Compare(_T("\\")) !=0 
			
			)
		{
			TRACE1("FindFirstVolume/FindNextVolume returned a bad path: %s\n", VolumeName);
			//return false ;
			break;
			
		}
		
		CString DeviceName =_T("");
		CString strNewVolumeName =_T("");
		strNewVolumeName = VolumeName.Mid(4,lvo-5);
		TRACE1("strNewVolumeName: %s\n", strNewVolumeName);
		
		
		CharCount = 
			QueryDosDevice( strNewVolumeName, (LPTSTR) DeviceName.GetBuffer(MAX_PATH), MAX_PATH); 
		if ( CharCount == 0 ) 
		{
			TRACE1("QueryDosDeviceW failed with error code %d\n", GetLastError());
			//return false ;
			break;
			
		}
		TRACE1("\n---Found a device:  %s \n", DeviceName);
		TRACE1("---Volume name: %s \n", VolumeName);

		
		VolumeInfo.VolumeName = VolumeName; //{GUID}
		VolumeInfo.DosDeviceName= DeviceName;		
		
		//
		DWORD dwReturn = 0 ;
		CString strPath= _T("");
		
		BOOL bOK = GetVolumePathNamesForVolumeName(VolumeName, (LPTSTR)strPath.GetBuffer(MAX_PATH), MAX_PATH, &dwReturn);
		if (bOK)
		{
			strPath.Format(_T("%s"), strPath);
			TRACE1("---Volume Path: %s \n", strPath);

			(VolumeInfo.Path).Format(_T("%s"),strPath);			
		}
		
		TRACE0("---\n");

		m_volue_infos.Add(VolumeInfo);		
		
		//
		//  Move on to the next volume.
		Success = FindNextVolume(FindHandle, (LPTSTR)VolumeName.GetBuffer(MAX_PATH), MAX_PATH);
		if ( !Success )
		{
			Error = GetLastError();
			if (Error != ERROR_NO_MORE_FILES) 
			{
				TRACE1("FindNextVolumeW failed with error code %d\n", Error);
				break;
			}
			else
			{
				Error = ERROR_SUCCESS; //是没有下一个了 //ERROR_NO_MORE_FILES
				TRACE1("NO MORE FILES! END ! Error code : %d\n\n", ERROR_NO_MORE_FILES);
				break;
			}
		}
		
		TRACE1("\n---Next----: %s\n", VolumeName);
		
	}

	FindVolumeClose(FindHandle);
	FindHandle = INVALID_HANDLE_VALUE;
	return true;

}
其中结构体定义
typedef struct _STRUCT_VOLUME_INFO
{
	CString VolumeName ;  /* \\?\Volume{77aaa0d9-1b5d-11e6-9bc7-0015830cbfeb}\  */
	CString DosDeviceName ;      // \Device\HarddiskVolume8
	CString Path ;   // c:\	D:\	
	CString lable ;  // 可能存在的卷标。
	CString FileType ;  // NTFS ? FAT32? 。
	
} ES_VOLUME_INFO;

。。。。
	CArray < ES_VOLUME_INFO, ES_VOLUME_INFO>  m_volue_infos ;


路杨 2016-06-08
  • 打赏
  • 举报
回复
引用 3 楼 jennyvenus 的回复:
你说的问题我都没听说过,只能过来围观了。
围观也是参与,感谢围观。
用户 昵称 2016-06-08
  • 打赏
  • 举报
回复
你说的问题我都没听说过,只能过来围观了。
用户 昵称 2016-06-08
  • 打赏
  • 举报
回复
路杨 2016-06-08
  • 打赏
  • 举报
回复
现在汇报新问题: 因为是 GPT 格式硬盘,隐藏的分区比较多。 于是我搞错了一个问题: FindFirstVolume, FindNextVolume 循环 的确找到了没有分配盘符的区,但是哪个是OEM分区,而非 ESP区(启动区)。 也就是说: FindFirstVolume, FindNextVolume枚举根本就没有能够正常获取到 ESP区 。 请教一下:还有其他API可以获取吗? 管理员权限我也试了,应该不是权限问题。。。 关于GetVolumeInformation ,我倒是解决了,发现 GetVolumeInformation 的第一个参数可以是 GUID方式的VolumeName。 大汗!。
leopard硬盘安装助手v0.3 新鲜出炉:leopard硬盘安装史重要更新:leopard硬盘安装助手!!支持iso文件! 1、格式化一盘为fat32,或将盘上所有文件(含隐藏的)删空 2、打开程序,选镜象文件(支持iso文件) 3、目标盘选刚才格的盘,点开始进行镜象 4、重启,你可以从硬盘装leopard了! 重启选'Mac Os X System'启动项回车后你可能要立即按F8来进入leopard启动菜单 xp直接执行就可以建立启动菜单 vista请输入如下命令 注意,要用管理员权限打开命令提示符 BCDEdit /create /d "Mac OSX Leopard" /application bootsector BCDEDIT /set {***X-***X...} device boota BCDEDIT /set {***X-***X...} path \TBOOT BCDEDIT /displayorder {***X-***X...} /addlast BCDEDIT /timeout 5 (大括号内的内容因机器不同而异,所以,执行第一条命令后,记下 GUID,假设为:{***X-***X...}) 感谢远景论坛的wannarlove提供命令 四楼反映不太会用,在这里我简单讲一下用法(因为最近工作较忙,以后如有时间制作一个图文教程,其实很简单,我说一下大家都会弄的) 以我的电脑为例: 1、系统要求: 要求能够启动的xp或者vista。(xp相对简单) 2、磁盘划分: 建议尽量使用逻辑磁盘,以我的电脑为例:以前是35g的C盘标是vista(最好有标,防止抹盘时弄错,损失数据),其余为D盘(硬盘是120g的,所以D盘就是70多g) 因为vista有调整磁盘大小的功能,所以我从D盘压缩了20g。 先创建一个5g的分区(大小就是大概能放下mac安装镜像差不多),设置上盘符,最好不要格式化(格成fat32也行)。 其余的创建一个分区,就是用来安装mac的,盘符也可以不设置,不格式化(格成fat32也行) 现在我的分区是:C盘35g标vista,D盘50多g标movies,E盘光驱,F盘5g未格式化,剩下15g没有盘符。 3、安装: 下面就简单了。启动硬盘安装助理,在最上面的那个框选择硬盘上的镜像文件;目标分区选择F盘;因为我是vista所以“在boot.ini中加入……”这一项我没选(xp用户要选择这一项);其他两个打勾;然后点击开始。等软件操作结束就好了。 4、制作启动项: xp用户在上一步“在boot.ini中加入……”这一项选中就已经制作好启动项了,这一步跳过。 vista用户按照我在二楼开始的地方提供的方法用命令行制作启动项。这一步一定要做。 5、重新启动: 重新启动你就能看到“mac os x leopard”的启动项,高亮选中,按下回车后立即按F8键,好了,这就是熟悉的mac启动选择画面了。 几点注意: 1、如果重启后发现无法启动或者无法进入Windows,只要用有winpm之类的磁盘管理工具的光盘(或者winpe光盘)启动,进入磁盘工具,把你的Windows分区设置成active(活动分区)就行了。 2、如果你安装的是10.4.x的话,不要选efi哪一项。 3、如果在后面的安装中发现无法用mac的磁盘工具抹盘的话,在前面准备分区的时候把准备安装mac的分区id改成af,这种情况通常发生在安装10.4.x中。 4、这种方法其实就是把安装iso克隆在硬盘上,用硬盘安装,所以速度很快。但因此也不适用ghost的安装镜像。

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧