• ベストアンサー

物理ドライブの全容量を取得する方法

現在、HDDを物理的に読み書きするソフトウェアを製作しております。 その際HDDをドライブレターではなく物理ドライブ番号で判断する必要があり、 全容量を取得する方法がわからず困っています。 環境はWindows2000Pro(VisualC++ V6/API)です。 ドライブレターが使用できる場合GetDiskFreeSpace(Ex)にて取得できるようですが、 試しに第一引数に「\\.\PhysicalDrive0」と渡し失敗することを確認しました。 指定方法や順序の問題かも知れませんが、 この状態でフォーマットされていないHDDの全容量を知る方法があれば、是非、ご教示ください。

質問者が選んだベストアンサー

  • ベストアンサー
  • noocyte
  • ベストアンサー率58% (171/291)
回答No.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 */

N_flick
質問者

お礼

ご連絡が遅くなってしまい申し訳ありませんでした。 お忙しい中、そのもののご回答をいただき心より感謝いたします。 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 を使用させていただきました。 詰まっておりましたので大変助かりました。ご回答、感謝いたします。

その他の回答 (2)

  • davidfox
  • ベストアンサー率58% (21/36)
回答No.2

DeviceIoControl で DISK_GEOMETRY構造体を取得して計算すれば良いのでは。 ただ、昔の話なので、現在どんなHDDでも通用するかは判りませんが。

N_flick
質問者

お礼

連絡が遅くなってしまい申し訳ありません。 DeviceIoControl 関数を使用することで取得できるとのことで、 試しに上記の様にテストしてみたところ、問題なく取得できました。 (2G以下のHDDを対象として、キャストが強引ではありますが…) 今回はPC-98時代の"昔の"HDDを読み書きする必要があり、 ご回答はズバリのものです。ご回答、感謝いたします。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

使ったことはありませんが、参考URLの ライブラリはどうでしょうか。

参考URL:
http://www.vector.co.jp/soft/dl/win95/prog/se116476.html
N_flick
質問者

お礼

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

