Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.01.24;
Скачать: CL | DM;

Вниз

Как програмно остановить USB-Flash?   Найти похожие ветки 

 
Grademax   (2006-10-12 09:11) [0]

Как програмно остановить USB-Flash? Если можно, то пример на чистом KOL


 
ANTPro ©   (2006-10-12 11:23) [1]

может на апи ?


 
Grademax   (2006-10-12 11:46) [2]

Почему бы и нет? Думаю без API здесь не обойтись...


 
ANTPro ©   (2006-10-12 12:00) [3]

Вопрос. Зачем?
Средствами Выни её не всегда тормознуть :(
особенно если файловая НТФС


 
Grademax   (2006-10-12 12:28) [4]

Так получилось, что наша контора закупила 12 ПК. Комплектация у всех одинаковая (в частности здорово глючили мамы на предмет работы USB портов). Наступил момент, когда USB порт перестал опознаваться вообще. Проблема решилась перепрошивкой BIOSa, но остался неприятный глюк - при работе с любыми фрешками не загорается значек в трее "Безопасное извлечение устройства". Можно конечно переустановить OS, но придется устанавливать целую гору ПО. Да и неохота, ведь в остальном всё работает стабильно.
Решение проблемы я вижу в следующем:
1) Написать програмку (замену стандартного "Безопасного извлечения устройства") - это конечно лучше (может ещё когда сгодится для чего-нибудь)
2) Найти как эта функция включается например в реестре (если конечно там).

В общем я в поисках и буду рад любой помощи по этому вопросу...


 
Thaddy   (2006-10-12 12:57) [5]

Here"s some code, but it needs to be extended a little to handle
the foillowing WM_DEVICECHANGE messages
1. DBT_DEVICEQUERYREMOVE  // broadcast this for the device to remove
2. DBT_DEVICEQUERYREMOVEFAILED // handle this in an event handler

unit KolUsb;
// original VCL by miguel lucero
// KOL translation Thaddy de Koning
interface

uses
 Windows, Messages, Kol, Objects;

type
 PDevBroadcastHdr  = ^DEV_BROADCAST_HDR;
 DEV_BROADCAST_HDR = packed record
   dbch_size: DWORD;
   dbch_devicetype: DWORD;
   dbch_reserved: DWORD;
 end;

 PDevBroadcastDeviceInterface  = ^DEV_BROADCAST_DEVICEINTERFACE;
 DEV_BROADCAST_DEVICEINTERFACE = record
   dbcc_size: DWORD;
   dbcc_devicetype: DWORD;
   dbcc_reserved: DWORD;
   dbcc_classguid: TGUID;
   dbcc_name: short;
 end;

const
 GUID_DEVINTERFACE_USB_DEVICE: TGUID = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}";
 DBT_DEVICEARRIVAL          = $8000;
 DBT_DEVICEREMOVECOMPLETE   = $8004;
 DBT_DEVTYP_DEVICEINTERFACE = $00000005;

type

 PKolUSB = ^ TKolUSB;
 TKolUSB= object(Tobj)
 private
   FWindowHandle: HWND;
   FOnUSBArrival: TNotifyEvent;
   FOnUSBRemove: TNotifyEvent;
   procedure WndProc(var Msg: TMessage);
   function USBRegister: Boolean;
 protected
   procedure WMDeviceChange(var Msg: TMessage); dynamic;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property OnUSBArrival: TNotifyEvent read FOnUSBArrival write FOnUSBArrival;
   property OnUSBRemove: TNotifyEvent read FOnUSBRemove write FOnUSBRemove;
 end;

implementation

constructor TKolUSB.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FWindowHandle := AllocateHWnd(WndProc);
 USBRegister;
end;

destructor TKolUSB.Destroy;
begin
 DeallocateHWnd(FWindowHandle);
 inherited Destroy;
end;

procedure TKolUSB.WndProc(var Msg: TMessage);
begin
 if (Msg.Msg = WM_DEVICECHANGE) then
 begin
   try
     WMDeviceChange(Msg);
   except
     Application.HandleException(Self);
   end;
 end
 else
   Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

