如何判断CreateFile()打开的是常规文件、设备还是控制台句柄?
判断CreateFile句柄类型的方法
不用预先检查路径,可通过以下Win32 API组合判断句柄类型:
1. 识别控制台句柄
直接调用GetConsoleMode():
- 调用成功(返回非0值),说明该句柄是控制台句柄(包括标准输入/输出/错误,或通过
CON打开的句柄)。 - 调用失败则排除控制台类型,继续后续判断。
2. 区分常规文件与设备句柄
方法一:借助GetFileInformationByHandle()
获取BY_HANDLE_FILE_INFORMATION结构体,查看dwFileAttributes字段:
- 若字段包含
FILE_ATTRIBUTE_NORMAL、FILE_ATTRIBUTE_ARCHIVE、FILE_ATTRIBUTE_HIDDEN等常规文件属性,说明是常规文件句柄。 - 若不包含上述属性,大概率是设备句柄,可结合
DeviceIoControl()进一步验证:- 尝试发送
IOCTL_DISK_GET_DRIVE_GEOMETRY控制码,成功则为卷设备; - 尝试发送
IOCTL_DISK_GET_DRIVE_LAYOUT_EX控制码,成功则为物理驱动器设备。
- 尝试发送
方法二:用GetFileType()辅助判断
该函数直接返回句柄对应类型:
FILE_TYPE_DISK:常规磁盘文件;FILE_TYPE_CHAR:控制台或字符类设备;FILE_TYPE_PIPE:命名/匿名管道;FILE_TYPE_REMOTE:远程文件;FILE_TYPE_UNKNOWN:未知类型,需结合其他API进一步确认。
示例逻辑伪代码
BOOL IsConsoleHandle(HANDLE hHandle) { DWORD mode; return GetConsoleMode(hHandle, &mode); } BOOL IsRegularFile(HANDLE hHandle) { BY_HANDLE_FILE_INFORMATION fileInfo; if (!GetFileInformationByHandle(hHandle, &fileInfo)) { return FALSE; } return (fileInfo.dwFileAttributes & (FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY)) != 0; } DWORD GetHandleType(HANDLE hHandle) { if (IsConsoleHandle(hHandle)) { return 1; // 控制台句柄 } if (IsRegularFile(hHandle)) { return 2; // 常规文件句柄 } return 3; // 设备句柄 }
内容的提问来源于stack exchange,提问作者Schilive
相关产品推荐
相关产品推荐

