我用过Rohitab 的 API 监视器 v2 http://www.rohitab.com/apimonitor监视 Windows API 调用。
更改目录名称时D:\test
to D:\abc
,此调用已记录:
explorerframe.dll ITransferSource::RenameItem ( 0x0000000015165738, "abc", TSF_COPY_CREATION_TIME | TSF_COPY_LOCALIZED_NAME | TSF_COPY_WRITE_TIME | TSF_DELETE_RECYCLE_IF_POSSIBLE, 0x00000000150f77d0 )
进一步挖掘监视器的输出显示了一些本机调用:
正如你所看到的,他们没有使用MoveFile
,相反,他们使用NtOpenFile
with FILE_OPEN_FOR_BACKUP_INTENT
等打开原目录,然后调用NtSetInformationFile
使用新的目录名称和标志FileRenameInformation
这是有记录的here https://msdn.microsoft.com/en-us/library/windows/hardware/ff567096(v=vs.85).aspx.
不幸的是,这些都是内核调用。
您可以从用户模式获取 C/C++ 中目录的句柄,如下所示:
HANDLE h = ::CreateFileA("D:\\test",
DELETE | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
但是,您仍然需要一个用户模式替代方案NtSetInformationFile
-call.
一些要继续的选项(按复杂性排序):
- 看看是否可以使用shell接口ITransferSource::RenameItem https://msdn.microsoft.com/en-us/library/windows/desktop/bb774535(v=vs.85).aspx或者找到一个现成的 shell 函数
- 进一步深入研究用户模式解决方案并尝试找到替代方案
NtSetInformationFile
- 编写一个包含执行这些内核模式操作的 IOCTL 的驱动程序并调用
DeviceIoControl
来自 C#。
Update
似乎是SHFileOperation https://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx函数执行 OP 发现的上述所有操作。
将把这个答案留在网上,因为它可能会向其他人展示如何调试类似的问题并获得有价值的指导。