помощь по Api-функции SetupGetInfDriverStoreLocation

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
romeo91
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.06.2005 (Чт) 9:48

помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение romeo91 » 20.03.2012 (Вт) 9:08

Друзья, очень прошу помочь в не очень легком для меня вопросе. Декларация API и получение возвращаемого ею значения
Пытаюсь получить на винде Vista и старше, местораположение первоисточника драйвера который лежит в каталоге DriverStore\Filerepository
Для этого есть функция SetupGetInfDriverStoreLocation описание функции на msdn
Но что-то у меня не получается. Функция возвращает пустое значение, посдкажите верно ли я описал API-функцию и ее вызов.
Код: Выделить всё
Public Declare Function SetupGetInfDriverStoreLocationA Lib "setupapi.dll" (ByVal FileName As String, _
                                                                           AlternatePlatformInfo As PSP_ALTPLATFORM_INFO, _
                                                                           ByVal LocaleName As String, _
                                                                           ByVal ReturnBuffer As String, _
                                                                           ByVal ReturnBufferSize As Long, _
                                                                           ByRef RequiredSize As Long) As Long
                                                                           
Private Declare Function FormatMessage _
                Lib "kernel32.dll" _
                Alias "FormatMessageA" (ByVal dwFlags As Long, _
                                        lpSource As Any, _
                                        ByVal dwMessageId As Long, _
                                        ByVal dwLanguageId As Long, _
                                        ByVal lpBuffer As String, _
                                        ByVal nSize As Long, _
                                        Arguments As Long) As Long

Private Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000

Private Type PSP_ALTPLATFORM_INFO
    cbSize As Long
    Platform As Long
    MajorVersion As Long
    MinorVersion As Long
    ProcessorArchitecture As Integer
    Reserved As Integer
End Type

Private Const MAX_PATH As Long = 260
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long

Sub Main()
Call Func3("c:\Windows\inf\oem8.inf")
End Sub

Public Function Func3(sInfPath As String) As String
Dim sBuffer As String
Dim as12 As PSP_ALTPLATFORM_INFO
Dim ret As Long
Dim lngsize As Long

    sBuffer = Space$(MAX_PATH)

    ret = SetupGetInfDriverStoreLocationA(sInfPath, as12, 0&, sBuffer, Len(sBuffer), 0)
    Func3 = TrimNull(sBuffer)
    MsgBox "Err ¹" & Err.LastDllError & " - " & ApiErrorText(Err.LastDllError)

End Function


[Хакер] :: Неужели с первого раза не доходит, в чём разница тегом code и icode? Неужели после второго раза, когда было увидено сообщение с невероятно омерзительным внешним видом, не стало ясно, что тег icode вместо code был выбран зря?


Заранее спасибо.
Последний раз редактировалось romeo91 20.03.2012 (Вт) 9:46, всего редактировалось 2 раз(а).

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение Хакер » 20.03.2012 (Вт) 9:15

Неправильно описал. 4-ый параметр должен быть ByVal. Ибо в оригинале PTSTR ReturnBuffer, а не PTSTR *ReturnBuffer.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

romeo91
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.06.2005 (Чт) 9:48

Re: помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение romeo91 » 20.03.2012 (Вт) 9:43

Поправил, все равно возвращает пустое значение. А результат работы функции равен 0, т.е ошибок вроде как нет.
Также не совсем ясно, должен ли я что-то делать с переменной as12 (as psp_platform_info), она вроде как опциональна

шапку тоже поправил

P.S. Спасибо за правку поста, если честно то не догадался ни с первого, ни со второго раза.

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Re: помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение Kostyan » 20.03.2012 (Вт) 23:22

Попробуй вместо sBuffer = Space$(MAX_PATH) сделать так: sBuffer = String$(MAX_PATH, 0)
Ну и собственно не нужно в предпоследнем параметре делать это: Len(sBuffer), можно просто написать MAX_PATH
Нет ничего невозможного для человека с интеллектом.

romeo91
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.06.2005 (Чт) 9:48

Re: помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение romeo91 » 21.03.2012 (Ср) 8:52

Kostyan писал(а):Попробуй вместо sBuffer = Space$(MAX_PATH) сделать так: sBuffer = String$(MAX_PATH, 0)
Ну и собственно не нужно в предпоследнем параметре делать это: Len(sBuffer), можно просто написать MAX_PATH

Аналогично. Не помогает.
Даже пробовал Юникодовый вариант функции.

Вот последний вариант кода модуля
Код: Выделить всё
Option Explicit

Private Type PSP_ALTPLATFORM_INFO
    cbSize As Long
    Platform As Long
    MajorVersion As Long
    MinorVersion As Long
    ProcessorArchitecture As Integer
    Reserved As Integer
End Type

Private Const MAX_PATH As Long = 260

