Articles - Дело о SHGetFolderPath(CSIDL_COMMON_DOCUMENTS), возвращающей ERROR_PATH_NOT_FOUND | BESK.SU - программирование без границ (c) 2025

Articles Дело о SHGetFolderPath(CSIDL_COMMON_DOCUMENTS), возвращающей ERROR_PATH_NOT_FOUND

FireWind

Завсегдатай
Moderator
Credits
586
Дело о SHGetFolderPath(CSIDL_COMMON_DOCUMENTS), возвращающей ERROR_PATH_NOT_FOUND
Александр Алексеев

[SHOWTOGROUPS=4,20]
Дело о SHGetFolderPath(CSIDL_COMMON_DOCUMENTS), возвращающей ERROR_PATH_NOT_FOUND
Александр Алексеев

Это перевод Как увидеть ссылки? | How to see hidden links?. Автор: Реймонд Чен.

У клиента возникла проблема с Как увидеть ссылки? | How to see hidden links?. В частности, у них была программа, которая вызывала функцию так:
1SHGetFolderPath(0, CSIDL_COMMON_DOCUMENTS, 0, SHGFP_TYPE_CURRENT, PChar(pathBuffer));
но вызов функции возвращал ошибку $80070003 - это HRESULT-версия для ERROR_PATH_NOT_FOUND. Ошибка возникает только при запуске из Как увидеть ссылки? | How to see hidden links?. Если же программа запускается автономно, то функция завершается успешно и возвращает ожидаемый результат.
Трассировка от procmon показала, что приложение пыталось получить доступ к папке C:\Windows\SysWOW64\autobuild\Documents и потерпело неудачу с ошибкой NAME_NOT_FOUND. Это и была подсказка к тому, почему всё сломалось.

По умолчанию папка Common Documents имеет значение %PUBLIC%\Documents. Обычное значение переменной среды PUBLIC - это C:\Users\Public, но когда программа запускается как часть Jenkins pipeline, для переменной среды по какой-то причине задается значение autobuild.

Это означает, что когда программа вызывает SHGetFolderPath и запрашивает CSIDL_COMMON_DOCUMENTS - система ищет папку autobuild\Documents, которая не существует, поэтому возникает ошибка $80070003: "Система не может найти указанный путь".

Есть ряд переменных среды, которые имеют особое значение, и вы меняете их на свой страх и риск. Вы, вероятно, знаете о таких переменных, как windir, ProgramFiles и TEMP, но существует множество других специальных переменных среды - и PUBLIC является одной из них.

Вооружившись этой информацией, клиент начал искать, кто портит переменную среды PUBLIC, и попытаться его остановить.
[/SHOWTOGROUPS]
 
Сверху