Список функций для получения текста ошибок из их кодов (WinAPI)



Здраствуйте!

Представляю обзор функций для получения текста ошибок из их кодов, который представлен в программе Error Lookup.

1. FormatMessage

Эта функция не такая уж и простая как может показаться (большая часть функционала в вышеупомянутой программе реализована через неё, т.к. эту функцию можно настроить на получение НЕ только системных кодов ошибок, см. пункт 2). По умолчанию функция выдаёт код системной ошибки.

Пример:
Функция получает текст ошибки из кода системных ошибок

// пример получения текста системной ошибки
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 1337, 0, lpszBuffer, cchBuffer, NULL);

printf("Error Code: %d\nError Name: %s", 1337, lpszBuffer);


Результат:
Error Code: 1337
Error Text: Идентификатор безопасности имеет неверную структуру.

2. FormatMessage + FORMAT_MESSAGE_FROM_HMODULE

При установленном флаге FORMAT_MESSAGE_FROM_HMODULE можно загрузить список ошибок из модуля (DLL) в котором находится список ошибок:
  • ntdll.dll — список ошибок NTSTATUS
  • wininet.dll — список ошибок Wininet
  • pdh.dll — список ошибок Performance Data Helper
  • … допишите в комментариях если знаете ещё


Также этот метод можно использовать и в своих проектах, нужно лишь упаковать ресурс типа message table внутрь библиотеки (спасибо ertaquo)

Пример:
В этом примере база ошибок загружается из файла ntdll.dll

// загружаем ntdll.dll для получения текста NTSTATUS ошибки
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, LoadLibrary("ntdll.dll"), -1072037872, 0, lpszBuffer, cchBuffer, NULL);

printf("Error Code: %d\nError Name: %s", -1072037872, lpszBuffer);


Результат:
Error Code: -1072037872
Error Text: Служба журнала обнаружила попытку ошибочного выделения или освобождения зарезервированного пространства.

3. DXGetErrorString & DXGetErrorDescription

  • DXGetErrorString — функция для получения имени ошибки (например ERROR_INVALID_SID)
  • DXGetErrorDescription — функция для получения текста ошибки (например The security ID structure is invalid.)


Пример:
Пример получения ошибки DirectX:

// получение текста DirectX ошибки
printf("Error Code: %d\nError Name: %s\nError Text: %s", 1337, DXGetErrorString((HRESULT)1337), DXGetErrorDescription((HRESULT)1337));


Результат:
Error Code: 1337
Error Name: ERROR_INVALID_SID
Error Text: The security ID structure is invalid.

4. RasGetErrorString

Эта функция для получает текст ошибки из библиотеки функций RAS

Пример:
Функция получает текст ошибки из кода RAS ошибок

// пример получения текста RAS ошибки
RasGetErrorString(633, lpszBuffer, cchBuffer);

printf("Error Code %d\nError Text: %s", 633, lpszBuffer);


Результат:
Error Code: 633
Error Text: Модем или другое устройство связи уже используется или не настроено.

5. GetIpErrorString

Эта функция для получения текста ошибки из библиотеки функций IP Helper Library

Пример:
Функция получает текст ошибки

// получаем текст ошибки IP Helper Library
GetIpErrorString(12, lpszBuffer, cchBuffer);

printf("Error Code %d\nError Text: %s", 12, lpszBuffer);


Результат:
Error Code: 12
Error Text: General failure.

Бонус

Ссылки на скачивание программы

Комментарии 11

    +1
    Как же всё стало удобнее с появлением IErrorInfo.
      0
      ну а я по старинке — WinAPI, и спасибо за IErrorInfo — посмотрю
        +1
        Оно, увы, только для продвинутых COM-объектов его поддерживающих. Для «деревянных» всё так же приходится использовать FormatMessage.
      +1
      Глупый вопрос:
      Это точно что-то, что следует описывать в статье и чего нет в документации к библиотекам?
        0
        Может быть и не следует, но…
        1) это список этих функций с примерами, а не их документация
        2) к 3 пункту в английском MSDN нет информации, только на японском
          +2
          Довольно печально осознавать, что для таких функций нужны примеры и не хватает документации… Всё сугубо имхо.
            +1
            Смысл этой статьи НЕ показать примеры, а рассказать какие функции существуют для получения текста ошибок (ну а примеры в виде дополнения). Просто когда я начинал, я кроме FormatMessage никаких функций не знал, вот решил помочь таким же как я
        +1
        По поводу второго пункта стоит упомянуть, что его вполне можно использовать в своих библиотеках. Нужно всего лишь упаковать внутрь библиотеки ресурс типа message table.
          0
          только в примере тамошнем течь ресурсов (LoadLibrary все ж)… хотя вообще говоря примеры на то и примеры, чтобы не тупо копипастить…
            0
            В данном примере LoadLibrary(«ntdll.dll») не вызовет течь. Под NT ntdll.dll и так всегда загружена в процесс. Лишь инкрементирует счетчик загруженной библиотеки. Разве что не эстетично это. Так лучше было бы: GetModuleHandle(«ntdll.dll»).
          +3
          Можно еще Рихтера упомянуть. Он в самом начале своей книги приводит реализацию функции сообщений об ошибках. А еще в Visual Studio можно в Watch добавить переменную
          @err,hr
          — она будет показывать код последней ошибки и сообщение. Об этом тоже можно почитать у Рихтера.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое