2010-08-02 13 views
5

Sto cercando di distinguere tra un'unità flash USB e un disco rigido USB su Windows utilizzando l'API Win32.Differenziazione tra unità flash USB e disco rigido USB su Windows

La funzione GetDriveType() restituirà DRIVE_REMOVABLE se l'unità è rimovibile e le unità flash USB sono ovviamente rimovibili. Ma penso che Windows consideri probabilmente anche gli hard disk USB rimovibili (sfortunatamente non ho accesso ad un hard disk USB per testarlo).

Grazie in anticipo.

+0

Solo per curiosità, perché vuoi farlo? Hai intenzione di fare qualcosa di diverso a seconda del tipo di unità che è? Come altri hanno già detto, DriveType non è molto coerente (anche se probabilmente è "abbastanza buono"). – Luke

risposta

0

In realtà Windows non lo è, GetDriveType restituisce 3 (DRIVE_FIXED) per entrambi i miei hard disk USB.

+0

No scherzo, grazie. E i tuoi dischi rigidi USB sono run-of-the-mill, e non ci sono impostazioni driver speciali o qualcosa di simile che potrebbe indurre Windows a considerarli DRIVE_FIXED invece di DRIVE_REMOVABLE? – user408962

+0

Sono solo unità digitali occidentali standard e l'installazione di Windows è abbastanza recente, quindi nulla sul fronte del driver è stato modificato rispetto alle impostazioni predefinite. – monoceres

0

Il tipo di azionamento viene determinato in ultima analisi dai driver; non esiste un modo sicuro per fare il tipo di determinazione che stai cercando.

posso dire, tuttavia, che mentre io ho visto un flash USB bastone ritorno DRIVE_FIXED, non ho mai visto un normale ritorno del disco rigido DRIVE_REMOVEABLE. Questo non vuol dire che è assolutamente impossibile che ciò accada, ma non l'ho mai visto.

Direi che fare affidamento su questi due valori è probabilmente il più vicino che si otterrà.

+0

Interessante affermare di aver visto una chiavetta USB restituire DRIVE_FIXED, poiché ho trovato questo alcuni minuti prima di leggere il tuo commento: http://social.msdn.microsoft.it/forums/en-US/embeddedwindowscomponents/thread/cfffc7b6-5679-46fc-a1c9-4c08228b7b47/ – user408962

+0

In definitiva non è determinato dai driver, perché i driver lo determinano in base a ciò che il dispositivo segnala, che non è sempre coerente . –

1

Windows restituisce DRIVE_FIXED per dischi rigidi USB esterni e in genere restituisce DRIVE_REMOVABLE per chiavette USB. Per questo motivo, se si desidera accedere a più partizioni su una memoria flash, è necessario installare un driver di filtro per indicare a Windows che non è un DRIVE_REMOVABLE ma un DRIVE_FIXED. Solo Windows "vede" la prima partizione su chiavette flash provocando un sacco di problemi per gli utenti di chiavette USB di avvio ESXi ;-)

0

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface consente di inviare comandi SCSI grezzi al dispositivo - si desidera inviare giù sia INQUIRY o MODE SENSO per scoprire cosa stai cercando. Tuttavia, un'alternativa molto migliore potrebbe essere l'API VDS, se fornirà informazioni corrette (non sono sicuro se sarà in questo caso)

1

Se si desidera determinare se un dispositivo è un dispositivo USB, è possibile aprire l'handle e inviare query IOCTL utilizzando DeviceIoControl() per ottenere il tipo di bus a cui è connesso un dispositivo.

EnumUsbDrivesLetters - il post è in russo ma contiene codice sorgente C++, quindi la questione potrebbe essere compresa facilmente.

Cheers, Andriy

+0

Si prega di non copiare e incollare le risposte su un numero di domande, collegandosi al proprio blogspot. Questo sarà considerato spamming. –

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