我正在使用:
DWORD d = GetLogicalDrives();
for (int i = 0; i < 26; i++)
{
if ((1 << i) & d) // drive letter 'A' + i present on computer
{
wstring s = std::wstring(L"\\\\.\\") + wchar_t('A' + i) + L":";
PARTITION_INFORMATION diskInfo;
DWORD dwResult;
HANDLE dev = CreateFile(LPWSTR(s.c_str()), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &diskInfo, sizeof(diskInfo), &dwResult, NULL);
CloseHandle(dev);
if (diskInfo.PartitionType == PARTITION_IFS)
{
...
}
}
}
枚举计算机的所有NTFS分区。
它可以在Windows 7,我尝试过的Windows 8.1和Windows 10计算机上使用。
但是在另一台Windows 10计算机上失败:在这台计算机上,卷C:
的{{1}}值等于diskInfo.PartitionType
,而不是0x00
({{1 }}。
此值为(请参见doc here):
PARTITION_ENTRY_UNUSED:0x00:未使用的条目分区。
这很奇怪,因为我可以确认分区实际上是NTFS。
问题:
是否众所周知0x07
并非100%可靠地获得分区类型?
枚举所有NTFS卷的更可靠的方法是什么?
注意:我还研究了使用IOCTL_DISK_GET_PARTITION_INFO_EX
而不是PARTITION_IFS
,但是结构PARTITION_INFORMATION_EX
似乎没有提供有关IOCTL_DISK_GET_PARTITION_INFO
的信息,而结构{{3 }}确实可以访问PARTITION_INFORMATION
。
答案 0 :(得分:1)
正如@RemyLebeau所说,您没有检查每个调用的返回值。
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery.bootstrapvalidator/0.5.0/css/bootstrapValidator.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-validator/0.4.5/js/bootstrapvalidator.min.js"></script>
<form class="well form-horizontal" action=" " method="post" id="contact_form">
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">First Name</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input name="first_name" placeholder="First Name" class="form-control" type="text">
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Last Name</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input name="last_name" placeholder="Last Name" class="form-control" type="text">
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">E-Mail</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-envelope"></i></span>
<input name="email" placeholder="E-Mail Address" class="form-control" type="text">
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Phone #</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-earphone"></i></span>
<input name="phone" placeholder="(845)555-1212" class="form-control" type="text">
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Address</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-home"></i></span>
<input name="address" placeholder="Address" class="form-control" type="text">
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">City</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-home"></i></span>
<input name="city" placeholder="city" class="form-control" type="text">
</div>
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-md-4 control-label">State</label>
<div class="col-md-4 selectContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-list"></i></span>
<select name="state" class="form-control selectpicker">
<option value=" ">Please select your state</option>
<option>Alabama</option>
<option>Alaska</option>
</select>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Zip Code</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-home"></i></span>
<input name="zip" placeholder="Zip Code" class="form-control" type="text">
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Website or domain name</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-globe"></i></span>
<input name="website" placeholder="Website or domain name" class="form-control" type="text">
</div>
</div>
</div>
<!-- radio checks -->
<div class="form-group">
<label class="col-md-4 control-label">Do you have hosting?</label>
<div class="col-md-4">
<div class="radio">
<label>
<input type="radio" name="hosting" value="yes" /> Yes
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="hosting" value="no" /> No
</label>
</div>
</div>
</div>
<!-- Text area -->
<div class="form-group">
<label class="col-md-4 control-label">Project Description</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-pencil"></i></span>
<textarea class="form-control" name="comment" placeholder="Project Description"></textarea>
</div>
</div>
</div>
<!-- Success message -->
<div class="alert alert-success" role="alert" id="success_message">Success <i class="glyphicon glyphicon-thumbs-up"></i> Thanks for contacting us, we will get back to you shortly.</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-4 control-label"></label>
<div class="col-md-4">
<button type="submit" class="btn btn-warning">Send <span class="glyphicon glyphicon-send"></span></button>
</div>
</div>
</fieldset>
</form>
通常意味着PARTITION_ENTRY_UNUSED
调用失败。这取决于用户的权限。您应该检查用户的访问权限,以查看它是否具有卷DeviceIoControl()
上的FILE_READ_DATA
权限(包含在GENERIC_READ
中)。在我的测试环境中,如果您无法使用C:
访问打开卷C:
,则GENERIC_READ
返回CreateFile()
,然后INVALID_HANDLE_VALUE
也将失败。
编辑:
我建议使用DeviceIoControl()
,例如:
GetVolumeInformation()
您将在wchar_t fs[MAX_PATH + 1] = { 0 };
GetVolumeInformationW(L"C:\\", NULL, 0, NULL, NULL, NULL, fs, MAX_PATH + 1);
缓冲区中看到类型信息。
答案 1 :(得分:1)
由于@RemyLebeau的评论,我进行了进一步调查:
HANDLE dev = CreateFile(..., GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (dev == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError(); // then MessageBox
}
else
{
BOOL ret = DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &diskInfo, sizeof(diskInfo), &dwResult, NULL);
if (ret == FALSE)
{
DWORD err = GetLastError(); // then MessageBox
}
CloseHandle(dev);
}
出现故障的计算机上的(装有Windows 10的计算机)。我发现CreateFile
成功了,但随后DeviceIoControl
失败了,而GetLastError
是1
,即ERROR_INVALID_FUNCTION
(请参阅System Error Codes (0-499))。
结论(我引用雷米的评论):
这意味着您传递给DeviceIoControl()的设备不支持IOCTL_DISK_GET_PARTITION_INFO。
然后我尝试使用IOCTL_DISK_GET_PARTITION_INFO_EX
:
PARTITION_INFORMATION_EX diskInfo;
BOOL ret = DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &diskInfo, sizeof(diskInfo), &lpBytesReturned, NULL);
,然后它起作用了。我可以看到diskInfo.PartitionStyle
是PARTITION_STYLE_GPT
(= 1),这就是IOCTL_DISK_GET_PARTITION_INFO
失败的原因。我再次引用雷米的评论:
GPT分区驱动器上不支持IOCTL_DISK_GET_PARTITION_INFO。
所以这是结论:
使用IOCTL_DISK_GET_PARTITION_INFO_EX
代替IOCTL_DISK_GET_PARTITION_INFO
如果diskInfo.PartitionStyle
为0(PARTITION_STYLE_MBR),则可以测试diskInfo.Mbr.PartitionType。 If it's 0x07, it's NTFS。
如果diskInfo.PartitionStyle
为1(PARTITION_STYLE_GPT),则可以测试diskInfo.Gpt.PartitionType,请参见此处:https://docs.microsoft.com/en-us/windows/desktop/api/winioctl/ns-winioctl-_partition_information_gpt。即使在GPT情况下NTFS Wikipedia page提到了NTFS的GUID EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
,该GUID实际上也与文件系统无关(请参见下面的评论)。
使用GetVolumeInformation()
可能更容易,并且只比较结果是否为"NTFS"
字符串,如other answer
在我的特定情况下,我最初想在尝试使用DeviceIoControl(hVol, FSCTL_ENUM_USN_DATA, ...)
进行索引之前 测试卷是否为NTFS,因为我认为这样的MFT查询仅限于NTFS卷。实际上,更简单的解决方案是不要测试是否为NTFS ,而只需执行FSCTL_ENUM_USN_DATA
。根据文档,可能发生的最坏情况是FSCTL_ENUM_USN_DATA
失败,并出现ERROR_INVALID_FUNCTION
错误:
“ ERROR_INVALID_FUNCTION指定卷上的文件系统不支持此控制代码。”