2010-08-02 24 views
5

J'essaie de faire la différence entre un lecteur flash USB et un disque dur USB sous Windows à l'aide de l'API Win32.Différencier entre lecteur flash USB et disque dur USB sous Windows

La fonction GetDriveType() retournera DRIVE_REMOVABLE si le lecteur est amovible, et les lecteurs flash USB sont bien sûr amovibles. Mais je pense que Windows considère probablement les disques durs USB comme étant amovibles (malheureusement, je n'ai pas accès à un disque dur USB pour le tester).

Merci d'avance.

+0

Juste par curiosité, pourquoi voulez-vous faire cela? Allez-vous faire quelque chose de différent selon le type de lecteur? Comme d'autres l'ont dit, le DriveType n'est pas très cohérent (même si c'est probablement "assez bon"). – Luke

Répondre

0

En fait Windows ne fait pas, GetDriveType renvoie 3 (DRIVE_FIXED) pour mes deux disques durs USB.

+0

Sans blague, merci. Et vos disques durs USB sont-ils ordinaires, et il n'y a pas de paramètres de pilote spéciaux ou quoi que ce soit de ce genre qui pourrait amener Windows à les considérer DRIVE_FIXED au lieu de DRIVE_REMOVABLE? – user408962

+0

Ce ne sont que des lecteurs numériques standard de l'Ouest et mon installation Windows est assez récente, donc rien sur le front du pilote n'a changé par rapport aux paramètres par défaut. – monoceres

0

Le type de lecteur est finalement déterminé par les pilotes; Il n'y a pas de moyen sûr de faire le genre de détermination que vous recherchez.

je peux dire, cependant, que si je ai vu un flash Clé USB retour DRIVE_FIXED, je jamais vu un retour du disque dur normale DRIVE_REMOVEABLE. Cela ne veut pas dire que c'est complètement impossible, mais je ne l'ai jamais vu.

Je dirais que s'appuyer sur ces deux valeurs est probablement le plus proche que vous allez obtenir.

+0

Intéressant vous dites que vous avez vu une clé USB retourner DRIVE_FIXED, comme je l'ai trouvé quelques minutes avant de lire votre commentaire: http://social.msdn.microsoft.com/forums/fr/US/embeddedwindowscomponents/thread/cfffc7b6-5679-46fc-a1c9-4c08228b7b47/ – user408962

+0

Ce n'est pas finalement déterminé par les pilotes, car les pilotes le déterminent en fonction de ce que le périphérique rapporte, ce qui n'est pas toujours cohérent . –

1

Windows renvoie DRIVE_FIXED pour les disques durs USB externes et renvoie généralement DRIVE_REMOVABLE pour les clés USB. Pour cette raison, si vous voulez accéder à plusieurs partitions sur une mémoire flash, vous devez installer un pilote de filtre pour indiquer à Windows qu'il ne s'agit pas d'un DRIVE_REMOVABLE mais d'un DRIVE_FIXED à la place. Windows ne "voit" que la première partition sur les clés USB causant beaucoup de problèmes pour les utilisateurs ESXi boot usb ;-)

0

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface vous permettra d'envoyer des commandes SCSI brutes à l'appareil - vous voulez envoyer soit INQUIRY ou MODE SENSE pour savoir ce que vous cherchez. Cependant, une meilleure alternative peut être l'API VDS, si elle vous fournira des informations correctes (je ne suis pas sûr que ce sera le cas dans ce cas)

1

Si vous voulez déterminer qu'un périphérique est un périphérique USB, vous pouvez ouvre son handle et envoie des requêtes IOCTL en utilisant DeviceIoControl() pour obtenir le type de bus auquel un périphérique est connecté.

EnumUsbDrivesLetters - le message est en russe mais il contient du code source C++, donc la question peut être facilement comprise.

Cheers, Andriy

+0

Veuillez ne pas copier-coller les réponses sur un certain nombre de questions, en créant un lien vers votre propre blogspot. Cela sera considéré comme du spam. –

1

Je pense que la clé est des propriétés d'entraînement, par exemple comptage cylindre. Vous pouvez utiliser l'interface WMI pour déterminer ces informations. Voici un exemple:

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; 
}