Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

263 lines
5.8 KiB

/***********************************************************************
* Microsoft (R) 32-Bit Incremental Linker
*
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
*
* File: coff.cpp
*
* File Comments:
*
* The NT COFF Linker/Librarian/Dumper/Editor/Binder
*
***********************************************************************/
#include "link.h"
#ifdef TIMEBOMB
#include <timebomb.h>
#endif // TIMEBOMB
typedef MainFunc (*MAINFUNCTION)(int, char *[]);
struct calltype {
char *Name;
int Switch;
TOOL_TYPE Tool;
MAINFUNCTION CallFunc;
} ToolType[] = {
{ "Linker", 4, Linker, (MAINFUNCTION) LinkerMain },
{ "Library Manager", 3, Librarian, (MAINFUNCTION) LibrarianMain },
{ "Dumper", 4, Dumper, (MAINFUNCTION) DumperMain },
{ "Editor", 4, Editor, (MAINFUNCTION) EditorMain },
#if DBG
{ "InspectIncrDb", 4, DbInspector, (MAINFUNCTION) DbInspMain },
#endif // DBG
{ "Helper", 4, NotUsed, (MAINFUNCTION) HelperMain },
{ NULL, 0, NotUsed, NULL }
};
#define STDIO_BUF_SIZE 2048 // buffer size used by linker
BOOL WINAPI ControlCHandler(DWORD /* CtrlType */)
{
if (Tool == Linker) {
fCtrlCSignal = TRUE;
return(TRUE);
}
BadExitCleanup();
return(FALSE);
}
#if DBG
void __cdecl HandleAbort(int /* signal */)
{
BadExitCleanup();
}
#endif // DBG
MainFunc __cdecl main(int Argc, char *Argv[])
/*++
Routine Description:
Calls either the Linker, Librarian, Dumper, or Editor.
Arguments:
Argc - Standard C argument count.
Argv - Standard C argument strings.
Return Value:
0 Successful.
1 Failed.
--*/
{
InfoStream = stdout; // Initial value.
#ifdef TIMEBOMB
FcCheckVerDate(0, &ctmOpenBy, &ctmCloseBy, CliTBCallBack);
#endif // TIMEBOMB
#if DBG
#ifdef _M_MRX000
if (getenv("link_noalign") != NULL) {
SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);
}
#endif
#endif
__try {
char *szDbFlags;
int iarg;
char szProgramName[_MAX_FNAME];
WORD i;
sprintf(szVersion, "Version " VERSION_STR);
SetConsoleCtrlHandler(ControlCHandler, TRUE);
#if DBG
signal(SIGABRT, HandleAbort); // Setup handler for assert() calls.
#endif
// Pre-scan commandline for a "-db" option; if found, handle and delete.
szDbFlags = NULL;
for (iarg = 1; iarg < Argc; iarg++) {
// Be careful not to recognize -dbgimplib
if ((Argv[iarg][0] == '-') &&
(Argv[iarg][1] == 'd') &&
(Argv[iarg][2] == 'b') &&
((Argv[iarg][3] == '\0') || isdigit(Argv[iarg][3]))) {
szDbFlags = &Argv[iarg][3];
memmove(&Argv[iarg], &Argv[iarg + 1],
sizeof(Argv[0]) * (Argc - iarg - 1));
Argc--;
iarg--;
}
}
dbsetflags(szDbFlags, "LINK_DB");
// Initialize the buffered I/O package
FileInit(cfiInSystemNT,
cfiCacheableInSystemNT,
cfiInSystemTNT,
cfiCacheableInSystemTNT);
_splitpath(Argv[0], NULL, NULL, szProgramName, NULL);
ToolName = _strupr(szProgramName);
if (Argc < 2) {
goto DefaultToLinker;
}
if ((Argv[1][0] != '/') && (Argv[1][0] != '-')) {
goto DefaultToLinker;
}
for (i = 0; ToolType[i].Name; i++) {
if (!_strnicmp(Argv[1]+1, ToolType[i].Name, ToolType[i].Switch)) {
// Remove Argv[1] from the arg vector
for (iarg = 1; iarg < Argc; iarg++) {
Argv[iarg] = Argv[iarg+1];
}
Argc--;
FoundTool:
switch (ToolType[i].Tool) {
case Dumper:
break;
case Editor:
// Editor gets buffers of 0 because the code currently
// doesn't do flush(stdout) before gets() ...
setvbuf(stdout, NULL, _IOFBF, 0);
setvbuf(stderr, NULL, _IOFBF, 0);
break;
default:
setvbuf(stdout, NULL, _IOFBF, STDIO_BUF_SIZE);
setvbuf(stderr, NULL, _IOFBF, STDIO_BUF_SIZE);
break;
}
ToolGenericName = ToolType[i].Name; // for printing banner later
Tool = ToolType[i].Tool;
return(ToolType[i].CallFunc(Argc, Argv));
}
}
DefaultToLinker:
// Default tool is LINK
i = 0;
goto FoundTool;
}
__except (fExceptionsOff ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER) {
const char *szFilename;
// UNDONE: Use Fatal or DisplayMessage?
if (fNeedBanner) {
PrintBanner();
}
if (InternalError.CombinedFilenames[0]) {
szFilename = InternalError.CombinedFilenames;
} else {
szFilename = ToolName;
}
printf("\n"
"%s : error : Internal error during %s\n",
szFilename,
InternalError.Phase);
fflush(NULL);
}
return(-2);
}
MainFunc
HelperMain(int /* Argc */, char * /* Argv */ [])
/*++
Routine Description:
Prints usage.
Arguments:
Argc - Standard C argument count.
Argv - Standard C argument strings.
Return Value:
USAGE.
--*/
{
WORD i;
for (i = 0; ToolType[i].Name; i++) {
printf("%s /%.*s for help on %s\n",
ToolName,
ToolType[i].Switch,
ToolType[i].Name,
ToolType[i].Name
);
}
return(USAGE);
}