2010-08-02 161 views
5

我試圖在Windows上使用Win32 API區分USB閃存驅動器和USB硬盤驅動器。在Windows上區分USB閃存驅動器和USB硬盤驅動器

GetDriveType()函數將返回DRIVE_REMOVABLE如果驅動器是可移動的,和USB閃存驅動器當然可移動的。但我認爲Windows可能會考慮USB硬盤驅動器(可惜我沒有訪問USB硬盤驅動器進行測試)。

在此先感謝。

+0

只是出於好奇,你爲什麼要這樣做?你打算做一些不同的事情取決於它是什麼類型的驅動器?正如其他人所說,DriveType不是很一致(儘管它可能「足夠好」)。 – Luke 2010-08-03 13:47:09

回答

0

其實Windows不,GetDriveType返回3(DRIVE_FIXED)兩個我的USB硬盤驅動器。

+0

沒有開玩笑,謝謝。你的USB硬盤是普通硬盤,沒有特殊的驅動設置或類似的東西,可能會導致Windows認爲它們是DRIVE_FIXED而不是DRIVE_REMOVABLE? – user408962 2010-08-02 19:07:28

+0

它們只是標準的西部數字驅動器,而且我的Windows安裝非常新,所以驅動程序前端的任何內容都不會改變默認設置。 – monoceres 2010-08-02 19:15:48

0

驅動器類型最終由驅動程序確定;沒有安全的方法來做出你正在尋找的那種決心。

我能說的,但是,當我看到一個USB閃存盤迴報DRIVE_FIXED,我也從來沒有看到一個正常的硬盤驅動器的返回DRIVE_REMOVEABLE。這並不是說這完全不可能發生,但我從來沒有見過。

我想說依靠這兩個值可能是,你會得到最接近的一次。

+0

有趣的是,你說你看過一個閃存卡,並返回DRIVE_FIXED,正如我在閱讀你的評論前幾​​分鐘發現的:http://social.msdn.microsoft。com/forums/zh-CN/embeddedwindowscomponents/thread/cfffc7b6-5679-46fc-a1c9-4c08228b7b47/ – user408962 2010-08-02 19:23:06

+0

它最終並不是由驅動程序決定的,因爲驅動程序會根據設備報告的內容來確定它,但這並不總是一致的。 – 2010-11-22 17:59:14

1

Windows返回DRIVE_FIXED外接USB硬盤驅動器通常會返回DRIVE_REMOVABLE USB閃存棒。因爲這個原因,如果你想訪問閃存上的多個分區,你必須安裝一個過濾驅動來告訴windows它不是DRIVE_REMOVABLE,而是DRIVE_FIXED。 Windows只會「看到」閃存盤上的第一個分區,從而給ESXi啓動usb stick用戶造成很多麻煩;-)

0

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface將允許您將原始SCSI命令發送到設備 - 您想要發送INQUIRY或MODE SENSE找出你要找的東西。然而,一個更好的替代方案可能是VDS的API,它是否會爲您提供正確的信息(我不知道它是否會在這種情況下)

1

如果要確定一個設備是USB設備,你可以打開其句柄並使用DeviceIoControl()發送IOCTL查詢以獲取設備連接的總線類型。

EnumUsbDrivesLetters - 後在俄羅斯,但它包含了C++源代碼,所以這個問題可以很容易理解。

乾杯, 舍甫琴科

+0

請不要複製粘貼多個問題的答案,鏈接到您自己的blogspot。這將被視爲垃圾郵件。 – 2011-06-10 09:00:37

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; 
} 
相關問題