예제 #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::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;
}