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

📄 resource.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *				NK Kernel resource loader code
 *
 *				Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
 *
 * Module Name:
 *
 *				heap.c
 *
 * Abstract:
 *
 *				This file implements the NK kernel resource loader
 *
 *
 */

/* Straight-forward implementation of the resouce API's.  Since resources are
   read-only, we always return the slot 1 (kernel) copy of the resource, which
   is visable to all processes. */

#include "kernel.h"

#define DWORDUP(x) (((x)+3)&~03)

extern CRITICAL_SECTION LLcs, RFBcs, ModListcs;

typedef struct VERHEAD {
	WORD wTotLen;
	WORD wValLen;
	WORD wType;			/* always 0 */
	WCHAR szKey[(sizeof("VS_VERSION_INFO")+3)&~03];
	VS_FIXEDFILEINFO vsf;
} VERHEAD ;

typedef struct resroot_t {
	DWORD flags;
	DWORD timestamp;
	DWORD version;
	WORD  numnameents;
	WORD  numidents;
} resroot_t;

typedef struct resent_t {
	DWORD id;
	DWORD rva;
} resent_t;

typedef struct resdata_t {
	DWORD rva;
	DWORD size;
	DWORD codepage;
	DWORD unused;
} resdata_t;

DWORD atoiW(LPWSTR str) {
	DWORD retval = 0;
	while (*str) {
		retval = retval * 10 + (*str-(WCHAR)'0');
		str++;
	}
	return retval;
}

extern WCHAR lowerW(WCHAR);
HANDLE FindResourcePart2(LPBYTE BasePtr, e32_lite* eptr, LPCWSTR lpszName, LPCWSTR lpszType);

// Compare a Unicode string and a Pascal string

int StrCmpPascW(LPWSTR ustr, LPWSTR pstr) {
	int loop = (int)*pstr++;
	while (*ustr && loop--)
		if (lowerW(*ustr++) != lowerW(*pstr++))
			return 1;
	return (!*ustr && !loop ? 0 : 1);
}

// Compare an Ascii string and a Pascal string

int StrCmpAPascW(LPSTR astr, LPWSTR pstr) {
	int loop = (int)*pstr++;
	while (*astr && loop--)
		if (lowerW((WCHAR)*astr++) != lowerW(*pstr++))
			return 1;
	return (!*astr && !loop ? 0 : 1);
}

// Search for a named type

DWORD FindTypeByName(LPBYTE BasePtr, LPBYTE curr, LPWSTR str) {
	resroot_t *rootptr = (resroot_t *)curr;
	resent_t *resptr = (resent_t *)(curr + sizeof(resroot_t));
	int count = rootptr->numnameents;
	while (count--) {
		if (!str || !StrCmpPascW(str,(LPWSTR)(BasePtr+(resptr->id&0x7fffffff))))
			return resptr->rva;
		resptr++;
	}
	return 0;
}

// Search for a numbered type

DWORD FindTypeByNum(LPBYTE curr, DWORD id) {
	resroot_t *rootptr = (resroot_t *)curr;
	resent_t *resptr = (resent_t *)(curr + sizeof(resroot_t) +
		rootptr->numnameents*sizeof(resent_t));
	int count = rootptr->numidents;
	while (count--) {
		if (!id || (resptr->id == id))
			return resptr->rva;
		resptr++;
	}
	return 0;
}

// Find first entry (from curr pointer)

DWORD FindFirst(LPBYTE curr) {
	resroot_t *rootptr = (resroot_t *)curr;
	resent_t *resptr = (resent_t *)(curr + sizeof(resroot_t) +
		rootptr->numnameents*sizeof(resent_t));
	return resptr->rva;
}

// Find type entry (by name or number)

DWORD FindType(LPBYTE BasePtr, LPBYTE curr, LPWSTR str) {
	DWORD res;
	if (((DWORD)str)>>16)
		if (str[0] == (WCHAR)'#')
			return FindTypeByNum(curr, atoiW(str+1));
		else
			return FindTypeByName(BasePtr, curr, str);
	if (!(res = FindTypeByNum(curr, (DWORD)str)) && !str)
		res = FindTypeByName(BasePtr, curr, str);
	return res;
}

