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

📄 loader.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *              NK Kernel loader code * *              Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. * * Module Name: * *              loader.c * * Abstract: * *              This file implements the NK kernel loader for EXE/DLL * *//* The loader is derived from the Win32 executable file format spec.  The only   interesting thing is how we load a process.  When we load a process, we   simply schedule a thread in a new process contect.  That thread (in coredll)   knows how to read in an executable, and does so.  Then it traps into the kernel   and starts running in the new process.  Most of the code below is simply a direct   implimentation of the executable file format specification */#include "kernel.h"#define SYSTEMDIR L"\\Windows\\"#define SYSTEMDIRLEN 9struct KDataStruct *PtrKData;fslog_t *LogPtr;FREEINFO FreeInfo[2];MEMORYINFO MemoryInfo;ROMChain_t FirstROM;ROMChain_t *ROMChain, *OEMRomChain;extern CRITICAL_SECTION VAcs, DbgApiCS, LLcs, ModListcs, PagerCS;DWORD MainMemoryEndAddress, PagedInCount;typedef void (* NFC_t)(DWORD, DWORD, DWORD, DWORD);NFC_t pNotifyForceCleanboot;extern Name *pPath;ROMHDR *const volatile pTOC = (ROMHDR *)-1;     // Gets replaced by RomLoader with real address// ROM Header extension.  The ROM loader (RomImage) will set the pExtensions field of the table// of contents to point to this structure.  This structure contains the PID and a extra field to point// to further extensions.const ROMPID RomExt = {	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},	NULL};DWORD Decompress(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip);void GoToUserTime(void);void GoToKernTime(void);int currcrumb = -1;#define SetBreadcrumb(P) ((P)->breadcrumb |= (1<<currcrumb))#define ClearBreadcrumb(P) ((P)->breadcrumb &= ~(1<<currcrumb))#define HasBreadcrumb(P) ((P)->breadcrumb & (1<<currcrumb))_inline BOOL InitBreadcrumbs() {	if (currcrumb == 31) {		DEBUGCHK(0);		return FALSE;	}	currcrumb++;	return TRUE;}void FinishBreadcrumbs() {	PMODULE pMod;	DEBUGCHK(currcrumb != -1);	DEBUGCHK(currcrumb < 32);	for (pMod = pModList; pMod; pMod = pMod->pMod)		ClearBreadcrumb(pMod);	currcrumb--;}WCHAR lowerW(WCHAR ch) {	return ((ch >= 'A') && (ch <= 'Z')) ? (ch - 'A' + 'a') : ch;}int strcmponeiW(const wchar_t *pwc1, const wchar_t *pwc2) {	while (*pwc1 && (lowerW(*pwc1) == *pwc2)) {		pwc1++;		pwc2++;	}	return (*pwc1 ? 1 : 0);}int strcmpdllnameW(LPCWSTR src, LPCWSTR tgt) {	while (*src && (*src == lowerW(*tgt))) {		src++;		tgt++;	}	return ((*tgt && strcmponeiW(tgt,L".dll") && strcmponeiW(tgt,L".cpl")) || (*src && memcmp(src,L".dll",10) && memcmp(src,L".cpl",10))) ? 1 : 0;}int strcmpiAandW(LPCHAR lpa, LPWSTR lpu) {	while (*lpa && (lowerW((WCHAR)*lpa) == lowerW(*lpu))) {		lpa++;		lpu++;	}	return ((*lpa || *lpu) ? 1 : 0);}int kstrncmpi(LPWSTR str1, LPWSTR str2, int count) {	wchar_t f,l;	if (!count)		return 0;	do {		f = lowerW(*str1++);		l = lowerW(*str2++);	} while (--count && f && (f == l));	return (int)(f - l);}int kstrcmpi(LPWSTR str1, LPWSTR str2) {	wchar_t f,l;    do  {		f = lowerW(*str1++);		l = lowerW(*str2++);    } while (f && (f == l));    return (int)(f - l);}void kstrcpyW(LPWSTR p1, LPCWSTR p2) {	while (*p2)		*p1++ = *p2++;	*p1 = 0;}typedef BOOL (* OEMLoadInit_t)(LPWSTR lpszName);typedef BOOL (* OEMLoadModule_t)(LPBYTE lpData, DWORD cbData);OEMLoadInit_t pOEMLoadInit;OEMLoadModule_t pOEMLoadModule;ERRFALSE(!OEM_CERTIFY_FALSE);// returns getlasterror code, or 0 for successDWORD VerifyBinary(openexe_t *oeptr, LPWSTR lpszName, LPBYTE pbTrustLevel) {#define VBSIZE 1024	BYTE Buf[VBSIZE];	int iTrust;	DWORD len, pos, size, bytesread;	if ((oeptr->filetype == FT_ROMIMAGE) || !pOEMLoadInit || !pOEMLoadModule)		return 0;	if (!pOEMLoadInit(lpszName))		return (DWORD)NTE_BAD_SIGNATURE;	if (oeptr->filetype == FT_PPFSFILE)		len = rlseek(oeptr->hppfs,0,2);	else		len = SetFilePointer(oeptr->hf,0,0,2);	for (pos = 0; pos < len; pos += size) {		size = ((len - pos) > VBSIZE ? VBSIZE : (len - pos));		if (oeptr->filetype == FT_PPFSFILE) {			if (rreadseek(oeptr->hppfs,Buf,size,pos) != (int)size)				return (DWORD)NTE_BAD_SIGNATURE;		} else {			if (!ReadFileWithSeek(oeptr->hf,Buf,size,&bytesread,0,pos,0) || (bytesread != size))				return (DWORD)NTE_BAD_SIGNATURE;		}		if (!pOEMLoadModule(Buf,size))			return (DWORD)NTE_BAD_SIGNATURE;	}	if (!(iTrust = pOEMLoadModule(0,0)))		return (DWORD)NTE_BAD_SIGNATURE;	if (iTrust != OEM_CERTIFY_TRUST)		*pbTrustLevel = KERN_TRUST_RUN;	return 0;}BOOL OpenExe(LPWSTR lpszName, openexe_t *oeptr, BOOL bIsDLL, BOOL bAllowPaging) {	static OEinfo_t OEinfo;	return SafeOpenExe(lpszName,oeptr,bIsDLL,bAllowPaging,&OEinfo);}BOOL SafeOpenExe(LPWSTR lpszName, openexe_t *oeptr, BOOL bIsDLL, BOOL bAllowPaging, OEinfo_t *poeinfo) {	CEGUID sysguid;	TOCentry *tocptr;	int loop, plainlen, totlen, copylen;	LPWSTR nameptr, p2;	BOOL inWin, isAbs;	DWORD dwLastError;	DWORD bytesread;	HANDLE hFind;	DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe: %s\r\n"),lpszName));	dwLastError = KGetLastError(pCurThread);	isAbs = ((*lpszName == '\\') || (*lpszName == '/'));	totlen = strlenW(lpszName);	nameptr = lpszName + totlen;	while ((nameptr != lpszName) && (*nameptr != '\\') && (*nameptr != '/'))		nameptr--;	if ((*nameptr == '\\') || (*nameptr == '/'))		nameptr++;	inWin = 0;	if ((nameptr != lpszName) && (nameptr != lpszName+1)) {		if (((nameptr == lpszName + SYSTEMDIRLEN) && !kstrncmpi(lpszName,SYSTEMDIR,SYSTEMDIRLEN)) ||			((nameptr == lpszName + SYSTEMDIRLEN - 1) && !kstrncmpi(lpszName,SYSTEMDIR+1,SYSTEMDIRLEN-1)))			inWin = 1;		else {			memcpy(poeinfo->tmpname,lpszName,(nameptr-lpszName-1)*sizeof(WCHAR));			poeinfo->tmpname[nameptr-lpszName-1] = 0;			hFind = FindFirstFile(poeinfo->tmpname,&poeinfo->wfd);			if (hFind != INVALID_HANDLE_VALUE) {				CloseHandle(hFind);				if (poeinfo->wfd.dwOID == 1)					inWin = 1;			}		}	}	p2 = (LPWSTR)poeinfo->plainname;	while (*nameptr && (p2 - poeinfo->plainname < MAX_PATH-1))		*p2++ = *nameptr++;	*p2 = 0;	plainlen = p2 - poeinfo->plainname;	DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe: plain name %s\r\n"),poeinfo->plainname));	oeptr->bIsOID = 1;	oeptr->lpName = 0;	if (!(oeptr->lpName = AllocName(MAX_PATH*2))) {		KSetLastError(pCurThread,dwLastError);		return 0;	}	// check the file system	if (SystemAPISets[SH_FILESYS_APIS]) {		if (!isAbs) {			// if dll, check in directory exe launched from			if (bIsDLL) {				PPROCESS pProc;				pProc = (pCurThread->pcstkTop ? pCurThread->pcstkTop->pprcLast : pCurProc);				if (pProc->oe.filetype != FT_ROMIMAGE) {					if (pProc->oe.bIsOID) {						CREATE_SYSTEMGUID(&sysguid);												if (!(CeOidGetInfoEx(&sysguid,pProc->oe.ceOid,&poeinfo->ceoi)) || (poeinfo->ceoi.wObjType != OBJTYPE_FILE))							goto DoWinDir;					} else						kstrcpyW(poeinfo->ceoi.infFile.szFileName,pProc->oe.lpName->name);					nameptr = poeinfo->ceoi.infFile.szFileName + strlenW(poeinfo->ceoi.infFile.szFileName);					while ((*nameptr != '\\') && (*nameptr != '/') && (nameptr != poeinfo->ceoi.infFile.szFileName))						nameptr--;					if ((nameptr != poeinfo->ceoi.infFile.szFileName) && (MAX_PATH - 1 - (nameptr + 1 - poeinfo->ceoi.infFile.szFileName) >= plainlen)) {						memcpy(nameptr+1,poeinfo->plainname,plainlen*sizeof(WCHAR));						nameptr[plainlen+1] = 0;						if ((oeptr->hf = CreateFileW(poeinfo->ceoi.infFile.szFileName,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->ceoi.infFile.szFileName)+1)*2)) {									FreeName(oeptr->lpName);									oeptr->lpName = pName;								}								kstrcpyW(oeptr->lpName->name,poeinfo->ceoi.infFile.szFileName);							}							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;						}					}				}			}DoWinDir:			oeptr->hf = INVALID_HANDLE_VALUE;			// check for file as path from root			if (plainlen != totlen) {				poeinfo->tmpname[0] = '\\';				copylen = (totlen < MAX_PATH - 2 ? totlen : MAX_PATH - 2);				memcpy((LPWSTR)poeinfo->tmpname+1,lpszName,totlen*sizeof(WCHAR));				poeinfo->tmpname[1+copylen] = 0;				oeptr->hf = CreateFileW((LPWSTR)poeinfo->tmpname,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);			}			if (oeptr->hf == INVALID_HANDLE_VALUE) {				// check for file in windows directory				memcpy(poeinfo->tmpname,SYSTEMDIR,SYSTEMDIRLEN*sizeof(WCHAR));				copylen = (plainlen + SYSTEMDIRLEN < MAX_PATH-1) ? plainlen : MAX_PATH - 2 - SYSTEMDIRLEN;				memcpy((LPWSTR)poeinfo->tmpname+SYSTEMDIRLEN,poeinfo->plainname,copylen*sizeof(WCHAR));				poeinfo->tmpname[SYSTEMDIRLEN+copylen] = 0;				oeptr->hf = CreateFileW((LPWSTR)poeinfo->tmpname,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);			}			if (oeptr->hf == INVALID_HANDLE_VALUE) {				// check for file in root directory				poeinfo->tmpname[0] = '\\';				copylen = (plainlen + 1 < MAX_PATH-1) ? plainlen : MAX_PATH - 3;				memcpy((LPWSTR)poeinfo->tmpname+1,poeinfo->plainname,copylen*sizeof(WCHAR));				poeinfo->tmpname[1+copylen] = 0;				oeptr->hf = CreateFileW((LPWSTR)poeinfo->tmpname,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);			}			if (oeptr->hf != 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);				}			}		} else {			// check in main file system (will route to mounted if part of path)			if ((oeptr->hf = CreateFileW((LPWSTR)lpszName,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(lpszName)+1)*2)) {						FreeName(oeptr->lpName);						oeptr->lpName = pName;					}					kstrcpyW(oeptr->lpName->name,lpszName);				}			}		}		if (oeptr->hf != INVALID_HANDLE_VALUE) {			DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe %s: OSTORE: %8.8lx\r\n"),lpszName,oeptr->hf));			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;		}	}	if ((plainlen == totlen) || inWin) {		ROMChain_t *pROM;		for (pROM = ROMChain; pROM; pROM = pROM->pNext) {			// check ROM for any copy			tocptr = (TOCentry *)(pROM->pTOC+1);  // toc entries follow the header			for (loop = 0; loop < (int)pROM->pTOC->nummods; loop++) {				if (!strcmpiAandW(tocptr->lpszFileName,poeinfo->plainname)) {					DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe %s: ROM: %8.8lx\r\n"),lpszName,tocptr));					oeptr->tocptr = tocptr;					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++;			}		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -