189 lines
5.3 KiB
ObjectPascal
189 lines
5.3 KiB
ObjectPascal
unit mr.drv.usb.notifier;
|
|
|
|
interface
|
|
uses
|
|
System.Classes,
|
|
Winapi.Windows,
|
|
Winapi.Messages,
|
|
mr.drv.usb;
|
|
|
|
const
|
|
DBT_DEVTYP_DEVICEINTERFACE = $00000005; // device interface class
|
|
|
|
DBT_DEVICEARRIVAL = $8000; // system detected a new device
|
|
DBT_DEVICEQUERYREMOVE = $8001;
|
|
DBT_DEVICEQUERYREMOVEFAILED= $8002;
|
|
DBT_DEVICEREMOVEPENDING = $8003;
|
|
DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
|
|
DBT_DEVICETYPESPECIFIC = $8005;
|
|
|
|
|
|
|
|
|
|
type
|
|
TusbNotifyEvent = procedure( APath: string; ADriverClass: TUsbDriverClass) of object;
|
|
|
|
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 : char;
|
|
end;
|
|
|
|
type
|
|
TusbNotifier = class
|
|
private
|
|
fDeviceInterface : string;
|
|
fDriverClass : TUsbDriverClass;
|
|
fNotifyHandle : HDEVNOTIFY;
|
|
FWindowHandle : HWND;
|
|
|
|
FOnUSBArrival : TusbNotifyEvent;
|
|
FOnUSBRemove : TusbNotifyEvent;
|
|
|
|
procedure WndProc(var Msg: TMessage);
|
|
function USBRegister: Boolean;
|
|
|
|
protected
|
|
procedure WMDeviceChange(var Msg: TMessage); dynamic;
|
|
|
|
public
|
|
constructor Create( ADeviceInterface: string; ADriverClass: TUsbDriverClass);
|
|
destructor Destroy; override;
|
|
|
|
public
|
|
property OnUSBArrival : TusbNotifyEvent read FOnUSBArrival write FOnUSBArrival;
|
|
property OnUSBRemove : TusbNotifyEvent read FOnUSBRemove write FOnUSBRemove;
|
|
|
|
property DeviceInterface: string read fDeviceInterface;
|
|
end;
|
|
|
|
implementation
|
|
uses
|
|
Vcl.Forms,
|
|
System.SysUtils;
|
|
|
|
{ TusbNotifier }
|
|
|
|
// ================================================================================================
|
|
// constructor
|
|
//
|
|
// '{CDDE880F-898A-4DAB-B0EA-51FBA32C1D82}' [trinity.inf]
|
|
// ================================================================================================
|
|
constructor TusbNotifier.Create( ADeviceInterface: string; ADriverClass: TUsbDriverClass);
|
|
begin
|
|
inherited Create;
|
|
|
|
fDeviceInterface := ADeviceInterface;
|
|
fDriverClass := ADriverClass;
|
|
fWindowHandle := AllocateHWnd(WndProc);
|
|
|
|
UsbRegister
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// destructor
|
|
// ================================================================================================
|
|
destructor TusbNotifier.Destroy;
|
|
begin
|
|
if fNotifyHandle <> nil then
|
|
UnregisterDeviceNotification( fNotifyHandle);
|
|
|
|
DeallocateHWnd( fWindowHandle);
|
|
inherited
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// UsbRegister
|
|
// ================================================================================================
|
|
function TusbNotifier.USBRegister: Boolean;
|
|
var
|
|
dbi : DEV_BROADCAST_DEVICEINTERFACE;
|
|
size : Integer;
|
|
|
|
begin
|
|
size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
|
|
|
|
ZeroMemory(@dbi, Size);
|
|
|
|
dbi.dbcc_size := Size;
|
|
dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
|
|
dbi.dbcc_classguid := StringToGUID( fDeviceInterface);
|
|
dbi.dbcc_reserved := 0;
|
|
dbi.dbcc_name := #0;
|
|
|
|
fNotifyHandle := RegisterDeviceNotification( fWindowHandle, @dbi, DEVICE_NOTIFY_WINDOW_HANDLE);
|
|
|
|
result := fNotifyHandle <> nil
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// WndProc
|
|
// ================================================================================================
|
|
procedure TusbNotifier.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;
|
|
|
|
// ================================================================================================
|
|
// WM Device Change
|
|
// ================================================================================================
|
|
procedure TusbNotifier.WMDeviceChange(var Msg: TMessage);
|
|
var
|
|
devType : Integer;
|
|
devHdr : PDevBroadcastHdr;
|
|
|
|
begin
|
|
if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then
|
|
begin
|
|
devHdr := PDevBroadcastHdr( Msg.lParam);
|
|
devType := devHdr^.dbch_devicetype;
|
|
|
|
if devType = DBT_DEVTYP_DEVICEINTERFACE then
|
|
begin // USB Device
|
|
var x := PDevBroadcastDeviceInterface( Msg.LParam);
|
|
var p := PChar( @x.dbcc_name);
|
|
var s := '';
|
|
|
|
while p^ <> #0 do
|
|
begin
|
|
s := s + p^;
|
|
INC(p)
|
|
end;
|
|
|
|
if Msg.wParam = DBT_DEVICEARRIVAL then
|
|
begin
|
|
if Assigned( fOnUSBArrival) then
|
|
FOnUSBArrival( s, fDriverClass)
|
|
end
|
|
|
|
else begin
|
|
if Assigned( fOnUSBRemove) then
|
|
FOnUSBRemove( s, fDriverClass)
|
|
end
|
|
end
|
|
end
|
|
end;
|
|
|
|
end.
|