procedure EnumerateCOMPorts(ComList: TStrings);
const
GUID_DEVINTERFACE_COMPORT:TGUID='{86E0D1E0-8089-11D0-9CE4-08003E301F73}';
var
cbRequired : DWORD;
hdev : HDEVINFO;
idev : Integer;
did : TSPDeviceInterfaceData;
pdidd : PSPDeviceInterfaceDetailData;
s : string;
PropertyBuffer : array[0..255] of Char;
DeviceInfoData : TSPDevInfoData;
PropertyRegDataType : DWORD;
RequiredSize : DWORD;
Key : HKEY;
PortName : string;
RegType,Count : DWORD;
begin
// enumerate the com ports
LoadSetupApi;
hdev := SetupDiGetClassDevs(@GUID_DEVINTERFACE_COMPORT, nil, 0, DIGCF_PRESENT OR DIGCF_DEVICEINTERFACE);
if (INVALID_HANDLE_VALUE<> THandle(hdev)) then
begin
try
idev:=0;
ZeroMemory(@did, SizeOf(did));
did.cbSize := SizeOf(did);
repeat
if (SetupDiEnumDeviceInterfaces(hdev, nil, GUID_DEVINTERFACE_COMPORT, idev, did)) then
begin
cbRequired := 0;
SetupDiGetDeviceInterfaceDetail(hdev, @did, nil, 0, cbRequired, nil);
if (ERROR_INSUFFICIENT_BUFFER= GetLastError()) then
begin
pdidd:=AllocMem(cbRequired);
try
pdidd^.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
DeviceInfoData.cbSize:= SizeOf(DeviceInfoData);
RequiredSize:=0;
if (SetupDiGetDeviceInterfaceDetail(hdev, @did, pdidd, cbRequired, RequiredSize, @DeviceInfoData)) then
begin
PropertyRegDataType:=0;
RequiredSize:=0;
s:='';
{
if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_FRIENDLYNAME, PropertyRegDataType, PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then
begin
s:=s+PropertyBuffer;
end;
s:=s+DefaultFormatSettings.ListSeparator;
if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_DEVICEDESC, PropertyRegDataType, PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then
begin
s:=s+PropertyBuffer;
end;
s:=s+DefaultFormatSettings.ListSeparator;
if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_MFG, PropertyRegDataType, PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then
begin
s:=s+PropertyBuffer;
end;
s:=s+DefaultFormatSettings.ListSeparator;
}
Key := SetupDiOpenDevRegKey(hdev, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
if (Key<>0) then
try
SetLength({%H-}PortName, MAX_PATH);
Count := Length(PortName);
Windows.RegQueryValueEx(Key, 'PortName', nil, @RegType, PByte(PChar(PortName)), @Count);
if (Count>0) AND (RegType=REG_SZ) then
begin
SetLength(PortName, Count - 1);
s:=s+PortName;
end;
finally
Windows.RegCloseKey(Key);
end;
s:=s+DefaultFormatSettings.ListSeparator;
if Length(s)>0 then
begin
SetLength(s,Length(s)-1);
ComList.Append(s);
end;
end
else
begin
RaiseLastOSError;
end;
finally
FreeMem(pdidd);
end;
end;
end
else
begin
break;
end;
inc(idev);
until false;
finally
SetupDiDestroyDeviceInfoList(hdev);
end;
end;
UnloadSetupApi;
end;