⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 5 页
字号:
					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 + -