不正确的函数调用"IOCTL_DISK_GET_DRIVE_LAYOUT_EX"
Incorrect Function Call "IOCTL_DISK_GET_DRIVE_LAYOUT_EX"
我目前正在尝试编写一个c++程序来自动检索有关示例硬盘驱动器映像的分区的信息,所讨论的信息是磁盘上的分区数量以及每个分区的起始扇区,大小和文件系统类型。
我很确定在这一点上,实现这一点的最好方法是通过MSDN功能,微软内置的命令。我试图使用"IOCTL_DISK_GET_DRIVE_LAYOUT_EX"函数,但根据我的get错误调用,我的函数是不正确的。当我调试程序时,似乎在"IOCTL_DISK_GET_DRIVE_LAYOUT_EX"调用后bool值也没有变化,这意味着它没有返回bResult值。
我使用的是Microsoft Visual c++ Express Edition。如果人们能看一下我的代码,并告诉我他们认为我做错了什么,我将不胜感激。
#define UNICODE 1
#define _UNICODE 1
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#define wszDrive L"\\.\PhysicalDrive6"
BOOL GetDriveParition(LPWSTR wszPath, DRIVE_LAYOUT_INFORMATION_EX *pdg)
{
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
hDevice = CreateFileW(wszPath, // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
bResult = DeviceIoControl(
hDevice, // handle to device
IOCTL_DISK_GET_DRIVE_LAYOUT_EX, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
pdg, // lpOutBuffer
sizeof(*pdg), // nOutBufferSize
&junk, // lpBytesReturned
NULL); // lpOverlapped
CloseHandle(hDevice);
return (bResult);
}
int wmain(int argc, wchar_t *argv[])
{
DRIVE_LAYOUT_INFORMATION_EX pdg; // disk drive partition structure
BOOL bResult = FALSE; // generic results flag
bResult = GetDriveParition (wszDrive, &pdg);
if (bResult)
{
wprintf(L"Drive path = %wsn", wszDrive);
wprintf(L"Partition Style = %I64dn", pdg.PartitionStyle);
wprintf(L"Partition Count = %ldn", pdg.PartitionCount);
system("Pause");
}
else
{
wprintf (L"GetDrivePartition failed. Error %ld.n", GetLastError ());
system("Pause");
}
return ((int)bResult);
}
DRIVE_LAYOUT_INFORMATION_EX
是一个奇怪的结构。它被定义为
struct {
DWORD PartitionStyle;
DWORD PartitionCount;
union {
DRIVE_LAYOUT_INFORMATION_MBR Mbr;
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
};
PARTITION_INFORMATION_EX PartitionEntry[ 1 ];
}
,但通常PartitionEntry
被视为一个更大的数组,包含PartitionCount
项。这类似于C99 VLA机制。由于只分配了sizeof(*pdg)
个字节,因此甚至没有空间容纳第二个PartitionEntry。
struct ExtraEntries : DRIVE_LAYOUT_INFORMATION_EX
{
PARTITION_INFORMATION_EX PartitionEntry[ 9 ]; // Or some other reasonable value
};
即使这篇文章有点旧,我也找到了另一种方法来获得一个完全填充的PartitionEntry,而无需创建一个棘手的结构。我是这样做的:
灵感来自这篇文章的答案:how -to-call-deviceiocontrol-to-retrieve-the-amount-of-memory-it- needed
DRIVE_LAYOUT_INFORMATION_EX dli;
DWORD bytesReturned = 0;
if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, (void*)&dli, sizeof(dli), &bytesReturned, NULL))
{
// Check last error if not ERROR_INSUFFICIENT_BUFFER then return
int nError = GetLastError();
if (nError != ERROR_INSUFFICIENT_BUFFER)
{
// std::cout << "DeviceIoControl() Failed: " << nError << std::endl;
CloseHandle(hDevice);
return false;
}
// Allocate enough buffer space based of the value of Partition Count:
size_t size = offsetof(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[dli.PartitionCount]);
std::vector<BYTE> buffer(size);
if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, (void*)buffer.data(), size, &bytesReturned, NULL))
{
nError = GetLastError();
// std::cout << "DeviceIoControl() Failed: " << nError << std::endl;
CloseHandle(hDevice);
return false;
}
const DRIVE_LAYOUT_INFORMATION_EX& result = *reinterpret_cast<const DRIVE_LAYOUT_INFORMATION_EX*>(buffer.data());
// Here all parition entry are populated ...
// TO DO... Do your stuff with result
}
else
{
// Call succeeded; dli is populated with a signle partition entry
// TO DO... Do your stuff with dli
}
相关文章:
- Arduino IDE告诉我找不到字符串文字运算符“运算符”“DRIVE”
- Poco HTTPSClientSession with google drive api
- 将文件从Raspberry Pi上传到Google Drive
- QWidget::layout() 无法返回 QGridLayout?
- qobject_cast<QVBoxLayout*>(layout()),是合适的演员表吗?
- 编译Qt项目时出错"layout was not declared"
- 适用于 C 或 C++ 的 Google Drive API
- Google Drive将我的应用程序显示为病毒
- QT 无法使用自动调整大小 QLineEdit & Layout
- c++/qt中google-drive的api和工具
- 为什么 C++11 的 POD "standard layout"定义是这样的?
- C++/CLI XMLSerialization Layout
- 如何在 Gtk::Layout::p ut 上使signal_add火
- 控制Dropbox, Google Drive和/或SugarSync与我的应用程序