📄 loader.c
字号:
if (MAX_PATH <= nTotalLen) {
// path too long
KSetLastError (pCurThread, ERROR_INVALID_PARAMETER);
return FALSE;
}
memset (oeptr, 0, sizeof (openexe_t));
oeptr->pagemode = (pTOC->ulKernelFlags & KFLAG_DISALLOW_PAGING)
? PM_CANNOT_PAGE
: (bAllowPaging? PM_FULLPAGING : PM_NOPAGING);
oeptr->bIsOID = 1;
// find the file name part of lpszName
pPlainName = GetPlainName (lpszName);
DEBUGMSG (ZONE_OPENEXE,(TEXT("OpenExecutable: plain name = %s\r\n"), pPlainName));
// see if we're looking for file in Windows directory
if ((pPlainName != lpszName) && (pPlainName != lpszName+1)) {
if (((pPlainName == lpszName + SYSTEMDIRLEN) && !kstrncmpi(lpszName,SYSTEMDIR,SYSTEMDIRLEN))
|| ((pPlainName == lpszName + SYSTEMDIRLEN - 1) && !kstrncmpi(lpszName,SYSTEMDIR+1,SYSTEMDIRLEN-1))) {
bIsInWindDir = TRUE;
} else {
bIsInWindDir = IsInWinDir (lpszName, pPlainName-lpszName-1);
}
}
// load from ROM if filesys is not ready
if (!SystemAPISets[SH_FILESYS_APIS]) {
DEBUGMSG (ZONE_OPENEXE,(TEXT("OpenExecutable: Filesys not loaded, Opening from ROM\r\n"), pPlainName));
dwErr = OpenFileFromROM (pPlainName, oeptr);
} else if (bIsAbs) {
DEBUGMSG (ZONE_OPENEXE,(TEXT("OpenExecutable: absolute path\r\n"), lpszName));
// absolute path
// try debug list if it's in \Windows
if (bIsInWindDir && IsInDbgList (pPlainName)) {
dwErr = TryDir (oeptr, DBGDIR, DBGDIRLEN, pPlainName, strlenW (pPlainName), TRUE);
}
// try filesystem
if (ERROR_FILE_NOT_FOUND == dwErr) {
dwErr = OpenFileFromFilesys ((LPWSTR)lpszName, oeptr, FALSE);
}
// if not found in filesystem and is in windows directory, try ROM
if ((ERROR_FILE_NOT_FOUND == dwErr) && bIsInWindDir) {
dwErr = OpenFileFromROM (pPlainName, oeptr);
}
} else {
// relative path
DEBUGMSG (ZONE_OPENEXE,(TEXT("OpenExecutable: relative path\r\n"), lpszName));
// try debug list first
if (IsInDbgList (pPlainName)) {
dwErr = TryDir (oeptr, DBGDIR, DBGDIRLEN, lpszName, nTotalLen, TRUE);
}
// try same directory as EXE for DLL
if (bIsDll && (ERROR_FILE_NOT_FOUND == dwErr)) {
PPROCESS pProc = (pCurThread->pcstkTop ? pCurThread->pcstkTop->pprcLast : pCurProc);
if (!(FA_PREFIXUP & pProc->oe.filetype)) {
dwErr = TrySameDir (oeptr, pPlainName, pProc);
}
}
if ((ERROR_FILE_NOT_FOUND == dwErr)
&& ((dwErr = TryDir (oeptr, SYSTEMDIR, SYSTEMDIRLEN, lpszName, nTotalLen, FALSE)) == ERROR_FILE_NOT_FOUND) // try \windows\lpszName
&& ((!bIsInWindDir && (lpszName != pPlainName)) // try ROM
|| ((dwErr = OpenFileFromROM (pPlainName, oeptr) == ERROR_FILE_NOT_FOUND)))
&& ((dwErr = TryDir (oeptr, L"\\", 1, lpszName, nTotalLen, FALSE)) == ERROR_FILE_NOT_FOUND)) { // try \lpszName
if (pPath) {
// check the alternative search path
LPCWSTR pTrav = pPath->name;
int nLen;
while (*pTrav && (ERROR_FILE_NOT_FOUND == dwErr)) {
nLen = strlenW(pTrav);
dwErr = TryDir (oeptr, pTrav, nLen, lpszName, nTotalLen, FALSE);
pTrav += nLen + 1;
}
}
}
}
// restore last err if succeeded, set last err if failed.
KSetLastError (pCurThread, dwErr? dwErr : dwLastErr);
return !dwErr;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
CloseExe(
openexe_t *oeptr
)
{
if (oeptr && oeptr->filetype) {
CALLBACKINFO cbi;
cbi.hProc = ProcArray[0].hProc;
if (!(FA_DIRECTROM & oeptr->filetype)) {
cbi.pfn = (FARPROC)SC_CloseHandle;
cbi.pvArg0 = (LPVOID)oeptr->hf;
PerformCallBack4Int(&cbi);
}
oeptr->filetype = 0;
if (!oeptr->bIsOID && oeptr->lpName)
FreeName(oeptr->lpName);
oeptr->lpName = 0;
}
}
//------------------------------------------------------------------------------
// @doc INTERNAL
// @func void | CloseProcOE | Closes down the internal file handle for the process
// @comm Used by apis.c in final process termination before doing final kernel syscall
//------------------------------------------------------------------------------
void
SC_CloseProcOE(
DWORD bCloseFile
)
{
THREAD *pdbgr, *ptrav;
DEBUGMSG(ZONE_ENTRY,(L"SC_CloseProcOE entry\r\n"));
if (bCloseFile == 2) {
if (!GET_DYING(pCurThread))
SetUserInfo(hCurThread,KGetLastError(pCurThread));
SET_DYING(pCurThread);
SET_DEAD(pCurThread);
DEBUGMSG(ZONE_ENTRY,(L"SC_CloseProcOE exit (2)\r\n"));
return;
}
EnterCriticalSection(&DbgApiCS);
if (pCurThread->pThrdDbg && pCurThread->pThrdDbg->hEvent) {
if (pCurProc->hDbgrThrd) {
pdbgr = HandleToThread(pCurProc->hDbgrThrd);
if (pdbgr->pThrdDbg->hFirstThrd == hCurThread)
pdbgr->pThrdDbg->hFirstThrd = pCurThread->pThrdDbg->hNextThrd;
else {
ptrav = HandleToThread(pdbgr->pThrdDbg->hFirstThrd);
while (ptrav->pThrdDbg->hNextThrd != hCurThread)
ptrav = HandleToThread(ptrav->pThrdDbg->hNextThrd);
ptrav->pThrdDbg->hNextThrd = pCurThread->pThrdDbg->hNextThrd;
}
}
pCurThread->pThrdDbg->dbginfo.dwDebugEventCode = 0;
SetEvent(pCurThread->pThrdDbg->hEvent);
CloseHandle(pCurThread->pThrdDbg->hEvent);
pCurThread->pThrdDbg->hEvent = 0;
pCurThread->pThrdDbg->dbginfo.dwDebugEventCode = 0;
if (pCurThread->pThrdDbg->hBlockEvent) {
CloseHandle(pCurThread->pThrdDbg->hBlockEvent);
pCurThread->pThrdDbg->hBlockEvent = 0;
}
}
LeaveCriticalSection(&DbgApiCS);
if (bCloseFile) {
HDModUnload((DWORD)pCurProc);
CloseExe(&pCurProc->oe);
CloseAllCrits();
}
DEBUGMSG(ZONE_ENTRY,(L"SC_CloseProcOE exit\r\n"));
}
#ifdef DEBUG
LPWSTR e32str[STD_EXTRA] = {
TEXT("EXP"),TEXT("IMP"),TEXT("RES"),TEXT("EXC"),TEXT("SEC"),TEXT("FIX"),TEXT("DEB"),TEXT("IMD"),
TEXT("MSP"),TEXT("TLS"),TEXT("CBK"),TEXT("RS1"),TEXT("RS2"),TEXT("RS3"),TEXT("RS4"),TEXT("RS5"),
};
//------------------------------------------------------------------------------
// Dump e32 header
//------------------------------------------------------------------------------
void
DumpHeader(
e32_exe *e32
)
{
int loop;
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_magic : %8.8lx\r\n"),*(LPDWORD)&e32->e32_magic));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_cpu : %8.8lx\r\n"),e32->e32_cpu));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_objcnt : %8.8lx\r\n"),e32->e32_objcnt));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_symtaboff : %8.8lx\r\n"),e32->e32_symtaboff));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_symcount : %8.8lx\r\n"),e32->e32_symcount));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_timestamp : %8.8lx\r\n"),e32->e32_timestamp));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_opthdrsize : %8.8lx\r\n"),e32->e32_opthdrsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_imageflags : %8.8lx\r\n"),e32->e32_imageflags));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_coffmagic : %8.8lx\r\n"),e32->e32_coffmagic));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_linkmajor : %8.8lx\r\n"),e32->e32_linkmajor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_linkminor : %8.8lx\r\n"),e32->e32_linkminor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_codesize : %8.8lx\r\n"),e32->e32_codesize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_initdsize : %8.8lx\r\n"),e32->e32_initdsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_uninitdsize: %8.8lx\r\n"),e32->e32_uninitdsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_entryrva : %8.8lx\r\n"),e32->e32_entryrva));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_codebase : %8.8lx\r\n"),e32->e32_codebase));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_database : %8.8lx\r\n"),e32->e32_database));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_vbase : %8.8lx\r\n"),e32->e32_vbase));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_objalign : %8.8lx\r\n"),e32->e32_objalign));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_filealign : %8.8lx\r\n"),e32->e32_filealign));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_osmajor : %8.8lx\r\n"),e32->e32_osmajor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_osminor : %8.8lx\r\n"),e32->e32_osminor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_usermajor : %8.8lx\r\n"),e32->e32_usermajor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_userminor : %8.8lx\r\n"),e32->e32_userminor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_subsysmajor: %8.8lx\r\n"),e32->e32_subsysmajor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_subsysminor: %8.8lx\r\n"),e32->e32_subsysminor));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_vsize : %8.8lx\r\n"),e32->e32_vsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_hdrsize : %8.8lx\r\n"),e32->e32_hdrsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_filechksum : %8.8lx\r\n"),e32->e32_filechksum));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_subsys : %8.8lx\r\n"),e32->e32_subsys));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_dllflags : %8.8lx\r\n"),e32->e32_dllflags));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_stackmax : %8.8lx\r\n"),e32->e32_stackmax));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_stackinit : %8.8lx\r\n"),e32->e32_stackinit));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_heapmax : %8.8lx\r\n"),e32->e32_heapmax));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_heapinit : %8.8lx\r\n"),e32->e32_heapinit));
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_hdrextra : %8.8lx\r\n"),e32->e32_hdrextra));
for (loop = 0; loop < STD_EXTRA; loop++)
DEBUGMSG(ZONE_LOADER1,(TEXT(" e32_unit:%3.3s : %8.8lx %8.8lx\r\n"),
e32str[loop],e32->e32_unit[loop].rva,e32->e32_unit[loop].size));
}
//------------------------------------------------------------------------------
// Dump o32 header
//------------------------------------------------------------------------------
void
DumpSection(
o32_obj *o32,
o32_lite *o32l
)
{
ulong loop;
DEBUGMSG(ZONE_LOADER1,(TEXT("Section %a:\r\n"),o32->o32_name));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32_vsize : %8.8lx\r\n"),o32->o32_vsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32_rva : %8.8lx\r\n"),o32->o32_rva));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32_psize : %8.8lx\r\n"),o32->o32_psize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32_dataptr : %8.8lx\r\n"),o32->o32_dataptr));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32_realaddr : %8.8lx\r\n"),o32->o32_realaddr));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32_flags : %8.8lx\r\n"),o32->o32_flags));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32l_vsize : %8.8lx\r\n"),o32l->o32_vsize));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32l_rva : %8.8lx\r\n"),o32l->o32_rva));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32l_realaddr : %8.8lx\r\n"),o32l->o32_realaddr));
DEBUGMSG(ZONE_LOADER1,(TEXT(" o32l_flags : %8.8lx\r\n"),o32l->o32_flags));
for (loop = 0; loop+16 <= o32l->o32_vsize; loop+=16) {
DEBUGMSG(ZONE_LOADER2,(TEXT(" %8.8lx: %8.8lx %8.8lx %8.8lx %8.8lx\r\n"),
loop,
*(LPDWORD)(o32l->o32_realaddr+loop),
*(LPDWORD)(o32l->o32_realaddr+loop+4),
*(LPDWORD)(o32l->o32_realaddr+loop+8),
*(LPDWORD)(o32l->o32_realaddr+loop+12)));
}
if (loop != o32l->o32_vsize) {
DEBUGMSG(ZONE_LOADER2,(TEXT(" %8.8lx:"),loop));
while (loop+4 <= o32l->o32_vsize) {
DEBUGMSG(ZONE_LOADER2,(TEXT(" %8.8lx"),*(LPDWORD)(o32l->o32_realaddr+loop)));
loop += 4;
}
if (loop+2 <= o32l->o32_vsize)
DEBUGMSG(ZONE_LOADER2,(TEXT(" %4.4lx"),(DWORD)*(LPWORD)(o32l->o32_realaddr+loop)));
DEBUGMSG(ZONE_LOADER2,(TEXT("\r\n")));
}
}
#endif
//
// OAL can call this function to force a clean boot
//
void NKForceCleanBoot (void)
{
fForceCleanBoot = TRUE;
if (LogPtr)
LogPtr->magic1 = 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SC_SetCleanRebootFlag(void)
{
TRUSTED_API_VOID (L"SC_SetCleanRebootFlag");
DEBUGMSG(ZONE_ENTRY,(L"SC_SetCleanRebootFlag entry\r\n"));
NKForceCleanBoot ();
DEBUGMSG(ZONE_ENTRY,(L"SC_SetCleanRebootFlag exit\r\n"));
}
//------------------------------------------------------------------------------
// Relocate the kernel
//------------------------------------------------------------------------------
void
KernelRelocate(
ROMHDR *const pTOC
)
{
ULONG loop;
COPYentry *cptr;
#ifdef DEBUG // Can't do much here, no r/w data or real stack, no VM
if (pTOC == (ROMHDR *const) 0xffffffff) {
OEMWriteDebugString(TEXT("ERROR: Kernel must be part of ROM image!\r\n"));
while (1) ; // spin forever!
}
#endif
KInfoTable[KINX_PTOC] = (long)pTOC;
// This is where the data sections become valid... don't read globals until after this
for (loop = 0; loop < pTOC->ulCopyEntries; loop++) {
cptr = (COPYentry *)(pTOC->ulCopyOffset + loop*sizeof(COPYentry));
if (cptr->ulCopyLen) {
memcpy((LPVOID)cptr->ulDest,(LPVOID)cptr->ulSource,cptr->ulCopyLen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -