下面的代码在 SMB 共享上打开一个文件并立即关闭它。由于某种原因,我发现 CloseHandle 调用和通过线路发送的 SMB Close 请求之间存在延迟。
#include <Windows.h>
#include <stdio.h>
typedef NTSTATUS (__stdcall *NtQuerySecurityObjectPtr)(
_In_ HANDLE Handle,
_In_ SECURITY_INFORMATION SecurityInformation,
_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ ULONG Length,
_Out_ PULONG LengthNeeded
);
void printTime() {
SYSTEMTIME time;
GetSystemTime(&time);
int required = GetTimeFormat(LOCALE_INVARIANT, 0, &time, nullptr, nullptr, 0);
LPTSTR buffer = (LPTSTR)GlobalAlloc(GPTR, required * sizeof(TCHAR));
GetTimeFormat(LOCALE_INVARIANT, 0, &time, nullptr, buffer, required);
wprintf(L"%s\n", buffer);
}
int main()
{
LPCTSTR file = L"\\\\192.168.13.163\\share\\file1";
HANDLE f = INVALID_HANDLE_VALUE;
f = CreateFile(
file,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr,
CREATE_ALWAYS,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN,
INVALID_HANDLE_VALUE
);
CloseHandle(f);
printTime();
return 0;
}
我使用调试器运行了这段代码,并在 printTime 调用之后放置了一个断点。在此 printTime 的一次测试运行中输出 12:18:11。
在 Wireshark 中,我看到相应的关闭请求在 12:18:20 发出。所以函数调用和消息发送之间有大约 10 秒的延迟。
我认为这可能是由于句柄在某处泄漏或其他进程保持文件句柄打开,但我认为情况并非如此。如果我在 CloseHandle 调用之前停止程序,则在系统用户 shell 中执行的 sysinternals 处理工具会显示我的进程拥有该文件的句柄
C:\Users\pepijn\Desktop>Handle.exe file1
Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
SmbClose.exe pid: 7020 type: File C8: \Device\Mup\192.168.13.163\DMTest_share\file1
在 CloseHandle 调用之后立即运行相同的命令会导致找不到句柄
C:\Users\pepijn\Desktop>Handle.exe file1
Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
No matching handles found.
有谁知道造成这种延迟的原因是什么?
我能找到的与该主题最接近的相关问题是FileStream.Close() 不会立即关闭文件句柄。公认的答案是其他一些进程可能会保留该文件。如上所述,我认为这里的情况并非如此。我没有运行任何病毒扫描程序,并且我希望任何打开的句柄都会显示在 Handle 的输出中,因为它以提升的权限运行。