Структурированные коды исключений определяются через номера NTSTATUS. Хотя кто-то из MS предлагает , используя FormatMessage () для преобразования чисел NTSTATUS в строки, я бы не стал этого делать. Флаг FORMAT_MESSAGE_FROM_SYSTEM
используется для преобразования результата GetLastError () в строку, поэтому здесь нет смысла. Использование флага FORMAT_MESSAGE_FROM_HMODULE
вместе с ntdll.dll
приведет к неверным результатам для некоторых кодов. Например, за EXCEPTION_ACCESS_VIOLATION
вы получите The instruction at 0x
, что не очень информативно :).
Когда вы смотрите на строки, хранящиеся в ntdll.dll
, становится очевидным, что многие из них должны использоваться с функцией printf () , а не с FormatMessage () . Например, строка для EXCEPTION_ACCESS_VIOLATION
:
The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
%0
обрабатывается FormatMessage () как escape-последовательность, означающая терминатор сообщения, а не вставка. Вставки от% 1 до% 99. Вот почему флаг FORMAT_MESSAGE_IGNORE_INSERTS
не имеет значения.
Возможно, вы захотите загрузить строку из ntdll.dll
и передать ее в vprintf, но вам нужно будет подготовить аргументы в точности так, как указано в строке (например, для EXCEPTION_ACCESS_VIOLATION
это unsigned long
, unsigned long
, char*
) , И у этого подхода есть существенный недостаток: любое изменение числа, порядка или размера аргументов в ntdll.dll
может нарушить ваш код.
Так что безопаснее и проще кодировать строки в ваш собственный код. Я считаю опасным использование строк, подготовленных кем-то другим, без согласования со мной :) и, более того, для других функций. Это еще одна возможность неисправности.