2003-02-08 22:25:08 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// *
|
|
|
|
// * .,-::::: .,:: .::::::::. .,:: .:
|
|
|
|
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
|
|
|
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
|
|
|
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
|
|
|
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
|
|
|
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
|
|
|
// *
|
|
|
|
// * Cxbx->Win32->CxbxKrnl->EmuX.cpp
|
|
|
|
// *
|
|
|
|
// * This file is part of the Cxbx project.
|
|
|
|
// *
|
|
|
|
// * Cxbx and Cxbe are free software; you can redistribute them
|
|
|
|
// * and/or modify them under the terms of the GNU General Public
|
|
|
|
// * License as published by the Free Software Foundation; either
|
|
|
|
// * version 2 of the license, or (at your option) any later version.
|
|
|
|
// *
|
|
|
|
// * This program is distributed in the hope that it will be useful,
|
|
|
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// * GNU General Public License for more details.
|
|
|
|
// *
|
|
|
|
// * You should have recieved a copy of the GNU General Public License
|
|
|
|
// * along with this program; see the file COPYING.
|
|
|
|
// * If not, write to the Free Software Foundation, Inc.,
|
|
|
|
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
|
|
|
// *
|
|
|
|
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
|
|
|
|
// *
|
|
|
|
// * All rights reserved
|
|
|
|
// *
|
|
|
|
// ******************************************************************
|
|
|
|
#define CXBXKRNL_INTERNAL
|
|
|
|
#define _XBOXKRNL_LOCAL_
|
|
|
|
|
|
|
|
#include "Cxbx.h"
|
|
|
|
#include "EmuX.h"
|
|
|
|
|
2003-03-07 18:22:13 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * prevent name collisions
|
|
|
|
// ******************************************************************
|
2003-02-08 22:25:08 +00:00
|
|
|
namespace xntdll
|
|
|
|
{
|
|
|
|
#include "xntdll.h"
|
|
|
|
};
|
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
using namespace win32;
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * static functions
|
|
|
|
// ******************************************************************
|
2003-02-15 22:16:14 +00:00
|
|
|
static void EmuXInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *XbeHeader);
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * func: EmuXInit
|
|
|
|
// ******************************************************************
|
2003-02-19 20:53:33 +00:00
|
|
|
CXBXKRNL_API void NTAPI EmuXInit(Xbe::LibraryVersion *LibraryVersion, DebugMode DebugConsole, char *DebugFilename, Xbe::Header *XbeHeader, uint32 XbeHeaderSize, void (*Entry)())
|
2003-02-08 22:25:08 +00:00
|
|
|
{
|
|
|
|
// ******************************************************************
|
|
|
|
// * debug console allocation (if configured)
|
|
|
|
// ******************************************************************
|
|
|
|
if(DebugConsole == DM_CONSOLE)
|
|
|
|
{
|
|
|
|
if(AllocConsole())
|
|
|
|
{
|
|
|
|
freopen("CONOUT$", "wt", stdout);
|
|
|
|
|
2003-02-15 08:56:40 +00:00
|
|
|
SetConsoleTitle("Cxbx : Kernel Debug Console");
|
2003-02-09 09:11:52 +00:00
|
|
|
|
2003-02-09 09:40:37 +00:00
|
|
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
|
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
printf("CxbxKrnl (0x%.08X): Debug console allocated.\n", GetCurrentThreadId());
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(DebugConsole == DM_FILE)
|
|
|
|
{
|
|
|
|
FreeConsole();
|
|
|
|
|
|
|
|
freopen(DebugFilename, "wt", stdout);
|
|
|
|
|
2003-02-09 08:35:33 +00:00
|
|
|
printf("EmuX (0x%.08X): Debug console allocated.\n", GetCurrentThreadId());
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * debug trace
|
|
|
|
// ******************************************************************
|
|
|
|
{
|
2003-02-09 08:35:33 +00:00
|
|
|
printf("EmuX: EmuXInit\n"
|
|
|
|
"(\n"
|
2003-02-19 20:53:33 +00:00
|
|
|
" LibraryVersion : 0x%.08X\n"
|
2003-02-09 08:35:33 +00:00
|
|
|
" DebugConsole : 0x%.08X\n"
|
|
|
|
" DebugFilename : \"%s\"\n"
|
|
|
|
" XBEHeader : 0x%.08X\n"
|
|
|
|
" XBEHeaderSize : 0x%.08X\n"
|
|
|
|
" Entry : 0x%.08X\n"
|
|
|
|
");\n",
|
2003-02-19 20:53:33 +00:00
|
|
|
LibraryVersion, DebugConsole, DebugFilename, XbeHeader, XbeHeaderSize, Entry);
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * Locate functions and install wrapper vectors
|
|
|
|
// ******************************************************************
|
|
|
|
{
|
2003-02-19 20:53:33 +00:00
|
|
|
uint32 dwLibraryVersions = XbeHeader->dwLibraryVersions;
|
|
|
|
uint32 dwHLEEntries = HLEDataBaseSize/sizeof(HLEData);
|
2003-02-15 22:48:07 +00:00
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
for(uint32 v=0;v<dwLibraryVersions;v++)
|
|
|
|
{
|
2003-02-22 07:49:02 +00:00
|
|
|
uint16 MajorVersion = LibraryVersion[v].wMajorVersion;
|
|
|
|
uint16 MinorVersion = LibraryVersion[v].wMinorVersion;
|
|
|
|
uint16 BuildVersion = LibraryVersion[v].wBuildVersion;
|
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
char szLibraryName[9] = {0};
|
|
|
|
|
|
|
|
for(uint32 c=0;c<8;c++)
|
|
|
|
szLibraryName[c] = LibraryVersion[v].szName[c];
|
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
printf("EmuX: Locating HLE Information for %s %d.%d.%d...", szLibraryName, MajorVersion, MinorVersion, BuildVersion);
|
2003-02-19 20:53:33 +00:00
|
|
|
|
|
|
|
bool found=false;
|
2003-02-22 07:49:02 +00:00
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
for(uint32 d=0;d<dwHLEEntries;d++)
|
|
|
|
{
|
2003-02-22 07:49:02 +00:00
|
|
|
if
|
|
|
|
(
|
|
|
|
BuildVersion != HLEDataBase[d].BuildVersion ||
|
|
|
|
MinorVersion != HLEDataBase[d].MinorVersion ||
|
|
|
|
MajorVersion != HLEDataBase[d].MajorVersion ||
|
|
|
|
strcmp(szLibraryName, HLEDataBase[d].Library) != 0
|
|
|
|
)
|
|
|
|
continue;
|
2003-02-15 22:48:07 +00:00
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
found = true;
|
2003-02-22 07:49:02 +00:00
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
printf("Found\n");
|
|
|
|
|
|
|
|
EmuXInstallWrappers(HLEDataBase[d].OovpaTable, HLEDataBase[d].OovpaTableSize, Entry, XbeHeader);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!found)
|
|
|
|
printf("Skipped\n");
|
|
|
|
}
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * Load the necessary pieces of XBEHeader
|
|
|
|
// ******************************************************************
|
|
|
|
{
|
2003-02-10 04:51:49 +00:00
|
|
|
Xbe::Header *MemXbeHeader = (Xbe::Header*)0x00010000;
|
|
|
|
|
2003-02-08 22:25:08 +00:00
|
|
|
uint32 old_protection = 0;
|
|
|
|
|
2003-02-10 04:51:49 +00:00
|
|
|
VirtualProtect(MemXbeHeader, 0x1000, PAGE_READWRITE, &old_protection);
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
// we sure hope we aren't corrupting anything necessary for an .exe to survive :]
|
2003-02-10 04:51:49 +00:00
|
|
|
MemXbeHeader->dwSizeofHeaders = XbeHeader->dwSizeofHeaders;
|
|
|
|
MemXbeHeader->dwCertificateAddr = XbeHeader->dwCertificateAddr;
|
|
|
|
MemXbeHeader->dwPeHeapReserve = XbeHeader->dwPeHeapReserve;
|
|
|
|
MemXbeHeader->dwPeHeapCommit = XbeHeader->dwPeHeapCommit;
|
|
|
|
|
|
|
|
memcpy(&MemXbeHeader->dwInitFlags, &XbeHeader->dwInitFlags, sizeof(XbeHeader->dwInitFlags));
|
|
|
|
|
|
|
|
memcpy((void*)XbeHeader->dwCertificateAddr, &((uint08*)XbeHeader)[XbeHeader->dwCertificateAddr - 0x00010000], sizeof(Xbe::Certificate));
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * Initialize FS system
|
|
|
|
// ******************************************************************
|
|
|
|
{
|
|
|
|
EmuXInitFS();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * Initialize FS:* structure
|
|
|
|
// ******************************************************************
|
|
|
|
{
|
|
|
|
EmuXGenerateFS();
|
|
|
|
}
|
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * Initialize Direct3D8
|
|
|
|
// ******************************************************************
|
|
|
|
{
|
|
|
|
xboxkrnl::EmuXInitD3D();
|
|
|
|
}
|
|
|
|
|
2003-02-09 08:35:33 +00:00
|
|
|
printf("EmuX (0x%.08X): Initial thread starting.\n", GetCurrentThreadId());
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
// This must be enabled or the debugger may crash (sigh)
|
2003-02-19 20:53:33 +00:00
|
|
|
// __asm _emit 0xF1
|
2003-02-09 08:35:33 +00:00
|
|
|
|
|
|
|
EmuXSwapFS(); // XBox FS
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
Entry();
|
|
|
|
|
|
|
|
EmuXSwapFS(); // Win2k/XP FS
|
|
|
|
|
2003-02-09 08:35:33 +00:00
|
|
|
printf("EmuX (0x%.08X): Initial thread ended.\n", GetCurrentThreadId());
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
2003-02-19 20:53:33 +00:00
|
|
|
while(true)
|
|
|
|
Sleep(1000);
|
|
|
|
|
2003-02-08 22:25:08 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * func: EmuXDummy
|
|
|
|
// ******************************************************************
|
|
|
|
CXBXKRNL_API void NTAPI EmuXDummy()
|
|
|
|
{
|
|
|
|
EmuXSwapFS(); // Win2k/XP FS
|
|
|
|
|
2003-02-09 08:35:33 +00:00
|
|
|
printf("EmuX (0x%.08X): EmuXDummy()\n", GetCurrentThreadId());
|
2003-02-08 22:25:08 +00:00
|
|
|
|
|
|
|
EmuXSwapFS(); // XBox FS
|
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * func: EmuXPanic
|
|
|
|
// ******************************************************************
|
|
|
|
CXBXKRNL_API void NTAPI EmuXPanic()
|
|
|
|
{
|
|
|
|
EmuXSwapFS(); // Win2k/XP FS
|
|
|
|
|
2003-02-09 08:35:33 +00:00
|
|
|
printf("EmuX (0x%.08X): EmuXPanic()\n", GetCurrentThreadId());
|
2003-02-08 22:25:08 +00:00
|
|
|
|
2003-02-21 00:07:28 +00:00
|
|
|
#ifdef _DEBUG_TRACE
|
|
|
|
MessageBox(NULL, "Kernel Panic! Process will now terminate.\n\n"
|
|
|
|
"Check debug traces for hints on the cause of this crash.", "CxbxKrnl", MB_OK | MB_ICONEXCLAMATION);
|
|
|
|
#else
|
2003-02-08 22:25:08 +00:00
|
|
|
MessageBox(NULL, "Kernel Panic! Process will now terminate.", "CxbxKrnl", MB_OK | MB_ICONEXCLAMATION);
|
2003-02-21 00:07:28 +00:00
|
|
|
#endif
|
2003-02-08 22:25:08 +00:00
|
|
|
EmuXSwapFS(); // XBox FS
|
|
|
|
}
|
|
|
|
|
2003-02-09 08:35:33 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * func: EmuXInstallWrapper
|
|
|
|
// ******************************************************************
|
|
|
|
inline void EmuXInstallWrapper(void *FunctionAddr, void *WrapperAddr)
|
|
|
|
{
|
|
|
|
uint08 *FuncBytes = (uint08*)FunctionAddr;
|
|
|
|
|
|
|
|
*(uint08*)&FuncBytes[0] = 0xE9;
|
|
|
|
*(uint32*)&FuncBytes[1] = (uint32)WrapperAddr - (uint32)FunctionAddr - 5;
|
|
|
|
}
|
|
|
|
|
2003-02-08 22:25:08 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * func: EmuXInstallWrappers
|
|
|
|
// ******************************************************************
|
2003-02-15 22:16:14 +00:00
|
|
|
void EmuXInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *XbeHeader)
|
2003-02-08 22:25:08 +00:00
|
|
|
{
|
|
|
|
// ******************************************************************
|
2003-02-15 22:16:14 +00:00
|
|
|
// * traverse the full OOVPA table
|
2003-02-08 22:25:08 +00:00
|
|
|
// ******************************************************************
|
2003-02-15 22:16:14 +00:00
|
|
|
for(uint32 a=0;a<OovpaTableSize/sizeof(OOVPATable);a++)
|
2003-02-08 22:25:08 +00:00
|
|
|
{
|
2003-02-21 04:51:03 +00:00
|
|
|
#ifdef _DEBUG_TRACE
|
|
|
|
printf("EmuXInstallWrappers: Searching for %s...", OovpaTable[a].szFuncName);
|
|
|
|
#endif
|
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
OOVPA *Oovpa = OovpaTable[a].Oovpa;
|
2003-02-09 08:35:33 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
uint32 count = Oovpa->Count;
|
|
|
|
uint32 lower = XbeHeader->dwBaseAddr;
|
|
|
|
uint32 upper = XbeHeader->dwBaseAddr + XbeHeader->dwSizeofImage;
|
2003-02-09 08:35:33 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * Large
|
|
|
|
// ******************************************************************
|
|
|
|
if(Oovpa->Large == 1)
|
|
|
|
{
|
|
|
|
LOOVPA<1> *Loovpa = (LOOVPA<1>*)Oovpa;
|
2003-02-20 08:07:52 +00:00
|
|
|
|
|
|
|
upper -= Loovpa->Lovp[count-1].Offset;
|
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
bool found = false;
|
|
|
|
|
2003-02-20 08:07:52 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * Search all of the image memory
|
|
|
|
// ******************************************************************
|
|
|
|
for(uint32 cur=lower;cur<upper;cur++)
|
|
|
|
{
|
|
|
|
uint32 v=0;
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * check all pairs, moving on if any do not match
|
|
|
|
// ******************************************************************
|
|
|
|
for(v=0;v<count;v++)
|
|
|
|
{
|
|
|
|
uint32 Offset = Loovpa->Lovp[v].Offset;
|
|
|
|
uint32 Value = Loovpa->Lovp[v].Value;
|
|
|
|
|
|
|
|
uint08 RealValue = *(uint08*)(cur + Offset);
|
|
|
|
|
|
|
|
if(RealValue != Value)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************
|
|
|
|
// * success if we found all pairs
|
|
|
|
// ******************************************************************
|
|
|
|
if(v == count)
|
|
|
|
{
|
|
|
|
#ifdef _DEBUG_TRACE
|
2003-02-21 04:51:03 +00:00
|
|
|
printf("Found! (0x%.08X)\n", cur);
|
2003-02-20 08:07:52 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
EmuXInstallWrapper((void*)cur, OovpaTable[a].lpRedirect);
|
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
found = true;
|
|
|
|
|
2003-02-20 08:07:52 +00:00
|
|
|
break;
|
|
|
|
}
|
2003-02-22 07:49:02 +00:00
|
|
|
}
|
2003-02-21 04:51:03 +00:00
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * not found
|
|
|
|
// ******************************************************************
|
|
|
|
if(!found)
|
|
|
|
{
|
|
|
|
#ifdef _DEBUG_TRACE
|
|
|
|
printf("None (OK)\n");
|
|
|
|
#endif
|
2003-02-20 08:07:52 +00:00
|
|
|
}
|
2003-02-15 22:16:14 +00:00
|
|
|
}
|
|
|
|
// ******************************************************************
|
|
|
|
// * Small
|
|
|
|
// ******************************************************************
|
|
|
|
else
|
2003-02-09 08:35:33 +00:00
|
|
|
{
|
2003-02-15 22:16:14 +00:00
|
|
|
SOOVPA<1> *Soovpa = (SOOVPA<1>*)Oovpa;
|
2003-02-15 06:54:56 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
upper -= Soovpa->Sovp[count-1].Offset;
|
2003-02-15 06:54:56 +00:00
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
bool found = false;
|
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * Search all of the image memory
|
|
|
|
// ******************************************************************
|
|
|
|
for(uint32 cur=lower;cur<upper;cur++)
|
2003-02-15 06:54:56 +00:00
|
|
|
{
|
2003-02-15 22:16:14 +00:00
|
|
|
uint32 v=0;
|
2003-02-08 22:25:08 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * check all pairs, moving on if any do not match
|
|
|
|
// ******************************************************************
|
|
|
|
for(v=0;v<count;v++)
|
2003-02-15 04:48:21 +00:00
|
|
|
{
|
2003-02-15 22:16:14 +00:00
|
|
|
uint32 Offset = Soovpa->Sovp[v].Offset;
|
|
|
|
uint32 Value = Soovpa->Sovp[v].Value;
|
2003-02-15 04:48:21 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
uint08 RealValue = *(uint08*)(cur + Offset);
|
2003-02-15 04:48:21 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
if(RealValue != Value)
|
|
|
|
break;
|
|
|
|
}
|
2003-02-15 04:48:21 +00:00
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * success if we found all pairs
|
|
|
|
// ******************************************************************
|
|
|
|
if(v == count)
|
|
|
|
{
|
|
|
|
#ifdef _DEBUG_TRACE
|
2003-02-21 04:51:03 +00:00
|
|
|
printf("Found! (0x%.08X)\n", cur);
|
2003-02-15 22:16:14 +00:00
|
|
|
#endif
|
2003-02-15 04:48:21 +00:00
|
|
|
|
2003-02-15 22:48:07 +00:00
|
|
|
EmuXInstallWrapper((void*)cur, OovpaTable[a].lpRedirect);
|
2003-02-15 04:55:31 +00:00
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
found = true;
|
|
|
|
|
2003-02-15 22:16:14 +00:00
|
|
|
break;
|
2003-02-15 04:48:21 +00:00
|
|
|
}
|
2003-02-22 07:49:02 +00:00
|
|
|
}
|
2003-02-21 04:51:03 +00:00
|
|
|
|
2003-02-22 07:49:02 +00:00
|
|
|
// ******************************************************************
|
|
|
|
// * not found
|
|
|
|
// ******************************************************************
|
|
|
|
if(!found)
|
|
|
|
{
|
|
|
|
#ifdef _DEBUG_TRACE
|
|
|
|
printf("None (OK)\n");
|
|
|
|
#endif
|
2003-02-15 04:48:21 +00:00
|
|
|
}
|
2003-02-09 08:35:33 +00:00
|
|
|
}
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|
2003-02-15 22:16:14 +00:00
|
|
|
|
2003-02-08 22:25:08 +00:00
|
|
|
}
|