2016-10-23 2 views
1

FindFirstVolume/FindNextVolume을 사용하여 컴퓨터의 모든 볼륨 목록을 가져옵니다. 잘 작동하지만 이상하게도 EFI 시스템 파티션은 어떤 이유로 건너 뜁니다. 반면 Diskpart는 EFI 시스템 파티션을 반환하고 Disk Management UI는이를 보여줍니다.FindFirstVolume이 EFI 시스템 파티션을 반환하지 않습니다.

이 FindFirstVolume/FindNextVolume 나에게 다른 4 권을 부여하지만, EFI 시스템 파티션을 생략

DISKPART> list volume 

    Volume ### Ltr Label  Fs  Type  Size  Status  Info 
    ---------- --- ----------- ----- ---------- ------- --------- -------- 
    Volume 0  C    NTFS Partition 476 GB Healthy Boot 
    Volume 1   Recovery  NTFS Partition 450 MB Healthy Hidden 
    Volume 2      FAT32 Partition 100 MB Healthy System 
    Volume 3  D Data   NTFS Partition 953 GB Healthy 
    Volume 4  E ESD-USB  FAT32 Removable  14 GB Healthy 

그 목록에서 EFI 시스템 파티션은 볼륨 2입니다 :

여기 DISKPART의 출력됩니다.

EFI 시스템 분할에 대한 볼륨 GUID 경로 또는 프로그래밍 방식으로 액세스 할 수있는 다른 방법은 어떤 아이디어입니까? FindFirstVolume/FindNextVolume로 복귀하지 않으면

+0

http://stackoverflow.com/questions/35102053/how-can-i-get-volume- 이름 -에 - 시스템 파티션/35105012 당신에게 어떤 아이디어를 줄 수 있습니다 – Naidu

+0

높은 권한으로 실행 중입니까? Windows가 권한이없는 사용자로부터 EFI 파티션을 보호하는 방법을 정확히 모르지만 열거 할 때 볼륨을 건너 뛸 수 있습니다. –

+0

@HarryJohnston : 예, 로컬 시스템으로도 –

답변

2

볼륨 GUID 경로 (즉 \ ?? \ 볼륨 {...}는) 존재하지 그러나 우리는 다른 방법으로 시스템 내의 모든 볼륨을 열거 할 수있다. 우리는 Virtual Disk Service com api를 사용할 수 있다고 말합니다. DISKPART> list volume 정확히 사용하십시오. (보다 '낮은'빠른) 또 다른 방법은 - pszFilter =와 CM_Get_Device_ID_ListW을 사용 (devguid.h에서 GUID_DEVCLASS_VOLUME)을 보면 "{-11D0-BEC7-08002BE2092F 71a27cdd-812A}"이 아닌 CM_Get_DevNode_PropertyWDEVPKEY_Device_PDOName에 대한 CM_Locate_DevNodeW 및 쿼리하여 장치 인스턴스 핸들을 얻을 - 우리는 ZwOpenFile에서 사용할 수있는 문자열 (\Device\HarddiskVolume<X>과 같은)을 가지고 있으며 볼륨 속성을 얻기 위해 일부 ioctls (IOCTL_DISK_GET_PARTITION_INFO_EX 및 기타)를 사용합니다. 코드 예제 :

#include <initguid.h> 
#include <cfgmgr32.h> 
#include <devguid.h> 
#include <devpkey.h> 
#include <diskguid.h> 

void DumpVolume(HANDLE hFile); 

void VolEnum() 
{ 
    STATIC_WSTRING(DEVCLASS_VOLUME, "{71a27cdd-812a-11d0-bec7-08002be2092f}"); 

    enum { flags = CM_GETIDLIST_FILTER_CLASS|CM_GETIDLIST_FILTER_PRESENT }; 

    ULONG len; 
    ULONG cb = 0, rcb = 64; 

    HANDLE hFile; 
    IO_STATUS_BLOCK iosb; 
    UNICODE_STRING ObjectName; 
    OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE }; 

    if (!CM_Get_Device_ID_List_SizeW(&len, DEVCLASS_VOLUME, flags)) 
    { 
     PWSTR buf = (PWSTR)alloca(len << 1); 
     if (!CM_Get_Device_ID_ListW(DEVCLASS_VOLUME, buf, len, flags)) 
     { 
      PVOID stack = buf; 
      while (*buf) 
      { 
       DbgPrint("%S\n", buf); 
       DEVINST dnDevInst; 
       if (!CM_Locate_DevNodeW(&dnDevInst, buf, CM_LOCATE_DEVNODE_NORMAL)) 
       { 
        DEVPROPTYPE PropertyType; 
        int err; 

        union { 
         PVOID pv; 
         PWSTR sz; 
         PBYTE pb; 
        }; 

        do 
        { 
         if (cb < rcb) 
         { 
          rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack); 
         } 

         if (!(err = CM_Get_DevNode_PropertyW(dnDevInst, &DEVPKEY_Device_PDOName, &PropertyType, pb, &rcb, 0))) 
         { 
          if (PropertyType == DEVPROP_TYPE_STRING) 
          { 
           DbgPrint("%S\n", sz); 

           RtlInitUnicodeString(&ObjectName, sz); 
           if (0 <= ZwOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb, FILE_SHARE_VALID_FLAGS, 0)) 
           { 
            DumpVolume(hFile); 
            ZwClose(hFile); 
           } 
          } 
         } 

        } while (err == CR_BUFFER_SMALL); 

       } 
       buf += 1 + wcslen(buf); 
      } 
     } 
    } 
} 

