2010-08-02 7 views
5

Win32 API를 사용하여 Windows에서 USB 플래시 드라이브와 USB 하드 드라이브를 구별하려고합니다.Windows에서 USB 플래시 드라이브와 USB 하드 드라이브를 구분하는 방법

드라이브가 착탈 가능하고 USB 플래시 드라이브가 물론 제거 가능한 경우 GetDriveType() 함수는 DRIVE_REMOVABLE을 반환합니다. 하지만 나는 Windows가 아마도 USB 하드 드라이브를 이동식으로 간주 할 것이라고 생각하고 있습니다. 불행히도 USB 하드 드라이브에 액세스 할 수는 없습니다.

미리 감사드립니다.

+0

호기심에서 벗어난 이유는 무엇입니까? 어떤 종류의 드라이브인지에 따라 다른 것을 할 것입니까? 다른 사람들이 말했듯이 DriveType은 그다지 일관성이 없습니다 ("충분 함"). – Luke

답변

0

실제로 Windows는 GetDriveType이 내 USB 하드 드라이브 모두에 ​​대해 3 (DRIVE_FIXED)을 반환합니다.

+0

감사합니다. 그리고 당신의 USB 하드 드라이브는 평범하고 특별한 드라이버 설정이나 Windows가 DRIVE_REMOVABLE 대신에 DRIVE_FIXED로 간주 할 수있는 것과 같은 어떤 것도 없습니다. – user408962

+0

그들은 단지 표준 서부 디지털 드라이브이고 내 Windows 설치는 꽤 신선하기 때문에 드라이버 앞면에는 아무 것도 기본 설정에서 변경되지 않았습니다. – monoceres

0

드라이브 유형은 궁극적으로 드라이버에 의해 결정됩니다. 원하는 결정을 내릴 수있는 확실한 방법은 없습니다.

은 내가 USB 플래시 스틱 반환 DRIVE_FIXED을 볼 수 있습니다 동안, 그러나, 말할 수, 나는 결코는 일반 하드 드라이브 반환 DRIVE_REMOVEABLE을 볼 수 있습니다. 그것은 그 일이 완전히 불가능하다는 것을 말하는 것은 아니지만, 나는 그것을 결코 보지 못했습니다.

나는이 두 값에 의존하는 것이 아마도 당신이 얻는 가장 가까운 것이라고 말할 수 있습니다.

+0

흥미로운 점은 플래시 스틱이 DRIVE_FIXED로 돌아가는 것을 보았다는 것입니다. 귀하의 의견을 읽기 전에이 내용을 발견했습니다 : http://social.msdn.microsoft.com/forums/ko-US/embeddedwindowscomponents/thread/cfffc7b6-5679-46fc-a1c9-4c08228b7b47/ – user408962

+0

드라이버가 궁극적으로 결정하지는 않습니다. 드라이버가 장치가보고 한 내용을 기반으로 결정하기 때문입니다. . –

1

Windows는 외장형 USB 하드 드라이브의 경우 DRIVE_FIXED를 반환하고 대개 USB 플래시 스틱의 경우 DRIVE_REMOVABLE을 반환합니다. 이러한 이유로 플래시 메모리의 여러 파티션에 액세스하려면 Windows에 DRIVE_REMOVABLE이 아니라 DRIVE_FIXED가 있음을 알리는 필터 드라이버를 설치해야합니다. Windows는 ESXi 부팅 USB 스틱 사용자에게 많은 문제를 일으키는 플래시 스틱의 첫 번째 파티션을 "인식"합니다 .-

0

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface 원시 SCSI 명령을 장치로 보낼 수있게합니다. INQUIRY 또는 MODE 당신이 찾고있는 것을 찾으십시오. 그러나 정확한 정보를 제공 할 경우 VDS API가 더 나은 대안이 될 수 있습니다 (이 경우에 해당할지 여부는 확실하지 않음)

1

장치가 USB 장치인지 확인하려면 다음을 수행 할 수 있습니다. 핸들을 열고 DeviceIoControl()을 사용하여 IOCTL 쿼리를 보내 장치가 연결된 버스 유형을 가져옵니다.

EnumUsbDrivesLetters - 게시물은 러시아어이지만 C++ 소스 코드가 포함되어있어 쉽게 이해할 수 있습니다.

건배, 안드리

+0

자신의 블로그 스폿에 링크 된 여러 가지 질문에 대해 답변을 복사하여 붙여 넣지 마십시오. 이것은 스패밍으로 간주됩니다. –

1
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
// Method  OpenVolume 
// Purpose: Open volume for removal. Change to ::CreateFile(volumeName, 0, 0, 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); 
//    if you just want to inquire if it's removable. 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

HANDLE OpenVolume(const char& driveLetter) 
{ 
    char volumeName[8] = ""; 
    char* volumeFormat = "\\\\.\\%c:"; 
    sprintf(volumeName, volumeFormat, driveLetter); 

    HANDLE volume = ::CreateFile(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 
    if (volume == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE; 

    DWORD bytesReturned = 0; 
    STORAGE_HOTPLUG_INFO Info = {0}; 
    if (::DeviceIoControl(volume, IOCTL_STORAGE_GET_HOTPLUG_INFO, 0, 0, &Info, sizeof(Info), &bytesReturned, NULL)) 
    { 
     if (!(Info.MediaRemovable || Info.DeviceHotplug)) 
     { 
      ::CloseHandle(volume); 
      ::SetLastError(ERROR_INVALID_PARAMETER); 
      return INVALID_HANDLE_VALUE; 
     } 
    } 

    return volume; 
}