2012-05-07 12 views
5

मैं जानना चाहता हूं कि डिवाइस प्रबंधक जैसे किसी विशेष डिवाइस के लिए मैं सभी ड्राइवर फ़ाइलों को कैसे प्राप्त कर सकता हूं?किसी विशेष डिवाइस के लिए ड्राइवर फ़ाइलों को प्राप्त करना

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); 

लेकिन ShowMessage() या तो बिल्कुल भी नहीं बुलाया जाता है या \ रिटर्न:

मैं निम्नलिखित कोड है। मैं फ़ाइलों को ठीक से कैसे प्राप्त करूं?

मैंने WinDDK से devcon पर एक नज़र डाली थी, लेकिन यह फ़ाइलों को भी वापस नहीं करता है।

धन्यवाद।

उत्तर

5

मैंने इसे समझ लिया। आपके लिए ऐसा करने के लिए कोई एपीआई नहीं है, आपको परिणाम प्राप्त करने के लिए आईएनएफ फाइलों को पार्स करने की आवश्यकता है। आप सभी के लिए एक त्वरित-गंदे समाधान यहां है, जो रुचि रखते हैं।

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; 
संबंधित मुद्दे