Mega Code Archive

 
Categories / Delphi / Hardware
 

Drivers Info Dump

Title: Drivers Info Dump Question: this little utility dumps in a memo a lot of information for each driver in your system Answer: unit Unit1; //Drivers Info Dump // // by Gian Paolo Papini // eMail: gppapini@live.it // //this little utility dumps in a memo a lot of information for each driver //in your system // //for instance: (* #73 Friendly name: DevDesc: Intel(R) PRO/1000 PL Network Connection Driver Key: {4D36E972-E325-11CE-BFC1-08002BE10318}\0008 Class: Net HardwareID: PCI\VEN_8086&DEV_109A&SUBSYS_81C21043&REV_00 Location: Bus PCI 2, periferica 0, funzione 0 Device Status: DN_DRIVER_LOADED: Has Register_Device_Driver DN_STARTED: Is currently configured DN_DISABLEABLE: Can be rebalanced Device Problem: No Problems *) //SetupApi by Robert Marquardt (Project Jedi) interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Setupapi //you need this for the Drivers API ; const CFGMGR32_DLL = 'cfgmgr32.dll'; CM_GET_DEVNODE_STATUS_NAME = 'CM_Get_DevNode_Status'; CR_SUCCESS = $00000000; // // DevInst problem values, returned by call to CM_Get_DevInst_Status // CM_PROB_NOT_CONFIGURED = $00000001; // no config for device CM_PROB_DEVLOADER_FAILED = $00000002; // service load failed CM_PROB_OUT_OF_MEMORY = $00000003; // out of memory CM_PROB_ENTRY_IS_WRONG_TYPE = $00000004; // WINDOWS 95 ONLY CM_PROB_LACKED_ARBITRATOR = $00000005; // WINDOWS 95 ONLY CM_PROB_BOOT_CONFIG_CONFLICT = $00000006; // boot config conflict CM_PROB_FAILED_FILTER = $00000007; // WINDOWS 95 ONLY CM_PROB_DEVLOADER_NOT_FOUND = $00000008; // Devloader not found CM_PROB_INVALID_DATA = $00000009; // WINDOWS 95 ONLY CM_PROB_FAILED_START = $0000000A; // WINDOWS 95 ONLY CM_PROB_LIAR = $0000000B; // ??? CM_PROB_NORMAL_CONFLICT = $0000000C; // config conflict CM_PROB_NOT_VERIFIED = $0000000D; // WINDOWS 95 ONLY CM_PROB_NEED_RESTART = $0000000E; // requires restart CM_PROB_REENUMERATION = $0000000F; // WINDOWS 95 ONLY CM_PROB_PARTIAL_LOG_CONF = $00000010; // WINDOWS 95 ONLY CM_PROB_UNKNOWN_RESOURCE = $00000011; // unknown res type CM_PROB_REINSTALL = $00000012; // WINDOWS 95 ONLY CM_PROB_REGISTRY = $00000013; // WINDOWS 95 ONLY CM_PROB_VXDLDR = $00000014; // WINDOWS 95 ONLY CM_PROB_WILL_BE_REMOVED = $00000015; // devinst will remove CM_PROB_DISABLED = $00000016; // devinst is disabled CM_PROB_DEVLOADER_NOT_READY = $00000017; // Devloader not ready CM_PROB_DEVICE_NOT_THERE = $00000018; // device doesn't exist CM_PROB_MOVED = $00000019; // WINDOWS 95 ONLY CM_PROB_TOO_EARLY = $0000001A; // WINDOWS 95 ONLY CM_PROB_NO_VALID_LOG_CONF = $0000001B; // no valid log config CM_PROB_FAILED_INSTALL = $0000001C; // install failed CM_PROB_HARDWARE_DISABLED = $0000001D; // device disabled CM_PROB_CANT_SHARE_IRQ = $0000001E; // can't share IRQ NUM_CM_PROB = $0000001F; // // Device Instance status flags, returned by call to CM_Get_DevInst_Status // DN_ROOT_ENUMERATED = $00000001; // Was enumerated by ROOT DN_DRIVER_LOADED = $00000002; // Has Register_Device_Driver DN_ENUM_LOADED = $00000004; // Has Register_Enumerator DN_STARTED = $00000008; // Is currently configured DN_MANUAL = $00000010; // Manually installed DN_NEED_TO_ENUM = $00000020; // May need reenumeration DN_NOT_FIRST_TIME = $00000040; // Has received a config DN_HARDWARE_ENUM = $00000080; // Enum generates hardware ID DN_LIAR = $00000100; // Lied about can reconfig once DN_HAS_MARK = $00000200; // Not CM_Create_DevInst lately DN_HAS_PROBLEM = $00000400; // Need device installer DN_FILTERED = $00000800; // Is filtered DN_MOVED = $00001000; // Has been moved DN_DISABLEABLE = $00002000; // Can be rebalanced DN_REMOVABLE = $00004000; // Can be removed DN_PRIVATE_PROBLEM = $00008000; // Has a private problem DN_MF_PARENT = $00010000; // Multi function parent DN_MF_CHILD = $00020000; // Multi function child DN_WILL_BE_REMOVED = $00040000; // DevInst is being removed type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; CheckBox1: TCheckBox; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } function DetectDriversInfo: boolean; end; var Form1: TForm1; HCfgMgr: THandle; CM_Get_DevNode_Status: function(pulStatus: PULONG; pulProblemNumber: PULONG; dnDevInst: DWORD; ulFlags: ULONG): DWORD; stdcall; implementation {$R *.dfm} function GetDeviceInstanceStatusProblemMessage(myulProblem: ULONG): string; //passing a ULONG problem (returned from CM_Get_DevInst_Status) //returns a corresponding string; var msg: string; begin case myulProblem of 0: msg := 'No Problems'; CM_PROB_NOT_CONFIGURED : // no config for device msg := 'CM_PROB_NOT_CONFIGURED'; CM_PROB_DEVLOADER_FAILED :// service load failed msg := 'CM_PROB_DEVLOADER_FAILED'; CM_PROB_OUT_OF_MEMORY : // out of memory msg := 'CM_PROB_OUT_OF_MEMORY'; CM_PROB_ENTRY_IS_WRONG_TYPE : // WINDOWS 95 ONLY msg := 'CM_PROB_ENTRY_IS_WRONG_TYPE'; CM_PROB_LACKED_ARBITRATOR : // WINDOWS 95 ONLY msg := 'CM_PROB_LACKED_ARBITRATOR'; CM_PROB_BOOT_CONFIG_CONFLICT : // boot config conflict msg := 'CM_PROB_BOOT_CONFIG_CONFLICT'; CM_PROB_FAILED_FILTER : // WINDOWS 95 ONLY msg := 'CM_PROB_FAILED_FILTER'; CM_PROB_DEVLOADER_NOT_FOUND : // Devloader not found msg := 'CM_PROB_DEVLOADER_NOT_FOUND'; CM_PROB_INVALID_DATA : // WINDOWS 95 ONLY msg := 'CM_PROB_INVALID_DATA'; CM_PROB_FAILED_START : // WINDOWS 95 ONLY msg := 'CM_PROB_FAILED_START'; CM_PROB_LIAR : // ??? msg := 'CM_PROB_LIAR'; CM_PROB_NORMAL_CONFLICT : // config conflict msg := 'CM_PROB_NORMAL_CONFLICT'; CM_PROB_NOT_VERIFIED : // WINDOWS 95 ONLY msg := 'CM_PROB_NOT_VERIFIED'; CM_PROB_NEED_RESTART : // requires restart msg := 'CM_PROB_NEED_RESTART'; CM_PROB_REENUMERATION : // WINDOWS 95 ONLY msg := 'CM_PROB_REENUMERATION'; CM_PROB_PARTIAL_LOG_CONF : // WINDOWS 95 ONLY msg := 'CM_PROB_PARTIAL_LOG_CONF'; CM_PROB_UNKNOWN_RESOURCE : // unknown res type msg := 'CM_PROB_UNKNOWN_RESOURCE'; CM_PROB_REINSTALL : // WINDOWS 95 ONLY msg := 'CM_PROB_REINSTALL'; CM_PROB_REGISTRY : // WINDOWS 95 ONLY msg := 'CM_PROB_REGISTRY'; CM_PROB_VXDLDR : // WINDOWS 95 ONLY msg := 'CM_PROB_VXDLDR'; CM_PROB_WILL_BE_REMOVED : // devinst will remove msg := 'CM_PROB_WILL_BE_REMOVED'; CM_PROB_DISABLED : // devinst is disabled msg := 'CM_PROB_DISABLED'; CM_PROB_DEVLOADER_NOT_READY : // Devloader not ready msg := 'CM_PROB_DEVLOADER_NOT_READY'; CM_PROB_DEVICE_NOT_THERE : // device doesn't exist msg := 'CM_PROB_DEVICE_NOT_THERE'; CM_PROB_MOVED : // WINDOWS 95 ONLY msg := 'CM_PROB_MOVED'; CM_PROB_TOO_EARLY : // WINDOWS 95 ONLY msg := 'CM_PROB_TOO_EARLY'; CM_PROB_NO_VALID_LOG_CONF : // no valid log config msg := 'CM_PROB_NO_VALID_LOG_CONF'; CM_PROB_FAILED_INSTALL : // install failed msg := 'CM_PROB_FAILED_INSTALL'; CM_PROB_HARDWARE_DISABLED : // device disabled msg := 'CM_PROB_HARDWARE_DISABLED'; CM_PROB_CANT_SHARE_IRQ : // can't share IRQ msg := 'CM_PROB_CANT_SHARE_IRQ'; else msg := 'Undefined Problem'; end; Result := msg; end;//function GetDeviceInstanceStatusProblemMessage function GetDeviceInstanceStatusFlagMessage(myulStatus: ULONG): string; //passing a ULONG bitmask status (returned from CM_Get_DevInst_Status) //builds a StringList with every message from every active bit in the mask var msg: string; i: integer; j: Ulong; mystrList: TStringList; begin if myulStatus = 0 then begin Result := 'The Device is not installed'; exit; end; mystrList := TStringList.Create; mystrList.Clear; j := 0; for i := 0 to 18 do begin //the DN_ consts are 19... if i = 0 then begin j := 1; end else begin j := j*2; end; if ((myulStatus and j) = j) then begin case j of DN_ROOT_ENUMERATED: mystrList.Add('DN_ROOT_ENUMERATED: Was enumerated by ROOT'); DN_DRIVER_LOADED: mystrList.Add('DN_DRIVER_LOADED: Has Register_Device_Driver'); DN_ENUM_LOADED: mystrList.Add('DN_ENUM_LOADED: Has Register_Enumerator'); DN_STARTED: mystrList.Add('DN_STARTED: Is currently configured'); DN_MANUAL: mystrList.Add('DN_MANUAL: Manually installed'); DN_NEED_TO_ENUM: mystrList.Add('DN_NEED_TO_ENUM: May need reenumeration'); DN_NOT_FIRST_TIME: mystrList.Add('DN_NOT_FIRST_TIME: Has received a config'); DN_HARDWARE_ENUM: mystrList.Add('DN_HARDWARE_ENUM: Enum generates hardware ID'); DN_LIAR: mystrList.Add('DN_LIAR: Lied about can reconfig once'); DN_HAS_MARK: mystrList.Add('DN_HAS_MARK: Not CM_Create_DevInst lately'); DN_HAS_PROBLEM: mystrList.Add('DN_HAS_PROBLEM: Need device installer'); DN_FILTERED: mystrList.Add('DN_FILTERED: Is filtered'); DN_MOVED: mystrList.Add('DN_MOVED: Has been moved'); DN_DISABLEABLE: mystrList.Add('DN_DISABLEABLE: Can be rebalanced'); DN_REMOVABLE: mystrList.Add('DN_REMOVABLE: Can be removed'); DN_PRIVATE_PROBLEM: mystrList.Add('DN_PRIVATE_PROBLEM: Has a private problem'); DN_MF_PARENT: mystrList.Add('DN_MF_PARENT: Multi function parent'); DN_MF_CHILD: mystrList.Add('DN_MF_CHILD: Multi function child'); DN_WILL_BE_REMOVED: mystrList.Add('DN_WILL_BE_REMOVED: DevInst is being removed'); else mystrList.Add('Status undefined'); end; end; end;//for i msg := mystrList.Text; Result := msg; FreeAndNil(mystrList); end;//function GetDeviceInstanceStatusFlagMessage( function TForm1.DetectDriversInfo: boolean; var PnPHandle: HDEVINFO; DevData: TSPDevInfoData; mybool: boolean; Index: DWORD; msg: string; ulStatus: ULONG; ulProblemNumber: ULONG; DataT: DWORD; nSize: DWORD; buf: array[0..MAX_PATH] of char; begin Result := false; Index := 0; Memo1.Clear; //Loads the SetupApi for //SetupDiEnumDeviceInfo //SetupDiGetDeviceRegistryProperty LoadSetupApi; //Function in SetupApi //Loads cfgmgr32.dll for //CM_Get_DevNode_Status HCfgMgr := LoadLibrary(CFGMGR32_DLL); if (HCfgMgr 32) then begin MessageDlg('Error: could not find Configuration Manager DLL', mtError, [mbOk], 0); exit; end; CM_Get_DevNode_Status := GetProcAddress(HCfgMgr, CM_GET_DEVNODE_STATUS_NAME); //obtains a pointer to the list of all the drivers PnPHandle := SetupDiGetClassDevs(nil, nil, 0, DIGCF_ALLCLASSES); while true do begin //obtains a SPDevInfoData for each driver DevData.cbSize := SizeOf(DevData); mybool := SetupDiEnumDeviceInfo(PnPHandle, Index, DevData); if not mybool then begin break; end else begin //obtains the status bitmask and the problemNumber for each driver if not CM_Get_DevNode_Status(@ulStatus, @ulProblemNumber, DevData.DevInst, 0) = CR_SUCCESS then begin msg := '#' + inttostr(Index); Memo1.Lines.Add(msg); Memo1.Lines.Add('DevNode Status error'); Memo1.Lines.Add('__________________'); Memo1.Lines.Add(''); inc(Index); continue; end; //if the driver status =0 --- the driver is "not installed", //it seems that old drivers garbage remain in the driver list //you can purge the list through the checkbox if you want to get rid of unused drivers if ulStatus = 0 then begin if CheckBox1.Checked then begin inc(Index); continue; end; end; nSize := 0; msg := ''; //obtains several parameters for each driver //and writes them in the Memo msg := '#' + inttostr(Index); Memo1.Lines.Add(msg); msg := 'Friendly name: '; if ( SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_FRIENDLYNAME, DataT, @buf, sizeof(buf), nSize) ) then begin msg := msg + buf; end; Memo1.Lines.Add(msg); msg := 'DevDesc: '; if ( SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_DEVICEDESC, DataT, @buf, sizeof(buf), nSize) ) then begin msg := msg + buf; end; Memo1.Lines.Add(msg); msg := 'Driver Key: '; if ( SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_DRIVER , DataT, @buf, sizeof(buf), nSize) ) then begin msg := msg + buf; end; Memo1.Lines.Add(msg); msg := 'Class: '; if ( SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_CLASS , DataT, @buf, sizeof(buf), nSize) ) then begin msg := msg + buf; end; Memo1.Lines.Add(msg); msg := 'HardwareID: '; if ( SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_HARDWAREID , DataT, @buf, sizeof(buf), nSize) ) then begin msg := msg + buf; end; Memo1.Lines.Add(msg); msg := 'Location: '; if ( SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, SPDRP_LOCATION_INFORMATION, DataT, @buf, sizeof(buf), nSize) ) then begin msg := msg + buf; end; Memo1.Lines.Add(msg); //obtains info strings based on the status and the problemnumber //of each device msg := 'Device Status: '; Memo1.Lines.Add(msg); //Indeed this function passes a stringList through the Text property //the text is automatically converted in several lines when you add it to the memo //cause the stringList and the memo share the same default delimiter for each string msg := GetDeviceInstanceStatusFlagMessage(ulStatus); Memo1.Lines.Add(msg); Memo1.Lines.Add(''); msg := 'Device Problem: '; msg := msg + GetDeviceInstanceStatusProblemMessage(ulProblemNumber); Memo1.Lines.Add(msg); Memo1.Lines.Add('__________________'); Memo1.Lines.Add(''); end; inc(Index); end; //Frees resources SetupDiDestroyDeviceInfoList(PnPHandle); FreeLibrary(HCfgMgr); UnloadSetupApi; //function in Setupapi.pas end;//function TForm1.DetectDriversInfo: boolean; procedure TForm1.Button1Click(Sender: TObject); begin DetectDriversInfo; end; procedure TForm1.FormCreate(Sender: TObject); begin Memo1.Clear; end; end.