2012-03-02 126 views
2

我有下面的代码在Windows服务 在Windows XP上执行32位:OpenProcess()成功,但EnumProcessModules()失败

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)。

回答

6

documentation包含答案:

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

返回此错误代码的机器是64位系统,并且您正在枚举的模块的进程是64位进程。

要从32位服务中枚举64位进程的模块,您需要使用 EnumProcessModulesEx事实上,您可能需要运行64位进程来枚举进程模块。

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

+0

对不起,我应该说,它是32位XP平台。 – hmjd 2012-03-02 13:24:32

+0

好的,但您无法访问的机器将是64位。 – 2012-03-02 13:24:58

+0

由于无法访问我个人指的是我:我无法登录并查看。数据是从这些机器远程收集的,包括架构和Windows平台以及任何失败消息。 – hmjd 2012-03-02 13:26:58

2

原因可能是因为您在您的代码中使用CreateProcessA ..并突然调用EnumProcessModules.Thus Windows无法创建ModuleInfo到那个时间,并且它返回错误299(认为它是一个64位系统..因为它无法读取内存)。

请看看这里的一个解决方案 EnumProcessModules failed with error 299 on 32bit win7