На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Как узнать откуда LoadLibrary неудачно пытался загрузить DLL ?
    В своём win32-приложении хочу использовать некую стороннюю но широкоизвестную DLL. Винда 64-битная…

    Если этой DLL в моей папке не лежит - то LoadLibrary() её ищет в том числе и в C:\Program Files, C:\ProgramData. И находит там 64-битную версию в домашней папке какой-либо чужой проги (я это вижу при помощи ProcMon).

    Итог - ошибка 193 (0xC1) ERROR_BAD_EXE_FORMAT - «%1 is not a valid Win32 application.»

    Но как мне в своей программе узнать где лежит эта 64-битная DLL которая вызвала ошибку в LoadLibrary() ???
    Если LoadLibrary() загрузил нормальную 32-битную DLL - то её файл можно найти через GetModuleFileName(). А если DLL не загрузилась - то как искать?

    Чтобы красиво сообщить пользователю о проблеме: «Ошибка загрузки DLL, файл C:\Program Files\ZZZ\XXX.dll не является приложением Win32.»
    А то вообще FormatMessage на эту ошибку сообщает не понятное «%1 не является приложением Win32.»…

    PS. причём в Program Files валяется и несколько 32-битных версий этой DLL, но LoadLibrary до них не доходит натыкаясь на 64-битную версию.
      Цитата f2065 @
      PS. причём в Program Files валяется и несколько 32-битных версий этой DLL, но LoadLibrary до них не доходит натыкаясь на 64-битную версию.

      Тогда получается, что главная задача - обнаружить "правильную" dll
      и использовать её.
      Если сразу не удалось загрузить dll, тогда
      можно просто устроить поиск файлов в конкретных директориях.
      И попробовать все найденные варианты, используя полные пути.
        Может тогда лучше юзать LoadLibraryEx ??
        Обрати внимание на третий параметр этой функции.
          Цитата Wound @
          Обрати внимание на третий параметр этой функции.

          А что именно?
          Я там пробовал DONT_RESOLVE_DLL_REFERENCES сделать (надеялся тогда система не поймёт что это win64-файл, я посмотрю путь, а потом уже вручную сделаю DllMainEntry) - но это не сработало, такая же ошибка ERROR_BAD_EXE_FORMAT сразу.

          Варианты ограничивать поиск не подходят, цель именно узнать на какой DLL возникла проблема.
            Цитата f2065 @
            Варианты ограничивать поиск не подходят, цель именно узнать на какой DLL возникла проблема.

            Почему не подходят? Что тебе мешает сделать то, что делает функция LoadLibrary? Она ищет в системных директориях подходящие библиотеки. Ты можешь ей это запретить, и сам поискать в этих дерикториях. На какой упадет с нужным тебе результатом, тот и выдавай.

            Добавлено
            Напихать в массив стрингов системные директории, и потом в цикле просто идти по ним, формировать нужный путь к файлу, пытаться загружать - ловить ошибку. Анализировать ошибку. Выдавать результат. Не вижу проблемы. Ты ее сам выдумал.

            Добавлено
            Если еще конкретнее: Ты можешь просто запретить этой функции искать где либо библиотеку, вызывая ее с определенным флагом, чтоб искала тупо в твоей директории. Если там нет библиотеки, а узнать ты это можешь например через GetLastError(), тогда искать в других системных дирректориях, прочитав про них по ссылке выше(где эта функция ищет библиотеки и в каком порядке), и как только тебе GetLastError(), возвратит код не что то типа FILE_NOT_FOUND, а например FILE_LOAD_ERROR или что то подобное, это я сам придумал эту ошибку чтоб ты понимал суть(ты можешь посмотреть коды ошибок в гугле, и выбрать подходящие), тогда вот тебе уже будет понятно, что файл есть, но он не грузится, значит в нем проблема. Можно даже проигнорить эту ошибку и попытаться поискать дальше, если это имеет смысл. И в итоге даже выдать несколько путей в сообщении об ошибке, мол де найдены вот такие библиотеки - но они не грузятся.

            Добавлено
            Вот тут коды ошибок GetLastError -> https://docs.microsoft.com/ru-ru/windows/wi...tem-error-codes в конец мотай на System Error Codes и там ссылки идут по номерам.
            Тебя скорее всего заинтересуют с 0 по 499 -> https://docs.microsoft.com/ru-ru/windows/wi...r-codes--0-499-
            ExpandedWrap disabled
              ERROR_SUCCESS
               
                  0 (0x0)
               
                  The operation completed successfully.
               
              ERROR_INVALID_FUNCTION
               
                  1 (0x1)
               
                  Incorrect function.
               
              ERROR_FILE_NOT_FOUND
               
                  2 (0x2)
               
                  The system cannot find the file specified.
               
              ERROR_PATH_NOT_FOUND
               
                  3 (0x3)
               
                  The system cannot find the path specified.
               
              ERROR_TOO_MANY_OPEN_FILES
               
                  4 (0x4)
               
                  The system cannot open the file.
               
              ERROR_ACCESS_DENIED
               
                  5 (0x5)
               
                  Access is denied.
               
              ERROR_INVALID_HANDLE
               
                  6 (0x6)
               
                  The handle is invalid.


            Добавлено
            Ну и в принципе даже так, ты можешь выхватить ошибку, и проверить GetLastError, если вернула не 0, значит ошибка, смотри номер ошибки и ищи ее описание, хотя бы по ссылке выше. Либо прямо в студии например в меню Tools(ЕМНИП) есть специальная тулза, которая по номеру ошибки вернет ее описание.
            Сообщение отредактировано: Wound -
              Цитата Wound @
              Если еще конкретнее: Ты можешь просто запретить этой функции искать где либо библиотеку, вызывая ее с определенным флагом, чтоб искала тупо в твоей директории.

              Есть такая функция - "SetDllDirectory".
              А директорий, откуда предполагается загрузка dll, не так много.
                Цитата ЫукпШ @
                Есть такая функция - "SetDllDirectory".

                Ну может быть. Если нужна какая то отличная от текущей директории, папка. А так по умолчанию, эта функция в текущей ищет для начала, а потом в остальных.

                Цитата ЫукпШ @

                А директорий, откуда предполагается загрузка dll, не так много.

                Да, и все они описаны в msdn'e, И даже в каком порядке их обходит LoadLibrary описано. Поэтому не вижу проблемы написать обертку, которая ищет в нужных директориях библиотеку, и если не может загрузить - выдает ошибку.
                Сообщение отредактировано: Wound -
                  Где-то, когда-то, откуда-то ... я себе оставил заметочку по поводу поиска DLL-ек:

                  • The directory where the executable module for the current process is located
                  • The current directory
                  • The Windows system directory. The GetSystemDirectory function retrieves the path of this directory
                  • The Windows directory. The GetWindowsDirectory function retrieves the path of this directory
                  • The directories listed in the PATH environment variable

                  Может быть как-то поможет :-?
                    Цитата f2065 @
                    В своём win32-приложении хочу использовать некую стороннюю но широкоизвестную DLL

                    Ну так и держи её рядом со своим исполняемым модулем! В чём проблема-то? Или такое рабоче-крестьянское решение не устраивает?
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0444 ]   [ 16 queries used ]   [ Generated: 16.04.24, 12:29 GMT ]