Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7914815
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T14:14:39+00:00 2026-06-03T14:14:39+00:00

I would like to know how I can get all the driver files for

  • 0

I would like to know how I can get all the driver files for a particular device just like the Device Manager does?

I have the following code:

procedure TdlgMain.Test(const DeviceIndex: Integer);
var
  PnPHandle: HDEVINFO;
  DevData: TSPDevInfoData;
  DeviceInterfaceData: TSPDeviceInterfaceData;
  FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
  Success: LongBool;
  Devn: Integer;
  BytesReturned: DWORD;
  SerialGUID: TGUID;
begin
  ZeroMemory(@DevData, SizeOf(SP_DEVINFO_DATA));
  DevData.cbSize := SizeOf(SP_DEVINFO_DATA);

  ZeroMemory(@DeviceInterfaceData, SizeOf(TSPDeviceInterfaceData));
  DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);

  if not SetupDiEnumDeviceInfo(hAllDevices,
    DeviceIndex, DevData) then Exit;

  SerialGUID := DevData.ClassGuid;

  PnPHandle := SetupDiGetClassDevs(@SerialGUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
  if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then
    Exit;

  Devn := 0;
  repeat
    DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
    Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, SerialGUID, Devn, DeviceInterfaceData);
    if Success then
    begin
      DevData.cbSize := SizeOf(DevData);
      BytesReturned := 0;
      // get size required for call
      SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
      if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
      begin
        // allocate buffer and initialize it for call
        FunctionClassDeviceData := AllocMem(BytesReturned);
        FunctionClassDeviceData.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
        //FunctionClassDeviceData.cbSize := BytesReturned;
        if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData,
          FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
        begin
          ShowMessage(FunctionClassDeviceData.DevicePath);
        end else
          RaiseLastOSError();
        FreeMem(FunctionClassDeviceData);
      end;
    end;
    Inc(Devn);
  until not Success;
  SetupDiDestroyDeviceInfoList(PnPHandle);

But the ShowMessage() is either not called at all or returns \. How do I get the files properly?

I had a look at devcon from the WinDDK, but it does not return the files either.

