2016-02-29 2 views
1

Из моего чтения MSDN documentation, я бы подумал (в случае, когда dll этого базового имени еще не загружен), что передача полного абсолютного имени файла в LoadLibraryExW будет выглядеть только по этому пути.LoadLibraryEx игнорирует полностью заверенное имя пути?

E.g. (Отметим, что это правильный путь CSIDL_SYSTEM, если это имеет значение)

LoadLibraryExW (L"C:\\Windows\\System32\\foobar.dll", LOAD_LIBRARY_AS_DATAFILE); 

должен потерпеть неудачу, если этот файл не существует в этом месте. Но я получаю забавные результаты, которые заставляют меня думать, что он берет базовое имя и применяет его к PATH, в Windows 8.1. и найти файл с тем же именем в другом месте.

Кроме того, если я использую LOAD_LIBRARY_AS_DATAFILE, это мешает мне узнать, где именно он его нашел.

Что делает эта функция действительно в этом отношении и зависит от версии ОС?

(Кстати, я знаю о LOAD_LIBRARY_SEARCH_SYSTEM32, но не существует на всех версиях ОС. Я хочу работать на что-нибудь еще в XP.)

Это особенно сбивает с толку, так как я думал, что используя абсолютный путь был эффективным решением в предыдущее время, когда я увидел, что он обнаружил неправильные файлы через PATH, в качестве переносной альтернативы LOAD_LIBRARY_SEARCH_SYSTEM32. Так что, возможно, это зависит от ОС или каких-то других волшебных изменений.

+0

Вам нужно будет показать код и предоставить тестовый пример с полной информацией. В частности, обратите внимание на применимые флаги «LOAD_», упомянутые в связанной с вами документации. – dxiv

+0

Вы можете использовать Process Monitor (доступный с веб-сайта MS), чтобы подтвердить, действительно ли файл загружается из другого места. Одна мысль: вы помнили использовать обратную косую черту на пути, а не косые черты, не так ли? –

+2

В одном случае, когда я думаю, что полностью определенный путь к DLL будет получен из другого фактического местоположения, когда используется перенаправление Wow64. Если ваше приложение представляет собой 32-разрядное приложение, работающее на ОС Win64, по умолчанию доступ к файлу System32 будет перенаправлен на SysWow64. См. Https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187.aspx Возможно, это то, что происходит с вами? Измените путь к чему-то другому, кроме System32, и я думаю, вы увидите, что функция LoadLibraryEx() завершилась с ошибкой. –

ответ

1

Windows будет игнорировать путь, если уже есть DLL этого имени.

Так что, если есть foobar.dll уже загружен в процессе с каким-либо другим путем, то, даже если вы указали полный, абсолютный путь к другим foobar.dll, он просто возвращает дескриптор первой и ударять счетчик ссылок ,

Отредактировано: Найденный documentation for this behavior:

Если DLL с тем же именем модуля уже загружен в память, система проверяет только для перенаправления и манифест перед разрешающие загруженной DLL, независимо от того, в котором он находится. Система не ищет DLL.

+0

Извините, DLL, о которой идет речь, еще не загружена (с наблюдаемым поведением). Я знаю, что это касается ссылок на существующий загруженный файл. Я уточню вопрос. –

+1

Возможно, вы можете отредактировать вопрос, чтобы показать все сообщения, загруженные модулем, из окна вывода в отладчике. Это должно показать нам, что происходит (в том числе, загружается ли другая DLL с тем же именем). –

2

Я наблюдал с помощью Process Monitor, что полное имя файла, который используется в качестве аргумента для LoadLibraryEx действительно вызывает только этот путь для проверки (то есть, когда это действительно необходимо, чтобы загрузить файл, потому что там нет DLL по этому имени уже загружено). Это наблюдалось для 32-битного процесса.

В случае каталога System32 то, что было указано как аргумент C: \ Windows \ System32, отображается в ProcMon как C: \ Windows \ SysWOW64 в 64-разрядной ОС.

Это наблюдалось в

  • Windows XP SP3, 32-разрядная (странность: если DLL не присутствовал, QueryOpen вызывается дважды с тем же путем)
  • для Windows 7, 32-разрядная
  • для Windows 10, 64-разрядные

Одно предостережение в том, что даже если с именем DLL загружается из указанного каталога абсолютный путь, зависимые библиотеки DLL загружаются с нормальным поиском пути. Это не проблема, если используется LOAD_LIBRARY_AS_DATAFILE.

Смежные вопросы