unit Unitcomlister;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, JwaWinType, SetupApi, Cfg, CfgMgr32, StdCtrls;
var
Portliste:TStringlist;
procedure FindComports(
var Astringlist:TStringlist;AuchVirtuell:Boolean;Bis:Integer);
implementation
// Delphi wrapper for CM_Get_Device_ID
function GetDeviceID(Inst: DEVINST):
string;
var
Buffer: PTSTR;
Size: ULONG;
begin
CM_Get_Device_ID_Size(Size, Inst, 0);
// Required! See DDK help for CM_Get_Device_ID
Inc(Size);
Buffer := AllocMem(Size * SizeOf(TCHAR));
CM_Get_Device_ID(Inst, Buffer, Size, 0);
Result := Buffer;
FreeMem(Buffer);
end;
// Delphi wrapper for SetupDiGetDeviceRegistryProperty
function GetRegistryPropertyString(PnPHandle: HDEVINFO;
const DevData: TSPDevInfoData; Prop: DWORD):
string;
var
BytesReturned: DWORD;
RegDataType: DWORD;
Buffer:
array [0..1023]
of TCHAR;
begin
BytesReturned := 0;
RegDataType := 0;
Buffer[0] := #0;
SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop,
RegDataType, PByte(@Buffer[0]), SizeOf(Buffer), BytesReturned);
Result := Buffer;
end;
function ExtractBus(DeviceID:
string):
string;
begin
Result := Copy(DeviceID, 1, Pos('
\', DeviceID) - 1);
end;
procedure FindComports(
var Astringlist:TStringlist);
const
GUID_DEVINTERFACE_COMPORT: TGUID = '
{86e0d1e0-8089-11d0-9ce4-08003e301f73}';
GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR: TGUID = '
{4D36E978-E325-11CE-BFC1-08002BE10318}';
var
PnPHandle: HDEVINFO;
DevData: TSPDevInfoData;
DeviceInterfaceData: TSPDeviceInterfaceData;
FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
Success: LongBool;
Devn: Integer;
BytesReturned: DWORD;
SerialGUID: TGUID;
Inst: DEVINST;
RegKey: HKEY;
RegBuffer:
array [0..1023]
of Char;
RegSize, RegType: DWORD;
FriendlyName:
string;
PortName:
string;
DeviceDescription:
string;
Bus:
string;
TestHandle : integer;
i:integer;
begin
// these API conversions are loaded dynamically by default
LoadSetupApi;
LoadConfigManagerApi;
// enumerate all serial devices (COM port devices)
SerialGUID := GUID_DEVINTERFACE_COMPORT;
// GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR;
PnPHandle := SetupDiGetClassDevs(@SerialGUID,
nil, 0, DIGCF_PRESENT
or DIGCF_DEVICEINTERFACE);
if PnPHandle = Pointer(INVALID_HANDLE_VALUE)
then
Exit;
Devn := 0;
repeat
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
Success := SetupDiEnumDeviceInterfaces(PnPHandle,
nil, SerialGUID, Devn, DeviceInterfaceData);
if Success
then
begin
DevData.cbSize := SizeOf(DevData);
BytesReturned := 0;
// get size required for call
SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData,
nil, 0, BytesReturned, @DevData);
if (BytesReturned <> 0)
and (GetLastError = ERROR_INSUFFICIENT_BUFFER)
then
begin
// allocate buffer and initialize it for call
FunctionClassDeviceData := AllocMem(BytesReturned);
FunctionClassDeviceData.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData,
FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData)
then
begin
// gives the friendly name of the device as shown in Device Manager
FriendlyName := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_FRIENDLYNAME);
// gives a device description
DeviceDescription := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_DEVICEDESC);
// now try to get the assigned COM port name
RegKey := SetupDiOpenDevRegKey(PnPHandle, DevData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
RegType := REG_SZ;
RegSize := SizeOf(RegBuffer);
RegQueryValueEx(RegKey, '
PortName',
nil, @RegType, @RegBuffer[0], @RegSize);
RegCloseKey(RegKey);
PortName := RegBuffer;
Inst := DevData.DevInst;
CM_Get_Parent(Inst, Inst, 0);
Bus := ExtractBus(GetDeviceID(Inst));
Astringlist.Add(PortName + '
(' + DeviceDescription + '
, ' + Bus+'
)');
end;
FreeMem(FunctionClassDeviceData);
end;
end;
Inc(Devn);
until not Success;
SetupDiDestroyDeviceInfoList(PnPHandle);
for I := 0
to Astringlist.Count - 1
do
Portliste.Add(Astringlist[i]);
// unload API conversions
UnloadSetupApi;
UnloadConfigManagerApi;
end;
initialization
Portliste:=TStringlist.Create;
finalization
portliste.Free;
end.