📄 resource.c
字号:
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");
// Do not load English as default since the default should be whatever built inside the executable.
// 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
// at this point, the only processes running should be NK and filesys.
// We need to synchronize the ref-count of coredll and it's MUI
EnterCriticalSection (&LLcs);
DEBUGCHK (!(pMod->inuse & ~3));
if (pMod->pmodResource = LoadMUI (pMod, pMod->BasePtr, &pMod->e32)) {
pMod->pmodResource->refcnt[0] = pMod->refcnt[0];
pMod->pmodResource->refcnt[1] = pMod->refcnt[1];
pMod->pmodResource->inuse = pMod->inuse;
}
LeaveCriticalSection (&LLcs);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
HANDLE
FindResourcePart2(
PMODULE pMod,
LPBYTE BasePtr,
e32_lite* eptr,
LPCWSTR lpszName,
LPCWSTR lpszType
)
{
DWORD trva;
if (!eptr->e32_unit[RES].rva) return 0;
if (pMod && pMod->rwHigh) {
// need to find the right section if RO/RW section are split
int loop;
o32_lite *optr = pMod->o32_ptr;
for (loop = 0; loop < eptr->e32_objcnt; loop++, optr ++) {
if (optr->o32_rva == eptr->e32_unit[RES].rva)
break;
}
if (loop == eptr->e32_objcnt) {
DEBUGMSG (ZONE_LOADER2, (L"FindRsc2 Failed: module '%s', eptr->e32_unit[RES].rva = %8.8lx\n",
pMod->lpszModName, eptr->e32_unit[RES].rva));
return 0;
}
BasePtr = (LPBYTE) optr->o32_realaddr;
} else {
BasePtr += eptr->e32_unit[RES].rva;
}
DEBUGMSG (ZONE_LOADER2, (L"FindRsc2: BasePtr = %8.8lx\n", BasePtr));
if (!(trva = FindType(BasePtr, BasePtr, (LPWSTR)lpszType)) ||
!(trva = FindType(BasePtr, BasePtr+(trva&0x7fffffff),(LPWSTR)lpszName)) ||
!(trva = FindFirst(BasePtr+(trva&0x7fffffff)))) {
return 0;
}
DEBUGMSG (ZONE_LOADER2, (L"FindRsc2 return %8.8lx\n", (BasePtr+(trva&0x7fffffff))));
return (HANDLE)(BasePtr+(trva&0x7fffffff));
}
//------------------------------------------------------------------------------
// Win32 FindResource
//------------------------------------------------------------------------------
HANDLE
SC_FindResource(
HANDLE hModule,
LPCWSTR lpszName,
LPCWSTR lpszType
)
{
LPBYTE BasePtr;
e32_lite *eptr;
PPROCESS pProc;
PMODULE pmodRes, pMod = 0;
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
BasePtr = (LPBYTE)MapPtrProc(pProc->BasePtr,pProc);
eptr = &pProc->e32;
pmodRes = pProc->pmodResource;
} else if (IsValidModule(pMod = (LPMODULE)hModule)) { // a module
BasePtr = (LPBYTE)MapPtrProc(pMod->BasePtr,&ProcArray[0]);
eptr = &pMod->e32;
pmodRes = pMod->pmodResource;
} else {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
DEBUGMSG(ZONE_ENTRY,(L"SC_FindResource exit: %8.8lx\r\n",0));
return 0;
}
// If we have a MUI dll try to load from it first
hRet = 0;
if(pmodRes) {
//DEBUGMSG(1,(L"SC_FindResource: Trying MUI %08x\r\n",pmodRes));
DEBUGCHK(IsValidModule(pmodRes)); // at this point pmodRes is a valid PMODULE
hRet = FindResourcePart2 (pmodRes, (LPBYTE) pmodRes->BasePtr, &(pmodRes->e32), lpszName, lpszType);
}
// if no MUI or failed to find resource, try the module itself
if(!hRet) {
//DEBUGMSG(1,(L"SC_FindResource: Trying self\r\n"));
hRet = FindResourcePart2(pMod, BasePtr, eptr, lpszName, lpszType);
}
if(!hRet)
KSetLastError(pCurThread,ERROR_RESOURCE_NAME_NOT_FOUND);
DEBUGMSG(ZONE_ENTRY,(L"SC_FindResource exit: %8.8lx\r\n",hRet));
return hRet;
}
//------------------------------------------------------------------------------
// Win32 SizeofResource
//------------------------------------------------------------------------------
#pragma prefast(disable: 322, "return value already set when except")
DWORD
SC_SizeofResource(
HANDLE hModule,
HANDLE hRsrc
)
{
DWORD dwSize = 0;
DEBUGMSG(ZONE_ENTRY,(L"SC_SizeofResource entry: %8.8lx %8.8lx\r\n",hModule,hRsrc));
if (hRsrc) {
__try {
dwSize = ((resdata_t *)hRsrc)->size;
} __except (EXCEPTION_EXECUTE_HANDLER) {
}
}
if (!dwSize) {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
}
DEBUGMSG(ZONE_ENTRY,(L"SC_SizeofResource exit: %8.8lx\r\n", dwSize));
return dwSize;
}
#pragma prefast(pop)
static HANDLE DoLoadResource(HANDLE hModule, HANDLE hRsrc)
{
DWORD pnum;
PMODULE pModRes = 0, pMod = (PMODULE) hModule;
LPBYTE BasePtr;
PPROCESS pProc = 0;
HANDLE h = 0;
if (hModule == GetCurrentProcess())
hModule = hCurProc;
if (!hRsrc) {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
return 0;
}
if (IsModCodeAddr (hRsrc) || IsInResouceSection (hRsrc)) {
// this is a resource from a module. need to handle it differently because the
// section might (and almost always) be moved.
o32_lite *optr;
int loop;
if (!(pMod = (PMODULE) hModule)) {
// find the module if hModule is NULL
EnterCriticalSection(&ModListcs);
pMod = pModList;
for (pMod = pModList; pMod; pMod = pMod->pMod)
if (((DWORD) hRsrc >= (DWORD) pMod->BasePtr)
&& ((DWORD) hRsrc < (DWORD) pMod->BasePtr+pMod->e32.e32_vsize))
break;
LeaveCriticalSection(&ModListcs);
} else if (pProc = HandleToProc (hModule)) {
pMod = pProc->pmodResource;
} else if (IsValidModule (pMod)) {
if ((pModRes = pMod->pmodResource)
&& (hRsrc >= pModRes->BasePtr)
&& ((LPBYTE) hRsrc < (LPBYTE) pModRes->BasePtr + pModRes->e32.e32_vsize)) {
pMod = pModRes;
}
}
if (!IsValidModule (pMod)) {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
return 0;
}
optr = pMod->o32_ptr;
for (loop = 0; loop < pMod->e32.e32_objcnt; loop ++, optr ++) {
if (((DWORD) hRsrc >= optr->o32_realaddr)
&& ((DWORD) hRsrc < optr->o32_realaddr + optr->o32_vsize)) {
// this is the section we're in
h = (HANDLE) (((resdata_t *)hRsrc)->rva - optr->o32_rva + optr->o32_realaddr);
break;
}
}
return h;
}
if (!hModule) {
pnum = IsSecureVa (hRsrc)? 1 : ((DWORD)hRsrc >> VA_SECTION);
DEBUGCHK (pnum <= MAX_PROCESSES);
if (pnum-- && ProcArray[pnum].dwVMBase) {
if (!pnum) {
// slot 1 address, find the real module
EnterCriticalSection(&ModListcs);
pMod = pModList;
pnum = ZeroPtr(hRsrc);
for (pMod = pModList; pMod; pMod = pMod->pMod)
if ((pnum >= ZeroPtr(pMod->BasePtr)) && (pnum < ZeroPtr(pMod->BasePtr)+pMod->e32.e32_vsize))
break;
LeaveCriticalSection(&ModListcs);
if (!pMod) {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
return 0;
}
BasePtr = MapPtrProc(pMod->BasePtr,&ProcArray[0]);
} else {
pProc = &ProcArray[pnum];
BasePtr = MapPtrProc(pProc->BasePtr, pProc);
}
} else {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
return 0;
}
} else if (pProc = HandleToProc(hModule)) { // a process
pModRes = pProc->pmodResource;
BasePtr = (LPBYTE)MapPtrProc(pProc->BasePtr, pProc);
} else if (IsValidModule(pMod)) { // a module
pModRes = pMod->pmodResource;
BasePtr = (LPBYTE)MapPtrProc(pMod->BasePtr,&ProcArray[0]);
} else {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
return 0;
}
// check if it came out of the MUI resource dll
if (pModRes
&& (ZeroPtr(hRsrc) >= ZeroPtr(pModRes->BasePtr))
&& (ZeroPtr(hRsrc) < ZeroPtr(pModRes->BasePtr)+pModRes->e32.e32_vsize)) {
BasePtr = (LPBYTE) pModRes->BasePtr;
}
h = (HANDLE) (BasePtr + ((resdata_t *)hRsrc)->rva);
if (ZeroPtr (h) >= (DWORD) DllLoadBase)
h = (HANDLE) ZeroPtr (h);
return h;
}
//------------------------------------------------------------------------------
// Win32 LoadResource
//------------------------------------------------------------------------------
HANDLE
SC_LoadResource(
HANDLE hModule,
HANDLE hRsrc
)
{
HANDLE h;
DEBUGMSG(ZONE_ENTRY,(L"SC_LoadResource entry: %8.8lx %8.8lx\r\n",hModule,hRsrc));
__try {
h = DoLoadResource (hModule, hRsrc);
} __except (EXCEPTION_EXECUTE_HANDLER) {
KSetLastError(pCurThread,ERROR_INVALID_HANDLE);
h = NULL;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_LoadResource exit: %8.8lx\r\n", h));
return h;
}
DWORD Decompress(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip);
DWORD DecompressROM(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip);
#pragma pack(2)
typedef struct {
WORD idReserved;
WORD idType;
WORD idCount;
} ICONHEADER;
typedef struct ResourceDirectory {
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
WORD wOrdinal; /* points to an RT_ICON resource */
} RESDIR;
typedef struct {
ICONHEADER ih;
RESDIR rgdir[1]; /* may really be > 1 */
} HEADER_AND_DIR, *PHEADER_AND_DIR;
BOOL ReadExtImageInfo (HANDLE hf, DWORD dwCode, DWORD cbSize, LPVOID pBuf);
static LPBYTE FindResourceSection (openexe_t *oeptr, DWORD *o32rva)
{
e32_lite e32l;
int loop;
LPBYTE lpres = NULL;
DWORD cbRead;
DWORD ftype = oeptr->filetype;
if (LoadE32 (oeptr, &e32l, NULL, NULL, TRUE) // loadE32 failed
|| !e32l.e32_unit[RES].rva) { // no resource section
return NULL;
}
if (ftype & FA_DIRECTROM) {
// 1st XIP
o32_rom *o32rp;
for (loop = 0; loop < e32l.e32_objcnt; loop++) {
o32rp = (o32_rom *)(oeptr->tocptr->ulO32Offset+loop*sizeof(o32_rom));
if ((o32rp->o32_rva == e32l.e32_unit[RES].rva) && (o32rp->o32_psize)) {
// if it's uncompressed, just directly pointing to ROM
if (!(o32rp->o32_flags & IMAGE_SCN_COMPRESSED)) {
*o32rva = o32rp->o32_rva;
return (LPBYTE) (o32rp->o32_dataptr);
}
// compressed. allocate memory to hold the resource
if (!(lpres = (LPBYTE)LocalAlloc (LMEM_FIXED, o32rp->o32_vsize))) {
return NULL;
}
cbRead = DecompressROM ((LPVOID)(o32rp->o32_dataptr), o32rp->o32_psize, lpres, o32rp->o32_vsize, 0);
if (cbRead && (cbRead != CEDECOMPRESS_FAILED)) {
// memset the rest of the section to 0 if read less than vsize
if (cbRead < o32rp->o32_vsize)
memset (lpres+cbRead, 0, o32rp->o32_vsize-cbRead);
*o32rva = o32rp->o32_rva;
return lpres;
}
break; // loop
}
}
} else if (ftype & FA_PREFIXUP) {
// BINFS
o32_lite *optr = (o32_lite *) _alloca (e32l.e32_objcnt * sizeof(o32_lite));
if (!optr
|| !ReadExtImageInfo (oeptr->hf, IOCTL_BIN_GET_O32, e32l.e32_objcnt * sizeof(o32_lite), optr)) {
// failed to get O32 info, return FALSE
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -