Использование Native API для получения текста сообщения по номеру ошибки
Приведённая пара функций позволяет получать текст ошибки не только для «родных» кодов ошибок (обычно их обозначают как NTSTATUS и их список есть в ntstatus.h в DDK), но и обычные ошибки (например 5 из kernel32.dll — Access Denied), и ошибки NetApi, и любые другие, лишь бы соответствующий модуль был загружен в процесс. Требование загруженности модуля вполне логичное, ибо генерирует номера ошибок всё-таки он. По хорошему перечисление потоков надо оборачивать в захват и освобождение критической секции Peb->LoaderLock, она должна захватываться при любой модификации структур данных загрузчика, что оставляю в качестве домашнего задания.
Функция GetMsg ищет сообщение по значению ns, если сообщение найдено, для него выделяется память в *p.
NTSTATUS NTAPI GetMsg(IN HANDLE hModule, IN NTSTATUS ns, OUT PWSTR *p)
{
PRTL_MESSAGE_RESOURCE_ENTRY pmsg;
if ((RtlFindMessage(hModule, 0x0B, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
ns, &pmsg)) == STATUS_SUCCESS)
{
if (*p = (PWSTR)malloc((pmsg->Length+2)))
{
swprintf(*p,(pmsg->Flags & MESSAGE_RESOURCE_UNICODE)
? L"%s" : L"%S", pmsg->Text);
return STATUS_SUCCESS;
}
return STATUS_NO_MEMORY;
}
return STATUS_OBJECT_NAME_NOT_FOUND;
}
Функция FindMsg ищет сообщение по значению ns во всех модулях, загруженных в процесс.
NTSTATUS NTAPI FindMsg(IN NTSTATUS ns, OUT PWSTR *p)
{
PLIST_ENTRY f = &(pPeb->ProcessModuleInfo->ModuleHeader.InLoadOrderModuleList);
PLIST_ENTRY cur = f;
for (;;)
{
if (GetMsg(((PLDR_MODULE)cur)->BaseAddress,ns,p) == STATUS_SUCCESS)
return STATUS_SUCCESS;
cur = cur->Flink;
if (cur == f)
return STATUS_OBJECT_NAME_NOT_FOUND;
}
}
Автор: Сергей Васкецов
Дата: 29.01.2003
Избранное
Остальное
По вопросам сотрудничества и другим вопросам по работе сайта пишите на cleogroup[собака]yandex.ru