Ir al contenido


Foto

Extracción segura de dispositivos USB


  • Por favor identifícate para responder
5 respuestas en este tema

#1 cHackAll

cHackAll

    Advanced Member

  • Administrador
  • 599 mensajes

Escrito 26 mayo 2009 - 10:22

El tema es muy buscado y poco documentado; por lo cual escribo la unidad Ejector que en su primera versión tiene la siguiente interfaz;



delphi
  1. // . . .
  2.  
  3. // retorna un mensaje de la libreria dinamica "hotplug"
  4. function usbGetMessage(uID: Cardinal; lpString: PChar): string;
  5.  
  6. // retorna la serie (física) de un dispositivo USB
  7. function usbGetSerial(Drive: Char; var SerialNumber: ShortString): LongBool;
  8.  
  9. // intenta expulsar un dispositivo en forma segura
  10. function usbTryEject(Drive: Char): LongBool;
  11.  
  12. // enumera todos los archivos/carpetas abiertos de una unidad
  13. function usbEnumUses(Drive: Char; Callback: TCallback; Param: Pointer = nil): Integer;
  14.  
  15. // . . .



Un ejemplo de su modo de uso;



delphi
  1. // . . .
  2.  
  3. uses Ejector;
  4.  
  5. function Enumerator(dwProcessId: Cardinal; lpObject, lpProcessName, lpList: PChar): LongBool; stdcall;
  6. begin
  7. PString(lpList)^ := PString(lpList)^ + #13' - ' + lpProcessName + '(' + IntToStr(dwProcessId) + ') - "' + lpObject + '"';
  8. Result := True;
  9. end;
  10.  
  11. procedure TForm1.Button1Click(Sender: TObject);
  12. var
  13. List: string;
  14. Count: Integer;
  15. Serial: ShortString;
  16. begin
  17. Button1.Enabled := False;                    // lock button...
  18.  
  19. List := usbGetMessage(1206, 'H:') + #13;      // get "unstopable" message
  20. Count := usbEnumUses('H', Enumerator, @List); // enumerate opened handles
  21. if (Count = -1) or not usbGetSerial('H', Serial) then // get "real" serial of device
  22.   MessageBox(Handle, PChar(usbGetMessage(1003, nil)), PChar(Application.Title), MB_ICONERROR)
  23. else
  24.   if Count > 0 then
  25.   MessageBox(Handle, PChar(List), nil, MB_ICONEXCLAMATION) // show opened objects
  26.   else
  27.   if MessageBox(Handle, PChar('Estás seguro de expulsar la unidad "' + Serial + '" ?'), PChar(Application.Title), MB_ICONQUESTION or MB_YESNO) = ID_YES then
  28.     if not usbTryEject('H') then  // try to eject it...
  29.     MessageBox(Handle, PChar(usbGetMessage(2257, 'H:')), nil, MB_ICONERROR)
  30.     else
  31.     MessageBox(Handle, PChar(usbGetMessage(2260, 'H:')), nil, MB_ICONINFORMATION);
  32.  
  33. Button1.Enabled := True;
  34. end;
  35.  
  36. // . . .



La función más inestable del código es usbEnumUses que utiliza un par de APIs no documentadas, utilizadas por el S.O. y sujetas a cambios, sin embargo dicha función habrá de cambiar según se encuentren alternativas optimas y con sus comentarios.

Enjoy!
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 26 mayo 2009 - 10:31

Hola Little Bro

Muy interesante tu code. (y)

Algunas veces me ha pasado que por alguna razón "desconocida" he querido desconectar mi USB y me muestra una pantalla de aviso que no es posible desconectar el dispositivo, esto con el ya conocido (Remover Hardware con seguridad) ¿este proceso "obliga" a windows desconectarlo?

Salud OS
  • 0

#3 cHackAll

cHackAll

    Advanced Member

  • Administrador
  • 599 mensajes

Escrito 26 mayo 2009 - 10:38

Algunas veces me ha pasado que por alguna razón "desconocida" he querido desconectar mi USB y me muestra una pantalla de aviso que no es posible desconectar el dispositivo, esto con el ya conocido (Remover Hardware con seguridad) ¿este proceso "obliga" a windows desconectarlo?


Existen varios motivos para que no puedas remover un dispositivo fí­sico USB, sin embargo la mas comun es que dicho dispositivo esta siendo utilizado por algun proceso; digamos que en el "Flash" tienes un programa, y lo corres... posteriormente lo intentas remover; esto no sera posible porque existen objetos que estan abiertos en el Flash (CurrentPath, exe, etc.), es el mismo caso si en el Flash tienes un virus y sin saberlo lo ejecutas.

Es por ello que implementé la funcion usbEnumUses. Para poder saber qué programas estan utilizando qué cosas en un Flash. No se puede forzar la extracción a pesar que se finalicen los procesos que lo utilizan o en su defecto si se anulan los manejadores de los objetos abiertos... pero este es un tema mas complejo.

Salud!
  • 0

#4 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 26 mayo 2009 - 04:45

Muy buen aporte, cHackAll.
Interesante el uso de la librerí­a hotplug.dll para la extracción segura del dispositivo.

Para documentar con un poco de teorí­a dejo este interesante artí­culo:
"How To Ejecting Removable Media in Windows NT/Windows 2000/Windows XP"

En definitiva es una buena unidad que sin duda nos ayudará a muchos.  (y)

Saludos.
  • 0

#5 cHackAll

cHackAll

    Advanced Member

  • Administrador
  • 599 mensajes

Escrito 28 mayo 2009 - 09:03

...Para documentar con un poco de teorí­a dejo este interesante artí­culo...


Solo me queda comentar la sencillez del codigo demostrado en el artí­culo que nos facilitas; me he percatado que el mismo realiza una extracción como si se tratara de la expulsión de un CD, y éste es el sistema utilizado por Windows 9x y Vista +. La extracción eléctrica solo está presente en Windows XP.

Salud!
  • 0

#6 V3ct0r

V3ct0r

    Member

  • Miembros
  • PipPip
  • 16 mensajes
  • LocationVenezuela

Escrito 15 septiembre 2009 - 08:35

Exelente el aporte voy a probarlos para ver que tal funciona
  • 0




IP.Board spam blocked by CleanTalk.