不正确的函数调用“IOCTL_DISK_GET_DRIVE_LAYOUT_EX”
我目前正在写一个C++程序来自动获取关于样本的分区信息的硬盘驱动器的形象,问题是在磁盘上,并为每个分区的分区数量的信息其起始扇区,大小和文件系统类型。不正确的函数调用“IOCTL_DISK_GET_DRIVE_LAYOUT_EX”
我敢肯定,在这一点上,以实现这一目标是通过MSDN的功能,微软内置命令的最佳方式。我试图使用“IOCTL_DISK_GET_DRIVE_LAYOUT_EX”函数,但根据我的错误调用我的函数是不正确的。当我调试程序看来,布尔值也是“IOCTL_DISK_GET_DRIVE_LAYOUT_EX”呼叫后保持不变,这意味着它不会返回bResult值。
我使用Microsoft Visual C++速成版。如果人们可以看看我的代码,并告诉我他们认为我做错了什么,这将非常感激。
#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 = %ws\n", wszDrive);
wprintf(L"Partition Style = %I64d\n", pdg.PartitionStyle);
wprintf(L"Partition Count = %ld\n", 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也没有空间。
C++黑客:
struct ExtraEntries : DRIVE_LAYOUT_INFORMATION_EX
{
PARTITION_INFORMATION_EX PartitionEntry[ 9 ]; // Or some other reasonable value
};
感谢您的答复MSalters。您能否解释如何实施您提供的解决方案?对这种烦恼抱歉,但我对C++来说比较新。 – 2013-03-15 15:42:49
@DavidRyan:在Windows结构不干净C++,但你必须要考虑,Windows是在理论上与语言无关。它的API并不总是很好地映射到C++。在这种情况下,您需要一个具有多于1个'PartitionEntry'成员的对象。我使用C++派生来添加额外的成员,并依靠编译器来获得正确的布局。现在在程序中用'ExtraEntries'替换'DRIVE_LAYOUT_INFOMARTION_EX'。因为它是一个派生类型,当你传递一个'ExtraEntries *'到Windows API,编译器会自动插入铸 - 底部给你所需要的'DRIVE_LAYOUT_INFORMATION_EX *'。 – MSalters 2013-03-18 10:53:55
请致电'GetLastError'的功能之后,看看是什么问题? – 2013-03-15 13:48:04
错误122意味着“传递给系统调用的数据错误太小”......您是否需要首先初始化结构? – 2013-03-15 13:53:40
感谢您的评论,只要我能够,我会尝试一下。将报告结果。 – 2013-03-15 14:36:06