开发者

ERROR_BAD_LENGTH when calling Process32First in Windows 7

I just tried to revoke some old code from Windows XP which generates a list of all running processes, but it failed on Windows 7. Before I continue, here's the code:

#include <windows.h>
#include <tlhelp32.h>

in开发者_JS百科t main()
{
    HANDLE hSnap, hTemp;
    PROCESSENTRY32 pe;

    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if(Process32First(hSnap, &pe)) {
        do {
            ...
            }
        } while(Process32Next(hSnap, &pe));
    }
    ...
}

I checked which function failed and it turned out that it's Process32First. GetLastError() returned 24: "ERROR_BAD_LENGTH" I can't really figure out what the problem is. Any suggestions?


From MSDN: http://msdn.microsoft.com/en-us/library/ms684834(VS.85).aspx

The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure.

To retrieve information about other processes recorded in the same snapshot, use the Process32Next function.


EDIT: You'd probably want to do something like this:

PROCESSENTRY32 pe = {0};
pe.dwSize = sizeof(PROCESSENTRY32);


There's a bug in tlhelp32.h, when invoked in WIN64:

If there's a #pragma pack directive somewhere before including tlhelp32.h, it will generate a PROCESSENTRY32 structure with the wrong size. Then anything can happen, including Process32First failures, or even crashes.

Try including tlhelp32.h this way:

 #pragma pack(push,8) /* Work around a bug in tlhelp32.h in WIN64, which generates the wrong structure if packing has been changed */<br/>
 #include &lt;tlhelp32.h&gt;<br/>
 #pragma pack(pop)


As jglouie answered, the problem is in missed pe.dwSize initialization. As Jean-François Larvoire answered, even if you correctly initialize it, it can still not work due to wrong alignment when including SDK headers. He wrote about 8 bytes alignment, but according to this: the C/C++ headers in the Windows SDK assume the platform's default alignment is used. The default alignment differs between different platforms. For example it's 8 bytes for x86 and 16 bytes for x64 (see the above link for a detailed list).

The solution is to set the default alignment in your project settings and don't use pragma pack for SDK headers.

Theoretically you can use constructs like this:

#ifdef _WIN64
#pragma pack(push,16)
#elif _WIN32
#pragma pack(push,8)
#else
#error Unsupported platform
#endif

include sdk here

#pragma pack(pop)

But these can not work - I encountered a case where including afxwin.h, one of MFC headers, changed alignment to the value from project settings, thus all SDK headers included below it used the wrong alignment.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