123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- #include "BeefySysLib/Common.h"
- #include <stdio.h>
- #include <iostream>
- #include <vector>
- #pragma warning(disable:4996)
- USING_NS_BF;
- #define BF_IMPORT extern "C" __declspec(dllimport)
- class BlContext;
- bool gFailed = false;
- BF_IMPORT BlContext* BF_CALLTYPE BlContext_Create();
- BF_IMPORT void BF_CALLTYPE BlContext_Delete(BlContext* blContext);
- BF_IMPORT void BF_CALLTYPE BlContext_Init(BlContext* blContext, bool is64Bit, bool isDebug);
- BF_IMPORT void BF_CALLTYPE BlContext_AddSearchPath(BlContext* blContext, const char* directory);
- BF_IMPORT void BF_CALLTYPE BlContext_AddFile(BlContext* blContext, const char* fileName);
- BF_IMPORT bool BF_CALLTYPE BlContext_Link(BlContext* blContext);
- BF_IMPORT bool BF_CALLTYPE BlContext_SetOutName(BlContext* blContext, const char* outName);
- BF_IMPORT bool BF_CALLTYPE BlContext_SetEntryPoint(BlContext* blContext, const char* outName);
- BF_IMPORT bool BF_CALLTYPE BlContext_SetImpLib(BlContext* blContext, const char* impLibName);
- BF_IMPORT void BF_CALLTYPE BlContext_SetDebug(BlContext* blContext, int debugMode);
- BF_IMPORT void BF_CALLTYPE BlContext_SetPDBName(BlContext* blContext, const char* pdbPath);
- BF_IMPORT void BF_CALLTYPE BlContext_SetIsDLL(BlContext* blContext);
- BF_IMPORT void BF_CALLTYPE BlContext_SetVerbose(BlContext* blContext, bool enabled);
- BF_IMPORT void BF_CALLTYPE BlContext_SetNoDefaultLib(BlContext* blContext, bool enabled);
- BF_IMPORT void BF_CALLTYPE BlContext_AddNoDefaultLib(BlContext* blContext, const char* name);
- BF_IMPORT void BF_CALLTYPE BlContext_AddDefaultLib(BlContext* blContext, const char* name);
- BF_IMPORT void BF_CALLTYPE BlContext_SetImageBase(BlContext* blContext, int64 imageBase);
- BF_IMPORT void BF_CALLTYPE BlContext_SetFixedBase(BlContext* blContext, bool enabled);
- BF_IMPORT void BF_CALLTYPE BlContext_SetDynamicBase(BlContext* blContext, bool enabled);
- BF_IMPORT void BF_CALLTYPE BlContext_SetHighEntropyVA(BlContext* blContext, bool enabled);
- BF_IMPORT void BF_CALLTYPE BlContext_ManifestUAC(BlContext* blContext, const char* manifestUAC);
- BF_IMPORT void BF_CALLTYPE BlContext_SetSubsystem(BlContext* blContext, int subsystem);
- BF_IMPORT void BF_CALLTYPE BlContext_SetStack(BlContext* blContext, int reserve, int commit);
- BF_IMPORT void BF_CALLTYPE BlContext_SetHeap(BlContext* blContext, int reserve, int commit);
- void Fail(const std::string& name)
- {
- gFailed = true;
- std::cerr << "ERROR: " << name.c_str() << std::endl;
- }
- static bool CheckBoolean(const std::string& arg)
- {
- if (stricmp(arg.c_str(), "YES") == 0)
- return true;
- if (stricmp(arg.c_str(), "NO") == 0)
- return false;
- Fail(StrFormat("Invalid boolean argument: %s", arg.c_str()));
- return false;
- }
- BlContext* blContext;
- std::vector<std::string> fileNames;
- std::string defFileName;
- std::string outPath;
- bool HandleParam(const std::string& arg, bool isFirstArg = false)
- {
- if ((arg[0] == '-') || (arg[0] == '/'))
- {
- int colonPos = (int)arg.find(':');
- if (colonPos != -1)
- {
- std::string argName = ToUpper(arg.substr(1, colonPos - 1));
- std::string argParam = arg.substr(colonPos + 1);
- if (argName == "OUT")
- {
- outPath = argParam;
- BlContext_SetOutName(blContext, outPath.c_str());
- }
- else if (argName == "ERRORREPORT")
- {
- }
- else if (argName == "MANIFEST")
- {
- }
- else if (argName == "MANIFESTUAC")
- {
- BlContext_ManifestUAC(blContext, argParam.c_str());
- }
- else if (argName == "UIACCESS")
- {
- }
- else if (argName == "DEBUG")
- {
- if (ToUpper(argParam) == "NONE")
- BlContext_SetDebug(blContext, 0);
- else
- BlContext_SetDebug(blContext, 1);
- }
- else if (argName == "DEBUGTYPE")
- {
- }
- else if (argName == "PDB")
- {
- BlContext_SetPDBName(blContext, argParam.c_str());
- }
- else if (argName == "ENTRY")
- {
- BlContext_SetEntryPoint(blContext, argParam.c_str());
- }
- else if (argName == "SUBSYSTEM")
- {
- std::string subsysName = ToUpper(argParam);
- if (subsysName == "WINDOWS")
- BlContext_SetSubsystem(blContext, IMAGE_SUBSYSTEM_WINDOWS_GUI);
- else if (subsysName == "CONSOLE")
- BlContext_SetSubsystem(blContext, IMAGE_SUBSYSTEM_WINDOWS_CUI);
- else
- Fail("Specified subsystem not supported");
- }
- else if (argName == "TLBID")
- {
- }
- else if (argName == "IMPLIB")
- {
- BlContext_SetImpLib(blContext, argParam.c_str());
- }
- else if (argName == "MACHINE")
- {
- if (argParam != "X64")
- {
- Fail("Only X64 is currently supported");
- }
- }
- else if (argName == "HEAP")
- {
- int commaPos = (int)argParam.find(',');
- if (commaPos > 0)
- BlContext_SetHeap(blContext, strtol(argParam.c_str(), NULL, 0), strtol(argParam.c_str() + commaPos + 1, NULL, 0));
- else
- BlContext_SetHeap(blContext, strtol(argParam.c_str(), NULL, 0), 0);
- }
- else if (argName == "STACK")
- {
- int commaPos = (int)argParam.find(',');
- if (commaPos > 0)
- BlContext_SetStack(blContext, strtol(argParam.c_str(), NULL, 0), strtol(argParam.c_str() + commaPos + 1, NULL, 0));
- else
- BlContext_SetStack(blContext, strtol(argParam.c_str(), NULL, 0), 0);
- }
- else if (argName == "LIBPATH")
- {
- BlContext_AddSearchPath(blContext, argParam.c_str());
- }
- else if (argName == "VERBOSE")
- {
- BlContext_SetVerbose(blContext, CheckBoolean(argParam));
- }
- else if (argName == "NODEFAULTLIB")
- {
- BlContext_AddNoDefaultLib(blContext, argParam.c_str());
- }
- else if (argName == "BASE")
- {
- int64 imageBase = 0;
- imageBase = strtoll(argParam.c_str(), NULL, 0);
- if (imageBase != 0)
- BlContext_SetImageBase(blContext, imageBase);
- }
- else if (argName == "FIXED")
- {
- BlContext_SetFixedBase(blContext, CheckBoolean(argParam));
- }
- else if (argName == "DYNAMICBASE")
- {
- BlContext_SetDynamicBase(blContext, CheckBoolean(argParam));
- }
- else if (argName == "HIGHENTROPYVA")
- {
- BlContext_SetHighEntropyVA(blContext, CheckBoolean(argParam));
- }
- else if (argName == "DEF")
- {
- defFileName = argParam;
- }
- else if (argName == "INCREMENTAL")
- {
- }
- else if (argName == "DEFAULTLIB")
- {
- BlContext_AddDefaultLib(blContext, argParam.c_str());
- }
- else
- {
- Fail(StrFormat("Invalid argument: %s", arg.c_str()));
- return 1;
- }
- }
- else
- {
- std::string argName = ToUpper(arg.substr(1));
- if (argName == "NODEFAULTLIB")
- {
- BlContext_SetNoDefaultLib(blContext, true);
- }
- if (argName == "VERBOSE")
- {
- BlContext_SetVerbose(blContext, true);
- }
- else if (argName == "NOLOGO")
- {
- }
- else if (argName == "MANIFEST")
- {
- }
- else if (argName == "DEBUG")
- {
- BlContext_SetDebug(blContext, 1);
- }
- else if (argName == "NXCOMPAT")
- {
- }
- else if (argName == "DLL")
- {
- BlContext_SetIsDLL(blContext);
- }
- else if (argName == "FIXED")
- {
- BlContext_SetFixedBase(blContext, true);
- }
- else if (argName == "DYNAMICBASE")
- {
- BlContext_SetDynamicBase(blContext, true);
- }
- else if (argName == "INCREMENTAL")
- {
- }
- else
- {
- Fail(StrFormat("Invalid argument: %s", arg.c_str()));
- return false;
- }
- }
- }
- else if (arg[0] == '@')
- {
- char* cmdData = LoadTextData(arg.substr(1), NULL);
- if (cmdData == NULL)
- {
- Fail(StrFormat("Failed to load command file: \"%s\"", arg.substr(1).c_str()));
- return false;
- }
- std::string curArg;
- bool inQuote = false;
- bool prevSlash = false;
- for (char* cPtr = cmdData; true; cPtr++)
- {
- char c = *cPtr;
- if (c == 0)
- {
- if (!curArg.empty())
- HandleParam(curArg);
- break;
- }
- if (c == '"')
- {
- inQuote = !inQuote;
- }
- else if ((isspace(c)) && (!inQuote))
- {
- if (!curArg.empty())
- {
- HandleParam(curArg);
- curArg.clear();
- }
- }
- else
- curArg += c;
- }
- delete cmdData;
- }
- else if (!isFirstArg)
- {
- fileNames.push_back(arg.c_str());
- }
- return true;
- }
- int main(int argc, char* argv[])
- {
- int startTick = GetTickCount();
- blContext = BlContext_Create();
- // C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\proj\TestCPP\x64\Debug\TestCPP.exe" /INCREMENTAL /NOLOGO /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\proj\TestCPP\x64\Debug\TestCPP.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\proj\TestCPP\x64\Debug\TestCPP.lib" /MACHINE:X64 kernel32.lib user32.lib advapi32.lib shell32.lib x64\Debug\main.obj
- bool success = true;
- for (int argIdx = 0; argIdx < argc; argIdx++)
- {
- if (!HandleParam(argv[argIdx], argIdx == 0))
- break;
- }
- if (gFailed)
- success = false;
- if (success)
- {
- BlContext_Init(blContext, true, true);
- for (auto fileName : fileNames)
- BlContext_AddFile(blContext, fileName.c_str());
- // Process DEF first. Relies on LIFO ordering
- if (!defFileName.empty())
- BlContext_AddFile(blContext, defFileName.c_str());
- success &= BlContext_Link(blContext);
- }
- BlContext_Delete(blContext);
- printf("Total Time: %dms\n", GetTickCount() - startTick);
- if (success)
- return 0;
- return 2;
- }
|