Потоковое локальное хранилище в режиме ядра?

Существует ли эквивалент локального потока (TLS) для драйверов режима ядра в Windows (точнее, Win32)?

Чего я пытаюсь добиться:

В конечном итоге изнутри процедуры диспетчеризации моего драйвера он может вызывать многие другие функции (может быть глубокий стэк). Я хочу предоставить некоторую контекстную информацию, относящуюся к обрабатываемому запросу. То есть у меня есть некоторая структура, указатель на которую должен быть виден во всех вызываемых функциях, без явной передачи ее в качестве параметра каждой функции.

Использование static / global не является идеальным вариантом (многопоточность, синхронизация объектов и т. Д.).

Если бы это был код пользовательского режима - очевидно, в такой ситуации можно использовать TLS. Но AFAIK нет функций режима ядра, таких какTlsGetValue/TlsSetValue, И это имеет смысл - чтобы эти функции работали, нужно сначала выделить индекс TLS для всего процесса. Код драйвера OTOH может быть вызван в произвольном потоке, не ограничиваясь конкретным процессом.

Однако мне на самом деле не нужнастойкий специфичное для потока хранилище. Мне просто нужно специфичное для потока хранилище для вызова функций верхнего уровня.

Я думаю, что знаю, как «реализовать» TLS, хотя и хакерским способом. Вместо выделения индекса TLS я всегда буду использовать предопределенный индекс (скажем, index = 0). В функции верхнего уровня я сохраню сохраненное значение TLS и перезапишу его нужным значением. По завершении сохраненное значение будет восстановлено.

К счастью, я знаю, как TLS реализован в Win32. ЭтоTIB структура (информационный блок потока) для каждого потока. В каждом потоке к нему можно получить доступ используяFS:[18h] селектор.TIB содержит (среди прочего) массив, используемый TLS. Остальное довольно просто.

Однако я бы предпочел использовать официальный API для достижения чего-то подобного.

Существует ли официальный API режима ядра для достижения того, что мне нужно?Есть ли причины избегать того, что я планирую сделать? Я знаю, что потенциально может быть проблема с повторным входом (то есть, какой-то код вызывает меня, я перезаписываю значение TLS и затем в конечном счете вызываю исходный код, который может полагаться на TLS). Но это не возможно в моем конкретном случае?Есть ли менее грязные способы решить эту проблему?

Заранее спасибо.

Постскриптум Теоретически можно использовать SEH (в котором также хранится информация для каждого потока). То есть, обернуть код верхнего уровня__try/__exceptтогда, где нужна контекстная информация - поднимитепродолжимы исключение с некоторым параметром, в__except Блок заполнить параметр контекстной информацией, а затем возобновить выполнение. И это 100% действительный программный поток, без использования недокументированных функций. Но, тем не менее, это кажется мне отвратительным занятием, не говоря уже о проблемах с производительностью.

Ответы на вопрос(3)

Ваш ответ на вопрос