SetEnvironmentVariable в 32-битном процессе в 64-битной ОС Windows

Недавно обнаружил интересную проблему. При использовании SetEnvironmentVariable я могу использовать Process Explorer для получения вновь созданной переменной среды. Однако, когда сам процесс является 32-разрядным, а ОС - 64-разрядной, Process Explorer (по крайней мере, v10 ~ последняя версия v11.33) не может найти новые переменные. Если программа родная 64-битная, то все работает нормально, как и 32-битный процесс, работающий на 32-битной ОС.

Вызов API SetEnvironmentVariable должен быть успешным, поскольку возвращаемое значение равно TRUE, а вызов GetEnvironmentVariable возвращает правильное значение. Кроме того, если вы создаете дочерний процесс, вы можете обнаружить, что переменная была правильно установлена ​​в новом процессе с помощью Process Explorer.

Нет, если это ограничение SysWOW64 или ошибка в Process Explorer. Кто-нибудь знает?

И есть ли способ правильно получить 32-битные переменные среды? (например, принудительно запустить Process Explorer в 32-битном режиме или какие-то другие инструменты)

Исходный код для воспроизведения:

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[])
{
    printf("setting variable... %s\n", 
        SetEnvironmentVariable("a_new_var", "1.0") ? "OK" : "FAILED");
    printf("press anykey to continue...\n");
    getchar();
    // system(argv[0]); // uncomment to inspect the child process
    return 0;
}

person Francis    schedule 18.01.2010    source источник


Ответы (1)


Я не уверен, как работает WOW64, но я почти (на 99%) уверен, что созданы два PEB (блока среды процесса) — 32-битный и 64-битный. Структуры параметров процесса (RTL_USER_PROCESS_PARAMETERS), вероятно, также дублируются. Поэтому, когда вы вызываете SetEnvironmentVariable, он изменяет только блок 32-битной среды. PE будет работать как собственная 64-битная программа, что означает, что он знает только о 64-битном PEB и 64-битном блоке среды (который не изменился).

Обновление (2010-07-10):

Немного новой информации по этой старой теме: вы можете найти 32-битный PEB, вызвав NtQueryInformationProcess с ProcessWow64Information. Он дает вам PVOID с адресом PEB.

person wj32    schedule 18.01.2010
comment
Так есть ли способ получить правильные результаты? Я не могу найти API для изменения 64-битного блока env внутри 32-битного процесса, а также никаких переключателей для работы PE в 32-битном режиме... - person Francis; 18.01.2010