85

Windows で物理ディスクを一覧表示する方法 利用可能なリストを取得するため"\\\\.\PhysicalDrive0"

4

15 に答える 15

79

#WMIC wmicは非常に完成度の高いツールです

wmic diskdrive list

たとえば、(多すぎる)詳細なリストを提供する

より少ない情報のために

wmic diskdrive list brief 

#C Sebastian Godeletがコメントで言及しています:

C:

system("wmic diskdrive list");

コメントされているように、WinAPI を呼び出すこともできますが、「C アプリケーションを使用して WMI からデータを取得する方法」に示されているように、これは非常に複雑です (通常は C ではなく C++ で行われます)。


#PowerShell または PowerShell を使用:

Get-WmiObject Win32_DiskDrive

更新 2022 年 2 月、マイクロソフトは「Windows 10 の機能の開発を中止しました」で発表しました。

WMIC ツールは、Windows 10 バージョン 21H1 および Windows Server の 21H1 一般提供チャネル リリースでは非推奨です。

このツールは、WMI 用の Windows PowerShell に取って代わられました。

注: この非推奨は、コマンドライン管理ツールにのみ適用されます。WMI 自体は影響を受けません。

于 2008-11-29T17:24:03.130 に答える
52

それを行う1つの方法:

  1. を使用して論理ドライブを列挙するGetLogicalDrives

  2. 論理ドライブごとに、"\\.\X:"(引用符を除く) という名前のファイルを開きます。ここで、X は論理ドライブ文字です。

  3. DeviceIoControl前の手順で開いたファイルへのハンドルを渡し、dwIoControlCodeパラメータを次のように設定して呼び出しIOCTL_VOLUME_GET_VOLUME_DISK_EXTENTSます。

    HANDLE hHandle;
    VOLUME_DISK_EXTENTS diskExtents;
    DWORD dwSize;
    [...]
    
    iRes = DeviceIoControl(
        hHandle,
        IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
        NULL,
        0,
        (LPVOID) &diskExtents,
        (DWORD) sizeof(diskExtents),
        (LPDWORD) &dwSize,
        NULL);
    

VOLUME_DISK_EXTENTSこれは、論理ボリュームの物理的な場所の情報を構造体として返します。

ボリュームが単一の物理ドライブ上に存在する単純なケースでは、物理ドライブ番号はdiskExtents.Extents[0].DiskNumber

于 2012-07-27T08:09:49.473 に答える
25

答えは、上記のすべての答えよりもはるかに簡単です。物理ドライブのリストは、実際にはレジストリ キーに保存され、デバイス マッピングも提供します。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\Enum

Countは PhysicalDrive# の数であり、番号が付けられた各レジストリ値は対応する物理ドライブです。

たとえば、レジ​​ストリ値「0」は PhysicalDrive0 です。値は、PhysicalDrive0 がマップされている実際のデバイスです。ここに含まれる値をパラメーター pDeviceID 内CM_Locate_DevNodeに渡して、プラグ アンド プレイ サービスを使用できます。これにより、デバイスに関する豊富な情報を収集できます。ドライブの名前、シリアル番号などが必要な場合は、「フレンドリ表示名」などのデバイス マネージャーのプロパティなど。

システム上で実行されていない可能性のある WMI サービスやその他のハッカーは必要ありません。この機能は少なくとも 2000 年から Windows に存在しており、Windows 10 でも引き続き使用されています。

于 2016-05-20T12:34:54.863 に答える
13

このディスク情報を引き出すために、「dskwipe」というオープンソース プログラムを修正しました。Dskwipe は C で記述されており、この関数を C から引き出すことができます。バイナリとソースはこちらから入手できます: dskwipe 0.3 がリリースされました

返される情報は次のようになります。

Device Name                         Size Type      Partition Type
------------------------------ --------- --------- --------------------
\\.\PhysicalDrive0               40.0 GB Fixed
\\.\PhysicalDrive1               80.0 GB Fixed
\Device\Harddisk0\Partition0     40.0 GB Fixed
\Device\Harddisk0\Partition1     40.0 GB Fixed     NTFS
\Device\Harddisk1\Partition0     80.0 GB Fixed
\Device\Harddisk1\Partition1     80.0 GB Fixed     NTFS
\\.\C:                           80.0 GB Fixed     NTFS
\\.\D:                            2.1 GB Fixed     FAT32
\\.\E:                           40.0 GB Fixed     NTFS
于 2008-12-08T17:55:21.687 に答える
12

唯一の正しい答えは @Grodriguez によるもので、これは彼が書くのが面倒だったコードです。

#include <windows.h>
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;

typedef struct _DISK_EXTENT {
    DWORD         DiskNumber;
    LARGE_INTEGER StartingOffset;
    LARGE_INTEGER ExtentLength;
} DISK_EXTENT, *PDISK_EXTENT;

typedef struct _VOLUME_DISK_EXTENTS {
    DWORD       NumberOfDiskExtents;
    DISK_EXTENT Extents[ANYSIZE_ARRAY];
} VOLUME_DISK_EXTENTS, *PVOLUME_DISK_EXTENTS;

#define CTL_CODE(DeviceType, Function, Method, Access) \
    (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#define IOCTL_VOLUME_BASE ((DWORD)'V')
#define METHOD_BUFFERED 0
#define FILE_ANY_ACCESS 0x00000000
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)

int main() {
    bitset<32> drives(GetLogicalDrives());
    vector<char> goodDrives;
    for (char c = 'A'; c <= 'Z'; ++c) {
        if (drives[c - 'A']) {
            if (GetDriveType((c + string(":\\")).c_str()) == DRIVE_FIXED) {
                goodDrives.push_back(c);
            }
        }
    }
    for (auto & drive : goodDrives) {
        string s = string("\\\\.\\") + drive + ":";
        HANDLE h = CreateFileA(
            s.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
            OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS, NULL
        );
        if (h == INVALID_HANDLE_VALUE) {
            cerr << "Drive " << drive << ":\\ cannot be opened";
            continue;
        }
        DWORD bytesReturned;
        VOLUME_DISK_EXTENTS vde;
        if (!DeviceIoControl(
            h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
            NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL
        )) {
            cerr << "Drive " << drive << ":\\ cannot be mapped into physical drive";
            continue;
        }
        cout << "Drive " << drive << ":\\ is on the following physical drives: ";
        for (int i = 0; i < vde.NumberOfDiskExtents; ++i) {
            cout << vde.Extents[i].DiskNumber << ' ';
        }
        cout << endl;
    }
}

Windows Driver Development Kit のインストールは非常に時間のかかるプロセスだと思うのでDeviceIoControl、このタスクに使用する必要がある宣言を含めました。

于 2015-02-16T21:33:41.590 に答える
11

GetLogicalDrives() は、物理ドライブではなく、マウントされているすべてのディスク パーティションを列挙します。

GetLogicalDrives を使用して (または使用せずに) ドライブ文字を列挙し、QueryDosDevice() を呼び出して、文字がマップされている物理ドライブを見つけることができます。

または、HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices にあるレジストリの情報をデコードできます。ただし、そこにあるバイナリ データのエンコーディングは明らかではありません。Russinovich と Solomon の著書「Microsoft Windows Internals」をお持ちの場合は、このレジストリ ハイブについて第 10 章で説明しています。

于 2008-11-29T18:11:28.337 に答える
10

これを行う唯一の確実な方法は、xが0から15までCreateFile()のすべての場所を呼び出すことです(16は許可されるディスクの最大数です)。\\.\Physicaldiskx戻りハンドル値を確認してください。無効な場合は、 ERROR_FILE_NOT_FOUNDGetLastError()を確認してください。それ以外のものが返された場合、ディスクは存在しますが、何らかの理由でアクセスできません。

于 2012-04-19T12:26:38.143 に答える
5

次の WMIC コマンドの組み合わせは正常に機能します。

wmic volume list brief
于 2013-06-20T21:51:13.063 に答える
1

「物理的な」アクセスが必要な場合は、最終的にストレージ デバイスとの通信を可能にするこの API を開発しています。これはオープン ソースであり、一部の情報については現在のコードを確認できます。その他の機能については、 https ://github.com/virtium/vtStor を確認してください。

于 2015-04-27T18:43:42.880 に答える
1

今日、RSSリーダーでこれに出くわしました。よりクリーンなソリューションがあります。この例は Delphi にありますが、非常に簡単に C/C++ に変換できます (すべて Win32 です)。

次のレジストリの場所からすべての値の名前を照会します: HKLM\SYSTEM\MountedDevices

それらを 1 つずつ次の関数に渡すと、デバイス名が返されます。かなりクリーンでシンプル!ここのブログでこのコードを見つけました。

function VolumeNameToDeviceName(const VolName: String): String;
var
  s: String;
  TargetPath: Array[0..MAX_PATH] of WideChar;
  bSucceeded: Boolean;
begin
  Result := ”;
  // VolumeName has a format like this: \\?\Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}\
  // We need to strip this to Volume{c4ee0265-bada-11dd-9cd5-806e6f6e6963}
  s :=  Copy(VolName, 5, Length(VolName) - 5);

  bSucceeded := QueryDosDeviceW(PWideChar(WideString(s)), TargetPath, MAX_PATH) <> 0;
  if bSucceeded then
  begin
    Result := TargetPath;
  end
  else begin
    // raise exception
  end;

end;
于 2008-12-10T16:31:40.670 に答える
-3

a と b をスキップして、米国英語のアルファベットのすべての文字のリストを作成します。"CDEFGHIJKLMNOPQRSTUVWXYZ". これらの各ドライブを、CreateFileたとえばで開きますCreateFile("\\.\C:")。戻らないINVALID_HANDLE_VALUE場合は、「良好な」ドライブを取得しています。次に、そのハンドルを取得して実行しDeviceIoControl、ディスク # を取得します。詳細については、関連する回答を参照してください

于 2012-02-18T08:12:34.000 に答える