Forum > Windows
is a device really there?
dieselnutjob:
compared to my previous post is this better, worse or no different? :-
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function TForm1.DeviceToCRcode(ADevice:pChar): CONFIGRET;var CM_Locate_DevNodeA: TCM_Locate_DevNodeA; CfgMgrApiLib: TLibHandle; Flags: ULong; ADevInst: PDEVINST;begin Result:=$FFFFFFFF; CfgMgrApiLib:=dynlibs.NilHandle; try CfgMgrApiLib:=Loadlibrary(CfgMgrDllName); if CfgMgrApiLib<>dynlibs.NilHandle then begin CM_Locate_DevNodeA:=TCM_Locate_DevNodeA(GetProcedureAddress(CfgMgrApiLib,'CM_Locate_DevNodeA')); Flags:=CM_LOCATE_DEVNODE_NORMAL; Result:=CM_Locate_DevNodeA(ADevInst,ADevice,Flags); end; finally if CfgMgrApiLib<>dynlibs.NilHandle then Freelibrary(CfgMgrApiLib); end;end;
otherwise it would be doing a loadlibrary over and over again without ever freeing it.
Does that matter?
or maybe the loadlibrary should be in the main code so it is just invoked one, pass the handle to the function each time, and then unload at the end of the main code?
As you can tell I'm not a professional coder.
dieselnutjob:
sorry more questions.
I have other code where I use the windows function GetIfTable https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getiftable
To use this function I didn't bother with dynlibs, I just defined it as an external function like this
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function GetIfTable(pIfTable:Pointer; pdwSize: Pointer; bOrder:LongWord):LongWord; stdcall; external 'IPHLPAPI.DLL';
When I try the same with CM_Locate_DevNodeA https://docs.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_locate_devnodea
like this
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function CM_Locate_DevNodeA(pdnDevInst:Pointer; pDeviceID: Pointer; ulFlags: LongWord): LongWord; stdcall; external 'CFGMGR32.DLL';
The program runs but the function always returns a 3 which means CR_INVALID_POINTER
The value of the pointer I pass in is exactly the same as with my previous code loading the DLL using Dynlibs.
Is it possible that GetIfTable can be invoked as an external function without dynlibs, but CM_Locate_DevNodeA cannot ?
I notice that the MSDN definitions of these functions is worded slightly differently:-
For GetIfTable
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---IPHLPAPI_DLL_LINKAGE DWORD GetIfTable( PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder);
For CM_Locate_DevNodeA
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---CMAPI CONFIGRET CM_Locate_DevNodeA( PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags);
Is this DLL_Linkage vs CMAPI wording significant?
or is there some other factor that I don't understand?
dieselnutjob:
OK finally got it working without dynlibs.
It was a stupid mistake.
I was sending a pointer to CM_Locate_DevNodeA that didn't point to anything.
If instead I define a longword and send it @longword, then it works.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Registry; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private function DeviceToCRcode(ADevice:pansichar): LongWord; public end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 }const CM_LOCATE_DEVNODE_NORMAL = $00000000; {$EXTERNALSYM CM_LOCATE_DEVNODE_NORMAL} CM_LOCATE_DEVNODE_PHANTOM = $00000001; {$EXTERNALSYM CM_LOCATE_DEVNODE_PHANTOM} CM_LOCATE_DEVNODE_CANCELREMOVE = $00000002; {$EXTERNALSYM CM_LOCATE_DEVNODE_CANCELREMOVE} CM_LOCATE_DEVNODE_NOVALIDATION = $00000004; {$EXTERNALSYM CM_LOCATE_DEVNODE_NOVALIDATION} CM_LOCATE_DEVNODE_BITS = $00000007; {$EXTERNALSYM CM_LOCATE_DEVNODE_BITS} function CM_Locate_DevNodeA(pdnDevInst:pointer; pDeviceID: pointer; ulFlags: Longword): Longword; stdcall; external 'cfgmgr32.dll'; procedure TForm1.Button1Click(Sender: TObject);var Registry: TRegistry; Key: AnsiString; DeviceList: TStringList; InstanceList: TStringList; i: integer; j: integer; DeviceID: AnsiString; DeviceInstanceID: AnsiString; begin DeviceList:=TStringList.Create; InstanceList:=TStringList.Create; memo1.Clear; Key:='\SYSTEM\CurrentControlSet\Enum\PCI'; memo1.Append(key); DeviceList.Clear; Registry := TRegistry.Create; try Registry.RootKey := HKEY_LOCAL_MACHINE; if Registry.OpenKeyReadOnly(Key) then begin Registry.GetKeyNames(DeviceList); end; finally Registry.Free; end; for i:=0 to DeviceList.Count-1 do begin DeviceID:='PCI\'+DeviceList[i]; memo1.Append(DeviceID); Key:='\SYSTEM\CurrentControlSet\Enum\PCI\'+DeviceList[i]; memo1.Append(key); InstanceList.Clear; Registry := TRegistry.Create; try Registry.RootKey := HKEY_LOCAL_MACHINE; if Registry.OpenKeyReadOnly(Key) then begin Registry.GetKeyNames(InstanceList); end; finally Registry.Free; end; for j:=0 to InstanceList.Count-1 do begin DeviceInstanceID:=DeviceID+'\'+InstanceList[j]; memo1.Append(DeviceInstanceID); if length(DeviceInstanceID)>0 then memo1.Append(IntToStr(DeviceToCRcode(@DeviceInstanceID[1]))); end; end;end; function TForm1.DeviceToCRcode(ADevice:pansichar): LongWord;var Flags: LongWord; ADevInst: LongWord;begin ADevInst:=0; Flags:=CM_LOCATE_DEVNODE_NORMAL; Result:=CM_Locate_DevNodeA(@ADevInst,ADevice,Flags);end; end.
dieselnutjob:
a final word of warning with my code.
It tells you if a device is really there, but not if it is really working.
As an example look at this device on the PCI bus of my laptop
https://pscan.uk/images/devicehasproblem.png
If you look at "Device Node Status" it returned CR_SUCCESS, so it's there, but the driver hasn't loaded.
If you want to know if it's working then you need to look for maybe DeviceStatus or something like that.
At least my code will give you a handle to pass to CM_Get_DevNode_Status
Navigation
[0] Message Index
[*] Previous page