OpenProcess()成功,但EnumProcessModules()失败

时间:2012-03-02 13:06:25

标签: c++ winapi

我在Windows服务中执行以下代码 在Windows XP 32位上:

HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                       FALSE,
                       a_impl->pid);

if (0 == h)
{
    throw Process_exception(__LINE__,
                            __FILE__,
                            "Failed obtain module list for '" +
                                a_impl->exe_name + "'",
                            GetLastError());
}

DWORD required_size  = 1024 * sizeof(HMODULE);
DWORD module_entries = 0;
BOOL result;
DWORD last_error;
HMODULE* module_handles = 0;

do
{
    module_entries = required_size / sizeof(HMODULE);
    delete[] module_handles;
    module_handles = new HMODULE[module_entries];
    memset(module_handles, 0, sizeof(HMODULE) * module_entries);

    result = EnumProcessModules(h,
                                module_handles, 
                                sizeof(HMODULE) * module_entries,
                                &required_size);

    last_error = GetLastError();

} while (TRUE == result &&
         required_size > (sizeof(HMODULE) * module_entries));

if (FALSE == result)
{
    CloseHandle(h);
    delete[] module_handles;

    throw Process_exception(__LINE__,
                            __FILE__,
                            "Failed to enumerate module list for '" +
                                a_impl->exe_name + "'",
                            last_error);
}

Windows服务部署在许多计算机和某些计算机上 (我无权访问) EnumProcessModules()调用因ERROR_PARTIAL_COPY而失败。 据我所知,在查询进程时,这会失败 由登录用户启动:我无法重现这一点 并尝试了以下内容:

  • 使用Process Explorer,拒绝本地系统帐户读取内存 并写入对登录用户启动的进程的内存访问。
  • 在不同的会话中启动进程(Windows服务和进程 由同一会话中的第一个登录用户执行0
  • 启动

任何人都可以解释这种行为吗?

注意,我看到这种行为的唯一过程是系统进程 (通常是进程ID 4)。

2 个答案:

答案 0 :(得分:6)

documentation包含答案:

  

如果从WOW64上运行的32位应用程序调用此函数,则它只能枚举32位进程的模块。如果进程是64位进程,则此函数失败,最后一个错误代码为 ERROR_PARTIAL_COPY (299)。

返回此错误代码的计算机是64位系统,而您枚举的模块的进程是64位进程。

要从32位服务枚举64位进程的模块,您需要使用EnumProcessModulesEx实际上,您可能需要按顺序运行64位进程枚举过程模块。

更新:您显然确定代码失败的系统是32位系统。在这种情况下,可能失败的是当您尝试枚举16位进程的模块时。

答案 1 :(得分:2)

原因可能是因为您在代码中使用了CreateProcessA ..并突然调用了EnumProcessModules.Thus窗口无法在那时创建ModuleInfo。它返回错误299(认为它是64位系统..因为它失败阅读记忆。)

请在这里寻找解决方案 EnumProcessModules failed with error 299 on 32bit win7