不正确的函数调用“;IOCTL“磁盘获取驱动器布局”; 我目前正试图编写一个C++程序来自动检索关于硬盘驱动器图像分区的信息,所讨论的信息是磁盘上的分区数,每个分区的起始扇区、大小和文件系统类型。p>

不正确的函数调用“;IOCTL“磁盘获取驱动器布局”; 我目前正试图编写一个C++程序来自动检索关于硬盘驱动器图像分区的信息,所讨论的信息是磁盘上的分区数,每个分区的起始扇区、大小和文件系统类型。p>,c++,msdn,hard-drive,disk-partitioning,C++,Msdn,Hard Drive,Disk Partitioning,我很确定,在这一点上,实现这一点的最好方法是通过MSDN函数,微软的内置命令。我试图使用“IOCTL\u DISK\u GET\u DRIVE\u LAYOUT\u EX”函数,但根据我的GET error调用,我的函数不正确。当我调试程序时,在“IOCTL\u DISK\u GET\u DRIVE\u LAYOUT\u EX”调用之后,bool值似乎也没有改变,这意味着它没有返回bResult值 我使用微软Visual C++快件版。如果人们能看看我的代码,告诉我他们认为我做错了什么,那将不胜

我很确定,在这一点上,实现这一点的最好方法是通过MSDN函数,微软的内置命令。我试图使用“IOCTL\u DISK\u GET\u DRIVE\u LAYOUT\u EX”函数,但根据我的GET error调用,我的函数不正确。当我调试程序时,在“IOCTL\u DISK\u GET\u DRIVE\u LAYOUT\u EX”调用之后,bool值似乎也没有改变,这意味着它没有返回bResult值

我使用微软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);
}
#定义UNICODE 1
#定义_unicode1
#包括
#包括
#包括
#定义wszDrive L“\\.\\PhysicalDrive6”
布尔GetDriveParation(LPWSTR wszPath、驱动器布局信息*pdg)
{
HANDLE hDevice=INVALID\u HANDLE\u VALUE;//要检查的驱动器的句柄
BOOL-bResult=FALSE;//结果标志
DWORD BUNK=0;//放弃结果
hDevice=CreateFileW(wszPath,//要打开的驱动器
0,//无法访问该驱动器
文件_共享|读取|//共享模式
文件共享写入,
NULL,//默认安全属性
打开\u现有,//处置
0,//文件属性
NULL);//不复制文件属性
如果(hDevice==无效的\u句柄\u值)//无法打开驱动器
{
返回(假);
}
bResult=设备控制(
hDevice,//句柄到设备
IOCTL\u DISK\u GET\u DRIVE\u LAYOUT\u EX,//dwIoControlCode
NULL,//lpInBuffer
0,//nInBufferSize
pdg,//lpburffer
sizeof(*pdg),//nOutBufferSize
&垃圾,//lpbytes返回
NULL);//lpOverlapped
闭合手柄(hDevice);
返回(bResult);
}
int wmain(int argc,wchar_t*argv[])
{
驱动器\u布局\u信息\u EX pdg;//磁盘驱动器分区结构
BOOL-bResult=FALSE;//通用结果标志
bResult=getdriveparion(wszDrive和pdg);
if(bResult)
{
wprintf(L“驱动器路径=%ws\n”,wszDrive);
wprintf(L“分区样式=%I64d\n”,pdg.PartitionStyle);
wprintf(L“分区计数=%ld\n”,pdg.PartitionCount);
系统(“暂停”);
} 
其他的
{
wprintf(L“GetDrivePartition失败。错误%ld。\n”,GetLastError());
系统(“暂停”);
}
返回((int)bResult);
}

驱动器布局信息是一种奇怪的结构。它的定义是

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)
bytes,所以甚至没有空间容纳第二个PartitionEntry

C++黑客:

struct ExtraEntries : DRIVE_LAYOUT_INFORMATION_EX
{
   PARTITION_INFORMATION_EX PartitionEntry[ 9 ]; // Or some other reasonable value
};

DRIVE\u LAYOUT\u INFORMATION\u 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)
bytes,所以甚至没有空间容纳第二个PartitionEntry

C++黑客:

struct ExtraEntries : DRIVE_LAYOUT_INFORMATION_EX
{
   PARTITION_INFORMATION_EX PartitionEntry[ 9 ]; // Or some other reasonable value
};

请在函数之后调用
GetLastError
,看看问题出在哪里?错误122表示“传递到系统调用的数据错误太小”。。。你需要先初始化结构吗?谢谢你的评论,我会尽快试用的。将报告结果。请在函数后调用
GetLastError
,看看问题出在哪里?错误122表示“传递到系统调用的数据错误太小”。。。你需要先初始化结构吗?谢谢你的评论,我会尽快试用的。将报告结果。谢谢回复。您能解释一下如何实施您提供的解决方案吗?抱歉,但我对C++是比较新的。@ DaviRay:Windows结构不是干净的C++,但是你必须考虑到Windows在理论上是语言中立的。它的API并不总是很好地映射到C++。在这种情况下,您需要一个具有多个
PartitionEntry
成员的对象。我使用C++派生来添加额外的成员,并依赖编译器来获得THA布局。现在将程序中的
DRIVE\u LAYOUT\u INFOMARTION\u EX
替换为
extracentries
。由于它是派生类型,当您将
extracentries*
传递给Windows API时,编译器将自动将强制转换插入base以提供所需的
DRIVE\u LAYOUT\u INFORMATION\u EX*
。感谢回复MSalters。您能解释一下如何实施您提供的解决方案吗?抱歉,但我对C++是比较新的。@ DaviRay:Windows结构不是干净的C++,但是你必须考虑到Windows在理论上是语言中立的。它的API并不总是很好地映射到C++。在这种情况下,您需要一个具有多个
PartitionEntry
成员的对象。我使用C++派生来添加额外的成员,并依赖编译器来获得THA布局。现在将程序中的
DRIVE\u LAYOUT\u INFOMARTION\u EX
替换为
extracentries
。由于它是派生类型,因此当您将
extracentries*
传递给Windows API时,编译器将自动将转换插入到base to