Thank you.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T14:14:41+00:00Added an answer on June 3, 2026 at 2:14 pm

    I figured it out. There’s no API to do it for you, you need to parse the INF files to achieve the result. Here’s a quick-n-dirty solution for all of you, who are interested.

    procedure TdlgMain.Test(const DeviceIndex: Integer);
    var
      Paths: TStringList;
      I: Integer;
    
      function GetWinDir: string; inline;
      var
        dir: array [0 .. MAX_PATH] of Char;
      begin
        GetWindowsDirectory(dir, MAX_PATH);
        Result := IncludeTrailingBackslash(StrPas(dir));
      end;
    
      function GetSpecialFolderPath(const folder: Integer): string; inline;
      const
        SHGFP_TYPE_CURRENT = 0;
      var
        path: array [0 .. MAX_PATH] of Char;
      begin
        if SUCCEEDED(SHGetFolderPath(0, folder, 0, SHGFP_TYPE_CURRENT, @path[0]))
        then
          Result := IncludeTrailingBackslash(path)
        else
          Result := '';
      end;
    
      function LocateInfFile(const F: String): String; inline;
      var
        T: String;
      begin
        Result := '';
    
        if (Pos(SysUtils.PathDelim, F) > 0) then
        begin
          Result := F;
          Exit;
        end;
    
        T := GetWinDir();
        if (FileExists(T + 'inf\' + F)) then
          Result := T + 'inf\' + F
        else if (FileExists(T + 'system32\' + F)) then
          Result := T + 'system32\' + F;
      end;
    
      procedure ReadSectionNoKeys(const AFile, ASection: String;
        const SL: TStringList);
      var
        TheFile: TStringList;
        Line: String;
        TrimEnd: Boolean;
        Idx, Tmp: Integer;
      begin
        TrimEnd := False;
    
        TheFile := TStringList.Create();
        try
          TheFile.LoadFromFile(AFile);
          Idx := TheFile.IndexOf('[' + ASection + ']');
          if (Idx <> -1) then
          begin
            Idx := Idx + 1;
            while True do
            begin
              Line := Trim(TheFile[Idx]);
              Inc(Idx);
              if (Pos(';', Line) = 1) then
                continue;
    
              if (Pos('[', Line) > 0) then
                Break;
    
              Tmp := Pos(',', Line);
              if (Tmp > 0) then
                TrimEnd := True
              else
              begin
                Tmp := PosEx(';', Line, 3);
                if (Tmp > 0) then
                  TrimEnd := True;
              end;
    
              if (Line <> '') then
              begin
                if (TrimEnd) then
                begin
                  Line := Trim(Copy(Line, 1, Tmp - 1));
                  TrimEnd := False;
                end;
    
                SL.Add(Line);
              end;
    
              if (Idx = (TheFile.Count - 1)) then
                Break;
            end;
          end;
        finally
          TheFile.Free();
        end;
      end;
    
      function IniReadStr(const Ini: TIniFile; const S, L, D: String): String;
      var
        T: Integer;
      begin
        Result := Ini.ReadString(S, L, D);
    
        T := Pos(';', Result);
        if (T > 0) then
          Result := Trim(Copy(Result, 1, T - 1));
      end;
    
      procedure ParseInfFile(const InfFile, SectionName: String);
      var
        I: TIniFile;
        SL, FilesList: TStringList;
        X, Y, Tmp: Integer;
        Pth, S, S1: String;
      begin
        I := TIniFile.Create(InfFile);
        try
          if (SectionName <> '') and (I.SectionExists(SectionName)) then
          begin
            // Check if the section has a value called "CopyFiles".
            if (I.ValueExists(SectionName, 'CopyFiles')) then
            begin
              // It has. Read it to a string and separate by commas.
              SL := TStringList.Create();
              try
                SL.CommaText := IniReadStr(I, SectionName, 'CopyFiles', '');
    
                // Now, every line of the string list is a section name. Check
                // the destination directory of each.
                if (I.SectionExists('DestinationDirs')) then
                  for X := 0 to SL.Count - 1 do
                  begin
                    S := IniReadStr(I, 'DestinationDirs', SL[X], '');
                    if (S = '') then
                      S := IniReadStr(I, 'DestinationDirs', 'DefaultDestDir', '');
    
                    if (S <> '') then
                    begin
                      // Split the path by comma, if any.
                      Tmp := Pos(',', S);
                      S1 := '';
                      if (Tmp > 0) then
                      begin
                        S1 := Trim(Copy(S, Tmp + 1, Length(S)));
                        S := Trim(Copy(S, 1, Tmp - 1));
                      end;
    
                      // Convert the numeric value of S to a proper directory.
                      Pth := '';
                      if (S = '10') then
                        Pth := GetWinDir();
                      if (S = '11') then
                        Pth := GetWinDir() + 'system32\';
                      if (S = '12') then
                        Pth := GetWinDir() + 'system32\drivers\';
                      if (S = '50') then
                        Pth := GetWinDir() + 'system\';
                      if (S = '30') then
                        Pth := ExtractFileDrive(GetWinDir());
                      if (StrToInt(S) >= 16384) then
                        Pth := GetSpecialFolderPath(StrToInt(S));
    
                      if (S1 <> '') then
                        Pth := IncludeTrailingBackslash(Pth + S1);
    
                      // If we got the path, read the files.
                      if (Pth <> '') then
                      begin
                        FilesList := TStringList.Create();
                        try
                          ReadSectionNoKeys(InfFile, SL[X], FilesList);
                          for Y := 0 to FilesList.Count - 1 do
                            if (Paths.IndexOf(Pth + FilesList[Y]) = -1) then
                              Paths.Add(Pth + FilesList[Y]);
                        finally
                          FilesList.Free();
                        end;
                      end;
                    end;
                  end;
              finally
                SL.Free();
              end;
            end;
    
            // Check if there're "Include" and "Needs" values.
            if ((I.ValueExists(SectionName, 'Include')) and
              (I.ValueExists(SectionName, 'Needs'))) then
            begin
              // Split both by comma.
              SL := TStringList.Create();
              FilesList := TStringList.Create();
              try
                SL.CommaText := IniReadStr(I, SectionName, 'Include', '');
                FilesList.CommaText := IniReadStr(I, SectionName, 'Needs', '');
                if (SL.Text <> '') and (FilesList.Text <> '') then
                  for X := 0 to SL.Count - 1 do
                    for Y := 0 to FilesList.Count - 1 do
                      ParseInfFile(LocateInfFile(SL[X]), FilesList[Y]);
              finally
                FilesList.Free();
                SL.Free();
              end;
            end;
          end;
        finally
          I.Free();
        end;
      end;
    
    begin
      Paths := TStringList.Create();
      try
        ParseInfFile(LocateInfFile(DeviceHelper.InfName), DeviceHelper.InfSection);
        Paths.Sort();
    
        ListView_InsertGroup(lvAdvancedInfo.Handle, 'Driver Files', 2);
        for I := 0 to Paths.Count - 1 do
          ListView_AddItemsInGroup(lvAdvancedInfo, '', Paths[I], 2);
      finally
        Paths.Free();
      end;
    end;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to know how can I get all tweets from a certain
I would like to know how can we validate the Credit Card. We have
I would like to know if I can use the following JQuery function on
I'm using SQL Server 2005 and would like to know how I can get
i would like know some reference. I know i can googling it. but prefer
I would like to know how can i read a value of input text
I would like to know how can I use tinyint in SQL Server 2005
I would like to know how can I use jQuery to select multiple items
I would like to know: how can i initialize class object with parameters? I've
I would like to know how can i write to a file within Application.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.