summaryrefslogtreecommitdiff
path: root/src/ildasm/windasm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ildasm/windasm.cpp')
-rw-r--r--src/ildasm/windasm.cpp730
1 files changed, 730 insertions, 0 deletions
diff --git a/src/ildasm/windasm.cpp b/src/ildasm/windasm.cpp
new file mode 100644
index 0000000000..d8a28812b7
--- /dev/null
+++ b/src/ildasm/windasm.cpp
@@ -0,0 +1,730 @@
+// 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.
+
+/************************************************************************************************
+ * *
+ * File: winmain.cpp *
+ * *
+ * Purpose: Main program for graphic COM+ 2.0 disassembler ILDASM.exe *
+ * *
+ ************************************************************************************************/
+#include "ildasmpch.h"
+
+#include "dynamicarray.h"
+
+#define DO_DASM_GUI
+#include "dasmgui.h"
+#include "dasmenum.hpp"
+#include "dis.h"
+#include <ndpversion.h>
+#include "resource.h"
+
+#include "new.hpp"
+
+#define MODE_DUMP_ALL 0
+#define MODE_DUMP_CLASS 1
+#define MODE_DUMP_CLASS_METHOD 2
+#define MODE_DUMP_CLASS_METHOD_SIG 3
+#define MODE_GUI 4
+
+// All externs are defined in DASM.CPP
+extern BOOL g_fDumpIL;
+extern BOOL g_fDumpHeader;
+extern BOOL g_fDumpAsmCode;
+extern BOOL g_fDumpTokens;
+extern BOOL g_fDumpStats;
+extern BOOL g_fDumpClassList;
+extern BOOL g_fDumpTypeList;
+extern BOOL g_fDumpSummary;
+extern BOOL g_fDecompile; // still in progress
+extern BOOL g_fShowRefs;
+
+extern BOOL g_fDumpToPerfWriter;
+
+extern BOOL g_fShowBytes;
+extern BOOL g_fShowSource;
+extern BOOL g_fInsertSourceLines;
+extern BOOL g_fTryInCode;
+extern BOOL g_fQuoteAllNames;
+extern BOOL g_fShowProgressBar;
+extern BOOL g_fTDC;
+extern BOOL g_fShowCA;
+extern BOOL g_fCAVerbal;
+
+extern char g_pszClassToDump[];
+extern char g_pszMethodToDump[];
+extern char g_pszSigToDump[];
+
+extern char g_szAsmCodeIndent[];
+
+extern DWORD g_Mode;
+
+extern char* g_pszExeFile;
+extern char g_szInputFile[]; // in UTF-8
+extern WCHAR g_wszFullInputFile[]; // in UTF-16
+extern char g_szOutputFile[]; // in UTF-8
+extern char* g_pszObjFileName;
+extern FILE* g_pFile;
+
+extern BOOL g_fLimitedVisibility;
+#if defined(_DEBUG) && defined(FEATURE_PREJIT)
+extern BOOL g_fNGenNativeMetadata;
+#endif
+extern BOOL g_fHidePub;
+extern BOOL g_fHidePriv;
+extern BOOL g_fHideFam;
+extern BOOL g_fHideAsm;
+extern BOOL g_fHideFAA;
+extern BOOL g_fHideFOA;
+extern BOOL g_fHidePrivScope;
+extern BOOL g_fProject;
+
+extern unsigned g_uCodePage;
+extern unsigned g_uConsoleCP;
+extern BOOL g_fForwardDecl;
+extern BOOL g_fUseProperName;
+
+#include "../tools/metainfo/mdinfo.h"
+extern BOOL g_fDumpMetaInfo;
+extern ULONG g_ulMetaInfoFilter;
+HINSTANCE g_hInstance;
+HINSTANCE g_hResources;
+HANDLE hConsoleOut=NULL;
+HANDLE hConsoleErr=NULL;
+// These are implemented in DASM.CPP:
+BOOL Init();
+void Uninit();
+void Cleanup();
+void DumpMetaInfo(__in __nullterminated const WCHAR* pszFileName, __in __nullterminated const char* pszObjFileName, void* GUICookie);
+FILE* OpenOutput(__in __nullterminated const char* szFileName);
+
+// Do we only view an IL-dasm window in GUI mode?
+// TRUE when we're in GUI mode and we specified a particular method from the cmd line
+BOOL IsGuiILOnly()
+{
+ return (g_Mode & MODE_GUI) && (g_pszMethodToDump[0] != 0);
+}
+
+void PrintLogo()
+{
+ printf("Microsoft (R) .NET Framework IL Disassembler. Version " VER_FILEVERSION_STR);
+ printf("\n%S\n\n", VER_LEGALCOPYRIGHT_LOGO_STR_L);
+}
+
+void SyntaxCon()
+{
+ DWORD l;
+
+ for(l=IDS_USAGE_01; l<= IDS_USAGE_23; l++) printf(RstrANSI(l));
+ if(g_fTDC)
+ {
+ for(l=IDS_USAGE_24; l<= IDS_USAGE_32; l++) printf(RstrANSI(l));
+ for(l=IDS_USAGE_34; l<= IDS_USAGE_36; l++) printf(RstrANSI(l));
+ for(l=IDS_USAGE_37; l<= IDS_USAGE_39; l++) printf(RstrANSI(l));
+ }
+ else printf(RstrANSI(IDS_USAGE_40));
+ for(l=IDS_USAGE_41; l<= IDS_USAGE_42; l++) printf(RstrANSI(l));
+
+}
+
+char* CheckForDQuotes(__inout __nullterminated char* sz)
+{
+ char* ret = sz;
+ if(*sz == '"')
+ {
+ ret++;
+ sz[strlen(sz)-1] = 0;
+ }
+ return ret;
+}
+
+char* EqualOrColon(__in __nullterminated char* szArg)
+{
+ char* pchE = strchr(szArg,'=');
+ char* pchC = strchr(szArg,':');
+ char* ret;
+ if(pchE == NULL) ret = pchC;
+ else if(pchC == NULL) ret = pchE;
+ else ret = (pchE < pchC)? pchE : pchC;
+ return ret;
+}
+
+void GetInputFileFullPath()
+{
+ // We need the input file's full path to make uses of it later, despite changing CurrentDirectory
+
+ // First, convert back up to UTF16
+ DWORD len = (DWORD) strlen(g_szInputFile) + 16;
+ WCHAR* wzArg = new WCHAR[len];
+ memset(wzArg, 0, len * sizeof(WCHAR));
+ WszMultiByteToWideChar(g_uConsoleCP, 0, g_szInputFile, -1, wzArg, len);
+
+ // Get the full path
+ len = WszGetFullPathName(wzArg, MAX_PATH, g_wszFullInputFile, NULL);
+ VDELETE(wzArg);
+}
+
+int ProcessOneArg(__in __nullterminated char* szArg, __out char** ppszObjFileName)
+{
+ char szOpt[128];
+ if(strlen(szArg) == 0) return 0;
+ if ((strcmp(szArg, "/?") == 0) || (strcmp(szArg, "-?") == 0)) return 1;
+
+#ifdef FEATURE_PAL
+ if(szArg[0] == '-')
+#else
+ if((szArg[0] == '/') || (szArg[0] == '-'))
+#endif
+ {
+ strncpy_s(szOpt,128, &szArg[1],10);
+ szOpt[3] = 0;
+ if (_stricmp(szOpt, "dec") == 0)
+ {
+ g_fDecompile = TRUE;
+ }
+ else if (_stricmp(szOpt, "hea") == 0)
+ {
+ g_fDumpHeader = TRUE;
+ }
+ else if (_stricmp(szOpt, "adv") == 0)
+ {
+ g_fTDC = TRUE;
+ }
+ else if (_stricmp(szOpt, "tok") == 0)
+ {
+ g_fDumpTokens = TRUE;
+ }
+ else if (_stricmp(szOpt, "noi") == 0)
+ {
+ g_fDumpAsmCode = FALSE;
+ }
+ else if (_stricmp(szOpt, "noc") == 0)
+ {
+ g_fShowCA = FALSE;
+ }
+ else if (_stricmp(szOpt, "cav") == 0)
+ {
+ g_fCAVerbal = TRUE;
+ }
+ else if (_stricmp(szOpt, "not") == 0)
+ {
+ g_fTryInCode = FALSE;
+ }
+ else if (_stricmp(szOpt, "raw") == 0)
+ {
+ g_fTryInCode = FALSE;
+ }
+ else if (_stricmp(szOpt, "byt") == 0)
+ {
+ g_fShowBytes = TRUE;
+ }
+ else if (_stricmp(szOpt, "sou") == 0)
+ {
+#ifdef FEATURE_CORECLR
+ printf("Warning: 'SOURCE' option is ignored for ildasm on CoreCLR.\n");
+#else
+ g_fShowSource = TRUE;
+#endif
+ }
+ else if (_stricmp(szOpt, "lin") == 0)
+ {
+ g_fInsertSourceLines = TRUE;
+ }
+ else if ((_stricmp(szOpt, "sta") == 0)&&g_fTDC)
+ {
+ g_fDumpStats = g_fTDC;
+ }
+ else if ((_stricmp(szOpt, "cla") == 0)&&g_fTDC)
+ {
+ g_fDumpClassList = g_fTDC;
+ }
+ else if (_stricmp(szOpt, "typ") == 0)
+ {
+ g_fDumpTypeList = TRUE;
+ }
+ else if (_stricmp(szOpt, "sum") == 0)
+ {
+ g_fDumpSummary = TRUE;
+ }
+ else if (_stricmp(szOpt, "per") == 0)
+ {
+ g_fDumpToPerfWriter = TRUE;
+ }
+ else if (_stricmp(szOpt, "for") == 0)
+ {
+ g_fForwardDecl = TRUE;
+ }
+ else if (_stricmp(szOpt, "ref") == 0)
+ {
+ g_fShowRefs = TRUE;
+ }
+ else if (_stricmp(szOpt, "pub") == 0)
+ {
+ g_fLimitedVisibility = TRUE;
+ g_fHidePub = FALSE;
+ }
+#if defined(_DEBUG) && defined(FEATURE_PREJIT)
+ else if (_stricmp(szOpt, "nat") == 0)
+ {
+ g_fNGenNativeMetadata = TRUE;
+ }
+#endif
+ else if (_stricmp(szOpt, "pre") == 0)
+ {
+ //g_fPrettyPrint = TRUE;
+ }
+ else if (_stricmp(szOpt, "pro") == 0)
+ {
+ g_fProject = TRUE;
+ }
+ else if (_stricmp(szOpt, "vis") == 0)
+ {
+ char *pc = EqualOrColon(szArg);
+ char *pStr;
+ if(pc == NULL) return -1;
+ do {
+ pStr = pc+1;
+ pStr = CheckForDQuotes(pStr);
+ if((pc = strchr(pStr,'+'))) *pc=0;
+ if (!_stricmp(pStr,"pub")) g_fHidePub = FALSE;
+ else if(!_stricmp(pStr,"pri")) g_fHidePriv = FALSE;
+ else if(!_stricmp(pStr,"fam")) g_fHideFam = FALSE;
+ else if(!_stricmp(pStr,"asm")) g_fHideAsm = FALSE;
+ else if(!_stricmp(pStr,"faa")) g_fHideFAA = FALSE;
+ else if(!_stricmp(pStr,"foa")) g_fHideFOA = FALSE;
+ else if(!_stricmp(pStr,"psc")) g_fHidePrivScope = FALSE;
+ } while(pc);
+ g_fLimitedVisibility = g_fHidePub ||
+ g_fHidePriv ||
+ g_fHideFam ||
+ g_fHideAsm ||
+ g_fHideFAA ||
+ g_fHideFOA ||
+ g_fHidePrivScope;
+ }
+ else if (_stricmp(szOpt, "nob") == 0)
+ {
+ g_fShowProgressBar = FALSE;
+ }
+ else if (_stricmp(szOpt, "quo") == 0)
+ {
+ g_fQuoteAllNames = TRUE;
+ }
+ else if (_stricmp(szOpt, "utf") == 0)
+ {
+ g_uCodePage = CP_UTF8;
+ }
+ else if (_stricmp(szOpt, "uni") == 0)
+ {
+ g_uCodePage = 0xFFFFFFFF;
+ }
+ else if (_stricmp(szOpt, "rtf") == 0)
+ {
+ g_fDumpRTF = TRUE;
+ g_fDumpHTML = FALSE;
+ }
+ else if (_stricmp(szOpt, "htm") == 0)
+ {
+ g_fDumpRTF = FALSE;
+ g_fDumpHTML = TRUE;
+ }
+ else if (_stricmp(szOpt, "all") == 0)
+ {
+ g_fDumpStats = g_fTDC;
+ g_fDumpHeader = TRUE;
+ g_fShowBytes = TRUE;
+ g_fDumpClassList = g_fTDC;
+ g_fDumpTokens = TRUE;
+ }
+ else if (_stricmp(szOpt, "ite") == 0)
+ {
+ char *pStr = EqualOrColon(szArg);
+ char *p, *q;
+ if(pStr == NULL) return -1;
+ pStr++;
+ pStr = CheckForDQuotes(pStr);
+ // treat it as meaning "dump only class X" or "class X method Y"
+ p = strchr(pStr, ':');
+
+ if (p == NULL)
+ {
+ // dump one class
+ g_Mode = MODE_DUMP_CLASS;
+ strcpy_s(g_pszClassToDump, MAX_CLASSNAME_LENGTH, pStr);
+ }
+ else
+ {
+ *p++ = '\0';
+ if (*p != ':') return -1;
+
+ strcpy_s(g_pszClassToDump, MAX_CLASSNAME_LENGTH, pStr);
+
+ p++;
+
+ q = strchr(p, '(');
+ if (q == NULL)
+ {
+ // dump class::method
+ g_Mode = MODE_DUMP_CLASS_METHOD;
+ strcpy_s(g_pszMethodToDump, MAX_MEMBER_LENGTH, p);
+ }
+ else
+ {
+ // dump class::method(sig)
+ g_Mode = MODE_DUMP_CLASS_METHOD_SIG;
+ *q = '\0';
+ strcpy_s(g_pszMethodToDump, MAX_MEMBER_LENGTH, p);
+ // get rid of external parentheses:
+ q++;
+ strcpy_s(g_pszSigToDump, MAX_SIGNATURE_LENGTH, q);
+ }
+ }
+ }
+ else if ((_stricmp(szOpt, "met") == 0)&&g_fTDC)
+ {
+ if(g_fTDC)
+ {
+ char *pStr = EqualOrColon(szArg);
+ g_fDumpMetaInfo = TRUE;
+ if(pStr)
+ {
+ char szOptn[64];
+ strncpy_s(szOptn, 64, pStr+1,10);
+ szOptn[3] = 0; // recognize metainfo specifier by first 3 chars
+ if (_stricmp(szOptn, "hex") == 0) g_ulMetaInfoFilter |= MDInfo::dumpMoreHex;
+ else if(_stricmp(szOptn, "csv") == 0) g_ulMetaInfoFilter |= MDInfo::dumpCSV;
+ else if(_stricmp(szOptn, "mdh") == 0) g_ulMetaInfoFilter |= MDInfo::dumpHeader;
+ else if(_stricmp(szOptn, "raw") == 0) g_ulMetaInfoFilter |= MDInfo::dumpRaw;
+ else if(_stricmp(szOptn, "hea") == 0) g_ulMetaInfoFilter |= MDInfo::dumpRawHeaps;
+ else if(_stricmp(szOptn, "sch") == 0) g_ulMetaInfoFilter |= MDInfo::dumpSchema;
+ else if(_stricmp(szOptn, "unr") == 0) g_ulMetaInfoFilter |= MDInfo::dumpUnsat;
+ else if(_stricmp(szOptn, "val") == 0) g_ulMetaInfoFilter |= MDInfo::dumpValidate;
+ else if(_stricmp(szOptn, "sta") == 0) g_ulMetaInfoFilter |= MDInfo::dumpStats;
+ else return -1;
+ }
+ }
+ }
+ else if (_stricmp(szOpt, "obj") == 0)
+ {
+ char *pStr = EqualOrColon(szArg);
+ if(pStr == NULL) return -1;
+ pStr++;
+ pStr = CheckForDQuotes(pStr);
+ *ppszObjFileName = new char[strlen(pStr)+1];
+ strcpy_s(*ppszObjFileName,strlen(pStr)+1,pStr);
+ }
+ else if (_stricmp(szOpt, "out") == 0)
+ {
+ char *pStr = EqualOrColon(szArg);
+ if(pStr == NULL) return -1;
+ pStr++;
+ pStr = CheckForDQuotes(pStr);
+ if(*pStr == 0) return -1;
+ if(_stricmp(pStr,"con"))
+ {
+ strncpy_s(g_szOutputFile, MAX_FILENAME_LENGTH, pStr,MAX_FILENAME_LENGTH-1);
+ g_szOutputFile[MAX_FILENAME_LENGTH-1] = 0;
+ }
+ else
+ g_fShowProgressBar = FALSE;
+
+ g_Mode &= ~MODE_GUI;
+ }
+ else if (_stricmp(szOpt, "tex") == 0)
+ {
+ g_Mode &= ~MODE_GUI;
+ g_fShowProgressBar = FALSE;
+ }
+ else
+ {
+ PrintLogo();
+ printf(RstrANSI(IDS_E_INVALIDOPTION),szArg); //"INVALID COMMAND LINE OPTION: %s\n\n",szArg);
+ return -1;
+ }
+ }
+ else
+ {
+ if(g_szInputFile[0])
+ {
+ PrintLogo();
+ printf(RstrANSI(IDS_E_MULTIPLEINPUT)); //"MULTIPLE INPUT FILES SPECIFIED\n\n");
+ return -1; // check if it was already specified
+ }
+ szArg = CheckForDQuotes(szArg);
+ strncpy_s(g_szInputFile, MAX_FILENAME_LENGTH,szArg,MAX_FILENAME_LENGTH-1);
+ g_szInputFile[MAX_FILENAME_LENGTH-1] = 0;
+ GetInputFileFullPath();
+ }
+ return 0;
+}
+
+char* UTF8toANSI(__in __nullterminated char* szUTF)
+{
+ ULONG32 L = (ULONG32) strlen(szUTF)+16;
+ WCHAR* wzUnicode = new WCHAR[L];
+ memset(wzUnicode,0,L*sizeof(WCHAR));
+ WszMultiByteToWideChar(CP_UTF8,0,szUTF,-1,wzUnicode,L);
+ L <<= 2;
+ char* szANSI = new char[L];
+ memset(szANSI,0,L);
+ WszWideCharToMultiByte(g_uConsoleCP,0,wzUnicode,-1,szANSI,L,NULL,NULL);
+ VDELETE(wzUnicode);
+ return szANSI;
+}
+char* ANSItoUTF8(__in __nullterminated char* szANSI)
+{
+ ULONG32 L = (ULONG32) strlen(szANSI)+16;
+ WCHAR* wzUnicode = new WCHAR[L];
+ memset(wzUnicode,0,L*sizeof(WCHAR));
+ WszMultiByteToWideChar(g_uConsoleCP,0,szANSI,-1,wzUnicode,L);
+ L *= 3;
+ char* szUTF = new char[L];
+ memset(szUTF,0,L);
+ WszWideCharToMultiByte(CP_UTF8,0,wzUnicode,-1,szUTF,L,NULL,NULL);
+ VDELETE(wzUnicode);
+ return szUTF;
+}
+
+int ParseCmdLineW(__in __nullterminated WCHAR* wzCmdLine, __out char** ppszObjFileName)
+{
+ int argc,ret=0;
+ LPWSTR* argv= SegmentCommandLine(wzCmdLine, (DWORD*)&argc);
+ char* szArg = new char[2048];
+ for(int i=1; i < argc; i++)
+ {
+ memset(szArg,0,2048);
+ WszWideCharToMultiByte(CP_UTF8,0,argv[i],-1,szArg,2048,NULL,NULL);
+ if((ret = ProcessOneArg(szArg,ppszObjFileName)) != 0) break;
+ }
+ VDELETE(szArg);
+ return ret;
+}
+
+int ParseCmdLineA(__in __nullterminated char* szCmdLine, __out char** ppszObjFileName)
+{
+ if((szCmdLine == NULL)||(*szCmdLine == 0)) return 0;
+
+ // ANSI to UTF-8
+ char* szCmdLineUTF = ANSItoUTF8(szCmdLine);
+
+ // Split into argv[]
+ int argc=0, ret = 0;
+ DynamicArray<char*> argv;
+ char* pch;
+ char* pchend;
+ bool bUnquoted = true;
+
+ pch = szCmdLineUTF;
+ pchend = pch+strlen(szCmdLineUTF);
+ while(pch)
+ {
+ for(; *pch == ' '; pch++); // skip the blanks
+ argv[argc++] = pch;
+ for(; pch < pchend; pch++)
+ {
+ if(*pch == '"') bUnquoted = !bUnquoted;
+ else if((*pch == ' ')&&bUnquoted) break;
+ }
+
+ if(pch < pchend) *pch++ = 0;
+ else break;
+ }
+
+ for(int i=1; i < argc; i++)
+ {
+ if((ret = ProcessOneArg(argv[i],ppszObjFileName)) != 0) break;
+ }
+ VDELETE(szCmdLineUTF);
+ return ret;
+}
+
+#ifdef FEATURE_CORECLR
+int __cdecl main(int nCmdShow, char* lpCmdLine[])
+#else
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ __in LPSTR lpCmdLine,
+ int nCmdShow)
+#endif
+{
+#if defined(FEATURE_CORECLR) && defined(FEATURE_PAL)
+ if (0 != PAL_Initialize(nCmdShow, lpCmdLine))
+ {
+ printError(g_pFile, "Error: Fail to PAL_Initialize\n");
+ exit(1);
+ }
+ g_pszExeFile = lpCmdLine[0];
+#endif
+
+ // ildasm does not need to be SO-robust.
+ SO_NOT_MAINLINE_FUNCTION;
+
+ // SWI has requested that the exact form of the function call below be used. For details see http://swi/SWI%20Docs/Detecting%20Heap%20Corruption.doc
+ (void)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
+
+#ifdef _DEBUG
+ DisableThrowCheck();
+#endif
+
+ int iCommandLineParsed = 0;
+ WCHAR* wzCommandLine = NULL;
+ char* szCommandLine = NULL;
+
+ g_fUseProperName = TRUE;
+
+#ifndef FEATURE_CORECLR
+ g_hInstance = hInstance;
+ g_Mode = MODE_GUI;
+#endif
+ g_pszClassToDump[0]=0;
+ g_pszMethodToDump[0]=0;
+ g_pszSigToDump[0]=0;
+ memset(g_szInputFile,0,MAX_FILENAME_LENGTH);
+ memset(g_szOutputFile,0,MAX_FILENAME_LENGTH);
+#if defined(_DEBUG)
+ g_fTDC = TRUE;
+#endif
+
+#undef GetCommandLineW
+#undef CreateProcessW
+ g_pszObjFileName = NULL;
+
+ g_szAsmCodeIndent[0] = 0;
+ hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ hConsoleErr = GetStdHandle(STD_ERROR_HANDLE);
+
+#ifndef FEATURE_PAL
+ // Dev11 #5320 - pull the localized resource loader up so if ParseCmdLineW need resources, they're already loaded
+ g_hResources = LoadLocalizedResourceDLLForSDK(L"ildasmrc.dll");
+#endif
+
+ iCommandLineParsed = ParseCmdLineW((wzCommandLine = GetCommandLineW()),&g_pszObjFileName);
+
+ if(!g_fLimitedVisibility)
+ {
+ g_fHidePub = FALSE;
+ g_fHidePriv = FALSE;
+ g_fHideFam = FALSE;
+ g_fHideAsm = FALSE;
+ g_fHideFAA = FALSE;
+ g_fHideFOA = FALSE;
+ g_fHidePrivScope = FALSE;
+ }
+ if(hConsoleOut != INVALID_HANDLE_VALUE) //First pass: console
+ {
+ g_uConsoleCP = GetConsoleOutputCP();
+
+ if(iCommandLineParsed)
+ {
+ if(iCommandLineParsed > 0) PrintLogo();
+ SyntaxCon();
+ exit((iCommandLineParsed == 1) ? 0 : 1);
+ }
+ if(!(g_Mode & MODE_GUI))
+ {
+ DWORD exitCode = 1;
+ if(g_szInputFile[0] == 0)
+ {
+ SyntaxCon();
+ exit(1);
+ }
+ g_pFile = NULL;
+ if(g_szOutputFile[0])
+ {
+ g_pFile = OpenOutput(g_szOutputFile);
+ if(g_pFile == NULL)
+ {
+ char sz[4096];
+ sprintf_s(sz,4096,RstrUTF(IDS_E_CANTOPENOUT)/*"Unable to open '%s' for output."*/, g_szOutputFile);
+ g_uCodePage = CP_ACP;
+ printError(NULL,sz);
+ exit(1);
+ }
+ }
+ else // console output -- force the code page to ANSI
+ {
+ g_uCodePage = g_uConsoleCP;
+ g_fDumpRTF = FALSE;
+ g_fDumpHTML = FALSE;
+ }
+ if (Init() == TRUE)
+ {
+ exitCode = DumpFile() ? 0 : 1;
+ Cleanup();
+ }
+ Uninit();
+ exit(exitCode);
+ }
+ else // if GUI ordered, restart as WinApp
+ {
+#ifdef FEATURE_CORECLR
+ _ASSERTE(!"GUI is not supported for ildasm on CoreCLR.");
+#else
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ memset(&pi, 0, sizeof(PROCESS_INFORMATION) );
+ memset(&si, 0, sizeof(STARTUPINFO) );
+ si.cb = sizeof(STARTUPINFO);
+ si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
+ si.wShowWindow = SW_SHOW;
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ si.hStdInput = INVALID_HANDLE_VALUE;
+ si.hStdError = INVALID_HANDLE_VALUE;
+ // Create the child process.
+ if(CreateProcessW(NULL,
+ wzCommandLine, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ DETACHED_PROCESS, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ (LPSTARTUPINFOW)&si, // STARTUPINFO pointer
+ &pi)==0) // receives PROCESS_INFORMATION
+ {
+ printf(RstrANSI(IDS_E_CANTCREATEPROC));//"Failed to CreateProcess\n\n");
+ exit(1);
+ }
+ exit(0);
+#endif
+ }
+ }
+#ifndef FEATURE_CORECLR
+ else //Second pass: WinApp
+ {
+ g_uCodePage = CP_UTF8;
+ g_Mode = MODE_GUI;
+ g_fDumpHTML = FALSE;
+
+ if(g_szInputFile[0])
+ {
+ char* pch = strrchr(g_szInputFile,'.');
+ if(pch && (!_strcmpi(pch+1,"lib") || !_strcmpi(pch+1,"obj")))
+ {
+ WszMessageBox(NULL,
+ RstrW(IDS_ONLYPEINGUI),//"ILDASM supports only PE files in graphic mode",
+ RstrW(IDS_BADFILETYPE),//"Invalid File Type",
+ MB_OK|MB_ICONERROR|GetDasmMBRTLStyle());
+ return 0;
+ }
+ }
+ if (Init() == TRUE)
+ {
+ CreateGUI();
+ if(g_szInputFile[0])
+ {
+ GUISetModule(g_szInputFile);
+ DumpFile();
+ }
+ GUIMainLoop();
+ Cleanup();
+ DestroyGUI();
+ }
+ Uninit();
+ return 0 ;
+ }
+#endif
+ return 0;
+}
+