【发布时间】:2014-10-21 13:18:35
【问题描述】:
我想检索操作系统中进程访问的所有文件路径。
检索进程列表并且这些进程具有正确的句柄值。所以现在我想使用GetFinalPathNameByHandle 函数来获取这些文件的路径,但是所有记录的路径变量都是相同的。伙计们,我需要帮助。
源代码在这里:http://pastebin.com/nU26Vcsd 或者如果无法访问 pastebin 则在这里 http://hastebin.com/wahudogawa.avrasm
第 66 行是我需要帮助的地方。测试进程的每个文件处理程序的路径都相同,并且等于执行该程序的路径(而不是进程启动文件夹)。
我将其运行为:testprogram.exe | grep 5231,其中 5231 是我需要的进程的 PID。
结果如下:
PID: 5231 FileHandlePid: 44 The final path is: \Device\HarddiskVolume4\KillFileHandle\C++\Debug
虽然那些应该是这样的:
PID: 5231 FileHandlePid: 44 The final path is: \Device\HarddiskVolume2\Users\username\AppData\Roaming\testapp
如果我的预期结果有误,请纠正我。
最新添加:
感谢@Raymond Chen cmets,我正在努力前进并使用 DuplicateHandle() 功能。到目前为止,我已经更新了代码(现在是硬编码的 pid,抱歉),添加了 HandleValueTemp,试图将它传递给 DuplicateHandle。输出更改为不可打印的字符。
for (i = 0; i < hCount; ++i)
if ((hFirstEntry[i].ObjectType == 28))
{
HANDLE TargetHandleValueTemp = (HANDLE)hFirstEntry[i].HandleValue;
HANDLE SourceProcHandleTemp = OpenProcess(PROCESS_DUP_HANDLE, FALSE, hFirstEntry[i].OwnerPid);
if (!DuplicateHandle(SourceProcHandleTemp, (HANDLE)hFirstEntry[i].HandleValue, GetCurrentProcess(), &TargetHandleValueTemp, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
cout << "Error in DuplicateHandle"
}
CloseHandle(SourceProcHandleTemp);
TCHAR Path[MAX_PATH];
DWORD dwret = GetFinalPathNameByHandle(TargetHandleValueTemp, Path, MAX_PATH, 0);
_tprintf(TEXT("PID: %d\tFileHandle: %d\tThe final path is: %s\n"), hFirstEntry[i].OwnerPid, TargetHandleValueTemp, Path);
CloseHandle(TargetHandleValueTemp);
}
不时深入挖掘并查看 cmets。也许这段代码对这里的其他人有用。
【问题讨论】:
-
未记录的 API 未记录。此外,句柄也不是那样工作的。
-
"这是假设您需要删除的所有文件都归执行删除的进程所有。"此外,强制关闭句柄可能会导致数据损坏和其他“不可能”的错误。您正在以长期痛苦为代价来创造短期缓解。另外,请在此处而不是在外部站点上包含代码。
-
"如果任何文件属于另一个进程,您将需要使用 DuplicateHandle() 的额外步骤。"但在这种情况下,您不会试图强制关闭手柄。此外,最好有一个调试或单元测试钩子,这样被测试的应用程序可以显式地提供句柄,而不是让你去寻找它。这样,您就可以避免使用未记录的 API。
-
您没有从 GetFinalPathByName 检查错误。
-
很快找到了原因。看起来在 Windows 8.1 中,文件的 SystemHandleInformation ObjectType 应该是 30,而不是像以前版本中的 28。现在有效