Share via


PreviousMode

Cuando una aplicación en modo de usuario llama a la versión Nt o Zw de una rutina de servicios del sistema nativo, el mecanismo de llamada del sistema intercepta el subproceso de llamada al modo kernel. Para indicar que los valores de parámetro se originaron en modo de usuario, el controlador de capturas de la llamada del sistema establece el campo PreviousMode en el objeto de subproceso del autor de la llamada en UserMode. La rutina de servicios del sistema nativo comprueba el campo PreviousMode del subproceso que realiza la llamada para determinar si los parámetros proceden de un origen en modo de usuario.

Si un controlador en modo kernel llama a una rutina de servicios del sistema nativo y pasa valores de parámetro a la rutina que procede de un origen en modo kernel, el controlador debe asegurarse de que el campo PreviousMode del objeto de subproceso actual está establecido en KernelMode.

Un controlador en modo kernel se puede ejecutar en el contexto de un subproceso arbitrario y el campo PreviousMode de este subproceso se puede establecer en UserMode. En esta situación, un controlador en modo kernel puede llamar a la versión Zw de una rutina de servicios del sistema nativo para informar a la rutina de que los valores de parámetro proceden de un origen de modo kernel de confianza. La llamada zw va a una función contenedora fina que invalida el valor PreviousMode en el objeto de subproceso actual. La función contenedora establece PreviousMode en KernelMode y llama a la versión Nt de la rutina. Cuando se devuelve desde la versión Nt de la rutina, la función contenedora restaura el valor PreviousMode original del objeto de subproceso y devuelve.

Un controlador en modo kernel puede llamar directamente a la versión Nt de una rutina de servicios del sistema nativo. Cuando un controlador en modo kernel procesa una solicitud de E/S que puede originarse en modo de usuario o en modo kernel, el controlador puede llamar a la versión Nt de la rutina para que el valor PreviousMode del subproceso actual permanezca inalterado durante la llamada. La rutina NtXxx comprueba el valor PreviousMode del subproceso que realiza la llamada para determinar si los valores de parámetro proceden de una aplicación en modo de usuario o de un componente en modo kernel, y los trata en consecuencia.

Se puede producir un error si un controlador en modo kernel llama a una rutina NtXxx y el valor PreviousMode del objeto de subproceso actual no indica con precisión si los valores de parámetro proceden de un modo de usuario o de un origen en modo kernel.

Por ejemplo, supongamos que un controlador en modo kernel se ejecuta en el contexto de un subproceso arbitrario y que el valor PreviousMode de este subproceso se establece en UserMode. Si el controlador pasa un identificador de archivo en modo kernel a la rutina NtClose , esta rutina comprueba el valor PreviousMode y decide que el identificador debe ser un identificador en modo de usuario. Cuando NtClose no encuentra el identificador en la tabla de identificadores del modo de usuario, devuelve el código de error STATUS_INVALID_HANDLE. Mientras tanto, el controlador filtra el identificador del modo kernel, que nunca se cerró.

Por otro ejemplo, si los parámetros de una rutina NtXxx incluyen un búfer de entrada o salida y, si PreviousMode UserMode = , la rutina llama a la rutinaProbeForRead o ProbeForWrite para validar el búfer. Si el búfer se asignó en la memoria del sistema en lugar de en la memoria en modo de usuario, la rutina ProbeForXxx genera una excepción y la rutina NtXxx devuelve el código de error de STATUS_ACCESS_VIOLATION.

Si es necesario, un controlador puede llamar a la rutina ExGetPreviousMode para obtener el valor PreviousMode del objeto de subproceso actual. O bien, el controlador puede leer el campo RequestorMode de la estructura IRP que describe la operación de E/S solicitada. El campo RequestorMode contiene una copia del valor PreviousMode del subproceso que solicitó la operación.