Windows 中的内核模式驱动程序是否有等效的线程本地存储 (TLS)(准确地说是 Win32)?
我试图达到的目标:
最终,在我的驱动程序的调度例程中,它可能会调用许多其他函数(可能有很深的调用堆栈)。我想提供一些特定于正在处理的请求的上下文信息。也就是说,我有一些结构,指向它的指针应该在所有被调用的函数中都是可见的,而不是显式地将它作为参数传递给每个函数。
使用静态/全局不是一个完美的选择(多线程、同步对象等)。
如果那是用户模式代码 - 在这种情况下显然会使用 TLS。但是 AFAIK 没有像TlsGetValue
/这样的内核模式函数TlsSetValue
。这是有道理的——要使这些功能正常工作,必须首先分配一个进程范围的 TLS 索引。OTOH 驱动程序代码可以在任意线程上调用,不限于特定进程。
但是,我实际上并不需要持久的特定于线程的存储。我只需要一个特定于线程的存储来进行顶级函数调用。
我想我知道如何“实施” TLS,尽管是以一种骇人听闻的方式。我不会分配 TLS 索引,而是始终使用预定义的索引(例如 index=0)。在顶级函数中,我将保存存储的 TLS 值,并用所需的值覆盖它。完成后,保存的值将被恢复。
幸运的是,我知道 TLS 在 Win32 中是如何实现的。每个线程都有一个TIB
结构(线程信息块)。在每个线程中都可以使用FS:[18h]
选择器访问它。包含(除其他外)TLS 使用的TIB
数组。其余的非常简单。
但是我更喜欢使用官方 API 来实现类似的东西。
- 是否有官方的内核模式 API 来实现我所需要的?
- 是否有理由避免我打算做的事情?我知道重入可能存在问题(即某些代码调用我,我覆盖 TLS 值,然后最终调用可能依赖于 TLS 的原始代码)。但这在我的具体情况下是不可能的?
- 有没有更脏的方法来解决这个问题?
提前致谢。
PS One 理论上可以使用 SEH(它还存储了每个线程的信息)。也就是说,用 包装顶层代码__try/__except
,然后在需要上下文信息的地方 - 用一些参数引发可继续异常,在__except
块中用上下文信息填充参数,然后恢复执行。这是一个 100% 有效的程序流程,没有使用未记录的功能。但尽管如此,这对我来说似乎是一个丑陋的 hack,更不用说性能上的复杂性了。