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

2024-01-04

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,然后在需要上下文信息的地方 - 提出可继续的某些参数的异常,在__exceptblock用上下文信息填充参数,然后恢复执行。这是一个 100% 有效的程序流程,没有使用未记录的功能。但尽管如此,这对我来说似乎是一个丑陋的黑客,更不用说性能的复杂性了。


您可能应该使用 PsGetCurrentThreadTeb,而不是使用 FS:[18h]。即使如此,我认为您仍会依赖未来操作系统版本(可能包括服务包)中可能发生变化的细节。

相反,您不能使用 KeGetCurrentProcessorNumber 作为数组的索引吗?您可以在其中存储指向上下文信息的指针? (当然,前提是您运行在 DISPATCH_LEVEL 或更高级别,这样您就不会意外地切换到不同的处理器。)

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内核模式下的线程本地存储? 的相关文章

  • 如何追踪手柄泄漏?

    在我的一个应用程序中 我观察到句柄数量不断增加 在不使用应用程序的情况下 该数字大约每秒增加一次 因此后台处理代码的某些部分一定存在句柄泄漏 我如何追踪此类泄漏 有什么工具可以帮助解决这个问题吗 跟踪句柄泄漏时要寻找哪些模式 导致手柄泄漏的
  • 我需要避免尝试更新连接到 TSQLQuery 的 Delphi TClientDataset 中的非物理字段

    概要 我的代码正在尝试更新 Delphi XE 中的非物理字段TClientDataset 连接到TSQLQuery以其SQL属性集 作为运行时的结果创建Open命令 我有一个TClientDataset连接到一个TDatasetProvi
  • WinError6 句柄无效 Python 3+ 多处理

    我正在运行一个 Python 3 7 Flask 应用程序 它使用flask socketio设置一个socketio用于浏览器客户端的服务器 另一个连接到单独远程的Python进程socketio服务器和交换消息 以及另一个从 PIR 传
  • 将 HttpApi 与 I/O 完成端口结合使用

    我刚刚偶然发现了微软的HTTP 服务器 API http msdn microsoft com en us library aa364510 28v vs 85 29 aspx 简介中写道 HTTP 服务器 API 使应用程序能够通过 HT
  • 如何创建共享网络目录或文件的超链接?

    我检查了以下两个相关讨论 1 如何创建指向本地可执行文件的超链接 https stackoverflow com questions 2815982 how do i make a hyperlink to a local executab
  • 如何在 WINAPI 中获取 Windows 10 内部版本、修订号?

    我想使用 WINAPI 在 Windows 10 上获取构建版本 当前窗口版本 10 0 19042 685 我尝试使用 WMI 查询来获取它 select Version BuildNumber from Win32 OperatingS
  • 如何取消同步 WinHttp 请求?

    我的服务有一个线程可能正在执行WinHttpSendRequest当有人试图停止我的服务时 The WinHttpCloseHandle 文档 http msdn microsoft com en us library windows de
  • 如何正确使用和实例化现有预览处理程序

    我正在尝试使用现有的预览处理程序来显示文件的预览 我编写了一个简单的测试程序 以 1 查找给定文件的预览处理程序的 CLSID 2 实例化预览处理程序 3 通过流或文件初始化它 4 在基本窗口上渲染预览 这有效 或多或少 It works
  • VirtualAlloc 对齐方式与分配大小一致吗?

    当使用VirtualAlloc用于分配和提交具有页面边界的两倍大小的虚拟内存区域的 API 例如 void address VirtualAlloc 0 0x10000 MEM COMMIT PAGE READWRITE Get 64KB
  • 在 Windows 上使用 docker compose 进行卷绑定

    我最近在 Windows 10 上升级了 Docker Toolbox 现在我的卷挂载不再起作用 我已经尝试了一切 这是当前的挂载路径 volumes C Users Joey Desktop backend var www html 我收
  • 监控进程的网络使用情况?

    C 或 C C Win32 中有没有一种方法可以监视某个进程的网络使用情况 显然没有您构建的应用程序 我想只监视 1 个进程大约一个小时左右 然后返回仅该进程 例如 Limewire 使用的字节 是否可以 我知道 Windows 上的 ne
  • 如何通过批处理文件检查服务是否正在运行并启动它,如果它没有运行?

    我想编写一个执行以下操作的批处理文件 Check if a service is running 如果正在运行 请退出批处理 如果没有运行 启动该服务 到目前为止 我在谷歌上搜索的代码示例被证明不起作用 所以我决定不发布它们 启动服务是通过
  • 选择 c 和 gamma 值

    您好 我正在使用 SMO 执行 SVM 分类 其中我的内核是 RBF 现在我想选择c and sigma值 使用网格搜索和交叉验证 我是内核函数的新手 请帮助 一步一步的过程 选择一些您认为有趣的 C 和 sigma 值 例如 C 1 10
  • 获取保证具有完整(4 位)年份的 LOCALE_SSHORTDATE 的正确方法是什么?

    我想创建一个日期时间选择器控件 它显示日期和时间 作为DTS SHORTDATECENTURYFORMAT and DTS TIMEFORMAT风格 由于日期时间选择器中没有内置这种样式 因此我必须自己做GetLocaleInfoEx 我注
  • 仅将 Firesharp 用于 Windows 桌面推送通知

    我想在 Windows 桌面应用程序中使用 Firesharp 该应用程序只会接收来自 Firebase 的通知 并且不会有任何类型的数据库交互 Firebase Cloud Messaging FCM 是 Firebase 唯一使用的东西
  • 将 Metro 应用程序固定到任务栏 Windows 10 Powershell

    以下代码将固定 Metro 应用程序以在给定 AUMID 的情况下启动 如果你改变 match Pin To Start 不幸的是 将匹配更改为 固定到任务栏 不起作用 这里发生了什么 function Pin Taskbar param
  • GOPATH值设置

    我用go1 3 1 windows amd64 msi安装go 安装后GOROOT是默认设置 我发现 D Programs Go bin 在 PATH 中 然后我创建一个 GOPATH 环境变量 使用 go get 命令时 出现错误 软件包
  • 如何检测Windows版本是否合法? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我对获取版本信息不感兴趣 我想做的就是确保我的应用程序只能在合法版本的 Windows 上运行 而不是在盗版版本上运行 Windows 使
  • Windows 上的 Node.js 和 Express

    今晚 我决定尝试在我的 Windows 7 计算机上使用 Express 构建一个简单的 Node js 应用程序 安装过程还算顺利 但 Express 拒绝配合 以下是我已采取的步骤 使用以下位置提供的 MSI 安装 Node jshtt
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目

随机推荐