Использование 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
Избранное
Остальное
Лента atom