[Lazarus] devmgmt.msc
José Mejuto
joshyfun at gmail.com
Thu Mar 29 14:22:00 CEST 2018
El 28/03/2018 a las 22:48, duilio foschi via Lazarus escribió:
> if I run devmgmt.msc on W7 I get this info on screen:
> Is there a Winows API I can call from my Lazarus program and get the same info ?
> My aim is to detect which COM number was assigned to the USB device
> "MSP Application UART1"
Hello,
Attached unit will help you to implement a COM port browsing. There is a
bit of extra code as original comes from a bigger unit, and this is an
extract.
--
-------------- next part --------------
unit udeviceenumwin;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
function EnumDevices: integer;
implementation
uses
windows;
const
WINDOWS_SETUPAPI_NAME='setupapi.dll';
DIGCF_DEFAULT = $00000001;
DIGCF_PRESENT = $00000002;
DIGCF_ALLCLASSES = $00000004;
DIGCF_PROFILE = $00000008;
DIGCF_DEVICEINTERFACE = $00000010;
SPDRP_FRIENDLYNAME = $0000000C;
type
{$PackRecords C}
HDEVINFO = type THANDLE;
SP_DEVINFO_DATA = record
cbSize: DWORD;
ClassGuid: TGUID;
DevInst: DWORD; // DEVINST handle
Reserved: Pointer;
end;
PSP_DEVINFO_DATA=^SP_DEVINFO_DATA;
SP_DEVICE_INTERFACE_DATA = record
cbSize: DWORD;
InterfaceClassGuid: TGUID;
Flags: DWORD;
Reserved: Pointer;
end;
PSP_DEVICE_INTERFACE_DATA= ^SP_DEVICE_INTERFACE_DATA;
SP_DEVICE_INTERFACE_DETAIL_DATA_W = packed record
cbSize: DWORD;
DevicePath: array [0..0] of WideChar;
end;
PSP_DEVICE_INTERFACE_DETAIL_DATA_W = ^SP_DEVICE_INTERFACE_DETAIL_DATA_W;
// SETUPAPI.DLL
TSetupDiGetClassDevs = function (var aGUID: TGUID; aEnumerator: PWideChar; hwndParent: SizeInt; aFlags: DWORD): HDEVINFO; stdcall;
TSetupDiEnumDeviceInterfaces = function (DeviceInfoSet: HDEVINFO; DeviceInfoData: PSP_DEVINFO_DATA; var InterfaceClassGuid: TGUID; MemberIndex: DWORD; var DeviceInterfaceData: SP_DEVICE_INTERFACE_DATA): WINBOOL; stdcall;
TSetupDiGetDeviceInterfaceDetailW = function (DeviceInfoSet: HDEVINFO; DeviceInterfaceData: PSP_DEVICE_INTERFACE_DATA;
DeviceInterfaceDetailData: PSP_DEVICE_INTERFACE_DETAIL_DATA_W;
DeviceInterfaceDetailDataSize: DWORD; var RequiredSize: DWORD;
DeviceInfoData: PSP_DEVINFO_DATA): WINBOOL; stdcall;
TSetupDiDestroyDeviceInfoList = function (DeviceInfoSet: HDEVINFO): WINBOOL; stdcall;
TSetupDiGetDeviceRegistryPropertyA = function (DeviceInfoSet: HDEVINFO; DeviceInfoData: PSP_DEVINFO_DATA;
PropertyID: DWORD; PropertyRegDataType: PDWORD;
PropertyBuffer: PBYTE; PropertyBufferSize: DWORD;
RequiredSize: PDWORD): WINBOOL; stdcall;
TSetupDiEnumDeviceInfo = function (DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; var DeviceInterfaceData: SP_DEVICE_INTERFACE_DATA): WINBOOL; stdcall;
type
TDLLSetupAPIEntriesRecord=record
SetupDiGetClassDevs: TSetupDiGetClassDevs;
SetupDiEnumDeviceInterfaces: TSetupDiEnumDeviceInterfaces;
SetupDiGetDeviceInterfaceDetailW: TSetupDiGetDeviceInterfaceDetailW;
SetupDiDestroyDeviceInfoList: TSetupDiDestroyDeviceInfoList;
SetupDiGetDeviceRegistryPropertyA: TSetupDiGetDeviceRegistryPropertyA;
SetupDiEnumDeviceInfo: TSetupDiEnumDeviceInfo;
end;
var
DLLSetupAPIHandle: TLibHandle;
DLLInitializedFlag: Boolean=false;
DLLInitializedSuccess: Boolean=false;
DLLSetupAPIFunctions: TDLLSetupAPIEntriesRecord;
function InitializeLibraries: Boolean; forward;
procedure DEBUG_OUTPUT(msg: string);
begin
writeln(msg);
end;
function EnumDevices(): integer;
var
lGUID: TGUID='{4d36e978-e325-11ce-bfc1-08002be10318}'; // COM PORTS and LPT
lDeviceInfoList: HDEVINFO;
lDeviceInfo: SP_DEVICE_INTERFACE_DATA;
lMemberIndex: integer;
lStopEnumeration: Boolean=false;
lIndex: integer;
lFriendlyName: array [0..511] of char;
begin
if not InitializeLibraries then exit(1);
ldeviceInfoList := DLLSetupAPIFunctions.SetupDiGetClassDevs(lGUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
if lDeviceInfoList=INVALID_HANDLE_VALUE then begin
exit(2);
end;
lDeviceInfo.cbSize:=SizeOf(lDeviceInfo);
lMemberIndex:=0;
while true do begin
if not DLLSetupAPIFunctions.SetupDiEnumDeviceInterfaces(ldeviceInfoList, nil, lGUID, lMemberIndex, lDeviceInfo) then begin
// Browse finished
lStopEnumeration:=true;
break;
end;
lIndex:=0;
while true do begin
if DLLSetupAPIFunctions.SetupDiEnumDeviceInfo(lDeviceInfoList,lIndex,lDeviceInfo)=FALSE then begin
break;
end;
if DLLSetupAPIFunctions.SetupDiGetDeviceRegistryPropertyA(lDeviceInfoList, at lDeviceInfo,SPDRP_FRIENDLYNAME,nil, at lFriendlyName[0],sizeof(lFriendlyName)-1,nil) then begin
DEBUG_OUTPUT(lFriendlyName);
end;
inc(lIndex);
end;
if lStopEnumeration then break;
inc(lMemberIndex);
end;
DLLSetupAPIFunctions.SetupDiDestroyDeviceInfoList(lDeviceInfoList);
Result:=0;
end;
function InitializeLibraries: Boolean;
var
lSuccessFunctions: Boolean=true;
function CheckFunctionsRecord(p: Pointer; aEntries: integer): Boolean;
var
j: integer;
pProc: Pointer;
lAssigned: Boolean=true;
pp: PPointer;
begin
pp:=p;
for j := 0 to Pred(aEntries) do begin
pProc:=pp^;
if not Assigned(pProc) then begin
lAssigned:=false;
break;
end;
inc(pp);
end;
Result:=lAssigned;
end;
begin
if DLLInitializedFlag then exit(DLLInitializedSuccess);
DLLSetupAPIFunctions:=Default(TDLLSetupAPIEntriesRecord);
DLLInitializedFlag:=true;
DLLSetupAPIHandle:=LoadLibrary(WINDOWS_SETUPAPI_NAME);
if DLLSetupAPIHandle<>0 then begin
Pointer(DLLSetupAPIFunctions.SetupDiGetClassDevs):=GetProcAddress(DLLSetupAPIHandle,'SetupDiGetClassDevsW');
Pointer(DLLSetupAPIFunctions.SetupDiEnumDeviceInterfaces):=GetProcAddress(DLLSetupAPIHandle,'SetupDiEnumDeviceInterfaces');
Pointer(DLLSetupAPIFunctions.SetupDiGetDeviceInterfaceDetailW):=GetProcAddress(DLLSetupAPIHandle,'SetupDiGetDeviceInterfaceDetailW');
Pointer(DLLSetupAPIFunctions.SetupDiDestroyDeviceInfoList):=GetProcAddress(DLLSetupAPIHandle,'SetupDiDestroyDeviceInfoList');
Pointer(DLLSetupAPIFunctions.SetupDiGetDeviceRegistryPropertyA):=GetProcAddress(DLLSetupAPIHandle,'SetupDiGetDeviceRegistryPropertyA');
Pointer(DLLSetupAPIFunctions.SetupDiEnumDeviceInfo):=GetProcAddress(DLLSetupAPIHandle,'SetupDiEnumDeviceInfo');
end;
if lSuccessFunctions then begin
lSuccessFunctions:=CheckFunctionsRecord(@DLLSetupAPIFunctions,sizeof(DLLSetupAPIFunctions) div sizeof(Pointer));
end;
if not lSuccessFunctions then begin
DEBUG_OUTPUT('LoadLibrary error');
end;
DLLInitializedSuccess:=lSuccessFunctions;
Result:=DLLInitializedSuccess;
end;
finalization
if DLLInitializedFlag then begin
if (DLLSetupAPIHandle<>0) then FreeLibrary(DLLSetupAPIHandle);
end;
end.
More information about the Lazarus
mailing list