Pull to refresh

Comments 11

3-я нулевыми байтами.
Один из этих «нулевых байт» — обрезок первого символа, а разделителем служит нулевой символ (они там по два байта на символ, UCS-2 же).
Приношу свои извинения, скорректировал. Это был огрызок символа. Всё верно, два нулевых байта как widechar.
Рантайм не следит за PEB, так что подмена PEB не заставляет кэш обновляться. Наблюдаемый эффект объясняется следующим образом: на момент первого вызова _wdupenv_s unicode-кэша просто нет, потому что до этого никакие unicode-функции работы с окружением не вызывались. Следовательно, первый вызов _wdupenv_s лезет в текущее окружение — в котором NewVar есть — кэширует его и возвращает информацию из текущего окружения. Следующий вызов возвращает кэшированную информацию, поэтому не видит, что PEB изменён.

Пример программы нетипичен. С одной стороны, используется функция main, а не wmain, так что компоновщик выбирает startup-код в ANSI-версии, который заполняет кэш _environ, но не _wenviron. С другой стороны, сама функция main вызывает w-функции. Если заменить main на wmain — дописать одну букву в коде, ага, — эффект исчезнет.
Ну соль вообщем в том, чтобы использовать SetEnvironmentVariable/GetEnvironmentVariable etc и не париться с getenv.
Я делал упор на замену таблицы в целом и предложил вариант с использованием соответствующих интерфейсов. Этого достаточно, чтобы решить проблему, возникшую у исторического автора.

Остальное просто банальный интерес.
Если уже так принципиально, то можно попробовать найти в хипе рантайма кэш этот и вставить туда свою переменную.
Спасибо, учту на будущее.
К сожалению у меня не так много кармы, чтобы заплюсовать Ваш комент про «интринсики». Вы реально облегчили мне жизнь только что!!!
А можно код дополнить комментариями? Или мне одному он неясен? :)
Sign up to leave a comment.

Articles