NTSTATUS — статусные коды ядра Windows¶
NTSTATUS — это 32-битный целочисленный тип данных и система кодов возврата, используемая в операционной системе Microsoft Windows для передачи информации о результате выполнения функций в режиме ядра и пользовательском режиме. Коды NTSTATUS применяются для обозначения успеха, предупреждения, ошибки или необходимости дальнейшей обработки запроса, являясь фундаментальным механизмом обработки ошибок в архитектуре Windows NT.
¶Назначение и область применения
Коды NTSTATUS используются в широком спектре системных компонентов: от драйверов устройств и диспетчера ввода-вывода до системных вызовов Win32 и подсистемы безопасности. В отличие от традиционных кодов ошибок C (errno) или HRESULT, NTSTATUS предоставляет унифицированную схему, позволяющую ядру и драйверам обмениваться структурированной информацией о сбоях. Значение NTSTATUS возвращается функциями вида Zw* (Native API), а также используется внутри структур IRP (I/O Request Packet) для указания статуса завершения операции.
¶Структура кода
Формат NTSTATUS определён в заголовочном файле ntdef.h и состоит из нескольких битовых полей:
- Severity (биты 30–31) — уровень серьёзности:
0— успех (Success),1— информация (Informational),2— предупреждение (Warning),3— ошибка (Error). - Customer (бит 29) — флаг, указывающий, определён ли код производителем оборудования или самой Microsoft.
- Reserved (бит 28) — зарезервированный бит.
- Facility (биты 16–27) — код подсистемы, в которой возникла ошибка (например,
0x00000000— ядро,0x00000001— RPC,0x00000007— Win32). - Code (биты 0–15) — непосредственно номер ошибки в рамках указанной подсистемы.
На практике макросы NT_SUCCESS, NT_INFORMATION, NT_WARNING и NT_ERROR позволяют быстро определить категорию кода. Например, макрос NT_SUCCESS(Status) возвращает истину, если старшие два бита равны нулю (успех или информационный статус).
¶Типовые значения
Многие коды NTSTATUS широко известны разработчикам:
STATUS_SUCCESS (0x00000000)— операция завершилась успешно.STATUS_PENDING (0x00000103)— операция ещё выполняется (асинхронный запрос).STATUS_BUFFER_OVERFLOW (0x80000005)— предупреждение о переполнении буфера.STATUS_ACCESS_DENIED (0xC0000022)— отказ в доступе.STATUS_INVALID_PARAMETER (0xC000000D)— неверный параметр функции.STATUS_INSUFFICIENT_RESOURCES (0xC000009A)— нехватка системных ресурсов.STATUS_UNSUCCESSFUL (0xC0000001)— общая ошибка без уточнения причины.
Эти коды отображаются в пользовательском режиме через механизм RtlNtStatusToDosError, преобразующий их в коды ошибок Win32, либо через формат 0xC0000000 в сообщениях «синего экрана» (BSOD), где указывается конкретный код остановки.
¶Использование в драйверах
Драйверы устройств обязаны возвращать значения NTSTATUS из своих callback-функций (например, DriverEntry, DispatchXxx). При обработке запросов ввода-вывода драйвер устанавливает поле IoStatus.Status в IRP, после чего диспетчер ввода-вывода передаёт результат вызывающему. Особое значение имеет код STATUS_PENDING, который сигнализирует о том, что запрос будет завершён асинхронно. Для корректной обработки ошибок драйверы используют макросы NT_SUCCESS и NT_ERROR, а также функцию IofCompleteRequest для завершения IRP.
¶Преобразование в другие форматы
В Windows существует несколько уровней представления ошибок. NTSTATUS является низкоуровневым форматом, который может быть преобразован:
- в код ошибки Win32 через
RtlNtStatusToDosError; - в HRESULT через макрос
HRESULT_FROM_NT(при этом код помещается в поле Facility); - в строковое описание через
RtlNtStatusToDosErrorиFormatMessage.
Обратное преобразование (из Win32 в NTSTATUS) выполняется макросом RtlGetLastNtStatus.
¶Отладка и диагностика
При отладке ядра коды NTSTATUS выводятся в отладчик (WinDbg) и в журнал событий. Для расшифровки кода применяется команда !error <код> в WinDbg, которая показывает текстовое описание и подсистему. В пользовательском режиме ошибки вида 0xC0000005 (нарушение доступа) часто встречаются при попытке записи в защищённую память, а 0xC0000135 — при невозможности загрузить DLL.
¶Критика и особенности
Сложность системы NTSTATUS связана с её избыточностью: для одной и той же ошибки существуют коды в разных подсистемах, что затрудняет диагностику. Кроме того, многие драйверы возвращают обобщённый STATUS_UNSUCCESSFUL, не раскрывая причину сбоя. Тем не менее, единый формат остаётся стандартом для всех компонентов Windows NT, обеспечивая совместимость между ядром, драйверами и прикладным программным обеспечением.
