📄 clntxres.cpp
字号:
IF_ERROR_RETURN(ReadDWord(h.OffsetToData));
return HXR_OK;
}
HX_RESULT CHXXResFile::GetResourceDirEntry(HX_IMAGE_RESOURCE_DIRECTORY& h)
{
IF_ERROR_RETURN(ReadDWord(h.Characteristics));
IF_ERROR_RETURN(ReadDWord(h.TimeDateStamp));
IF_ERROR_RETURN(ReadWord(h.MajorVersion));
IF_ERROR_RETURN(ReadWord(h.MinorVersion));
IF_ERROR_RETURN(ReadWord(h.NumberOfNamedEntries));
IF_ERROR_RETURN(ReadWord(h.NumberOfIdEntries));
return HXR_OK;
}
HX_RESULT CHXXResFile::FindInCache(ULONG32 type, ULONG32 ID, XResCacheEntry** ppEntry)
{
if (!mCacheList)
{
return HXR_OK;
}
HX_ASSERT(ppEntry);
//
// Scan all entries looking for the matching type, and id.
//
XResCacheEntry* curEntry = NULL;
LISTPOSITION listpos = mCacheList->GetHeadPosition();
while (listpos)
{
curEntry=(XResCacheEntry*) mCacheList->GetNext(listpos);
if (curEntry->type == type &&
curEntry->id == ID &&
curEntry->language == mLanguageId)
{
*ppEntry=curEntry;
return HXR_OK;
}
}
if (curEntry->type == type &&
curEntry->id == ID &&
curEntry->language == mLanguageId)
{
*ppEntry=curEntry;
return HXR_OK;
}
return HXR_RESOURCE_NOT_CACHED;
}
STDMETHODIMP
CHXXResFile::GetFirstResourceLanguage(REF(UINT32) ulLangID)
{
HX_RESULT rc = HXR_FAIL;
if(mCacheList)
{
mCachePos = mCacheList->GetHeadPosition();
if(mCachePos)
{
XResCacheEntry* pEntry = (XResCacheEntry*)mCacheList->
GetNext(mCachePos);
if(pEntry)
{
ulLangID = pEntry->language;
}
rc = HXR_OK;
}
}
return rc;
}
STDMETHODIMP
CHXXResFile::GetNextResourceLanguage(REF(UINT32) ulLangID)
{
HX_RESULT rc = HXR_FAIL;
if(mCacheList &&
mCachePos)
{
XResCacheEntry* pEntry = (XResCacheEntry*)mCacheList->
GetNext(mCachePos);
if(pEntry)
{
ulLangID = pEntry->language;
}
rc = HXR_OK;
}
return rc;
}
const int SIZEOF_VS_VERSION_KEY = 32; // (strlen("VS_VERSION_INFO") + 1) * 2
const int SIZEOF_FILE_INFO_KEY = 30; // (strlen("StringFileInfo") + 1) * 2
static UINT32
GetPadding(BYTE* pOrigin, BYTE* pCur)
{
// return number of bytes of padding needed
// to align pCur on a 32-bit boundary
HX_ASSERT(pCur >= pOrigin);
UINT32 ulOffset = pCur - pOrigin;
return ulOffset % 4;
}
BYTE*
CHXXResFile::GetResInfo(BYTE* pData, UINT16& uResInfoLen,
UINT16& uResInfoType, CHXString& key)
{
// parses a res info struct and returns the
// offset to the 'Children' or 'Value' member
BYTE* pStart = pData;
uResInfoLen = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(uResInfoLen);
UINT16 ulValueLen = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(ulValueLen);
uResInfoType = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(uResInfoType);
UINT32 ulStringMemLen = StringMemLength((const char*)pData);
char* pAsciiString = new char[ulStringMemLen];
ProcessFromUnicode((const char*)pData, (UINT16)ulStringMemLen,
pAsciiString, (UINT16)ulStringMemLen);
key = pAsciiString;
delete[] pAsciiString;
pData += ulStringMemLen;
pData += GetPadding(pStart, pData);
return pData;
}
STDMETHODIMP_(BOOL)
CHXXResFile::IncludesShortName(const char* pShortName)
{
// walk through the resource VERSION information
// to find the string key 'ShortName', then
// see if pShortName is contained in those values
BOOL bFound = FALSE;
IHXXResource* pRes = GetVersionInfo();
if(pRes)
{
BYTE* pData = (BYTE*)pRes->ResourceData();
BYTE* pStart = pData;
// walk through VS_VERSION_INFO
UINT16 vsInfoLen = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(vsInfoLen);
UINT16 vsInfoValueLen = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(vsInfoValueLen);
pData += sizeof(UINT16); // skip type
pData += SIZEOF_VS_VERSION_KEY;
pData += GetPadding(pStart, pData);
pData += vsInfoValueLen; // skip over VS_FIXEDFILEINFO
pData += GetPadding(pStart, pData);
CHXString keyStr;
UINT16 uResInfoLen = 0;
UINT16 uResInfoType = 0;
BYTE* pEndOfData = pStart + vsInfoLen;
while(pData < pEndOfData &&
!bFound)
{
// find 'StringFileInfo'
pData = GetResInfo(pData, uResInfoLen, uResInfoType, keyStr);
if(strcasecmp((const char*)keyStr, "StringFileInfo") == 0)
{
BYTE* pDataEnd = pData + uResInfoLen;
// get string table
pData = GetResInfo(pData, uResInfoLen, uResInfoType, keyStr);
while(pData < pDataEnd &&
!bFound)
{
// get string name/value pairs
pData = GetResInfo(pData, uResInfoLen, uResInfoType, keyStr);
// pData now points to a UNICODE value
UINT32 ulStringMemLen = StringMemLength((const char*)pData);
char* pAsciiString = new char[ulStringMemLen];
ProcessFromUnicode((const char*)pData, (UINT16)ulStringMemLen,
pAsciiString, (UINT16)ulStringMemLen);
if(strcasecmp((const char*)keyStr, "ShortName") == 0)
{
if(strstr(pAsciiString, pShortName))
{
bFound = TRUE;
}
}
delete[] pAsciiString;
pData += ulStringMemLen;
pData += GetPadding(pStart, pData);
}
}
}
HX_RELEASE(pRes);
}
#if defined (_MACINTOSH) || defined (_UNIX) /* version resource type not supported */
bFound = TRUE;
#endif
return bFound; // not implemented yet...
}
//
// This function dumps the entire contents of the cache.
//
HX_RESULT CHXXResFile::KillCache(void)
{
if (!mCacheList)
{
return HXR_OK;
}
//
// Scan all entries killing off any cached data.
//
XResCacheEntry* curEntry = NULL;
LISTPOSITION listpos = mCacheList->GetHeadPosition();
while (listpos)
{
curEntry = (XResCacheEntry*)mCacheList->GetAt(listpos);
if (curEntry->cached == TRUE)
{
HX_ASSERT(curEntry->cached_data);
if (curEntry->cached_data != NULL)
{
delete [] curEntry->cached_data;
curEntry->cached_data = NULL;
}
}
mCacheList->RemoveAt(listpos);
delete curEntry;
listpos = mCacheList->GetHeadPosition();
}
return HXR_OK;
}
HX_RESULT CHXXResFile::TrimCachedData(ULONG32 needed)
{
if (needed > mMaxCachedData)
{
FlushCache();
return HXR_OK;
}
if (mLoadedCache->GetCount()==0)
{
return HXR_OK;
}
LISTPOSITION listpos = mLoadedCache->GetHeadPosition();
ULONG32 totalcached = 0;
XResCacheEntry* curEntry;
while (listpos)
{
curEntry = (XResCacheEntry*)mLoadedCache->GetNext(listpos);
totalcached += curEntry->size;
}
// never get out of this loop
while (mLoadedCache->GetCount() &&
needed + totalcached > mMaxCachedData)
{
//
// Find the largest thing and trash it.
//
LISTPOSITION savepos=NULL;
ULONG32 largestItem = 0;
listpos = mLoadedCache->GetHeadPosition();
while (listpos)
{
curEntry = (XResCacheEntry*)mLoadedCache->GetAt(listpos);
if (curEntry->size > largestItem)
{
savepos = listpos;
largestItem = curEntry->size;
}
mLoadedCache->GetNext(listpos);
}
HX_ASSERT( savepos );
curEntry = (XResCacheEntry*)mLoadedCache->GetAt(savepos);
HX_ASSERT(curEntry->cached && curEntry->cached_data);
delete [] curEntry->cached_data;
curEntry->cached_data = NULL;
curEntry->cached = FALSE;
totalcached -= curEntry->size;
mLoadedCache->RemoveAt(savepos);
}
return HXR_OK;
}
UINT32
CHXXResFile::GetCodePage()
{
if(!m_nCodePage)
{
m_nCodePage = 1252; // Default code page.
IHXXResource* pRes = GetVersionInfo();
if(pRes)
{
BYTE* pData = (BYTE*)pRes->ResourceData();
BYTE* pStart = pData;
// walk through VS_VERSION_INFO
UINT16 vsInfoLen = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(vsInfoLen);
UINT16 vsInfoValueLen = *((UINT16*)pData); pData += sizeof(UINT16);
ReverseWORD(vsInfoValueLen);
pData += sizeof(UINT16); // skip type
pData += SIZEOF_VS_VERSION_KEY;
pData += GetPadding(pStart, pData);
pData += vsInfoValueLen; // skip over VS_FIXEDFILEINFO
pData += GetPadding(pStart, pData);
CHXString keyStr;
UINT16 uResInfoLen = 0;
UINT16 uResInfoType = 0;
BYTE* pEndOfData = pStart + vsInfoLen;
while(pData < pEndOfData)
{
// find 'StringFileInfo'
pData = GetResInfo(pData, uResInfoLen, uResInfoType, keyStr);
if(strcasecmp((const char*)keyStr, "StringFileInfo") == 0)
{
// get string table
pData = GetResInfo(pData, uResInfoLen, uResInfoType, keyStr);
if(keyStr.GetLength() == 8)
{
m_nCodePage = strtoul(keyStr.Right(4), NULL, 16);
break;
}
}
}
}
HX_RELEASE(pRes);
}
return m_nCodePage;
}
//
//
// CHXXResource methods
//
// This object is returned from a call to CHXXResFile::GetResource
//
#ifdef _MACINTOSH
#pragma mark -
#pragma mark ***CHXXResource Entries***
#pragma mark -
#endif
CHXXResource::CHXXResource (void* data,
ULONG32 datalength,
ULONG32 ID,
ULONG32 Type,
ULONG32 Language,
IHXXResFile* file)
{
HX_ASSERT(data);
HX_ASSERT(file);
m_lRefCount = 0;
mResFile = file;
mResData = data;
mID = ID;
mType = Type;
mLength = datalength;
mLanguage = Language;
mResFile->AddRef();
}
CHXXResource::~CHXXResource()
{
if (mResData)
{
delete [] mResData;
mResData = NULL;
}
if (mResFile)
{
mResFile->Release();
}
}
/*
* QueryInterface
* --------------
* Used to get interfaces supported by us.
*
* input:
* REFIID riid - Id of interface.
* void **ppvObj - Place to copy interface pointer.
*
*/
STDMETHODIMP
CHXXResource::QueryInterface
(
REFIID riid,
void** ppvObj
)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IHXXResource), (IHXXResource*)this },
{ GET_IIDHANDLE(IID_IHXXResFile), (IHXXResFile*)mResFile },
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXXResource*)this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
/*
* AddRef
* ------
* Increments the ref count by one.
*
* input:
* void
*
* output:
* ULONG32 - The count.
*
*/
STDMETHODIMP_ (ULONG32)
CHXXResource::AddRef
(
void
)
{
return InterlockedIncrement(&m_lRefCount);
}
/*
* Release
* -------
* Decrements the ref count by one, deleting
* self if count reaches zero.
*
* input:
* void
*
* output:
* ULONG32 - Current ref count.
*
*/
STDMETHODIMP_(ULONG32)
CHXXResource::Release
(
void
)
{
// Decrement, return count if possible.
if (InterlockedDecrement(&m_lRefCount) > 0) return m_lRefCount;
// Else, delete self.
delete this;
return 0;
}
//
// Functions for determining information from a loaded resource.
//
STDMETHODIMP_(ULONG32) CHXXResource::ID (void)
{
return mID;
}
STDMETHODIMP_(ULONG32) CHXXResource::Type (void)
{
return mType;
}
STDMETHODIMP_(ULONG32) CHXXResource::Length (void)
{
return mLength;
}
STDMETHODIMP_(ULONG32) CHXXResource::Language (void)
{
return mLanguage;
}
STDMETHODIMP_(IHXXResFile*) CHXXResource::ResFile (void)
{
IHXXResFile* result = NULL;
QueryInterface(IID_IHXXResFile, (void**)&result);
return result;
}
//
// Data accessors
//
STDMETHODIMP_(void*) CHXXResource::ResourceData (void)
{
return mResData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -