2012-03-02 406 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