Использование 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