【问题标题】:Call RtlIsNameInExpression from .Net code从 .Net 代码调用 RtlIsNameInExpression
【发布时间】:2018-03-21 14:47:24
【问题描述】:

由于 Windows(和以前的 DOS)中的 filename patternmatching 中有很多 intricacies,我想从我的 .Net 代码中调用 RtlIsNameInExpression 以确保我的(控制台)应用程序的行为与 Windows 应用程序相同.但是,我似乎无法找到如何 PInvoke 这个函数;我不知道DllImport 应该是什么样子,我在pinvoke.net 上找不到任何示例或任何有用的东西。

任何帮助将不胜感激!

编辑: 我是瞎子。我在谷歌搜索 FsRtlIsNameInExpression应该在谷歌搜索 RtlIsNameInExpression(解释 here)。

无论如何;找到了 here 的东西,这似乎有效。

【问题讨论】:

  • 您的 FsRtlIsNameInExpression 链接似乎已损坏 - 它会将我发送到 MSDN 错误页面。
  • @MattJones 对不起;修复了链接。我只是注意到它似乎是一个“驱动程序”功能(FsRtlIsNameInExpression),所以不是用户空间......这将是问题所在。我应该寻找RtlIsNameInExpression。将再次开始我的谷歌之旅......
  • 终于找到something。会试试的。
  • 许多函数驻留在几个地方,正如您从原型中看出的那样,它们可能都有匹配或非常相似的实现。 KM 版本可能会注意一些只存在于内核模式中的限制。

标签: c# windows pinvoke dllimport windows-console


【解决方案1】:

找到下面的代码here。发布/回答我自己的问题以确保它不会丢失。全部归功于David Růžička

// UNICODE_STRING for Rtl... method
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct UNICODE_STRING
{
    public ushort Length;
    public ushort MaximumLength;
    [MarshalAs(UnmanagedType.LPWStr)]
    string Buffer;

    public UNICODE_STRING(string buffer)
    {
        if (buffer == null)
            Length = MaximumLength = 0;
        else
            Length = MaximumLength = unchecked((ushort)(buffer.Length * 2));
        Buffer = buffer;
    }
}

// RtlIsNameInExpression method from NtDll.dll system library
public static class NtDll
{
    [DllImport("NtDll.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
    [return: MarshalAs(UnmanagedType.U1)]
    public extern static bool RtlIsNameInExpression(
        ref UNICODE_STRING Expression,
        ref UNICODE_STRING Name,
        [MarshalAs(UnmanagedType.U1)]
        bool IgnoreCase,
        IntPtr Zero
        );
}

public bool MatchMask(string mask, string fileName)
{
    // Expression must be uppercase for IgnoreCase == true (see MSDN for RtlIsNameInExpression)
    UNICODE_STRING expr = new UNICODE_STRING(mask.ToUpper());
    UNICODE_STRING name = new UNICODE_STRING(fileName);

    if (NtDll.RtlIsNameInExpression(ref expr, ref name, true, IntPtr.Zero))
    {
        // MATCHES !!!
    }
}

【讨论】:

  • 在文件系统中为NtQueryDirectoryFile 系统调用实现了通配符。 Microsoft 文件系统将调用 FsRtlIsNameInExpression 或类似名称,但它们不一定使用当前系统大写表,这就是您在此处使用的。例如,NTFS 在格式化卷时存储大写表。原则上它可能会有所不同,具体取决于 Unicode 版本,但实际上这应该不是问题。
  • 另外,我们不知道其他文件系统设备驱动程序做了什么——例如ext3 卷或 VirtualBox 共享文件夹的驱动程序。但是有一个可靠的案例表明,不遵守 FindFirstFile 和 Windows 应用程序所期望的规则(例如,DOS_QMDOS_STARDOS_DOT)是一个错误。
猜你喜欢
  • 1970-01-01
  • 2011-02-05
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多