関連するQ&A

  • (Win32)ファイルパスから物理ドライブ番号を取得するには

     任意のファイルが保存されているディスクの固有情報を取得するプログラムを作成しています。固有情報は論理ディスクでは取得できないため、「C:\sample.txt」の「C:」といった論理ドライブ名から「PHYSICALDRIVE0」のような物理ドライブ名を取得する方法を探しています。 なお開発環境はVisual C++ 2008/Win32 SDKの組み合わせとなります。

  • HDDの空き容量を取得するAPIはありませんか?

    お世話になります。 LinuxでHDD(ストレージ)の空き容量を取得するAPIを探しております。 ご存じの方、いらっしゃいましたらどうか教えて下さい。 dfコマンドの結果をリダイレクトして読み出す方法は不可です。 OSはRedHat系です。 以上、よろしくお願い致します。

  • DirectX&Win32API&C++ ドライブ情報の取得方法について

    Windowsプログラム(Win32API)と、DirectX9(2007January)と、C++を使用してゲームを制作しています。 ですがDirectXは環境によっては動作しないものも多く、 どんな環境では動かないかというのもを手軽に調べるために ゲーム起動前にドライブ情報を表示するようにしたいのです。 (例えば、グラフィックボードだとか、VRAMや、HDD容量や  メインメモリの容量など、DirectX診断ツールのようなもの) それを調べる関数が有りそうな気もしたのですが、 C#やJavaだといくつかありましたが意外と見つからず、 (調べ方が悪いだけかもしれませんが)難儀しています。 もしドライブ情報の取得方法をご存知の方がいらっしゃいましたら どうかアドバイスをお願い致します。

  • Cドライブ(システムドライブ)の最適な容量

    自作PCを作成しようと考えております。OSは「Windows Vista Home Premium 」(推奨「40GBのHDD容量と15GBの空き容量が必要」)。 Cドライブをシステムドライブとした場合、最適な環境の選択は(1)(2)(3)のどれになりますでしょうか? (1)Cドライブ/80G物理ドライブ+Dドライブ/500G物理ドライブ (2)Cドライブ/80G理論ドライブ+Dドライブ/420G理論ドライブ (3)Cドライブ/5000G物理ドライブ 「Windows XP Professional」を使用していたとき、他のユーザー間での権限を制限できたのはシステムドライブ内のみでしたので、プライバシー保護を目的とするのでしたら(3)が妥当かと考えております。ただ、市販品のパソコンのCドライブは必ずと言って良いほど容量が控えめになっているので気になるところです。 ご教示よろしくお願い致します。

  • ドライブの容量変更

    ノートパソコンのHDDをSSDに交換しました。 容量が少ないためEドライブの容量が少なくなりました、パテ-ションを変更してCかDドライブの容量を減らしてEを増やしたいのですが、どのような方法がいいでしょうか。 Windows7 64ビットです。 空いたHDDを外付けドライブとして利用します。全部フォーマットして良いでしょうか。

  • 存在しないドライブの削除方法

    先日、誤ってwin7をwin10にアップグレードしてしまいました。 アップグレード後、PCの運用そのものに支障をきたすエラーを抱えてしまったため、win10のリカバリ画面の「ビルドを戻す」からwin7へ復元しました。 復元後、コンピューター(記憶域の一覧)画面にCDドライブ(E:)という以前は存在しなかったドライブが現れています。E:は復元前のwin7でHDDに割り当てていたドライブレターです。以前E:だったボリュームは現在F:になっています。 現在、CDドライブ(E:)はコンピューター画面にしか表示されず、ディスクの管理画面やコマンドプロント上からも認識されていません。また、デバイスマネージャー上にも物理的に存在するデバイスのみが認識されています。しかし、ドライブレターの割当画面ではE:は選択できません。(使用中の文字同様、表示されない) 他のアプリケーションからHDDへアクセスする際にファイルパスが変わっている状態が非常に不便なので、どうしてもE:をHDDへ割り当て直したいのですが、この幽霊ドライブの削除方法及びE:をHDDへ再度割り当てる方法をご教授いただけないでしょうか。 参考情報: C:システム領域、プライマリパーティション D:論理ドライブ F:プライマリパーティション 上記以外には物理・仮想問わず記憶域を持つデバイスは接続されていません。 CDドライブ(E:)のプロパティは、 種類:CDドライブ ファイルシステム:不明 使用容量及び空き容量:0バイト となっています。

  • ExcelかAccessのVBAでドライブの容量取得

    社内のいくつかのサーバーの各ドライブごとの容量を調べたいのですが・・・。 (1)ドライブの数がトータルで40個くらいあります (2)週に一度くらい確認しています (3)各サーバーはネットワークでつながっています 上記のような状況のため、VBAなどで自動取得できないかと悩んでいます。 (現在はサーバのマイコンピュータを見て、リストに記入・・・とやっています) VBAでネットワークドライブの割り当てを行い、容量を取得、その後割り当てを解除・・・という形で行おうと思ったのですが、 VBAで割り当てを行う方法がわかりません。 (FileSystemObjectでDriveのサイズは取得できます) また、割り当てを行わずに容量を取得する方法があるのでしたらそれでもいいと思うのですが、調べても分かりませんでした。 できればファイルに結果を残したいので、エクセルかアクセスのVBAでできたらなぁと思っています。 (またスキルの面からも、VBAくらいしか使えません) 何か良いやり方があれば、教えていただけないでしょうか? よろしくお願い致します。 *環境:windows2000・office2000

  • 物理メモリの空き容量

    WinME,IE5.5SP2を使っています。 CPU700MHZ,HDD20G,メモリ256Mです。 システム情報で見ると、起動直後の物理メモリの空き容量が86Mくらいしかありません。特に常駐させているプログラムはアンチウィルスソフトとファイヤーウォールソフトくらいしかないんですけど、この量って少ないですか? 空き容量を増やす方法がありましたら教えてください。

  • Cドライブの空き容量が少ないです

    ご覧いただきありがとうございます。 vistaのBIBLO MG75Yを使用しています。 最近、Cドライブの空き容量がとても少なく、5GBを切って赤い印がついてしまいました。(全容量は約50GBと表示されています) 容量の大きいファイルやプログラム等は入れておらず、DVDへの書き込みをする際にはDドライブにデータが入るように設定しています。(書きこんだデータはその都度消去しています) ほとんど使用していないDドライブは約60GB残量があります。 ちなみに、説明書の仕様を見るとHDDドライブは160GBとありますので、Cドライブの全容量は約100GBと思われます。 ディスクのデフラグや、HDDのクリーンアップを実行してみましたが、いっこうに容量は増えず、むしろ減っていくばかりです… このままだと、動作が遅くなったり、DVDへの書き込みができなくなったりしないかとても心配です。 空き容量を増やす方法はあるのでしょうか? 回答よろしくお願いします。

  • Cドライブの空き容量について

    自作パソコンです。 HDDは、500GBあるんですが、最初パーティションを2つにした時に、Cドライブを20GBにしてしまいました。 追加でインストールしたソフトやデータは、全部もう一方のドライブに入れるようにしているのですが、使い始めて半年ほどの現在、空き容量は2GBほどになっています。 そこで質問です。 (1)空き容量はこのままで大丈夫でしょうか? (パフォーマンスに影響があるかという意味で) (2)ドライブのクリーンアップ、レジストリクリーンの他に空き容量を増やす方法はありますか? (3)Cドライブの容量自体を増やす方法はありますか? OS:Vista Home Premium SP2 32ビット CPU:Core2Duo E8400 3.00GHz HDD:500GB メインメモリ:2GB よろしくお願いします。

専門家に質問してみよう