*pFormat = MDFormat_Invalid;
pStream = MDFormat::GetFirstStream_Verify(&sHdr, pData, &cbStreamBuffer);
// Loop through each stream and pick off the ones we need.
for (i = 0; i < sHdr.GetiStreams(); i++)
{
// Get next stream.
PSTORAGESTREAM pNext = pStream->NextStream_Verify();
if (strcmp(pStream->GetName(), "#~") == 0)
{
// Validate that only one of compressed/uncompressed is present.
if (*pFormat != MDFormat_Invalid)
// Already found a good stream.
goto ErrExit;
// Found the compressed meta data stream.
*pFormat = MDFormat_ReadOnly;
}
else if (strcmp(pStream->GetName(), "#-") == 0)
{
// Validate that only one of compressed/uncompressed is present.
if (*pFormat != MDFormat_Invalid)
// Already found a good stream.
goto ErrExit;
// Found the ENC meta data stream.
*pFormat = MDFormat_ReadWrite;
}
else if (strcmp(pStream->GetName(), "#Schema") == 0)
{
// Found the uncompressed format
*pFormat = MDFormat_ICR;
}
// Pick off the next stream if there is one.
pStream = pNext;
}
pStream = MDFormat::GetFirstStream_Verify(&sHdr, pData, &cbStreamBuffer);
// Loop through each stream and pick off the ones we need.
for (i = 0; i < sHdr.GetiStreams(); i++)
{
void *pvCurrentData = (void *)((BYTE *)pData + pStream->GetOffset());
ULONG cbCurrentData = pStream->GetSize();
// Get next stream.
PSTORAGESTREAM pNext = pStream->NextStream_Verify();
// String pool.
if (strcmp(pStream->GetName(), "#Strings") == 0)
{
// Initialize string heap with null-terminated block of data
IfFailGo(m_MiniMd.m_StringHeap.Initialize(
MetaData::DataBlob((BYTE *)pvCurrentData, cbCurrentData),
FALSE)); // fCopyData
}
// Literal String Blob pool.
else if (strcmp(pStream->GetName(), "#US") == 0)
{
METADATATRACKER_ONLY(MetaDataTracker::NoteSection(TBL_COUNT + MDPoolUSBlobs, pvCurrentData, cbCurrentData, 1));
// Initialize user string heap with block of data
IfFailGo(m_MiniMd.m_UserStringHeap.Initialize(
MetaData::DataBlob((BYTE *)pvCurrentData, cbCurrentData),
FALSE)); // fCopyData
}
// GUID pool.
else if (strcmp(pStream->GetName(), "#GUID") == 0)
{
METADATATRACKER_ONLY(MetaDataTracker::NoteSection(TBL_COUNT + MDPoolGuids, pvCurrentData, cbCurrentData, 1));
// Initialize guid heap with block of data
IfFailGo(m_MiniMd.m_GuidHeap.Initialize(
MetaData::DataBlob((BYTE *)pvCurrentData, cbCurrentData),
FALSE)); // fCopyData
}
// Blob pool.
else if (strcmp(pStream->GetName(), "#Blob") == 0)
{
METADATATRACKER_ONLY(MetaDataTracker::NoteSection(TBL_COUNT + MDPoolBlobs, pvCurrentData, cbCurrentData, 1));
// Initialize blob heap with block of data
IfFailGo(m_MiniMd.m_BlobHeap.Initialize(
MetaData::DataBlob((BYTE *)pvCurrentData, cbCurrentData),
FALSE)); // fCopyData
}
// Found the compressed meta data stream.
else if (strcmp(pStream->GetName(), "#~") == 0)
{
IfFailGo( m_MiniMd.InitOnMem(pvCurrentData, cbCurrentData) );
bFoundMd = true;
}
// Pick off the next stream if there is one.
pStream = pNext;
cbStreamBuffer = (ULONG)((LPBYTE)pData + cbData - (LPBYTE)pNext);}
意思是一切以最后一次发现的表和堆为准
然后我们看看CLR如何加载未压缩的元数据
我化简的代码
[C++] 纯文本查看复制代码
// Load the string pool.
if (SUCCEEDED(hr = pStorage->OpenStream(L"#Strings", &cbData, &pvData)))
{
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolStrings, pvData, cbData, bReadOnly));
}
else
{
if (hr != STG_E_FILENOTFOUND)
{
IfFailGo(hr);
}
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolStrings, NULL, 0, bReadOnly));
}
// Load the user string blob pool.
if (SUCCEEDED(hr = pStorage->OpenStream(L"#US", &cbData, &pvData)))
{
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolUSBlobs, pvData, cbData, bReadOnly));
}
else
{
if (hr != STG_E_FILENOTFOUND)
{
IfFailGo(hr);
}
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolUSBlobs, NULL, 0, bReadOnly));
}
// Load the guid pool.
if (SUCCEEDED(hr = pStorage->OpenStream(L"#GUID", &cbData, &pvData)))
{
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolGuids, pvData, cbData, bReadOnly));
}
else
{
if (hr != STG_E_FILENOTFOUND)
{
IfFailGo(hr);
}
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolGuids, NULL, 0, bReadOnly));
}
// Load the blob pool.
if (SUCCEEDED(hr = pStorage->OpenStream(L"#Blob", &cbData, &pvData)))
{
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolBlobs, pvData, cbData, bReadOnly));
}
else
{
if (hr != STG_E_FILENOTFOUND)
{
IfFailGo(hr);
}
IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolBlobs, NULL, 0, bReadOnly));
}
// Open the metadata.
hr = pStorage->OpenStream(L"#~", &cbData, &pvData);
if (hr == STG_E_FILENOTFOUND)
{
IfFailGo(pStorage->OpenStream(ENC_MODEL_STREAM, &cbData, &pvData));
}