将STD_OUTPUT_HANDLE直接作为输入句柄传递给写入文件是否合法



WinApi WriteFile()函数似乎直接接受STD_xxx_HANDLE常量作为第一个参数。 我执行了以下内容:

#include <windows.h>
main() {
    DWORD bw;
    WriteFile( (void *)STD_OUTPUT_HANDLE,       "output", 6, &bw, NULL);
    WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), "output", 6, &bw, NULL);
    WriteFile( (void *)STD_ERROR_HANDLE,        "error", 5, &bw, NULL);
    WriteFile( GetStdHandle(STD_ERROR_HANDLE),  "error", 6, &bw, NULL);
}

上面的例子将"output"写入标准输出两次,将"错误"写入标准输出两次。 我已经在Win XP和Win 7上进行了测试(我无法访问WINE或Win 10(。

我可以看到GetStdHandle()确实转换了该值(在 STD_OUTPUT_HANDLE 的情况下从 -11 转换为 7(,但任一值的工作方式都与WriteFile()输入HANDLE相同。

当 WriteFile 将STD_xxx_HANDLE常量识别为其HANDLE输入时,它是否隐式执行GetStdHandle()? 我已经看过了,但找不到记录在案。

是的,我知道如果没有记录,请不要这样做...我只是想知道我是否错过了什么。

令人惊讶的是,这甚至可以在Windows 95 RTM和NT 4(以及XP和8(上运行,所以它似乎是故意的。我不能告诉你为什么,也不能告诉你这在NT 3.x中有多远。

但它没有记录在案,也不是 ABI 的一部分,所以我建议你继续打电话给GetStdHandle以避免将来出现令人讨厌的惊喜。

WriteFile 需要一个句柄。STD_xxx_HANDLE值不是句柄。将这些值传递给WriteFile是不合法的。您必须通过调用 GetStdHandle 将它们转换为句柄。

不,它被视为伪句柄,与句柄相同GetCurrentProcess()句柄。

尝试窥视KernelBase.dll内部,它会检查hFile参数是否等于STD_X_HANDLE宏。

如果是,hFile句柄将变为NtCurrentPeb()->ProcessParameter->StandardXxx句柄。

还有其他功能可以识别STD_XXX_HANDLE宏。GetFiletype、FlushFileBuffers、CloseHandle 和 WaitForSingleObject(Ex( 也可以识别STD_XXX_HANDLE

最新更新