programing

물리 디스크를 표시하는 방법

goodsources 2022. 8. 16. 23:40
반응형

물리 디스크를 표시하는 방법

의 리스트를 하려면 , 의 「」를 참조해 주세요."\\\\.\PhysicalDrive0"이용할 수 있는.

#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월 업데이트, Microsoft는 "Windows 10 기능은 더 이상 개발하지 않습니다"에서 발표

WMIC 툴은 Windows Server의 Windows 10, 버전21H1 및 21H1 General Availability Channel 릴리즈에서는 권장되지 않습니다.

이 도구는 WMI용 Windows PowerShell로 대체되었습니다.

주의: 이 권장사항은 명령줄 관리 도구에만 적용됩니다.WMI 자체는 영향을 받지 않습니다.

답은 위의 모든 대답보다 훨씬 간단하다.실제 드라이브 목록은 레지스트리 키에 실제로 저장되며, 레지스트리 키는 디바이스 매핑도 제공합니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\disk\열거형

개수는 PhysicalDrive#의 개수로 번호가 매겨진 각 레지스트리 값은 대응하는 물리 드라이브입니다.

예를 들어 레지스트리 값 "0"은 PhysicalDrive0입니다.이 값은 PhysicalDrive0이 매핑되는 실제 디바이스입니다.여기에 포함된 값은 파라미터 pDevice 내의 CM_Locate_DevNode에 전달할 수 있습니다.플러그 앤 플레이 서비스를 사용할 ID입니다.이를 통해 장치에서 풍부한 정보를 수집할 수 있습니다.예를 들어 드라이브 이름, 일련 번호 등이 필요한 경우 "친절한 표시 이름"과 같은 장치 관리자의 속성.

WMI 서비스는 시스템 또는 기타 해킹으로 실행되지 않을 수 있으며, 이 기능은 2000년 이후 Windows에 존재하며 Windows 10에서도 마찬가지입니다.

한 가지 방법:

  1. 다음을 사용하여 논리 드라이브 열거

  2. 논리 파일 인 각음음음음음음음음 a a a a a a a a a a a a를 ."\\.\X:"(따옴표 없음) 여기서 X는 논리 드라이브 문자입니다.

  3. 이전 순서로 열린 파일에 핸들을 건네주는 콜과dwIoControlCode파라미터는 다음과 같이 설정됩니다.

    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);
    

논리 볼륨의 물리적 위치에 대한 정보를 구조로 반환합니다.

물리 드라이브에 번호는, 「 」로 할 수 있습니다.diskExtents.Extents[0].DiskNumber

5년 정도 늦어질 수 있습니다. : )근데 아직 답이 안 보이니까 이거 추가해서.

셋업 API를 사용하여 디스크, 즉 시스템 내의 디바이스 목록을 가져올 수 있습니다.

일단 그들의 디바이스 경로를 파악한 후, 우리는 발행하여"\\.\PHYSICALDRIVE%d"STORAGE_DEVICE_NUMBER.DeviceNumber

'함수'도 참조

#include <Windows.h>
#include <Setupapi.h>
#include <Ntddstor.h>

#pragma comment( lib, "setupapi.lib" )

#include <iostream>
#include <string>
using namespace std;

#define START_ERROR_CHK()           \
    DWORD error = ERROR_SUCCESS;    \
    DWORD failedLine;               \
    string failedApi;

#define CHK( expr, api )            \
    if ( !( expr ) ) {              \
        error = GetLastError( );    \
        failedLine = __LINE__;      \
        failedApi = ( api );        \
        goto Error_Exit;            \
    }

#define END_ERROR_CHK()             \
    error = ERROR_SUCCESS;          \
    Error_Exit:                     \
    if ( ERROR_SUCCESS != error ) { \
        cout << failedApi << " failed at " << failedLine << " : Error Code - " << error << endl;    \
    }

int main( int argc, char **argv ) {

    HDEVINFO diskClassDevices;
    GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
    DWORD requiredSize;
    DWORD deviceIndex;

    HANDLE disk = INVALID_HANDLE_VALUE;
    STORAGE_DEVICE_NUMBER diskNumber;
    DWORD bytesReturned;

    START_ERROR_CHK();

    //
    // Get the handle to the device information set for installed
    // disk class devices. Returns only devices that are currently
    // present in the system and have an enabled disk device
    // interface.
    //
    diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid,
                                            NULL,
                                            NULL,
                                            DIGCF_PRESENT |
                                            DIGCF_DEVICEINTERFACE );
    CHK( INVALID_HANDLE_VALUE != diskClassDevices,
         "SetupDiGetClassDevs" );

    ZeroMemory( &deviceInterfaceData, sizeof( SP_DEVICE_INTERFACE_DATA ) );
    deviceInterfaceData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
    deviceIndex = 0;

    while ( SetupDiEnumDeviceInterfaces( diskClassDevices,
                                         NULL,
                                         &diskClassDeviceInterfaceGuid,
                                         deviceIndex,
                                         &deviceInterfaceData ) ) {

        ++deviceIndex;

        SetupDiGetDeviceInterfaceDetail( diskClassDevices,
                                         &deviceInterfaceData,
                                         NULL,
                                         0,
                                         &requiredSize,
                                         NULL );
        CHK( ERROR_INSUFFICIENT_BUFFER == GetLastError( ),
             "SetupDiGetDeviceInterfaceDetail - 1" );

        deviceInterfaceDetailData = ( PSP_DEVICE_INTERFACE_DETAIL_DATA ) malloc( requiredSize );
        CHK( NULL != deviceInterfaceDetailData,
             "malloc" );

        ZeroMemory( deviceInterfaceDetailData, requiredSize );
        deviceInterfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );

        CHK( SetupDiGetDeviceInterfaceDetail( diskClassDevices,
                                              &deviceInterfaceData,
                                              deviceInterfaceDetailData,
                                              requiredSize,
                                              NULL,
                                              NULL ),
             "SetupDiGetDeviceInterfaceDetail - 2" );

        disk = CreateFile( deviceInterfaceDetailData->DevicePath,
                           GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE,
                           NULL,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           NULL );
        CHK( INVALID_HANDLE_VALUE != disk,
             "CreateFile" );

        CHK( DeviceIoControl( disk,
                              IOCTL_STORAGE_GET_DEVICE_NUMBER,
                              NULL,
                              0,
                              &diskNumber,
                              sizeof( STORAGE_DEVICE_NUMBER ),
                              &bytesReturned,
                              NULL ),
             "IOCTL_STORAGE_GET_DEVICE_NUMBER" );

        CloseHandle( disk );
        disk = INVALID_HANDLE_VALUE;

        cout << deviceInterfaceDetailData->DevicePath << endl;
        cout << "\\\\?\\PhysicalDrive" << diskNumber.DeviceNumber << endl;
        cout << endl;
    }
    CHK( ERROR_NO_MORE_ITEMS == GetLastError( ),
         "SetupDiEnumDeviceInterfaces" );

    END_ERROR_CHK();

Exit:

    if ( INVALID_HANDLE_VALUE != diskClassDevices ) {
        SetupDiDestroyDeviceInfoList( diskClassDevices );
    }

    if ( INVALID_HANDLE_VALUE != disk ) {
        CloseHandle( disk );
    }

    return error;
}

유일한 정답은 @Groudrigues의 것으로, 여기에 그가 너무 게을러서 쓸 수 없었던 코드가 있다.

#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;
    }
}

Development 의은 꽤 이 걸리는 Windows 를 사용하기 했습니다.DeviceIoControl을 사용하다

기존 디스크만 살펴봐야 하는 경우 이 디스크로 충분합니다.

powershell "get-physicaldisk"

Thic WMIC 명령어 조합은 정상적으로 동작합니다.

wmic volume list brief

GetLogicalDrives()는 물리 드라이브가 아닌 마운트된 모든 디스크 파티션을 열거합니다.

GetLogicalDrives가 있거나 없는 드라이브 문자를 열거한 다음 QueryDosDevice()를 호출하여 문자가 매핑된 물리적 드라이브를 확인할 수 있습니다.

또는 HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices 레지스트리의 정보를 디코딩할 수도 있습니다.단, 바이너리 데이터 인코딩은 명확하지 않습니다.Russinovich 와 Solomon 의 책 Microsoft Windows Internals 의 카피가 있는 경우는, 이 레지스트리 하이브에 대해 10 장에서 설명합니다.

이 디스크 정보를 꺼내기 위해 "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

다음은 WMI 호출을 사용하여 이를 수행하는 새로운 솔루션입니다.
만 하면 돼요.

queryAndPrintResult(L"SELECT * FROM Win32_DiskDrive", L"Name");

을 하려면 , 「 」를 호출하는 .CreateFile() 모로\\.\Physicaldiskx여기서 x는 0 ~15입니다(16은 허용되는 최대 디스크 수).반환된 핸들 값을 확인합니다.는, 체크해 주세요.GetLastError()ERROR_FILE_NOT_FOUND. 다른 항목이 반환되면 해당 디스크는 존재하지만 어떤 이유로 액세스할 수 없습니다.

오늘 RSS Reader에서 이걸 우연히 발견했어요.더 깔끔한 해결책이 있습니다.이 예는 Dellphi에 있지만 C/C++(모두 Win32)로 쉽게 변환할 수 있습니다.

HKLM\SYSTEM\MountedDevices 레지스트리 위치에서 모든 값 이름을 쿼리합니다.

하나씩 다음 함수로 전달하면 디바이스 이름이 반환됩니다.꽤 깔끔하고 심플해요!여기 블로그에서 이 코드를 찾았어요

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;

a와 b를 건너뛰고 미국 영어 알파벳으로 모든 문자 목록을 작성합니다. "CDEFGHIJKLMNOPQRSTUVWXYZ"를 사용하여 각 드라이브를 엽니다.CreateFile예.CreateFile("\\.\C:"). 다시 돌아오지 않을 경우INVALID_HANDLE_VALUE'좋은' 드라이브를 갖게 될 거야다음에 그 손잡이를 잡고 통과시켜라.DeviceIoControl디스크 번호를 가져옵니다.자세한 내용은 관련 답변을 참조하십시오.

누가 사용하는지 모르기 때문에 이전 A: 및 B: 드라이브를 포함하기를 원할 수 있습니다.USB 드라이브가 Readyboost 전용 SDHC 드라이브 두 개를 충돌시키는 데 지쳤습니다.드라이브 문자를 원하는 대로 장치에 할당하는 유틸리티를 사용하여 높은 문자 Z: Y:에 할당했습니다.궁금해서...Readyboost 드라이브 문자를 A: ? YES! 두 번째 SDHC 드라이브 문자를 B: ? YES로 입력할 수 있습니까?

예전에 플로피 드라이브를 사용해봤지만, A: 또는 B:가 Readyboost에 유용할 것이라고는 생각하지 못했습니다.

내 요점은 A: & B:는 어떤 것에 대해서도 사용되지 않을 것이라고 가정하지 말라는 것입니다. 오래된 SUBST 명령어가 사용되고 있는 것을 발견할 수도 있습니다.

"물리적" 액세스를 원하는 경우 스토리지 디바이스와 통신할 수 있는 API를 개발 중입니다.오픈 소스라서 최신 코드를 보시면 알 수 있습니다.자세한 것은, https://github.com/virtium/vtStor 를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/327718/how-to-list-physical-disks

반응형