2010-08-02 17 views
5

Estoy tratando de diferenciar entre una unidad flash USB y un disco duro USB en Windows utilizando la API de Win32.Diferenciar entre unidad flash USB y disco duro USB en Windows

La función GetDriveType() devolverá DRIVE_REMOVABLE si la unidad es extraíble y, por supuesto, las unidades flash USB son extraíbles. Pero creo que Windows probablemente también considere los discos duros USB como extraíbles (desafortunadamente no tengo acceso a un disco duro USB para probarlo).

Gracias de antemano.

+0

Solo por curiosidad, ¿por qué quieres hacer esto? ¿Vas a hacer algo diferente dependiendo de qué tipo de disco es? Como otros han dicho, DriveType no es muy consistente (aunque probablemente sea "lo suficientemente bueno"). – Luke

Respuesta

0

Actualmente Windows no tiene, GetDriveType devuelve 3 (DRIVE_FIXED) para mis dos discos duros usb.

+0

No es broma, gracias. ¿Y sus unidades de disco duro USB no están en funcionamiento, y no hay configuraciones especiales para el controlador ni nada por el estilo que pueda hacer que Windows las considere DRIVE_FIXED en lugar de DRIVE_REMOVABLE? – user408962

+0

Son solo unidades digitales occidentales estándar y mi instalación de Windows es bastante reciente, por lo que no ha cambiado nada en el frente del controlador de la configuración predeterminada. – monoceres

0

El tipo de unidad es determinada en última instancia por los controladores; no hay una forma segura de hacer el tipo de determinación que estás buscando.

lo que puedo decir, sin embargo, que mientras yo tengo visto un palo de retorno flash USB DRIVE_FIXED, tengo nunca se ve un retorno de disco duro normal de DRIVE_REMOVEABLE. Eso no quiere decir que sea completamente imposible que eso suceda, pero nunca lo he visto.

Yo diría que depender de esos dos valores es probablemente lo más cercano que va a obtener.

+0

Es interesante que diga que ha visto una memoria flash, devuelva DRIVE_FIXED, ya que encontré esto unos minutos antes de leer su comentario: http://social.msdn.microsoft.com/forums/es-ES/embeddedwindowscomponents/thread/cfffc7b6-5679-46fc-a1c9-4c08228b7b47/ – user408962

+0

No lo determinan los controladores, ya que los controladores lo determinan según lo que informa el dispositivo, lo que no siempre es coherente . –

1

Windows devuelve DRIVE_FIXED para discos duros USB externos y generalmente devuelve DRIVE_REMOVABLE para memorias USB. Por esta razón, si desea acceder a múltiples particiones en una memoria flash, debe instalar un controlador de filtro para decirle a Windows que no es un DRIVE_REMOVABLE sino un DRIVE_FIXED. Windows solo "ve" la primera partición en flash sticks causando muchos problemas para los usuarios de ESXi boot usb stick ;-)

0

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface le permitirá enviar comandos SCSI sin procesar al dispositivo - desea enviar INQUIRY o MODE SENTIDO para descubrir lo que estás buscando. Sin embargo, una alternativa mucho mejor pueden ser las API de VDS, si le proporcionará información correcta (no estoy seguro si lo hará en este caso)

1

Si desea determinar que un dispositivo es un dispositivo USB, puede abra su identificador y envíe consultas IOCTL usando DeviceIoControl() para obtener el tipo de bus al que está conectado un dispositivo.

EnumUsbDrivesLetters - la publicación está en ruso pero contiene el código fuente C++, por lo que el asunto podría ser entendido fácilmente.

Saludos, Andriy

+0

No copie y pegue las respuestas sobre una serie de preguntas, vinculándolas a su propio blog. Esto se considerará spam. –

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