Программно отключить USB-флешку
От: Luzer  
Дата: 06.11.07 20:27
Оценка:
Как программно отключить флешку, чтобы исчезла иконка в трее и потухла лампочка на флешке? Максимум, что я добился, это отключение (disable, eject) устройства, при этом диск виден в проводнике, но при попытке его открытия пишет "Вставьте диск". Кто знает, как? Желательно на Builder'e, но пойдет и Delphi, и командная строка, и vbs. Блин, хоть как-нибудь... Перерыл уже весь интернет, перепробовал несколько способов.
Re: Программно отключить USB-флешку
От: Аноним  
Дата: 06.11.07 20:45
Оценка:
Здравствуйте, Luzer, Вы писали:

L>Как программно отключить флешку, чтобы исчезла иконка в трее и потухла лампочка на флешке? Максимум, что я добился, это отключение (disable, eject) устройства, при этом диск виден в проводнике, но при попытке его открытия пишет "Вставьте диск". Кто знает, как? Желательно на Builder'e, но пойдет и Delphi, и командная строка, и vbs. Блин, хоть как-нибудь... Перерыл уже весь интернет, перепробовал несколько способов.


1)Попробуй остановить службу Съемные ЗУ... но тогда все флешки перестанут работать
2)Мб перехватом ее сделать невидимой?
Re: Программно отключить USB-флешку
От: Pavel_Agurov Россия  
Дата: 15.11.07 16:20
Оценка:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    DiskName: TEdit;
    btnEject: TButton;
    Label1: TLabel;
    procedure btnEjectClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
 IOCTL_STORAGE_BASE      = $0000002d;
 FILE_READ_ACCESS        = $0001;
 FILE_ANY_ACCESS         = $0000;
 FILE_DEVICE_FILE_SYSTEM = $00000009;
 METHOD_BUFFERED         = 0;
 IOCTL_STORAGE_MEDIA_REMOVAL = IOCTL_STORAGE_BASE shl 16 or
                               FILE_READ_ACCESS shl 14 or
                               $0201 shl 2 or METHOD_BUFFERED;
 IOCTL_STORAGE_EJECT_MEDIA   = IOCTL_STORAGE_BASE shl 16 or
                               FILE_READ_ACCESS shl 14 or
                               $0202 shl 2 or METHOD_BUFFERED;

 FSCTL_LOCK_VOLUME     = FILE_DEVICE_FILE_SYSTEM shl 16 or
                         FILE_ANY_ACCESS shl 14 or
                         6 shl 2 or METHOD_BUFFERED;
 FSCTL_DISMOUNT_VOLUME = FILE_DEVICE_FILE_SYSTEM shl 16 or
                         FILE_ANY_ACCESS shl 14 or
                         8 shl 2 or METHOD_BUFFERED;

procedure TForm1.btnEjectClick(Sender: TObject);
var
 dwBytesReturned: DWord;
 hVolume: THandle;
 PMRBuffer: Bool;
 DevName : String;
begin
 // Получаем полное имя диска
 DevName:= Format('\\.\%s:', [DiskName.Text]);
 // Открываем устройство
 hVolume:= CreateFile(PChar(@DevName[1]), GENERIC_READ or GENERIC_WRITE,
               FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
 PMRBuffer := False;
 If hVolume <> INVALID_HANDLE_VALUE then try
   // Выдаем команды
   If
     DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, dwBytesReturned, nil) and
     DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0,  dwBytesReturned, nil) and
     DeviceIoControl(hVolume, IOCTL_STORAGE_MEDIA_REMOVAL, @PMRBuffer, sizeof(PMRBuffer), nil, 0, dwBytesReturned, nil) and
     DeviceIoControl(hVolume, IOCTL_STORAGE_EJECT_MEDIA, nil, 0, nil, 0, dwBytesReturned, nil)
   Then begin
      ShowMessage('Устройство успешно извлечено');
   End
   Else begin
     // Ошибка извлечения устройства
     ShowMessage(SysErrorMessage(GetLastError))
   End;  
 Finally
   // Освободить дескриптор
   CloseHandle(hVolume)
 End
 Else begin
   // Ошибка открытия устройства
   ShowMessage(SysErrorMessage(GetLastError));
 End;  
end;

end.
Re[2]: Программно отключить USB-флешку
От: Pavel_Agurov Россия  
Дата: 15.11.07 16:23
Оценка:
Книга здесь
Re[3]: Программно отключить USB-флешку
От: Luzer  
Дата: 16.11.07 20:03
Оценка:
Pavel_Agurov, спасибо. Я так пробовал, но пишет ошибку, уже не помню какую, на команду IOCTL_STORAGE_MEDIA_REMOVAL.
В итоге сделал через setupapi. Вроде работает так, как надо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.