procedure TKolUSB.WMDeviceChange(var Msg: TMessage);
var
 devType: Integer;
 Datos: PDevBroadcastHdr;
begin
 if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then
 begin
   Datos := PDevBroadcastHdr(Msg.lParam);
   devType := Datos^.dbch_devicetype;
   if devType = DBT_DEVTYP_DEVICEINTERFACE then
   begin
     if Msg.wParam = DBT_DEVICEARRIVAL then
     begin
       if Assigned(FOnUSBArrival) then
         FOnUSBArrival(Self);
     end
     else
     begin
       if Assigned(FOnUSBRemove) then
         FOnUSBRemove(Self);
     end;
   end;
 end;
end;

function TKolUSB.USBRegister: Boolean;
var
 dbi: DEV_BROADCAST_DEVICEINTERFACE;
 Size: Integer;
 r: Pointer;
begin
 Result := False;
 Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
 ZeroMemory(@dbi, Size);
 dbi.dbcc_size := Size;
 dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
 dbi.dbcc_reserved := 0;
 dbi.dbcc_classguid  := GUID_DEVINTERFACE_USB_DEVICE;
 dbi.dbcc_name := 0;

 r := RegisterDeviceNotification(FWindowHandle, @dbi,
   DEVICE_NOTIFY_WINDOW_HANDLE
   );
 if Assigned(r) then Result := True;
end;

end.



 
Thaddy   (2006-10-12 13:02) [6]

And you have to remove Application handle exception. I was to fast translating this ;) This is better:


unit KolUsb;
// original VCL by miguel lucero
// KOL translation Thaddy de Koning
interface

uses
 Windows, Messages, Kol, Objects;

type
 PDevBroadcastHdr  = ^DEV_BROADCAST_HDR;
 DEV_BROADCAST_HDR = packed record
   dbch_size: DWORD;
   dbch_devicetype: DWORD;
   dbch_reserved: DWORD;
 end;

 PDevBroadcastDeviceInterface  = ^DEV_BROADCAST_DEVICEINTERFACE;
 DEV_BROADCAST_DEVICEINTERFACE = record
   dbcc_size: DWORD;
   dbcc_devicetype: DWORD;
   dbcc_reserved: DWORD;
   dbcc_classguid: TGUID;
   dbcc_name: short;
 end;

const
 GUID_DEVINTERFACE_USB_DEVICE: TGUID = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}";
 DBT_DEVICEARRIVAL          = $8000;
 DBT_DEVICEREMOVECOMPLETE   = $8004;
 DBT_DEVTYP_DEVICEINTERFACE = $00000005;

type

 PKolUSB = ^ TKolUSB;
 TKolUSB= object(Tobj)
 private
   FWindowHandle: HWND;
   FOnUSBArrival: TOnEvent;
   FOnUSBRemove: TOnEvent;
   procedure WndProc(var Msg: TMessage);
   function USBRegister: Boolean;
 protected
   procedure WMDeviceChange(var Msg: TMessage);
 public
   destructor Destroy; virtual;
   property OnUSBArrival: TOnEvent read FOnUSBArrival write FOnUSBArrival;
   property OnUSBRemove: TOnEvent read FOnUSBRemove write FOnUSBRemove;
 end;

function NewKolUSB:PKolUSB;

implementation

function NewKolUSB:PKolUSB;
begin
 New(Result,Create);
 Result.FWindowHandle := AllocateHWnd(Result.WndProc);
 Result.USBRegister;
end;

destructor TKolUSB.Destroy;
begin
 DeallocateHWnd(FWindowHandle);
 inherited Destroy;
end;

procedure TKolUSB.WndProc(var Msg: TMessage);
begin
 if (Msg.Msg = WM_DEVICECHANGE) then
 begin
   try
     WMDeviceChange(Msg);
   except
   end;
 end
 else
   Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

