内核模式下的线程本地存储?

是否有与Windows中的内核模式驱动程序等效的线程本地存储(TLS)(准确地说是Win32)?

我试图实现的是:

最后从我的驱动程序的调度例程中,它可能会调用许多其他function(可能有一个深层的调用堆栈)。 我想提供一些特定于正在处理的请求的上下文信息。 也就是说,我有一些结构,指针应该在所有被调用的函数中可见,而不必将其作为参数明确地传递给每个函数。

使用静态/全局不是一个完美的select(multithreading,同步对象等)。

如果这是一个用户模式的代码 – 在这种情况下显然会使用TLS。 但是AFAIK没有像TlsGetValue / TlsSetValue这样的内核模式函数。 这是有道理的 – 对于那些需要工作的函数,必须先分配一个进程范围的TLS索引。 OTOH驱动程序代码可以在任意线程上调用,而不限于特定的进程。

但是,我实际上并不需要一个持久的线程特定的存储。 我只需要一个特定于线程的存储,用于我的顶级函数调用。

我想我知道如何“实施”红绿灯系统,虽然是一种骇人听闻的方式。 我将永远使用预定义的索引(比如index = 0),而不是分配TLS索引。 在顶层函数中,我将保存存储的TLS值,并用所需值覆盖它。 完成后保存的值将被恢复。

幸运的是我知道如何在Win32中实现TLS。 每个线程都有一个TIB结构(线程信息块)。 在每个线程中可以使用FS:[18h]select器访问。 TIB包含(除其他之外)由TLS使用的数组。 其余的很简单。

不过,我宁愿使用官方的API来实现类似的东西。

  • 有一个官方的内核模式API来实现我所需要的吗?
  • 有没有理由避免我打算做的事情? 我知道再入口可能存在问题(例如,某些代码调用了我,我覆盖了TLS值,最终调用了可能依赖于TLS的原始代码)。 但是在我的具体情况下这是不可能的?
  • 有没有更less的肮脏方法来解决这个问题

提前致谢。

PS One理论上可以使用SEH(也存储了每个线程的信息)。 也就是说, __try/__except__try/__except包装顶级代码__try/__except ,还需要在需要上下文信息的地方使用一些参数来引发可继续的exception,在__except块中用上下文信息填充参数,然后恢复执行。 这是一个100%有效的程序stream程,不使用未logging的function。 但是,这对我来说似乎是一个丑陋的黑客,更不用说性能的复杂性了。

Solutions Collecting From Web of "内核模式下的线程本地存储?"

而不是使用FS:[18h]你应该使用PsGetCurrentThreadTeb。 即使这样,我想你会依赖未来操作系统版本(可能包括服务包)可能会改变的细节。

相反,你不能使用KeGetCurrentProcessorNumber作为一个数组的索引,你可以存储一个指向你的上下文信息的指针? (假设你正在运行DISPATCH_LEVEL或更高,当然,这样你就不会意外地切换到不同的处理器。)

如果您不能保证在DISPATCH_LEVEL上运行,则可以使用表或链接列表,每个条目(表示当前正在运行代码的线程)都标记为PsGetCurrentThread的值。

您可以创建一个结构来保存传入的请求,然后传递这个结果而不是实际的请求,然后你只需要放入你需要的任何字段。 很明显,这并不能完全消除传递对象的需要,但是通常情况下你总是传递请求。

从我见过的大多数驱动程序中(这个数量并不是很多),一切都以请求为中心。 所以他们总是把事情和请求绑在一起,而不是试图把它放在其他位置。

不要与TEB做这个! TIB和TEB是用户模式结构。 用户模式应用程序可以在驱动程序运行时从另一个线程/处理器随意修改这些东西。 这将是您的驱动程序中的特权升级漏洞。

我会建议传递一个与您的请求有关的短暂上下文的上下文结构。 如果你需要更永久的东西,你可以使用AVL表或哈希表,当线程退出的时候你可以清理它们。