プロが教えるわが家の防犯対策術!

現在、HDDを物理的に読み書きするソフトウェアを製作しております。
その際HDDをドライブレターではなく物理ドライブ番号で判断する必要があり、
全容量を取得する方法がわからず困っています。

環境はWindows2000Pro(VisualC++ V6/API)です。
ドライブレターが使用できる場合GetDiskFreeSpace(Ex)にて取得できるようですが、
試しに第一引数に「\\.\PhysicalDrive0」と渡し失敗することを確認しました。

指定方法や順序の問題かも知れませんが、
この状態でフォーマットされていないHDDの全容量を知る方法があれば、是非、ご教示ください。

A 回答 (3件)

パーティション (ドライブレター) ごとではなく,


物理ドライブごとでいいんでしょうか?
ちょっと調べて作ってみましたのでご参考まで.
(CreateFile の引数がこれでいいのか,十分マニュアルを
熟読していませんが,とりあえずそれらしい結果は出ました.)

//--------------------------------------------------------------------------
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <windows.h>

/*--------------------------------------------------------------------------
機能 :物理ドライブごとのディスク容量を出力する.
--------------------------------------------------------------------------*/
void PrintPhysicalDriveCapacities(void)
{
 HANDLE hDrive;
 GET_LENGTH_INFORMATION length;
 unsigned driveNo;
 DWORD nBytes;
 char fileName[29];

 for(driveNo = 0; ; driveNo++) {
  // 物理ドライブ driveNo をオープンする.
  sprintf(fileName, "\\\\.\\PHYSICALDRIVE%u", driveNo);
  hDrive = CreateFile(fileName, GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_WRITE, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if(hDrive == INVALID_HANDLE_VALUE) break;

  // 物理ドライブの全容量を取得する.
  if(DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0,
            &length, (DWORD)sizeof(length), &nBytes, NULL)) {
   printf("Physical Drive #%u: %I64u bytes\n", driveNo, length.Length);
  }
  CloseHandle(hDrive);
 }
}

//--------------------------------------------------------------------------
int main(void)
{
 PrintPhysicalDriveCapacities();
 return EXIT_SUCCESS;
}

// 実行結果 ----------------------------------------------------------------

Physical Drive #0: 120034123776 bytes  /* 120GB HDD */
Physical Drive #1: 2086535168 bytes   /* 2GB USB Memory */
    • good
    • 0
この回答へのお礼

ご連絡が遅くなってしまい申し訳ありませんでした。
お忙しい中、そのもののご回答をいただき心より感謝いたします。
noocyte氏のコードを参考に、No.2 davidfox氏の示された方法で取得してみました。
同じく取り敢えずの結果ではありますが、テスト中のコードを記載いたします。
 
 ---------------------
  #include <windows.h>
  #include <stdio.h>
  #include <winioctl.h>
 ---------------------
 
 ---------------------
  引数 DWORD numdrv( = 0);
 ---------------------
 
 char devicename[64];
 sprintf(devicename, "\\\\.\\PhysicalDrive%u", numdrv);
 
 HANDLE hDevice;
 
 // デバイスを開く
 hDevice = CreateFile(devicename, GENERIC_WRITE,
          FILE_SHARE_READ|FILE_SHARE_WRITE,
          NULL, OPEN_EXISTING, 0, NULL);
 
 // デバイスが開けない
 if(!hDevice){
  fprintf(stdout, "failed to open device %d.\n", numdrv);
  return 0;
 }
 
 DISK_GEOMETRY geo;
 BOOL res;
 DWORD res_bytes;
 
 // ジオメトリ取得
 res = DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY,
          NULL, 0, &geo, sizeof(geo), &res_bytes, NULL);
 
 // 取得に失敗
 if(!res){
  fprintf(stdout, "failed to get device status.\n");
  return 0;
 }
 
 // 全容量割り出し
 fprintf(stdout, "SecSize : %u\nSecNum : %u\nCls : %I64u \nTrk : %u\n",
          geo.BytesPerSector, geo.SectorsPerTrack,
          geo.Cylinders, geo.TracksPerCylinder);
 
 ULONGLONG totalsize;
 totalsize = geo.SectorsPerTrack * geo.BytesPerSector * geo.TracksPerCylinder;
 totalsize = (totalsize * geo.Cylinders.QuadPart) / 1048576;
 fprintf(stdout, "Total : %I64u MB\n", totalsize);
 CloseHandle(hDevice);

今回はWinNT上で動作し、またセクタサイズ等も可能であれば必要なため
GET_DRIVE_GEOMETRY を使用させていただきました。
詰まっておりましたので大変助かりました。ご回答、感謝いたします。

お礼日時:2007/03/01 00:07

DeviceIoControl で DISK_GEOMETRY構造体を取得して計算すれば良いのでは。


ただ、昔の話なので、現在どんなHDDでも通用するかは判りませんが。
    • good
    • 0
この回答へのお礼

連絡が遅くなってしまい申し訳ありません。

DeviceIoControl 関数を使用することで取得できるとのことで、
試しに上記の様にテストしてみたところ、問題なく取得できました。
(2G以下のHDDを対象として、キャストが強引ではありますが…)

今回はPC-98時代の"昔の"HDDを読み書きする必要があり、
ご回答はズバリのものです。ご回答、感謝いたします。

お礼日時:2007/02/28 23:37

使ったことはありませんが、参考URLの


ライブラリはどうでしょうか。

参考URL:http://www.vector.co.jp/soft/dl/win95/prog/se116 …
    • good
    • 0
この回答へのお礼

ご連絡が遅くなってしまい申し訳ありません。
ライブラリ、拝見いたしました。
ライブラリとのことで今回は使用できませんが、
次回、その他リソースを取得する際参考にさせていただきます。
ご回答、有り難うございました。

お礼日時:2007/02/28 23:34

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!