PDA

Ver la versión completa : Codigo para detectar unidades extraibles en vb6



pato21
16-03-2009, 08:15
Pueden ayudarme con el codigo para detectar unidades extraibles en vb6 he buscad y encontre que se usan apis pero no lo tengo clar ojala y ustedes me puedan ayudar

hystd
16-03-2009, 14:53
Las API que puedes usar son GetLogicalDrives y GetLogicalDriveStrings, ambas contenidas en Kernel32.dll.

La primera es muy simple, ya que no recibe ningún parámetro, y devuelve un DWORD (64 bits para arquitecturas de 32 bits).

La forma de interpretar el valor devuelto es viendo cada uno de esos bits y si está a 1 existe la unidad "i", donde "i" es la posición que ocupa el bit en el valor devuelto por esta función. Si está a 0, quiere decir que no hay unidad.

Un ejemplo:

supongamos que devuelve 28. En binario 28 es 11100, por tanto leemos de la siguiente manera: el bit menos significativo (el de más a la derecha) corresponde a la unidad A, y como es 0, quiere decir que no hay unidad A. El siguiente también es 0, por tanto no hay unidad B. El siguiente es 1 que indica que si hay unidad C, y los dos últimos que son 1, indican que hay unidad D Y E.


La segunda función GetLogicalDriveStrings recibe dos parámetros: tamaño de un bufer y un puntero a éste. El bufer contendrá las cadenas de texto con la letra de unidad de la siguiente forma:

C:\<null>D:\<null>E:\<null><null> (para el ejemplo anterior)

El valor devuelto por esta función es la longitud de la cadena almacenada en el buffer.

Así un ejemplo con esta segunda función es el siguiente:



Option Explicit

