📄 loader.c
字号:
oeptr->filetype = FT_ROMIMAGE;
oeptr->pagemode = (bAllowPaging && !(pTOC->ulKernelFlags & KFLAG_DISALLOW_PAGING)) ? PM_FULLPAGING : PM_NOPAGING;
KSetLastError(pCurThread,dwLastError);
if (oeptr->lpName)
FreeName(oeptr->lpName,);
return 1;
}
tocptr++;
}
}
}
if (!isAbs && pPath) {
LPWSTR pTrav = pPath->name;
int len;
while (*pTrav) {
len = strlenW(pTrav);
memcpy(poeinfo->tmpname,pTrav,len*sizeof(WCHAR));
copylen = (totlen + len < MAX_PATH-1) ? totlen : MAX_PATH - 2 - len;
memcpy((LPWSTR)poeinfo->tmpname+len,lpszName,copylen*sizeof(WCHAR));
poeinfo->tmpname[len+copylen] = 0;
if ((oeptr->hf = CreateFileW((LPWSTR)poeinfo->tmpname,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0)) != INVALID_HANDLE_VALUE) {
if (GetFileInformationByHandle(oeptr->hf,&poeinfo->bhfi) && (poeinfo->bhfi.dwOID != (ULONG)INVALID_HANDLE_VALUE)) {
FreeName(oeptr->lpName);
oeptr->ceOid = poeinfo->bhfi.dwOID;
} else {
LPName pName;
oeptr->bIsOID = 0;
if (pName = AllocName((strlenW(poeinfo->tmpname)+1)*2)) {
FreeName(oeptr->lpName);
oeptr->lpName = pName;
}
kstrcpyW(oeptr->lpName->name,poeinfo->tmpname);
}
oeptr->filetype = FT_OBJSTORE;
oeptr->pagemode = (bAllowPaging && !(pTOC->ulKernelFlags & KFLAG_DISALLOW_PAGING) &&
ReadFileWithSeek(oeptr->hf,0,0,0,0,0,0)) ? PM_FULLPAGING : PM_NOPAGING;
if ((SetFilePointer(oeptr->hf,0x3c,0,FILE_BEGIN) != 0x3c) ||
!ReadFile(oeptr->hf,(LPBYTE)&oeptr->offset,4,&bytesread,0) || (bytesread != 4)) {
CloseExe(oeptr);
return 0;
}
KSetLastError(pCurThread,dwLastError);
return 1;
}
pTrav += len + 1;
}
}
if ((plainlen == totlen) || inWin) {
// check PPFS, if string is short (PPFS doesn't like big names)
if (plainlen < 128) {
oeptr->hppfs = ropen(poeinfo->plainname,0x10000);
if (oeptr->hppfs != HFILE_ERROR) {
LPName pName;
RETAILMSG(1,(L"Kernel Loader: Using PPFS to load file %s\r\n",lpszName));
oeptr->filetype = FT_PPFSFILE;
oeptr->pagemode = (bAllowPaging && !(pTOC->ulKernelFlags & KFLAG_DISALLOW_PAGING)) ? PM_FULLPAGING : PM_NOPAGING;
if ((rlseek(oeptr->hppfs,0x3c,0) != 0x3c) ||
(rread(oeptr->hppfs,(LPBYTE)&oeptr->offset,4) != 4)) {
CloseExe(oeptr);
return 0;
}
oeptr->bIsOID = 0;
if (pName = AllocName((strlenW(poeinfo->plainname)+9+1)*2)) {
FreeName(oeptr->lpName);
oeptr->lpName = pName;
}
memcpy(oeptr->lpName->name,L"\\Windows\\",9*sizeof(WCHAR));
kstrcpyW(&oeptr->lpName->name[9],poeinfo->plainname);
KSetLastError(pCurThread,dwLastError);
return 1;
}
}
}
DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe %s: failed!\r\n"),lpszName));
// If not, it failed!
if (oeptr->lpName)
FreeName(oeptr->lpName);
return 0;
}
void CloseExe(openexe_t *oeptr) {
CALLBACKINFO cbi;
if (oeptr && oeptr->filetype) {
cbi.hProc = ProcArray[0].hProc;
if (oeptr->filetype == FT_PPFSFILE) {
cbi.pfn = (FARPROC)rclose;
cbi.pvArg0 = (LPVOID)oeptr->hppfs;
PerformCallBack4Int(&cbi);
} else if (oeptr->filetype == FT_OBJSTORE) {
cbi.pfn = (FARPROC)CloseHandle;
cbi.pvArg0 = oeptr->hf;
PerformCallBack4Int(&cbi);
}
if (!oeptr->bIsOID && oeptr->lpName)
FreeName(oeptr->lpName);
oeptr->lpName = 0;
oeptr->filetype = 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) {
KDUpdateSymbols(((DWORD)pCurProc->BasePtr)+1, TRUE);
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
void SC_SetCleanRebootFlag(void) {
DEBUGMSG(ZONE_ENTRY,(L"SC_SetCleanRebootFlag entry\r\n"));
ERRORMSG(pCurProc->bTrustLevel != KERN_TRUST_FULL,(L"SC_SetCleanRebootFlag failed due to insufficient trust\r\n"));
if (pCurProc->bTrustLevel == KERN_TRUST_FULL)
LogPtr->magic1 = 0;
DEBUGMSG(ZONE_ENTRY,(L"SC_SetCleanRebootFlag exit\r\n"));
}
// Relocate the kernel
void KernelRelocate(ROMHDR *const pTOC)
{
ULONG loop;
COPYentry *cptr;
#ifdef DEBUG if (pTOC == (ROMHDR *const) 0xffffffff) {
OEMWriteDebugString(TEXT("ERROR: Kernel must be part of ROM image!\r\n"));
while (1) ; }
#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);
if (cptr->ulCopyLen != cptr->ulDestLen)
memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),0,cptr->ulDestLen-cptr->ulCopyLen);
}
// Now you can read global variables...
PtrKData = &KData; // Set this to allow displaying the kpage from the KD.
MainMemoryEndAddress = pTOC->ulRAMEnd;
FirstROM.pTOC = pTOC;
FirstROM.pNext = 0;
ROMChain = &FirstROM;
}
void SC_NotifyForceCleanboot(void) {
if (pNotifyForceCleanboot)
pNotifyForceCleanboot(LogPtr->fsmemblk[0].startptr,LogPtr->fsmemblk[0].length,
LogPtr->fsmemblk[1].startptr,LogPtr->fsmemblk[1].length);
}
// should match same define in filesys\heap\heap.c
#define MAX_FILESYSTEM_HEAP_SIZE 256*1024*1024
DWORD CalcFSPages(DWORD pages) {
DWORD fspages;
if (pages <= 2*1024*1024/PAGE_SIZE) {
fspages = (pages*(pTOC->ulFSRamPercent&0xff))/256;
} else {
fspages = ((2*1024*1024/PAGE_SIZE)*(pTOC->ulFSRamPercent&0xff))/256;
if (pages <= 4*1024*1024/PAGE_SIZE) {
fspages += ((pages-2*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>8)&0xff))/256;
} else {
fspages += ((2*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>8)&0xff))/256;
if (pages <= 6*1024*1024/PAGE_SIZE) {
fspages += ((pages-4*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>16)&0xff))/256;
} else {
fspages += ((2*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>16)&0xff))/256;
fspages += ((pages-6*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>24)&0xff))/256;
}
}
}
return fspages;
}
DWORD CarveMem(LPBYTE pMem, DWORD dwExt, DWORD dwLen, DWORD dwFSPages) {
DWORD dwPages, dwNow, loop;
LPBYTE pCur, pPage;
dwPages = dwLen / PAGE_SIZE;
pCur = pMem + dwExt;
while (dwPages && dwFSPages) {
pPage = pCur;
pCur += PAGE_SIZE;
dwPages--;
*(LPBYTE *)pPage = LogPtr->pFSList;
LogPtr->pFSList = pPage;
dwNow = dwPages;
if (dwNow > dwFSPages)
dwNow = dwFSPages;
if (dwNow > (PAGE_SIZE/4) - 2)
dwNow = (PAGE_SIZE/4) - 2;
*((LPDWORD)pPage+1) = dwNow;
for (loop = 0; loop < dwNow; loop++) {
*((LPDWORD)pPage+2+loop) = (DWORD)pCur;
pCur += PAGE_SIZE;
}
dwPages -= dwNow;
dwFSPages -= dwNow;
}
return dwFSPages;
}
void RemovePage(DWORD dwAddr);
void GrabFSPages(void) {
LPBYTE pPageList;
DWORD loop,max;
pPageList = LogPtr->pFSList;
while (pPageList) {
max = *((LPDWORD)pPageList+1);
RemovePage((DWORD)pPageList);
for (loop = 0; loop < max; loop++)
RemovePage(*((LPDWORD)pPageList+2+loop));
pPageList = *(LPBYTE *)pPageList;
}
}
// need to avoid kernel stack overflow while system starting
#ifdef SHIP_BUILD
#define RTLMSG(cond,printf_exp) ((void)0)
#else
#define RTLMSG(cond,printf_exp) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -