Соглашение
__stdcall
обязывает пользователя функции передать параметры функции на стеке по значению, но освобождает его чистить стек после вызова. Стек от параметров чистит сама вызванная функция.
В результате подмены сигнатуры с
BOOL (__stdcall *)(HANDLE, PBOOL)
на
bool (__stdcall *)(void*, bool*)
компилятор думает об одном размере стека, а код функции - о других.
Поэтому сигнатуры и соглашение о вызове импортируемой функции всегда должны совпадать с объявлением этой функции в импортируемой библиотеке! Вообще всегда! Даже при условии следующего текста.
Однако, конкретно тут проблема у нас не в несовпадении типов, потому что.
__stdcall
свой результат передает через регистр. регистр используется целочисленный или вещественный. Для целочисленного регистра используется правило
продвижения типа. Это означает, что функция, записав значение типа
BOOL
(размер 4Б) ничего не испортит пользовательскому коду, который прочитает из регистра все 4Б с учетом правила продвижения.
Реальная проблема кроется в том, что указатель на однобайтовое целое (
bool*
) передается в использование как указатель на четырехбайтовое целое (
BOOL*
или
PBOOL
). Вызываемая функция ведь имеет сигнатуру
BOOL (__stdcall *)(HANDLE, PBOOL)
и со вторым параметром работает как с 4Б целым по указателю.
Именно это и приводит к порче стека и тебе, автор, сильно повезло что ты запускаешься в отладке, где каждое значение на стеке обрамлено заборчиком, за сохранностью которого всегда приглядывает специальный сервисный код между обращениями к подпрограммам.
Именно такой заборчик рядом с
isWow64
и был поломан в результате вызова
IsWow64Process
с параметром неподходящей длины. Измени тип
isWow64
на
BOOL
и все станет нормально, даже хендл
"kernel32.dll"
потом сможешь нормально освободить.