procedure TKolUSB.WMDeviceChange(var Msg: TMessage);
var
 devType: Integer;
 Datos: PDevBroadcastHdr;
begin
 if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then
 begin
   Datos := PDevBroadcastHdr(Msg.lParam);
   devType := Datos^.dbch_devicetype;
   if devType = DBT_DEVTYP_DEVICEINTERFACE then
   begin
     if Msg.wParam = DBT_DEVICEARRIVAL then
     begin
       if Assigned(FOnUSBArrival) then
         FOnUSBArrival(@Self);
     end
     else
     begin
       if Assigned(FOnUSBRemove) then
         FOnUSBRemove(@Self);
     end;
   end;
 end;
end;

function TKolUSB.USBRegister: Boolean;
var
 dbi: DEV_BROADCAST_DEVICEINTERFACE;
 Size: Integer;
 r: Pointer;
begin
 Result := False;
 Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
 ZeroMemory(@dbi, Size);
 dbi.dbcc_size := Size;
 dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
 dbi.dbcc_reserved := 0;
 dbi.dbcc_classguid  := GUID_DEVINTERFACE_USB_DEVICE;
 dbi.dbcc_name := 0;

 r := RegisterDeviceNotification(FWindowHandle, @dbi,
   DEVICE_NOTIFY_WINDOW_HANDLE
   );
 if Assigned(r) then Result := True;
end;

end.



 
[e]Bu$ter ©   (2006-10-12 13:16) [7]

Зачем тратить время? На это дело, есть куча готовых решений, вот например, пока в FAR manager не встроили эту фишку (возможность отключать сменные девайсы) я узал DevEject - http://www.heise.de/ct/03/25/links/206.shtml
// там, если я не ошибаюсь, да же сорцы прилагаюстся, только на С++


 
AndreyRus   (2006-10-12 15:52) [8]


program USBEject;

uses
Windows;

const
setupapi = "SetupApi.dll";

type
HDEVINFO = THandle;

PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;
SP_DEVINFO_DATA = packed record
cbSize: DWORD;
ClassGuid: TGUID;
DevInst: DWORD;
Reserved: DWORD;
end;

function SetupDiGetClassDevsA(ClassGuid: PGUID; Enumerator: PChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external setupapi;
function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; DeviceInfoData: PSP_DEVINFO_DATA): boolean; stdcall; external setupapi;
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): boolean; stdcall; external setupapi;
function CM_Get_Parent(pdnDevInst: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Get_Device_ID_Size(pulLen: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Get_Device_IDA(dnDevInst: DWORD; Buffer: PChar; BufferLen: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Locate_DevNodeA(pdnDevInst: PDWORD; pDeviceID: PChar; ulFlags: DWORD): DWORD; stdcall; external setupapi;
function CM_Request_Device_EjectA(dnDevInst: DWORD; pVetoType: Pointer; pszVetoName: PChar; ulNameLength: DWORD;
ulFlags: DWORD): DWORD; stdcall; external setupapi;

function IsUSBDevice(DevInst: DWORD): boolean;
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;
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_IDA(DevInst, ID, IDLen, 0) <> 0) or (not CompareMem(ID, PChar("USBSTOR"), 7)) then
begin
 FreeMemory(ID);
 exit;
end;
FreeMemory(ID);
result := true;
end;

procedure EjectUSB();
const
GUID_DEVCLASS_DISKDRIVE: TGUID = (D1: $4D36E967; D2: $E325; D3: $11CE; D4: ($BF, $C1, $08, $00, $2B, $E1, $03, $18));
var
hDevInfoSet: HDEVINFO;
DevInfo: SP_DEVINFO_DATA;
i: Integer;
Parent: DWORD;
VetoName: PChar;
begin
DevInfo.cbSize := sizeof(SP_DEVINFO_DATA);
hDevInfoSet := SetupDiGetClassDevsA(@GUID_DEVCLASS_DISKDRIVE, nil, 0, 2);
if hDevInfoSet = INVALID_HANDLE_VALUE then exit;
i := 0;
while (SetupDiEnumDeviceInfo(hDevInfoSet, i, @DevInfo)) do
begin
 if (IsUSBDevice(DevInfo.DevInst)) and (CM_Get_Parent(@Parent, DevInfo.DevInst, 0) = 0) then
  begin
   VetoName := GetMemory(260);
   if (CM_Request_Device_EjectA(Parent, nil, VetoName, 260, 0) <> 0) then
    begin
     if (CM_Locate_DevNodeA(@Parent, VetoName, 0) <> 0) then
      begin
       FreeMemory(VetoName);
       continue;
      end;
     FreeMemory(VetoName);
     if (CM_Request_Device_EjectA(Parent, nil, nil, 0, 0) <> 0) then continue;
    end;
   FreeMemory(VetoName);
   break;
  end;
 inc(i);
end;
SetupDiDestroyDeviceInfoList(hDevInfoSet);
end;

begin
if MessageBoxA(0, "Вы действительно хотите извлечь USB-диск?", "Подтверждение", MB_YESNO) = ID_YES then
EjectUSB();
end.


 
Grademax   (2006-10-13 05:17) [9]

Спасибо за помощь! Всё работает как часы! Проверял!


 
Doom-2   (2007-05-10 13:29) [10]

А конкретное как? D: F: ...


 
DVK   (2007-05-14 07:21) [11]

Как остановить USB Flash понятно. А может кто знает, как заставить Windows снова обнаружить USB устройство, если оно было только программно извлечено из компьютера, а физически не извлекалось, то есть "пересканировать" USB-устройства?


 
ANTPro ©   (2007-05-14 14:13) [12]

> [11] DVK   (14.05.07 07:21)

Так лень флешку вытащить? : )


 
DVK   (2007-05-16 12:28) [13]

Да нет, не в этом дело, хотя и лень тоже:)
Я написал программу для проверки правильности записи информации на USB флэшку. Но вот только сразу после записи файлов на флэш их проверять нельзя, поскольку Winows как-то кэширует информацию, и вместо реального чтения с USB устройства подсовывает данные из своего кэша. Необходимо извлечь устройство, а затем снова вставить его в компьютер. Мне захотелось сделать это программно. Извлечь удалось, а вот снова "Вставить" - нет.


 
Thaddy   (2007-05-16 12:34) [14]

My code detects USB insert.


 
AndreyRus   (2007-05-16 12:34) [15]

Use google. "Rescan SetupApi".


 
DVK   (2007-05-17 15:31) [16]

2AndreyRus
Спасибо, решил использовать devcon.exe restart usb\*


 
Daemvil ©   (2007-08-20 16:18) [17]

Так как же сделать так, чтобы можно было вытаскивать флеш-диск, зная только его букву?...


 
Andrey_rus ©   (2007-08-20 16:58) [18]

А причем здесь KOL? Итак ветка не по теме!


 
CraZy_MaTH   (2007-08-26 02:49) [19]

нашел программку, при запуске её с флешки закрывает все программы и вытаскивает флешку безопасно.
http://code.google.com/p/pr-safe-eject/


 
имя   (2007-09-17 22:47) [20]

Удалено модератором


 
имя   (2007-12-01 02:45) [21]

Удалено модератором


 
имя   (2008-05-12 15:54) [22]

Удалено модератором



Страницы: 1 вся ветка

Текущий архив: 2010.01.24;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.008 c
1-1233798973
ply
2009-02-05 04:56
2010.01.24
Разная процедура для каждой формы.. как?


2-1259921265
Alexxx
2009-12-04 13:07
2010.01.24
indy &amp; 503


1-1230566193
alek_1
2008-12-29 18:56
2010.01.24
Rave Report проблема с кирилицей в ПДФ


15-1258368049
stas
2009-11-16 13:40
2010.01.24
TWebBrowser


15-1258407522
K-one
2009-11-17 00:38
2010.01.24
Const Массив