}
//*****************************************************************************
-// To get a new instance, call CreateNewInstance() or CreateNewInstanceEx() instead of new
+// To get a new instance, call CreateNewInstance() instead of new
//*****************************************************************************
-HRESULT CeeFileGenWriter::CreateNewInstance(CCeeGen *pCeeFileGenFrom,
- CeeFileGenWriter* & pGenWriter,
+HRESULT CeeFileGenWriter::CreateNewInstance(CeeFileGenWriter* & pGenWriter,
DWORD createFlags)
-{
- return CreateNewInstanceEx(pCeeFileGenFrom, pGenWriter, createFlags);
-}
-
-//
-// Seed file is used as the base file. The new file data will be "appended" to the seed file
-//
-
-HRESULT CeeFileGenWriter::CreateNewInstanceEx(CCeeGen *pCeeFileGenFrom,
- CeeFileGenWriter* & pGenWriter,
- DWORD createFlags,
- LPCWSTR seedFileName)
{
HRESULT hr = S_OK;
ULONG preallocatedOffset = 0;
if (pPEWriter == NULL)
IfFailGo(E_OUTOFMEMORY);
- //workaround
- //What's really the correct thing to be doing here?
- //HRESULT hr = pPEWriter->Init(pCeeFileGenFrom ? pCeeFileGenFrom->getPESectionMan() : NULL);
- hr = pPEWriter->Init(NULL, createFlags, seedFileName);
+ hr = pPEWriter->Init(NULL, createFlags);
IfFailGo(hr);
//Create the general PEWriter.
hr = pPrivateGenWriter->Init(); // base class member to finish init
IfFailGo(hr);
- if (!seedFileName) // Use base file's preferred base (if present)
+ if (pPEWriter->isPE32())
{
- if (pPEWriter->isPE32())
- {
- pPrivateGenWriter->setImageBase((DWORD) CEE_IMAGE_BASE_32); // use same default as linker
- }
- else
- {
- pPrivateGenWriter->setImageBase64((ULONGLONG) CEE_IMAGE_BASE_64); // use same default as linker
- }
+ pPrivateGenWriter->setImageBase((DWORD) CEE_IMAGE_BASE_32); // use same default as linker
+ }
+ else
+ {
+ pPrivateGenWriter->setImageBase64((ULONGLONG) CEE_IMAGE_BASE_64); // use same default as linker
}
pPrivateGenWriter->setSubsystem(IMAGE_SUBSYSTEM_WINDOWS_CUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION);
hr = pPrivateGenWriter->allocateCorHeader(); // get COR header near front
IfFailGo(hr);
- //If we were passed a CCeeGen at the beginning, copy it's data now.
- if (pCeeFileGenFrom) {
- pCeeFileGenFrom->cloneInstance((CCeeGen*)pPrivateGenWriter);
- }
-
hr = pPrivateGenWriter->getSectionCreate(".text0", sdExecute, &corHeaderSection);
IfFailGo(hr);
preallocatedOffset = corHeaderSection->dataLen();
}
HRESULT ICeeFileGen::CreateCeeFileEx (HCEEFILE *ceeFile, DWORD createFlags)
-{
- return CreateCeeFileEx2(ceeFile, createFlags, NULL);
-}
-
-//
-// Seed file is used as the base file. The new file data will be "appended" to the seed file
-//
-
-HRESULT ICeeFileGen::CreateCeeFileEx2 (HCEEFILE *ceeFile, DWORD createFlags, LPCWSTR seedFileName)
{
if (!ceeFile)
return E_POINTER;
CeeFileGenWriter *gen = NULL;
HRESULT hr;
- IfFailRet(CeeFileGenWriter::CreateNewInstanceEx(NULL, gen, createFlags, seedFileName));
+ IfFailRet(CeeFileGenWriter::CreateNewInstance(gen, createFlags));
TESTANDRETURN(gen != NULL, E_OUTOFMEMORY);
*ceeFile = gen;
return S_OK;
}
-HRESULT ICeeFileGen::CreateCeeFileFromICeeGen(ICeeGenInternal *pICeeGen, HCEEFILE *ceeFile, DWORD createFlags)
-{
- if (!ceeFile)
- return E_POINTER;
- CCeeGen *genFrom = reinterpret_cast<CCeeGen*>(pICeeGen);
- CeeFileGenWriter *gen = NULL;
- HRESULT hr = CeeFileGenWriter::CreateNewInstance(genFrom, gen, createFlags);
- if (FAILED(hr))
- return hr;
- TESTANDRETURN(gen != NULL, E_OUTOFMEMORY);
- *ceeFile = gen;
- return S_OK;
-}
-
HRESULT ICeeFileGen::DestroyCeeFile(HCEEFILE *ceeFile)
{
if (!ceeFile)
return S_OK;
}
-HRESULT ICeeFileGen::GetIMapTokenIface(HCEEFILE ceeFile, IMetaDataEmit *emitter, IUnknown **pIMapToken)
-{
- _ASSERTE(!"This is an obsolete function!");
- return E_NOTIMPL;
-}
-
HRESULT ICeeFileGen::GetMethodRVA(HCEEFILE ceeFile, ULONG codeOffset, ULONG *codeRVA)
{
TESTANDRETURNARG(ceeFile != 0);
return(gen->emitMetaData(emitter, sec, offset, buffer, buffLen));
}
-HRESULT ICeeFileGen::GetIMapTokenIfaceEx(HCEEFILE ceeFile, IMetaDataEmit *emitter, IUnknown **pIMapToken)
-{
- TESTANDRETURNPOINTER(ceeFile);
- TESTANDRETURNPOINTER(pIMapToken);
-
- CeeFileGenWriter *gen = reinterpret_cast<CeeFileGenWriter*>(ceeFile);
- return gen->getMapTokenIface(pIMapToken);
-}
-
-HRESULT ICeeFileGen::AddNotificationHandler(HCEEFILE ceeFile,
- IUnknown *pHandler)
-{
- TESTANDRETURNPOINTER(ceeFile);
- TESTANDRETURNPOINTER(pHandler);
-
- CeeFileGenWriter *gen = reinterpret_cast<CeeFileGenWriter*>(ceeFile);
- return gen->addNotificationHandler(pHandler);
-}
-
HRESULT ICeeFileGen::SetManifestEntry(HCEEFILE ceeFile, ULONG size, ULONG offset)
{
TESTANDRETURNPOINTER(ceeFile);
}
/******************************************************************/
-
-PESeedSection::PESeedSection(PEDecoder * peDecoder,
- IMAGE_SECTION_HEADER * seedSection)
- : PEWriterSection((const char *)seedSection->Name,
- VAL32(seedSection->Characteristics),
- VAL32(seedSection->SizeOfRawData),
- 0),
- m_pSeedFileDecoder(peDecoder),
- m_pSeedSectionHeader(seedSection)
-{
- m_baseRVA = VAL32(seedSection->VirtualAddress);
-}
-
-HRESULT PESeedSection::write(HANDLE file) {
- ULONG sizeOfSection = VAL32(m_pSeedSectionHeader->SizeOfRawData);
- LPCVOID sectionData = PBYTE(m_pSeedFileDecoder->GetBase()) + m_pSeedSectionHeader->PointerToRawData;
-
- DWORD dwWritten = 0;
- if (!WriteFile(file, sectionData, sizeOfSection, &dwWritten, NULL)) {
- return HRESULT_FROM_GetLastError();
- }
- _ASSERTE(dwWritten == sizeOfSection);
- return S_OK;
-}
-
-unsigned PESeedSection::writeMem(void ** pMem) {
- ULONG sizeOfSection = VAL32(m_pSeedSectionHeader->SizeOfRawData);
- LPCVOID sectionData = PBYTE(m_pSeedFileDecoder->GetBase()) + m_pSeedSectionHeader->PointerToRawData;
-
- COPY_AND_ADVANCE(*pMem, sectionData, sizeOfSection);
- return sizeOfSection;
-}
-
-/******************************************************************/
-HRESULT PEWriter::Init(PESectionMan *pFrom, DWORD createFlags, LPCWSTR seedFileName)
+HRESULT PEWriter::Init(PESectionMan *pFrom, DWORD createFlags)
{
if (pFrom)
*(PESectionMan*)this = *pFrom;
m_file = INVALID_HANDLE_VALUE;
- //
- // Seed file
- //
-
- m_hSeedFile = INVALID_HANDLE_VALUE;
- m_hSeedFileMap = INVALID_HANDLE_VALUE;
- m_pSeedFileDecoder = NULL;
- m_iSeedSections = 0;
- m_pSeedSectionToAdd = NULL;
-
- if (seedFileName)
- {
- HandleHolder hFile (WszCreateFile(seedFileName,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL));
-
- if (hFile == INVALID_HANDLE_VALUE)
- return HRESULT_FROM_GetLastError();
-
- MapViewHolder hMapFile (WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL));
- DWORD dwFileLen = SafeGetFileSize(hFile, 0);
- if (dwFileLen == 0xffffffff)
- return HRESULT_FROM_GetLastError();
-
- if (hMapFile == NULL)
- return HRESULT_FROM_GetLastError();
-
- BYTE * baseFileView = (BYTE*) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
-
- PEDecoder * pPEDecoder = new (nothrow) PEDecoder(baseFileView, (COUNT_T)dwFileLen);
- if (pPEDecoder == NULL) return E_OUTOFMEMORY;
-
- if (pPEDecoder->Has32BitNTHeaders())
- {
- if ((createFlags & ICEE_CREATE_FILE_PE32) == 0)
- return E_FAIL;
-
- setImageBase32(DWORD(size_t(pPEDecoder->GetPreferredBase())));
- }
- else
- {
- if ((createFlags & ICEE_CREATE_FILE_PE64) == 0)
- return E_FAIL;
-
- setImageBase64(UINT64((intptr_t) pPEDecoder->GetPreferredBase()));
- }
-
- setFileAlignment (VAL32(pPEDecoder->GetFileAlignment()));
- setSectionAlignment(VAL32(pPEDecoder->GetSectionAlignment()));
-
- hFile.SuppressRelease();
- hMapFile.SuppressRelease();
-
- m_hSeedFile = hFile;
- m_hSeedFileMap = hMapFile;
- m_pSeedFileDecoder = pPEDecoder;
-
-#ifdef HOST_64BIT
- m_pSeedFileNTHeaders = pPEDecoder->GetNTHeaders64();
-#else
- m_pSeedFileNTHeaders = pPEDecoder->GetNTHeaders32();
-#endif
-
- // Add the seed sections
-
- m_pSeedSections = m_pSeedFileDecoder->FindFirstSection();
-
- m_pSeedSectionToAdd = m_pSeedSections;
- m_iSeedSections = m_pSeedFileDecoder->GetNumberOfSections();
-
- for (unsigned i = 0; i < m_iSeedSections; m_pSeedSectionToAdd++, i++) {
- PESection * dummy;
- getSectionCreate((const char *)(m_pSeedSectionToAdd->Name),
- VAL32(m_pSeedSectionToAdd->Characteristics),
- &dummy);
- }
-
- m_pSeedSectionToAdd = NULL;
- }
-
return S_OK;
}
/******************************************************************/
HRESULT PEWriter::Cleanup() {
- if (m_hSeedFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(m_hSeedFile);
- CloseHandle(m_hSeedFileMap);
- delete m_pSeedFileDecoder;
- }
-
if (isPE32())
{
delete ntHeaders32();
return PESectionMan::Cleanup();
}
-PESection* PEWriter::getSection(const char* name)
-{
- int len = (int)strlen(name);
-
- // the section name can be at most 8 characters including the null.
- if (len < 8)
- len++;
- else
- len = 8;
-
- // dbPrintf(("looking for section %s\n", name));
- // Skip over the seed sections
-
- for(PESection** cur = sectStart+m_iSeedSections; cur < sectCur; cur++) {
- // dbPrintf(("searching section %s\n", (*cur)->m_ame));
- if (strncmp((*cur)->m_name, name, len) == 0) {
- // dbPrintf(("found section %s\n", (*cur)->m_name));
- return(*cur);
- }
- }
- return(0);
-}
-
HRESULT PEWriter::newSection(const char* name, PESection **section,
unsigned flags, unsigned estSize,
unsigned estRelocs)
{
- if (m_pSeedSectionToAdd) {
- _ASSERTE(strcmp((const char *)(m_pSeedSectionToAdd->Name), name) == 0 &&
- VAL32(m_pSeedSectionToAdd->Characteristics) == flags);
-
- PESeedSection * ret = new (nothrow) PESeedSection(m_pSeedFileDecoder, m_pSeedSectionToAdd);
- *section = ret;
- TESTANDRETURNMEMORY(ret);
- return S_OK;
- }
-
PEWriterSection * ret = new (nothrow) PEWriterSection(name, flags, estSize, estRelocs);
*section = ret;
TESTANDRETURNMEMORY(ret);
entry * m_entries;
PEWriterSection ** m_sections;
unsigned m_count;
- unsigned m_seedCount;
public:
- SectionNameSorter(entry *entries, PEWriterSection ** sections, int count, unsigned seedSections)
+ SectionNameSorter(entry *entries, PEWriterSection ** sections, int count)
: CQuickSort<entry>(entries, count),
m_entries(entries),
m_sections(sections),
- m_count(unsigned(count)),
- m_seedCount(seedSections)
+ m_count(unsigned(count))
{}
// Sorts the entries according to alphabetical + numerical order
PEWriterSection * firstSection = m_sections[first->arrayIndex];
PEWriterSection * secondSection = m_sections[second->arrayIndex];
- // Seed sections are always at the start, in the order they were
- // added to the PEWriter
-
- if (firstSection->isSeedSection() || secondSection->isSeedSection()) {
- if (firstSection->isSeedSection() && secondSection->isSeedSection())
- return first->arrayIndex - second->arrayIndex;
-
- return firstSection->isSeedSection() ? -1 : 1;
- }
-
// Sort the names
int lenDiff = first->nameLength - second->nameLength;
for (unsigned i = 1; i < m_count; i++, ePrev = e, e++) {
- // Seed sections should stay at the front
- _ASSERTE(i >= m_seedCount || i == e->arrayIndex);
-
- if (!m_sections[ePrev->arrayIndex]->isSeedSection() &&
- (ePrev->nameLength == e->nameLength) &&
+ if ((ePrev->nameLength == e->nameLength) &&
strncmp(ePrev->name, e->name, e->nameLength) == 0)
{
continue;
// Sort the entries according to alphabetical + numerical order
//
- SectionNameSorter sorter(entries, getSectStart(), int(e - entries), m_iSeedSections);
+ SectionNameSorter sorter(entries, getSectStart(), int(e - entries));
*piUniqueSections = sorter.SortSections();
*piEntries = unsigned(e - entries);
for (entry * e = entries ; e < entriesEnd; e++)
{
if (ePrev != NULL
- && !getSectStart()[ePrev->arrayIndex]->isSeedSection()
&& e->nameLength == ePrev->nameLength
&& strncmp(e->name, ePrev->name, e->nameLength) == 0)
{
entry * e = entries + VAL32(h->FirstEntryIndex);
PEWriterSection *s = getSectStart()[e->arrayIndex];
- if (s->isSeedSection()) {
- virtualPos = s->getBaseRVA();
- }
-
h->VirtualAddress = VAL32(virtualPos);
h->PointerToRawData = VAL32(filePos);
void PEWriter::setSectionIndex(IMAGE_SECTION_HEADER * h, unsigned sectionIndex) {
- if (getSectStart()[sectionIndex]->isSeedSection()) {
- h->SectionIndex = VAL32(sectionIndex);
- return;
- }
-
//
// Reserve some dummy "array index" values for special sections
// at the start of the image (after the seed sections)
}
else if (strcmp((char *) h->Name, *s) == 0)
{
- h->SectionIndex = VAL32(m_iSeedSections + DWORD(s - SpecialNames));
+ h->SectionIndex = VAL32(DWORD(s - SpecialNames));
break;
}
}
virtualPos = roundUp(filePos, VAL32(m_ntHeaders->OptionalHeader.SectionAlignment));
- if (m_hSeedFile != INVALID_HANDLE_VALUE) {
- // We do not support relocating/sliding down the seed sections
- if (filePos > VAL32(m_pSeedSections->VirtualAddress) ||
- virtualPos > VAL32(m_pSeedSections->VirtualAddress))
- return E_FAIL;
-
- if (virtualPos < VAL32(m_pSeedSections->VirtualAddress)) {
- virtualPos = VAL32(m_pSeedSections->VirtualAddress);
- }
- }
-
// Now finally assign RVAs to the sections
IfFailRet(linkPlaceSections(entries, iEntries));
void PEWriter::setImageBase32(DWORD imageBase)
{
- _ASSERTE(m_hSeedFile == INVALID_HANDLE_VALUE);
-
_ASSERTE(isPE32());
ntHeaders32()->OptionalHeader.ImageBase = VAL32(imageBase);
}
public:
// See ICeeFileGen.h for definition of createFlags
- HRESULT Init(PESectionMan *pFrom, DWORD createFlags, LPCWSTR seedFileName = NULL);
+ HRESULT Init(PESectionMan *pFrom, DWORD createFlags);
HRESULT Cleanup();
- // Finds section with given name. returns 0 if not found
- virtual PESection* getSection(const char* name);
-
// Create a new section
virtual HRESULT newSection(const char* name, PESection **section,
unsigned flags=sdNone, unsigned estSize=0x10000,
HANDLE m_file;
- // "Seed" file information. The new file data will be "appended" to the seed file
- // These are valid only if m_hSeedFile is valid
-
- HANDLE m_hSeedFile;
- HANDLE m_hSeedFileMap;
- PEDecoder * m_pSeedFileDecoder;
- IMAGE_NT_HEADERS * m_pSeedFileNTHeaders;
- unsigned m_iSeedSections;
- IMAGE_SECTION_HEADER*m_pSeedSections;
- IMAGE_SECTION_HEADER*m_pSeedSectionToAdd; // used only by newSection()
-
PEWriterSection **getSectStart() {
return (PEWriterSection**)sectStart;
}
virtual HRESULT write (HANDLE file);
virtual unsigned writeMem (void ** pMem);
- virtual bool isSeedSection() { return false; }
-
-};
-
-// This is for sections from the seed file. Their order needs to be maintained and
-// they need to be written to the output file.
-
-class PESeedSection : public PEWriterSection {
-
-public:
-
- PESeedSection(PEDecoder * peDecoder, IMAGE_SECTION_HEADER * seedSection);
-
- // PESection methods
-
- unsigned dataLen() { return m_pSeedSectionHeader->SizeOfRawData; }
- HRESULT applyRelocs(CeeGenTokenMapper *pTokenMapper) { return S_OK; }
- char* getBlock(unsigned len, unsigned align) { _ASSERTE(!"PESeedSection"); return NULL; }
- HRESULT truncate(unsigned newLen) { _ASSERTE(!"PESeedSection"); return E_FAIL; }
- void writeSectReloc(unsigned val, CeeSection& relativeTo,
- CeeSectionRelocType reloc,
- CeeSectionRelocExtra *extra) { _ASSERTE(!"PESeedSection"); return; }
- HRESULT addSectReloc(unsigned offset, CeeSection& relativeTo,
- CeeSectionRelocType reloc,
- CeeSectionRelocExtra *extra) { _ASSERTE(!"PESeedSection"); return E_FAIL; }
- HRESULT addSectReloc(unsigned offset, PESection *relativeTo,
- CeeSectionRelocType reloc,
- CeeSectionRelocExtra *extra) { _ASSERTE(!"PESeedSection"); return E_FAIL; }
- HRESULT addBaseReloc(unsigned offset, CeeSectionRelocType reloc,
- CeeSectionRelocExtra *extra) { _ASSERTE(!"PESeedSection"); return E_FAIL; }
-// unsigned char *name();
-// unsigned flags();
-// unsigned getBaseRVA();
- int getDirEntry() { _ASSERTE(!"PESeedSection"); return 0; }
- HRESULT directoryEntry(unsigned num) { _ASSERTE(!"PESeedSection"); return E_FAIL; }
- char * computePointer(unsigned offset) const { _ASSERTE(!"PESeedSection"); return NULL; }
- BOOL containsPointer(_In_ char *ptr) const { _ASSERTE(!"PESeedSection"); return FALSE; }
- unsigned computeOffset(_In_ char *ptr) const { _ASSERTE(!"PESeedSection"); return 0; }
- HRESULT cloneInstance(PESection *destination) { _ASSERTE(!"PESeedSection"); return E_FAIL; }
-
- // PEWriterSection
-
- HRESULT applyRelocs(IMAGE_NT_HEADERS * pNtHeaders,
- PERelocSection * relocSection,
- CeeGenTokenMapper * pTokenMapper,
- DWORD rdataRvaBase,
- DWORD dataRvaBase,
- DWORD textRvaBase) { return S_OK; }
-
- HRESULT write(HANDLE file);
- unsigned writeMem(void ** pMem);
- bool isSeedSection() { return true; }
-
-protected:
-
- PEDecoder * m_pSeedFileDecoder;
- IMAGE_SECTION_HEADER * m_pSeedSectionHeader;
-
};
inline DWORD PEWriter::getSectionAlignment() {
- return VAL32(m_ntHeaders->OptionalHeader.FileAlignment);
+ return VAL32(m_ntHeaders->OptionalHeader.SectionAlignment);
}
inline void PEWriter::setSectionAlignment(DWORD SectionAlignment) {
-
- _ASSERTE(m_hSeedFile == INVALID_HANDLE_VALUE);
m_ntHeaders->OptionalHeader.SectionAlignment = VAL32(SectionAlignment);
}
}
inline void PEWriter::setFileAlignment(DWORD fileAlignment) {
- _ASSERTE(m_hSeedFile == INVALID_HANDLE_VALUE);
m_ntHeaders->OptionalHeader.FileAlignment = VAL32(fileAlignment);
}
HRESULT allocateIAT();
public:
// Create with one of these two methods, not operator new
- static HRESULT CreateNewInstance(CCeeGen *pCeeFileGenFrom, CeeFileGenWriter* & pGenWriter,
- DWORD createFlags = ICEE_CREATE_FILE_PURE_IL);
- // See ICeeFileGen.h for the definition of the bits used in createFlags
- static HRESULT CreateNewInstanceEx(CCeeGen *pCeeFileGenFrom, CeeFileGenWriter* & pGenWriter,
- DWORD createFlags, LPCWSTR seedFileName = NULL);
+ static HRESULT CreateNewInstance(CeeFileGenWriter* & pGenWriter,
+ DWORD createFlags = ICEE_CREATE_FILE_PURE_IL);
virtual HRESULT Cleanup();
CeeGenTokenMapper *m_pTokenMap;
BOOLEAN m_fTokenMapSupported; // temporary to support both models
- IMapToken *m_pRemapHandler;
CeeSection **m_sections;
short m_numSections;
ULONG RVA,
UCHAR **lpBuffer);
- STDMETHODIMP GetIMapTokenIface (
- IUnknown **pIMapToken);
-
STDMETHODIMP GenerateCeeFile ();
STDMETHODIMP GetIlSection (
UCHAR **lpBuffer); // [OUT] Returned buffer
- STDMETHODIMP AddNotificationHandler(IUnknown *pHandler);
-
// Write the metadata in "emitter" to the default metadata section is "section" is 0
// If 'section != 0, it will put the data in 'buffer'. This
// buffer is assumed to be in 'section' at 'offset' and of size 'buffLen'
LIMITED_METHOD_CONTRACT;
return m_pTokenMap;
}
-
- virtual HRESULT addNotificationHandler(IUnknown *pHandler);
-
- //Clone is actually a misnomer here. This method will copy all of the
- //instance variables and then do a deep copy (as necessary) of the sections.
- //Section data will be appended onto any information already in the section.
- //This is done to support the DynamicIL -> PersistedIL transform.
- virtual HRESULT cloneInstance(CCeeGen *destination);
};
// ***** CeeSection inline methods
static int IndexForType(mdToken tk);
- CeeGenTokenMapper() : m_pIImport(0), m_cRefs(1), m_pIMapToken(NULL) { LIMITED_METHOD_CONTRACT; }
+ CeeGenTokenMapper() : m_pIImport(0), m_cRefs(1) { LIMITED_METHOD_CONTRACT; }
virtual ~CeeGenTokenMapper() {}
//*****************************************************************************
ULONG cRefs = --m_cRefs;
if (cRefs == 0)
{
- if (m_pIMapToken)
- {
- m_pIMapToken->Release();
- m_pIMapToken = NULL;
- }
-
delete this;
}
return cRefs;
//*****************************************************************************
virtual HRESULT GetMetaData(IMetaDataImport **ppIImport);
-//*****************************************************************************
-// Add another token mapper.
-//*****************************************************************************
- virtual HRESULT AddTokenMapper(IMapToken *pIMapToken)
- {
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_FORBID_FAULT;
-
- // Add the token mapper, if there isn't already one.
- if (m_pIMapToken == NULL)
- {
- m_pIMapToken = pIMapToken;
- m_pIMapToken->AddRef();
- return S_OK;
- }
- else
- {
- _ASSERTE(!"Token mapper already set!");
- return E_FAIL;
- }
- }
-
protected:
// m_rgMap is an array indexed by token type. For each type, an array of
// tokens is kept, indexed by from rid. To see if a token has been moved,
TOKENMAP m_rgMap[MAX_TOKENMAP];
IMetaDataImport *m_pIImport;
ULONG m_cRefs; // Ref count.
- IMapToken *m_pIMapToken;
-
};
#endif // __CeeGenTokenMapper_h__
ULONG RVA, // [IN] RVA for method to return
UCHAR * *lpBuffer) PURE; // [OUT] Returned buffer
- STDMETHOD(GetIMapTokenIface) (
- IUnknown * *pIMapToken) PURE;
-
STDMETHOD(GenerateCeeFile) () PURE;
STDMETHOD(GetIlSection) (
virtual HRESULT SetComImageFlags (HCEEFILE ceeFile, DWORD mask);
virtual HRESULT GetComImageFlags (HCEEFILE ceeFile, DWORD *mask);
- // get IMapToken interface for tracking mapped tokens
- virtual HRESULT GetIMapTokenIface(HCEEFILE ceeFile, IMetaDataEmit *emitter, IUnknown **pIMapToken);
virtual HRESULT SetDirectoryEntry (HCEEFILE ceeFile, HCEESECTION section, ULONG num, ULONG size, ULONG offset = 0);
// Write out the metadata in "emitter" to the metadata section in "ceeFile"
// Use EmitMetaDataAt() for more control
virtual HRESULT EmitMetaDataEx (HCEEFILE ceeFile, IMetaDataEmit *emitter);
- virtual HRESULT GetIMapTokenIfaceEx(HCEEFILE ceeFile, IMetaDataEmit *emitter, IUnknown **pIMapToken);
-
- virtual HRESULT CreateCeeFileFromICeeGen(
- ICeeGenInternal *pFromICeeGen, HCEEFILE *ceeFile, DWORD createFlags = ICEE_CREATE_FILE_PURE_IL); // call this to instantiate a file handle
-
virtual HRESULT SetManifestEntry(HCEEFILE ceeFile, ULONG size, ULONG offset);
virtual HRESULT ComputeSectionOffset(HCEESECTION section, _In_ char *ptr,
virtual HRESULT GetFileTimeStamp (HCEEFILE ceeFile, DWORD *pTimeStamp);
- // Add a notification handler. If it implements an interface that
- // the ICeeFileGen understands, S_OK is returned. Otherwise,
- // E_NOINTERFACE.
- virtual HRESULT AddNotificationHandler(HCEEFILE ceeFile,
- IUnknown *pHandler);
-
virtual HRESULT SetFileAlignment(HCEEFILE ceeFile, ULONG fileAlignment);
virtual HRESULT ClearComImageFlags (HCEEFILE ceeFile, DWORD mask);
PIMAGE_SECTION_HEADER *ppSections,
ULONG *pNumSections);
- // Seed file is a base file which is copied over into the output file
- // Note that there are restrictions on the seed file (the sections
- // cannot be relocated), and that the copy is not complete as the new
- // headers overwrite the seed file headers.
- virtual HRESULT CreateCeeFileEx2(HCEEFILE *ceeFile, ULONG createFlags,
- LPCWSTR seedFileName = NULL);
-
virtual HRESULT SetVTableEntry64(HCEEFILE ceeFile, ULONG size, void* ptr);
};
DWORD GetCheckSum() const;
WORD GetMachine() const;
WORD GetCharacteristics() const;
- DWORD GetFileAlignment() const;
- DWORD GetSectionAlignment() const;
SIZE_T GetSizeOfStackReserve() const;
SIZE_T GetSizeOfStackCommit() const;
SIZE_T GetSizeOfHeapReserve() const;
return VAL32(FindNTHeaders()->OptionalHeader.CheckSum);
}
-inline DWORD PEDecoder::GetFileAlignment() const
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckNTHeaders());
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- //even though some data in OptionalHeader is different for 32 and 64, this field is the same
- return VAL32(FindNTHeaders()->OptionalHeader.FileAlignment);
-}
-
-inline DWORD PEDecoder::GetSectionAlignment() const
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckNTHeaders());
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- //even though some data in OptionalHeader is different for 32 and 64, this field is the same
- return VAL32(FindNTHeaders()->OptionalHeader.SectionAlignment);
-}
-
inline WORD PEDecoder::GetMachine() const
{
CONTRACTL
// Apply all the relocs for in memory conversion
HRESULT applyRelocs(CeeGenTokenMapper *pTokenMapper);
- HRESULT cloneInstance(PESectionMan *destination);
-
protected:
// Finds section with given name. returns 0 if not found
// computes an offset as if this were an array
virtual unsigned computeOffset(_In_ char *ptr) const;
- // Make 'destination' a copy of the current PESection
- HRESULT cloneInstance(PESection *destination);
-
// Cause the section to allocate memory in smaller chunks
void SetInitialGrowth(unsigned growth);
return hr;
}
-STDMETHODIMP CCeeGen::GetIMapTokenIface (
- IUnknown **pIMapToken)
-{
- _ASSERTE(!"E_NOTIMPL");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP CCeeGen::AddNotificationHandler (
- IUnknown *pHandler)
-{
- _ASSERTE(!"E_NOTIMPL");
- return E_NOTIMPL;
-}
-
STDMETHODIMP CCeeGen::GenerateCeeFile ()
{
_ASSERTE(!"E_NOTIMPL");
m_cRefs = 0;
m_peSectionMan = NULL;
m_pTokenMap = NULL;
- m_pRemapHandler = NULL;
-
}
// Shared init code between derived classes, called by virtual Init()
m_pTokenMap = NULL;
m_fTokenMapSupported = FALSE;
- m_pRemapHandler = NULL;
// These text section needs special support for handling string management now that we have
// merged the sections together, so create it with an underlying CeeSectionString rather than the
return hr;
}
-HRESULT CCeeGen::cloneInstance(CCeeGen *destination) { //public, virtual
- _ASSERTE(destination);
-
- destination->m_pTokenMap = m_pTokenMap;
- destination->m_fTokenMapSupported = m_fTokenMapSupported;
- destination->m_pRemapHandler = m_pRemapHandler;
-
- //Create a deep copy of the section manager (and each of it's sections);
- return m_peSectionMan->cloneInstance(destination->m_peSectionMan);
-}
-
HRESULT CCeeGen::Cleanup() // virtual
{
HRESULT hr;
m_pTokenMap = NULL;
}
- if (m_pRemapHandler)
- {
- m_pRemapHandler->Release();
- m_pRemapHandler = NULL;
- }
-
if (m_peSectionMan) {
m_peSectionMan->Cleanup();
delete m_peSectionMan;
}
m_pTokenMap = pMapper;
m_fTokenMapSupported = (emitter == 0);
-
- // If we've been holding onto a token remap handler waiting
- // for the token mapper to get created, add it to the token
- // mapper now and release our hold on it.
- if (m_pRemapHandler && m_pTokenMap)
- {
- m_pTokenMap->AddTokenMapper(m_pRemapHandler);
- m_pRemapHandler->Release();
- m_pRemapHandler = NULL;
- }
}
*pIMapToken = getTokenMapper()->GetMapTokenIface();
return S_OK;
}
-
-HRESULT CCeeGen::addNotificationHandler(IUnknown *pHandler)
-{
- // Null is no good...
- if (!pHandler)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- IMapToken *pIMapToken = NULL;
-
- // Is this an IMapToken? If so, we can put it to good use...
- if (SUCCEEDED(pHandler->QueryInterface(IID_IMapToken,
- (void**)&pIMapToken)))
- {
- // You gotta have a token mapper to use an IMapToken, though.
- if (m_pTokenMap)
- {
- hr = m_pTokenMap->AddTokenMapper(pIMapToken);
- pIMapToken->Release();
- }
- else
- {
- // Hold onto it for later, just in case a token mapper
- // gets created. We're holding a reference to it here,
- // too.
- m_pRemapHandler = pIMapToken;
- }
- }
-
- return hr;
-}
_ASSERTE(IndexForType(tkFrom) < GetMaxMapSize());
_ASSERTE(IndexForType(tkTo) != -1 && IndexForType(tkTo) < GetMaxMapSize());
- // If there is another token mapper that the user wants called, go
- // ahead and call it now.
- if (m_pIMapToken)
- m_pIMapToken->Map(tkFrom, tkTo);
-
ridFrom = RidFromToken(tkFrom);
pMap = &m_rgMap[IndexForType(tkFrom)];
return S_OK;
}
-//Clone each of our sections. This will cause a deep copy of the sections
-HRESULT PESectionMan::cloneInstance(PESectionMan *destination) {
- _ASSERTE(destination);
- PESection *pSection;
- PESection **destPtr;
- HRESULT hr = NOERROR;
-
- //Copy each of the sections
- for (PESection** ptr = sectStart; ptr < sectCur; ptr++) {
- destPtr = destination->sectStart;
- pSection = NULL;
-
- // try to find the matching section by name
- for (; destPtr < destination->sectCur; destPtr++)
- {
- if (strcmp((*destPtr)->m_name, (*ptr)->m_name) == 0)
- {
- pSection = *destPtr;
- break;
- }
- }
- if (destPtr >= destination->sectCur)
- {
- // cannot find a section in the destination with matching name
- // so create one!
- IfFailRet( destination->getSectionCreate((*ptr)->m_name,
- (*ptr)->flags(),
- &pSection) );
- }
- if (pSection)
- IfFailRet( (*ptr)->cloneInstance(pSection) );
- }
-
- //destination->sectEnd=destination->sectStart + (sectEnd-sectStart);
- return S_OK;
-}
-
-
//*****************************************************************************
// Implementation for PESection
//*****************************************************************************
return S_OK;
}
-HRESULT PESection::cloneInstance(PESection *destination) {
- PESectionReloc *cur;
- INT32 newSize;
- HRESULT hr = NOERROR;
-
- _ASSERTE(destination);
-
- destination->dirEntry = dirEntry;
-
- //Merge the information currently in the BlobFetcher into
- //out current blob fetcher
- m_blobFetcher.Merge(&(destination->m_blobFetcher));
-
- //Copy the name.
- strncpy_s(destination->m_name, sizeof(destination->m_name), m_name, sizeof(m_name) - 1);
-
- //Clone the relocs
- //If the arrays aren't the same size, reallocate as necessary.
- //<REVISIT_TODO>@FUTURE: Make this a ref-counted structure and don't copy it.</REVISIT_TODO>
-
- newSize = (INT32)(m_relocCur-m_relocStart);
-
- if (newSize>(destination->m_relocEnd - destination->m_relocStart)) {
- delete[] destination->m_relocStart;
-
- destination->m_relocStart = new (nothrow) PESectionReloc[newSize];
- if (destination->m_relocStart == NULL)
- IfFailGo( E_OUTOFMEMORY );
- destination->m_relocEnd = destination->m_relocStart+(newSize);
- }
-
- //copy the correct data over into our new array.
- memcpy(destination->m_relocStart, m_relocStart, sizeof(PESectionReloc)*(newSize));
- destination->m_relocCur = destination->m_relocStart + (newSize);
- for (cur=destination->m_relocStart; cur<destination->m_relocCur; cur++) {
- cur->section=destination;
- }
-ErrExit:
- return hr;
-}
-
void PESection::SetInitialGrowth(unsigned growth)
{
m_blobFetcher.SetInitialGrowth(growth);