【发布时间】:2020-07-18 05:47:50
【问题描述】:
我总是使用this solution 递归地枚举文件和文件夹。该代码工作得很好,向所有找到的人显示正确的文件/文件夹名称。但是存在识别symbolic link文件相关的问题,导致链接解决方案失败,例如:
如上图所示,这 3 个文件是指向某个地方的 dll 文件的符号链接文件。然后,执行上面提到的代码将打印:
- api-ms-win-core-console-l1-1-0.dll
而不是
- api-ms-win-core-console-l1-1-0.symlink
另一个类似的案例,使用了IoCreateFile() 函数。如果这接收到错误的文件名或对象属性(仍然是指链接答案的代码),也会失败并出现 ntstatus 错误 STATUS_OBJECT_PATH_NOT_FOUND 或与此问题相关的其他一些问题。
那么我的问题是:
是否有一些解决方案来识别我使用的链接代码可以工作的符号链接文件(以及为什么没有像ZwOpenFile 等任何其他功能)?
提前感谢您的任何建议。
版本:
这是一个代码,当符号链接作为文件名传递时,IoCreateFile() 函数失败:
#include <ntifs.h>
#include <ntddk.h>
HANDLE
MyIoOpenFile(
IN PCWSTR FileName,
IN ACCESS_MASK DesiredAccess,
IN ULONG ShareAccess)
{
NTSTATUS ntStatus;
UNICODE_STRING uniFileName;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE ntFileHandle;
IO_STATUS_BLOCK ioStatus;
if (KeGetCurrentIrql() > PASSIVE_LEVEL) {
DbgPrint("KeGetCurrentIrql() > PASSIVE_LEVEL\n");
return 0;
}
RtlInitUnicodeString(&uniFileName, FileName);
InitializeObjectAttributes(&objectAttributes, &uniFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = IoCreateFile(&ntFileHandle,
DesiredAccess,
&objectAttributes,
&ioStatus,
0,
FILE_ATTRIBUTE_NORMAL,
ShareAccess,
FILE_OPEN,
0,
NULL,
0,
0,
NULL,
IO_NO_PARAMETER_CHECKING);
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("IoCreateFile() error - 0x%X \n", ntStatus);
return 0;
}
return ntFileHandle;
}
//---------------------------------------------------------------------------
HANDLE hFileHandle = MyIoOpenFile(L"\\??\\C:\\Full-Path-FileName-Here",
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ);
if (hFileHandle != 0) {
DbgPrint("hFileHandle: %08X\n", hFileHandle);
ZwClose(hFileHandle);
}
【问题讨论】:
-
代码打印正确的文件名 api-ms-win-core-console-l1-1-0.dll 并在代码中检查符号链接/重解析点 -
FILE_ATTRIBUTE_REPARSE_POINT -
.symlink - 这不是扩展名,也不是文件名的一部分。这是在 Type 列内 - 文件类型的简单描述。 api-ms-win-core-console-l1-1-0.symlink - 这是错误的名称 - 不存在这样的文件。真正的文件名是 api-ms-win-core-console-l1-1-0.dll 你得到的(你在系统上测试选项不显示已知文件扩展名,如 . dll 开启)
-
@RbMm,那么不存在操纵符号链接(这些快捷方式:D)文件的解决方案,例如删除(之前将您的句柄作为参考)-
IoCreateFile/ZwOpenFile?已经知道它总是指向不存在的“api-ms-win-core-console-l1-1-0.dll”(STATUS_OBJECT_PATH_NOT_FOUND)。 -
您需要使用
FILE_OPEN_REPARSE_POINT选项。猜你不使用它。如果你想删除这个文件 - 用FILE_OPEN_REPARSE_POINT|FILE_DELETE_ON_CLOSE打开它 -
你的代码当然是错的——没有
FILE_OPEN_REPARSE_POINT选项
标签: c++ windows filesystems driver kernel-mode