Windows(确切地说是 Win32)中的内核模式驱动程序是否有等效的线程本地存储 (TLS)?
我试图实现的目标:
最终,从我的驱动程序的调度例程中,它可能会调用许多其他函数(可能有一个深层调用堆栈)。我想提供一些特定于正在处理的请求的上下文信息。也就是说,我有一些结构,指向该结构的指针应该在所有被调用的函数中可见,而无需将其作为参数显式传递给每个函数。
使用静态/全局并不是一个完美的选择(多线程、同步对象等)。
如果那是用户模式代码 - 在这种情况下显然会使用 TLS。但据我所知,没有像这样的内核模式函数TlsGetValue
/TlsSetValue
。这是有道理的 - 为了使这些函数正常工作,必须首先分配一个进程范围的 TLS 索引。 OTOH 驱动程序代码可以在任意线程上调用,而不限于特定进程。
但我实际上并不需要执着的线程特定的存储。我只需要一个线程特定的存储来用于我的顶级函数调用。
我想我知道如何“实施”TLS,尽管是以一种黑客的方式。我将始终使用预定义索引(例如,index=0),而不是分配 TLS 索引。在顶层函数中,我将保存存储的 TLS 值,并用所需的值覆盖它。完成后,保存的值将恢复。
幸运的是我知道 TLS 在 Win32 中是如何实现的。有一个TIB
每个线程的结构(线程信息块)。在每个线程中可以使用以下方式访问它FS:[18h]
选择器。这TIB
包含(除其他外)TLS 使用的数组。剩下的事情就非常简单了。
不过我更喜欢使用官方 API 来实现类似的功能。
- 是否有官方的内核模式 API 可以实现我的需求?
- 有理由避免我计划做的事情吗?我知道重新进入可能存在问题(即某些代码调用我,我覆盖 TLS 值,然后最终调用可能依赖于 TLS 的原始代码)。但这在我的具体情况下不可能吗?
- 有没有更少肮脏的方法来解决这个问题?
提前致谢。
附:理论上可以使用 SEH(它还存储了每线程信息)。也就是说,将顶层代码包装为__try/__except
,然后在需要上下文信息的地方 - 提出可继续的某些参数的异常,在__except
block用上下文信息填充参数,然后恢复执行。这是一个 100% 有效的程序流程,没有使用未记录的功能。但尽管如此,这对我来说似乎是一个丑陋的黑客,更不用说性能的复杂性了。
您可能应该使用 PsGetCurrentThreadTeb,而不是使用 FS:[18h]。即使如此,我认为您仍会依赖未来操作系统版本(可能包括服务包)中可能发生变化的细节。
相反,您不能使用 KeGetCurrentProcessorNumber 作为数组的索引吗?您可以在其中存储指向上下文信息的指针? (当然,前提是您运行在 DISPATCH_LEVEL 或更高级别,这样您就不会意外地切换到不同的处理器。)
如果不能保证在 DISPATCH_LEVEL 上运行,则可以使用表或链接列表,其中每个条目(代表当前正在运行代码的线程)都标有 PsGetCurrentThread 的值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)