summaryrefslogtreecommitdiff
path: root/src/ilasm/writer_enc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ilasm/writer_enc.cpp')
-rw-r--r--src/ilasm/writer_enc.cpp661
1 files changed, 661 insertions, 0 deletions
diff --git a/src/ilasm/writer_enc.cpp b/src/ilasm/writer_enc.cpp
new file mode 100644
index 0000000000..055b2edca9
--- /dev/null
+++ b/src/ilasm/writer_enc.cpp
@@ -0,0 +1,661 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// writer_ENC.cpp
+//
+
+//
+#include "ilasmpch.h"
+
+#include "assembler.h"
+
+//#include "ceefilegenwriter.h"
+#include "strongname.h"
+
+int ist=0;
+#define REPT_STEP //printf("Step %d\n",++ist);
+
+HRESULT Assembler::InitMetaDataForENC(__in __nullterminated WCHAR* wzOrigFileName)
+{
+ HRESULT hr = E_FAIL;
+
+ if((wzOrigFileName==NULL)||(*wzOrigFileName == 0)||(m_pDisp==NULL)) return hr;
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->Close();
+ m_pSymWriter->Release();
+ m_pSymWriter = NULL;
+ }
+ if (m_pImporter != NULL)
+ {
+ m_pImporter->Release();
+ m_pImporter = NULL;
+ }
+ if (m_pEmitter != NULL)
+ {
+ m_pEmitter->Release();
+ m_pEmitter = NULL;
+ }
+ //WszSetEnvironmentVariable(L"COMP_ENC_OPENSCOPE", wzOrigFileName);
+ //hr = m_pDisp->DefineScope(CLSID_CorMetaDataRuntime, 0, IID_IMetaDataEmit2,
+ // (IUnknown **)&m_pEmitter);
+
+ if((m_pbsMD==NULL)||(m_pbsMD->length()==0))
+ {
+ _ASSERTE(!"NO BASE METADATA!");
+ return E_FAIL;
+ }
+
+ VARIANT encOption;
+ V_VT(&encOption) = VT_UI4;
+ V_UI4(&encOption) = MDUpdateENC;
+ m_pDisp->SetOption(MetaDataSetENC, &encOption);
+ V_UI4(&encOption) = MDErrorOutOfOrderDefault;
+ m_pDisp->SetOption(MetaDataErrorIfEmitOutOfOrder, &encOption);
+ hr = m_pDisp->OpenScopeOnMemory( m_pbsMD->ptr(),
+ m_pbsMD->length(),
+ ofWrite,
+ IID_IMetaDataEmit2,
+ (IUnknown **)&m_pEmitter);
+ _ASSERTE(SUCCEEDED(hr));
+ if (FAILED(hr))
+ goto exit;
+
+ m_pManifest->SetEmitter(m_pEmitter);
+ if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataImport2, (void**)&m_pImporter)))
+ goto exit;
+
+ //WszSetEnvironmentVariable(L"COMP_ENC_EMIT", wzOrigFileName);
+ if(!Init()) goto exit; // close and re-open CeeFileGen and CeeFile
+ hr = S_OK;
+
+#ifndef FEATURE_CORECLR
+ hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_ISymUnmanagedWriter,
+ (void **)&m_pSymWriter);
+ if(SUCCEEDED(hr))
+ {
+ WCHAR* pwc = &wzOrigFileName[wcslen(wzOrigFileName)];
+ wcscat_s(wzOrigFileName,MAX_SCOPE_LENGTH,W(".pdb"));
+ if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
+ wzOrigFileName,
+ NULL,
+ TRUE);
+ *pwc = 0;
+ }
+ else
+ {
+ fprintf(stderr, "Error: CoCreateInstance(IID_ISymUnmanagedWriter) returns %X\n",hr);
+ m_pSymWriter = NULL;
+ }
+#endif
+
+exit:
+ return hr;
+}
+/*********************************************************************************/
+
+BOOL Assembler::EmitFieldsMethodsENC(Class* pClass)
+{
+ unsigned n;
+ BOOL ret = TRUE;
+ // emit all field definition metadata tokens
+ if((pClass->m_FieldDList.COUNT()))
+ {
+ FieldDescriptor* pFD;
+ int j;
+ for(j=0, n=0; (pFD = pClass->m_FieldDList.PEEK(j)); j++) // can't use POP here: we'll need field list for props
+ {
+ if(pFD->m_fNew)
+ {
+ if(!EmitField(pFD))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pFD->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Fields: %d;\t",n);
+ }
+ // Fields are emitted; emit the class layout
+ {
+ COR_FIELD_OFFSET *pOffsets = NULL;
+ ULONG ul = pClass->m_ulPack;
+ ULONG N = pClass->m_dwNumFieldsWithOffset;
+
+ EmitSecurityInfo(pClass->m_cl,
+ pClass->m_pPermissions,
+ pClass->m_pPermissionSets);
+ pClass->m_pPermissions = NULL;
+ pClass->m_pPermissionSets = NULL;
+ if((pClass->m_ulSize != 0xFFFFFFFF)||(ul != 0)||(N != 0))
+ {
+ if(IsTdAutoLayout(pClass->m_Attr)) report->warn("Layout specified for auto-layout class\n");
+ if((ul > 128)||((ul & (ul-1)) !=0 ))
+ report->error("Invalid packing parameter (%d), must be 1,2,4,8...128\n",pClass->m_ulPack);
+ if(N)
+ {
+ pOffsets = new COR_FIELD_OFFSET[N+1];
+ ULONG i,j=0;
+ FieldDescriptor *pFD;
+ for(i=0; (pFD = pClass->m_FieldDList.PEEK(i)); i++)
+ {
+ if(pFD->m_ulOffset != 0xFFFFFFFF)
+ {
+ pOffsets[j].ridOfField = RidFromToken(pFD->m_fdFieldTok);
+ pOffsets[j].ulOffset = pFD->m_ulOffset;
+ j++;
+ }
+ }
+ _ASSERTE(j == N);
+ pOffsets[j].ridOfField = mdFieldDefNil;
+ }
+ m_pEmitter->SetClassLayout (
+ pClass->m_cl, // [IN] typedef
+ ul, // [IN] packing size specified as 1, 2, 4, 8, or 16
+ pOffsets, // [IN] array of layout specification
+ pClass->m_ulSize); // [IN] size of the class
+ if(pOffsets) delete [] pOffsets;
+ }
+ }
+ // emit all method definition metadata tokens
+ if((pClass->m_MethodList.COUNT()))
+ {
+ Method* pMethod;
+ int i;
+
+ for(i=0, n=0; (pMethod = pClass->m_MethodList.PEEK(i));i++)
+ {
+ if(pMethod->m_fNew)
+ {
+ if(!EmitMethod(pMethod))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pMethod->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Methods: %d;\t",n);
+ }
+ if(m_fReportProgress) printf("\n");
+ return ret;
+}
+
+BOOL Assembler::EmitEventsPropsENC(Class* pClass)
+{
+ unsigned n;
+ BOOL ret = TRUE;
+ // emit all event definition metadata tokens
+ if((pClass->m_EventDList.COUNT()))
+ {
+ EventDescriptor* pED;
+ int j;
+ for(j=0,n=0; (pED = pClass->m_EventDList.PEEK(j)); j++) // can't use POP here: we'll need event list for props
+ {
+ if(pED->m_fNew)
+ {
+ if(!EmitEvent(pED))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pED->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Events: %d;\t",n);
+ }
+ // emit all property definition metadata tokens
+ if((pClass->m_PropDList.COUNT()))
+ {
+ PropDescriptor* pPD;
+ int j;
+
+ for(j=0,n=0; (pPD = pClass->m_PropDList.PEEK(j)); j++)
+ {
+ if(pPD->m_fNew)
+ {
+ if(!EmitProp(pPD))
+ {
+ if(!OnErrGo) return FALSE;
+ ret = FALSE;
+ }
+ pPD->m_fNew = FALSE;
+ n++;
+ }
+ }
+ if(m_fReportProgress) printf("Props: %d;\t",n);
+ }
+ if(m_fReportProgress) printf("\n");
+ return ret;
+}
+
+HRESULT Assembler::CreateDeltaFiles(__in __nullterminated WCHAR *pwzOutputFilename)
+{
+ HRESULT hr;
+ DWORD mresourceSize = 0;
+ BYTE* mresourceData = NULL;
+ WCHAR* pEnd = NULL;
+
+ if(m_fReportProgress) printf("Creating DMETA,DIL files\n");
+ if (!m_pEmitter)
+ {
+ printf("Error: Cannot create a PE file with no metadata\n");
+ return E_FAIL;
+ }
+REPT_STEP
+ if(m_pManifest)
+ {
+ hr = S_OK;
+ if(m_pManifest->m_pAsmEmitter==NULL)
+ hr=m_pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &(m_pManifest->m_pAsmEmitter));
+
+ if(SUCCEEDED(hr))
+ {
+ m_pManifest->EmitAssemblyRefs();
+ }
+ }
+ // Emit classes, class members and globals:
+ {
+ Class *pSearch;
+ int i;
+ BOOL bIsUndefClass = FALSE;
+ if(m_fReportProgress) printf("\nEmitting classes:\n");
+ for (i=1; (pSearch = m_lstClass.PEEK(i)); i++) // 0 is <Module>
+ {
+ if(pSearch->m_fNew)
+ {
+ if(m_fReportProgress)
+ printf("Class %d:\t%s\n",i,pSearch->m_szFQN);
+
+ if(pSearch->m_bIsMaster)
+ {
+ report->msg("Error: Reference to undefined class '%s'\n",pSearch->m_szFQN);
+ bIsUndefClass = TRUE;
+ }
+ if(!EmitClass(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ pSearch->m_fNew = FALSE;
+ }
+ }
+ if(bIsUndefClass && !OnErrGo) return E_FAIL;
+
+ if(m_fReportProgress) printf("\nEmitting fields and methods:\n");
+ for (i=0; (pSearch = m_lstClass.PEEK(i)) != NULL; i++)
+ {
+ if(pSearch->m_fNewMembers)
+ {
+ if(m_fReportProgress)
+ {
+ if(i == 0) printf("Global \t");
+ else printf("Class %d\t",i);
+ }
+ if(!EmitFieldsMethodsENC(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ }
+ }
+ }
+REPT_STEP
+
+ // All ref'ed items def'ed in this file are emitted, resolve member refs to member defs:
+ hr = ResolveLocalMemberRefs();
+ if(FAILED(hr) &&(!OnErrGo)) goto exit;
+
+ // Local member refs resolved, emit events, props and method impls
+ {
+ Class *pSearch;
+ int i;
+
+ if(m_fReportProgress) printf("\nEmitting events and properties:\n");
+ for (i=0; (pSearch = m_lstClass.PEEK(i)); i++)
+ {
+ if(pSearch->m_fNewMembers)
+ {
+ if(m_fReportProgress)
+ {
+ if(i == 0) printf("Global \t");
+ else printf("Class %d\t",i);
+ }
+ if(!EmitEventsPropsENC(pSearch))
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ pSearch->m_fNewMembers = FALSE;
+ }
+ }
+ }
+ if(m_MethodImplDList.COUNT())
+ {
+ if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT());
+ if(!EmitMethodImpls())
+ {
+ if(!OnErrGo) return E_FAIL;
+ }
+ }
+REPT_STEP
+ // Emit the rest of the metadata
+ hr = S_OK;
+ if(m_pManifest)
+ {
+ if (FAILED(hr = m_pManifest->EmitManifest())) goto exit;
+ }
+ ResolveLocalMemberRefs(); // in case CAs added some
+ EmitUnresolvedCustomAttributes();
+REPT_STEP
+
+ hr = DoLocalMemberRefFixups();
+ if(FAILED(hr) &&(!OnErrGo)) goto exit;
+
+ // Local member refs resolved and fixed up in BinStr method bodies. Emit the bodies to a separate file.
+ pEnd = &pwzOutputFilename[wcslen(pwzOutputFilename)];
+ {
+ Class* pClass;
+ Method* pMethod;
+ FILE* pF = NULL;
+ wcscat_s(pwzOutputFilename,MAX_SCOPE_LENGTH,W(".dil"));
+ if(_wfopen_s(&pF,pwzOutputFilename,W("wb"))==0)
+ {
+ int i,j,L=0,M=0;
+ BinStr bsOut;
+ for (i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(j=0; (pMethod = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if(pMethod->m_fNewBody)
+ {
+ L+= pMethod->m_pbsBody->length()+3;
+ M++;
+ }
+ }
+ }
+ bsOut.getBuff(L+sizeof(DWORD)); // to avoid reallocs
+ bsOut.remove(L);
+ for (i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(j=0; (pMethod = pClass->m_MethodList.PEEK(j)); j++)
+ {
+ if(pMethod->m_fNewBody)
+ {
+ if(!EmitMethodBody(pMethod,&bsOut))
+ {
+ report->msg("Error: failed to emit body of '%s'\n",pMethod->m_szName);
+ hr = E_FAIL;
+ if(!OnErrGo)
+ {
+ fclose(pF);
+ *pEnd = 0;
+ goto exit;
+ }
+ }
+ pMethod->m_fNewBody = FALSE;
+ }
+ }
+ }
+ *((DWORD*)(bsOut.ptr())) = bsOut.length() - sizeof(DWORD);
+ fwrite(bsOut.ptr(),bsOut.length(),1,pF);
+ fclose(pF);
+ }
+ else
+ report->msg("Error: failed to open file '%S'\n",pwzOutputFilename);
+
+ *pEnd = 0;
+ }
+REPT_STEP
+
+ //if (DoGlobalFixups() == FALSE)
+ // return E_FAIL;
+
+ //if (FAILED(hr=m_pCeeFileGen->SetOutputFileName(m_pCeeFile, pwzOutputFilename))) goto exit;
+
+ // Emit the meta-data to a separate file
+ IMetaDataEmit2* pENCEmitter;
+ if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataEmit2, (void**)&pENCEmitter)))
+ goto exit;
+
+ DWORD metaDataSize;
+ if (FAILED(hr=pENCEmitter->GetDeltaSaveSize(cssAccurate, &metaDataSize))) goto exit;
+
+ wcscat_s(pwzOutputFilename,MAX_SCOPE_LENGTH,W(".dmeta"));
+ pENCEmitter->SaveDelta(pwzOutputFilename,0); // second arg (dwFlags) is not used
+ *pEnd = 0;
+ pENCEmitter->Release();
+
+ // apply delta to create basis for the next ENC iteration
+ if(m_pbsMD)
+ {
+ IMetaDataEmit2* pBaseMDEmit = NULL;
+ if(FAILED(hr = m_pDisp->OpenScopeOnMemory(m_pbsMD->ptr(),
+ m_pbsMD->length(),
+ ofWrite,
+ IID_IMetaDataEmit2,
+ (IUnknown **)&pBaseMDEmit))) goto exit;
+
+ if(FAILED(hr = pBaseMDEmit->ApplyEditAndContinue((IUnknown*)m_pImporter))) goto exit;
+ delete m_pbsMD;
+ if((m_pbsMD = new BinStr()) != NULL)
+ {
+ DWORD cb;
+ hr = pBaseMDEmit->GetSaveSize(cssAccurate,&cb);
+ BYTE* pb = m_pbsMD->getBuff(cb);
+ hr = pBaseMDEmit->SaveToMemory(pb,cb);
+ }
+ pBaseMDEmit->Release();
+ }
+
+#if(0)
+//===================================================================================
+ // release SymWriter interfaces
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->Close();
+ m_pSymWriter->Release();
+ m_pSymWriter = NULL;
+ }
+
+ hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_ISymUnmanagedWriter,
+ (void **)&m_pSymWriter);
+ if(SUCCEEDED(hr))
+ {
+ WCHAR* pwc = &pwzOutputFilename[wcslen(pwzOutputFilename)];
+ wcscat(pwzOutputFilename,L".pdb");
+ if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
+ pwzOutputFilename,
+ NULL,
+ TRUE);
+ *pwc = 0;
+ }
+ else
+ {
+ fprintf(stderr, "Error: CoCreateInstance(IID_ISymUnmanagedWriter) returns %X\n",hr);
+ m_pSymWriter = NULL;
+ }
+
+ m_fENCMode = FALSE;
+ if(FAILED(hr=CreatePEFile(pwzOutputFilename)))
+ report->msg("Could not create output file, error code=0x%08X\n",hr);
+ m_fENCMode = TRUE;
+//=====================================================================================
+#endif
+
+ // release all interfaces
+ if (m_pSymWriter != NULL)
+ {
+ m_pSymWriter->Close();
+ m_pSymWriter->Release();
+ m_pSymWriter = NULL;
+ }
+ if (m_pImporter != NULL)
+ {
+ m_pImporter->Release();
+ m_pImporter = NULL;
+ }
+ if (m_pEmitter != NULL)
+ {
+ m_pEmitter->Release();
+ m_pEmitter = NULL;
+ }
+
+ return S_OK;
+
+REPT_STEP
+
+ // set managed resource entry, if any
+ if(m_pManifest && m_pManifest->m_dwMResSizeTotal)
+ {
+ mresourceSize = m_pManifest->m_dwMResSizeTotal;
+
+ if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, mresourceSize,
+ sizeof(DWORD), (void**) &mresourceData))) goto exit;
+ if (FAILED(hr=m_pCeeFileGen->SetManifestEntry(m_pCeeFile, mresourceSize, 0))) goto exit;
+ }
+REPT_STEP
+ /*
+ if (m_fWindowsCE)
+ {
+ if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, 2, 10))) goto exit;
+
+ if (FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, 0x10000))) goto exit;
+ }
+ else if(m_dwSubsystem != (DWORD)-1)
+ {
+ if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, m_dwSubsystem, 4, 0))) goto exit;
+ }
+
+ if (FAILED(hr=m_pCeeFileGen->ClearComImageFlags(m_pCeeFile, COMIMAGE_FLAGS_ILONLY))) goto exit;
+ if (FAILED(hr=m_pCeeFileGen->SetComImageFlags(m_pCeeFile, m_dwComImageFlags & ~COMIMAGE_FLAGS_STRONGNAMESIGNED))) goto exit;
+
+ if(m_dwFileAlignment)
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetFileAlignment(m_pCeeFile, m_dwFileAlignment))) goto exit;
+ }
+ if(m_stBaseAddress)
+ {
+ if(FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, m_stBaseAddress))) goto exit;
+ }
+ */
+REPT_STEP
+ //Compute all the RVAs
+ if (FAILED(hr=m_pCeeFileGen->LinkCeeFile(m_pCeeFile))) goto exit;
+
+REPT_STEP
+ // Fix up any fields that have RVA associated with them
+/*
+ if (m_fHaveFieldsWithRvas) {
+ hr = S_OK;
+ ULONG dataSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pGlobalDataSection, &dataSectionRVA))) goto exit;
+
+ ULONG tlsSectionRVA;
+ if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pTLSSection, &tlsSectionRVA))) goto exit;
+
+ FieldDescriptor* pListFD;
+ Class* pClass;
+ for(int i=0; (pClass = m_lstClass.PEEK(i)); i++)
+ {
+ for(int j=0; (pListFD = pClass->m_FieldDList.PEEK(j)); j++)
+ {
+ if (pListFD->m_rvaLabel != 0)
+ {
+ DWORD rva;
+ if(*(pListFD->m_rvaLabel)=='@')
+ {
+ rva = (DWORD)atoi(pListFD->m_rvaLabel + 1);
+ }
+ else
+ {
+ GlobalLabel *pLabel = FindGlobalLabel(pListFD->m_rvaLabel);
+ if (pLabel == 0)
+ {
+ report->msg("Error:Could not find label '%s' for the field '%s'\n", pListFD->m_rvaLabel, pListFD->m_szName);
+ hr = E_FAIL;
+ continue;
+ }
+
+ rva = pLabel->m_GlobalOffset;
+ if (pLabel->m_Section == m_pTLSSection)
+ rva += tlsSectionRVA;
+ else {
+ _ASSERTE(pLabel->m_Section == m_pGlobalDataSection);
+ rva += dataSectionRVA;
+ }
+ }
+ if (FAILED(m_pEmitter->SetFieldRVA(pListFD->m_fdFieldTok, rva))) goto exit;
+ }
+ }
+ }
+ if (FAILED(hr)) goto exit;
+ }
+REPT_STEP
+*/
+
+REPT_STEP
+ // actually output the resources
+ if(mresourceSize && mresourceData)
+ {
+ size_t i, N = m_pManifest->m_dwMResNum, sizeread, L;
+ BYTE *ptr = (BYTE*)mresourceData;
+ BOOL mrfail = FALSE;
+ FILE* pFile = NULL;
+ char sz[2048];
+ for(i=0; i < N; i++)
+ {
+ if(!m_pManifest->m_fMResNew[i]) continue;
+ m_pManifest->m_fMResNew[i] = FALSE;
+ memset(sz,0,2048);
+ WszWideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL);
+ L = m_pManifest->m_dwMResSize[i];
+ sizeread = 0;
+ memcpy(ptr,&L,sizeof(DWORD));
+ ptr += sizeof(DWORD);
+ pFile = NULL;
+ if(fopen_s(&pFile,sz,"rb")==0)
+ {
+ sizeread = fread((void *)ptr,1,L,pFile);
+ fclose(pFile);
+ ptr += sizeread;
+ }
+ else
+ {
+ report->msg("Error: failed to open mgd resource file '%ls'\n",m_pManifest->m_wzMResName[i]);
+ mrfail = TRUE;
+ }
+ if(sizeread < L)
+ {
+ report->msg("Error: failed to read expected %d bytes from mgd resource file '%ls'\n",L,m_pManifest->m_wzMResName[i]);
+ mrfail = TRUE;
+ L -= sizeread;
+ memset(ptr,0,L);
+ ptr += L;
+ }
+ }
+ if(mrfail)
+ {
+ hr = E_FAIL;
+ goto exit;
+ }
+ }
+REPT_STEP
+
+ // Generate the file -- moved to main
+ //if (FAILED(hr=m_pCeeFileGen->GenerateCeeFile(m_pCeeFile))) goto exit;
+
+
+ hr = S_OK;
+
+exit:
+ return hr;
+}