Search code examples
delphiwinapidelphi-xewpd

Device Interface Events, Get Device Name


Based on this blog post, I've written some code to detect USB devices:

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

.
.
.

procedure TUsbClass.RegisterUsbHandler;
var rDbi : DEV_BROADCAST_DEVICEINTERFACE;
    iSize : integer;
begin
  iSize := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
  ZeroMemory(@rDbi,iSize);
  rDbi.dbcc_size := iSize;
  rDbi.dbcc_devicetype := USB_INTERFACE;
  rDbi.dbcc_reserved := 0;
  rDbi.dbcc_classguid  := GUID_DEVINTF_USB_DEVICE;
  rDbi.dbcc_name := #0;
  RegisterDeviceNotification(FHandle,@rDbi,DEVICE_NOTIFY_WINDOW_HANDLE);
end;

procedure TUsbClass.WMDeviceChange(var AMessage : TMessage);
var iDevType : integer;
    sDevString,sDevType,
    sDriverName,sFriendlyName : string;
    pData : PDevBroadcastDeviceInterface;
    pVol : PDEV_BROADCAST_VOLUME;
begin
  if (AMessage.wParam = USB_INSERTION) or
     (AMessage.wParam = USB_REMOVAL) then begin
    pData := PDevBroadcastDeviceInterface(AMessage.LParam);
    iDevType := pData^.dbcc_devicetype;

    if iDevType = USB_VOLUME then
      if Assigned(FOnDevVolumeEvent) then begin
        ...
      end
      else
    else
    // Is it a USB Interface Device ?
    if iDevType = USB_INTERFACE then begin
      sDevString := PChar(@pData^.dbcc_name);
      ...
    end;
  end;
end;

Everything works fine and I do receive events when a USB device is inserted, but the problem is that sDevString is always an empty string. I've also tried detecting WPD devices (by setting rDbi.dbcc_classguid to proper GUID value) and it works fine, except I always get an empty string for sDevString. How can I get the correct device name?


Solution

  • The code in the article that you link works correctly, when added to a clean project. When a USB device, e.g. a flash drive is inserted, the value assigned to sDevString is not empty, and contains the correct device string.

    I can only imagine that there is some extra code that you have not shown that is confusing matters.

    I suggest that you use the code from the article verbatim. Copy and paste the entire unit. The author of that article has done a good job of making it easy for you to use the code. You simply use that unit directly, there is no need for you to make any changes.

    Should you desire to adapt the code, you may do so. But once you've convinced yourself that the code as supplied works, you'll know that it is your changes that are responsible for any failures.