2

私は現在、サンプル ハード ドライブ イメージのパーティションに関する情報の取得を自動化する C++ プログラムを作成しようとしています。問題の情報は、ディスク上のパーティションの数と、各パーティションの開始セクター、サイズ、およびファイル システムの種類です。 .

この時点で、これを達成するための最良の方法は、MSDN 関数、Microsoft の組み込みコマンドを使用することだと確信しています。「IOCTL_DISK_GET_DRIVE_LAYOUT_EX」関数を使用しようとしていますが、取得エラー呼び出しによると、関数が正しくありません。プログラムをデバッグすると、"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            = %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);
}
4

2 に答える 2

4

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これは、C99VLAメカニズムに似ています。バイトだけを割り当てたのでsizeof(*pdg)、2番目のPartitionEntryさえも入れる余地はありません。

C ++ハック:

struct ExtraEntries : DRIVE_LAYOUT_INFORMATION_EX
{
   PARTITION_INFORMATION_EX PartitionEntry[ 9 ]; // Or some other reasonable value
};
于 2013-03-15T14:37:54.837 に答える