BOOL CVersionInfo::LoadVersionInfoResource(const CString& strModulePath, CVersionInfoBuffer &viBuf, LPCTSTR lpszResourceId, WORD wLangId) { HRSRC hResInfo; HMODULE hModule = LoadLibraryEx(strModulePath, NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); if (NULL == hModule) return FALSE; if ((NULL == lpszResourceId) && (wLangId == 0xFFFF)) { //Load first RT_VERSION resource that will be found m_lpszResourceId = NULL; EnumResourceNames(hModule, RT_VERSION, (ENUMRESNAMEPROC)EnumResourceNamesFuncFindFirst, (LONG_PTR)this); if (NULL == m_lpszResourceId) { FreeLibrary(hModule); return FALSE; } // Now the m_lpszResourceId must be the name of the resource m_wLangId = 0xFFFF; EnumResourceLanguages(hModule, RT_VERSION, m_lpszResourceId, (ENUMRESLANGPROC)EnumResourceLangFuncFindFirst, (LONG_PTR)this); // Found resource, copy the ID's to local vars lpszResourceId = m_lpszResourceId; wLangId = m_wLangId; } hResInfo = FindResourceEx(hModule, RT_VERSION, lpszResourceId, wLangId); // Write the resource language to the resource information file. DWORD dwSize = SizeofResource(hModule, hResInfo); if (dwSize) { HGLOBAL hgRes = LoadResource(hModule, hResInfo); if (hgRes) { LPVOID lpMemory = LockResource(hgRes); if (lpMemory) { viBuf.Write(lpMemory,dwSize); UnlockResource(hgRes); FreeLibrary(hModule); return TRUE; } } } FreeLibrary(hModule); return FALSE; }
void CVersionInfo::WriteVarInfo(CVersionInfoBuffer & viBuf) { //Check string tables if (m_stringFileInfo.IsEmpty()) return; //Prepare to write VarFileInfo DWORD posVarInfo = viBuf.PadToDWORD(); //Skip size of VarFileInfo for now; viBuf.Pad(sizeof WORD); //Write wValueLength viBuf.WriteWord(0); //Write type viBuf.WriteWord(1); viBuf.WriteString(L"VarFileInfo"); //Save offset of Var structure (Translation) DWORD posTranslation = viBuf.PadToDWORD(); viBuf.Pad(sizeof WORD); //Write size of translation, that is number of string tables * size of DWORD DWORD dwTableCount = m_stringFileInfo.GetStringTableCount(); viBuf.WriteWord(LOWORD(dwTableCount * sizeof DWORD)); //Write type viBuf.WriteWord(0); //Write key (Translation) viBuf.WriteString(L"Translation"); //Pad for value viBuf.PadToDWORD(); //Collect all id's in one DWORD array DWORD *pTranslationBuf = (DWORD*)_alloca(dwTableCount * sizeof DWORD); DWORD *pTranslation = pTranslationBuf; POSITION posTable = m_stringFileInfo.GetFirstStringTablePosition(); while (posTable) { CStringTable * pStringTable = m_stringFileInfo.GetNextStringTable(posTable); TCHAR* pchEnding = NULL; DWORD dwKey = _tcstol(pStringTable->GetKey(),&pchEnding, 16); *pTranslation = (LOWORD(dwKey) << 16) | (HIWORD(dwKey)); pTranslation++; } viBuf.Write(pTranslationBuf, dwTableCount * sizeof DWORD); //Write structure sizes viBuf.WriteStructSize(posTranslation); viBuf.WriteStructSize(posVarInfo); }
void CVersionInfo::Write(CVersionInfoBuffer & viBuf) { //Pad to DWORD and save position for wLength DWORD pos = viBuf.PadToDWORD(); //Skip size for now; viBuf.Pad(sizeof WORD); //Write wValueLength viBuf.WriteWord(sizeof VS_FIXEDFILEINFO); //Write wType viBuf.WriteWord(0); //Write key viBuf.WriteString(L"VS_VERSION_INFO"); //Pad Fixed info viBuf.PadToDWORD(); //Write Fixed file info viBuf.Write(&m_vsFixedFileInfo, sizeof VS_FIXEDFILEINFO); if (m_bRegularInfoOrder) { //Write string file info, it will pad as needed m_stringFileInfo.Write(viBuf); WriteVarInfo(viBuf); } else { WriteVarInfo(viBuf); //Write string file info, it will pad as needed m_stringFileInfo.Write(viBuf); } //Set the size of the Version Info viBuf.WriteStructSize(pos); }