新功能/增强功能的描述
上下文
在当前的 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)
}
}
3条答案
按热度按时间92vpleto1#
@jaimecbernardo-msft - 如果你同意这个改变,我将移除需求分类标签并添加招聘标签。
ycggw6v22#
@jaimecbernardo-msft - 如果你同意这个改变,我会移除needs-triage标签并添加Help-Wanted标签
听起来不错,@joadoumie 。谢谢你!
gmol16393#
我也在这里描述了另一个改进。
一般来说,不需要Interop C++库。可以像我在我的一个项目中所做的那样用C#编写查找锁的代码。