Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Когда приложение в режиме пользователя вызывает Nt или Zw версию рутинного вызова собственных системных служб, то механизм вызова системы переводит вызывающий поток в режим ядра. Чтобы указать, что значения параметров были установлены в пользовательском режиме, обработчик ловушки для системного вызова задает поле PreviousMode в объекте потока вызывающего в UserMode. Подпрограмма собственных системных служб проверяет поле PreviousMode вызывающего потока, чтобы определить, являются ли параметры из источника пользовательского режима.
Если драйвер в режиме ядра вызывает подпрограмму собственных системных служб и передает значения параметров подпрограмме из источника режима ядра, драйвер должен убедиться, что поле PreviousMode в текущем объекте потока имеет значение KernelMode.
Драйвер режима ядра может выполняться в контексте произвольного потока, а поле PreviousMode этого потока может иметь значение UserMode. В этой ситуации драйвер в режиме ядра может вызывать версию Zw собственной системной службы, чтобы сообщить подпрограмме, что значения параметров находятся из доверенного источника в режиме ядра. Вызов Zw переходит к облегчённой функции-оболочке, которая переопределяет значение PreviousMode в текущем объекте потока. Оборачивающая функция устанавливает PreviousMode в KernelMode и вызывает версию процедуры Nt. При возврате из версии Nt подпрограммы функция-оболочка восстанавливает исходное значение PreviousMode объекта потока и завершает выполнение.
Драйвер в режиме ядра может напрямую вызывать рутинную процедуру системных служб Nt. Когда драйвер в режиме ядра обрабатывает запрос ввода-вывода, который может возникать либо в пользовательском режиме, либо в режиме ядра, драйвер может вызывать версию подпрограммы NT , чтобы значение PreviousMode текущего потока оставалось неуправляемым во время вызова. Подпрограмма NtXxx проверяет значение PreviousMode вызывающего потока, чтобы определить, поступили ли значения параметров из приложения пользовательского режима или компонента режима ядра, и обрабатывает их соответствующим образом.
Ошибка может возникать, если драйвер в режиме ядра вызывает подпрограмму NtXxx и значение PreviousMode в текущем объекте потока не точно указывает, являются ли значения параметров из пользовательского режима или источника в режиме ядра.
Например, предположим, что драйвер в режиме ядра выполняется в контексте произвольного потока, и значение PreviousMode для этого потока имеет значение UserMode. Если драйвер передает дескриптор файла режима ядра подпрограмме NtClose , эта подпрограмма проверяет значение PreviousMode и решает, что дескриптор должен быть дескриптором пользовательского режима. Если NtClose не находит дескриптор в таблице дескрипторов пользовательского режима, он возвращает код ошибки STATUS_INVALID_HANDLE. Между тем драйвер допускает утечку дескриптора режима ядра, который никогда не был закрыт.
Например, если параметры для подпрограммы NtXxx включают входной или выходной буфер, а если PreviousMode UserMode = , подпрограмма вызывает подпрограммуProbeForRead или ProbeForWrite для проверки буфера. Если буфер был выделен в системной памяти вместо памяти в пользовательском режиме, подпрограмма ProbeForXxx вызывает исключение, а подпрограмма NtXxx возвращает код ошибки STATUS_ACCESS_VIOLATION.
При необходимости драйвер может вызвать подпрограмму ExGetPreviousMode , чтобы получить значение PreviousMode из текущего объекта потока. Или драйвер может считывать поле RequestorMode из структуры IRP , описывающей запрошенную операцию ввода-вывода. Поле RequestorMode содержит копию значения PreviousMode из потока, запрашивающего операцию.