CloseHandle 函数调用和 SMB 关闭请求之间的延迟

2023-12-08

下面的代码在 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 的输出中,因为它以提升的权限运行。


感谢第一个答案,我更好地知道该去哪里寻找。据我所知,这是 Windows SMB 重定向器的故意行为。它有一个打开文件句柄的缓存,每 x 秒获取一次。这样做是为了透明地优化经常打开/关闭/重新打开文件的应用程序。有许多注册表项会影响这一点(请参阅https://support.microsoft.com/en-us/kb/102981, https://msdn.microsoft.com/en-us/library/windows/hardware/dn567661%28v=vs.85%29.aspx, https://social.msdn.microsoft.com/Forums/en-US/832d395b-6e6f-4658-8dbb-120138a4cd7c/smb2-registry-settings?forum=os_fileservices)但这些似乎都不会导致 CloseHandle 上立即发出 SMB 关闭请求。 我能够获得的最佳结果是将 CacheFileTimeout 设置为 0。这仍然会留下 3-5 秒之间的延迟(可能由触发清理计时器的频率决定)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CloseHandle 函数调用和 SMB 关闭请求之间的延迟 的相关文章

  • Windows 8.1 如何修复这个过时的代码?

    我已将我的项目从 Windows 8 0 升级到 Windows 8 1 并收到一些过时代码的警告 其中一些我已经修复了 有些还没有 这是我无法修复且找不到任何信息的最后警告的图像 所有警告都引用相同的方法 并且它说它已过时 我应该怎么做才
  • 将 runas 作为子进程启动并将密码写入标准输入?

    我正在尝试编写一个 C 程序 该程序应该从 Windows 调用 runas 工具并自动输入密码 我尝试过的 Process runas new Process runas StartInfo FileName runas runas St
  • 为什么不允许 UTF-8 作为“ANSI”代码页?

    窗户 setmbcp https web archive org web 20100108193149 http msdn microsoft com en us library 883tf19a VS 80 aspx函数允许任何有效的代码
  • 批处理文件进度旋转轮

    我已经尝试了好几天了 似乎可以让它发挥作用 我找到了一个例子 但它使用了 CryEcho 但它不起作用 我只是想添加这个 让用户知道在 ping IP 地址时发生了什么事 我确实在这里找到了一些代码 但这让我感到困惑 因为我刚刚开始为了好玩
  • 提取图像文件元数据

    我希望能够在不打开文件的情况下提取图像的元数据和扩展属性 换句话说 如何以编程方式访问在 Windows 中右键单击文件并选择 详细信息 选项卡时显示的信息 使用 Net Framework 4 5 及更高版本执行此操作的正确方法是什么 我
  • Windows 上的 DLL Main 与 Windows 上的 DLL Main Linux 上的 __attribute__((constructor)) 入口点

    考虑代码 EXE int main printf Executable Main loading library n ifdef HAVE WINDOWS HMODULE lib LoadLibraryA testdll dll elif
  • 如何在本地主机上托管 Office 加载项?

    我是网络服务器的新手 我在 Windows 10 上安装了 Internet 信息服务 IIS 10 Express 我正在尝试开发 Office 加载项 以便将其托管在我使用的同一台计算机上 问题是如何在本地 Web 服务器中托管加载项
  • 无法在 Qt Creator 中检索调试输出

    在 Windows 上的 Qt Creator 中 qDebug 语句不起作用 并且输出窗口中出现以下消息 无法检索调试输出 如何解决 如果多个 Qt Creator 实例处于活动状态 则可能会出现此问题 要解决此问题 只需关闭 Qt Cr
  • MFC中如何获取子菜单?

    我正在尝试获取一个子菜单 以便我可以在显示它之前对其进行更改 所以我创建了一个OnInitMenu 我的窗口的处理程序 我本来计划使用pMenu gt GetMenuItemInfo 获取子菜单 然而 这似乎行不通 为了找到我想要的菜单 我
  • 如何使用 Windows API 从麦克风录制 wav 声音?

    如何使用 Windows API 从麦克风录制 wav 声音 您可以使用一系列的waveInXXX Windows API 来录制音频 即waveInOpen waveInPrepareHeader waveInAddBuffer wave
  • 如何在 Windows 窗体应用程序中跟踪 C# 中两次按钮单击之间的时间?

    我已经用 C 创建了一个 Windows 窗体应用程序 其中接受用户的输入 我想计算用户在两次提交之间花费的时间 我该怎么做 Use 跑表 http msdn microsoft com en us library system diagn
  • 如何获取文件或目录的标准化日期/时间戳。在纯批处理脚本中?

    Windows 命令行中有没有一种方法可以检索标准化文件或目录的日期 时间戳 修改 创建 访问 独立于语言环境格式 例如 ISO8601 http www iso org iso home standards iso8601 htm 我发现
  • 如何在 Windows 路径中使用卷标?

    我想使用批处理文件从可移动驱动器复制文件 无论它获得的驱动器号是什么 到目前为止 还没有去 似乎没有任何现成的命令或第三方命令行工具可以处理基于卷标签的路径 我尝试了 FreeFileSync 但它可以大批量工作 并且我在这里需要精确的文件
  • 如何将 Windows 窗体应用程序 (C++) 设置为具有 Aero/Glass 背景?

    我正在使用 Visual Studio 2010 Pro 用 C 创建 Windows 窗体应用程序 我想创建一个透明背景 即使用 Aero Glass 效果 类似于它围绕 Windows 照片查看器中 UI 底部的方式 此时 我已经查看了
  • Powershell:别名和函数有什么区别?

    Im setting up my powershell profile to create aliases of commonly used commands On Microsoft s documentation https learn
  • 如何在 Windows 上以编程方式将 SVG 转换为 PDF?

    我希望在服务器上以编程方式将 SVG 转换为 PDF 文档 在 Windows 上执行此操作有哪些选项 我看过链接Inkscape http www inkscape org Batik http xmlgraphics apache or
  • 如何在每个批处理脚本运行后清除变量?

    看来 由于我使用 SET 在批处理脚本中声明变量 如果我在 cmd 中运行多次 变量值将持续存在 除非我显式重置它们 我是否必须使用 setlocal 和 endlocal 来确保一次运行中的变量不会在不关闭 CMD 的情况下持续到另一次运
  • WinSock.h 和 WinSock2.h 使用哪个?

    有谁知道 WinSock h 和 WinSock2 h 之间的区别 我知道它们不使用相同的库 lib 但我不知道 WinSock2 是否仅添加了新功能 或者是否还改进了 WinSock 1 功能 我正在使用 IP TCP 套接字 并希望使用
  • 在 Windows 上部署 Meteor

    我觉得很奇怪的是 没有关于如何将自己的 Meteor Web 应用程序部署到自己的 Windows 服务器上的详细分步说明 或者也许我只是无法使用谷歌找到这样的解释 在很多页面上 甚至在关于 SO 的一些问题上 我发现人们只是简单地说 bu
  • phoenix 框架 - 新套接字处的参数无效 - windows

    我无法运行新的 Phoenix 应用程序 这是我收到的错误 我不确定原因是什么 我尝试更改端口 但这并没有改变行为 另外 我似乎能够正确运行节点 Compiled web views error view ex Compiled web c

随机推荐