unsigned int ExeHeadStringList::find(const void *ptr, unsigned int cchF, WORD codepage, bool processed, char**ppBufMB) const { const wchar_t *find = (const wchar_t*) ptr; // Data is: m_wide ? UTF16LE : wchar_t if (!*find) return 0; // The empty string is always first. char *p = (char*) m_gr.get(); if (!p) return -1; unsigned int cbF = ++cchF * 2; // Include \0 as part of cchF, * 2 for UTF16 & DBCS. char *bufMB = 0; if (!m_wide) { unsigned int cbMB; bufMB = new char[cbF]; if (processed) { char *pTmp = convert_processed_string_to_ansi(bufMB,find,codepage); cbMB = pTmp ? pTmp - bufMB : 0; } else { cbMB = WideCharToMultiByte(codepage,0,find,cchF,bufMB,cbF,0,0); } assert(cbMB); cbF = cbMB, find = (const wchar_t*) bufMB; } unsigned int cbList = gettotalsize(), cb = 0, retval = -1, pos; pos = 1 + !!m_wide, p += pos; // Skip empty string if (m_wide) { for(;;) { if (pos+=cb >= cbList) break; cb = (StrLenUTF16(p+=cb) + 1) * 2; if (cb < cbF) continue; if (byte_rev_match(p,find,cbF)) { retval = pos / WIDEDIV; break; } } } else { for(;;) { if (pos+=cb >= cbList) break; cb = strlen(p+=cb) + 1; if (cb < cbF) continue; if (byte_rev_match(p,find,cbF)) { retval = pos; break; } } if (ppBufMB) *ppBufMB = bufMB; else delete[] bufMB; } return retval; }
/* * find() finds the offset where the string is stored, returns -1 if not found. * It only compares raw byte values, there is no Unicode normalization handling. * If ppBufMB is non-null you must delete[] it (Only valid when m_wide is false)! */ unsigned int ExeHeadStringList::find(const TCHAR *str, WORD codepage, bool processed, char**ppBufMB) const { if (m_wide && *str) { WCToUTF16LEHlpr cnv; if (!cnv.Create(str)) return -1; unsigned int pos = find(cnv.Get(),StrLenUTF16(cnv.Get()),codepage,processed,ppBufMB); cnv.Destroy(); return pos; } else { return find(str,_tcslen(str),codepage,processed,ppBufMB); } }
// Helper function only used by CResourceVersionInfo::ExportToStream // Cannot handle anything longer than 65K objects. // // @param wLength Size in bytes of the entire object we are storing. // @param wValueLength The value length in bytes. // @param wType If type is 1, it's a wchar_t string, so save value length appropriately. // @param key The string key // @param value The value mapped to string key. static void SaveVersionHeaderUTF16LE(GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const unsigned short *key, void *value) { WORD valueLen; WORD keyLen; strm.add (&wLength, sizeof(wLength)); strm.add (&wValueLength, sizeof(wValueLength)); strm.add (&wType, sizeof (wType)); keyLen = WORD((StrLenUTF16(key) + 1) * sizeof(WINWCHAR)); strm.add ((void*)key, keyLen); PadStream(strm); if ( wValueLength > 0 ) { valueLen = wValueLength; if ( wType == 1 ) valueLen = valueLen * WORD(sizeof(WINWCHAR)); strm.add (value, valueLen); } }
unsigned int ExeHeadStringList::getnum() const { char *p = (char*) m_gr.get(); if (!p) return 1; // The empty string always exists unsigned int cbList = gettotalsize(), cb = 0, num = 1, pos; pos = 1 + !!m_wide, p += pos; // Skip empty string if (m_wide) { for(;;) { if (pos+=cb >= cbList) break; cb = StrLenUTF16(p+=cb) + 1, ++num; } } else { for(;;) { if (pos+=cb >= cbList) break; cb = strlen(p+=cb) + 1, ++num; } } return num; }
void CResourceVersionInfo::ExportToStream(GrowBuf &strm, int Index) { DWORD v; WORD wSize; int p, p1; strm.resize(0); SaveVersionHeader(strm, 0, sizeof (VS_FIXEDFILEINFO), 0, L"VS_VERSION_INFO", &m_FixedInfo); DefineList *pChildStrings = m_ChildStringLists.get_strings(Index); if ( pChildStrings->getnum() > 0 ) { GrowBuf stringInfoStream; int codepage = m_ChildStringLists.get_codepage(Index); LANGID langid = m_ChildStringLists.get_lang(Index); wchar_t Buff[16]; _snwprintf(Buff, COUNTOF(Buff), L"%04x%04x", langid, codepage); SaveVersionHeader(stringInfoStream, 0, 0, 0, Buff, &ZEROS); for ( int i = 0; i < pChildStrings->getnum(); i++ ) { PadStream (stringInfoStream); WCToUTF16LEHlpr cnvName, cnvValue; if (!cnvName.Create(pChildStrings->getname(i), codepage)) throw std::runtime_error("Unicode conversion failed"); if (!cnvValue.Create(pChildStrings->getvalue(i), codepage)) throw std::runtime_error("Unicode conversion failed"); p = stringInfoStream.getlen(); SaveVersionHeaderUTF16LE(stringInfoStream, 0, WORD(StrLenUTF16(cnvValue.Get()) + 1), 1, cnvName.Get(), (void*)cnvValue.Get()); cnvName.Destroy(), cnvValue.Destroy(); wSize = WORD(stringInfoStream.getlen() - p); *(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize; } wSize = WORD(stringInfoStream.getlen()); *(WORD*)((PBYTE)stringInfoStream.get())=wSize; PadStream (strm); p = strm.getlen(); SaveVersionHeader(strm, 0, 0, 0, L"StringFileInfo", &ZEROS); strm.add (stringInfoStream.get(), stringInfoStream.getlen()); wSize = WORD(strm.getlen() - p); *(WORD*)((PBYTE)strm.get()+p)=wSize; } // Show all languages avaiable using Var-Translations if ( m_ChildStringLists.getnum() > 0 ) { PadStream (strm); p = strm.getlen(); SaveVersionHeader(strm, 0, 0, 0, L"VarFileInfo", &ZEROS); PadStream (strm); p1 = strm.getlen(); SaveVersionHeader(strm, 0, 0, 0, L"Translation", &ZEROS); // First add selected code language translation v = MAKELONG(m_ChildStringLists.get_lang(Index), m_ChildStringLists.get_codepage(Index)); strm.add (&v, sizeof (v)); for ( int k =0; k < m_ChildStringLists.getnum(); k++ ) { if ( k != Index ) { v = MAKELONG(m_ChildStringLists.get_lang(k), m_ChildStringLists.get_codepage(k)); strm.add (&v, sizeof (v)); } } wSize = WORD(strm.getlen() - p1); *(WORD*)((PBYTE)strm.get()+p1)=wSize; wSize = WORD(sizeof (int) * m_ChildStringLists.getnum()); p1+=sizeof(WORD); *(WORD*)((PBYTE)strm.get()+p1)=wSize; wSize = WORD(strm.getlen() - p); *(WORD*)((PBYTE)strm.get()+p)=wSize; } wSize = WORD(strm.getlen()); *(WORD*)((PBYTE)strm.get())=wSize; }