Bruno Klein
Bruno Klein

Reputation: 3367

EnumResTypeProc blank LPTSTR argument

I have the following code to enumerate all the resource files in a given .exe

BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam);
BOOL CALLBACK EnumResTypeProc(HMODULE hModule, LPTSTR lpType, LONG_PTR lParam);

REMOTECONTROL_API BOOL EnumResources(LPCWSTR file1, LPCWSTR file2)
{
    HMODULE hFile = LoadLibrary(file1);

    BOOL bSuccess = EnumResourceTypes(hFile, EnumResTypeProc, NULL);

    FreeLibrary(hFile);

    return bSuccess;
}

BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG_PTR lParam)
{
    return TRUE;
}

BOOL CALLBACK EnumResTypeProc(HMODULE hModule, LPTSTR lpType, LONG_PTR lParam)
{
    MessageBox(NULL, lpType, L"Type", 0);
    return TRUE;
}

But when the EnumResTypeProc callback is called, the argument lpType is a blank string.

Why does this happens?

Upvotes: 0

Views: 206

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598154

If you read the documentation, it says:

lpszType [in]
Type: LPTSTR

The type of resource for which the type is being enumerated. Alternately, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is the integer identifier of the given resource type.
...
If IS_INTRESOURCE(lpszType) is TRUE, then lpszType specifies the integer identifier of the given resource type. Otherwise, it is a pointer to a null-terminated string.

Also this documentation says:

Note that the lpszType in EnumResTypeProc is either a resource ID or a pointer to a string (containing a resource ID or type name); lpszType and lpszName in EnumResNameProc and EnumResLangProc are similar.

That means your callback's lpType parameter is not always a pointer to a string, like you are assuming. Sometimes it is a number that has been type-casted as a pointer instead.

Try this:

BOOL CALLBACK EnumResTypeProc(HMODULE hModule, LPWSTR lpType, LONG_PTR lParam)
{
    WCHAR szMsg[256];

    if (IS_INTRESOURCE(lpType))
        StringCchPrintfW(szMsg, 256, L"Type: %u", (USHORT)lpType);
    else
        StringCchPrintfW(szMsg, 256, L"Type: %s", lpType);

    MessageBoxW(NULL, szMsg, L"Type", 0);

    return TRUE;
}

REMOTECONTROL_API BOOL EnumResources(LPCWSTR file1, LPCWSTR file2)
{
    BOOL bSuccess = FALSE;

    HMODULE hFile = LoadLibraryExW(file1, NULL, LOAD_LIBRARY_AS_DATAFILE);
    if (hFile != NULL)
    {
        bSuccess = EnumResourceTypesW(hFile, EnumResTypeProc, NULL);
        FreeLibrary(hFile);
    }

    return bSuccess;
}

Upvotes: 1

Related Questions