OpenProcess the handle is invalid. CloseHandle not

2019-09-21 14:03发布

I don't know what something wrong with my code. i already put condition when the handle is invalid. it will CloseHandle. but it seems not work. this code trying to get processName. when i input exist PID. it return the processName. opposite when i input doesn't exist PID like 10000. it return handle is invalid. and Error Exception throw. but in my code i already put condition when invalid. it will Close Handle.

    std::wstring GetProcessNameById(DWORD i_processId)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
    if (hProcess != NULL)
    {
        wchar_t processFilePath[MAX_PATH];
        if (GetModuleFileNameExW(hProcess, NULL, processFilePath, MAX_PATH))
        {
            CloseHandle(hProcess);
            wchar_t *processFileName = PathFindFileNameW(processFilePath);
            return processFileName;
        }
        else
        {
            CloseHandle(hProcess);
            SystemErrorMessage();
        }
    }
    else 
    {
        CloseHandle(hProcess);
        SystemErrorMessage();
    }
}

int main()
{
std::wcout << GetProcessNameById(10000);
return 0;
}

1条回答
叼着烟拽天下
2楼-- · 2019-09-21 14:57

A compact version of your code makes the bug obvious:

if (hProcess != NULL)
{
    // Left out for brevity
}
else 
{
    // Here, hProcess is NULL
    CloseHandle(hProcess);
    SystemErrorMessage();
}

In essence, this is calling CloseHandle(NULL);, presumably setting the thread's last error code to ERROR_INVALID_HANDLE. SystemErrorMessage() probably blindly calls GetLastError (without evaluating whether it should), and throws an exception if the value returned is anything other than ERROR_SUCCESS.

To fix this, you need to fix the logic bug (remove the call to CloseHandle in the else branch, in which you know hProcess to be invalid). When done, rework your entire error handling. It won't work reliably. You cannot blindly call GetLastError, anytime an API call failed. When done with that, study the RAII idiom, so that you won't have to write manual cleanup code, like you would have to do with C.

查看更多
登录 后发表回答