📄 clntxres.cpp
字号:
return err;} // // HIGH LEVEL FUNCTIONS // // // Return a 'C' string from the given ID. //#define STRINGTABLEMASK 0xFFF0#define STRINGENTRYMASK 0x000FSTDMETHODIMP_(IHXXResource*)CHXXResFile::GetString (ULONG32 ID){ HX_ASSERT(this); UINT16 wID = (UINT16)ID; UINT16 StringTableID = wID & STRINGTABLEMASK; StringTableID = StringTableID >> 4; StringTableID++; UINT16 StringEntryID = wID & STRINGENTRYMASK; // // Okay now after determining the string ID, we must // actually load the data. // char* StringTable = NULL; char* ResultString = NULL; char* tempstring = NULL; IHXXResource* OriginalStringTable = NULL; IHXXResource* result = NULL; ULONG32 bufferlength = 0; HX_RESULT rc = HXR_OK; UINT16 counter = 0; UINT16 len = 0; rc = GetResource(HX_RT_STRING,StringTableID,&OriginalStringTable); if (rc != HXR_OK) { goto CleanUp; } HX_ASSERT(OriginalStringTable); StringTable=(char*)OriginalStringTable->ResourceData(); // // Okay now we have the String Table resource data. Let's parse it. // while (counter < StringEntryID) { UINT16 len = *((UINT16*)StringTable); ReverseWORD(len); // // Jump past the length word. // StringTable += 2; HX_ASSERT(StringTable); // // Jump ahead len * 2 // StringTable += (2 * len); HX_ASSERT(StringTable); counter++; } // // Okay we should now be at the string we wnat. // len = *((UINT16*)StringTable); ReverseWORD(len); if (!len) { goto CleanUp; } StringTable += 2; // // Make buffer for holoding the string, add 2 bytes to make it long enough for two \0's // ResultString = new char[(len * 2) + 2]; HX_ASSERT(ResultString); if (!ResultString) { return NULL; } memset(ResultString, 0, (len * 2) + 2); memcpy(ResultString, StringTable, (len * 2)); /* Flawfinder: ignore */ // // Okay turn the string into a normal ASCII string. // tempstring = new char[ (len+1) * 2]; HX_ASSERT(tempstring); if (!tempstring) { goto CleanUp; }#ifdef _WIN32 WideCharToMultiByte(GetCodePage(), 0, (unsigned short*)ResultString, len+1, tempstring, (len+1) * 2, "", 0);#else if (HXR_OK != ProcessFromUnicode((const char*)ResultString, len * 2, tempstring, len * 2)) { delete [] ResultString; ResultString=NULL; delete [] tempstring; tempstring=NULL; goto CleanUp; }#endif // // Here we return the string that was output from the ProcessFromUnicode function. // delete [] ResultString; ResultString = tempstring; // // We return it as an IHXXResource so that deletion happens correctly. // result = new CHXXResource(ResultString, strlen(ResultString)+1, ID, HX_RT_STRING, OriginalStringTable->Language(), this); HX_ASSERT(result); if (result) { result->AddRef(); } if (!result) { delete [] ResultString; }CleanUp: if (OriginalStringTable) { OriginalStringTable->Release(); OriginalStringTable=NULL; StringTable=NULL; } return result;}STDMETHODIMP_(IHXXResource*)CHXXResFile::GetVersionInfo(){ IHXXResource* pRes = NULL; GetResource(HX_RT_VERSION, 1, &pRes); return pRes;}//// Return a "BITMAP" from the given ID.// STDMETHODIMP_(IHXXResource*)CHXXResFile::GetBitmap (ULONG32 ID){ IHXXResource* result = NULL; HX_RESULT rc = GetResource(HX_RT_BITMAP, ID, &result); return result;}//// Return a "DIALOG" from the given ID.//STDMETHODIMP_(IHXXResource*)CHXXResFile::GetDialog (ULONG32 ID){ IHXXResource* result = NULL; HX_RESULT rc = GetResource(HX_RT_DIALOG, ID, &result); return result;}//// This function removes extra resource data chunks, that are loaded// when a resource is loaded.//STDMETHODIMP_(HX_RESULT)CHXXResFile::FlushCache(void){ if (!mCacheList) { return HXR_OK; } // // 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->cached_data) { delete [] curEntry->cached_data; curEntry->cached_data = NULL; curEntry->cached = FALSE; } } /* This fixes a bug causing an infinite loop in the TrimCacheData */ if (mLoadedCache) { listpos = mLoadedCache->GetHeadPosition(); while (listpos) { curEntry = (XResCacheEntry*)mLoadedCache->GetAt(listpos); curEntry->cached_data = NULL; curEntry->cached = FALSE; mLoadedCache->RemoveAt(listpos); listpos = mLoadedCache->GetHeadPosition(); } } return HXR_OK;}//// Sets the amount of memory that can be filled with cached resource data.//STDMETHODIMP_(HX_RESULT)CHXXResFile::SetCacheLimit(ULONG32 MaxCachedData) { mMaxCachedData=MaxCachedData; return HXR_OK;};//// Sets the Language ID of resources to be loaded.//STDMETHODIMP_(HX_RESULT) CHXXResFile::SetLanguage(ULONG32 id){ // // Eventually check a list and determine if the language is valid. // mLanguageId=id; return HXR_OK;}STDMETHODIMPCHXXResFile::UseResourceFile(INT16 nResourceFileRef){ m_nResFileRef = nResourceFileRef; return HXR_OK;} //////// SUPPORT METHODS////HX_RESULT CHXXResFile::FindResourceData(){ HX_RESULT rc = HXR_OK; ULONG32 size; ULONG32 pos; HX_IMAGE_SECTION_HEADER sectionheader; rc = GetSectionHeaderNamed(".rsrc", sectionheader); if (rc != HXR_OK) { return rc; } mResSectionVirtualAddress = sectionheader.VirtualAddress; // // This actually moves us to the data portion of the section. // rc = FindSectionNamed(".rsrc",size,pos); if (rc != HXR_OK) { return rc; } // // Save the location of the ResourceData for a later time. // mResourceDataPosition = pos; return HXR_OK;}//// This function searches the resource tree, and caches the resource data.// This helps later, we basically just do a search of this cache and save// moocho time, instead of reading through the resource tree again.//// Also if the resource had already been loaded, it's data may have been cached already// So we check this later, and return the cached data as well, instead of going back to // disk.//HX_RESULT CHXXResFile::CacheResourceEntries(void){ if (mCacheList) { KillCache(); delete mCacheList; mCacheList = NULL; } if (mLoadedCache) { delete mLoadedCache; mLoadedCache = NULL; } mCacheList = new CHXSimpleList(); if (mCacheList == NULL) { return HXR_OUTOFMEMORY; } HX_RESULT rc = HXR_OK; rc = ReadResourceHeader(); if (rc != HXR_OK) { return rc; } rc = ReadInAllResources(); if (rc != HXR_OK) { return rc; } return HXR_OK;}HX_RESULT CHXXResFile::ReadResourceHeader(void){ return GetResourceDirEntry(mResourceHeader);}//// This function is what actually does the resource reading.// Currently named resources are not being supported.//HX_RESULT CHXXResFile::ReadInAllResources(void){ // Skip ahead over the named resources. mFile->Seek(8*mResourceHeader.NumberOfNamedEntries,1); // Now read each of the tree branches for the entries left. ULONG32 count=mResourceHeader.NumberOfIdEntries; ULONG32 counter=0; for (counter=1; counter <= count; counter++) { HX_IMAGE_RESOURCE_DIRECTORY_ENTRY type; HX_IMAGE_RESOURCE_DIRECTORY_ENTRY id; HX_IMAGE_RESOURCE_DIRECTORY_ENTRY language; HX_IMAGE_RESOURCE_DATA_ENTRY data; ULONG32 curtoplevelpos; ULONG32 rootpos; // // Get the top level directory entries. It is synonymous with type. // rootpos = mFile->Tell(); GetResourceEntry(type); curtoplevelpos = mFile->Tell(); type.OffsetToData = type.OffsetToData ^ 0x80000000; mFile->Seek(type.OffsetToData+mResourceDataPosition, 0); // // Get teh second level directory. It is synonymous with ID. // ULONG32 idoffset = mFile->Tell(); HX_IMAGE_RESOURCE_DIRECTORY dir_id; GetResourceDirEntry(dir_id); // // scan all the entries in the id directory. // for (ULONG32 id_counter = 1; id_counter <= dir_id.NumberOfIdEntries; id_counter++) { GetResourceEntry(id); ULONG32 curIdPos = mFile->Tell(); id.OffsetToData = id.OffsetToData ^ 0x80000000; mFile->Seek(id.OffsetToData+mResourceDataPosition, 0); // // Scan all the language entries for the given id. // HX_IMAGE_RESOURCE_DIRECTORY dir_language; GetResourceDirEntry(dir_language); for (ULONG32 lang_counter = 1; lang_counter <= dir_language.NumberOfIdEntries; lang_counter++) { GetResourceEntry(language); ULONG32 curLangPos = mFile->Tell(); mFile->Seek(language.OffsetToData+mResourceDataPosition, 0); // // Get the Data attributes for this file. // ReadDWord(data.OffsetToData); ReadDWord(data.Size); ReadDWord(data.CodePage); ReadDWord(data.Reserved); // // The data offset is VIRTUAL. // However it is relative to the VIRTUAL address of the section // we are currently in. This adjusts for that, giving us the physical location of the resource. // data.OffsetToData -= mResSectionVirtualAddress; // // Okay cache the data. // XResCacheEntry* newentry = new XResCacheEntry; HX_ASSERT_VALID_PTR(newentry); if (!newentry) { return HXR_OUTOFMEMORY; } memset(newentry, 0, sizeof(XResCacheEntry)); newentry->type = type.Name; newentry->id = id.Name; newentry->language = language.Name; newentry->size = data.Size + sizeof(kEndOfResourceMarker); newentry->location = data.OffsetToData + mResourceDataPosition; // // Add the entry to the cache for later. // mCacheList->AddTail(newentry); // // Seek back to the next language directory entry. // mFile->Seek(curLangPos,0); } // // Seek back to the next ID directory entry // mFile->Seek(curIdPos,0); } // // Reset to the position in the file where the next resource branch starts. // mFile->Seek(curtoplevelpos,0); } return HXR_OK;}HX_RESULT CHXXResFile::GetResourceEntry(HX_IMAGE_RESOURCE_DIRECTORY_ENTRY& h){ IF_ERROR_RETURN(ReadDWord(h.Name));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -