- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我稍微修改了这里的代码:
Delphi - finding the process that is accessing a file from my program
为了返回给定 pID 的句柄名称列表,我将每个条目添加到 TStringList。问题是名称中包含诸如“?”之类的垃圾。在包含 unicode 字符的文件名中,例如“xxx ★ 5”显示为“xxx ? 5”
代码有什么问题吗?
最佳答案
看到任何非 ASCII 字符的问号是尝试从 Unicode 转换为 ANSI 的标志。
问题出在这个函数上:
function GetFileNameHandleThr(Data: Pointer): DWORD; stdcall;
var
dwReturn: DWORD;
FileNameInfo: FILE_NAME_INFORMATION;
ObjectNameInfo: TOBJECT_NAME_INFORMATION;
IoStatusBlock: IO_STATUS_BLOCK;
pThreadParam: TGetFileNameThreadParam;
begin
ZeroMemory(@FileNameInfo, SizeOf(FILE_NAME_INFORMATION));
pThreadParam := PGetFileNameThreadParam(Data)^;
Result := NtQueryInformationFile(pThreadParam.hFile, @IoStatusBlock, @FileNameInfo, MAX_PATH * 2, FileNameInformation);
if Result = STATUS_SUCCESS then
begin
Result := NtQueryObject(pThreadParam.hFile, ObjectNameInformation, @ObjectNameInfo, MAX_PATH * 2, @dwReturn);
if Result = STATUS_SUCCESS then
begin
pThreadParam.Result := Result;
WideCharToMultiByte(CP_ACP, 0, @ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength - ObjectNameInfo.Name.Length], ObjectNameInfo.Name.Length, @pThreadParam.FileName[0], MAX_PATH, nil, nil);
end
else
begin
pThreadParam.Result := STATUS_SUCCESS;
Result := STATUS_SUCCESS;
WideCharToMultiByte(CP_ACP, 0, @FileNameInfo.FileName[0], IoStatusBlock.Information, @pThreadParam.FileName[0], MAX_PATH, nil, nil);
end;
end;
PGetFileNameThreadParam(Data)^ := pThreadParam;
ExitThread(Result);
end;
这会在对 WideCharToMultiByte
的调用中从 Unicode 转换为 ANSI。您只需删除那部分代码即可。
您需要修改此记录
TGetFileNameThreadParam = packed record
hFile : THandle;
Result : NT_STATUS;
FileName : array [0..MAX_PATH - 1] of AnsiChar;
end;
这样 FileName
是一个 WideChar
数组。
TGetFileNameThreadParam = packed record
hFile : THandle;
Result : NT_STATUS;
FileName : array [0..MAX_PATH - 1] of WideChar;
end;
然后相应地调整GetFileNameHandleThr
。我没有详细研究它,但我希望你需要这样的东西:
function GetFileNameHandleThr(Data: Pointer): DWORD; stdcall;
var
dwReturn: DWORD;
FileNameInfo: FILE_NAME_INFORMATION;
ObjectNameInfo: TOBJECT_NAME_INFORMATION;
IoStatusBlock: IO_STATUS_BLOCK;
pThreadParam: TGetFileNameThreadParam;
begin
ZeroMemory(@FileNameInfo, SizeOf(FILE_NAME_INFORMATION));
pThreadParam := PGetFileNameThreadParam(Data)^;
Result := NtQueryInformationFile(pThreadParam.hFile, @IoStatusBlock, @FileNameInfo, MAX_PATH * 2, FileNameInformation);
if Result = STATUS_SUCCESS then
begin
Result := NtQueryObject(pThreadParam.hFile, ObjectNameInformation, @ObjectNameInfo, MAX_PATH * 2, @dwReturn);
if Result = STATUS_SUCCESS then
begin
pThreadParam.Result := Result;
Move(ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength - ObjectNameInfo.Name.Length], pThreadParam.FileName[0], Min(ObjectNameInfo.Name.Length, MAX_PATH)*SizeOf(WideChar));
//WideCharToMultiByte(CP_ACP, 0, @ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength - ObjectNameInfo.Name.Length], ObjectNameInfo.Name.Length, @pThreadParam.FileName[0], MAX_PATH, nil, nil);
end
else
begin
pThreadParam.Result := STATUS_SUCCESS;
Result := STATUS_SUCCESS;
Move(FileNameInfo.FileName[0], pThreadParam.FileName[0], Min(IoStatusBlock.Information, MAX_PATH)*SizeOf(WideChar));
//WideCharToMultiByte(CP_ACP, 0, @FileNameInfo.FileName[0], IoStatusBlock.Information, @pThreadParam.FileName[0], MAX_PATH, nil, nil);
end;
end;
PGetFileNameThreadParam(Data)^ := pThreadParam;
ExitThread(Result);
end;
我尚未运行此代码,因此您可能需要进一步处理它。但是,很明显问题出在 ANSI 转换上。
我现在已经运行了这段代码并且运行良好。
关于delphi - 使用 NTQuerySystemInformation/NtQueryInformationFile/NtQueryObject 获取进程使用的 Unicode 文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14316461/
我需要在运行时通过它的句柄获取注册表路径。为此,我使用了 NtQueryObject 函数。我的问题是 NtQueryObject 以奇怪的格式给我路径(见下图)。 我猜,这是你在写驱动时需要使用的那
我看到 NtQueryObject 因具有这些授权访问值的重复句柄而挂起(handle.GrantedAccess 是 ACCESS_MASK 类型): 1179785 (integer) --> 0
我稍微修改了这里的代码: Delphi - finding the process that is accessing a file from my program 为了返回给定 pID 的句柄名称列
我是一名优秀的程序员,十分优秀!