Forum > Windows

is a device really there?

<< < (3/3)

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

Go to full version