Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.07.2017, 09:55   #1
vladimir412
Пользователь
 
Регистрация: 04.01.2014
Сообщений: 18
По умолчанию Безопасное извлечение в Dilphi

Здравствуйте!
Есть программа в Dilphi для безопасного извлечения флешки, как ее можно переделать чтоб она извлекала только одну конкретную флешку?
Заранее спасибо!
Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    LogMemo: TMemo;
    Button3: TButton;
    Label1: TLabel;
    DrivesListBox: TListBox;
    Button7: TButton;
    Label3: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
  private
    { Private declarations }
  public   
    procedure OnDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}  



function GetDeviceName(PnPHandle: HDEVINFO; const DevData: TSPDevInfoData): string;
var
  BytesReturned: DWORD;
  RegDataType: DWORD;
  Buffer: array [0..256] of CHAR;
begin
  BytesReturned := 0;
  RegDataType := 0;
  Buffer[0] := #0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_FRIENDLYNAME,
    RegDataType, PByte(@Buffer[0]), SizeOf(Buffer), BytesReturned);
  Result := Buffer;
  if Result<>'' then exit;
  BytesReturned := 0;
  RegDataType := 0;
  Buffer[0] := #0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_DEVICEDESC,
    RegDataType, PByte(@Buffer[0]), SizeOf(Buffer), BytesReturned);
  Result:=Buffer;
end;

function DWORDtoDiskNames(val:DWORD):string;
var
  _i: integer;
begin
  Result:='';
  for _i := 0 to 25 do
   begin
    if ((val mod 2)=1) then Result:=result+ chr(_i + 65);
    val:=val shr 1;
   end;
end;

procedure TForm1.OnDeviceChange(var Msg: TMessage);
var
  MSGSTR:String;
begin
  if Msg.WParam=DBT_DEVICEARRIVAL then
   begin
    case PDEV_BROADCAST_HDR(Msg.LParam)^.dbch_devicetype of
     DBT_DEVTYP_DEVICEINTERFACE:
      LogMemo.Lines.Add('вставлен новый интерфейс: '+pchar(@PDEV_BROADCAST_DEVICEINTERFACE(Msg.LParam)^.dbcc_name[0])); 
    DBT_DEVTYP_VOLUME:
     begin
      MSGSTR:='новый диск'+MSGSTR;
      LogMemo.Lines.Add(MSGSTR+' '+DWORDtoDiskNames(PDEV_BROADCAST_VOLUME(Msg.LParam)^.dbcv_unitmask)+':');
     end;
    end;
   end;
  if Msg.WParam=DBT_DEVICEREMOVECOMPLETE then
   begin
    case PDEV_BROADCAST_HDR(Msg.LParam)^.dbch_devicetype of
     DBT_DEVTYP_DEVICEINTERFACE:
      LogMemo.Lines.Add('извлечён интерфейс: '+pchar(@PDEV_BROADCAST_DEVICEINTERFACE(Msg.LParam)^.dbcc_name[0]));
     DBT_DEVTYP_VOLUME:
      begin
       MSGSTR:='извлечён диск'+MSGSTR;
       LogMemo.Lines.Add(MSGSTR+' '+DWORDtoDiskNames(PDEV_BROADCAST_VOLUME(Msg.LParam)^.dbcv_unitmask)+':');
      end;
    end;
   end;
 if Msg.WParam=DBT_DEVNODES_CHANGED then
  begin
   LogMemo.Lines.Add('конфигурация изменена');
  end;
  Button6Click(nil);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  NF:TDEV_BROADCAST_DEVICEINTERFACE;
