Из параметров сообщения можно узнать воткнули или выдернули. Вот пример кода для Delphi:
type
 PDEV_BROADCAST_HDR = ^TDEV_BROADCAST_HDR;
 TDEV_BROADCAST_HDR = record
  dbch_size,
  dbch_devicetype,
  dbch_reserved: DWORD;
 end;
 PDEV_BROADCAST_PORT = ^TDEV_BROADCAST_PORT;
 TDEV_BROADCAST_PORT = record
  dbcp_size,
  dbcp_devicetype,
  dbcp_reserved: DWORD;
  dbcp_name: array[0..0] of char;
 end;
const
 DBT_CONFIGCHANGED = $0018;
 DBT_DEVICEREMOVECOMPLETE = $8004;
 DBT_DEVTYP_PORT = 3;
procedure TForm1.OnDeviceChange(var Msg: TMessage);
var s: string;
begin
 if (Msg.WParam = DBT_DEVICEREMOVECOMPLETE) and
    (PDEV_BROADCAST_HDR(Msg.LParam)^.dbch_devicetype = DBT_DEVTYP_PORT) then
  begin
   s:= pchar(@PDEV_BROADCAST_PORT(Msg.LParam)^.dbcp_name[0]);
   if s = ComPort.Port then ComPort.CloseCom;
  end;
end;