PowerToys [FileLocksmith.Interop] 使用GetFinalPathNameByHandle增强文件路径解析

efzxgjgh  于 4个月前  发布在  其他
关注(0)|答案(3)|浏览(44)

新功能/增强功能的描述

上下文

在当前的 FileLocksmith 模块实现中,NtdllExtensions::path_to_kernel_name 被用于将 NT 风格的路径转换为更传统的基于驱动器的形式。
在使用 NtDll.NtQuerySystemInformation 函数获取文件路径后,需要进行这种转换。
虽然这种手动方法是可行的,但 Windows API 提供了一种更健壮、可能出错概率更低的方法来实现相同的目标:GetFinalPathNameByHandleW。这个函数给定一个文件句柄,会自动返回文件的完整基于驱动器的路径,包括处理各种路径细微差别和边缘情况。

建议

GetFinalPathNameByHandleW 替换当前在 path_to_kernel_name 中实现的手动方法。

在什么情况下会使用这个功能?

将 NT 设备对象路径转换为带有驱动器字母的路径。

支持信息

伪 C# 中的参考实现:

internal static class WinApi {
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
    [DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
    private static extern int GetFinalPathNameByHandleW(SafeFileHandle hFile, [Out] StringBuilder filePathBuffer, int filePathBufferSize, int flags);

    public static string? GetFinalPathNameByHandle(SafeFileHandle hFile)
    {
        var buf = new StringBuilder();
        var result = GetFinalPathNameByHandleW(hFile, buf, buf.Capacity, 0);
        if(result == 0)
        {
            return null;
        }

        buf.EnsureCapacity(result);
        result = GetFinalPathNameByHandleW(hFile, buf, buf.Capacity, 0);
        if (result == 0)
        {
            return null;
        }

        var str = buf.ToString();
        return str.StartsWith(@"\\?\") ? str.Substring(4) : str;
    }
}

public void Test()
{
    var handles = NtDll.QuerySystemHandleInformation();
    foreach (var h in handles)
    {
        using var openedProcess = WinApi.OpenProcess(...);
        var curProcess = WinApi.GetCurrentProcess();
        var res = WinApi.DuplicateHandle(out var dupHandle);

        // If the handle type is a File, then the driveLetterBasedFileFullName will have a value like "\\?\C:\Windows\System32\en-US\combase.dll.mui"
        var driveLetterBasedFileFullName = WinApi.GetFinalPathNameByHandle(dupHandle)
    }
}
92vpleto

92vpleto1#

@jaimecbernardo-msft - 如果你同意这个改变,我将移除需求分类标签并添加招聘标签。

ycggw6v2

ycggw6v22#

@jaimecbernardo-msft - 如果你同意这个改变,我会移除needs-triage标签并添加Help-Wanted标签
听起来不错,@joadoumie 。谢谢你!

gmol1639

gmol16393#

我也在这里描述了另一个改进。

一般来说,不需要Interop C++库。可以像我在我的一个项目中所做的那样用C#编写查找锁的代码。

相关问题