begin
  LogMemo.Clear;
  NF.dbcc_size:=sizeof(TDEV_BROADCAST_DEVICEINTERFACE);
  NF.dbcc_devicetype:=DBT_DEVTYP_DEVICEINTERFACE;
  RegisterDeviceNotification(Handle,@NF,DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 LogMemo.Clear;
end;

function CompareMem(p1, p2: Pointer; len: DWORD): boolean;
var
  i: DWORD;
begin
  result := false;
  if len = 0 then exit;
  for i := 0 to len-1 do
   if PByte(DWORD(p1) + i)^ <> PByte(DWORD(p2) + i)^ then exit;
  result := true;
end;

function IsUSBDevice(DevInst: DWORD): boolean;  
var
  IDLen: DWORD;
  ID: PChar;
begin
  result := false;
  if (CM_Get_Device_ID_Size(IDLen, DevInst, 0) <> 0) or (IDLen = 0) then exit;
  inc(IDLen);
  ID := GetMemory(IDLen);
  if ID = nil then exit;
  if (CM_Get_Device_ID(DevInst, ID, IDLen, 0) <> 0) or (not CompareMem(ID, PChar('USBSTOR'), 7)) then
   begin
    FreeMemory(ID);
    exit;
   end;
  FreeMemory(ID);
  result := true;
end;

procedure RemoveDrive(index:integer);
var
  DrivesPnPHandle: HDEVINFO;
  DevInfo: SP_DEVINFO_DATA;
  Parent: DWORD;
  VetoName:array[0..MAX_PATH] of char;
begin
  DevInfo.cbSize := sizeof(SP_DEVINFO_DATA);
  DrivesPnPHandle := SetupDiGetClassDevsA(@GUID_DEVCLASS_DISKDRIVE, nil, 0, 2);
  if DrivesPnPHandle = INVALID_HANDLE_VALUE then exit;
  if SetupDiEnumDeviceInfo(DrivesPnPHandle, index, DevInfo) then
   begin
    if (IsUSBDevice(DevInfo.DevInst)) and (CM_Get_Parent(Parent, DevInfo.DevInst, 0) = CR_SUCCESS)
     then
      begin
       CM_Request_Device_Eject(Parent, nil, @VetoName, MAX_PATH, 0);
       if VetoName='' then
        ShowMessage('Устройство может быть извлечено')
                      else
        ShowMessage('Устройство не может быть извлечено');
      end
     else
      ShowMessage('Это не USB устройство');
   end;
  SetupDiDestroyDeviceInfoList(DrivesPnPHandle);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Button6Click(nil);
end;

procedure TForm1.Button6Click(Sender: TObject);
var
  DrivePnPHandle: HDEVINFO;
  DeviceNumber:DWORD;
  DevData: TSPDevInfoData;
  DeviceInterfaceData: TSPDeviceInterfaceData;
  RES:BOOL;
begin
  DrivesListBox.Clear;
  DrivePnPHandle := SetupDiGetClassDevs(@GUID_DEVCLASS_DISKDRIVE, nil, 0, DIGCF_PRESENT);
  if DrivePnPHandle = INVALID_HANDLE_VALUE then  Exit;
  DeviceNumber := 0;
  repeat
   DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
   DevData.cbSize := SizeOf(TSPDevInfoData);
   RES := SetupDiEnumDeviceInfo(DrivePnPHandle, DeviceNumber, DevData);
   if (RES) then
    begin
     DrivesListBox.Items.Add(GetDeviceName(DrivePnPHandle, DevData));
     Inc(DeviceNumber);
    end;
  until not RES;
  SetupDiDestroyDeviceInfoList(DrivePnPHandle);
  DrivesListBox.Enabled:=true;
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
  if DrivesListBox.ItemIndex<0 then exit;
  RemoveDrive(DrivesListBox.ItemIndex);
  DrivesListBox.Clear;
  DrivesListBox.Enabled:=false;
  Button6Click(nil);
end;

end.
vladimir412 вне форума Ответить с цитированием
Старый 29.07.2017, 10:19   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,706
По умолчанию

Так оно и извлекает выбранную флешку.
p51x вне форума Ответить с цитированием
Старый 29.07.2017, 11:08   #3
vladimir412
Пользователь
 
Регистрация: 04.01.2014
Сообщений: 18
По умолчанию

при помощи индивидуального идентификатора который имеет каждое устройство
vladimir412 вне форума Ответить с цитированием
Старый 29.07.2017, 11:18   #4
vladimir412
Пользователь
 
Регистрация: 04.01.2014
Сообщений: 18
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Так оно и извлекает выбранную флешку.
оно извлекает избранную флешку, а должно извлекать только одну конкретную, прописанную в коде программы
vladimir412 вне форума Ответить с цитированием
Старый 29.07.2017, 11:45   #5
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,706
По умолчанию

Ну и в чем проблема? У вас есть получение всех флешек, получение имени флешки, извлечение конкретной флешки... соберите конструктор.
p51x вне форума Ответить с цитированием
Старый 29.07.2017, 11:50   #6
vladimir412
Пользователь
 
Регистрация: 04.01.2014
Сообщений: 18
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Ну и в чем проблема? У вас есть получение всех флешек, получение имени флешки, извлечение конкретной флешки... соберите конструктор.
я не знаю как и куда вписать идентификатор
vladimir412 вне форума Ответить с цитированием
Старый 29.07.2017, 16:08   #7
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

USB Disk Ejector (open source)
Цитата:
The command line options are very flexible, they can be used to:
  • Eject the drive that the program is running from.
  • Eject a drive by specifying a drive letter.
  • Eject a drive by specifying a drive name.
  • Eject a drive by specifying a mountpoint
  • Eject a drive by specifying a partial drive name.
Filka вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
безопасное извлечение флешки Лонли-Локли Общие вопросы Delphi 4 22.02.2022 23:06
безопасное извлечение флэшки. vladimir412 Паскаль, Turbo Pascal, PascalABC.NET 7 08.12.2014 15:00
Безопасное извлечение флешки Janger Общие вопросы Delphi 7 16.10.2014 08:41
Безопасное извлечение устройства Xardas Компьютерное железо 7 28.02.2011 00:49
Безопасное извлечение SunKnight Win Api 1 12.01.2008 02:06