#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct
{
	WORD wLanguage;
	WORD wCodePage;
} LANGANDCODEPAGE;

BOOL PrintVersionInfo(LPTSTR pszProgram)
{
	DWORD dwHandle;
	DWORD cb;
	BYTE *pb;
	LANGANDCODEPAGE *pLangAndCodePage;
	UINT i, uLen, uLen2;
	TCHAR sz[256];
	LPTSTR pch;
	BOOL f;
	
	f = FALSE;
	cb = GetFileVersionInfoSize(pszProgram, &dwHandle);
	if (cb != 0)
	{
		pb = (BYTE *)malloc(cb);
		if (pb != NULL)
		{
			if (GetFileVersionInfo(pszProgram, dwHandle, cb, pb))
			{
				VerQueryValue(pb, 
					TEXT("\\VarFileInfo\\Translation"), 
					(void **)&pLangAndCodePage, &uLen);
				for(i = 0; i < uLen / sizeof(LANGANDCODEPAGE); i++)
				{
					printf("------------------------------------\n");
					printf("コードページ: 0x%04x\n", pLangAndCodePage[i].wCodePage);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\OriginalFilename"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("オリジナル ファイル名: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
						VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("ファイルの説明: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\Comments"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("コメント: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\CompanyName"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("会社名: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\ProductName"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("製品名: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\LegalCopyright"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("著作権: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\LegalTrademarks"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("商標: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\OriginalFileName"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("正式ファイル名: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\InternalName"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("内部名: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("ファイル・バージョン: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\PrivateBuild"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("プライベート・ビルド情報: %s\n", pch);
					wsprintf(sz, 
						TEXT("\\StringFileInfo\\%04x%04x\\SpecialBuild"),
						pLangAndCodePage[i].wLanguage, 
						pLangAndCodePage[i].wCodePage);
					VerQueryValue(pb, sz, (void **)&pch, &uLen2);
					printf("スペシャル・ビルド情報: %s\n", pch);
				}
				f = TRUE;
			}
			free(pb);
		}
	}
	return f;
}

int main(void)
{
	TCHAR szNotepad[] = "notepad.exe";
	PrintVersionInfo(szNotepad);
	return 0;
}