Cxbx-Reloaded/Source/Win32/CxbxKrnl/Emu.cpp

857 lines
30 KiB
C++
Raw Normal View History

// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
2003-03-27 06:23:58 +00:00
// * Cxbx->Win32->CxbxKrnl->Emu.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
// *
// ******************************************************************
2003-03-07 22:01:44 +00:00
#define _CXBXKRNL_INTERNAL
#define _XBOXKRNL_LOCAL_
2003-03-07 22:01:44 +00:00
// ******************************************************************
// * prevent name collisions
// ******************************************************************
2003-04-02 02:23:30 +00:00
namespace xboxkrnl
{
2003-04-02 02:23:30 +00:00
#include <xboxkrnl/xboxkrnl.h>
};
2003-04-02 02:23:30 +00:00
#include "Emu.h"
#include "EmuFS.h"
2003-05-21 03:03:05 +00:00
// ******************************************************************
// * prevent name collisions
// ******************************************************************
2003-07-02 20:14:15 +00:00
namespace XTL
2003-05-21 03:03:05 +00:00
{
2003-07-02 20:14:15 +00:00
#include "EmuXTL.h"
2003-05-23 02:55:39 +00:00
};
2003-05-23 22:04:21 +00:00
#include <locale.h>
#include "EmuShared.h"
2003-04-02 02:23:30 +00:00
#include "HLEDataBase.h"
2003-03-27 05:56:08 +00:00
// ******************************************************************
2003-03-27 06:33:57 +00:00
// * global / static
// ******************************************************************
2003-06-05 23:42:45 +00:00
Xbe::TLS *g_pTLS = NULL;
void *g_pTLSData = NULL;
Xbe::Header *g_pXbeHeader = NULL;
HANDLE g_hCurDir = NULL;
2003-06-25 02:01:51 +00:00
HANDLE g_hTDrive = NULL;
HANDLE g_hUDrive = NULL;
2003-04-26 08:57:51 +00:00
// ******************************************************************
// * static
// ******************************************************************
2003-05-04 19:55:25 +00:00
static void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper);
static void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader);
2003-07-01 23:52:07 +00:00
static void EmuXRefFailure();
2003-05-04 19:55:25 +00:00
static int ExitException(LPEXCEPTION_POINTERS e);
2003-04-06 00:25:30 +00:00
2003-03-27 05:56:08 +00:00
// ******************************************************************
// * func: DllMain
// ******************************************************************
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if(fdwReason == DLL_PROCESS_ATTACH)
2003-04-04 03:31:43 +00:00
EmuShared::Init();
2003-03-27 05:56:08 +00:00
if(fdwReason == DLL_PROCESS_DETACH)
2003-04-04 03:31:43 +00:00
EmuShared::Cleanup();
2003-03-27 05:56:08 +00:00
return TRUE;
}
// ******************************************************************
2003-03-27 06:23:58 +00:00
// * func: EmuNoFunc
// ******************************************************************
2003-04-02 02:23:30 +00:00
extern "C" CXBXKRNL_API void NTAPI EmuNoFunc()
2003-03-27 06:23:58 +00:00
{
EmuSwapFS(); // Win2k/XP FS
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): EmuNoFunc()\n", GetCurrentThreadId());
2003-03-27 06:23:58 +00:00
EmuSwapFS(); // XBox FS
}
2003-04-27 04:56:09 +00:00
// ******************************************************************
// * func: EmuCleanThread
// ******************************************************************
2003-05-20 21:39:25 +00:00
extern "C" CXBXKRNL_API void NTAPI EmuCleanThread()
2003-04-27 04:56:09 +00:00
{
if(EmuIsXboxFS())
EmuSwapFS(); // Win2k/XP FS
EmuCleanupFS();
2003-05-03 08:29:37 +00:00
TerminateThread(GetCurrentThread(), 0);
2003-04-27 04:56:09 +00:00
}
2003-03-27 06:23:58 +00:00
// ******************************************************************
// * func: EmuInit
// ******************************************************************
2003-05-03 08:29:37 +00:00
extern "C" CXBXKRNL_API void NTAPI EmuInit
(
2003-05-04 19:55:25 +00:00
void *pTLSData,
2003-05-03 08:29:37 +00:00
Xbe::TLS *pTLS,
Xbe::LibraryVersion *pLibraryVersion,
DebugMode DbgMode,
char *szDebugFilename,
Xbe::Header *pXbeHeader,
uint32 dwXbeHeaderSize,
void (*Entry)())
{
2003-05-21 03:03:05 +00:00
g_pTLS = pTLS;
g_pTLSData = pTLSData;
g_pXbeHeader = pXbeHeader;
2003-04-06 00:25:30 +00:00
2003-05-23 22:04:21 +00:00
// For Unicode Conversions
setlocale(LC_ALL, "English");
// ******************************************************************
// * debug console allocation (if configured)
// ******************************************************************
2003-04-04 04:35:00 +00:00
if(DbgMode == 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-05-23 02:55:39 +00:00
printf("Emu (0x%X): Debug console allocated (DM_CONSOLE).\n", GetCurrentThreadId());
}
}
2003-04-04 04:35:00 +00:00
else if(DbgMode == DM_FILE)
{
FreeConsole();
2003-04-04 04:35:00 +00:00
freopen(szDebugFilename, "wt", stdout);
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Debug console allocated (DM_FILE).\n", GetCurrentThreadId());
}
2003-04-15 08:08:53 +00:00
else
{
FreeConsole();
2003-05-03 08:29:37 +00:00
char buffer[16];
if(GetConsoleTitle(buffer, 16) != NULL)
freopen("nul", "w", stdout);
2003-04-15 08:08:53 +00:00
}
// ******************************************************************
// * debug trace
// ******************************************************************
{
2003-03-28 20:14:48 +00:00
#ifdef _DEBUG_TRACE
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Debug Trace Enabled.\n", GetCurrentThreadId());
2003-03-28 20:14:48 +00:00
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): EmuInit\n"
2003-02-09 08:35:33 +00:00
"(\n"
2003-05-04 19:55:25 +00:00
" pTLSData : 0x%.08X\n"
2003-05-03 08:29:37 +00:00
" pTLS : 0x%.08X\n"
" pLibraryVersion : 0x%.08X\n"
2003-02-09 08:35:33 +00:00
" DebugConsole : 0x%.08X\n"
" DebugFilename : \"%s\"\n"
2003-05-03 08:29:37 +00:00
" pXBEHeader : 0x%.08X\n"
" pXBEHeaderSize : 0x%.08X\n"
2003-02-09 08:35:33 +00:00
" Entry : 0x%.08X\n"
");\n",
2003-05-21 03:03:05 +00:00
GetCurrentThreadId(), pTLSData, pTLS, pLibraryVersion, DbgMode, szDebugFilename, pXbeHeader, dwXbeHeaderSize, Entry);
2003-03-28 20:14:48 +00:00
#else
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Debug Trace Disabled.\n", GetCurrentThreadId());
2003-03-28 20:14:48 +00:00
#endif
}
// ******************************************************************
2003-04-08 03:34:05 +00:00
// * Load the necessary pieces of XBEHeader
// ******************************************************************
{
2003-04-08 03:34:05 +00:00
Xbe::Header *MemXbeHeader = (Xbe::Header*)0x00010000;
uint32 old_protection = 0;
VirtualProtect(MemXbeHeader, 0x1000, PAGE_READWRITE, &old_protection);
// we sure hope we aren't corrupting anything necessary for an .exe to survive :]
2003-05-03 08:29:37 +00:00
MemXbeHeader->dwSizeofHeaders = pXbeHeader->dwSizeofHeaders;
MemXbeHeader->dwCertificateAddr = pXbeHeader->dwCertificateAddr;
MemXbeHeader->dwPeHeapReserve = pXbeHeader->dwPeHeapReserve;
MemXbeHeader->dwPeHeapCommit = pXbeHeader->dwPeHeapCommit;
memcpy(&MemXbeHeader->dwInitFlags, &pXbeHeader->dwInitFlags, sizeof(pXbeHeader->dwInitFlags));
2003-04-08 03:34:05 +00:00
2003-05-03 08:29:37 +00:00
memcpy((void*)pXbeHeader->dwCertificateAddr, &((uint08*)pXbeHeader)[pXbeHeader->dwCertificateAddr - 0x00010000], sizeof(Xbe::Certificate));
2003-04-08 03:34:05 +00:00
}
// ******************************************************************
2003-05-23 02:55:39 +00:00
// * Initialize current directory
2003-04-08 03:34:05 +00:00
// ******************************************************************
2003-05-23 02:55:39 +00:00
{
char szBuffer[260];
2003-04-08 03:34:05 +00:00
2003-05-23 02:55:39 +00:00
GetModuleFileName(NULL, szBuffer, 260);
sint32 spot=-1;
for(int v=0;v<260;v++)
{
if(szBuffer[v] == '\\')
spot = v;
else if(szBuffer[v] == '\0')
break;
}
if(spot != -1)
szBuffer[spot] = '\0';
SetCurrentDirectory(szBuffer);
2003-05-28 22:54:38 +00:00
g_hCurDir = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2003-06-25 02:01:51 +00:00
if(g_hCurDir == INVALID_HANDLE_VALUE)
2003-05-28 22:54:38 +00:00
EmuCleanup("Could not map D:\\\n");
2003-05-23 02:55:39 +00:00
}
2003-04-08 03:34:05 +00:00
2003-06-25 02:01:51 +00:00
// ******************************************************************
// * Initialize T:\ and U:\ directories
// ******************************************************************
{
char szBuffer[260];
#ifdef _DEBUG
GetModuleFileName(GetModuleHandle("CxbxKrnl.dll"), szBuffer, 260);
#else
GetModuleFileName(GetModuleHandle("Cxbx.dll"), szBuffer, 260);
#endif
sint32 spot=-1;
for(int v=0;v<260;v++)
{
if(szBuffer[v] == '\\')
spot = v;
else if(szBuffer[v] == '\0')
break;
}
if(spot != -1)
szBuffer[spot] = '\0';
Xbe::Certificate *pCertificate = (Xbe::Certificate*)pXbeHeader->dwCertificateAddr;
2003-06-26 23:55:09 +00:00
// Create TData Directory
{
strcpy(&szBuffer[spot], "\\TDATA");
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
CreateDirectory(szBuffer, NULL);
2003-06-25 02:01:51 +00:00
sprintf(&szBuffer[spot+6], "\\%08x", pCertificate->dwTitleId);
CreateDirectory(szBuffer, NULL);
2003-06-26 23:55:09 +00:00
g_hTDrive = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
if(g_hTDrive == INVALID_HANDLE_VALUE)
EmuCleanup("Could not map T:\\\n");
}
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
// Create UData Directory
{
strcpy(&szBuffer[spot], "\\UDATA");
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
CreateDirectory(szBuffer, NULL);
2003-06-25 02:01:51 +00:00
sprintf(&szBuffer[spot+6], "\\%08x", pCertificate->dwTitleId);
CreateDirectory(szBuffer, NULL);
2003-06-26 23:55:09 +00:00
g_hUDrive = CreateFile(szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
if(g_hUDrive == INVALID_HANDLE_VALUE)
EmuCleanup("Could not map U:\\\n");
}
2003-06-25 02:01:51 +00:00
}
2003-04-08 03:34:05 +00:00
// ******************************************************************
// * Initialize OpenXDK emulation
// ******************************************************************
2003-05-03 08:29:37 +00:00
if(pLibraryVersion == 0)
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Detected OpenXDK application...\n", GetCurrentThreadId());
2003-04-08 03:34:05 +00:00
// ******************************************************************
// * Initialize Microsoft XDK emulation
// ******************************************************************
2003-05-03 08:29:37 +00:00
if(pLibraryVersion != 0)
2003-04-08 03:34:05 +00:00
{
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Detected Microsoft XDK application...\n", GetCurrentThreadId());
2003-04-08 03:34:05 +00:00
2003-05-03 08:29:37 +00:00
uint32 dwLibraryVersions = pXbeHeader->dwLibraryVersions;
2003-02-19 20:53:33 +00:00
uint32 dwHLEEntries = HLEDataBaseSize/sizeof(HLEData);
2003-02-15 22:48:07 +00:00
2003-07-01 23:52:07 +00:00
uint32 LastUnResolvedXRefs;
2003-07-03 05:09:28 +00:00
uint32 OrigUnResolvedXRefs = UnResolvedXRefs;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
for(int p=0;UnResolvedXRefs < LastUnResolvedXRefs;p++)
2003-02-19 20:53:33 +00:00
{
2003-07-03 05:09:28 +00:00
printf("Emu (0x%X): Beginning HLE Pass %d...\n", GetCurrentThreadId(), p);
2003-07-01 23:52:07 +00:00
LastUnResolvedXRefs = UnResolvedXRefs;
2003-02-22 07:49:02 +00:00
2003-07-01 23:52:07 +00:00
bool bFoundD3D = false;
for(uint32 v=0;v<dwLibraryVersions;v++)
{
uint16 MajorVersion = pLibraryVersion[v].wMajorVersion;
uint16 MinorVersion = pLibraryVersion[v].wMinorVersion;
uint16 BuildVersion = pLibraryVersion[v].wBuildVersion;
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
char szLibraryName[9] = {0};
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
for(uint32 c=0;c<8;c++)
szLibraryName[c] = pLibraryVersion[v].szName[c];
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
printf("Emu (0x%X): Locating HLE Information for %s %d.%d.%d...", GetCurrentThreadId(), szLibraryName, MajorVersion, MinorVersion, BuildVersion);
2003-06-25 23:55:50 +00:00
2003-07-01 23:52:07 +00:00
// TODO: HACK: These libraries are packed into one database
if(strcmp(szLibraryName, "D3DX8") == 0)
strcpy(szLibraryName, "D3D8");
2003-02-22 07:49:02 +00:00
2003-07-01 23:52:07 +00:00
if(strcmp(szLibraryName, "D3D8") == 0)
{
if(bFoundD3D)
{
printf("Redundant\n");
continue;
}
2003-02-22 07:49:02 +00:00
2003-07-01 23:52:07 +00:00
bFoundD3D = true;
}
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
bool found=false;
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
for(uint32 d=0;d<dwHLEEntries;d++)
{
if(BuildVersion != HLEDataBase[d].BuildVersion || MinorVersion != HLEDataBase[d].MinorVersion || MajorVersion != HLEDataBase[d].MajorVersion || strcmp(szLibraryName, HLEDataBase[d].Library) != 0)
continue;
2003-05-04 19:55:25 +00:00
2003-07-01 23:52:07 +00:00
found = true;
2003-05-23 02:55:39 +00:00
2003-07-01 23:52:07 +00:00
printf("Found\n");
2003-05-23 02:55:39 +00:00
2003-07-01 23:52:07 +00:00
EmuInstallWrappers(HLEDataBase[d].OovpaTable, HLEDataBase[d].OovpaTableSize, Entry, pXbeHeader);
}
2003-05-24 06:06:35 +00:00
2003-07-01 23:52:07 +00:00
if(!found)
printf("Skipped\n");
2003-06-20 16:42:31 +00:00
2003-07-03 05:09:28 +00:00
if(bXRefFirstPass)
2003-06-13 00:37:41 +00:00
{
2003-07-03 05:09:28 +00:00
if(strcmp("XAPILIB", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 && (BuildVersion == 4627 || BuildVersion == 4361 || BuildVersion == 4034 || BuildVersion == 3911))
{
2003-07-03 05:09:28 +00:00
uint32 lower = pXbeHeader->dwBaseAddr;
uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
// ******************************************************************
// * Locate XapiProcessHeap
// ******************************************************************
if(BuildVersion == 4361 || BuildVersion == 4627)
{
void *pFunc = EmuLocateFunction((OOVPA*)&XapiInitProcess_1_0_4361, lower, upper);
if(pFunc != 0)
{
XTL::EmuXapiProcessHeap = *(PVOID**)((uint32)pFunc + 0x3E);
XTL::g_pRtlCreateHeap = *(XTL::pfRtlCreateHeap*)((uint32)pFunc + 0x37);
XTL::g_pRtlCreateHeap = (XTL::pfRtlCreateHeap)((uint32)pFunc + (uint32)XTL::g_pRtlCreateHeap + 0x37 + 0x04);
printf("Emu (0x%X): 0x%.08X -> EmuXapiProcessHeap\n", GetCurrentThreadId(), XTL::EmuXapiProcessHeap);
printf("Emu (0x%X): 0x%.08X -> RtlCreateHeap\n", GetCurrentThreadId(), XTL::g_pRtlCreateHeap);
}
}
}
2003-07-03 05:09:28 +00:00
else if(strcmp("D3D8", szLibraryName) == 0 && MajorVersion == 1 && MinorVersion == 0 && (BuildVersion == 4361 || BuildVersion == 4627))
{
uint32 lower = pXbeHeader->dwBaseAddr;
uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
void *pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetRenderState_CullMode_1_0_4361, lower, upper);
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
// ******************************************************************
// * Locate D3DDeferredRenderState
// ******************************************************************
if(pFunc != 0 && (BuildVersion == 4361 || BuildVersion == 4627))
2003-07-01 23:52:07 +00:00
{
2003-07-03 05:09:28 +00:00
if(BuildVersion == 4361)
XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x200 + 82*4);
else if(BuildVersion == 4627)
XTL::EmuD3DDeferredRenderState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x2B) - 0x24C + 92*4);
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
for(int v=0;v<146;v++)
XTL::EmuD3DDeferredRenderState[v] = X_D3DRS_UNK;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
printf("Emu (0x%X): 0x%.08X -> EmuD3DDeferredRenderState\n", GetCurrentThreadId(), XTL::EmuD3DDeferredRenderState);
2003-07-01 23:52:07 +00:00
}
else
{
2003-07-03 05:09:28 +00:00
XTL::EmuD3DDeferredRenderState = 0;
printf("Emu (0x%X): *Warning* EmuD3DDeferredRenderState not found!\n", GetCurrentThreadId());
2003-07-01 23:52:07 +00:00
}
2003-07-03 05:09:28 +00:00
// ******************************************************************
// * Locate D3DDeferredTextureState
// ******************************************************************
{
if(BuildVersion == 4361)
pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4361, lower, upper);
else if(BuildVersion == 4627)
pFunc = EmuLocateFunction((OOVPA*)&IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4627, lower, upper);
if(pFunc != 0)
{
XTL::EmuD3DDeferredTextureState = (DWORD*)(*(DWORD*)((uint32)pFunc + 0x19) - 0x70);
for(int v=0;v<32*4;v++)
XTL::EmuD3DDeferredTextureState[v] = X_D3DTSS_UNK;
printf("Emu (0x%X): 0x%.08X -> EmuD3DDeferredTextureState\n", GetCurrentThreadId(), XTL::EmuD3DDeferredTextureState);
}
else
{
XTL::EmuD3DDeferredTextureState = 0;
printf("Emu (0x%X): *Warning* EmuD3DDeferredTextureState not found!\n", GetCurrentThreadId());
}
}
}
}
2003-07-01 23:52:07 +00:00
}
bXRefFirstPass = false;
2003-02-19 20:53:33 +00:00
}
2003-07-01 23:52:07 +00:00
// ******************************************************************
// * Display XRef Summary
// ******************************************************************
2003-07-03 05:09:28 +00:00
printf("Emu (0x%X): Resolved %d cross reference(s)\n", GetCurrentThreadId(), OrigUnResolvedXRefs - UnResolvedXRefs);
}
2003-05-23 02:55:39 +00:00
// ******************************************************************
// * Initialize FS Emulation
// ******************************************************************
{
EmuInitFS();
EmuGenerateFS(pTLS, pTLSData);
}
printf("Emu (0x%X): Initializing Direct3D.\n", GetCurrentThreadId());
2003-07-02 20:14:15 +00:00
XTL::EmuD3DInit(pXbeHeader, dwXbeHeaderSize);
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Initial thread starting.\n", GetCurrentThreadId());
2003-04-08 03:34:05 +00:00
// ******************************************************************
2003-04-08 03:34:05 +00:00
// * Entry Point
// ******************************************************************
2003-04-08 03:34:05 +00:00
__try
{
2003-04-08 03:34:05 +00:00
EmuSwapFS(); // XBox FS
2003-06-18 05:15:02 +00:00
// _USE_XGMATH Disabled in mesh :[
2003-07-03 05:09:28 +00:00
_asm int 3
2003-06-16 16:43:50 +00:00
2003-05-30 02:08:25 +00:00
Entry();
2003-04-08 03:34:05 +00:00
EmuSwapFS(); // Win2k/XP FS
}
2003-04-08 03:34:05 +00:00
__except(EmuException(GetExceptionInformation()))
{
2003-04-08 03:34:05 +00:00
printf("Emu: WARNING!! Problem with ExceptionFilter\n");
}
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): Initial thread ended.\n", GetCurrentThreadId());
fflush(stdout);
2003-04-27 04:56:09 +00:00
EmuCleanThread();
2003-04-26 07:30:21 +00:00
2003-04-27 04:56:09 +00:00
return;
2003-04-26 07:30:21 +00:00
}
2003-04-16 19:06:20 +00:00
// ******************************************************************
// * func: EmuCleanup
// ******************************************************************
2003-06-10 08:18:43 +00:00
extern "C" CXBXKRNL_API void NTAPI EmuCleanup(const char *szErrorMessage, ...)
2003-04-16 19:06:20 +00:00
{
2003-04-26 08:57:51 +00:00
// ******************************************************************
// * Print out ErrorMessage (if exists)
// ******************************************************************
if(szErrorMessage != NULL)
{
2003-06-10 08:18:43 +00:00
char szBuffer1[255];
char szBuffer2[255];
2003-04-26 08:57:51 +00:00
2003-06-10 08:18:43 +00:00
va_list argp;
2003-04-26 08:57:51 +00:00
2003-06-10 08:18:43 +00:00
sprintf(szBuffer1, "Emu (0x%X): Recieved Fatal Message -> \n\n", GetCurrentThreadId());
2003-04-26 08:57:51 +00:00
2003-06-10 08:18:43 +00:00
va_start(argp, szErrorMessage);
vsprintf(szBuffer2, szErrorMessage, argp);
va_end(argp);
strcat(szBuffer1, szBuffer2);
printf("%s\n", szBuffer1);
2003-06-10 08:18:43 +00:00
MessageBox(NULL, szBuffer1, "CxbxKrnl", MB_OK | MB_ICONEXCLAMATION);
2003-04-26 08:57:51 +00:00
}
2003-05-02 05:43:21 +00:00
printf("CxbxKrnl: Terminating Process\n");
fflush(stdout);
2003-05-02 02:42:29 +00:00
// ******************************************************************
// * Cleanup debug output
// ******************************************************************
{
FreeConsole();
2003-05-03 08:29:37 +00:00
char buffer[16];
2003-05-02 02:42:29 +00:00
2003-05-03 08:29:37 +00:00
if(GetConsoleTitle(buffer, 16) != NULL)
freopen("nul", "w", stdout);
2003-04-27 23:08:42 +00:00
}
2003-04-16 19:06:20 +00:00
2003-05-03 08:29:37 +00:00
TerminateProcess(GetCurrentProcess(), 0);
2003-04-16 19:06:20 +00:00
return;
}
// ******************************************************************
2003-03-27 06:23:58 +00:00
// * func: EmuPanic
// ******************************************************************
2003-04-02 02:23:30 +00:00
extern "C" CXBXKRNL_API void NTAPI EmuPanic()
{
2003-04-12 11:21:35 +00:00
if(EmuIsXboxFS())
EmuSwapFS(); // Win2k/XP FS
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): EmuPanic()\n", GetCurrentThreadId());
2003-04-26 04:32:46 +00:00
EmuCleanup("Kernel Panic!");
2003-04-12 11:21:35 +00:00
2003-03-27 06:23:58 +00:00
EmuSwapFS(); // XBox FS
}
2003-02-09 08:35:33 +00:00
// ******************************************************************
2003-03-27 06:23:58 +00:00
// * func: EmuInstallWrapper
2003-02-09 08:35:33 +00:00
// ******************************************************************
2003-03-27 06:23:58 +00:00
inline void EmuInstallWrapper(void *FunctionAddr, void *WrapperAddr)
2003-02-09 08:35:33 +00:00
{
uint08 *FuncBytes = (uint08*)FunctionAddr;
*(uint08*)&FuncBytes[0] = 0xE9;
*(uint32*)&FuncBytes[1] = (uint32)WrapperAddr - (uint32)FunctionAddr - 5;
}
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * func: EmuLocateFunction
// ******************************************************************
2003-05-04 19:55:25 +00:00
void *EmuLocateFunction(OOVPA *Oovpa, uint32 lower, uint32 upper)
{
2003-05-04 19:55:25 +00:00
uint32 count = Oovpa->Count;
2003-07-01 23:52:07 +00:00
// Skip out if this is an unnecessary search
if(!bXRefFirstPass && Oovpa->XRefCount == 0 && Oovpa->XRefSaveIndex == (uint08)-1)
return 0;
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * Large
// ******************************************************************
2003-05-04 19:55:25 +00:00
if(Oovpa->Large == 1)
{
2003-05-04 19:55:25 +00:00
LOOVPA<1> *Loovpa = (LOOVPA<1>*)Oovpa;
2003-02-21 04:51:03 +00:00
2003-05-04 19:55:25 +00:00
upper -= Loovpa->Lovp[count-1].Offset;
2003-02-09 08:35:33 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * Search all of the image memory
// ******************************************************************
2003-05-04 19:55:25 +00:00
for(uint32 cur=lower;cur<upper;cur++)
{
2003-07-01 23:52:07 +00:00
uint32 v;
// ******************************************************************
// * check all cross references
// ******************************************************************
for(v=0;v<Loovpa->XRefCount;v++)
{
uint32 Offset = Loovpa->Lovp[v].Offset;
uint32 Value = Loovpa->Lovp[v].Value;
uint32 RealValue = *(uint32*)(cur + Offset);
if(XRefDataBase[Value] == -1)
2003-07-03 05:09:28 +00:00
goto skipout_L; // Unsatisfied XRef is not acceptable
2003-07-01 23:52:07 +00:00
if(RealValue + cur + Offset+4 != XRefDataBase[Value])
break;
}
2003-02-22 07:49:02 +00:00
2003-02-20 08:07:52 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * check all pairs, moving on if any do not match
2003-02-20 08:07:52 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
for(v=0;v<count;v++)
2003-02-20 08:07:52 +00:00
{
2003-05-04 19:55:25 +00:00
uint32 Offset = Loovpa->Lovp[v].Offset;
uint32 Value = Loovpa->Lovp[v].Value;
2003-02-20 08:07:52 +00:00
2003-05-04 19:55:25 +00:00
uint08 RealValue = *(uint08*)(cur + Offset);
2003-02-22 07:49:02 +00:00
2003-05-04 19:55:25 +00:00
if(RealValue != Value)
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
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * success if we found all pairs
2003-02-22 07:49:02 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
if(v == count)
2003-07-01 23:52:07 +00:00
{
2003-07-03 05:09:28 +00:00
if(Loovpa->XRefSaveIndex != (uint08)-1)
2003-07-01 23:52:07 +00:00
{
2003-07-03 05:09:28 +00:00
if(XRefDataBase[Loovpa->XRefSaveIndex] == -1)
{
UnResolvedXRefs--;
XRefDataBase[Loovpa->XRefSaveIndex] = cur;
return (void*)cur;
}
else
return 0; // Already Found, no bother patching again
2003-07-01 23:52:07 +00:00
}
2003-05-04 19:55:25 +00:00
return (void*)cur;
2003-07-01 23:52:07 +00:00
}
2003-07-03 05:09:28 +00:00
skipout_L:;
}
2003-05-04 19:55:25 +00:00
}
// ******************************************************************
// * Small
// ******************************************************************
else
{
SOOVPA<1> *Soovpa = (SOOVPA<1>*)Oovpa;
upper -= Soovpa->Sovp[count-1].Offset;
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * Search all of the image memory
// ******************************************************************
2003-05-04 19:55:25 +00:00
for(uint32 cur=lower;cur<upper;cur++)
2003-02-09 08:35:33 +00:00
{
2003-07-01 23:52:07 +00:00
uint32 v;
// ******************************************************************
// * check all cross references
// ******************************************************************
for(v=0;v<Soovpa->XRefCount;v++)
{
uint32 Offset = Soovpa->Sovp[v].Offset;
uint32 Value = Soovpa->Sovp[v].Value;
uint32 RealValue = *(uint32*)(cur + Offset);
if(XRefDataBase[Value] == -1)
2003-07-03 05:09:28 +00:00
goto skipout_S; // Unsatisfied XRef is not acceptable
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
if( (RealValue + cur + Offset + 4 != XRefDataBase[Value]))
2003-07-01 23:52:07 +00:00
break;
}
2003-02-22 07:49:02 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * check all pairs, moving on if any do not match
// ******************************************************************
2003-07-01 23:52:07 +00:00
for(;v<count;v++)
2003-02-15 06:54:56 +00:00
{
2003-05-04 19:55:25 +00:00
uint32 Offset = Soovpa->Sovp[v].Offset;
uint32 Value = Soovpa->Sovp[v].Value;
2003-05-04 19:55:25 +00:00
uint08 RealValue = *(uint08*)(cur + Offset);
2003-05-04 19:55:25 +00:00
if(RealValue != Value)
break;
}
2003-05-04 19:55:25 +00:00
// ******************************************************************
// * success if we found all pairs
// ******************************************************************
if(v == count)
2003-07-01 23:52:07 +00:00
{
if(Soovpa->XRefSaveIndex != (uint08)-1)
{
2003-07-03 05:09:28 +00:00
if(XRefDataBase[Soovpa->XRefSaveIndex] == -1)
{
UnResolvedXRefs--;
XRefDataBase[Soovpa->XRefSaveIndex] = cur;
return (void*)cur;
}
else
return 0; // Already Found, no bother patching again
2003-07-01 23:52:07 +00:00
}
2003-05-04 19:55:25 +00:00
return (void*)cur;
2003-07-01 23:52:07 +00:00
}
2003-07-03 05:09:28 +00:00
skipout_S:;
2003-05-04 19:55:25 +00:00
}
}
2003-05-04 19:55:25 +00:00
return 0;
}
2003-05-04 19:55:25 +00:00
// ******************************************************************
// * func: EmuInstallWrappers
// ******************************************************************
void EmuInstallWrappers(OOVPATable *OovpaTable, uint32 OovpaTableSize, void (*Entry)(), Xbe::Header *pXbeHeader)
{
uint32 lower = pXbeHeader->dwBaseAddr;
uint32 upper = pXbeHeader->dwBaseAddr + pXbeHeader->dwSizeofImage;
2003-02-15 04:55:31 +00:00
2003-05-04 19:55:25 +00:00
// ******************************************************************
// * traverse the full OOVPA table
// ******************************************************************
for(uint32 a=0;a<OovpaTableSize/sizeof(OOVPATable);a++)
{
OOVPA *Oovpa = OovpaTable[a].Oovpa;
2003-02-21 04:51:03 +00:00
2003-05-04 19:55:25 +00:00
void *pFunc = EmuLocateFunction(Oovpa, lower, upper);
if(pFunc != 0)
{
#ifdef _DEBUG_TRACE
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): 0x%.08X -> %s\n", GetCurrentThreadId(), pFunc, OovpaTable[a].szFuncName);
2003-05-04 19:55:25 +00:00
#endif
2003-07-01 23:52:07 +00:00
if(OovpaTable[a].lpRedirect == 0)
EmuInstallWrapper(pFunc, EmuXRefFailure);
else
EmuInstallWrapper(pFunc, OovpaTable[a].lpRedirect);
2003-05-04 19:55:25 +00:00
}
}
2003-04-08 03:34:05 +00:00
}
2003-07-01 23:52:07 +00:00
// ******************************************************************
// * func: EmuXRefFailure
// ******************************************************************
void EmuXRefFailure()
{
EmuSwapFS(); // Win2k/XP FS
2003-07-03 05:09:28 +00:00
_asm int 3
2003-07-01 23:52:07 +00:00
EmuCleanup("XRef-only function body reached. Fatal Error.");
}
2003-04-08 03:34:05 +00:00
// ******************************************************************
// * func: EmuException
2003-04-25 23:49:58 +00:00
// ******************************************************************
2003-04-08 03:34:05 +00:00
int EmuException(LPEXCEPTION_POINTERS e)
{
2003-06-26 23:55:09 +00:00
if(EmuIsXboxFS())
EmuSwapFS();
2003-05-30 02:08:25 +00:00
// ******************************************************************
2003-04-25 23:49:58 +00:00
// * Debugging Information
// ******************************************************************
{
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): * * * * * EXCEPTION * * * * *\n", GetCurrentThreadId());
2003-06-13 00:37:41 +00:00
printf("Emu (0x%X): Recieved Exception [0x%.08X]@0x%.08X\n", GetCurrentThreadId(), e->ExceptionRecord->ExceptionCode, e->ContextRecord->Eip);
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): * * * * * EXCEPTION * * * * *\n", GetCurrentThreadId());
2003-04-25 23:49:58 +00:00
}
2003-06-19 05:37:16 +00:00
fflush(stdout);
2003-04-25 23:49:58 +00:00
// ******************************************************************
// * Notify User
// ******************************************************************
{
char buffer[256];
2003-06-13 00:37:41 +00:00
sprintf(buffer, "Recieved Exception [0x%.08X]@0x%.08X\n\nPress 'OK' to terminate emulation.\nPress 'Cancel' to debug.", e->ExceptionRecord->ExceptionCode, e->ContextRecord->Eip);
2003-04-25 23:49:58 +00:00
2003-07-02 20:14:15 +00:00
if(MessageBox(XTL::g_hEmuWindow, buffer, "Cxbx", MB_ICONSTOP | MB_OKCANCEL) == IDOK)
2003-04-25 23:49:58 +00:00
ExitProcess(1);
2003-04-25 16:55:24 +00:00
}
2003-04-08 03:34:05 +00:00
return EXCEPTION_CONTINUE_SEARCH;
}
2003-04-27 23:08:42 +00:00
// ******************************************************************
// * func: ExitException
// ******************************************************************
int ExitException(LPEXCEPTION_POINTERS e)
{
2003-06-26 23:55:09 +00:00
if(EmuIsXboxFS())
EmuSwapFS();
2003-04-27 23:08:42 +00:00
static int count = 0;
// ******************************************************************
// * Debugging Information
// ******************************************************************
{
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): * * * * * EXCEPTION * * * * *\n", GetCurrentThreadId());
2003-06-13 00:37:41 +00:00
printf("Emu (0x%X): Recieved Exception [0x%.08X]@0x%.08X\n", GetCurrentThreadId(), e->ExceptionRecord->ExceptionCode, e->ContextRecord->Eip);
2003-05-23 02:55:39 +00:00
printf("Emu (0x%X): * * * * * EXCEPTION * * * * *\n", GetCurrentThreadId());
2003-04-27 23:08:42 +00:00
}
2003-06-19 05:37:16 +00:00
fflush(stdout);
2003-07-02 20:14:15 +00:00
MessageBox(XTL::g_hEmuWindow, "Warning: Could not safely terminate process!", "Cxbx", MB_OK);
2003-04-29 03:30:58 +00:00
2003-04-27 23:08:42 +00:00
count++;
if(count > 1)
{
2003-07-02 20:14:15 +00:00
MessageBox(XTL::g_hEmuWindow, "Warning: Multiple Problems!", "Cxbx", MB_OK);
2003-04-27 23:08:42 +00:00
return EXCEPTION_CONTINUE_SEARCH;
}
ExitProcess(1);
return EXCEPTION_CONTINUE_SEARCH;
}