Private Declare Function GetLogicalDriveStrings Lib "kernel32" _
Alias "GetLogicalDriveStringsA" _
(ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long

Private Function GetDriveStrings() As String
Dim result As Long
Dim strDrives As String
Dim lenStrDrives As Long

result = GetLogicalDriveStrings(0, strDrives)

strDrives = String(result, 0)
lenStrDrives = result

result = GetLogicalDriveStrings(lenStrDrives, strDrives)

If result = 0 Then
GetDriveStrings = ""
Else
GetDriveStrings = strDrives
End If
End Function

Private Sub Command1_Click()
Dim strDrives As String
strDrives = GetDriveStrings()

If strDrives = "" Then
MsgBox "No se han encontrado unidades", vbCritical
Else
DisplayDriveTypes strDrives
End If
End Sub

Private Sub DisplayDriveTypes(drives As String)
Dim pos As Long
Dim drive As String

List1.Clear
pos = 1

Do While Not Mid$(drives, pos, 1) = Chr(0)
drive = Mid$(drives, pos, 3)
pos = pos + 4
List1.AddItem UCase(drive)
Loop
End Sub

Un saludo.

pato21
16-03-2009, 22:21
vale pana gracias por tu respuesta me sirve mucho el codigo aunque no lo entendi muy bien me va a tocar analizar mas este asunto
para saber cuando es de tipo removible usb se usa otra api diferente GetVolumeInformation

hystd
16-03-2009, 23:45
GetVolumeInformation no se utiliza para eso, o no da información sobre qué tipo de unidad, ni qué controlador es el que utiliza.

Esta función sirve para obtener información sobre una unidad cualquiera de almacenamiento masivo como por ejemplo, obtener el número de serie del dispositivo, sistema de ficheros utilizado, longitud máxima de ficheros y de nombres, compresión, número de clusteres, sectores, etc... Pero no podemos obtener qué controladora es la que utiliza, si es IDE, SATA, SCSI, USB, etc... y por tanto desconocemos si es removible o no.

Para saber de qué tipo de unidad se trata, consulta el siguiente hilo, dentro de nuestro foro:

http://www.hackhispano.com/foro/showthread.php?t=29373

Un saludo.

pato21
17-03-2009, 00:46
yo hice uno parecido al del enlace pero lo malo es que al ejecutarlo todo bien pero quiesiera que cuando se conecte un nuevo dispositivo aparesca en la lista y cuando se lo desconecte desaparesca he intentado con un timer pero no me sale no tendran alguna forma

Private Declare Function GetDriveType Lib "kernel32" Alias _
"GetDriveTypeA" (ByVal nDrive As String) As Long
Private Sub lista()
Dim NumDisco As Integer, letradisco As String
Dim Tipos(0 To 6) As String

Tipos(0) = " No Instalado"
Tipos(1) = " No Instalado"
Tipos(2) = " Extraible"
Tipos(3) = " Fijo"
Tipos(4) = " Remoto"
Tipos(5) = " CDROM"
Tipos(6) = " RAMDISK"

For NumDisco = 0 To 25
letradisco = Chr(NumDisco + 65) & ":\"

senal = GetDriveType(letradisco)


If senal > 1 Then
List1.AddItem letradisco & " " & Tipos(senal)
End If
Next
End Sub

Private Sub Form_Load()
Lista
End Sub

pato21
17-03-2009, 00:54
bueno googleando encontre informacion sobre este tema que podria ser de utilidad para todos los que les interese les dejo el enlace
aunque es de otro foro

http://foro.code-makers.es/1_cm_ezine-t3059.0.html;msg15002#msg15002

hystd
17-03-2009, 02:39
Ok!

Aunque existen muchas más técnicas o metodologías a parte de las mencionadas... Lo que si es cierto es que cada una conlleva mayor o menor grado de dificultad a la hora de ser implementadas.

Por ejemplo, el caso de un bucle que compruebe el estado de las unidades de almacenammiento conectadas al sistema o una consulta al registro de windows (el cual se actualiza automáticamente tras un notificador de evento), es mucho más simple que utilizar por ejemplo un gancho del sistema (o hook), el cual será detectado por la mayoría de antivirus, a pesar de que no se trata de un virus.

Lo más fiable y que soluciona todos los problemas comentados en ese enlace que has puesto es realizar un Lower FiDO. Para el caso de dispositivos removibles, conectados al puerto USB, se trataría de interceptar los URB's que llegan del driver de bus, el cual recibe los descriptores del dispositivo por el endpoint 0 (de control) del dispositivo. Cada uno de estos descriptores posee una longitud fija e indicada por el campo bLength de dicho descriptor. Leyendo el Device Descriptor que manda al sistema operativo, podemos ver qué tipo de dispositivo USB se ha introducido en el sistema, ya sea un dispositivo de almacenamiento masivo, de interfaz humana, de video, de audio, de potencia, etc...

En cuanto a detectar cambios referidos a unidades que no son removibles, no tiene mucho sentido ¿no crees? Uno no está continuamente extrayendo el disco duro de la controladora IDE o SATA (a menos que sea clarinetista xDD). A parte que cuando hablamos de dispositivos removibles, hablamos de dispositivos que a parte de ser PnP, poseen la característica "hot plug", como es el caso de la interfaz USB.

En fin, si es por creatividad, técnicas las hay a montones, sólo depende de cual es el objetivo general del software que estes desarrollando, y del grado de complicación al que estás dispuesto a llegar para lograr ciertas metas.

Un saludo.

hystd
18-03-2009, 15:12
Por cierto, se me olvidó comentar el código que has puesto...

Como dije en el hilo que puse en ese enlace:


1er paso: Detectar unidades activas
2º paso: Guardarlas en una array
3er paso: Cada intervalo de tiempo, comprobar si las unidades activas en el instante actual han cambiado (se han añadido o quitado unidades extraibles)

Tu código no contempla ésto, es por eso por lo que al extraer la unidad no ocurre nada.
Haz una traza de tu algoritmo, despacito, contemplando que existe una unidad removible en el segundo 1 del timer, y luego haz esa misma traza cuando ya no existe esa unidad en el segundo 2 del timer.

Un saludo.

pato21
18-03-2009, 21:45
ya lo consegui con un timer que limpie la lista y vuelva a verificar las unidades

hystd
18-03-2009, 22:35
Ok! pues cierro el hilo entonces.

Un saludo