Ir al contenido


Foto

Expulsar USB o extracción segura


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

#1 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 24 septiembre 2015 - 10:20

Buenos días con todos, yo aquí de nuevo para hacerles una pequeña consulta :)

resulta que estoy buscando la forma de como poder expulsar con código una memoria usb (sean pendrives, memory stick, lector de memorias, disco duros usb, etc)

 

de momento con este código (sacado de una web) me funciona para todos los USB menos para discos duros externos, les adjunto el código completo:


php
  1. USES
  2. windows, shellapi
  3. -------
  4.  
  5. function OpenVolume(ADrive: char): THandle;
  6. var
  7.   RootName, VolumeName: string;
  8.   AccessFlags: DWORD;
  9. begin
  10.   RootName := ADrive + ':\'; (* '\'' // keep SO syntax highlighting working *)
  11.   case GetDriveType(PChar(RootName)) of
  12.     DRIVE_REMOVABLE:
  13.       AccessFlags := GENERIC_READ or GENERIC_WRITE;
  14.     DRIVE_CDROM:
  15.       AccessFlags := GENERIC_READ;
  16.   else
  17.     Result := INVALID_HANDLE_VALUE;
  18.     exit;
  19.   end;
  20.   VolumeName := Format('\\.\%s:', [ADrive]);
  21.   Result := CreateFile(PChar(VolumeName), AccessFlags,
  22.     FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  23.   if Result = INVALID_HANDLE_VALUE then
  24.     RaiseLastWin32Error;
  25.  
  26. function LockVolume(AVolumeHandle: THandle): boolean;
  27. const
  28.   LOCK_TIMEOUT = 10 * 1000; // 10 Seconds
  29.   LOCK_RETRIES = 20;
  30.   LOCK_SLEEP = LOCK_TIMEOUT div LOCK_RETRIES;
  31.  
  32. // #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
  33.   FSCTL_LOCK_VOLUME = (9 shl 16) or (0 shl 14) or (6 shl 2) or 0;
  34. var
  35.   Retries: integer;
  36.   BytesReturned: Cardinal;
  37. begin
  38.   for Retries := 1 to LOCK_RETRIES do begin
  39.     Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, nil, 0,
  40.       nil, 0, BytesReturned, nil);
  41.     if Result then
  42.       break;
  43.     Sleep(LOCK_SLEEP);
  44.   end;
  45.  
  46. function DismountVolume(AVolumeHandle: THandle): boolean;
  47. const
  48. // #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
  49.   FSCTL_DISMOUNT_VOLUME = (9 shl 16) or (0 shl 14) or (8 shl 2) or 0;
  50. var
  51.   BytesReturned: Cardinal;
  52. begin
  53.   Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, nil, 0,
  54.     nil, 0, BytesReturned, nil);
  55.   if not Result then
  56.     RaiseLastWin32Error;
  57.  
  58. function PreventRemovalOfVolume(AVolumeHandle: THandle;
  59.   APreventRemoval: boolean): boolean;
  60. const
  61. // #define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
  62.   IOCTL_STORAGE_MEDIA_REMOVAL = ($2d shl 16) or (1 shl 14) or ($201 shl 2) or 0;
  63. type
  64.   TPreventMediaRemoval = record
  65.     PreventMediaRemoval: BOOL;
  66.   end;
  67. var
  68.   BytesReturned: Cardinal;
  69.   PMRBuffer: TPreventMediaRemoval;
  70. begin
  71.   PMRBuffer.PreventMediaRemoval := APreventRemoval;
  72.   Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL,
  73.     @PMRBuffer, SizeOf(TPreventMediaRemoval), nil, 0, BytesReturned, nil);
  74.   if not Result then
  75.     RaiseLastWin32Error;
  76.  
  77. function AutoEjectVolume(AVolumeHandle: THandle): boolean;
  78. const
  79. // #define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
  80.   IOCTL_STORAGE_EJECT_MEDIA = ($2d shl 16) or (1 shl 14) or ($202 shl 2) or 0;
  81. var
  82.   BytesReturned: Cardinal;
  83. begin
  84.   Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, nil, 0,
  85.     nil, 0, BytesReturned, nil);
  86.   if not Result then
  87.     RaiseLastWin32Error;
  88.  
  89. function EjectVolume(ADrive: char): boolean;
  90. var
  91.   VolumeHandle: THandle;
  92. begin
  93.   Result := FALSE;
  94.   // Open the volume
  95.   VolumeHandle := OpenVolume(ADrive);
  96.   if VolumeHandle = INVALID_HANDLE_VALUE then
  97.     exit;
  98.   try
  99.     // Lock and dismount the volume
  100.     if LockVolume(VolumeHandle) and DismountVolume(VolumeHandle) then begin
  101.       // Set prevent removal to false and eject the volume
  102.       if PreventRemovalOfVolume(VolumeHandle, FALSE) then
  103.         AutoEjectVolume(VolumeHandle);
  104.     end;
  105.   finally
  106.     // Close the volume so other processes can use the drive
  107.     CloseHandle(VolumeHandle);
  108.   end;
  109.  
  110. // Y la llamada sería
  111.  
  112. procedure TForm1.Button1Click(Sender: TObject);
  113. begin
  114.   EjectVolume('E');

.

Este código me funciona a la perfección menos para discos duros USB, por tal motivo acudo a ustedes si me pueden dar una mano, Gracias


  • 0




IP.Board spam blocked by CleanTalk.