📄 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;}STDMETHODIMPCHXXResFile::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;}STDMETHODIMPCHXXResFile::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) * 2const int SIZEOF_FILE_INFO_KEY = 30; // (strlen("StringFileInfo") + 1) * 2static UINT32GetPadding(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;}UINT32CHXXResFile::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 -#endifCHXXResource::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 + -