void DumpVolume(HANDLE hFile) 
{ 
    NTSTATUS status; 
    PARTITION_INFORMATION_EX pi; 
    IO_STATUS_BLOCK iosb; 

    if (0 <= (status = ZwDeviceIoControlFile(hFile, 0, 0, 0, &iosb, IOCTL_DISK_GET_PARTITION_INFO_EX, 0, 0, &pi, sizeof(pi)))) 
    { 
     CHAR PartitionName[40], *szPartitionName; 

     PCSTR szps = "??"; 
     switch (pi.PartitionStyle) 
     { 
     case PARTITION_STYLE_MBR: szps = "MBR"; 
      break; 
     case PARTITION_STYLE_GPT: szps = "GPT"; 
      break; 
     } 

     DbgPrint("%u %s %I64u(%I64x) %I64u ", 
      pi.PartitionNumber, 
      szps, 
      pi.StartingOffset.QuadPart, pi.StartingOffset.QuadPart, 
      pi.PartitionLength.QuadPart); 

     switch (pi.PartitionStyle) 
     { 

     case PARTITION_STYLE_MBR: 
      DbgPrint("type=%x boot=%x", pi.Mbr.PartitionType, pi.Mbr.BootIndicator); 
      break; 

     case PARTITION_STYLE_GPT: 

      if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID)) 
      { 
       szPartitionName = "UNUSED"; 
      } 
      else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_SYSTEM_GUID)) 
      { 
       szPartitionName = "SYSTEM"; 
      } 
      else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_MSFT_RESERVED_GUID)) 
      { 
       szPartitionName = "RESERVED"; 
      } 
      else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_BASIC_DATA_GUID)) 
      { 
       szPartitionName = "DATA"; 
      } 
      else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_MSFT_RECOVERY_GUID)) 
      { 
       szPartitionName = "RECOVERY"; 
      } 
      else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_MSFT_SNAPSHOT_GUID)) 
      { 
       szPartitionName = "SNAPSHOT"; 
      } 
      else 
      { 
       sprintf(szPartitionName = PartitionName, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", 
        pi.Gpt.PartitionType.Data1, 
        pi.Gpt.PartitionType.Data2, 
        pi.Gpt.PartitionType.Data3, 
        pi.Gpt.PartitionType.Data4[0], 
        pi.Gpt.PartitionType.Data4[1], 
        pi.Gpt.PartitionType.Data4[2], 
        pi.Gpt.PartitionType.Data4[3], 
        pi.Gpt.PartitionType.Data4[4], 
        pi.Gpt.PartitionType.Data4[5], 
        pi.Gpt.PartitionType.Data4[6], 
        pi.Gpt.PartitionType.Data4[7]); 
      } 
      DbgPrint("[%s] %I64x \"%S\"", 
       szPartitionName, 
       pi.Gpt.Attributes, 
       pi.Gpt.Name); 
      break; 
     } 

     ULONG cb = FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[32]); 
     PFILE_FS_ATTRIBUTE_INFORMATION pffai = (PFILE_FS_ATTRIBUTE_INFORMATION)alloca(cb); 

     switch (ZwQueryVolumeInformationFile(hFile, &iosb, pffai, cb, FileFsAttributeInformation)) 
     { 
     case STATUS_SUCCESS: 
     case STATUS_BUFFER_OVERFLOW: 
      DbgPrint(" \"%.*S\"", pffai->FileSystemNameLength >> 1 , pffai->FileSystemName); 
      break; 
     } 

     DbgPrint("\n"); 
    } 
    else 
    { 
     DbgPrint("status=%x\n", status); 
    } 
} 

및 디버그 출력 속성

STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000012D00000 
\Device\HarddiskVolume2 
2 GPT 315621376(12d00000) 104857600 [SYSTEM] 8000000000000000 "EFI system partition" "FAT32" 
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000000100000 
\Device\HarddiskVolume1 
1 GPT 1048576(100000) 314572800 [RECOVERY] 8000000000000001 "Basic data partition" "NTFS" 
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000021100000 
\Device\HarddiskVolume4 
4 GPT 554696704(21100000) 255506513920 [DATA] 0 "Basic data partition" "NTFS" 
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000019100000 
\Device\HarddiskVolume3 
3 GPT 420478976(19100000) 134217728 [RESERVED] 8000000000000000 "Microsoft reserved partition" "RAW" 
STORAGE\Volume\{a4d55aa5-4d7f-11e5-8256-5cc5d4ea6270}#0000000000007E00 
\Device\HarddiskVolume5 
1 MBR 32256(7e00) 32017013248 type=7 boot=1 "NTFS" 

모양 - https://msdn.microsoft.com/en-us/library/windows/desktop/aa365449(v=vs.85).aspx

+0

매우 유용합니다. 정말 고마워요! 분명히 CM_ * 함수는 EFI 시스템 파티션 (및 RAW 파티션)을 반환하는 유일한 함수입니다. SetupDi * 기능은 그렇게하지 않습니다 (체크). –

관련 문제