使用 EasyHook 从 C# 连接到 Win32 打印 API

Hooking into Win32 printing API from C# using EasyHook

类似的事情是 asked before,但没有收到任何答复。我的问题有点笼统。

我正在寻找一种在 C# 应用程序中使用 EasyHook library 的方法,这将使我能够拦截来自 notepad.exe.[= 的键打印 API 调用22=]

我的目标是将记事本的打印重定向到与所选记事本不同的打印机

当然,这只是人为测试。但如果证明成功,我会使用该解决方案从无法配置目标打印机的实际遗留应用程序重定向打印。它只是打印到系统默认打印机,这并不总是为用户所接受。

此外,该应用程序的原始源代码已在多年前供应商倒闭时丢失,因此无法对其进行修改。但我希望使用 API 钩子来解决它,正如所解释的那样。

现在,问题是我不完全确定 API 挂钩!

使用API Monitor v2 I was able to determine that Notepad calls into the OpenPrinterW inside PrintConfig.dll. I wasn't able to find the headers for this specific DLL, but I've found a very similar function inside winspool.drv.

注意:我确定之前的陈述是错误的,这让我很高兴!除了 winspool.drv 中的函数外,没有任何其他函数。我误读了 API 监视器的输出并假设 PrintConfig.dll 是实现库,而实际上它只是调用库。呸!但遗憾的是,仍然没有雪茄,所以问题成立。

不幸的是,我所有的挂钩尝试都失败了。我的代码根本没有被调用。另一方面,挂钩例如kernel32.dllReadFile 在我的所有测试中都按预期工作。

值得一提的是,我并没有特别接受 hook 的想法 OpenPrinterW。我选择从这里开始的原因是:

  1. API 监视器显示它确实是被调用的那个(至少记事本是这样)。
  2. 看起来是正确的,因为它接受打印机名称和returns一个句柄,然后传递给其他打印调用。如果我可以在调用实际 OpenPrinterW 之前更改挂钩中的打印机名称,我会觉得我可能已经完成了 90%。

所以...有什么想法吗?

我在我的挂钩 DLL 中添加了一些额外的日志记录代码后发现了这个问题。

目前我正在尝试从注入的 DLL 中将钩子安装到记事本进程中,winspool.drv 模块尚未加载到进程中。它只会在第一次实际需要时加载。呸!

一个简单的 LoadLibrary 调用解决了我的问题,我现在可以成功拦截 OpenPrinterW API.

现在剩下的 10% 的问题...:)