2011-03-31 3 views
4

Windows 7의 CDROM 드라이브의 드라이브 문자에서 실제 드라이브 번호를 조회하려고합니다 (\\.\PhysicalDriveN에있는 N이 필요합니다). This page은 IOCTL_STORAGE_GET_DEVICE_NUMBER가 작동해야 함을 나타내며, C :와 D : (D :는 이동식 드라이브 임)의 드라이브 번호에 대해 0을 반환하므로 옳지 않을 수 있습니다. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS도 제안되었지만 D :의 ERROR_INVALID_FUNCTION과 함께 실패합니다.Windows 7에서 드라이브 문자로 이동식 장치의 실제 드라이브 번호를 얻으려면 어떻게해야합니까?

저는 어딘가에서 중요한 개념을 놓친 것 같은 느낌이 들지만 도움이되지 않습니다. 나는 그것을 실행할 때 하나 관리자 또는하지,

#include "stdafx.h" 
#include "Windows.h" 


void printLastError(){ 
    DWORD lastError; 
    DWORD bytesReturned; 
    WCHAR outbuf[2048]; 

    lastError = GetLastError(); 

    bytesReturned = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 
    NULL, lastError, LANG_USER_DEFAULT, outbuf, 2048, NULL); 

    if (bytesReturned > 0){ 
    wprintf(outbuf); 
    } else { 
    printf("Error %d while formatting error %d\n", GetLastError(),  lastError); 
    } 
} 

void readDeviceNumberByExtents(HANDLE hFile){ 
    BOOL ioctlSuccess; 
    DWORD bytesReturned; 

    VOLUME_DISK_EXTENTS vde; 

    ioctlSuccess = DeviceIoControl(hFile, 
    IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 
    NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL); 

    if (ioctlSuccess != 0){ 
     printf("%d\n", vde.Extents->DiskNumber); 
    } else { 
     printLastError(); 
    } 
} 

void readDeviceNumberByStorage(HANDLE hFile){ 
    BOOL ioctlSuccess; 
    DWORD bytesReturned; 

    STORAGE_DEVICE_NUMBER sdn; 

    ioctlSuccess = DeviceIoControl(hFile, 
    IOCTL_STORAGE_GET_DEVICE_NUMBER, 
    NULL, 0, &sdn, sizeof(sdn), &bytesReturned, NULL); 

    if (ioctlSuccess != 0){ 
    printf("%d\n", sdn.DeviceNumber); 
    } else { 
    printLastError(); 
    } 
} 

void runTest(WCHAR* driveName){ 
    HANDLE driveHandle; 
    DWORD diskNumber; 

    driveHandle = CreateFile(driveName, 
    0, 
    FILE_SHARE_READ | FILE_SHARE_WRITE, 
    NULL, 
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL, 
    NULL); 

    if (driveHandle != INVALID_HANDLE_VALUE){ 
    wprintf(L"Opened %s\n", driveName); 

    printf("Device number by extents: "); 
    readDeviceNumberByExtents(driveHandle); 
    printf("Device number by storage: "); 
    readDeviceNumberByStorage(driveHandle); 

    CloseHandle(driveHandle); 
    } else { 
    printf("Failure!\n"); 
    } 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    runTest(L"\\\\.\\C:"); 
    printf("\n"); 
    runTest(L"\\\\.\\D:"); 

    getc(stdin); 
    return 0; 
} 

... 그리고 출력 :

Opened \\.\C: 
Device number by extents: 0 
Device number by storage: 0 

Opened \\.\D: 
Device number by extents: Incorrect function. 
Device number by storage: 0 

답변

5

"\\.\PhysicalDriveN"은 (처럼 행동 일) 작동 여기

내 코드입니다 하드 드라이브, 이동식 디스크가 아닙니다. 이동식 디스크 (또는 플로피, CD-ROM 등)처럼 작동하는 경우 "\\.\X:"은 원시 드라이브를 엽니 다. 다른 드라이브는 파티션을 지원하지 않으므로 "\\.\x:""\\.\PhysicalDiskN"의 구별이 없습니다. 일반적으로 GetDriveType을 사용하여 가지고있는 디스크의 종류를 알아 내고 DRIVE_FIXED 일 경우에만 드라이브 번호를 찾고 "\\.\PhysicalDriveN"을 사용하려고 시도합니다.

+0

아 - 하를! 그게 핵심 개념 인 것 같습니다 :-) – regularfry

+1

그건 사실입니다, USB 드라이브 (이동식 유형입니다)에 원시 액세스가 필요하지만, 여는 \\. \ X : USB 드라이브의 첫 번째 파티션 만 제공합니다 - X : \에서 \\. \ PhysicalDriveX로 매핑하는 방법을 찾고 있는데 이것이 작동하는 것처럼 보이면 내 대답은 –

+0

원본을 \ n. \ PhysicalDriveX를 위해 읽지 않은 곳에 보여주십시오. 이동식 장치? 필자는 윈도우즈가 USB 펜 드라이브를 위해 \\. \ PhysicalDriveX 엔트리를 생성하고 펜 드라이브가 제거되었을 때 번호 매김에 간격을 남겨 두는 것처럼이 가정을 바탕으로 현재 버그가 있고 소프트웨어의이 부분을 재 설계해야합니다. .. – Calmarius

2

그것은 C# .NET 코드입니다, 그러나 이것은 내가 작업 할 작성한 것입니다 :

using System.Management; //Add in a reference to this as well in the project settings 
public static string GetPhysicalDevicePath(char DriveLetter) 
{ 
    ManagementClass devs = new ManagementClass(@"Win32_Diskdrive"); 
    { 
     ManagementObjectCollection moc = devs.GetInstances(); 
     foreach(ManagementObject mo in moc) 
     { 
      foreach (ManagementObject b in mo.GetRelated("Win32_DiskPartition")) 
      { 
       foreach (ManagementBaseObject c in b.GetRelated("Win32_LogicalDisk")) 
       { 
        string DevName = string.Format("{0}", c["Name"]); 
        if (DevName[0] == DriveLetter) 
         return string.Format("{0}", mo["DeviceId"]); 
       } 
      } 
     } 
    } 
    return ""; 
} 
관련 문제