From 68a328bd3a21dfb01cbb54ca82b5b278d1341a37 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Sun, 26 Jan 2003 06:18:56 +0000 Subject: [PATCH] First GNU Release !! --- Bin/Debug/dir.txt | 1 + Bin/dir.txt | 1 + Cxbe.dsp | 157 +++ Cxbx.dsp | 221 ++++ Cxbx.dsw | 56 + CxbxKrnl.dsp | 131 +++ Doc/Changelog.txt | 140 +++ Doc/Thanks.txt | 1 + Doc/Todo.txt | 17 + Include/Core/Error.h | 84 ++ Include/Core/Exe.h | 275 +++++ Include/Core/Xbe.h | 324 ++++++ Include/Cxbx.h | 75 ++ Include/Linux/AlignPosfix1.h | 42 + Include/Linux/AlignPrefix1.h | 41 + Include/Win32/AlignPosfix1.h | 42 + Include/Win32/AlignPrefix1.h | 47 + Include/Win32/Cxbx/EmuExe.h | 51 + Include/Win32/Cxbx/Prolog.h | 42 + Include/Win32/Cxbx/Wnd.h | 72 ++ Include/Win32/Cxbx/WndAbout.h | 56 + Include/Win32/Cxbx/WndMain.h | 86 ++ Include/Win32/CxbxKrnl/Kernel.h | 83 ++ Include/Win32/CxbxKrnl/xntdll.h | 149 +++ Makefile | 68 ++ PostBuild/upxCxbx.bat | 2 + Resource/Cxbx.ico | Bin 0 -> 2238 bytes Resource/Cxbx.rc | 137 +++ Resource/Logo.bmp | Bin 0 -> 188 bytes Resource/Splash.bmp | Bin 0 -> 153656 bytes Resource/resource.h | 36 + Source/Core/Error.cpp | 67 ++ Source/Core/Exe.cpp | 310 +++++ Source/Core/Xbe.cpp | 1500 +++++++++++++++++++++++++ Source/Standard/Cxbe/Main.cpp | 318 ++++++ Source/Win32/Cxbx/EmuExe.cpp | 567 ++++++++++ Source/Win32/Cxbx/Prolog.cpp | 66 ++ Source/Win32/Cxbx/WinMain.cpp | 56 + Source/Win32/Cxbx/Wnd.cpp | 177 +++ Source/Win32/Cxbx/WndAbout.cpp | 184 +++ Source/Win32/Cxbx/WndMain.cpp | 1183 +++++++++++++++++++ Source/Win32/CxbxKrnl/Kernel.cpp | 151 +++ Source/Win32/CxbxKrnl/KernelThunk.cpp | 420 +++++++ 43 files changed, 7436 insertions(+) create mode 100644 Bin/Debug/dir.txt create mode 100644 Bin/dir.txt create mode 100644 Cxbe.dsp create mode 100644 Cxbx.dsp create mode 100644 Cxbx.dsw create mode 100644 CxbxKrnl.dsp create mode 100644 Doc/Changelog.txt create mode 100644 Doc/Thanks.txt create mode 100644 Doc/Todo.txt create mode 100644 Include/Core/Error.h create mode 100644 Include/Core/Exe.h create mode 100644 Include/Core/Xbe.h create mode 100644 Include/Cxbx.h create mode 100644 Include/Linux/AlignPosfix1.h create mode 100644 Include/Linux/AlignPrefix1.h create mode 100644 Include/Win32/AlignPosfix1.h create mode 100644 Include/Win32/AlignPrefix1.h create mode 100644 Include/Win32/Cxbx/EmuExe.h create mode 100644 Include/Win32/Cxbx/Prolog.h create mode 100644 Include/Win32/Cxbx/Wnd.h create mode 100644 Include/Win32/Cxbx/WndAbout.h create mode 100644 Include/Win32/Cxbx/WndMain.h create mode 100644 Include/Win32/CxbxKrnl/Kernel.h create mode 100644 Include/Win32/CxbxKrnl/xntdll.h create mode 100644 Makefile create mode 100644 PostBuild/upxCxbx.bat create mode 100644 Resource/Cxbx.ico create mode 100644 Resource/Cxbx.rc create mode 100644 Resource/Logo.bmp create mode 100644 Resource/Splash.bmp create mode 100644 Resource/resource.h create mode 100644 Source/Core/Error.cpp create mode 100644 Source/Core/Exe.cpp create mode 100644 Source/Core/Xbe.cpp create mode 100644 Source/Standard/Cxbe/Main.cpp create mode 100644 Source/Win32/Cxbx/EmuExe.cpp create mode 100644 Source/Win32/Cxbx/Prolog.cpp create mode 100644 Source/Win32/Cxbx/WinMain.cpp create mode 100644 Source/Win32/Cxbx/Wnd.cpp create mode 100644 Source/Win32/Cxbx/WndAbout.cpp create mode 100644 Source/Win32/Cxbx/WndMain.cpp create mode 100644 Source/Win32/CxbxKrnl/Kernel.cpp create mode 100644 Source/Win32/CxbxKrnl/KernelThunk.cpp diff --git a/Bin/Debug/dir.txt b/Bin/Debug/dir.txt new file mode 100644 index 000000000..398ac7722 --- /dev/null +++ b/Bin/Debug/dir.txt @@ -0,0 +1 @@ +This directory holds debug mode output binaries. \ No newline at end of file diff --git a/Bin/dir.txt b/Bin/dir.txt new file mode 100644 index 000000000..c8097bb17 --- /dev/null +++ b/Bin/dir.txt @@ -0,0 +1 @@ +This directory holds release mode output binaries. \ No newline at end of file diff --git a/Cxbe.dsp b/Cxbe.dsp new file mode 100644 index 000000000..edf1a7c6f --- /dev/null +++ b/Cxbe.dsp @@ -0,0 +1,157 @@ +# Microsoft Developer Studio Project File - Name="Cxbe" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 60000 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Cxbe - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Cxbe.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Cxbe.mak" CFG="Cxbe - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Cxbe - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Cxbe - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Cxbe - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Bin" +# PROP Intermediate_Dir "Bin" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "Include" /I "Include/Standard" /I "Include/Standard/Cxbe" /I "Include/Win32/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Cxbe - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Bin/Debug" +# PROP Intermediate_Dir "Bin/Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "Include" /I "Include/Standard" /I "Include/Standard/Cxbe" /I "Include/Win32/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Cxbe - Win32 Release" +# Name "Cxbe - Win32 Debug" +# Begin Group "Bin" + +# PROP Default_Filter "" +# Begin Group "Debug" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Bin\Debug\Cxbe.exe +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Bin\Cxbe.exe +# End Source File +# End Group +# Begin Group "Doc" + +# PROP Default_Filter "" +# End Group +# Begin Group "Include" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Include\Win32\AlignPosfix1.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\AlignPrefix1.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Cxbx.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Core\Error.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Core\Exe.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Core\Xbe.h +# End Source File +# End Group +# Begin Group "Resource" + +# PROP Default_Filter "" +# End Group +# Begin Group "Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Source\Core\Error.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Core\Exe.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Standard\Cxbe\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Core\Xbe.cpp +# End Source File +# End Group +# End Target +# End Project diff --git a/Cxbx.dsp b/Cxbx.dsp new file mode 100644 index 000000000..0315e3397 --- /dev/null +++ b/Cxbx.dsp @@ -0,0 +1,221 @@ +# Microsoft Developer Studio Project File - Name="Cxbx" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 60000 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=Cxbx - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Cxbx.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Cxbx.mak" CFG="Cxbx - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Cxbx - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "Cxbx - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Cxbx - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Bin" +# PROP Intermediate_Dir "Bin" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "Include" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /I "Include/Win32/Cxbx" /I "Resource" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=cd PostBuild upxCxbx.bat +# End Special Build Tool + +!ELSEIF "$(CFG)" == "Cxbx - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Bin\Debug" +# PROP Intermediate_Dir "Bin\Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "Include" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /I "Include/Win32/Cxbx" /I "Resource" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Cxbx - Win32 Release" +# Name "Cxbx - Win32 Debug" +# Begin Group "Bin" + +# PROP Default_Filter "" +# Begin Group "Debug" + +# PROP Default_Filter "" +# End Group +# End Group +# Begin Group "Doc" + +# PROP Default_Filter "" +# End Group +# Begin Group "Include" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Include\Win32\AlignPosfix1.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\AlignPrefix1.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Cxbx.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\Cxbx\EmuExe.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Core\Error.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Core\Exe.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\CxbxKrnl\Kernel.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\Cxbx\Prolog.h +# End Source File +# Begin Source File + +SOURCE=.\Resource\resource.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\Cxbx\Wnd.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\Cxbx\WndAbout.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\Cxbx\WndMain.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Core\Xbe.h +# End Source File +# End Group +# Begin Group "Resource" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Resource\Cxbx.ico +# End Source File +# Begin Source File + +SOURCE=.\Resource\Cxbx.rc +# End Source File +# Begin Source File + +SOURCE=.\Resource\Logo.bmp +# End Source File +# Begin Source File + +SOURCE=.\Resource\Splash.bmp +# End Source File +# End Group +# Begin Group "Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Source\Win32\Cxbx\EmuExe.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Core\Error.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Core\Exe.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Win32\Cxbx\Prolog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Win32\Cxbx\WinMain.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Win32\Cxbx\Wnd.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Win32\Cxbx\WndAbout.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Win32\Cxbx\WndMain.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Core\Xbe.cpp +# End Source File +# End Group +# End Target +# End Project diff --git a/Cxbx.dsw b/Cxbx.dsw new file mode 100644 index 000000000..2de057b28 --- /dev/null +++ b/Cxbx.dsw @@ -0,0 +1,56 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Cxbe"=.\Cxbe.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "Cxbx"=.\Cxbx.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name CxbxKrnl + End Project Dependency +}}} + +############################################################################### + +Project: "CxbxKrnl"=.\CxbxKrnl.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CxbxKrnl.dsp b/CxbxKrnl.dsp new file mode 100644 index 000000000..32c7cd816 --- /dev/null +++ b/CxbxKrnl.dsp @@ -0,0 +1,131 @@ +# Microsoft Developer Studio Project File - Name="CxbxKrnl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 60000 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=CxbxKrnl - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "CxbxKrnl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "CxbxKrnl.mak" CFG="CxbxKrnl - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CxbxKrnl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "CxbxKrnl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "CxbxKrnl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "CxbxKrnl___Win32_Release" +# PROP BASE Intermediate_Dir "CxbxKrnl___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Bin" +# PROP Intermediate_Dir "Bin" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "Include" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Bin/Cxbx.dll" + +!ELSEIF "$(CFG)" == "CxbxKrnl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Bin\Debug" +# PROP Intermediate_Dir "Bin\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "Include" /I "Include/Win32/" /I "Include/Win32/Cxbxkrnl" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CXBXKRNL_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Bin\Debug/Cxbx.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "CxbxKrnl - Win32 Release" +# Name "CxbxKrnl - Win32 Debug" +# Begin Group "Bin" + +# PROP Default_Filter "" +# Begin Group "Debug" + +# PROP Default_Filter "" +# End Group +# End Group +# Begin Group "Doc" + +# PROP Default_Filter "" +# End Group +# Begin Group "Include" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Include\Win32\CxbxKrnl\Kernel.h +# End Source File +# Begin Source File + +SOURCE=.\Include\Win32\CxbxKrnl\xntdll.h +# End Source File +# End Group +# Begin Group "Resource" + +# PROP Default_Filter "" +# End Group +# Begin Group "Source" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Source\Win32\CxbxKrnl\Kernel.cpp +# End Source File +# Begin Source File + +SOURCE=.\Source\Win32\CxbxKrnl\KernelThunk.cpp +# End Source File +# End Group +# End Target +# End Project diff --git a/Doc/Changelog.txt b/Doc/Changelog.txt new file mode 100644 index 000000000..d0bd131f4 --- /dev/null +++ b/Doc/Changelog.txt @@ -0,0 +1,140 @@ +cxbx website: http://www.caustik.com/xbox/ + +version: 0.6.0 (??/??/03) +-------------------------------- + +- Released source code under GNU license. + +- Beginning HLE process. + +- Debugging interface changed. Much cleaner. + +version: 0.5.2 (12/14/02) +-------------------------------- + +- Fixed a bug in section name generation. This might + add some compatibility, not sure yet. + +version: 0.5.1 (??/??/??) +-------------------------------- + +- more .xbe information added to core and xbe dump + +version: 0.5.0 (11/16/02) +-------------------------------- + +- fixed a bug in displaying section digests. + +- added conversion from .exe to .xbe!! + +- more code cleanup, tiny ui improvements. + +version: 0.4.4 (11/01/02) +-------------------------------- + +- updated .xbe structure for more acccuracy + +- added/fixed alot of information in xbe info + dumps. most notably is the TLS information, + which is finally completely correct. + +- lots and lots of new kernel function prototypes + and structs/enums are very accurate now. + +version: 0.4.3 (10/09/02) +-------------------------------- + +- added edit menu options to patch for allowing + more than 64mb of ram, and also to toggle between + debug mode / release mode. i also fixed a few + relatively minor gui things, such as suggesting + an appropriate name for saving an .xbe file, instead + of just defaulting to "default.xbe". + +version: 0.4.2 (10/07/02) +-------------------------------- + +- finally got around to adding logo bitmap import + feature. this is pretty damn cool because you + can change that little logo that appears when + you boot your xbox software to whatever you want + it to be. for example, you can modify xbox media + player to display "XBMP" instead of "Microsoft" + +version: 0.4.1 (10/04/02) +-------------------------------- + +- internally alot of little things have changed, + code is organized pretty well now. software run + through the emulator typically safely terminates, + which is pretty damn cool from my perspective. + +version: 0.4.0 (BETA) (09/16/02) +-------------------------------- + +- total code rewrite. most the funcionality + has remained intact with cleaner code UI + and code design. + +- logo bitmap is now decoded and displayed + in the main window when you open an .xbe + file. debug output window traces kernel + calls. logo bitmap can be exported to a + bitmap file. + +- xbe_info.txt now displays the correctly + decoded kernel thunk table address. + +version: 0.3.1 (09/02/2002) +-------------------------------- + +- significantly decreased file sizes for cxbx.exe + and cxbx_krnl.dll. Also made debug output cleaner. + +version: 0.3.0 (08/19/2002) +-------------------------------- + +- various gui changes, new web site, significant + changes in emulation theory. kernel exports are + now hijacked and interpretted. + +version: 0.2.2 (07/24/2002) +--------------------------- + +- fixed various minor GUI problems + +- added kernel thunk address description in GUI + +version: 0.2.1 (07/24/2002) +--------------------------- + +- added "Convert To .EXE" menu option. + +- fixed problem where entry point wasn't being detected + correctly when converting to .exe + +version: 0.2.0 (07/24/2002) +--------------------------- + +- drastically changed UI, took out convert to .exe + feature (temporarily). + +version: 0.1.3b(07/18/2002) +--------------------------- + +- oops..fixed an incorrect debug xor value + +version: 0.1.3 (07/16/2002) +--------------------------- + +- .xbe file information dump now shows retail/debug + translated addresses. + +version: 0.1.2 (07/16/2002) +--------------------------- + +- cxbx now dumps .xbe file information in a .txt file. + +- new icon ? + +- various tiny improvements \ No newline at end of file diff --git a/Doc/Thanks.txt b/Doc/Thanks.txt new file mode 100644 index 000000000..c640e19fe --- /dev/null +++ b/Doc/Thanks.txt @@ -0,0 +1 @@ +Special Thanks to the authors of UPX file compressor (http://upx.sourceforge.net/). \ No newline at end of file diff --git a/Doc/Todo.txt b/Doc/Todo.txt new file mode 100644 index 000000000..4142819bb --- /dev/null +++ b/Doc/Todo.txt @@ -0,0 +1,17 @@ +Cxbx Todo: + + General Code Cleanup [caustik] + + Exe->Xbe should use an "OpenXDK" logo bitmap by default. This can be done + by having a debug version of Cxbx output the necessary raw data. Then, you + just inline it into the code. + + Allow a logo bitmap to be added if one does not exist. This may require that + the size of headers be increased. (sizeof_headers). + + When loading a file, menus and WM_CLOSE should be disabled and an update + progress should be sent via callback from core. + + Xbe::m_Header should be allocated dynamically to make room for huge headers. + + TLS needs to be implemented. diff --git a/Include/Core/Error.h b/Include/Core/Error.h new file mode 100644 index 000000000..62f578ae1 --- /dev/null +++ b/Include/Core/Error.h @@ -0,0 +1,84 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Core->Error.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef ERROR_H +#define ERROR_H + +// ****************************************************************** +// * class : Error +// ****************************************************************** +class Error +{ + public: + // ****************************************************************** + // * Return current error (or zero if there is none) + // ****************************************************************** + const char *GetError() const { return m_szError; } + + // ****************************************************************** + // * True : Error is fatal (class should be dead) + // * False : Error can safely be cleared and class can continue + // ****************************************************************** + bool IsFatal() const { return m_bFatal; } + + // ****************************************************************** + // * True : Error was cleared + // * False : Error is fatal (class should be dead) + // ****************************************************************** + bool ClearError(); + + protected: + // ****************************************************************** + // * Protected constructor so this class must be inherited from + // ****************************************************************** + Error() : m_szError(0), m_bFatal(false) { } + + // ****************************************************************** + // * Protected deconstructor + // ****************************************************************** + ~Error() { delete[] m_szError; } + + // ****************************************************************** + // * Protected so only derived class may set an error + // ****************************************************************** + void SetError(const char *x_szError, bool x_bFatal); + + private: + // ****************************************************************** + // * Current error information + // ****************************************************************** + bool m_bFatal; + char *m_szError; +}; + +#endif diff --git a/Include/Core/Exe.h b/Include/Core/Exe.h new file mode 100644 index 000000000..a7fff5129 --- /dev/null +++ b/Include/Core/Exe.h @@ -0,0 +1,275 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Core->Exe.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef EXE_H +#define EXE_H + +// ****************************************************************** +// * class : Exe +// ****************************************************************** +class Exe : public Error +{ + public: + // ****************************************************************** + // * Construct via Exe file + // ****************************************************************** + Exe(const char *x_szFilename); + + // ****************************************************************** + // * Deconstructor + // ****************************************************************** + ~Exe(); + + // ****************************************************************** + // * Export to EXE file + // ****************************************************************** + void Export(const char *x_szExeFilename); + + // ****************************************************************** + // * DOSHeader + // ****************************************************************** + #include "AlignPrefix1.h" + struct DOSHeader + { + uint16 m_magic; // DOS .EXE magic number + uint16 m_cblp; // byte on last page + uint16 m_cp; // number of pages + uint16 m_crlc; // number of relocations + uint16 m_cparhdr; // size of header (in paragraphs) + uint16 m_minalloc; // minimum extra paragraphs needed + uint16 m_maxalloc; // maximum extra paragraphs needed + uint16 m_ss; // initial SS value (relative) + uint16 m_sp; // initial SP value + uint16 m_csum; // checksum + uint16 m_ip; // initial IP value + uint16 m_cs; // initial CS value (relative) + uint16 m_lfarlc; // file address of relocation table + uint16 m_ovno; // overlay number + uint16 m_res[4]; // reserved words + uint16 m_oemid; // OEM identifier + uint16 m_oeminfo; // OEM information + uint16 m_res2[10]; // reserved words + uint32 m_lfanew; // file address of new .EXE header + } + #include "AlignPosfix1.h" + m_DOSHeader; + + // ****************************************************************** + // * Header (PE) + // ****************************************************************** + #include "AlignPrefix1.h" + struct Header + { + uint32 m_magic; // magic number [should be "PE\0\0"] + uint16 m_machine; // machine type + uint16 m_sections; // number of sections + uint32 m_timedate; // timedate stamp + uint32 m_symbol_table_addr; // symbol table address + uint32 m_symbols; // number of symbols + uint16 m_sizeof_optional_header; // size of optional header + uint16 m_characteristics; // characteristics + } + #include "AlignPosfix1.h" + m_Header; + + // ****************************************************************** + // * OptionalHeader (PE) + // ****************************************************************** + #include "AlignPrefix1.h" + struct OptionalHeader + { + uint16 m_magic; // magic number [should be 0x010B] + uint08 m_linker_version_major; // linker version [major] + uint08 m_linker_version_minor; // linker version [minor] + uint32 m_sizeof_code; // size of code + uint32 m_sizeof_initialized_data; // size of initialized data + uint32 m_sizeof_uninitialized_data; // size of uninitialized data + uint32 m_entry; // address of entry point + uint32 m_code_base; // address of code base + uint32 m_data_base; // address of data base + uint32 m_image_base; // address of image base + uint32 m_section_alignment; // section alignment + uint32 m_file_alignment; // file alignment + uint16 m_os_version_major; // operating system version [major] + uint16 m_os_version_minor; // operating system version [minor] + uint16 m_image_version_major; // image version [major] + uint16 m_image_version_minor; // image version [minor] + uint16 m_subsystem_version_major; // subsystem version [major] + uint16 m_subsystem_version_minor; // subsystem version [minor] + uint32 m_win32_version; // win32 version + uint32 m_sizeof_image; // size of image + uint32 m_sizeof_headers; // size of headers + uint32 m_checksum; // checksum + uint16 m_subsystem; // subsystem + uint16 m_dll_characteristics; // dll characteristics + uint32 m_sizeof_stack_reserve; // size of stack reserve + uint32 m_sizeof_stack_commit; // size of stack commit + uint32 m_sizeof_heap_reserve; // size of heap reserve + uint32 m_sizeof_heap_commit; // size of heap commit + uint32 m_loader_flags; // loader flags + uint32 m_data_directories; // data directories + + struct image_data_directory // image data directory + { + uint32 m_virtual_addr; // virtual address + uint32 m_size; // size + } + m_image_data_directory[0x10]; + } + #include "AlignPosfix1.h" + m_OptionalHeader; + + // ****************************************************************** + // * PE Section Header + // ****************************************************************** + #include "AlignPrefix1.h" + struct SectionHeader + { + char m_name[8]; // name of section + uint32 m_virtual_size; // virtual size of segment + uint32 m_virtual_addr; // virtual address of segment + uint32 m_sizeof_raw; // size of raw data + uint32 m_raw_addr; // address of raw data + uint32 m_relocations_addr; // address of relocations + uint32 m_linenumbers_addr; // address of line numbers + uint16 m_relocations; // number of relocations + uint16 m_linenumbers; // number of linenumbers + uint32 m_characteristics; // characteristics for this segment + } + #include "AlignPosfix1.h" + *m_SectionHeader; + + // ****************************************************************** + // * array of section data + // ****************************************************************** + uint08 **m_bzSection; + + protected: + // ****************************************************************** + // * Protected Default Constructor + // ****************************************************************** + Exe() {}; + + // ****************************************************************** + // * constructor initialization + // ****************************************************************** + void ConstructorInit(); + + // ****************************************************************** + // * return a modifiable pointer inside this structure that + // * corresponds to a virtual address + // ****************************************************************** + uint08 *GetAddr(uint32 x_dwVirtualAddress); + +}; + +// ****************************************************************** +// * PE File/Segment alignments: these must always both equal 0x0020 +// ****************************************************************** +static uint32 PE_FILE_ALIGN (0x0020); +static uint32 PE_SEGM_ALIGN (0x0020); + +// ****************************************************************** +// * Section Characeristics +// ****************************************************************** +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// ****************************************************************** +// * Based relocation types +// ****************************************************************** +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// ****************************************************************** +// * Machine type(s) +// ****************************************************************** +#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. + +// ****************************************************************** +// * Subsystems +// ****************************************************************** +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define IMAGE_SUBSYSTEM_OS2_CUI 5 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 + +// ****************************************************************** +// * DOS stub +// ****************************************************************** +static uint08 bzDOSStub[] = +{ + 0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, + 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, + 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, + 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, + 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x85, 0xE3, 0xB8, 0xDB, 0xC1, 0x82, 0xD6, 0x88, + 0xC1, 0x82, 0xD6, 0x88, 0xC1, 0x82, 0xD6, 0x88, + 0xC1, 0x82, 0xD7, 0x88, 0xC3, 0x82, 0xD6, 0x88, + 0x3E, 0xA2, 0xD2, 0x88, 0xC2, 0x82, 0xD6, 0x88, + 0x95, 0xA1, 0xE7, 0x88, 0xC0, 0x82, 0xD6, 0x88, + 0x52, 0x69, 0x63, 0x68, 0xC1, 0x82, 0xD6, 0x88, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#endif diff --git a/Include/Core/Xbe.h b/Include/Core/Xbe.h new file mode 100644 index 000000000..268b58d80 --- /dev/null +++ b/Include/Core/Xbe.h @@ -0,0 +1,324 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Core->Xbe.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef XBE_H +#define XBE_H + +#include + +// ****************************************************************** +// * class : Xbe +// ****************************************************************** +class Xbe : public Error +{ + public: + // ****************************************************************** + // * Construct via Xbe file + // ****************************************************************** + Xbe(const char *x_szFilename); + + // ****************************************************************** + // * Construct via Exe file object + // ****************************************************************** + Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail); + + // ****************************************************************** + // * Deconstructor + // ****************************************************************** + ~Xbe(); + + // ****************************************************************** + // * Export to XBE file + // ****************************************************************** + void Export(const char *x_szXbeFilename); + + // ****************************************************************** + // * Dump XBE information to text file + // ****************************************************************** + void DumpInformation(const char *x_szTxtFilename); + + // ****************************************************************** + // * Import logo bitmap from raw monochrome data + // ****************************************************************** + void ImportLogoBitmap(const uint08 x_Gray[100*17]); + + // ****************************************************************** + // * Export logo bitmap to raw monochrome data + // ****************************************************************** + void ExportLogoBitmap(uint08 x_Gray[100*17]); + + // ****************************************************************** + // * XBE header + // ****************************************************************** + #include "AlignPrefix1.h" + struct Header + { + uint32 dwMagic; // magic number [should be "XBEH"] + uint08 pbDigitalSignature[256]; // digital signature + uint32 dwBaseAddr; // base address + uint32 dwSizeofHeaders; // size of headers + uint32 dwSizeofImage; // size of image + uint32 dwSizeofImageHeader; // size of image header + uint32 dwTimeDate; // timedate stamp + uint32 dwCertificateAddr; // certificate address + uint32 dwSections; // number of sections + uint32 dwSectionHeadersAddr; // section headers address + + struct InitFlags + { + uint32 bMountUtilityDrive : 1; // mount utility drive flag + uint32 bFormatUtilityDrive : 1; // format utility drive flag + uint32 bLimit64MB : 1; // limit development kit run time memory to 64mb flag + uint32 bDontSetupHarddisk : 1; // don't setup hard disk flag + uint32 Unused : 4; // unused (or unknown) + uint32 Unused_b1 : 8; // unused (or unknown) + uint32 Unused_b2 : 8; // unused (or unknown) + uint32 Unused_b3 : 8; // unused (or unknown) + } + dwInitFlags; + + uint32 dwEntryAddr; // entry point address + uint32 dwTLSAddr; // thread local storage directory address + uint32 dwPeStackCommit; // size of stack commit + uint32 dwPeHeapReserve; // size of heap reserve + uint32 dwPeHeapCommit; // size of heap commit + uint32 dwPeBaseAddr; // original base address + uint32 dwPeSizeofImage; // size of original image + uint32 dwPeChecksum; // original checksum + uint32 dwPeTimeDate; // original timedate stamp + uint32 dwDebugPathnameAddr; // debug pathname address + uint32 dwDebugFilenameAddr; // debug filename address + uint32 dwDebugUnicodeFilenameAddr; // debug unicode filename address + uint32 dwKernelImageThunkAddr; // kernel image thunk address + uint32 dwNonKernelImportDirAddr; // non kernel import directory address + uint32 dwLibraryVersions; // number of library versions + uint32 dwLibraryVersionsAddr; // library versions address + uint32 dwKernelLibraryVersionAddr; // kernel library version address + uint32 dwXAPILibraryVersionAddr; // xapi library version address + uint32 dwLogoBitmapAddr; // logo bitmap address + uint32 dwSizeofLogoBitmap; // logo bitmap size + } + #include "AlignPosfix1.h" + m_Header; + + // ****************************************************************** + // * XBE header extra bytes (used to preserve unknown data) + // ****************************************************************** + char *m_HeaderEx; + + // ****************************************************************** + // * XBE certificate + // ****************************************************************** + #include "AlignPrefix1.h" + struct Certificate + { + uint32 dwSize; // size of certificate + uint32 dwTimeDate; // timedate stamp + uint32 dwTitleId; // title id + wchar_t wszTitleName[40]; // title name (unicode) + uint32 dwAlternateTitleId[0x10]; // alternate title ids + uint32 dwAllowedMedia; // allowed media types + uint32 dwGameRegion; // game region + uint32 dwGameRatings; // game ratings + uint32 dwDiskNumber; // disk number + uint32 dwVersion; // version + uint08 bzLanKey[16]; // lan key + uint08 bzSignatureKey[16]; // signature key + uint08 bzTitleAlternateSignatureKey[16][16]; // alternate signature keys + } + #include "AlignPosfix1.h" + m_Certificate; + + // ****************************************************************** + // * XBE section header + // ****************************************************************** + #include "AlignPrefix1.h" + struct SectionHeader + { + struct _Flags + { + uint32 bWritable : 1; // writable flag + uint32 bPreload : 1; // preload flag + uint32 bExecutable : 1; // executable flag + uint32 bInsertedFile : 1; // inserted file flag + uint32 bHeadPageRO : 1; // head page read only flag + uint32 bTailPageRO : 1; // tail page read only flag + uint32 Unused_a1 : 1; // unused (or unknown) + uint32 Unused_a2 : 1; // unused (or unknown) + uint32 Unused_b1 : 8; // unused (or unknown) + uint32 Unused_b2 : 8; // unused (or unknown) + uint32 Unused_b3 : 8; // unused (or unknown) + } + dwFlags; + + uint32 dwVirtualAddr; // virtual address + uint32 dwVirtualSize; // virtual size + uint32 dwRawAddr; // file offset to raw data + uint32 dwSizeofRaw; // size of raw data + uint32 dwSectionNameAddr; // section name addr + uint32 dwSectionRefCount; // section reference count + uint32 dwHeadSharedRefCountAddr; // head shared page reference count address + uint32 dwTailSharedRefCountAddr; // tail shared page reference count address + uint08 bzSectionDigest[20]; // section digest + } + #include "AlignPosfix1.h" + *m_SectionHeader; + + // ****************************************************************** + // * XBE library versions + // ****************************************************************** + #include "AlignPrefix1.h" + struct LibraryVersion + { + char szName[8]; // library name + uint16 wMajorVersion; // major version + uint16 wMinorVersion; // minor version + uint16 wBuildVersion; // build version + + struct Flags + { + uint16 QFEVersion : 13; // QFE Version + uint16 Approved : 2; // Approved? (0:no, 1:possibly, 2:yes) + uint16 bDebugBuild : 1; // Is this a debug build? + } + dwFlags; + } + #include "AlignPosfix1.h" + *m_LibraryVersion, *m_KernelLibraryVersion, *m_XAPILibraryVersion; + + // ****************************************************************** + // * XBE thread local storage + // ****************************************************************** + #include "AlignPrefix1.h" + struct TLS + { + uint32 dwDataStartAddr; // raw start address + uint32 dwDataEndAddr; // raw end address + uint32 dwTLSIndexAddr; // tls index address + uint32 dwTLSCallbackAddr; // tls callback address + uint32 dwSizeofZeroFill; // size of zero fill + uint32 dwCharacteristics; // characteristics + } + #include "AlignPosfix1.h" + *m_TLS; + + // ****************************************************************** + // * XBE section names, each 8 bytes max and null terminated + // ****************************************************************** + char (*m_szSectionName)[9]; + + // ****************************************************************** + // * XBE sections + // ****************************************************************** + uint08 **m_bzSection; + + // ****************************************************************** + // * XBE ascii title, translated from certificate title + // ****************************************************************** + char m_szAsciiTitle[40]; + + private: + // ****************************************************************** + // * constructor initialization + // ****************************************************************** + void ConstructorInit(); + + // ****************************************************************** + // * return a modifiable pointer inside this structure that + // * corresponds to a virtual address + // ****************************************************************** + uint08 *GetAddr(uint32 x_dwVirtualAddress); + + // ****************************************************************** + // * return a modifiable pointer to logo bitmap data + // ****************************************************************** + uint08 *GetLogoBitmap(uint32 x_dwSize); + + // ****************************************************************** + // * used to encode / decode logo bitmap data + // ****************************************************************** + union LogoRLE + { + struct Eight + { + uint32 bType1 : 1; + uint32 Len : 3; + uint32 Data : 4; + } + m_Eight; + + struct Sixteen + { + uint32 bType1 : 1; + uint32 bType2 : 1; + uint32 Len : 10; + uint32 Data : 4; + } + m_Sixteen; + }; +}; + +// ****************************************************************** +// * Debug / Retail XOR Keys +// ****************************************************************** +const uint32 XOR_EP_DEBUG = 0x94859D4B; // Entry Point (Debug) +const uint32 XOR_EP_RETAIL = 0xA8FC57AB; // Entry Point (Retail) +const uint32 XOR_KT_DEBUG = 0xEFB1F152; // Kernel Thunk (Debug) +const uint32 XOR_KT_RETAIL = 0x5B6D40B6; // Kernel Thunk (Retail) + +// ****************************************************************** +// * Game region flags for XBE certificate +// ****************************************************************** +const uint32 XBEIMAGE_GAME_REGION_NA = 0x00000001; +const uint32 XBEIMAGE_GAME_REGION_JAPAN = 0x00000002; +const uint32 XBEIMAGE_GAME_REGION_RESTOFWORLD = 0x00000004; +const uint32 XBEIMAGE_GAME_REGION_MANUFACTURING = 0x80000000; + +// ****************************************************************** +// * Media type flags for XBE certificate +// ****************************************************************** +const uint32 XBEIMAGE_MEDIA_TYPE_HARD_DISK = 0x00000001; +const uint32 XBEIMAGE_MEDIA_TYPE_DVD_X2 = 0x00000002; +const uint32 XBEIMAGE_MEDIA_TYPE_DVD_CD = 0x00000004; +const uint32 XBEIMAGE_MEDIA_TYPE_CD = 0x00000008; +const uint32 XBEIMAGE_MEDIA_TYPE_DVD_5_RO = 0x00000010; +const uint32 XBEIMAGE_MEDIA_TYPE_DVD_9_RO = 0x00000020; +const uint32 XBEIMAGE_MEDIA_TYPE_DVD_5_RW = 0x00000040; +const uint32 XBEIMAGE_MEDIA_TYPE_DVD_9_RW = 0x00000080; +const uint32 XBEIMAGE_MEDIA_TYPE_DONGLE = 0x00000100; +const uint32 XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD = 0x00000200; +const uint32 XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK = 0x40000000; +const uint32 XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE = 0x80000000; +const uint32 XBEIMAGE_MEDIA_TYPE_MEDIA_MASK = 0x00FFFFFF; + +#endif diff --git a/Include/Cxbx.h b/Include/Cxbx.h new file mode 100644 index 000000000..9167e4827 --- /dev/null +++ b/Include/Cxbx.h @@ -0,0 +1,75 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Cxbx.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef CXBX_H +#define CXBX_H + +// ****************************************************************** +// * Caustik's favorite typedefs +// ****************************************************************** +typedef signed int sint; +typedef unsigned int uint; +typedef char int08; +typedef short int16; +typedef long int32; +typedef unsigned char uint08; +typedef unsigned short uint16; +typedef unsigned long uint32; +typedef signed char sint08; +typedef signed short sint16; +typedef signed long sint32; + +// ****************************************************************** +// * Version Information +// ****************************************************************** +#define CXBX_VERSION "0.6.0-Pre9" + +// ****************************************************************** +// * func : RoundUp +// ****************************************************************** +static uint32 RoundUp(uint32 x_dwValue, uint32 x_dwMult) +{ + if(x_dwMult == 0) + return x_dwValue; + + return x_dwValue - (x_dwValue-1)%x_dwMult + (x_dwMult - 1); +} + +// ****************************************************************** +// * Core Components +// ****************************************************************** +#include "Core/Error.h" +#include "Core/Exe.h" +#include "Core/Xbe.h" + +#endif diff --git a/Include/Linux/AlignPosfix1.h b/Include/Linux/AlignPosfix1.h new file mode 100644 index 000000000..30363c266 --- /dev/null +++ b/Include/Linux/AlignPosfix1.h @@ -0,0 +1,42 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Linux->AlignPosfix1.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef ALIGNPOSFIX1_H +#define ALIGNPOSFIX1_H + +// ****************************************************************** +// * 1-byte structure alignment +// ****************************************************************** +__attribute((packed)) + +#endif diff --git a/Include/Linux/AlignPrefix1.h b/Include/Linux/AlignPrefix1.h new file mode 100644 index 000000000..d13986177 --- /dev/null +++ b/Include/Linux/AlignPrefix1.h @@ -0,0 +1,41 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Linux->AlignPrefix1.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef ALIGNPREFIX1_H +#define ALIGNPREFIX1_H + +// ****************************************************************** +// * For linux, we don't have any alignment prefix (just posfix) +// ****************************************************************** + +#endif diff --git a/Include/Win32/AlignPosfix1.h b/Include/Win32/AlignPosfix1.h new file mode 100644 index 000000000..0051c3047 --- /dev/null +++ b/Include/Win32/AlignPosfix1.h @@ -0,0 +1,42 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->AlignPosfix1.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef ALIGNPOSFIX1_H +#define ALIGNPOSFIX1_H + +// ****************************************************************** +// * Turn off 1-byte structure alignment +// ****************************************************************** +#pragma pack() + +#endif diff --git a/Include/Win32/AlignPrefix1.h b/Include/Win32/AlignPrefix1.h new file mode 100644 index 000000000..e1417bcde --- /dev/null +++ b/Include/Win32/AlignPrefix1.h @@ -0,0 +1,47 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->AlignPrefix1.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef ALIGNPREFIX1_H +#define ALIGNPREFIX1_H + +// ****************************************************************** +// * Turn on 1-byte structure alignment +// ****************************************************************** +#pragma pack(1) + +// ****************************************************************** +// * Tell the compiler not to complain about this *odd* circumstance +// ****************************************************************** +#pragma warning(disable:4103) + +#endif diff --git a/Include/Win32/Cxbx/EmuExe.h b/Include/Win32/Cxbx/EmuExe.h new file mode 100644 index 000000000..213f9c2d2 --- /dev/null +++ b/Include/Win32/Cxbx/EmuExe.h @@ -0,0 +1,51 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->EmuExe.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef EMUEXE_H +#define EMUEXE_H + +#include "Cxbx.h" + +// ****************************************************************** +// * class : EmuExe +// ****************************************************************** +class EmuExe : public Exe +{ + public: + // ****************************************************************** + // * Construct via Xbe file object + // ****************************************************************** + EmuExe(class Xbe *x_Xbe, uint32 x_debug_console); +}; + +#endif diff --git a/Include/Win32/Cxbx/Prolog.h b/Include/Win32/Cxbx/Prolog.h new file mode 100644 index 000000000..6d05c2252 --- /dev/null +++ b/Include/Win32/Cxbx/Prolog.h @@ -0,0 +1,42 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->Prolog.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef PROLOG_H +#define PROLOG_H + +// ****************************************************************** +// * func : Prolog +// ****************************************************************** +extern uint08 Prolog[]; + +#endif diff --git a/Include/Win32/Cxbx/Wnd.h b/Include/Win32/Cxbx/Wnd.h new file mode 100644 index 000000000..01ff116d5 --- /dev/null +++ b/Include/Win32/Cxbx/Wnd.h @@ -0,0 +1,72 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->Wnd.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef WND_H +#define WND_H + +#include + +// ****************************************************************** +// * class : Wnd +// ****************************************************************** +class Wnd : public Error +{ + public: + + Wnd(HINSTANCE x_hInstance); + ~Wnd(); + + bool ProcessMessages(); + + static LRESULT CALLBACK WndProcForward(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + HWND GetHwnd() { return m_hwnd; } + + protected: + HINSTANCE m_hInstance; + ATOM m_class; + HWND m_hwnd; + const char *m_classname; + const char *m_wndname; + UINT m_clsstyle; + DWORD m_wndstyle; + int m_x, m_y, m_w, m_h; + HWND m_parent; + HBRUSH m_background; + bool m_initialized; + + private: +}; + +#endif \ No newline at end of file diff --git a/Include/Win32/Cxbx/WndAbout.h b/Include/Win32/Cxbx/WndAbout.h new file mode 100644 index 000000000..c06c6a709 --- /dev/null +++ b/Include/Win32/Cxbx/WndAbout.h @@ -0,0 +1,56 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->WndAbout.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef WNDABOUT_H +#define WNDABOUT_H + +#include "Wnd.h" + +// ****************************************************************** +// * class : WndAbout +// ****************************************************************** +class WndAbout : public Wnd +{ + public: + + WndAbout(HINSTANCE x_hInstance, HWND x_parent); + ~WndAbout(); + + LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + private: + + HFONT m_hFont; +}; + +#endif \ No newline at end of file diff --git a/Include/Win32/Cxbx/WndMain.h b/Include/Win32/Cxbx/WndMain.h new file mode 100644 index 000000000..5d760b0b3 --- /dev/null +++ b/Include/Win32/Cxbx/WndMain.h @@ -0,0 +1,86 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->WndMain.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef WNDMAIN_H +#define WNDMAIN_H + +#include "Wnd.h" + +// ****************************************************************** +// * class : WndMain +// ****************************************************************** +class WndMain : public Wnd +{ + public: + + WndMain(HINSTANCE x_hInstance); + ~WndMain(); + + LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + private: + + void SuggestFilename(const char *x_orig_filename, char *x_filename, char x_extension[4]); + + void XbeLoaded(); // after an xbe is loaded, some stuff needs to update + void LoadLogo(); // refresh the logo in the main window + + bool ConvertToExe(); + + void SaveXbe(const char *x_filename); + void SaveXbeAs(); + + void CloseXbe(); + + HDC m_back_dc; + HDC m_logo_dc; + + HBITMAP m_orig_bmp; + HBITMAP m_orig_logo; + + HBITMAP m_back_bmp; + HBITMAP m_logo_bmp; + + Xbe *m_xbe; + Exe *m_exe; + + char *m_xbe_filename; + char *m_exe_filename; + + bool m_xbe_changed; + bool m_exe_changed; + + uint32 m_krnl_debug; +}; + +#endif \ No newline at end of file diff --git a/Include/Win32/CxbxKrnl/Kernel.h b/Include/Win32/CxbxKrnl/Kernel.h new file mode 100644 index 000000000..6a2ca0989 --- /dev/null +++ b/Include/Win32/CxbxKrnl/Kernel.h @@ -0,0 +1,83 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->Kernel.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef KERNEL_H +#define KERNEL_H + +// ****************************************************************** +// * namespace used to avoid collisions with ntdll and win32 +// ****************************************************************** +namespace xboxkrnl +{ + #include +}; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// ****************************************************************** +// * cxbxkrnl exports, others import +// ****************************************************************** +#ifndef CXBXKRNL_INTERNAL +#define CXBXKRNL_API DECLSPEC_IMPORT +#else +#define CXBXKRNL_API DECLSPEC_EXPORT +#endif + +// ****************************************************************** +// * data: KernelThunkTable +// ****************************************************************** +extern CXBXKRNL_API uint32 KernelThunkTable[367]; + +// ****************************************************************** +// * func: EmuXInit +// ****************************************************************** +CXBXKRNL_API void NTAPI EmuXInit(uint32 DebugConsole, uint08 *XBEHeader, uint32 XBEHeaderSize, void (*Entry)()); + +// ****************************************************************** +// * func: EmuXDummy +// ****************************************************************** +CXBXKRNL_API void NTAPI EmuXDummy(); + +// ****************************************************************** +// * func: EmuXPanic +// ****************************************************************** +CXBXKRNL_API void NTAPI EmuXPanic(); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/Include/Win32/CxbxKrnl/xntdll.h b/Include/Win32/CxbxKrnl/xntdll.h new file mode 100644 index 000000000..6abdd39fb --- /dev/null +++ b/Include/Win32/CxbxKrnl/xntdll.h @@ -0,0 +1,149 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->xntdll.h +// * +// * 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 +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef XNTDLL_H +#define XNTDLL_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// ****************************************************************** +// * dll import/export +// ****************************************************************** +#define DECLSPEC_IMPORT __declspec(dllimport) +#define DECLSPEC_EXPORT __declspec(dllexport) + +// ****************************************************************** +// * cxbx_krnl exports, others import +// ****************************************************************** +#define NTSYSAPI DECLSPEC_IMPORT + +// ****************************************************************** +// * Basic types +// ****************************************************************** +typedef char CHAR; +typedef short SHORT; +typedef long LONG; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; +typedef unsigned char BOOLEAN; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned long ULONG; +typedef unsigned long DWORD; +typedef unsigned long SIZE_T, *PSIZE_T; +typedef unsigned long ACCESS_MASK; +typedef unsigned long PHYSICAL_ADDRESS; +typedef long INT_PTR; + +// ****************************************************************** +// * Pointer types +// ****************************************************************** +typedef CHAR *PCHAR; +typedef CHAR *PCSZ; +typedef BYTE *PBYTE; +typedef BOOLEAN *PBOOLEAN; +typedef UCHAR *PUCHAR; +typedef USHORT *PUSHORT; +typedef ULONG *PULONG; +typedef ACCESS_MASK *PACCESS_MASK; +typedef LONG *LONG_PTR; +typedef INT_PTR *PINT_PTR; +typedef void VOID; +typedef VOID *PVOID; +typedef void *HANDLE; +typedef HANDLE *PHANDLE; + +// ****************************************************************** +// * NTSTATUS +// ****************************************************************** +typedef long NTSTATUS; +typedef unsigned __int64 ULONGLONG; + +// ****************************************************************** +// * LDT_ENTRY +// ****************************************************************** +typedef struct _LDT_ENTRY +{ + WORD LimitLow; + WORD BaseLow; + + union + { + struct + { + BYTE BaseMid; + BYTE Flags1; // Declare as bytes to avoid alignment + BYTE Flags2; // Problems. + BYTE BaseHi; + } + Bytes; + + struct + { + DWORD BaseMid : 8; + DWORD Type : 5; + DWORD Dpl : 2; + DWORD Pres : 1; + DWORD LimitHi : 4; + DWORD Sys : 1; + DWORD Reserved_0 : 1; + DWORD Default_Big : 1; + DWORD Granularity : 1; + DWORD BaseHi : 8; + } + Bits; + + } + HighWord; +} +LDT_ENTRY, *PLDT_ENTRY; + +// ****************************************************************** +// * NtSetLdtEntries +// ****************************************************************** +NTSYSAPI NTSTATUS NTAPI NtSetLdtEntries +( + IN USHORT Selector1, + IN LDT_ENTRY Descriptor1, + IN USHORT Selector2, + IN LDT_ENTRY Descriptor2 +); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d91663590 --- /dev/null +++ b/Makefile @@ -0,0 +1,68 @@ +# ****************************************************************** +# * +# * .,-::::: .,:: .::::::::. .,:: .: +# * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +# * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +# * $$$ Y$$$P $$""""Y$$ Y$$$P +# * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +# * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +# * +# * Cxbx->Makefile +# * +# * 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 +# * +# * All rights reserved +# * +# ****************************************************************** +# * File Authors: Aaron Robinson, Edgar Hucek +# ****************************************************************** +CC = g++ +CFLAGS = -g -O2 -IInclude -IInclude/Standard -IInclude/Standard/Cxbe -IInclude/Linux/ +OBJCOPY = objcopy +GCC295 = cpp0-2.95 +#LDFLAGS = -s -S -T ldscript.ld + +OBJECTS = Source/Core/Error.o \ + Source/Core/Exe.o \ + Source/Core/Xbe.o \ + Source/Standard/Cxbe/Main.o + +RESOURCES = + +# target: +all : cxbe + +clean : + rm -rf *.o *~ core *.core ${OBJECTS} ${RESOURCES} + rm -rf *.o *~ core *.core ${OBJECTS} ${RESOURCES} Bin/cxbe Bin/cxbe.exe + +cxbe : ${OBJECTS} ${RESOURCES} + ${CC} -o Bin/$@ ${OBJECTS} ${RESOURCES} ${LDFLAGS-XBE} + +### rules: + +%.o : %.cpp + ${CC} ${CFLAGS} -o $@ -c $< + +%.o : %.c + ${CC} ${CFLAGS} -o $@ -c $< + +%.o : %.S + ${CC} -DASSEMBLER ${CFLAGS} -o $@ -c $< diff --git a/PostBuild/upxCxbx.bat b/PostBuild/upxCxbx.bat new file mode 100644 index 000000000..d7e5f5fb9 --- /dev/null +++ b/PostBuild/upxCxbx.bat @@ -0,0 +1,2 @@ +upx -9 ../Bin/Cxbx.exe +upx -9 ../Bin/Cxbx.dll diff --git a/Resource/Cxbx.ico b/Resource/Cxbx.ico new file mode 100644 index 0000000000000000000000000000000000000000..59fa34bf6fb90abdc6a26cfb26a117ffad548d18 GIT binary patch literal 2238 zcmd6mF-x355QgW-!5tz5o2#xcR6y4|ky`+ZqmU6r-9H5m*BG8_(NV`D=$H#cQ> zcUMNEk!){o%huMGG%rGSc0%6BiNw_9^T{_kxww$mA3tHFgb{`C`Bu>sP0_S!F~4Hy zhHmJFZs_&3f?m)In}S}@S;WyD-O(Mv(Sv=k4^L-hR{WJj%1bICY0soEC=3dN!jMQX zC=3dN!k{oDCJYLL!k{oH42ced!k{oH3<`q=8XO9TR*s0Q019jU6v7Gg`jufZ%nc(W zslk$E;Lvz5SPYgd3mgWA!C`P199b$j3_EFnJg5Bn@{tqxRp z7j9*#@h&hGObZ4Drh<3ju#lwSUGUC!q&GVL1^q&D7#xOxAz*MANJDTRhJYbp2pC9Bpu-R_1PlQ{;O`_0 zUJNc7IgGu*5t+N*F?k~IWN&Xz_V@SY;NUjSZ zUth~?Hj}IGA#ab4_&;u_Zv7vq3;A+a^VV(1%6}Za9KSP!CP%N=dgIqIYwLx3&Tk#J zCV1%QE4KmL3J}vAd9C&QR)V(kd2<$XYX|-;F4C{`>O;%bhko9Id{>&@m6nuy&ZqaC yFC|;vWOtXPf3aJ%CF1H?#N=^ALj&be#t-R4TLk)FM?64 MB", ID_EDIT_PATCH_ALLOW64MB + MENUITEM "Debug Mode", ID_EDIT_PATCH_DEBUGMODE + END + MENUITEM SEPARATOR + MENUITEM "Extract &Xbe Info...", ID_EDIT_EXTRACTXBEINFO + , GRAYED + END + POPUP "&View" + BEGIN + MENUITEM "&Debug Console (GUI)", ID_VIEW_DEBUGCONSOLE + MENUITEM "Debug Console (Kernel)", ID_VIEW_KERNELDEBUGCONSOLE + END + POPUP "E&mulation" + BEGIN + MENUITEM "&Start", ID_EMULATION_START, GRAYED + END + POPUP "&Help" + BEGIN + MENUITEM "&Caustik's XBox Hacking Page...", ID_HELP_HOMEPAGE + MENUITEM SEPARATOR + MENUITEM "&About", ID_HELP_ABOUT + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Resource/Logo.bmp b/Resource/Logo.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3826a8c0a52bc2366b9f9dae9ba80a4205abfe6b GIT binary patch literal 188 zcmZ?r-NOI@Wk5;;h*N-A5QrHWSQwaqv>Om(1A>Br3`$B$493RB3@$D%456W+3~6a; z4CUqJ3>_UE3^QlWWLULo6~pe`yBW@$Im2-G?p=m=@7^)||NkFs2gn{uFask1XO$s2 literal 0 HcmV?d00001 diff --git a/Resource/Splash.bmp b/Resource/Splash.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b72d96c8eb451410994b779a06943752d6e7a472 GIT binary patch literal 153656 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.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#include + +// ****************************************************************** +// * func : ClearError +// ****************************************************************** +bool Error::ClearError() +{ + if(m_bFatal) + return false; + + delete[] m_szError; + + m_szError = 0; + m_bFatal = false; + + return true; +} + +// ****************************************************************** +// * func : SetError +// ****************************************************************** +void Error::SetError(const char *x_szError, bool x_bFatal) +{ + if(m_szError == 0) + m_szError = new char[256]; + + strcpy(m_szError, x_szError); + + m_bFatal = x_bFatal; + + return; +} diff --git a/Source/Core/Exe.cpp b/Source/Core/Exe.cpp new file mode 100644 index 000000000..501cbb238 --- /dev/null +++ b/Source/Core/Exe.cpp @@ -0,0 +1,310 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Core->Exe.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#include +#include + +// ****************************************************************** +// * constructor +// ****************************************************************** +Exe::Exe(const char *x_szFilename) +{ + ConstructorInit(); + + FILE *ExeFile = fopen(x_szFilename, "rb"); + + // ****************************************************************** + // * verify exe file was opened + // ****************************************************************** + if(ExeFile == 0) + { + SetError("could not open .exe file.", true); + return; + } + + // ****************************************************************** + // * ignore dos stub (if it exists) + // ****************************************************************** + { + if(fread(&m_DOSHeader.m_magic, sizeof(m_DOSHeader.m_magic), 1, ExeFile) != 1) + { + SetError("unexpected read error while reading magic number", true); + goto cleanup; + } + + if(m_DOSHeader.m_magic == *(uint16*)"MZ") + { + if(fread(&m_DOSHeader.m_cblp, sizeof(m_DOSHeader)-2, 1, ExeFile) != 1) + { + SetError("unexpected read error while reading dos header", true); + goto cleanup; + } + + fseek(ExeFile, m_DOSHeader.m_lfanew, SEEK_SET); + } + } + + // ****************************************************************** + // * read pe header + // ****************************************************************** + { + if(fread(&m_Header, sizeof(m_Header), 1, ExeFile) != 1) + { + SetError("unexpected read error while reading pe header", true); + goto cleanup; + } + + if(m_Header.m_magic != *(uint32*)"PE\0\0") + { + SetError("invalid file, could not locate PE header", true); + goto cleanup; + } + } + + // ****************************************************************** + // * read optional header + // ****************************************************************** + { + if(fread(&m_OptionalHeader, sizeof(m_OptionalHeader), 1, ExeFile) != 1) + { + SetError("unexpected read error while reading optional header", true); + goto cleanup; + } + + if(m_OptionalHeader.m_magic != 0x010B) + { + SetError("invalid file, could not locate optional header", true); + goto cleanup; + } + } + + // ****************************************************************** + // * read section headers + // ****************************************************************** + { + m_SectionHeader = new SectionHeader[m_Header.m_sections]; + + for(uint32 v=0;v 0) + // ****************************************************************** + { + fseek(ExeFile, raw_addr, SEEK_SET); + + if(fread(m_bzSection[v], raw_size, 1, ExeFile) != 1) + { + char buffer[255]; + sprintf(buffer, "could not read pe section %d (%Xh)", v, v); + SetError(buffer, true); + goto cleanup; + } + } + } + } + +cleanup: + + fclose(ExeFile); +} + +// ****************************************************************** +// * ConstructorInit +// ****************************************************************** +void Exe::ConstructorInit() +{ + m_SectionHeader = 0; + m_bzSection = 0; +} + +// ****************************************************************** +// * deconstructor +// ****************************************************************** +Exe::~Exe() +{ + if(m_bzSection != 0) + { + for(uint32 v=0;v= virt_addr) && (x_dwVirtualAddress < (virt_addr + virt_size)) ) + return &m_bzSection[v][x_dwVirtualAddress - virt_addr]; + } + + return 0; +} diff --git a/Source/Core/Xbe.cpp b/Source/Core/Xbe.cpp new file mode 100644 index 000000000..80b50b703 --- /dev/null +++ b/Source/Core/Xbe.cpp @@ -0,0 +1,1500 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Core->Xbe.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#include +#include +#include +#include +#include + +// ****************************************************************** +// * constructor +// ****************************************************************** +Xbe::Xbe(const char *x_szFilename) +{ + ConstructorInit(); + + FILE *XbeFile = fopen(x_szFilename, "rb"); + + // ****************************************************************** + // * verify xbe file was opened + // ****************************************************************** + if(XbeFile == 0) + { + SetError("could not open .xbe file.", true); + return; + } + + // ****************************************************************** + // * read xbe image header + // ****************************************************************** + { + if(fread(&m_Header, sizeof(m_Header), 1, XbeFile) != 1) + { + SetError("unexpected end of file while reading .xbe image header", true); + goto cleanup; + } + + if(m_Header.dwMagic != *(uint32 *)"XBEH") + { + SetError("invalid magic number in .xbe file", true); + goto cleanup; + } + } + + // ****************************************************************** + // * read xbe image header extra bytes + // ****************************************************************** + if(m_Header.dwSizeofHeaders > sizeof(m_Header)) + { + uint32 ExSize = RoundUp(m_Header.dwSizeofHeaders, 0x1000) - sizeof(m_Header); + + m_HeaderEx = new char[ExSize]; + + if(fread(m_HeaderEx, ExSize, 1, XbeFile) != 1) + { + SetError("unexpected end of file while reading .xbe image header (ex)", true); + goto cleanup; + } + } + + // ****************************************************************** + // * read xbe certificate + // ****************************************************************** + { + fseek(XbeFile, m_Header.dwCertificateAddr - m_Header.dwBaseAddr, SEEK_SET); + + if(fread(&m_Certificate, sizeof(m_Certificate), 1, XbeFile) != 1) + { + SetError("unexpected end of file while reading .xbe certificate", true); + goto cleanup; + } + + setlocale( LC_ALL, "English" ); + + wcstombs(m_szAsciiTitle, m_Certificate.wszTitleName, 40); + } + + // ****************************************************************** + // * read xbe section headers + // ****************************************************************** + { + fseek(XbeFile, m_Header.dwSectionHeadersAddr - m_Header.dwBaseAddr, SEEK_SET); + + m_SectionHeader = new SectionHeader[m_Header.dwSections]; + + for(uint32 v=0;vm_Header.m_sections; + + // ****************************************************************** + // * TODO: allow configuration + // ****************************************************************** + { + memset(&m_Header.dwInitFlags, 0, sizeof(m_Header.dwInitFlags)); + + m_Header.dwInitFlags.bLimit64MB = true; + m_Header.dwInitFlags.bDontSetupHarddisk = false; + m_Header.dwInitFlags.bMountUtilityDrive = true; + } + + // ****************************************************************** + // * various pe copies + // ****************************************************************** + { + m_Header.dwPeStackCommit = 0x00010000; //x_Exe->m_OptionalHeader.m_sizeof_stack_commit; + m_Header.dwPeHeapReserve = x_Exe->m_OptionalHeader.m_sizeof_heap_reserve; + m_Header.dwPeHeapCommit = x_Exe->m_OptionalHeader.m_sizeof_heap_commit; + m_Header.dwPeSizeofImage = x_Exe->m_OptionalHeader.m_sizeof_image; + m_Header.dwPeChecksum = 0x00000000; + m_Header.dwPeTimeDate = x_Exe->m_Header.m_timedate; + } + + // ****************************************************************** + // * build time/date + // ****************************************************************** + m_Header.dwTimeDate = CurrentTime; + + // ****************************************************************** + // * TODO: generate valid addr if necessary + // ****************************************************************** + m_Header.dwNonKernelImportDirAddr = 0; + + // ****************************************************************** + // * TODO: generate these values + // ****************************************************************** + m_Header.dwLibraryVersions = 0; + m_Header.dwLibraryVersionsAddr = 0; + m_Header.dwKernelLibraryVersionAddr = 0; + m_Header.dwXAPILibraryVersionAddr = 0; + } + + // ****************************************************************** + // * Pass 2 + // ****************************************************************** + { + // ****************************************************************** + // * make room cursor + // ****************************************************************** + uint32 mrc = m_Header.dwBaseAddr + sizeof(m_Header); + + // ****************************************************************** + // * make room for certificate + // ****************************************************************** + { + m_Header.dwCertificateAddr = mrc; + + mrc += sizeof(m_Certificate); + } + + // ****************************************************************** + // * make room for section headers + // ****************************************************************** + { + m_Header.dwSectionHeadersAddr = mrc; + + mrc += m_Header.dwSections * (sizeof(*m_SectionHeader)); + + // ****************************************************************** + // * make room for head / tail reference count words + // ****************************************************************** + mrc += (m_Header.dwSections+1)*2; + + // ****************************************************************** + // * make room for section names + // ****************************************************************** + for(uint32 v=0;vm_SectionHeader[v].m_name[s] != '\0') + s++; + + mrc += s + 1; + } + } + + // ****************************************************************** + // * TODO: make room for library versions + // ****************************************************************** + { + } + + // ****************************************************************** + // * make room for debug path / debug file names + // ****************************************************************** + { + // TODO: allow this to be configured, right now we will + // just null out these values + m_Header.dwDebugUnicodeFilenameAddr = mrc; + m_Header.dwDebugPathnameAddr = mrc; + m_Header.dwDebugFilenameAddr = mrc; + + mrc += 2; + } + + // ****************************************************************** + // * make room for logo bitmap (temporary HACK) + // ****************************************************************** + { + mrc = RoundUp(mrc, 0x10); + + m_Header.dwLogoBitmapAddr = mrc; + m_Header.dwSizeofLogoBitmap = 0x6A4; // Max Possible + + mrc += m_Header.dwSizeofLogoBitmap; + } + + // ****************************************************************** + // * update size of headers + // ****************************************************************** + m_Header.dwSizeofHeaders = mrc - m_Header.dwBaseAddr; + } + + // ****************************************************************** + // * Pass 3 + // ****************************************************************** + { + m_Header.dwPeBaseAddr = m_Header.dwBaseAddr + RoundUp(m_Header.dwSizeofHeaders, 0x1000) - x_Exe->m_SectionHeader[0].m_virtual_addr; + + // ****************************************************************** + // * encode entry point + // ****************************************************************** + { + uint32 ep = x_Exe->m_OptionalHeader.m_entry + m_Header.dwPeBaseAddr; + + if(x_bRetail) + ep ^= XOR_EP_RETAIL; + else + ep ^= XOR_EP_DEBUG; + + m_Header.dwEntryAddr = ep; + } + + // ****************************************************************** + // * header write cursor + // ****************************************************************** + uint32 hwc = m_Header.dwBaseAddr + sizeof(m_Header); + + // ****************************************************************** + // * check if we need to store extra header bytes (we always will) + // ****************************************************************** + if(m_Header.dwSizeofHeaders > sizeof(m_Header)) + { + uint32 ExSize = RoundUp(m_Header.dwSizeofHeaders - sizeof(m_Header), 0x1000); + + m_HeaderEx = new char[ExSize]; + } + + // ****************************************************************** + // * start a write buffer inside header_ex + // ****************************************************************** + char *Buffer = m_HeaderEx; + + // ****************************************************************** + // * write certificate + // ****************************************************************** + { + // ****************************************************************** + // * certificate size is a constant + // ****************************************************************** + m_Certificate.dwSize = sizeof(m_Certificate); + + m_Certificate.dwTimeDate = CurrentTime; + + // ****************************************************************** + // * TODO: generate in the form CX-9999 + // ****************************************************************** + m_Certificate.dwTitleId = 0xFFFF0002; + + // ****************************************************************** + // * title name + // ****************************************************************** + { + memset(m_Certificate.wszTitleName, 0, 40); + + mbstowcs(m_Certificate.wszTitleName, x_szTitle, 40); + } + + // ****************************************************************** + // * zero out alternate ids + // ****************************************************************** + { + for(uint32 c=0;c<0x10;c++) + m_Certificate.dwAlternateTitleId[c] = 0; + } + + // ****************************************************************** + // * for now we'll just allow any media you could want + // ****************************************************************** + m_Certificate.dwAllowedMedia = XBEIMAGE_MEDIA_TYPE_HARD_DISK | XBEIMAGE_MEDIA_TYPE_DVD_CD | XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD; + + // ****************************************************************** + // * TODO: allow configuration + // ****************************************************************** + m_Certificate.dwGameRegion = XBEIMAGE_GAME_REGION_MANUFACTURING | XBEIMAGE_GAME_REGION_NA | XBEIMAGE_GAME_REGION_JAPAN | XBEIMAGE_GAME_REGION_RESTOFWORLD; + + // ****************************************************************** + // * TODO: allow configuration + // ****************************************************************** + m_Certificate.dwGameRatings = 0xFFFFFFFF; + + // ****************************************************************** + // * always disk 0, AFAIK + // ****************************************************************** + m_Certificate.dwDiskNumber = 0; + + // ****************************************************************** + // * TODO: allow configuration + // ****************************************************************** + m_Certificate.dwVersion = 0; + + // ****************************************************************** + // * generate blank lan, signature, and alternate signature keys + // ****************************************************************** + { + for(uint32 v=0;v<0x10;v++) + m_Certificate.bzLanKey[v] = m_Certificate.bzSignatureKey[v] = 0; + + for(uint32 x=0;x<0x10;x++) + for(uint32 y=0;y<0x10;y++) + m_Certificate.bzTitleAlternateSignatureKey[x][y] = 0; + + } + + // ****************************************************************** + // * write certificate + // ****************************************************************** + { + memcpy(Buffer, &m_Certificate, sizeof(m_Certificate)); + + Buffer += sizeof(m_Certificate); + + hwc += sizeof(m_Certificate); + } + } + + // ****************************************************************** + // * generate ascii title from certificate title name + // ****************************************************************** + { + setlocale( LC_ALL, "English" ); + + wcstombs(m_szAsciiTitle, m_Certificate.wszTitleName, 40); + } + + // ****************************************************************** + // * write section headers / section names + // ****************************************************************** + { + m_szSectionName = new char[m_Header.dwSections][9]; + + m_SectionHeader = new SectionHeader[m_Header.dwSections]; + + uint32 SectionCursor = RoundUp(m_Header.dwSizeofHeaders, 0x1000); + + // ****************************************************************** + // * head / tail reference count write buffer + // ****************************************************************** + uint16 *htrc = (uint16*)(Buffer + m_Header.dwSections*sizeof(*m_SectionHeader)); + + // ****************************************************************** + // * section write Buffer + // ****************************************************************** + char *secn = (char*)((uint32)htrc + (m_Header.dwSections+1)*2); + + // ****************************************************************** + // * head / tail reference count write cursor + // ****************************************************************** + uint32 hwc_htrc = hwc + m_Header.dwSections*sizeof(*m_SectionHeader); + + // ****************************************************************** + // * section write cursor + // ****************************************************************** + uint32 hwc_secn = hwc_htrc + (m_Header.dwSections+1)*2; + + for(uint32 v=0;vm_SectionHeader[v].m_characteristics; + + memset(&m_SectionHeader[v].dwFlags, 0, sizeof(m_SectionHeader->dwFlags)); + + if(characteristics & IMAGE_SCN_MEM_WRITE) + m_SectionHeader[v].dwFlags.bWritable = true; + + if( (characteristics & IMAGE_SCN_MEM_EXECUTE) || (characteristics & IMAGE_SCN_CNT_CODE) ) + m_SectionHeader[v].dwFlags.bExecutable = true; + + m_SectionHeader[v].dwFlags.bPreload = true; + m_SectionHeader[v].dwVirtualAddr = x_Exe->m_SectionHeader[v].m_virtual_addr + m_Header.dwPeBaseAddr; + + if(v < m_Header.dwSections-1) + m_SectionHeader[v].dwVirtualSize = x_Exe->m_SectionHeader[v+1].m_virtual_addr - x_Exe->m_SectionHeader[v].m_virtual_addr; + else + m_SectionHeader[v].dwVirtualSize = RoundUp(x_Exe->m_SectionHeader[v].m_virtual_size, 4); + + m_SectionHeader[v].dwRawAddr = SectionCursor; + + // ****************************************************************** + // * calculate sizeof_raw...this is done by locating the last non- + // * -zero value in the raw section data + // ****************************************************************** + { + uint32 r = x_Exe->m_SectionHeader[v].m_sizeof_raw - 1; + + while(r > 0) + { + if(x_Exe->m_bzSection[v][r--] != 0) + break; + } + + // word aligned + m_SectionHeader[v].dwSizeofRaw = RoundUp(r+2, 4); + } + + SectionCursor += RoundUp(m_SectionHeader[v].dwSizeofRaw, 0x1000); + + // ****************************************************************** + // * head / tail reference count + // ****************************************************************** + { + m_SectionHeader[v].dwHeadSharedRefCountAddr = hwc_htrc; + htrc[v] = 0; + + hwc_htrc += 2; + + m_SectionHeader[v].dwTailSharedRefCountAddr = hwc_htrc; + htrc[v+1] = 0; + } + + // ****************************************************************** + // * section name + // ****************************************************************** + { + uint32 s = 0; + + memset(secn, 0, 8); + + m_SectionHeader[v].dwSectionNameAddr = hwc_secn; + while(s < 8 && x_Exe->m_SectionHeader[v].m_name[s] != '\0') + { + m_szSectionName[v][s] = secn[s] = x_Exe->m_SectionHeader[v].m_name[s]; + s++; + } + + m_szSectionName[v][s] = '\0'; + + secn += s+1; + hwc_secn += s+1; + } + + m_SectionHeader[v].dwSectionRefCount = 0; + + // ****************************************************************** + // * write section digest (just zeros) + // ****************************************************************** + memset(m_SectionHeader[v].bzSectionDigest, 0, 20); + + // ****************************************************************** + // * write section header + // ****************************************************************** + memcpy(Buffer, &m_SectionHeader[v], sizeof(*m_SectionHeader)); + + Buffer += sizeof(*m_SectionHeader); + } + + hwc = hwc_secn; + } + + // ****************************************************************** + // * write debug path / debug file names + // ****************************************************************** + { + *(uint16*)Buffer = 0x0000; + + Buffer += 2; + hwc += 2; + } + + // ****************************************************************** + // * blank logo bitmap (HACK) + // ****************************************************************** + { + uint08 *blank = GetAddr(m_Header.dwLogoBitmapAddr); + + memset(blank, 0, 100*17); + } + + // ****************************************************************** + // * write sections + // ****************************************************************** + { + m_bzSection = new uint08*[m_Header.dwSections]; + + memset(m_bzSection, 0, m_Header.dwSections); + + for(uint32 v=0;vm_bzSection[v], RawSize); + } + } + } + + // ****************************************************************** + // * Pass 4 + // ****************************************************************** + { + m_Header.dwSizeofImage = m_SectionHeader[m_Header.dwSections-1].dwVirtualAddr + m_SectionHeader[m_Header.dwSections-1].dwVirtualSize - m_Header.dwBaseAddr; + + m_Header.dwTLSAddr = 0; + + // ****************************************************************** + // * Relocate to base : 0x00010000 + // ****************************************************************** + { + uint32 relo_addr = x_Exe->m_OptionalHeader.m_image_data_directory[5].m_virtual_addr; + uint32 relo_size = x_Exe->m_OptionalHeader.m_image_data_directory[5].m_size; + + uint32 dwBaseDiff = m_Header.dwPeBaseAddr - x_Exe->m_OptionalHeader.m_image_base; + + uint08 *reloc = GetAddr(relo_addr + m_Header.dwPeBaseAddr); + + // ****************************************************************** + // * relocate, if necessary + // ****************************************************************** + if(reloc != 0) + { + uint32 v = 0; + + // ****************************************************************** + // * relocate each relocation block + // ****************************************************************** + while(v < relo_size) + { + uint32 block_addr = *(uint32 *)&reloc[v+0]; + uint32 block_stop = *(uint32 *)&reloc[v+4] + v; + + v += 8; + + // ****************************************************************** + // * relocate each rva + // ****************************************************************** + while(v < block_stop && v < relo_size) + { + uint16 data = *(uint16 *)&reloc[v]; + + uint32 type = (data & 0xF000) >> 12; + + if(type == 0) + { + v+=2; + break; + } + + // ****************************************************************** + // * 32-bit field relocation + // ****************************************************************** + if(type == IMAGE_REL_BASED_HIGHLOW) + { + uint32 dwFixAddr = block_addr + (data & 0x0FFF) + m_Header.dwPeBaseAddr; + + uint08 *bzModRVA = GetAddr(dwFixAddr); + + if(bzModRVA != 0) + *(uint32*)bzModRVA += dwBaseDiff; + } + else + { + SetError("unsupported relocation type", true); + goto cleanup; + } + + v+=2; + } + } + } + } + + // ****************************************************************** + // * Locate kernel thunk table + // ****************************************************************** + { + uint32 kt = x_Exe->m_OptionalHeader.m_image_data_directory[12].m_virtual_addr + m_Header.dwPeBaseAddr; + + if(x_bRetail) + kt ^= XOR_KT_RETAIL; + else + kt ^= XOR_KT_DEBUG; + + m_Header.dwKernelImageThunkAddr = kt; + } + } + +cleanup: + + return; +} + +// ****************************************************************** +// * deconstructor +// ****************************************************************** +Xbe::~Xbe() +{ + if(m_bzSection != 0) + { + for(uint32 v=0;v"); + for(int y=0;y<16;y++) + { + fprintf(TxtFile, "\n "); + for(int x=0;x<16;x++) + fprintf(TxtFile, "%.02X", m_Header.pbDigitalSignature[y*16+x]); + } + fprintf(TxtFile, "\n \n"); + } + + fprintf(TxtFile, "Base Address : 0x%.08X\n", m_Header.dwBaseAddr); + fprintf(TxtFile, "Size of Headers : 0x%.08X\n", m_Header.dwSizeofHeaders); + fprintf(TxtFile, "Size of Image : 0x%.08X\n", m_Header.dwSizeofImage); + fprintf(TxtFile, "Size of Image Header : 0x%.08X\n", m_Header.dwSizeofImageHeader); + fprintf(TxtFile, "TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwTimeDate, BetterTime(ctime((const long*)&m_Header.dwTimeDate))); + fprintf(TxtFile, "Certificate Address : 0x%.08X\n", m_Header.dwCertificateAddr); + fprintf(TxtFile, "Number of Sections : 0x%.08X\n", m_Header.dwSections); + fprintf(TxtFile, "Section Headers Address : 0x%.08X\n", m_Header.dwSectionHeadersAddr); + + // ****************************************************************** + // * print init flags + // ****************************************************************** + { + fprintf(TxtFile, "Init Flags : 0x%.08X "); + + if(m_Header.dwInitFlags.bMountUtilityDrive) + fprintf(TxtFile, "[Mount Utility Drive] "); + + if(m_Header.dwInitFlags.bFormatUtilityDrive) + fprintf(TxtFile, "[Format Utility Drive] "); + + if(m_Header.dwInitFlags.bLimit64MB) + fprintf(TxtFile, "[Limit Devkit Run Time Memory to 64MB] "); + + if(!m_Header.dwInitFlags.bDontSetupHarddisk) + fprintf(TxtFile, "[Setup Harddisk] "); + + fprintf(TxtFile, "\n"); + } + + char AsciiFilename[40]; + + setlocale( LC_ALL, "English" ); + + wcstombs(AsciiFilename, (const wchar_t*)GetAddr(m_Header.dwDebugUnicodeFilenameAddr), 40); + + fprintf(TxtFile, "Entry Point : 0x%.08X (Retail: 0x%.08X, Debug: 0x%.08X)\n", m_Header.dwEntryAddr, m_Header.dwEntryAddr ^ XOR_EP_RETAIL, m_Header.dwEntryAddr ^ XOR_EP_DEBUG); + fprintf(TxtFile, "TLS Address : 0x%.08X\n", m_Header.dwTLSAddr); + fprintf(TxtFile, "(PE) Stack Commit : 0x%.08X\n", m_Header.dwPeStackCommit); + fprintf(TxtFile, "(PE) Heap Reserve : 0x%.08X\n", m_Header.dwPeHeapReserve); + fprintf(TxtFile, "(PE) Heap Commit : 0x%.08X\n", m_Header.dwPeHeapCommit); + fprintf(TxtFile, "(PE) Base Address : 0x%.08X\n", m_Header.dwPeBaseAddr); + fprintf(TxtFile, "(PE) Size of Image : 0x%.08X\n", m_Header.dwPeSizeofImage); + fprintf(TxtFile, "(PE) Checksum : 0x%.08X\n", m_Header.dwPeChecksum); + fprintf(TxtFile, "(PE) TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwPeTimeDate, BetterTime(ctime((time_t*)&m_Header.dwPeTimeDate))); + fprintf(TxtFile, "Debug Pathname Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugPathnameAddr, GetAddr(m_Header.dwDebugPathnameAddr)); + fprintf(TxtFile, "Debug Filename Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugFilenameAddr, GetAddr(m_Header.dwDebugFilenameAddr)); + fprintf(TxtFile, "Debug Unicode filename Address : 0x%.08X (L\"%s\")\n", m_Header.dwDebugUnicodeFilenameAddr, AsciiFilename); + fprintf(TxtFile, "Kernel Image Thunk Address : 0x%.08X (Retail: 0x%.08X, Debug: 0x%.08X)\n", m_Header.dwKernelImageThunkAddr, m_Header.dwKernelImageThunkAddr ^ XOR_KT_RETAIL, m_Header.dwKernelImageThunkAddr ^ XOR_KT_DEBUG); + fprintf(TxtFile, "NonKernel Import Dir Address : 0x%.08X\n", m_Header.dwNonKernelImportDirAddr); + fprintf(TxtFile, "Library Versions : 0x%.08X\n", m_Header.dwLibraryVersions); + fprintf(TxtFile, "Library Versions Address : 0x%.08X\n", m_Header.dwLibraryVersionsAddr); + fprintf(TxtFile, "Kernel Library Version Address : 0x%.08X\n", m_Header.dwKernelLibraryVersionAddr); + fprintf(TxtFile, "XAPI Library Version Address : 0x%.08X\n", m_Header.dwXAPILibraryVersionAddr); + fprintf(TxtFile, "Logo Bitmap Address : 0x%.08X\n", m_Header.dwLogoBitmapAddr); + fprintf(TxtFile, "Logo Bitmap Size : 0x%.08X\n", m_Header.dwSizeofLogoBitmap); + fprintf(TxtFile, "\n"); + fprintf(TxtFile, "Dumping XBE Certificate...\n"); + fprintf(TxtFile, "\n"); + fprintf(TxtFile, "Size of Certificate : 0x%.08X\n", m_Certificate.dwSize); + fprintf(TxtFile, "TimeDate Stamp : 0x%.08X (%s)\n", m_Certificate.dwTimeDate, BetterTime(ctime((time_t*)&m_Certificate.dwTimeDate))); + fprintf(TxtFile, "Title ID : 0x%.08X\n", m_Certificate.dwTitleId); + fprintf(TxtFile, "Title : L\"%s\"\n", m_szAsciiTitle); + + // ****************************************************************** + // * print alternate titles + // ****************************************************************** + { + fprintf(TxtFile, "Alternate Titles IDs : "); + + for(int v=0;v<0x10;v++) + { + if(v != 0) + fprintf(TxtFile, " "); + fprintf(TxtFile, "0x%.08X", m_Certificate.dwAlternateTitleId[v]); + if(v != 0x0F) + fprintf(TxtFile, "\n"); + } + + fprintf(TxtFile, "\n"); + } + + fprintf(TxtFile, "Allowed Media : 0x%.08X\n", m_Certificate.dwAllowedMedia); + fprintf(TxtFile, "Game Region : 0x%.08X\n", m_Certificate.dwGameRegion); + fprintf(TxtFile, "Game Ratings : 0x%.08X\n", m_Certificate.dwGameRatings); + fprintf(TxtFile, "Disk Number : 0x%.08X\n", m_Certificate.dwDiskNumber); + fprintf(TxtFile, "Version : 0x%.08X\n", m_Certificate.dwVersion); + + // ****************************************************************** + // * print lan key + // ****************************************************************** + { + fprintf(TxtFile, "LAN Key : "); + for(int x=0;x<16;x++) + fprintf(TxtFile, "%.02X", m_Certificate.bzLanKey[x]); + fprintf(TxtFile, "\n"); + } + + // ****************************************************************** + // * print signature key + // ****************************************************************** + { + fprintf(TxtFile, "Signature Key : "); + for(int x=0;x<16;x++) + fprintf(TxtFile, "%.02X", m_Certificate.bzSignatureKey[x]); + fprintf(TxtFile, "\n"); + } + + // ****************************************************************** + // * print alternative signature keys + // ****************************************************************** + { + fprintf(TxtFile, "Title Alternative Signature Keys : "); + for(int y=0;y<16;y++) + { + fprintf(TxtFile, "\n "); + for(int x=0;x<16;x++) + fprintf(TxtFile, "%.02X", m_Certificate.bzTitleAlternateSignatureKey[y][x]); + } + fprintf(TxtFile, "\n \n"); + } + + fprintf(TxtFile, "\n"); + fprintf(TxtFile, "Dumping XBE Section Headers...\n"); + fprintf(TxtFile, "\n"); + + // ****************************************************************** + // * print section headers + // ****************************************************************** + { + for(uint32 v=0;vdwDataStartAddr); + fprintf(TxtFile, "Data End Address : 0x%.08X\n", m_TLS->dwDataEndAddr); + fprintf(TxtFile, "TLS Index Address : 0x%.08X\n", m_TLS->dwTLSIndexAddr); + fprintf(TxtFile, "TLS Callback Address : 0x%.08X\n", m_TLS->dwTLSCallbackAddr); + fprintf(TxtFile, "Size of Zero Fill : 0x%.08X\n", m_TLS->dwSizeofZeroFill); + fprintf(TxtFile, "Characteristics : 0x%.08X\n", m_TLS->dwCharacteristics); + } + else + { + fprintf(TxtFile, "(This XBE contains no TLS)\n"); + } + + fclose(TxtFile); +} + + +// ****************************************************************** +// * ImportLogoBitmap +// ****************************************************************** +void Xbe::ImportLogoBitmap(const uint08 x_Gray[100*17]) +{ + char *LogoBuffer = new char[4*1024]; + uint32 LogoSize = 0; + + // ****************************************************************** + // * encode logo bitmap + // ****************************************************************** + { + for(uint32 v=1;v<100*17;LogoSize++) + { + char color = x_Gray[v] >> 4; + + uint32 len = 1; + + while(++v<100*17-1 && len < 1024 && color == x_Gray[v] >> 4) + len++; + + LogoRLE *cur = (LogoRLE *)&LogoBuffer[LogoSize]; + + if(len <= 7) + { + cur->m_Eight.bType1 = 1; + cur->m_Eight.Len = len; + cur->m_Eight.Data = color; + } + else + { + cur->m_Sixteen.bType1 = 0; + cur->m_Sixteen.bType2 = 1; + cur->m_Sixteen.Len = len; + cur->m_Sixteen.Data = color; + LogoSize++; + } + } + } + + // ****************************************************************** + // * check if there is room to save this, it not then throw an error + // ****************************************************************** + { + uint08 *RLE = GetLogoBitmap(LogoSize); + + if(RLE == 0) + { + if(GetError() == 0) + SetError("Logo bitmap could not be imported (not enough space in file?)", false); + + return; + } + + memcpy(RLE, LogoBuffer, LogoSize); + } + + return; +} + +// ****************************************************************** +// * ExportLogoBitmap +// ****************************************************************** +// * +// * This algorithm was originally discovered by superfro. I couldnt +// * figure out what the hell the encoding format was before he gave +// * me the information: +// * +// * basically what is going on here is a single pass through the +// * bitmap data, with 2 possible encodings per rle chunk. data is +// * stored as 4 bit grayscale, so the logical approach is to expand +// * this to 8 bit using a simple 4 bit left shift (*16). However, it +// * has been suggested to me by superfro that you might calculate a +// * slightly darker image by multiplying by 15 and adding .5. It's +// * a toss up, but i've choosen a simple bit shift left. +// * +// ****************************************************************** +void Xbe::ExportLogoBitmap(uint08 x_Gray[100*17]) +{ + memset(x_Gray, 0, 100*17); + + uint32 dwLength = m_Header.dwSizeofLogoBitmap; + + uint08 *RLE = GetAddr(m_Header.dwLogoBitmapAddr); + + if(RLE == 0 || GetError()) + return; + + uint32 o = 0; + + for(uint32 v=0;vm_Eight.bType1) + { + len = cur->m_Eight.Len; + data = cur->m_Eight.Data; + } + else + { + if(cur->m_Sixteen.bType2) + { + len = cur->m_Sixteen.Len; + data = cur->m_Sixteen.Data; + v += 1; + } + } + + for(uint32 j=0;j= VirtAddr) && (x_dwVirtualAddress < (VirtAddr + VirtSize)) ) + return &m_bzSection[v][x_dwVirtualAddress - VirtAddr]; + } + } + + return 0; +} + +// ****************************************************************** +// * GetLogoBitmap +// ****************************************************************** +uint08 *Xbe::GetLogoBitmap(uint32 x_dwSize) +{ + uint32 dwOffs = m_Header.dwLogoBitmapAddr - m_Header.dwBaseAddr; + uint32 dwLength = m_Header.dwSizeofLogoBitmap; + + if(dwOffs == 0 || dwLength == 0) + { + return 0; + } + + // ****************************************************************** + // * if this bitmap will fit inside the already existing one, we + // * don't need to resize anything in the xbe, just return a pointer + // ****************************************************************** + if(dwLength >= x_dwSize) + { + // ****************************************************************** + // * update size of headers, if necessary + // ****************************************************************** + if(dwOffs < m_Header.dwSizeofHeaders) + { + m_Header.dwSizeofHeaders -= dwLength; + + m_Header.dwSizeofHeaders += x_dwSize; + + m_Header.dwSizeofLogoBitmap = x_dwSize; + + return GetAddr(m_Header.dwLogoBitmapAddr); + } + } + + return 0; +} diff --git a/Source/Standard/Cxbe/Main.cpp b/Source/Standard/Cxbe/Main.cpp new file mode 100644 index 000000000..ba44a0396 --- /dev/null +++ b/Source/Standard/Cxbe/Main.cpp @@ -0,0 +1,318 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Standard->Cxbe->Main.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#include +#include + +// ****************************************************************** +// * static functions +// ****************************************************************** +void ShowUsage(); +void MakeUpper(char *str); + +// ****************************************************************** +// * func : main +// ****************************************************************** +int main(int argc, char *argv[]) +{ + char szErrorMessage[266] = {0}; + char szExeFilename[266] = {0}; + char szXbeFilename[266] = {0}; + char szDumpFilename[266] = {0}; + char szXbeTitle[256] = "Untitled"; + bool bRetail = true; + + // ****************************************************************** + // * parse command line + // ****************************************************************** + for(int v=1;v 256) + { + printf("WARNING: Title too long, using default title\n"); + } + else + { + strcpy(szXbeTitle, szParam); + } + } + else if(strcmp(szOptionU, "MODE") == 0) + { + if(strcmp(szParamU, "RETAIL") == 0) + { + bRetail = true; + } + else if(strcmp(szParamU, "DEBUG") == 0) + { + bRetail = false; + } + else + { + strcpy(szErrorMessage, "invalid MODE"); + goto cleanup; + } + } + else + { + char szBuffer[255]; + sprintf(szBuffer, "Unrecognized command : %s", szOption); + strcpy(szErrorMessage, szBuffer); + goto cleanup; + } + } + } + + // ****************************************************************** + // * verify we recieved the required parameters + // ****************************************************************** + if(szExeFilename[0] == '\0') + { + ShowUsage(); + return 1; + } + + // ****************************************************************** + // * if we dont have an .xbe filename, generate one from exe_filename + // ****************************************************************** + if(szXbeFilename[0] == '\0') + { + strcpy(szXbeFilename, szExeFilename); + + char *szFilename = &szXbeFilename[0]; + + // ****************************************************************** + // * locate last \ or / (if there are any) + // ****************************************************************** + { + for(int c=0;szXbeFilename[c] != 0;c++) + { + if(szXbeFilename[c] == '\\' || szXbeFilename[c] == '/') + szFilename = &szXbeFilename[c+1]; + } + } + + // ****************************************************************** + // * locate and remove last . (if there are any) + // ****************************************************************** + { + char szWorkingU[266]; + + char *szWorking = szFilename; + + strncpy(szWorkingU, szWorking, 265); + + for(int c=0;szFilename[c] != 0;c++) + { + if(szFilename[c] == '.') + szWorking = &szFilename[c]; + } + + MakeUpper(szWorking); + + if(strcmp(szWorkingU, ".exe") == 0) + { + strcpy(szWorking, ".xbe"); + } + else + { + strcat(szXbeFilename, ".xbe"); + } + } + } + + // ****************************************************************** + // * open, and convert exe file + // ****************************************************************** + { + Exe *ExeFile = new Exe(szExeFilename); + + if(ExeFile->GetError() != 0) + { + strcpy(szErrorMessage, ExeFile->GetError()); + goto cleanup; + + } + + Xbe *XbeFile = new Xbe(ExeFile, szXbeTitle, bRetail); + + if(XbeFile->GetError() != 0) + { + strcpy(szErrorMessage, XbeFile->GetError()); + goto cleanup; + } + + if(szDumpFilename[0] != 0) + { + XbeFile->DumpInformation(szDumpFilename); + + if(XbeFile->GetError() != 0) + { + if(XbeFile->IsFatal()) + { + strcpy(szErrorMessage, XbeFile->GetError()); + goto cleanup; + } + else + { + printf("DUMPINFO -> Warning: %s\n", XbeFile->GetError()); + XbeFile->ClearError(); + } + } + } + + XbeFile->Export(szXbeFilename); + + if(XbeFile->GetError() != 0) + { + strcpy(szErrorMessage, XbeFile->GetError()); + goto cleanup; + } + } + +cleanup: + + if(szErrorMessage[0] != 0) + { + ShowUsage(); + + printf("\n"); + printf(" * Error : %s\n", szErrorMessage); + + return 1; + } + + return 0; +} + +// ****************************************************************** +// * ShowUsage +// ****************************************************************** +void ShowUsage() +{ + printf + ( + "CXBE XBE->EXE (XBox->Win32) Relinker (CXBX Core Version " CXBX_VERSION ")\n" + "Copyright (C) Aaron Robinson 2002-2003. All rights reserved.\n" + "\n" + "Usage : cxbe [options] [exefile]\n" + "\n" + "Options :\n" + "\n" + " -OUT:filename\n" + " -DUMPINFO:filename\n" + " -TITLE:title\n" + " -MODE:{debug|retail}\n" + ); +} + +// ****************************************************************** +// * MakeUpper +// ****************************************************************** +void MakeUpper(char *str) +{ + while(*str != '\0') + { + if(*str >= 'a' && *str <= 'z') + *str = *str - ('a' - 'A'); + + str++; + } +} diff --git a/Source/Win32/Cxbx/EmuExe.cpp b/Source/Win32/Cxbx/EmuExe.cpp new file mode 100644 index 000000000..74ea219dc --- /dev/null +++ b/Source/Win32/Cxbx/EmuExe.cpp @@ -0,0 +1,567 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->EmuExe.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#include "EmuExe.h" +#include "Prolog.h" +#include "Kernel.h" + +#include +#include + +// ****************************************************************** +// * constructor +// ****************************************************************** +EmuExe::EmuExe(Xbe *x_Xbe, uint32 x_debug_console) : Exe() +{ + ConstructorInit(); + + // ****************************************************************** + // * generate pe header + // ****************************************************************** + { + m_Header.m_magic = *(uint32 *)"PE\0\0"; // magic number : "PE\0\0" + m_Header.m_machine = IMAGE_FILE_MACHINE_I386; // machine type : i386 + m_Header.m_sections = (uint16)(x_Xbe->m_Header.dwSections + 2); // xbe sections + .cxbximp + .cxbxplg + m_Header.m_timedate = x_Xbe->m_Header.dwTimeDate; // time/date stamp + m_Header.m_symbol_table_addr = 0; // unused + m_Header.m_symbols = 0; // unused + m_Header.m_sizeof_optional_header = sizeof(OptionalHeader); // size of optional header + m_Header.m_characteristics = 0x010F; // should be fine.. + } + + // ****************************************************************** + // * generate optional header + // ****************************************************************** + { + m_OptionalHeader.m_magic = 0x010B; // magic number : 0x010B + + // ****************************************************************** + // * abitrary linker version : 6.0 + // ****************************************************************** + m_OptionalHeader.m_linker_version_major = 0x06; + m_OptionalHeader.m_linker_version_minor = 0x00; + + // ****************************************************************** + // * size of headers + // ****************************************************************** + m_OptionalHeader.m_sizeof_headers = sizeof(bzDOSStub) + sizeof(m_Header); + m_OptionalHeader.m_sizeof_headers += sizeof(m_OptionalHeader) + sizeof(*m_SectionHeader)*m_Header.m_sections; + m_OptionalHeader.m_sizeof_headers = RoundUp(m_OptionalHeader.m_sizeof_headers, PE_FILE_ALIGN); + + m_OptionalHeader.m_image_base = x_Xbe->m_Header.dwBaseAddr; + + m_OptionalHeader.m_section_alignment = PE_SEGM_ALIGN; + m_OptionalHeader.m_file_alignment = PE_FILE_ALIGN; + + // ****************************************************************** + // * OS version : 4.0 + // ****************************************************************** + m_OptionalHeader.m_os_version_major = 0x0004; + m_OptionalHeader.m_os_version_minor = 0x0000; + + // ****************************************************************** + // * image version : 0.0 + // ****************************************************************** + m_OptionalHeader.m_image_version_major = 0x0000; + m_OptionalHeader.m_image_version_minor = 0x0000; + + // ****************************************************************** + // * subsystem version : 4.0 + // ****************************************************************** + m_OptionalHeader.m_subsystem_version_major = 0x0004; + m_OptionalHeader.m_subsystem_version_minor = 0x0000; + + m_OptionalHeader.m_win32_version = 0x00000000; + m_OptionalHeader.m_checksum = 0x00000000; + m_OptionalHeader.m_subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; + + // ****************************************************************** + // * no special dll characteristics are necessary + // ****************************************************************** + m_OptionalHeader.m_dll_characteristics = 0x0000; + + // ****************************************************************** + // * TODO: for each of these, check for bad values and correct them + // ****************************************************************** + m_OptionalHeader.m_sizeof_stack_reserve = 0x00100000; + m_OptionalHeader.m_sizeof_stack_commit = 0x00001000; + m_OptionalHeader.m_sizeof_heap_reserve = x_Xbe->m_Header.dwPeHeapReserve; + m_OptionalHeader.m_sizeof_heap_commit = x_Xbe->m_Header.dwPeHeapCommit; + + // ****************************************************************** + // * this member is obsolete, so we'll just set it to zero + // ****************************************************************** + m_OptionalHeader.m_loader_flags = 0x00000000; + + // ****************************************************************** + // * we'll set this to the typical 0x10 (16) + // ****************************************************************** + m_OptionalHeader.m_data_directories = 0x10; + + // ****************************************************************** + // * clear all data directories (we'll setup some later) + // ****************************************************************** + for(uint32 d=0;dm_Header.dwSections;v++) + { + // ****************************************************************** + // * generate xbe section name + // ****************************************************************** + { + memset(m_SectionHeader[v].m_name, 0, 8); + + for(int c=0;c<8;c++) + { + m_SectionHeader[v].m_name[c] = x_Xbe->m_szSectionName[v][c]; + + if(m_SectionHeader[v].m_name[c] == '\0') + break; + } + } + + // ****************************************************************** + // * generate xbe section virtual size / addr + // ****************************************************************** + { + uint32 VirtSize = x_Xbe->m_SectionHeader[v].dwVirtualSize; + uint32 VirtAddr = x_Xbe->m_SectionHeader[v].dwVirtualAddr - x_Xbe->m_Header.dwBaseAddr; + + m_SectionHeader[v].m_virtual_size = VirtSize; + m_SectionHeader[v].m_virtual_addr = VirtAddr; + } + + // ****************************************************************** + // * generate xbe section raw size / addr + // ****************************************************************** + { + // TODO: get this working such that m_sizeof_raw can be the actual raw size, not virtual size + uint32 RawSize = RoundUp(x_Xbe->m_SectionHeader[v].dwVirtualSize, PE_FILE_ALIGN); + uint32 RawAddr = dwSectionCursor; + + m_SectionHeader[v].m_sizeof_raw = RawSize; + m_SectionHeader[v].m_raw_addr = RawAddr; + + dwSectionCursor += RawSize; + } + + // ****************************************************************** + // * relocation / line numbers will not exist + // ****************************************************************** + { + m_SectionHeader[v].m_relocations_addr = 0; + m_SectionHeader[v].m_linenumbers_addr = 0; + + m_SectionHeader[v].m_relocations = 0; + m_SectionHeader[v].m_linenumbers = 0; + } + + // ****************************************************************** + // * generate flags for this xbe section + // ****************************************************************** + { + uint32 flags = IMAGE_SCN_MEM_READ; + + if(x_Xbe->m_SectionHeader[v].dwFlags.bExecutable) + { + flags |= IMAGE_SCN_MEM_EXECUTE; + flags |= IMAGE_SCN_CNT_CODE; + } + else + { + flags |= IMAGE_SCN_CNT_INITIALIZED_DATA; + } + + if(x_Xbe->m_SectionHeader[v].dwFlags.bWritable) + flags |= IMAGE_SCN_MEM_WRITE; + + m_SectionHeader[v].m_characteristics = flags; + } + } + } + + // ****************************************************************** + // * generate .cxbximp section header + // ****************************************************************** + { + uint32 i = m_Header.m_sections - 2; + + memcpy(m_SectionHeader[i].m_name, ".cxbximp", 8); + + // ****************************************************************** + // * generate .cxbximp section virtual size / addr + // ****************************************************************** + { + uint32 virt_size = RoundUp(0x55, PE_SEGM_ALIGN); + uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN); + + m_SectionHeader[i].m_virtual_size = virt_size; + m_SectionHeader[i].m_virtual_addr = virt_addr; + } + + // ****************************************************************** + // * generate .cxbximp section raw size / addr + // ****************************************************************** + { + uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN); + + m_SectionHeader[i].m_sizeof_raw = raw_size; + m_SectionHeader[i].m_raw_addr = dwSectionCursor; + + dwSectionCursor += raw_size; + } + + // ****************************************************************** + // * relocation / line numbers will not exist + // ****************************************************************** + { + m_SectionHeader[i].m_relocations_addr = 0; + m_SectionHeader[i].m_linenumbers_addr = 0; + + m_SectionHeader[i].m_relocations = 0; + m_SectionHeader[i].m_linenumbers = 0; + } + + // ****************************************************************** + // * make this section readable initialized data + // ****************************************************************** + m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA; + + // ****************************************************************** + // * update import table directory entry + // ****************************************************************** + m_OptionalHeader.m_image_data_directory[1].m_virtual_addr = m_SectionHeader[i].m_virtual_addr + 0x08; + m_OptionalHeader.m_image_data_directory[1].m_size = 0x28; + + // ****************************************************************** + // * update import address table directory entry + // ****************************************************************** + m_OptionalHeader.m_image_data_directory[12].m_virtual_addr = m_SectionHeader[i].m_virtual_addr; + m_OptionalHeader.m_image_data_directory[12].m_size = 0x08; + } + + // ****************************************************************** + // * generate .cxbxplg section header + // ****************************************************************** + { + uint32 i = m_Header.m_sections - 1; + + memcpy(m_SectionHeader[i].m_name, ".cxbxplg", 8); + + // ****************************************************************** + // * generate .cxbxplg section virtual size / addr + // ****************************************************************** + { + uint32 virt_size = RoundUp(0x1000 + x_Xbe->m_Header.dwSizeofHeaders, 0x1000); + uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN); + + m_SectionHeader[i].m_virtual_size = virt_size; + m_SectionHeader[i].m_virtual_addr = virt_addr; + + // our entry point should be the first bytes in this section + m_OptionalHeader.m_entry = virt_addr; + } + + // ****************************************************************** + // * generate .cxbxplg section raw size / addr + // ****************************************************************** + { + uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN); + + m_SectionHeader[i].m_sizeof_raw = raw_size; + m_SectionHeader[i].m_raw_addr = dwSectionCursor; + + dwSectionCursor += raw_size; + } + + // ****************************************************************** + // * relocation / line numbers will not exist + // ****************************************************************** + { + m_SectionHeader[i].m_relocations_addr = 0; + m_SectionHeader[i].m_linenumbers_addr = 0; + + m_SectionHeader[i].m_relocations = 0; + m_SectionHeader[i].m_linenumbers = 0; + } + + // ****************************************************************** + // * make this section readable and executable + // ****************************************************************** + m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE; + } + } + + // ****************************************************************** + // * generate sections + // ****************************************************************** + { + m_bzSection = new uint08*[m_Header.m_sections]; + + // ****************************************************************** + // * generate xbe sections + // ****************************************************************** + { + uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr; + + // ****************************************************************** + // * decode kernel thunk address + // ****************************************************************** + { + if(kt ^ XOR_KT_DEBUG > 0x01000000) + kt ^= XOR_KT_RETAIL; + else + kt ^= XOR_KT_DEBUG; + } + + // ****************************************************************** + // * generate xbe sections + // ****************************************************************** + for(uint32 v=0;vm_Header.dwSections;v++) + { + uint32 SectionSize = m_SectionHeader[v].m_sizeof_raw; + + m_bzSection[v] = new uint08[SectionSize]; + + memset(m_bzSection[v], 0, SectionSize); + + memcpy(m_bzSection[v], x_Xbe->m_bzSection[v], x_Xbe->m_SectionHeader[v].dwSizeofRaw); + } + + } + + // ****************************************************************** + // * generate .cxbximp section + // ****************************************************************** + { + // ****************************************************************** + // * TODO: fix up this entire chunk of code, it is a total hack + // ****************************************************************** + uint32 i = m_Header.m_sections - 2; + + uint32 dwVirtAddr = m_SectionHeader[i].m_virtual_addr; + + uint32 dwRawSize = m_SectionHeader[i].m_sizeof_raw; + + m_bzSection[i] = new uint08[dwRawSize]; + + memset(m_bzSection[i], 0, dwRawSize); + + *(uint32*)&m_bzSection[i][0x00] = dwVirtAddr + 0x38; + *(uint32*)&m_bzSection[i][0x04] = 0; + *(uint32*)&m_bzSection[i][0x08] = dwVirtAddr + 0x30; + *(uint32*)&m_bzSection[i][0x0C] = 0; + + *(uint32*)&m_bzSection[i][0x10] = 0; + *(uint32*)&m_bzSection[i][0x14] = dwVirtAddr + 0x48; + *(uint32*)&m_bzSection[i][0x18] = dwVirtAddr + 0x00; + *(uint32*)&m_bzSection[i][0x1C] = 0; + + *(uint32*)&m_bzSection[i][0x20] = 0; + *(uint32*)&m_bzSection[i][0x24] = 0; + *(uint32*)&m_bzSection[i][0x28] = 0; + *(uint32*)&m_bzSection[i][0x2C] = 0; + + *(uint32*)&m_bzSection[i][0x30] = dwVirtAddr + 0x38; + *(uint32*)&m_bzSection[i][0x34] = 0; + *(uint16*)&m_bzSection[i][0x38] = 0x0001; + + memcpy(&m_bzSection[i][0x3A], "_EmuXDummy@0\0\0cxbx.dll\0\0\0\0\0\0", 28); + } + + // ****************************************************************** + // * generate .cxbxplg section + // ****************************************************************** + { + uint32 ep = x_Xbe->m_Header.dwEntryAddr; + uint32 i = m_Header.m_sections - 1; + + // ****************************************************************** + // * decode entry point + // ****************************************************************** + if( (ep ^ XOR_EP_RETAIL) > 0x01000000) + ep ^= XOR_EP_DEBUG; + else + ep ^= XOR_EP_RETAIL; + + m_bzSection[i] = new uint08[m_SectionHeader[i].m_sizeof_raw]; + + // ****************************************************************** + // * append prolog section + // ****************************************************************** + memcpy(m_bzSection[i], Prolog, 0x1000); + + // ****************************************************************** + // * append xbe header + // ****************************************************************** + memcpy(m_bzSection[i] + 0x100, &x_Xbe->m_Header, sizeof(Xbe::Header)); + + // ****************************************************************** + // * append xbe extra header bytes + // ****************************************************************** + memcpy(m_bzSection[i] + 0x100 + sizeof(Xbe::Header), x_Xbe->m_HeaderEx, x_Xbe->m_Header.dwSizeofHeaders - sizeof(Xbe::Header)); + + // ****************************************************************** + // * patch prolog function parameters + // ****************************************************************** + *(uint32 *)((uint32)m_bzSection[i] + 1) = (uint32)EmuXInit; + *(uint32 *)((uint32)m_bzSection[i] + 6) = (uint32)ep; + *(uint32 *)((uint32)m_bzSection[i] + 11) = (uint32)x_Xbe->m_Header.dwSizeofHeaders; + *(uint32 *)((uint32)m_bzSection[i] + 16) = m_SectionHeader[i].m_virtual_addr + m_OptionalHeader.m_image_base + 0x100; + *(uint32 *)((uint32)m_bzSection[i] + 21) = x_debug_console; + } + } + + // ****************************************************************** + // * patch kernel thunk table + // ****************************************************************** + { + uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr; + + // ****************************************************************** + // * decode kernel thunk address + // ****************************************************************** + { + if( (kt ^ XOR_KT_DEBUG) > 0x01000000) + kt ^= XOR_KT_RETAIL; + else + kt ^= XOR_KT_DEBUG; + } + + // ****************************************************************** + // * locate section containing kernel thunk table + // ****************************************************************** + for(uint32 v=0;vm_Header.dwSections;v++) + { + uint32 imag_base = m_OptionalHeader.m_image_base; + + uint32 virt_addr = m_SectionHeader[v].m_virtual_addr; + uint32 virt_size = m_SectionHeader[v].m_virtual_size; + + // ****************************************************************** + // * modify kernel thunk table, if found + // ****************************************************************** + if(kt >= virt_addr + imag_base && kt < virt_addr + virt_size + imag_base) + { + uint32 *kt_tbl = (uint32*)&m_bzSection[v][kt - virt_addr - imag_base]; + + while(*kt_tbl != 0) + *kt_tbl++ = KernelThunkTable[*kt_tbl & 0x7FFFFFFF]; + + break; + } + } + } + + // ****************************************************************** + // * update imcomplete header fields + // ****************************************************************** + { + // ****************************************************************** + // * calculate size of code / data / image + // ****************************************************************** + { + uint32 sizeof_code = 0; + uint32 sizeof_data = 0; + uint32 sizeof_undata = 0; + uint32 sizeof_image = 0; + + for(uint32 v=0;vWin32->Cxbx->Prolog.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +// ****************************************************************** +// * .cxbxplg +// ****************************************************************** +#pragma code_seg(".cxbxplg") +#pragma comment(linker, "/SECTION:.cxbxplg,RW") + +// ****************************************************************** +// * Func : Prolog +// ****************************************************************** +__declspec(allocate(".cxbxplg")) uint08 Prolog[] = +{ + // ****************************************************************** + // * + // * WARNING: + // * + // * This function is hard-coded as an array to stress the point that + // * it can not be modified (unless you really know what you're + // * doing). EmuExe will modify the contents of this function + // * directly, so this precise structure is necessary. + // * + // ****************************************************************** + 0xBE, 0xC3, 0xC3, 0xC3, 0xC3, // mov esi, 0xC3C3C3C3 + 0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3 + 0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3 + 0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3 + 0x68, 0xC3, 0xC3, 0xC3, 0xC3, // push 0xC3C3C3C3 + 0xFF, 0xD6, // call esi + 0xC3 // ret +}; + +#pragma code_seg() diff --git a/Source/Win32/Cxbx/WinMain.cpp b/Source/Win32/Cxbx/WinMain.cpp new file mode 100644 index 000000000..1f08356b9 --- /dev/null +++ b/Source/Win32/Cxbx/WinMain.cpp @@ -0,0 +1,56 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->WinMain.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" +#include "EmuExe.h" +#include "WndMain.h" + +#include + +// ****************************************************************** +// * func : WinMain +// ****************************************************************** +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + WndMain *caustik = new WndMain(hInstance); + + while(caustik->GetError() == 0 && caustik->ProcessMessages()) + Sleep(10); + + if(caustik->GetError() != 0) + MessageBox(NULL, caustik->GetError(), "cxbx", MB_OK); + + delete caustik; + + return 0; +} \ No newline at end of file diff --git a/Source/Win32/Cxbx/Wnd.cpp b/Source/Win32/Cxbx/Wnd.cpp new file mode 100644 index 000000000..ce7c1125d --- /dev/null +++ b/Source/Win32/Cxbx/Wnd.cpp @@ -0,0 +1,177 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->Wnd.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" +#include "Wnd.h" + +#include "resource.h" + +// ****************************************************************** +// * constructor +// ****************************************************************** +Wnd::Wnd(HINSTANCE x_hInstance) : m_hInstance(x_hInstance) +{ + m_classname = "CxbxWnd"; + m_wndname = "Cxbx Generic Window"; + m_x = 150; + m_y = 150; + m_w = 320; + m_h = 240; + m_parent = NULL; + m_clsstyle = CS_HREDRAW | CS_VREDRAW; + m_wndstyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE; + m_background = (HBRUSH)GetStockObject(BLACK_BRUSH); + m_initialized = false; + + return; +} + +// ****************************************************************** +// * deconstructor +// ****************************************************************** +Wnd::~Wnd() +{ +} + +// ****************************************************************** +// * ProcessMessages +// ****************************************************************** +bool Wnd::ProcessMessages() +{ + // initialize window + if(!m_initialized) + { + m_initialized = true; + + WNDCLASS wnd_class; + + wnd_class.hInstance = m_hInstance; + wnd_class.lpszClassName = m_classname; + wnd_class.lpfnWndProc = WndProcForward; + wnd_class.style = m_clsstyle; + wnd_class.hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_CXBX)); + wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW); + wnd_class.lpszMenuName = NULL; + wnd_class.cbClsExtra = 0; + wnd_class.cbWndExtra = 0; + wnd_class.hbrBackground = m_background; + + m_class = RegisterClass(&wnd_class); + + m_hwnd = CreateWindowEx + ( + NULL, + m_classname, + m_wndname, + m_wndstyle, + m_x, + m_y, + m_w, + m_h, + m_parent, + NULL, + m_hInstance, + this + ); + + if(m_hwnd == 0) + { + SetError("Could not create window.", true); + UnregisterClass(m_classname, m_hInstance); + goto cleanup; + } + + SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this); + +cleanup:; + + } + + MSG msg; + + if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) + { + if(!GetMessage(&msg, NULL, 0, 0)) + { + UnregisterClass(m_classname, m_hInstance); + return false; + } + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return true; +} + +// ****************************************************************** +// * WndProcForward +// ****************************************************************** +LRESULT CALLBACK Wnd::WndProcForward(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + Wnd *forward_to = (Wnd*)GetWindowLong(hwnd, GWL_USERDATA); + + if(forward_to == 0) + { + if(uMsg == WM_CREATE) + { + LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; + + forward_to = (Wnd*)cs->lpCreateParams; + }else{ + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + } + + return forward_to->WndProc(hwnd, uMsg, wParam, lParam); +} + +// ****************************************************************** +// * WndProc +// ****************************************************************** +LRESULT CALLBACK Wnd::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_CLOSE: + DestroyWindow(hwnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + + return 0; +} diff --git a/Source/Win32/Cxbx/WndAbout.cpp b/Source/Win32/Cxbx/WndAbout.cpp new file mode 100644 index 000000000..cb926272d --- /dev/null +++ b/Source/Win32/Cxbx/WndAbout.cpp @@ -0,0 +1,184 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->WndAbout.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" +#include "WndAbout.h" + +#include "resource.h" + +// ****************************************************************** +// * constructor +// ****************************************************************** +WndAbout::WndAbout(HINSTANCE x_hInstance, HWND x_parent) : Wnd(x_hInstance) +{ + m_classname = "WndAbout"; + m_wndname = "Cxbx - About"; + + m_w = 200; + m_h = 120; + + // center to parent + { + RECT rect; + + GetWindowRect(x_parent, &rect); + + m_x = rect.left + (rect.right - rect.left)/2 - m_w/2; + m_y = rect.top + (rect.bottom - rect.top)/2 - m_h/2; + } + + m_parent = x_parent; + m_wndstyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_VISIBLE; + + return; +} + +// ****************************************************************** +// * deconstructor +// ****************************************************************** +WndAbout::~WndAbout() +{ +} + +// ****************************************************************** +// * WndProc +// ****************************************************************** +LRESULT CALLBACK WndAbout::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_CREATE: + { + EnableWindow(m_parent, FALSE); + + HDC hDC = GetDC(hwnd); + + int nHeight = -MulDiv(8, GetDeviceCaps(hDC, LOGPIXELSY), 72); + + m_hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_ROMAN, "verdana"); + + ReleaseDC(hwnd, hDC); + } + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hwnd, &ps); + + HDC hDC = GetDC(hwnd); + + // draw text + { + HGDIOBJ tmpObj = SelectObject(hDC, m_hFont); + + // draw top version bar and bottom url bar + { + SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); + + SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + + // top version bar + { + char buffer[] = " Cxbx Version " CXBX_VERSION; + + RECT rect = {0, 0, 200, 14}; + ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rect, buffer, strlen(buffer), 0); + } + + // bottom url bar + { + char buffer[] = " http://www.caustik.com/xbox/"; + + RECT rect = {0, 74, 200, 88}; + ExtTextOut(hDC, 0, 74, ETO_OPAQUE, &rect, buffer, strlen(buffer), 0); + } + } + + // draw credits + { + SetBkColor(hDC, RGB(0,0,0)); + + SetTextColor(hDC, RGB(0xFF,0xFF,0xFF)); + + char bufferA[] = " The First XBox Emulator"; + char bufferB[] = " Designed and Coded by Caustik"; + char bufferC[] = " (Click Window to Close)"; + + RECT rectA = {0, 22, 200, 37}; + ExtTextOut(hDC, 0, 22, ETO_OPAQUE, &rectA, bufferA, strlen(bufferA), 0); + + RECT rectB = {0, 37, 200, 51}; + ExtTextOut(hDC, 0, 37, ETO_OPAQUE, &rectB, bufferB, strlen(bufferB), 0); + + RECT rectC = {22, 53, 70, 67}; + ExtTextOut(hDC, 22, 53, ETO_OPAQUE, &rectC, bufferC, strlen(bufferC), 0); + } + + SelectObject(hDC, tmpObj); + } + + if(hDC != NULL) + ReleaseDC(hwnd, hDC); + + EndPaint(hwnd, &ps); + } + break; + + case WM_LBUTTONUP: + { + SendMessage(hwnd, WM_CLOSE, 0, 0); + } + break; + + case WM_CLOSE: + { + EnableWindow(m_parent, TRUE); + DestroyWindow(hwnd); + } + break; + + case WM_DESTROY: + { + DeleteObject(m_hFont); + PostQuitMessage(0); + } + break; + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + + return 0; +} \ No newline at end of file diff --git a/Source/Win32/Cxbx/WndMain.cpp b/Source/Win32/Cxbx/WndMain.cpp new file mode 100644 index 000000000..b7513f6b8 --- /dev/null +++ b/Source/Win32/Cxbx/WndMain.cpp @@ -0,0 +1,1183 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->Cxbx->WndMain.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" +#include "EmuExe.h" +#include "Kernel.h" +#include "WndMain.h" +#include "WndAbout.h" + +#include "resource.h" + +#include + +// ****************************************************************** +// * constructor +// ****************************************************************** +WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_xbe(0), m_exe(0), m_exe_changed(false), m_xbe_changed(false), m_krnl_debug(0) +{ + m_classname = "WndMain"; + m_wndname = "Cxbx: Version " CXBX_VERSION; + + m_w = 327; + m_h = 253; + + // center to desktop + { + RECT rect; + + GetWindowRect(GetDesktopWindow(), &rect); + + m_x = rect.left + (rect.right - rect.left)/2 - m_w/2; + m_y = rect.top + (rect.bottom - rect.top)/2 - m_h/2; + } + + m_exe_filename = new char[260]; + m_exe_filename[0] = '\0'; + + m_xbe_filename = new char[260]; + m_xbe_filename[0] = '\0'; + + return; +} + +// ****************************************************************** +// * deconstructor +// ****************************************************************** +WndMain::~WndMain() +{ + delete[] m_xbe_filename; + delete[] m_exe_filename; +} + +// ****************************************************************** +// * WndProc +// ****************************************************************** +LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_CREATE: + { + // resize so that client area = 321x201 + { + RECT cRect = {0}; + RECT wRect = {0}; + + GetClientRect(hwnd, &cRect); + GetWindowRect(hwnd, &wRect); + + uint32 difW = (wRect.right - wRect.left) - (cRect.right); + uint32 difH = (wRect.bottom - wRect.top) - (cRect.bottom); + + MoveWindow(hwnd, wRect.left, wRect.top, difW + 321, difH + 221, TRUE); + } + + // initialize menu + { + HMENU hMenu = LoadMenu(m_hInstance, MAKEINTRESOURCE(IDR_MAINMENU)); + + SetMenu(hwnd, hMenu); + } + + // initialize back buffer + { + HDC hDC = GetDC(hwnd); + + m_back_bmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_SPLASH), IMAGE_BITMAP, 0, 0, 0); + m_logo_bmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_LOGO), IMAGE_BITMAP, 0, 0, 0); + + m_back_dc = CreateCompatibleDC(hDC); + m_logo_dc = CreateCompatibleDC(hDC); + + m_orig_bmp = (HBITMAP)SelectObject(m_back_dc, m_back_bmp); + m_orig_logo = (HBITMAP)SelectObject(m_logo_dc, m_logo_bmp); + + if(hDC != NULL) + ReleaseDC(hwnd, hDC); + } + } + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint(hwnd, &ps); + + HDC hDC = GetDC(hwnd); + + BitBlt(hDC, 0, 0, 320, 160, m_back_dc, 0, 0, SRCCOPY); + BitBlt(hDC, 220, 168, 100, 17, m_logo_dc, 0, 0, SRCCOPY); + + // draw status bar + { + int nHeight = -MulDiv(8, GetDeviceCaps(hDC, LOGPIXELSY), 72); + + HFONT hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_ROMAN, "verdana"); + + HGDIOBJ tmpObj = SelectObject(hDC, hFont); + + SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); + + SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + + char buffer[255]; + + if(m_xbe != 0 && m_xbe->GetError() == 0) + sprintf(buffer, "%s Loaded!", m_xbe->m_szAsciiTitle); + else + sprintf(buffer, "%s", "Disclaimer: CXBX has no affiliation with Microsoft"); + + RECT rect = {0, 187, 321, 201}; + + ExtTextOut(hDC, 5, 187, ETO_OPAQUE, &rect, buffer, strlen(buffer), 0); + + SelectObject(hDC, tmpObj); + + DeleteObject(hFont); + } + + if(hDC != NULL) + ReleaseDC(hwnd, hDC); + + EndPaint(hwnd, &ps); + } + break; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case ID_FILE_OPEN_XBE: + { + m_exe_filename[0] = '\0'; + + OPENFILENAME ofn = {0}; + + char filename[260] = {0}; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = ".xbe file (*.xbe)\0*.xbe\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if(GetOpenFileName(&ofn) == TRUE) + { + strcpy(m_xbe_filename, ofn.lpstrFile); + + m_xbe = new Xbe(ofn.lpstrFile); + + if(m_xbe->GetError() != 0) + { + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + + delete m_xbe; m_xbe = 0; + + break; + } + + XbeLoaded(); + } + + } + break; + + case ID_FILE_CLOSE_XBE: + { + CloseXbe(); + } + break; + + case ID_FILE_SAVEXBEFILE: + { + if(m_xbe_filename[0] == '\0') + SaveXbeAs(); + else + SaveXbe(m_xbe_filename); + } + break; + + case ID_FILE_SAVEXBEFILEAS: + { + SaveXbeAs(); + } + break; + + case ID_FILE_IMPORTFROMEXE: + { + m_exe_filename[0] = '\0'; + + OPENFILENAME ofn = {0}; + + char filename[260] = {0}; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Win32 Executable file (*.exe)\0*.exe\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if(GetOpenFileName(&ofn) == TRUE) + { + m_xbe_filename[0] = '\0'; + + Exe *tmp = new Exe(ofn.lpstrFile); + + if(tmp->GetError() != 0) + { + MessageBox(m_hwnd, tmp->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + + delete tmp; + + break; + } + + m_xbe = new Xbe(tmp, "Untitled", true); + + if(m_xbe->GetError() != 0) + { + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + + delete m_xbe; m_xbe = 0; + + break; + } + + XbeLoaded(); + + m_exe_changed = true; + } + } + break; + + case ID_FILE_EXPORTTOEXE: + ConvertToExe(); + break; + + case ID_FILE_EXIT: + SendMessage(hwnd, WM_CLOSE, 0, 0); + break; + + case ID_EDIT_LOGOBITMAP_EXPORT: + { + OPENFILENAME ofn = {0}; + + char filename[260] = "logo.bmp"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Bitmap file (*.bmp)\0*.bmp\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "bmp"; + ofn.lpstrTitle = "Export Logo Bitmap"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if(GetSaveFileName(&ofn) == TRUE) + { + // check if file exists + { + FILE *tmp = fopen(ofn.lpstrFile, "r"); + + if(tmp != 0) + { + fclose(tmp); + + if(MessageBox(m_hwnd, "overwrite existing file?", "Cxbx", MB_ICONQUESTION | MB_YESNO) != IDYES) + return TRUE; + } + } + + // export logo bitmap + { + uint08 i_gray[100*17]; + + m_xbe->ExportLogoBitmap(i_gray); + + if(m_xbe->GetError() == 0) + { + FILE *logo = fopen(ofn.lpstrFile, "wb"); + + // write bitmap header + { + BITMAPFILEHEADER bmfh; + + bmfh.bfType = *(uint16*)"BM"; + bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD) + (100*17)*sizeof(RGBTRIPLE) + 2; + bmfh.bfReserved1 = 0; + bmfh.bfReserved2 = 0; + bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD); + + fwrite(&bmfh, sizeof(bmfh), 1, logo); + } + + // write bitmap info + { + BITMAPINFO bmi; + + bmi.bmiHeader.biSize = sizeof(BITMAPINFO) - sizeof(RGBQUAD); + bmi.bmiHeader.biWidth = 100; + bmi.bmiHeader.biHeight = -17; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 24; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + + fwrite(&bmi, sizeof(bmi) - 4, 1, logo); + } + + // write bitmap data + { + RGBTRIPLE bmp_data[100*17]; + + for(uint32 v=0;v<100*17;v++) + { + bmp_data[v].rgbtRed = i_gray[v]; + bmp_data[v].rgbtGreen = i_gray[v]; + bmp_data[v].rgbtBlue = i_gray[v]; + } + + fwrite(bmp_data, 100*17*sizeof(RGBTRIPLE), 1, logo); + } + + // padd the extra 2 bytes + { + uint16 pad = 0; + + fwrite(&pad, 2, 1, logo); + } + + fclose(logo); + } + + if(m_xbe->GetError() != 0) + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + else + { + char buffer[255]; + + sprintf(buffer, "%s's logo bitmap was successfully exported.", m_xbe->m_szAsciiTitle); + + MessageBox(m_hwnd, buffer, "Cxbx", MB_ICONINFORMATION | MB_OK); + + printf("%s\n", buffer); + } + } + } + } + break; + + case ID_EDIT_LOGOBITMAP_IMPORT: + { + OPENFILENAME ofn = {0}; + + char filename[260] = "*.bmp"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Bitmap file (*.bmp)\0*.bmp\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "bmp"; + ofn.lpstrTitle = "Import Logo Bitmap"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if(GetOpenFileName(&ofn) == TRUE) + { + // import logo bitmap + { + uint08 i_gray[100*17]; + + // read bitmap file + { + FILE *logo = fopen(ofn.lpstrFile, "rb"); + + char *bmp_err = 0; + + // read bitmap header + if(!bmp_err) + { + BITMAPFILEHEADER bmfh; + + fread(&bmfh, sizeof(bmfh), 1, logo); + + if(bmfh.bfType != *(uint16*)"BM") + bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; + else if(bmfh.bfSize != sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) - sizeof(RGBQUAD) + (100*17)*sizeof(RGBTRIPLE) + 2) + bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; + } + + // read bitmap info + if(!bmp_err) + { + BITMAPINFO bmi; + + fread(&bmi, sizeof(bmi) - 4, 1, logo); + + if(bmi.bmiHeader.biWidth != 100 || bmi.bmiHeader.biHeight != -17) + bmp_err = "Invalid bitmap file...\n\nonly allows 24 bit bitmaps (100 by 17 pixels) with row order swapped"; + } + + // read bitmap data + if(!bmp_err) + { + RGBTRIPLE bmp_data[100*17]; + + fread(bmp_data, 100*17*sizeof(RGBTRIPLE), 1, logo); + + for(uint32 c=0;c<100*17;c++) + i_gray[c] = (char)(((float)bmp_data[c].rgbtRed + (float)bmp_data[c].rgbtGreen + (float)bmp_data[c].rgbtBlue) / 3.0); + } + + fclose(logo); + + if(bmp_err != 0) + { + MessageBox(m_hwnd, bmp_err, "Cxbx", MB_OK | MB_ICONEXCLAMATION); + break; + } + } + + m_xbe->ImportLogoBitmap(i_gray); + + if(m_xbe->GetError() != 0) + { + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + + if(m_xbe->IsFatal()) + CloseXbe(); + else + m_xbe->ClearError(); + } + else + { + m_exe_changed = true; + m_xbe_changed = true; + + LoadLogo(); + + char buffer[255]; + + sprintf(buffer, "%s's logo bitmap was successfully updated.", m_xbe->m_szAsciiTitle); + + printf("%s\n", buffer); + + MessageBox(m_hwnd, buffer, "Cxbx", MB_ICONINFORMATION | MB_OK); + } + } + } + } + break; + + case ID_EDIT_PATCH_ALLOW64MB: + { + m_exe_changed = true; + m_xbe_changed = true; + + m_xbe->m_Header.dwInitFlags.bLimit64MB = !m_xbe->m_Header.dwInitFlags.bLimit64MB; + + HMENU menu = GetMenu(m_hwnd); + HMENU edit_menu = GetSubMenu(menu, 1); + HMENU pach_menu = GetSubMenu(edit_menu, 1); + + // check "allow >64 MB" if appropriate + { + bool res = m_xbe->m_Header.dwInitFlags.bLimit64MB; + + UINT chk_flag = (res) ? MF_UNCHECKED : MF_CHECKED; + + if(res) + printf("Cxbx: %s was patched to limit to 64MB of memory usage.\n", m_xbe->m_szAsciiTitle); + else + printf("Cxbx: %s was patched to allow >64MB of memory usage.\n", m_xbe->m_szAsciiTitle); + + CheckMenuItem(pach_menu, ID_EDIT_PATCH_ALLOW64MB, chk_flag); + } + } + break; + + case ID_EDIT_PATCH_DEBUGMODE: + { + m_exe_changed = true; + m_xbe_changed = true; + + // patch to/from debug mode + if((m_xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000) + { + // we're in debug mode, so switch over to retail + uint32 ep = m_xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL; // decode from debug mode + uint32 kt = m_xbe->m_Header.dwKernelImageThunkAddr ^ XOR_KT_DEBUG; // decode from debug mode + + m_xbe->m_Header.dwEntryAddr = ep ^ XOR_EP_DEBUG; // encode to retail mode + m_xbe->m_Header.dwKernelImageThunkAddr = kt ^ XOR_KT_RETAIL; // encode to retail mode + } + else + { + // we're in retail mode, so switch to debug + uint32 ep = m_xbe->m_Header.dwEntryAddr ^ XOR_EP_DEBUG; // decode from retail mode + uint32 kt = m_xbe->m_Header.dwKernelImageThunkAddr ^ XOR_KT_RETAIL; // decode from retail mode + + m_xbe->m_Header.dwEntryAddr = ep ^ XOR_EP_RETAIL; // encode to debug mode + m_xbe->m_Header.dwKernelImageThunkAddr = kt ^ XOR_KT_DEBUG; // encode to debug mode + } + + HMENU menu = GetMenu(m_hwnd); + HMENU edit_menu = GetSubMenu(menu, 1); + + HMENU pach_menu = GetSubMenu(edit_menu, 1); + + // check "debug mode" if appropriate + { + bool res = (m_xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000; + + UINT chk_flag = (res) ? MF_CHECKED : MF_UNCHECKED; + + if(res) + printf("Cxbx: %s was converted to debug mode.\n", m_xbe->m_szAsciiTitle); + else + printf("Cxbx: %s was converted to retail mode.\n", m_xbe->m_szAsciiTitle); + + CheckMenuItem(pach_menu, ID_EDIT_PATCH_DEBUGMODE, chk_flag); + } + } + break; + + case ID_EDIT_EXTRACTXBEINFO: + { + OPENFILENAME ofn = {0}; + + char filename[260] = "Xbe.txt"; + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "text file (*.txt)\0*.txt\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "txt"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if(GetSaveFileName(&ofn) == TRUE) + { + // check if file exists + { + FILE *tmp = fopen(ofn.lpstrFile, "r"); + + if(tmp != 0) + { + fclose(tmp); + + if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx", MB_ICONQUESTION | MB_YESNO) != IDYES) + return TRUE; + } + } + + // convert file + { + m_xbe->DumpInformation(ofn.lpstrFile); + + if(m_xbe->GetError() != 0) + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + else + { + char buffer[255]; + + sprintf(buffer, "%s's .xbe info was successfully exported.", m_xbe->m_szAsciiTitle); + + printf("%s\n", buffer); + + MessageBox(m_hwnd, buffer, "Cxbx", MB_ICONINFORMATION | MB_OK); + } + } + } + } + break; + + case ID_VIEW_KERNELDEBUGCONSOLE: + { + HMENU menu = GetMenu(m_hwnd); + HMENU view_menu = GetSubMenu(menu, 2); + + if(m_krnl_debug == 0) + { + m_krnl_debug = 1; + + CheckMenuItem(view_menu, ID_VIEW_KERNELDEBUGCONSOLE, MF_CHECKED); + } + else + { + m_krnl_debug = 0; + + CheckMenuItem(view_menu, ID_VIEW_KERNELDEBUGCONSOLE, MF_UNCHECKED); + } + + MessageBox(m_hwnd, "This will not take effect until emulation is (re)started.\n", "Cxbx", MB_OK); + } + break; + + case ID_VIEW_DEBUGCONSOLE: + { + HMENU menu = GetMenu(m_hwnd); + HMENU view_menu = GetSubMenu(menu, 2); + + if(AllocConsole()) + { + freopen("CONOUT$", "w", stdout); + + printf("%s", "Cxbx: Debug console allocated.\n"); + + CheckMenuItem(view_menu, ID_VIEW_DEBUGCONSOLE, MF_CHECKED); + } + else + { + FreeConsole(); + CheckMenuItem(view_menu, ID_VIEW_DEBUGCONSOLE, MF_UNCHECKED); + } + } + break; + + case ID_EMULATION_START: + { + if(m_exe_filename[0] == '\0' || m_exe_changed) + if(!ConvertToExe()) + break; + + // shell .exe + { + char dir[260]; + + GetModuleFileName(NULL, dir, 260); + + sint32 spot=-1; + for(int v=0;v<260;v++) + { + if(dir[v] == '\\') + spot = v; + else if(dir[v] == '\0') + break; + } + + if(spot != -1) + dir[spot] = '\0'; + + if((int)ShellExecute(NULL, "open", m_exe_filename, NULL, dir, SW_SHOWDEFAULT) <= 32) + { + MessageBox(m_hwnd, "Shell failed. (try converting .exe again)", "Cxbx", MB_ICONSTOP | MB_OK); + + printf("Cxbx: %s shell failed.\n", m_xbe->m_szAsciiTitle); + } + else + { + printf("Cxbx: %s emulation started.\n", m_xbe->m_szAsciiTitle); + } + } + } + break; + + case ID_HELP_ABOUT: + { + WndAbout *AboutWnd = new WndAbout(m_hInstance, m_hwnd); + + while(AboutWnd->GetError() == 0 && AboutWnd->ProcessMessages()) + Sleep(10); + + if(AboutWnd->GetError() != 0) + MessageBox(m_hwnd, AboutWnd->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + + delete AboutWnd; + } + break; + + case ID_HELP_HOMEPAGE: + { + ShellExecute(NULL, "open", "http://www.caustik.com/xbox/", NULL, NULL, SW_SHOWNORMAL); + } + break; + } + + break; + } + + case WM_CLOSE: + if(m_xbe_changed) + { + int ret = MessageBox(m_hwnd, "Changes have been made, do you wish to save?", "Cxbx", MB_ICONQUESTION | MB_YESNOCANCEL); + + if(ret == IDYES) + SaveXbeAs(); + else if(ret == IDCANCEL) + break; + } + DestroyWindow(hwnd); + break; + + case WM_DESTROY: + { + FreeConsole(); + + HDC hDC = GetDC(hwnd); + + SelectObject(m_logo_dc, m_orig_logo); + + SelectObject(m_back_dc, m_orig_bmp); + + DeleteObject(m_logo_dc); + + DeleteObject(m_back_dc); + + DeleteObject(m_logo_bmp); + + DeleteObject(m_back_bmp); + + ReleaseDC(hwnd, hDC); + + if(m_xbe != 0) + { + delete m_xbe; + m_xbe = 0; + } + + PostQuitMessage(0); + } + break; + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + + return 0; +} + +// ****************************************************************** +// * SuggestFilename +// ****************************************************************** +void WndMain::SuggestFilename(const char *x_orig_filename, char *x_filename, char x_extension[4]) +{ + uint32 found = 0; + uint32 v = 0; + + while(x_orig_filename[v] != '\0') + { + if(x_orig_filename[v] == '\\') + found = v; + v++; + } + + if(found != 0) + { + strcpy(x_filename, x_orig_filename + found + 1); + + uint32 loc = 0; + uint32 c = 0; + + while(x_filename[c] != '\0') + { + if(x_filename[c] == '.') + loc = c; + c++; + } + + if(loc != 0) + *(uint32*)&x_filename[loc] = *(uint32*)x_extension; + } +} + +// ****************************************************************** +// * XbeLoaded +// ****************************************************************** +void WndMain::XbeLoaded() +{ + LoadLogo(); + + // disable / enable appropriate menus + { + HMENU menu = GetMenu(m_hwnd); + + // file menu + { + HMENU file_menu = GetSubMenu(menu, 0); + + // disable open .xbe file + EnableMenuItem(file_menu, ID_FILE_OPEN_XBE, MF_BYCOMMAND | MF_GRAYED); + + // enable close .xbe file + EnableMenuItem(file_menu, ID_FILE_CLOSE_XBE, MF_BYCOMMAND | MF_ENABLED); + + // enable save .xbe file + EnableMenuItem(file_menu, ID_FILE_SAVEXBEFILE, MF_BYCOMMAND | MF_ENABLED); + + // enable save .xbe file as + EnableMenuItem(file_menu, ID_FILE_SAVEXBEFILEAS, MF_BYCOMMAND | MF_ENABLED); + + // disable import from .exe + EnableMenuItem(file_menu, ID_FILE_IMPORTFROMEXE, MF_BYCOMMAND | MF_GRAYED); + + // enable export to .exe + EnableMenuItem(file_menu, ID_FILE_EXPORTTOEXE, MF_BYCOMMAND | MF_ENABLED); + } + + // edit menu + { + HMENU edit_menu = GetSubMenu(menu, 1); + HMENU logo_menu = GetSubMenu(edit_menu, 0); + HMENU pach_menu = GetSubMenu(edit_menu, 1); + + // enable export .xbe info + EnableMenuItem(edit_menu, ID_EDIT_EXTRACTXBEINFO, MF_BYCOMMAND | MF_ENABLED); + + // enable logo bitmap menu + EnableMenuItem(edit_menu, 0, MF_BYPOSITION | MF_ENABLED); + + // enable patch menu + EnableMenuItem(edit_menu, 1, MF_BYPOSITION | MF_ENABLED); + + // patch menu + { + // check "allow >64 MB" if appropriate + { + UINT chk_flag = (m_xbe->m_Header.dwInitFlags.bLimit64MB) ? MF_UNCHECKED : MF_CHECKED; + + CheckMenuItem(pach_menu, ID_EDIT_PATCH_ALLOW64MB, chk_flag); + } + + // check "debug mode" if appropriate + { + UINT chk_flag = ((m_xbe->m_Header.dwEntryAddr ^ XOR_EP_RETAIL) > 0x01000000) ? MF_CHECKED : MF_UNCHECKED; + + CheckMenuItem(pach_menu, ID_EDIT_PATCH_DEBUGMODE, chk_flag); + } + } + } + + // view menu + { + HMENU view_menu = GetSubMenu(menu, 2); + } + + // emulation menu + { + HMENU emul_menu = GetSubMenu(menu, 3); + // enable emulation start + EnableMenuItem(emul_menu, ID_EMULATION_START, MF_BYCOMMAND | MF_ENABLED); + } + } + + printf("Cxbx: %s loaded.\n", m_xbe->m_szAsciiTitle); +} + +// ****************************************************************** +// * LoadLogo +// ****************************************************************** +void WndMain::LoadLogo() +{ + uint08 i_gray[100*17]; + + m_xbe->ExportLogoBitmap(i_gray); + + if(m_xbe->GetError() != 0) + { + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONEXCLAMATION | MB_OK); + + if(m_xbe->IsFatal()) + CloseXbe(); + + return; + } + + uint32 v=0; + for(uint32 y=0;y<17;y++) + { + for(uint32 x=0;x<100;x++) + { + SetPixel(m_logo_dc, x, y, RGB(i_gray[v], i_gray[v], i_gray[v])); + v++; + } + } + + RedrawWindow(m_hwnd, NULL, NULL, RDW_INVALIDATE); +} + +// ****************************************************************** +// * ConvertToExe +// ****************************************************************** +bool WndMain::ConvertToExe() +{ + OPENFILENAME ofn = {0}; + + char filename[260] = "default.exe"; + + SuggestFilename(m_xbe_filename, filename, ".exe"); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = "Win32 Executable file (*.exe)\0*.exe\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "exe"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if(GetSaveFileName(&ofn) == FALSE) + return false; + + // check if file exists + { + FILE *tmp = fopen(ofn.lpstrFile, "r"); + + if(tmp != 0) + { + fclose(tmp); + + if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx", MB_ICONQUESTION | MB_YESNO) != IDYES) + return false; + } + } + + // convert file + { + EmuExe i_EmuExe(m_xbe, m_krnl_debug); + + i_EmuExe.Export(ofn.lpstrFile); + + if(i_EmuExe.GetError() != 0) + { + MessageBox(m_hwnd, i_EmuExe.GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + return false; + } + else + { + strcpy(m_exe_filename, ofn.lpstrFile); + + char buffer[255]; + + sprintf(buffer, "%s was successfully converted to .exe.", m_xbe->m_szAsciiTitle); + + printf("Cxbx: %s was converted to .exe.\n", m_xbe->m_szAsciiTitle); + + MessageBox(m_hwnd, buffer, "Cxbx", MB_ICONINFORMATION | MB_OK); + + m_exe_changed = false; + } + } + + return true; +} + +// ****************************************************************** +// * SaveXbeAs +// ****************************************************************** +void WndMain::SaveXbeAs() +{ + OPENFILENAME ofn = {0}; + + char filename[260] = "default.xbe"; + + SuggestFilename(m_xbe_filename, filename, ".xbe"); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = m_hwnd; + ofn.lpstrFilter = ".xbe file (*.xbe)\0*.xbe\0"; + ofn.lpstrFile = filename; + ofn.nMaxFile = 260; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrDefExt = "xbe"; + ofn.Flags = OFN_PATHMUSTEXIST; + + if(GetSaveFileName(&ofn) == TRUE) + SaveXbe(ofn.lpstrFile); + +} + +// ****************************************************************** +// * SaveXbe +// ****************************************************************** +void WndMain::SaveXbe(const char *x_filename) +{ + // check if file exists + { + FILE *tmp = fopen(x_filename, "r"); + + if(tmp != 0) + { + fclose(tmp); + + if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx", MB_ICONQUESTION | MB_YESNO) != IDYES) + return; + } + } + + // save xbe file + { + m_xbe->Export(x_filename); + + if(m_xbe->GetError() != 0) + MessageBox(m_hwnd, m_xbe->GetError(), "Cxbx", MB_ICONSTOP | MB_OK); + else + { + char buffer[255]; + + sprintf(buffer, "%s was successfully saved.", m_xbe->m_szAsciiTitle); + + printf("Cxbx: %s was successfully saved.\n", m_xbe->m_szAsciiTitle); + + MessageBox(m_hwnd, buffer, "Cxbx", MB_ICONINFORMATION | MB_OK); + + m_xbe_changed = false; + } + } +} + +// ****************************************************************** +// * CloseXbe +// ****************************************************************** +void WndMain::CloseXbe() +{ + if(m_xbe_changed) + { + int ret = MessageBox(m_hwnd, "Changes have been made, do you wish to save?", "Cxbx", MB_ICONQUESTION | MB_YESNOCANCEL); + + if(ret == IDYES) + SaveXbeAs(); + else if(ret == IDCANCEL) + return; + } + + printf("Cxbx: %s unloaded.\n", m_xbe->m_szAsciiTitle); + + m_xbe_changed = false; + + delete m_xbe; m_xbe = 0; + + // disable / enable appropriate menus + { + HMENU menu = GetMenu(m_hwnd); + + // file menu + { + HMENU file_menu = GetSubMenu(menu, 0); + + // enable open .xbe file + EnableMenuItem(file_menu, ID_FILE_OPEN_XBE, MF_BYCOMMAND | MF_ENABLED); + + // disable close .xbe file + EnableMenuItem(file_menu, ID_FILE_CLOSE_XBE, MF_BYCOMMAND | MF_GRAYED); + + // disable save .xbe file + EnableMenuItem(file_menu, ID_FILE_SAVEXBEFILE, MF_BYCOMMAND | MF_GRAYED); + + // disable save .xbe file as + EnableMenuItem(file_menu, ID_FILE_SAVEXBEFILEAS, MF_BYCOMMAND | MF_GRAYED); + + // enable import from .exe + EnableMenuItem(file_menu, ID_FILE_IMPORTFROMEXE, MF_BYCOMMAND | MF_ENABLED); + + // disable convert to .exe + EnableMenuItem(file_menu, ID_FILE_EXPORTTOEXE, MF_BYCOMMAND | MF_GRAYED); + } + + // edit menu + { + HMENU edit_menu = GetSubMenu(menu, 1); + + // disable export .xbe info + EnableMenuItem(edit_menu, ID_EDIT_EXTRACTXBEINFO, MF_BYCOMMAND | MF_GRAYED); + + // disable logo bitmap menu + EnableMenuItem(edit_menu, 0, MF_BYPOSITION | MF_GRAYED); + + // disable patch menu + EnableMenuItem(edit_menu, 1, MF_BYPOSITION | MF_GRAYED); + } + + // view menu + { + HMENU view_menu = GetSubMenu(menu, 2); + } + + // emulation menu + { + HMENU emul_menu = GetSubMenu(menu, 3); + + // disable emulation start + EnableMenuItem(emul_menu, ID_EMULATION_START, MF_BYCOMMAND | MF_GRAYED); + } + } + + // clear logo bitmap + { + uint32 v=0; + for(uint32 y=0;y<17;y++) + { + for(uint32 x=0;x<100;x++) + { + SetPixel(m_logo_dc, x, y, RGB(0, 0, 0)); + v++; + } + } + } + + RedrawWindow(m_hwnd, NULL, NULL, RDW_INVALIDATE); +} diff --git a/Source/Win32/CxbxKrnl/Kernel.cpp b/Source/Win32/CxbxKrnl/Kernel.cpp new file mode 100644 index 000000000..908898d0f --- /dev/null +++ b/Source/Win32/CxbxKrnl/Kernel.cpp @@ -0,0 +1,151 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->Kernel.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#define CXBXKRNL_INTERNAL +#define _XBOXKRNL_LOCAL_ +#include "Kernel.h" + +#include + +// ****************************************************************** +// * ntdll wrapped in namespace to avoid collisions +// ****************************************************************** +namespace xntdll +{ + #include "xntdll.h" +}; + +// ****************************************************************** +// * win32 wrapped in namespace to avoid collisions +// ****************************************************************** +namespace win32 +{ + #include +}; + +using namespace win32; + +// ****************************************************************** +// * func: EmuXInit +// ****************************************************************** +CXBXKRNL_API void NTAPI EmuXInit(uint32 DebugConsole, uint08 *XBEHeader, uint32 XBEHeaderSize, void (*Entry)()) +{ + if(DebugConsole) + { + AllocConsole(); + + freopen("CONOUT$", "w", stdout); + + printf("%s", "CxbxKrnl: Debug console allocated.\n"); + } + + printf("CxbxKrnl: EmuXInit(0x%.08X, %d, 0x%.08X)\n", XBEHeader, XBEHeaderSize, Entry); + + Entry(); + + return; +} + +// ****************************************************************** +// * func: EmuXDummy +// ****************************************************************** +CXBXKRNL_API void NTAPI EmuXDummy() +{ +} + +// ****************************************************************** +// * func: EmuXPanic +// ****************************************************************** +CXBXKRNL_API void NTAPI EmuXPanic() +{ + printf("CxbxKrnl: EmuXPanic()\n"); + + MessageBox(NULL, "Kernel Panic! Process will now terminate.", "CxbxKrnl", MB_OK | MB_ICONEXCLAMATION); + + exit(1); +} + +using namespace xboxkrnl; + +// ****************************************************************** +// * 0x00BB - NtClose +// ****************************************************************** +XBSYSAPI EXPORTNUM(187) NTSTATUS NTAPI xboxkrnl::NtClose +( + IN HANDLE Handle +) +{ + return STATUS_SUCCESS; +} + +// ****************************************************************** +// * 0x00FF - PsCreateSystemThreadEx +// ****************************************************************** +XBSYSAPI EXPORTNUM(255) NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadEx +( + OUT PHANDLE ThreadHandle, + IN ULONG ThreadExtraSize, + IN ULONG KernelStackSize, + IN ULONG TlsDataSize, + OUT PULONG ThreadId OPTIONAL, + IN PVOID StartContext1, + IN PVOID StartContext2, + IN BOOLEAN CreateSuspended, + IN BOOLEAN DebugStack, + IN PKSTART_ROUTINE StartRoutine +) +{ + return STATUS_SUCCESS; +} + +// ****************************************************************** +// * 0x0031 - HalReturnToFirmware +// ****************************************************************** +XBSYSAPI EXPORTNUM(49) VOID DECLSPEC_NORETURN xboxkrnl::HalReturnToFirmware +( + RETURN_FIRMWARE Routine +) +{ + /* + ReturnFirmwareHalt = 0x0, + ReturnFirmwareReboot = 0x1, + ReturnFirmwareQuickReboot = 0x2, + ReturnFirmwareHard = 0x3, + ReturnFirmwareFatal = 0x4, + ReturnFirmwareAll = 0x5 + */ + + exit(1); +} \ No newline at end of file diff --git a/Source/Win32/CxbxKrnl/KernelThunk.cpp b/Source/Win32/CxbxKrnl/KernelThunk.cpp new file mode 100644 index 000000000..f05acb3d9 --- /dev/null +++ b/Source/Win32/CxbxKrnl/KernelThunk.cpp @@ -0,0 +1,420 @@ +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->KernelThunkTable.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 +// * +// * All rights reserved +// * +// ****************************************************************** +#include "Cxbx.h" + +#define CXBXKRNL_INTERNAL +#define _XBOXKRNL_LOCAL_ +#include "Kernel.h" + +// ****************************************************************** +// * NOTE: +// ****************************************************************** +// * i typically enable "#define PANIC(numb) numb" whenever i want +// * to find out what kernel export is trying to be called but is +// * not implemented yet (no prototype exists). otherwise, enable +// * "#define PANIC(numb) cxbx_panic" +// ****************************************************************** +#define PANIC(numb) EmuXPanic +//#define PANIC(numb) numb + +CXBXKRNL_API uint32 KernelThunkTable[367] = +{ + (uint32)PANIC(0x0000), // 0x0000 (0) + (uint32)PANIC(0x0001), // 0x0001 (1) + (uint32)PANIC(0x0002), // 0x0002 (2) + (uint32)PANIC(0x0003), // 0x0003 (3) + (uint32)PANIC(0x0004), // 0x0004 (4) + (uint32)PANIC(0x0005), // 0x0005 (5) + (uint32)PANIC(0x0006), // 0x0006 (6) + (uint32)PANIC(0x0007), // 0x0007 (7) + (uint32)PANIC(0x0008), // 0x0008 (8) + (uint32)PANIC(0x0009), // 0x0009 (9) + (uint32)PANIC(0x000A), // 0x000A (10) + (uint32)PANIC(0x000B), // 0x000B (11) + (uint32)PANIC(0x000C), // 0x000C (12) + (uint32)PANIC(0x000D), // 0x000D (13) + (uint32)PANIC(0x000E), // 0x000E (14) + (uint32)PANIC(0x000F), // 0x000F (15) + (uint32)PANIC(0x0010), // 0x0010 (16) + (uint32)PANIC(0x0011), // 0x0011 (17) + (uint32)PANIC(0x0012), // 0x0012 (18) + (uint32)PANIC(0x0013), // 0x0013 (19) + (uint32)PANIC(0x0014), // 0x0014 (20) + (uint32)PANIC(0x0015), // 0x0015 (21) + (uint32)PANIC(0x0016), // 0x0016 (22) + (uint32)PANIC(0x0017), // 0x0017 (23) + (uint32)PANIC(0x0018), // 0x0018 (24) + (uint32)PANIC(0x0019), // 0x0019 (25) + (uint32)PANIC(0x001A), // 0x001A (26) + (uint32)PANIC(0x001B), // 0x001B (27) + (uint32)PANIC(0x001C), // 0x001C (28) + (uint32)PANIC(0x001D), // 0x001D (29) + (uint32)PANIC(0x001E), // 0x001E (30) + (uint32)PANIC(0x001F), // 0x001F (31) + (uint32)PANIC(0x0020), // 0x0020 (32) + (uint32)PANIC(0x0021), // 0x0021 (33) + (uint32)PANIC(0x0022), // 0x0022 (34) + (uint32)PANIC(0x0023), // 0x0023 (35) + (uint32)PANIC(0x0024), // 0x0024 (36) + (uint32)PANIC(0x0025), // 0x0025 (37) + (uint32)PANIC(0x0026), // 0x0026 (38) + (uint32)PANIC(0x0027), // 0x0027 (39) + (uint32)PANIC(0x0028), // 0x0028 (40) + (uint32)PANIC(0x0029), // 0x0029 (41) + (uint32)PANIC(0x002A), // 0x002A (42) + (uint32)PANIC(0x002B), // 0x002B (43) + (uint32)PANIC(0x002C), // 0x002C (44) + (uint32)PANIC(0x002D), // 0x002D (45) + (uint32)PANIC(0x002E), // 0x002E (46) + (uint32)PANIC(0x002F), // 0x002F (47) + (uint32)PANIC(0x0030), // 0x0030 (48) + (uint32)&xboxkrnl::HalReturnToFirmware, // 0x0031 (49) + (uint32)PANIC(0x0032), // 0x0032 (50) + (uint32)PANIC(0x0033), // 0x0033 (51) + (uint32)PANIC(0x0034), // 0x0034 (52) + (uint32)PANIC(0x0035), // 0x0035 (53) + (uint32)PANIC(0x0036), // 0x0036 (54) + (uint32)PANIC(0x0037), // 0x0037 (55) + (uint32)PANIC(0x0038), // 0x0038 (56) + (uint32)PANIC(0x0039), // 0x0039 (57) + (uint32)PANIC(0x003A), // 0x003A (58) + (uint32)PANIC(0x003B), // 0x003B (59) + (uint32)PANIC(0x003C), // 0x003C (60) + (uint32)PANIC(0x003D), // 0x003D (61) + (uint32)PANIC(0x003E), // 0x003E (62) + (uint32)PANIC(0x003F), // 0x003F (63) + (uint32)PANIC(0x0040), // 0x0040 (64) + (uint32)PANIC(0x0041), // 0x0041 (65) + (uint32)PANIC(0x0042), // 0x0042 (66) + (uint32)PANIC(0x0043), // 0x0043 (67) + (uint32)PANIC(0x0044), // 0x0044 (68) + (uint32)PANIC(0x0045), // 0x0045 (69) + (uint32)PANIC(0x0046), // 0x0046 (70) + (uint32)PANIC(0x0047), // 0x0047 (71) + (uint32)PANIC(0x0048), // 0x0048 (72) + (uint32)PANIC(0x0049), // 0x0049 (73) + (uint32)PANIC(0x004A), // 0x004A (74) + (uint32)PANIC(0x004B), // 0x004B (75) + (uint32)PANIC(0x004C), // 0x004C (76) + (uint32)PANIC(0x004D), // 0x004D (77) + (uint32)PANIC(0x004E), // 0x004E (78) + (uint32)PANIC(0x004F), // 0x004F (79) + (uint32)PANIC(0x0050), // 0x0050 (80) + (uint32)PANIC(0x0051), // 0x0051 (81) + (uint32)PANIC(0x0052), // 0x0052 (82) + (uint32)PANIC(0x0053), // 0x0053 (83) + (uint32)PANIC(0x0054), // 0x0054 (84) + (uint32)PANIC(0x0055), // 0x0055 (85) + (uint32)PANIC(0x0056), // 0x0056 (86) + (uint32)PANIC(0x0057), // 0x0057 (87) + (uint32)PANIC(0x0058), // 0x0058 (88) + (uint32)PANIC(0x0059), // 0x0059 (89) + (uint32)PANIC(0x005A), // 0x005A (90) + (uint32)PANIC(0x005B), // 0x005B (91) + (uint32)PANIC(0x005C), // 0x005C (92) + (uint32)PANIC(0x005D), // 0x005D (93) + (uint32)PANIC(0x005E), // 0x005E (94) + (uint32)PANIC(0x005F), // 0x005F (95) + (uint32)PANIC(0x0060), // 0x0060 (96) + (uint32)PANIC(0x0061), // 0x0061 (97) + (uint32)PANIC(0x0062), // 0x0062 (98) + (uint32)PANIC(0x0063), // 0x0063 (99) + (uint32)PANIC(0x0064), // 0x0064 (100) + (uint32)PANIC(0x0065), // 0x0065 (101) + (uint32)PANIC(0x0066), // 0x0066 (102) + (uint32)PANIC(0x0067), // 0x0067 (103) + (uint32)PANIC(0x0068), // 0x0068 (104) + (uint32)PANIC(0x0069), // 0x0069 (105) + (uint32)PANIC(0x006A), // 0x006A (106) + (uint32)PANIC(0x006B), // 0x006B (107) + (uint32)PANIC(0x006C), // 0x006C (108) + (uint32)PANIC(0x006D), // 0x006D (109) + (uint32)PANIC(0x006E), // 0x006E (110) + (uint32)PANIC(0x006F), // 0x006F (111) + (uint32)PANIC(0x0070), // 0x0070 (112) + (uint32)PANIC(0x0071), // 0x0071 (113) + (uint32)PANIC(0x0072), // 0x0072 (114) + (uint32)PANIC(0x0073), // 0x0073 (115) + (uint32)PANIC(0x0074), // 0x0074 (116) + (uint32)PANIC(0x0075), // 0x0075 (117) + (uint32)PANIC(0x0076), // 0x0076 (118) + (uint32)PANIC(0x0077), // 0x0077 (119) + (uint32)PANIC(0x0078), // 0x0078 (120) + (uint32)PANIC(0x0079), // 0x0079 (121) + (uint32)PANIC(0x007A), // 0x007A (122) + (uint32)PANIC(0x007B), // 0x007B (123) + (uint32)PANIC(0x007C), // 0x007C (124) + (uint32)PANIC(0x007D), // 0x007D (125) + (uint32)PANIC(0x007E), // 0x007E (126) + (uint32)PANIC(0x007F), // 0x007F (127) + (uint32)PANIC(0x0080), // 0x0080 (128) + (uint32)PANIC(0x0081), // 0x0081 (129) + (uint32)PANIC(0x0082), // 0x0082 (130) + (uint32)PANIC(0x0083), // 0x0083 (131) + (uint32)PANIC(0x0084), // 0x0084 (132) + (uint32)PANIC(0x0085), // 0x0085 (133) + (uint32)PANIC(0x0086), // 0x0086 (134) + (uint32)PANIC(0x0087), // 0x0087 (135) + (uint32)PANIC(0x0088), // 0x0088 (136) + (uint32)PANIC(0x0089), // 0x0089 (137) + (uint32)PANIC(0x008A), // 0x008A (138) + (uint32)PANIC(0x008B), // 0x008B (139) + (uint32)PANIC(0x008C), // 0x008C (140) + (uint32)PANIC(0x008D), // 0x008D (141) + (uint32)PANIC(0x008E), // 0x008E (142) + (uint32)PANIC(0x008F), // 0x008F (143) + (uint32)PANIC(0x0090), // 0x0090 (144) + (uint32)PANIC(0x0091), // 0x0091 (145) + (uint32)PANIC(0x0092), // 0x0092 (146) + (uint32)PANIC(0x0093), // 0x0093 (147) + (uint32)PANIC(0x0094), // 0x0094 (148) + (uint32)PANIC(0x0095), // 0x0095 (149) + (uint32)PANIC(0x0096), // 0x0096 (150) + (uint32)PANIC(0x0097), // 0x0097 (151) + (uint32)PANIC(0x0098), // 0x0098 (152) + (uint32)PANIC(0x0099), // 0x0099 (153) + (uint32)PANIC(0x009A), // 0x009A (154) + (uint32)PANIC(0x009B), // 0x009B (155) + (uint32)PANIC(0x009C), // 0x009C (156) + (uint32)PANIC(0x009D), // 0x009D (157) + (uint32)PANIC(0x009E), // 0x009E (158) + (uint32)PANIC(0x009F), // 0x009F (159) + (uint32)PANIC(0x00A0), // 0x00A0 (160) + (uint32)PANIC(0x00A1), // 0x00A1 (161) + (uint32)PANIC(0x00A2), // 0x00A2 (162) + (uint32)PANIC(0x00A3), // 0x00A3 (163) + (uint32)PANIC(0x00A4), // 0x00A4 (164) + (uint32)PANIC(0x00A5), // 0x00A5 (165) + (uint32)PANIC(0x00A6), // 0x00A6 (166) + (uint32)PANIC(0x00A7), // 0x00A7 (167) + (uint32)PANIC(0x00A8), // 0x00A8 (168) + (uint32)PANIC(0x00A9), // 0x00A9 (169) + (uint32)PANIC(0x00AA), // 0x00AA (170) + (uint32)PANIC(0x00AB), // 0x00AB (171) + (uint32)PANIC(0x00AC), // 0x00AC (172) + (uint32)PANIC(0x00AD), // 0x00AD (173) + (uint32)PANIC(0x00AE), // 0x00AE (174) + (uint32)PANIC(0x00AF), // 0x00AF (175) + (uint32)PANIC(0x00B0), // 0x00B0 (176) + (uint32)PANIC(0x00B1), // 0x00B1 (177) + (uint32)PANIC(0x00B2), // 0x00B2 (178) + (uint32)PANIC(0x00B3), // 0x00B3 (179) + (uint32)PANIC(0x00B4), // 0x00B4 (180) + (uint32)PANIC(0x00B5), // 0x00B5 (181) + (uint32)PANIC(0x00B6), // 0x00B6 (182) + (uint32)PANIC(0x00B7), // 0x00B7 (183) + (uint32)PANIC(0x00B8), // 0x00B8 (184) + (uint32)PANIC(0x00B9), // 0x00B9 (185) + (uint32)PANIC(0x00BA), // 0x00BA (186) + (uint32)&xboxkrnl::NtClose, // 0x00BB (187) + (uint32)PANIC(0x00BC), // 0x00BC (188) + (uint32)PANIC(0x00BD), // 0x00BD (189) + (uint32)PANIC(0x00BE), // 0x00BE (190) + (uint32)PANIC(0x00BF), // 0x00BF (191) + (uint32)PANIC(0x00C0), // 0x00C0 (192) + (uint32)PANIC(0x00C1), // 0x00C1 (193) + (uint32)PANIC(0x00C2), // 0x00C2 (194) + (uint32)PANIC(0x00C3), // 0x00C3 (195) + (uint32)PANIC(0x00C4), // 0x00C4 (196) + (uint32)PANIC(0x00C5), // 0x00C5 (197) + (uint32)PANIC(0x00C6), // 0x00C6 (198) + (uint32)PANIC(0x00C7), // 0x00C7 (199) + (uint32)PANIC(0x00C8), // 0x00C8 (200) + (uint32)PANIC(0x00C9), // 0x00C9 (201) + (uint32)PANIC(0x00CA), // 0x00CA (202) + (uint32)PANIC(0x00CB), // 0x00CB (203) + (uint32)PANIC(0x00CC), // 0x00CC (204) + (uint32)PANIC(0x00CD), // 0x00CD (205) + (uint32)PANIC(0x00CE), // 0x00CE (206) + (uint32)PANIC(0x00CF), // 0x00CF (207) + (uint32)PANIC(0x00D0), // 0x00D0 (208) + (uint32)PANIC(0x00D1), // 0x00D1 (209) + (uint32)PANIC(0x00D2), // 0x00D2 (210) + (uint32)PANIC(0x00D3), // 0x00D3 (211) + (uint32)PANIC(0x00D4), // 0x00D4 (212) + (uint32)PANIC(0x00D5), // 0x00D5 (213) + (uint32)PANIC(0x00D6), // 0x00D6 (214) + (uint32)PANIC(0x00D7), // 0x00D7 (215) + (uint32)PANIC(0x00D8), // 0x00D8 (216) + (uint32)PANIC(0x00D9), // 0x00D9 (217) + (uint32)PANIC(0x00DA), // 0x00DA (218) + (uint32)PANIC(0x00DB), // 0x00DB (219) + (uint32)PANIC(0x00DC), // 0x00DC (220) + (uint32)PANIC(0x00DD), // 0x00DD (221) + (uint32)PANIC(0x00DE), // 0x00DE (222) + (uint32)PANIC(0x00DF), // 0x00DF (223) + (uint32)PANIC(0x00E0), // 0x00E0 (224) + (uint32)PANIC(0x00E1), // 0x00E1 (225) + (uint32)PANIC(0x00E2), // 0x00E2 (226) + (uint32)PANIC(0x00E3), // 0x00E3 (227) + (uint32)PANIC(0x00E4), // 0x00E4 (228) + (uint32)PANIC(0x00E5), // 0x00E5 (229) + (uint32)PANIC(0x00E6), // 0x00E6 (230) + (uint32)PANIC(0x00E7), // 0x00E7 (231) + (uint32)PANIC(0x00E8), // 0x00E8 (232) + (uint32)PANIC(0x00E9), // 0x00E9 (233) + (uint32)PANIC(0x00EA), // 0x00EA (234) + (uint32)PANIC(0x00EB), // 0x00EB (235) + (uint32)PANIC(0x00EC), // 0x00EC (236) + (uint32)PANIC(0x00ED), // 0x00ED (237) + (uint32)PANIC(0x00EE), // 0x00EE (238) + (uint32)PANIC(0x00EF), // 0x00EF (239) + (uint32)PANIC(0x00F0), // 0x00F0 (240) + (uint32)PANIC(0x00F1), // 0x00F1 (241) + (uint32)PANIC(0x00F2), // 0x00F2 (242) + (uint32)PANIC(0x00F3), // 0x00F3 (243) + (uint32)PANIC(0x00F4), // 0x00F4 (244) + (uint32)PANIC(0x00F5), // 0x00F5 (245) + (uint32)PANIC(0x00F6), // 0x00F6 (246) + (uint32)PANIC(0x00F7), // 0x00F7 (247) + (uint32)PANIC(0x00F8), // 0x00F8 (248) + (uint32)PANIC(0x00F9), // 0x00F9 (249) + (uint32)PANIC(0x00FA), // 0x00FA (250) + (uint32)PANIC(0x00FB), // 0x00FB (251) + (uint32)PANIC(0x00FC), // 0x00FC (252) + (uint32)PANIC(0x00FD), // 0x00FD (253) + (uint32)PANIC(0x00FE), // 0x00FE (254) + (uint32)&xboxkrnl::PsCreateSystemThreadEx, // 0x00FF (255) + (uint32)PANIC(0x0100), // 0x0100 (256) + (uint32)PANIC(0x0101), // 0x0101 (257) + (uint32)PANIC(0x0102), // 0x0102 (258) + (uint32)PANIC(0x0103), // 0x0103 (259) + (uint32)PANIC(0x0104), // 0x0104 (260) + (uint32)PANIC(0x0105), // 0x0105 (261) + (uint32)PANIC(0x0106), // 0x0106 (262) + (uint32)PANIC(0x0107), // 0x0107 (263) + (uint32)PANIC(0x0108), // 0x0108 (264) + (uint32)PANIC(0x0109), // 0x0109 (265) + (uint32)PANIC(0x010A), // 0x010A (266) + (uint32)PANIC(0x010B), // 0x010B (267) + (uint32)PANIC(0x010C), // 0x010C (268) + (uint32)PANIC(0x010D), // 0x010D (269) + (uint32)PANIC(0x010E), // 0x010E (270) + (uint32)PANIC(0x010F), // 0x010F (271) + (uint32)PANIC(0x0110), // 0x0110 (272) + (uint32)PANIC(0x0111), // 0x0111 (273) + (uint32)PANIC(0x0112), // 0x0112 (274) + (uint32)PANIC(0x0113), // 0x0113 (275) + (uint32)PANIC(0x0114), // 0x0114 (276) + (uint32)PANIC(0x0115), // 0x0115 (277) + (uint32)PANIC(0x0116), // 0x0116 (278) + (uint32)PANIC(0x0117), // 0x0117 (279) + (uint32)PANIC(0x0118), // 0x0118 (280) + (uint32)PANIC(0x0119), // 0x0119 (281) + (uint32)PANIC(0x011A), // 0x011A (282) + (uint32)PANIC(0x011B), // 0x011B (283) + (uint32)PANIC(0x011C), // 0x011C (284) + (uint32)PANIC(0x011D), // 0x011D (285) + (uint32)PANIC(0x011E), // 0x011E (286) + (uint32)PANIC(0x011F), // 0x011F (287) + (uint32)PANIC(0x0120), // 0x0120 (288) + (uint32)PANIC(0x0121), // 0x0121 (289) + (uint32)PANIC(0x0122), // 0x0122 (290) + (uint32)PANIC(0x0123), // 0x0123 (291) + (uint32)PANIC(0x0124), // 0x0124 (292) + (uint32)PANIC(0x0125), // 0x0125 (293) + (uint32)PANIC(0x0126), // 0x0126 (294) + (uint32)PANIC(0x0127), // 0x0127 (295) + (uint32)PANIC(0x0128), // 0x0128 (296) + (uint32)PANIC(0x0129), // 0x0129 (297) + (uint32)PANIC(0x012A), // 0x012A (298) + (uint32)PANIC(0x012B), // 0x012B (299) + (uint32)PANIC(0x012C), // 0x012C (300) + (uint32)PANIC(0x012D), // 0x012D (301) + (uint32)PANIC(0x012E), // 0x012E (302) + (uint32)PANIC(0x012F), // 0x012F (303) + (uint32)PANIC(0x0130), // 0x0130 (304) + (uint32)PANIC(0x0131), // 0x0131 (305) + (uint32)PANIC(0x0132), // 0x0132 (306) + (uint32)PANIC(0x0133), // 0x0133 (307) + (uint32)PANIC(0x0134), // 0x0134 (308) + (uint32)PANIC(0x0135), // 0x0135 (309) + (uint32)PANIC(0x0136), // 0x0136 (310) + (uint32)PANIC(0x0137), // 0x0137 (311) + (uint32)PANIC(0x0138), // 0x0138 (312) + (uint32)PANIC(0x0139), // 0x0139 (313) + (uint32)PANIC(0x013A), // 0x013A (314) + (uint32)PANIC(0x013B), // 0x013B (315) + (uint32)PANIC(0x013C), // 0x013C (316) + (uint32)PANIC(0x013D), // 0x013D (317) + (uint32)PANIC(0x013E), // 0x013E (318) + (uint32)PANIC(0x013F), // 0x013F (319) + (uint32)PANIC(0x0140), // 0x0140 (320) + (uint32)PANIC(0x0141), // 0x0141 (321) + (uint32)PANIC(0x0142), // 0x0142 (322) + (uint32)PANIC(0x0143), // 0x0143 (323) + (uint32)PANIC(0x0144), // 0x0144 (324) + (uint32)PANIC(0x0145), // 0x0145 (325) + (uint32)PANIC(0x0146), // 0x0146 (326) + (uint32)PANIC(0x0147), // 0x0147 (327) + (uint32)PANIC(0x0148), // 0x0148 (328) + (uint32)PANIC(0x0149), // 0x0149 (329) + (uint32)PANIC(0x014A), // 0x014A (330) + (uint32)PANIC(0x014B), // 0x014B (331) + (uint32)PANIC(0x014C), // 0x014C (332) + (uint32)PANIC(0x014D), // 0x014D (333) + (uint32)PANIC(0x014E), // 0x014E (334) + (uint32)PANIC(0x014F), // 0x014F (335) + (uint32)PANIC(0x0150), // 0x0150 (336) + (uint32)PANIC(0x0151), // 0x0151 (337) + (uint32)PANIC(0x0152), // 0x0152 (338) + (uint32)PANIC(0x0153), // 0x0153 (339) + (uint32)PANIC(0x0154), // 0x0154 (340) + (uint32)PANIC(0x0155), // 0x0155 (341) + (uint32)PANIC(0x0156), // 0x0156 (342) + (uint32)PANIC(0x0157), // 0x0157 (343) + (uint32)PANIC(0x0158), // 0x0158 (344) + (uint32)PANIC(0x0159), // 0x0159 (345) + (uint32)PANIC(0x015A), // 0x015A (346) + (uint32)PANIC(0x015B), // 0x015B (347) + (uint32)PANIC(0x015C), // 0x015C (348) + (uint32)PANIC(0x015D), // 0x015D (349) + (uint32)PANIC(0x015E), // 0x015E (350) + (uint32)PANIC(0x015F), // 0x015F (351) + (uint32)PANIC(0x0160), // 0x0160 (352) + (uint32)PANIC(0x0161), // 0x0161 (353) + (uint32)PANIC(0x0162), // 0x0162 (354) + (uint32)PANIC(0x0163), // 0x0163 (355) + (uint32)PANIC(0x0164), // 0x0164 (356) + (uint32)PANIC(0x0165), // 0x0165 (357) + (uint32)PANIC(0x0166), // 0x0166 (358) + (uint32)PANIC(0x0167), // 0x0167 (359) + (uint32)PANIC(0x0168), // 0x0168 (360) + (uint32)PANIC(0x0169), // 0x0169 (361) + (uint32)PANIC(0x016A), // 0x016A (362) + (uint32)PANIC(0x016B), // 0x016B (363) + (uint32)PANIC(0x016C), // 0x016C (364) + (uint32)PANIC(0x016D), // 0x016D (365) + (uint32)PANIC(0x016E), // 0x016E (366) +}; \ No newline at end of file