Как узнать номер физического диска съемного устройства из буквы диска в Windows 7? - PullRequest
4 голосов
/ 31 марта 2011

Я пытаюсь найти номер физического диска (например, мне нужно N в \\.\PhysicalDriveN, чтобы открыть блочное устройство для чтения) по букве диска CDROM в Windows 7. Эта страница указывает, что IOCTL_STORAGE_GET_DEVICE_NUMBER должен работать, но возвращает 0 для номера диска для C: и D: (где D: съемный диск), так что это не может быть правильным.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS также предлагается, но это не работает с ERROR_INVALID_FUNCTION для D:.

Я не могу не чувствовать, что где-то пропустил важную концепцию.

Вот мой код:

#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

Ответы [ 2 ]

5 голосов
/ 31 марта 2011

"\\.\PhysicalDriveN" работает только для (схожих) жестких дисков, но не для съемных дисков.Если что-то действует как съемный диск (или дискета, CD-ROM и т. Д.), "\\.\X:" открывает сырой диск (другие приводы не поддерживают разделы, поэтому различия между "\\.\x:" и "\\.\PhysicalDiskN" не существуетдля них).Обычно вы хотите использовать GetDriveType, чтобы выяснить, какой у вас диск, и только если это говорит о том, что это DRIVE_FIXED, вы пытаетесь найти номер диска и используете "\\.\PhysicalDriveN" с ним.

2 голосов
/ 18 августа 2011

Это код на C # .Net, но это то, что я написал для этой работы:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...