Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "KOL";
Текущий архив: 2010.01.24;
Скачать: [xml.tar.bz2];

Вниз

Как програмно остановить 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 вся ветка

Форум: "KOL";
Текущий архив: 2010.01.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.012 c
2-1259405265
Студент_ПИ
2009-11-28 13:47
2010.01.24
Информатика. Задача на кол-во информации.


15-1258538079
Palladin
2009-11-18 12:54
2010.01.24
Семь раз отмерь, один раз отрежь.


15-1258645461
И. Павел
2009-11-19 18:44
2010.01.24
Кпоблема с кодировками


2-1259855245
Bellf
2009-12-03 18:47
2010.01.24
Тип данных TXSDecimal


8-1202652073
nuflin
2008-02-10 17:01
2010.01.24
вопрос по графике





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский