예제 #1
0
BOOL CVersionInfo::ToFile(const CString &strModulePath, LPCTSTR lpszResourceId, 
                          WORD wLangId, const bool bReplace)
{
  CString strUseModulePath(strModulePath);

  if (strUseModulePath.IsEmpty()) {
    strUseModulePath = m_strModulePath;
  }

  if (NULL == lpszResourceId) {
    //Try resource ID that we loaded from;
    lpszResourceId = m_lpszResourceId;

    if (NULL == lpszResourceId) {
      //Use default
      lpszResourceId = MAKEINTRESOURCE(1);
    }
  }

  if (0xFFFF == wLangId) {
    //Try using language that we loaded from
    wLangId = m_wLangId;

    if (0xFFFF == wLangId) {
      //Use neutral
      wLangId = NULL;
    }
  }

  CVersionInfoBuffer viSaveBuf;
  Write(viSaveBuf);

  return UpdateModuleResource(strUseModulePath, lpszResourceId, wLangId,
                              viSaveBuf.GetData(), viSaveBuf.GetPosition(), bReplace);
}
예제 #2
0
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;

}
예제 #3
0
void CStringTable::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(0);

	//Write wType
	viBuf.WriteWord(1);

	//Write key
	viBuf.WriteString(m_strKey);

	POSITION posString = m_lstStrings.GetHeadPosition();
	while (posString)
	{
		CVersionInfoString * pString = (CVersionInfoString*) m_lstStrings.GetNext(posString);
		pString->Write(viBuf);
	}
	//Set the size of the structure based on current offset from the position
	viBuf.WriteStructSize(pos);
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
BOOL CVersionInfo::FromFile(const CString &strModulePath, LPCTSTR lpszResourceId, WORD wLangId)
{
	CVersionInfoBuffer viLoadBuf;

	m_wLangId = wLangId;
	m_lpszResourceId = (LPTSTR)lpszResourceId;

	//LoadVersionInfoResource will update member variables m_wLangId, m_lpszResourceId, which is awkward, need to change this flow
	if (!LoadVersionInfoResource(strModulePath, viLoadBuf, lpszResourceId, wLangId))
		return FALSE;

	m_strModulePath = strModulePath;

	DWORD dwSize = viLoadBuf.GetPosition();
	VERSION_INFO_HEADER* pVI = (VERSION_INFO_HEADER*) viLoadBuf.GetData();
	
	ASSERT(!wcscmp(pVI->szKey, L"VS_VERSION_INFO"));

	VS_FIXEDFILEINFO* pFixedInfo = (VS_FIXEDFILEINFO*)DWORDALIGN(&pVI->szKey[wcslen(pVI->szKey)+1]);
	
	memcpy(&m_vsFixedFileInfo, pFixedInfo, sizeof(VS_FIXEDFILEINFO));
	
	// Iterate children StringFileInfo or VarFileInfo
	BaseFileInfo *pChild = (BaseFileInfo*) DWORDALIGN((DWORD)pFixedInfo + pVI->wValueLength);
	
	BOOL bHasVar = FALSE;
	BOOL bHasStrings = FALSE;
	BOOL bBlockOrderKnown = FALSE;
	CStringList lstTranslations;

	while ((DWORD)pChild < ((DWORD)(pVI) + pVI->wLength))
	{
		if (!wcscmp(pChild->szKey, L"StringFileInfo"))
		{
			//It is a StringFileInfo
			//ASSERT(1 == pChild->wType);
			//如果类型是0表示二进制内容,类型为1时才包含字符串内容
			if (1 != pChild->wType)
			{
				//pChild = (BaseFileInfo*)DWORDALIGN((DWORD)pChild + pChild->wLength);
				//continue;
			}

			StringFileInfo* pStringFI = (StringFileInfo*)pChild;
			ASSERT(!pStringFI->wValueLength);
			
			//MSDN says: Specifies an array of zero or one StringFileInfo structures.  So there should be only one StringFileInfo at most
			ASSERT(m_stringFileInfo.IsEmpty());
			
			m_stringFileInfo.FromStringFileInfo(pStringFI);
			bHasStrings = TRUE;
		}
		else
		{
			VarFileInfo* pVarInfo = (VarFileInfo*)pChild;
			//ASSERT(1 == pVarInfo->wType);
			//如果类型是0表示二进制内容,类型为1时才包含字符串内容
			if (1 != pChild->wType)
			{
				//pChild = (BaseFileInfo*)DWORDALIGN((DWORD)pChild + pChild->wLength);
				//continue;
			}

			ASSERT(!wcscmp(pVarInfo->szKey, L"VarFileInfo"));
			ASSERT(!pVarInfo->wValueLength);
			//Iterate Var elements
			//There really must be only one
			Var* pVar = (Var*) DWORDALIGN(&pVarInfo->szKey[wcslen(pVarInfo->szKey)+1]);
			while ((DWORD)pVar < ((DWORD) pVarInfo + pVarInfo->wLength))
			{
				ASSERT(!bHasVar && "Multiple Vars in VarFileInfo");
				ASSERT(!wcscmp(pVar->szKey, L"Translation"));
				ASSERT(pVar->wValueLength);
				
				DWORD *pValue = (DWORD*) DWORDALIGN(&pVar->szKey[wcslen(pVar->szKey)+1]);
				DWORD *pdwTranslation = pValue;
				while ((LPBYTE)pdwTranslation < (LPBYTE)pValue + pVar->wValueLength)
				{
					CString strStringTableKey;
					strStringTableKey.Format(_T("%04x%04x"), LOWORD(*pdwTranslation), HIWORD(*pdwTranslation));
								
					lstTranslations.AddTail(strStringTableKey);
					pdwTranslation++;
				}

				bHasVar = TRUE;
				pVar = (Var*) DWORDALIGN((DWORD)pVar + pVar->wLength);
			}

			ASSERT(bHasVar && "No Var in VarFileInfo");

		}
		
		if (!bBlockOrderKnown)
		{
			bBlockOrderKnown = TRUE;
			m_bRegularInfoOrder = bHasStrings;
		}
		pChild = (BaseFileInfo*) DWORDALIGN((DWORD)pChild + pChild->wLength);
	}


#ifdef _DEBUG
	ASSERT((DWORD)lstTranslations.GetCount() == m_stringFileInfo.GetStringTableCount());

	CString strKey = m_stringFileInfo.GetFirstStringTable().GetKey();
	POSITION posTranslation = lstTranslations.GetHeadPosition();
	while (posTranslation)
	{
		CString strTranslation = lstTranslations.GetNext(posTranslation);
		CString strTranslationUpper (strTranslation);
		strTranslation.MakeUpper();

		ASSERT(m_stringFileInfo.HasStringTable(strTranslation) || m_stringFileInfo.HasStringTable(strTranslationUpper));
	}

	//Verify Write
	CVersionInfoBuffer viSaveBuf;
	Write(viSaveBuf);
	ASSERT(viSaveBuf.GetPosition() == viLoadBuf.GetPosition());
	ASSERT(!memcmp(viSaveBuf.GetData(), viLoadBuf.GetData(), viSaveBuf.GetPosition()));

	CFile fOriginal(_T("f1.res"), CFile::modeCreate | CFile::modeWrite);
	fOriginal.Write(viLoadBuf.GetData(), viLoadBuf.GetPosition());
	fOriginal.Close();

	CFile fSaved(_T("f2.res"), CFile::modeCreate | CFile::modeWrite);
	fSaved.Write(viSaveBuf.GetData(), viSaveBuf.GetPosition());
	fSaved.Close();
#endif
	return TRUE;
}