// global array that keeps our current UI language, and default UI language
LANGID g_rgwUILangs[6];	// at most 5 langs, one extra for array terminator
// 0 == current UI lang
// 1 == MAKELANGID(PRIMARYLANGID(g_rgwUILangs[0]), SUBLANG_DEFAULT)
// 2 == default UI lang
// 3 == MAKELANGID(PRIMARYLANGID(g_rgwUILangs[2]), SUBLANG_DEFAULT)
// 4 == 0x0409 (US English) 
// The array may be smaller since duplicates are eliminated

// Flag that enables/disables MUI globally 0==not inited, 1==inited&enabled 2==inited&disabled
DWORD g_EnableMUI;

// saved path to system MUI DLL. sizeof(\\windows\\ceosXXXX.mui)
//WCHAR g_szSystemMUI[22];

// Read language setting & add uniquely to array
void AddLangUnique(DWORD dwValue, HKEY hkey, LPCTSTR szValName)
{
	int i;
	DWORD  dwType, dwSize;
	LANGID langid1, langid2;

	if(!dwValue)	{
		dwSize = sizeof(DWORD);
		// load a langid, skip if error
		if( ERROR_SUCCESS!=RegQueryValueExW(hkey, szValName, (LPDWORD)L"MUI", &dwType, (LPBYTE)&dwValue, &dwSize) ||
			(dwType != REG_DWORD) || !dwValue ) {
				DEBUGMSG(1,(L"InitMUI: Failed to read regkey %s\r\n", szValName));
				return;
		}
	}				
	langid1 = (LANGID)dwValue;
	langid2 = MAKELANGID(PRIMARYLANGID(langid1), SUBLANG_DEFAULT);
	if(langid2 == langid1)
		langid2 = 0;
	DEBUGMSG(1,(L"InitMUI: Got Langs=%x %x\r\n", langid1, langid2));
	
	// add them uniquely to array
	for(i=0; ;i++) {
		if(!g_rgwUILangs[i]) {
			g_rgwUILangs[i] = langid1;
			g_rgwUILangs[i+1] = langid2;
			break;
		} else if(g_rgwUILangs[i]==langid1) {
			langid1 = 0;
		} else if(g_rgwUILangs[i]==langid2) {
			langid2 = 0;
		}
	}
}

// Initialize MUI language globals -- called only once during system startup, from RunApps
void InitMUILanguages(void)
{
	DWORD  dwType, dwSize, dwValue;
	
	DEBUGCHK(!g_EnableMUI); // this must be called only once
	if(!SystemAPISets[SH_FILESYS_APIS]) {
		g_EnableMUI = (DWORD)-1;	// if this config has no filesystem then MUI is disabled
		return;
	}
	
	// check if MUI is enabled
	dwSize = sizeof(DWORD);
	if( ERROR_SUCCESS!=RegQueryValueExW(HKEY_LOCAL_MACHINE, L"Enable",(LPDWORD)L"MUI", &dwType, (LPBYTE)&dwValue, &dwSize) ||
		(dwType != REG_DWORD) || !dwValue ) {
			DEBUGMSG(1,(L"InitMUI: DISABLED (%d)\r\n", dwValue));
			g_EnableMUI = (DWORD)-1; // disable MUI
			return;
	}

	// memset(g_rgwUILangs, 0, sizeof(g_rgwUILangs)); // not reqd
	// load Current User language, skip if error
	AddLangUnique(0, HKEY_CURRENT_USER, L"CurLang");
	// load System Default language, skip if error
	AddLangUnique(0, HKEY_LOCAL_MACHINE, L"SysLang");
	// load English
	AddLangUnique(0x0409, 0, 0);
	
	DEBUGMSG(1,(L"InitMUI: Langs=%x %x %x %x %x %x\r\n", g_rgwUILangs[0], g_rgwUILangs[1], 
		g_rgwUILangs[2], g_rgwUILangs[3], g_rgwUILangs[4], g_rgwUILangs[5]));



	g_EnableMUI = 1;	// set this as the last thing before exit
}


// Called to load MUI resource DLL. NOT in a critsec. Must be re-entrant.
HMODULE LoadMUI(HANDLE hModule, LPBYTE BasePtr2, e32_lite* eptr2)
{
	WCHAR	szPath[MAX_PATH];
	int		iLen, i;
	HMODULE hmodRes;
	DWORD dwLangID;
	HANDLE hRsrc;

	// if MUI disabled (or not yet inited, e.g. call by filesys.exe), then fail immediately
	if(g_EnableMUI != 1)
		return (HMODULE)-1;

	// See if module contains a reference to a MUI (resource type=222, id=1). If found,
	// the resource contains a basename to which we append .XXXX.MUI, where XXXX is the language code
	if( (hRsrc = FindResourcePart2(BasePtr2, eptr2, MAKEINTRESOURCE(ID_MUI), MAKEINTRESOURCE(RT_MUI))) &&
		(iLen = ((resdata_t *)hRsrc)->size) &&
		(iLen < sizeof(WCHAR)*(MAX_PATH-10)) ) {
			memcpy(szPath, (BasePtr2 + ((resdata_t *)hRsrc)->rva), iLen);
			iLen /= sizeof(WCHAR);
			szPath[iLen]=0;
			DEBUGMSG(1,(L"LoadMUI: Found indirection (%s, %d)\r\n", szPath, iLen)); 
	} 
	// otherwise search for local MUI dll, based on module path name
	else  if(!(iLen=GetModuleFileName(hModule, szPath, MAX_PATH-10))) {
		DEBUGCHK(FALSE);
		return (HMODULE)-1;
	}

	for(i=0; g_rgwUILangs[i]; i++)
	{
		// try to find local DLL in each of current/default/english languages
		dwLangID = g_rgwUILangs[i];
		NKwvsprintfW(szPath+iLen, TEXT(".%04X.MUI"), (LPVOID)&dwLangID, (MAX_PATH-iLen));
		DEBUGMSG(1,(L"LoadMUI: Trying %s\r\n",szPath));
		if(hmodRes=LoadLibraryEx(szPath, NULL, LOAD_LIBRARY_AS_DATAFILE)) { // dont call dllentry/resolve refs etc
			DEBUGMSG(1,(L"LoadMUI: Loaded %s\r\n", szPath)); 
			return hmodRes;
		}
	}
	return (HMODULE)-1;

		
}	

HANDLE FindResourcePart2(LPBYTE BasePtr, e32_lite* eptr, LPCWSTR lpszName, LPCWSTR lpszType) {
	DWORD trva;
	if (!eptr->e32_unit[RES].rva) return 0;
	BasePtr += eptr->e32_unit[RES].rva;
	if (!(trva = FindType(BasePtr, BasePtr, (LPWSTR)lpszType)) || 
		!(trva = FindType(BasePtr, BasePtr+(trva&0x7fffffff),(LPWSTR)lpszName)) ||
		!(trva = FindFirst(BasePtr+(trva&0x7fffffff)))) {
			return 0;
	}
	return (HANDLE)(BasePtr+(trva&0x7fffffff));
}

// Gets pmodResource, atomically updating it if reqd
PMODULE InterlockedUpdatePmodRes(PMODULE* ppMod, HMODULE hModule, LPBYTE BasePtr2, e32_lite* eptr2)
{
	PMODULE pmodRes;
	pmodRes = (PMODULE)LoadMUI(hModule, BasePtr2, eptr2);
	if(InterlockedTestExchange((LPLONG)ppMod, 0, (LONG)pmodRes)!=0) {
				if(pmodRes != (PMODULE)-1) 
			FreeLibrary(pmodRes);
		pmodRes = *ppMod;
	}
	DEBUGCHK(pmodRes);
	return pmodRes;
}


// Win32 FindResource

HANDLE SC_FindResource(HANDLE hModule, LPCWSTR lpszName, LPCWSTR lpszType) {
	LPBYTE BasePtr2;
	e32_lite *eptr2;
	PPROCESS pProc;
	PMODULE pmodRes;
	HANDLE	hRet;
	
	DEBUGMSG(ZONE_ENTRY,(L"SC_FindResource entry: %8.8lx %8.8lx %8.8lx\r\n",hModule,lpszName,lpszType));
	if (hModule == GetCurrentProcess())
		hModule = hCurProc;
	// Get Base & e32 ptr for current process or module as approp
	// also get MUI resource dll, loading it if neccesary
	if (pProc = HandleToProc(hModule)) { // a process
		BasePtr2 = (LPBYTE)MapPtrProc(pProc->BasePtr,pProc);
		eptr2 = &pProc->e32;
		if(!(pmodRes = pProc->pmodResource))
			pmodRes = InterlockedUpdatePmodRes(&(pProc->pmodResource), hModule, BasePtr2, eptr2);
	} else if (IsValidModule((LPMODULE)hModule)) { // a module

⌨️ 快捷键说明

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