#include <windows.h>
#include "file_info.h"

bool FileInfoUtils::QueryValue(const std::wstring wsValueName, const std::wstring wsModuleName, std::wstring &wsRetStr)
{
    bool bSuccess = FALSE;
    BYTE *lpVersionData = NULL;
    DWORD dwLangCharset = 0;
    TCHAR *pStr = NULL;

    do {
        if (wsValueName.empty() || wsModuleName.empty())
            break;

        DWORD dwHandle;
        DWORD dwDataSize = ::GetFileVersionInfoSize((LPCWSTR)wsModuleName.c_str(), &dwHandle);
        if (dwDataSize == 0)
            break;

        lpVersionData = new (std::nothrow) BYTE[dwDataSize];
        if (NULL == lpVersionData)
            break;

        if (!::GetFileVersionInfo((LPCWSTR)wsModuleName.c_str(), dwHandle, dwDataSize, (void *)lpVersionData))
            break;

        UINT nQuerySize;
        DWORD *pTransTable;
        if (!::VerQueryValue(lpVersionData, L"\\VarFileInfo\\Translation", (void **)&pTransTable, &nQuerySize))
            break;

        dwLangCharset = MAKELONG(HIWORD(pTransTable[0]), LOWORD(pTransTable[0]));
        if (lpVersionData == NULL)
            break;

        pStr = new (std::nothrow) TCHAR[128];
        if (NULL == pStr)
            break;

        // wchar_t str2[MAX_PATH];
        // wcscpy_s(str2, MAX_PATH, wsValueName.c_str());
        swprintf_s(pStr, 128, L"\\StringFileInfo\\%08lx\\%s", dwLangCharset, wsValueName.c_str());

        LPVOID lpData;

        // GetFileVersionInfoSize, GetFileVersionInfo
        if (::VerQueryValue((void *)lpVersionData, pStr, &lpData, &nQuerySize))
            wsRetStr = (TCHAR *)lpData;

        bSuccess = TRUE;

    } while (FALSE);

    if (lpVersionData) {
        delete[] lpVersionData;
        lpVersionData = NULL;
    }
    
    if (pStr) {
        delete[] pStr;
        pStr = NULL;
    }

    return bSuccess;
}
