【问题标题】:Is it possible to capture a "file not found" from another process and then return a file to that process?是否可以从另一个进程捕获“找不到文件”,然后将文件返回到该进程?
【发布时间】:2011-03-01 08:38:27
【问题描述】:

我有一个在目录中查找文件的旧应用程序。它不能很好地处理丢失的文件。我想要做的是“捕获”文件未找到错误,并将另一个文件发送回调用应用程序。类似于您如何在网络服务器上处理 404 错误并根据所请求的 URL 返回某些内容,本地文件系统除外。

这可能吗?更可取的是,在 .Net 中是否可行?

【问题讨论】:

    标签: .net windows error-handling filesystems file-not-found


    【解决方案1】:

    是的,您所描述的都是可能的。

    我建议使用filesystem filter driver or mini filter 来处理这种类型的事情,尽管这在.Net 中无法完成。

    我建议的方式可能是在文件系统级别捕获所有内容的最合适的方式。

    【讨论】:

    • 我至少可以从 .Net 调用它吗?
    • 代码将使用 C 或 C++,然后您可以通过注册的回调或其他 IPC 通信方式从那里传递信息。
    • @Brian R. Bondy。你错了。即使在 .NET 中,这也是完全可能的
    • @Max:如果你想捕捉一切,你应该在文件系统级别进行。 .Net 无法做到这一点。
    • @Brian:如果“一切”是指系统函数,那么我想不出简单应用程序可以使用任何其他 Win API 函数来打开文件。你有什么特别的功能吗?文件系统层是什么意思?文件系统有很多层。 FS 驱动程序就是其中之一
    【解决方案2】:

    您可以通过拦截对 Win API 函数 CreateFile 的调用来做到这一点。这需要dll注入。在 .NET 中,您可以使用这个库:easyhook.codeplex.com

    【讨论】:

    • 每个文件最终都用 CreateFile 打开。为什么这是一个坏建议?我前段时间自己尝试过这个库,效果很好。
    • 每个文件最终都不是用 CreateFile 打开的。
    • 编写系统驱动程序将是一项复杂得多的任务。
    • @Max:同意它要复杂得多。我想这取决于 OP 是想以正确的方式还是以骇人听闻的方式来做。根据他的需要,您的方式会更快但不太合适。
    • 可能还有其他Win API函数可以打开文件(你能说出它们的名字吗?),但是如果有这样的函数,你也可以拦截它们。没什么大不了的。
    【解决方案3】:

    如果商业解决方案是可以接受的,那么像 Eldos CallbackFilter 这样的解决方案可能符合要求:

    http://www.eldos.com/cbflt/spec.php

    我并没有完全将它用于您的目的,但您当然可以拦截文件系统调用,在那里您可以检查文件是否存在,如果不存在则创建一个虚拟文件。

    事实证明,这对于清理行为不良的遗留应用程序可能要简单得多。

    【讨论】:

      【解决方案4】:

      如果您知道要打开文件的进程中的代码在哪里,您可以围绕它编写一个像调试器一样的包装进程,拦截调用,自己检查它是否存在,如果不存在,用不同的文件名替换文件名。

      类似:

      CreateProcess(bla bla, DEBUG_ONLY_THIS_PROCESS, bla bla);
      
      SetBreakPoint(address of code to set breakpoint)
      {
        ReadProcessMemory to save off byte for breakpoint
        WriteProcessMemory 0xCC to set breakpoint
        FlushInstructionCache
      }
      
      while (TRUE == bContinue)
      {
        bContinue = WaitForDebugEvent(&debugEvent);
        switch (dwDebugEventCode)
        {
          case EXCEPTION_BREAKPOINT:
            // Read the file name from memory, check if it exists, if not, replace it with
            // new file name using the same length in memory :)
            // Replace your code byte you read out when you set the breakpoint
        }
      }
      

      另一种方法是用您自己对 CreateFile 的调用(或他们在相关应用程序中使用的任何方法)覆盖函数调用表。在这里查找 API 挂钩,甚至 Dll 注入都可能对您有所帮助。

      Microsoft 有 Detours 包可以帮助您,CodePlex 有 EasyHook 看起来很有趣。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-04
        • 1970-01-01
        • 2018-02-25
        • 2012-10-17
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        • 2014-12-23
        相关资源
        最近更新 更多