Private Declare Function SetupGetInfDriverStoreLocationA _
               Lib "setupapi.dll" (ByVal FileName As String, _
                                   AlternatePlatformInfo As PSP_ALTPLATFORM_INFO, _
                                   ByVal LocaleName As String, _
                                   ByVal ReturnBuffer As String, _
                                   ByVal ReturnBufferSize As Long, _
                                   ByRef RequiredSize As Long) As Long

Private Declare Function SetupGetInfDriverStoreLocationW _
               Lib "setupapi.dll" (ByVal FileName As Long, _
                                   AlternatePlatformInfo As PSP_ALTPLATFORM_INFO, _
                                   ByVal LocaleName As String, _
                                   ByVal ReturnBuffer As Long, _
                                   ByVal ReturnBufferSize As Long, _
                                   ByRef RequiredSize As Long) As Long

Private Declare Function FormatMessage _
                Lib "kernel32.dll" _
                Alias "FormatMessageA" (ByVal dwFlags As Long, _
                                        lpSource As Any, _
                                        ByVal dwMessageId As Long, _
                                        ByVal dwLanguageId As Long, _
                                        ByVal lpBuffer As String, _
                                        ByVal nSize As Long, _
                                        Arguments As Long) As Long

Private Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000

Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long

Sub Main()

    MsgBox FuncA("c:\Windows\inf\oem8.inf")
    MsgBox FuncA("oem8.inf")
   
    MsgBox FuncW("c:\Windows\inf\oem8.inf")
    MsgBox FuncW("oem8.inf")
End Sub

Public Function FuncA(sInfPath As String) As String

    Dim sBuffer As String
    Dim as12    As PSP_ALTPLATFORM_INFO
    Dim ret     As Long

    sBuffer = String$(MAX_PATH, 0)
    ret = SetupGetInfDriverStoreLocationA(sInfPath, as12, 0&, sBuffer, MAX_PATH, 0&)
    FuncA = TrimNull(sBuffer)

    If ret <> 0 Then
        MsgBox "Возвратное значение: " & ret & " - Err №" & Err.LastDllError & " - " & ApiErrorText(Err.LastDllError)
    End If
End Function

Public Function FuncW(sInfPath As String) As String

    Dim sBuffer As String
    Dim as12    As PSP_ALTPLATFORM_INFO
    Dim ret     As Long

    sBuffer = String$(MAX_PATH, vbNullChar)
    ret = SetupGetInfDriverStoreLocationW(StrPtr(sInfPath), as12, 0&, StrPtr(sBuffer), MAX_PATH, 0&)
    FuncW = TrimNull(sBuffer)

    If ret <> 0 Then
        MsgBox "Возвратное значение: " & ret & " - Err №" & Err.LastDllError & " - " & ApiErrorText(Err.LastDllError)
    End If
End Function

' получаем значение из буфера данных
Public Function TrimNull(ByVal startstr As String) As String

    TrimNull = Left$(startstr, lstrlenW(StrPtr(startstr)))
End Function

Public Function ApiErrorText(ByVal errNum As Long) As String

    Dim Msg  As String
    Dim nRet As Long

    Msg = Space$(1024)
    nRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, ByVal 0&, errNum, 0&, Msg, Len(Msg), ByVal 0&)

    If nRet Then
        ApiErrorText = Replace$(Left$(Msg, nRet), vbNewLine, vbNullString, , , vbTextCompare)
    Else
        ApiErrorText = "Error (" & errNum & ") not defined."
    End If
End Function

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение Хакер » 21.03.2012 (Ср) 10:12

Замена «A» на «W» не решает всех проблем. Надо ещё все сроковые параметры менять со String-а на Long (или As Any) и передавать StrPtr (или ByVal StrPtr). Все.

Общая рекомендация такая: внимательно читать документацию, обращать внимание на каждые мелочи в ней, и пытаться обнаружить какое-то отличие между описанной в документации методикой работы с функцией и реально практикуемой методикой.

Например в документации написано, что нужно вызывать SetupDiGetDriverInfoDetail, а потмо уже SetupGetInfDriverStoreLocation. Возможно дело в этом: возможно между вызовами этих двух функций сохраняется какое-то внутреннее состояние, хотя конечно это глупо.

У меня нет Висты чтобы проверить в чём дело.

Ещё как вариант: посмотреть LastDllError после вызова (даже с учётом возвращённого нуля), но убедиться код (если он будет ненулевым) установился именно после вызова этой функции, а не где-то раньше.

И вообще, как ты определяешь, правильно ли она работает или нет? Может быть она работает правильно, просто ты ожидаешь от неё чего-то того, на что она изначально не расчитана.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

romeo91
Начинающий
Начинающий
 
Сообщения: 4
Зарегистрирован: 02.06.2005 (Чт) 9:48

Re: помощь по Api-функции SetupGetInfDriverStoreLocation

Сообщение romeo91 » 21.03.2012 (Ср) 14:19

Ура. Заработало.

Я при вызове функции для строкового параметра (ByVal LocaleName As String) указывал значение 0&, вот функция и не работала.
Спасибо всем за помощь!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 68

    TopList