您可以使用DuplicateHandle 来测试句柄有效性。
第一种方法:您可以尝试复制要检查有效性的句柄。基本上无效句柄是不能复制的。
第二种方法:DuplicateHandle 函数确实从一开始就在 Win32 句柄描述符表中搜索一条空记录以重用它,并为它分配一个重复的句柄。您可以仅在大于您的句柄地址的值上测试重复的句柄地址值,如果它更大,则句柄不会被视为无效,因此不会被重用。但是这种方法是非常具体和有限的,它只在您要测试的句柄值地址之上没有更多空的或无效的句柄记录时才有效。
但是,上面所说的所有这些只有在您跟踪所有句柄的创建和复制时才有效。
Windows 7 的示例:
方法#1
// check stdin on validity
HANDLE stdin_handle_dup = INVALID_HANDLE_VALUE;
const bool is_stdin_handle_dup = !!DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &stdin_handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (is_stdin_handle_dup && stdin_handle_dup != INVALID_HANDLE_VALUE) {
CloseHandle(stdin_handle_dup);
stdin_handle_dup = INVALID_HANDLE_VALUE;
}
方法#2
// Assume `0x03` address has a valid stdin handle, then the `0x07` address can be tested on validity (in Windows 7 basically stdin=0x03, stdout=0x07, stderr=0x0b).
// So you can duplicate `0x03` to test `0x07`.
bool is_stdout_handle_default_address_valid = false;
HANDLE stdin_handle_dup = INVALID_HANDLE_VALUE;
const bool is_stdin_handle_dup = !!DuplicateHandle(GetCurrentProcess(), (HANDLE)0x03, GetCurrentProcess(), &stdin_handle_dup, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (is_stdin_handle_dup && stdin_handle_dup != INVALID_HANDLE_VALUE) {
if (stdin_handle_dup > (HANDLE)0x07) {
is_stdout_handle_default_address_valid = true; // duplicated into address higher than 0x07, so 0x07 contains a valid handle
}
CloseHandle(stdin_handle_dup);
stdin_handle_dup = INVALID_HANDLE_VALUE;
}