Rework
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
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.
|
||||
Reference in New Issue
Block a user