📄 resource.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*
* NK Kernel resource loader code
*
*
* Module Name:
*
* resource.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"
#undef LocalAlloc
#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif
#define DWORDUP(x) (((x)+3)&~03)
extern
void*
KmodeEntries(
void
);
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;
/* xref ref regset
; MUI Register setttins :
; HKLM\MUI\Enable - enable MUI or not
; HKLM\MUI\SysLang - system default langid
; HKCU\MUI\CurLang - langid for current user
[HKEY_LOCAL_MACHINE\MUI]
; Update the enable field to enable MUI
;"Enable"=dword:1
; Update the SysLang field to set system default langid
;"SysLang"=dword:0409
[HKEY_CURRENT_USER\MUI]
; Update the CurLang field to set user default langid
;"CurLang"=dword:0409
*/
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
atoiW(
LPWSTR str
)
{
DWORD retval = 0;
while (*str) {
retval = retval * 10 + (*str-(WCHAR)'0');
str++;
}
return retval;
}
extern WCHAR lowerW(WCHAR);
HANDLE FindResourcePart2(PMODULE pMod, 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)))) {
DEBUGCHK (!IsSecureVa(resptr->rva));
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)) {
DEBUGCHK (!IsSecureVa(resptr->rva));
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;
}
#define MAX_MUI_LANG 6
// global array that keeps our current UI language, and default UI language
LANGID g_rgwUILangs[MAX_MUI_LANG]; // 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 < MAX_MUI_LANG; 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;
}
}
}
//------------------------------------------------------------------------------
// Called to load MUI resource DLL. NOT in a critsec. Must be re-entrant.
//------------------------------------------------------------------------------
PMODULE LoadMUI (HANDLE hModule, LPBYTE BasePtr, e32_lite* eptr)
{
WCHAR szPath[MAX_PATH];
int iLen, i;
DWORD dwLangID;
HANDLE hRsrc;
PMODULE pMod;
// if MUI disabled (or not yet inited, e.g. call by filesys.exe), or the module doesn't have
// resources, then fail immediately
if ((g_EnableMUI != 1) || !eptr->e32_unit[RES].rva) {
return NULL;
}
// we must be holding LLcs already
DEBUGCHK (LLcs.OwnerThread == hCurThread);
pMod = (!((DWORD) hModule & 3) && IsValidModule((PMODULE)hModule))? (PMODULE)hModule : 0;
// 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(pMod, BasePtr, eptr, MAKEINTRESOURCE(ID_MUI), MAKEINTRESOURCE(RT_MUI)))
&& (iLen = ((resdata_t *)hRsrc)->size)
&& (iLen < sizeof(WCHAR)*(MAX_PATH-10)) ) {
memcpy(szPath, (BasePtr + ((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 NULL;
}
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 (pMod = (PMODULE) LoadOneLibraryW (szPath, LLIB_NO_MUI, LOAD_LIBRARY_AS_DATAFILE)) { // dont call dllentry/resolve refs etc
DEBUGMSG (1,(L"LoadMUI: Loaded %s\r\n", szPath));
return pMod;
}
}
return NULL;
}
//------------------------------------------------------------------------------
// Initialize MUI language globals -- called only once during system startup, from RunApps
//------------------------------------------------------------------------------
void
InitMUILanguages(void)
{
DWORD dwType, dwSize, dwValue;
PMODULE pMod = (PMODULE) hCoreDll;
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -