Skip to content

Commit 148d0df

Browse files
committed
Add ReportWriter class and add DebugReportWriter override
1 parent 2d71289 commit 148d0df

9 files changed

Lines changed: 323 additions & 0 deletions

File tree

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
.vscode
1111
__pycache__
1212
Debug
13+
!Spore ModAPI/Spore/Debug/
14+
!Spore ModAPI/SourceCode/Debug/
1315
Release
1416
Projects/*
1517
!Projects/Example Projects/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifdef MODAPI_DLL_EXPORT
2+
#include "stdafx.h"
3+
#include <Spore\Debug\ReportWriter.h>
4+
5+
namespace Debug
6+
{
7+
namespace Addresses(ReportWriter)
8+
{
9+
DefineAddress(GetFileNameExtension, SelectAddress(0x0091eee0, 0x0091ec20));
10+
DefineAddress(OpenReport, SelectAddress(0x0091ef10, 0x0091ec50));
11+
DefineAddress(CloseReport, SelectAddress(0x0091ef70, 0x0091ecb0));
12+
DefineAddress(BeginSection, SelectAddress(0x0091efa0, 0x0091ece0));
13+
DefineAddress(EndSection, SelectAddress(0x0091efd0, 0x0091ed10));
14+
DefineAddress(WriteText, SelectAddress(0x0091efe0, 0x0091ed20));
15+
DefineAddress(WriteFormatted, SelectAddress(0x0091f020, 0x0091ed60));
16+
DefineAddress(WriteKeyValue, SelectAddress(0x0091f070, 0x0091edb0));
17+
DefineAddress(WriteKeyValueFormatted, SelectAddress(0x0091f0f0, 0x0091ee30));
18+
DefineAddress(WriteBlankLine, SelectAddress(0x0091f140, 0x0091ee80));
19+
DefineAddress(Write, SelectAddress(0x0091f150, 0x0091ee90));
20+
DefineAddress(GetPosition, SelectAddress(0x0091f1b0, 0x0091eef0));
21+
DefineAddress(SetPosition, SelectAddress(0x0091f1d0, 0x0091ef10));
22+
};
23+
}
24+
25+
#endif
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#ifdef MODAPI_DLL_EXPORT
2+
#include "stdafx.h"
3+
#include "DebugReportWriterOverride.h"
4+
5+
#include <Spore\Debug\ReportWriter.h>
6+
#include <Spore\ModAPI.h>
7+
8+
typedef LONG(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
9+
10+
member_detour(WriteSystemInfoDetour, Debug::ReportWriter, bool(void))
11+
{
12+
bool detoured(void)
13+
{
14+
char buffer[256] = { 0 };
15+
DWORD bufferSize = sizeof(buffer);
16+
17+
if (GetComputerNameExA(COMPUTER_NAME_FORMAT::ComputerNameDnsFullyQualified, buffer, &bufferSize))
18+
{
19+
WriteKeyValue("Computer name", buffer);
20+
}
21+
22+
bufferSize = sizeof(buffer);
23+
if (GetUserNameA(buffer, &bufferSize))
24+
{
25+
WriteKeyValue("User name", buffer);
26+
}
27+
28+
WriteKeyValue("EA_PLATFORM", "Windows on X86");
29+
30+
// GetVersionExA() is deprecated and only reports upto Windows 8
31+
// unless a higher Windows version is specified in the executable
32+
// manifest, so use RtlGetVersion() from ntdll.dll instead
33+
HMODULE ntdllHandle = GetModuleHandleW(L"ntdll.dll");
34+
if (ntdllHandle != nullptr)
35+
{
36+
RtlGetVersionPtr rtlGetVersion = (RtlGetVersionPtr)GetProcAddress(ntdllHandle, "RtlGetVersion");
37+
if (rtlGetVersion != nullptr)
38+
{
39+
RTL_OSVERSIONINFOW versionInfo = { 0 };
40+
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
41+
42+
if (rtlGetVersion(&versionInfo) == 0)
43+
{
44+
if (versionInfo.dwMajorVersion == 5 &&
45+
versionInfo.dwMinorVersion == 1)
46+
{
47+
sprintf_s(buffer, sizeof(buffer), "Windows XP");
48+
}
49+
else if (versionInfo.dwMajorVersion == 6 &&
50+
versionInfo.dwMinorVersion == 0)
51+
{
52+
sprintf_s(buffer, sizeof(buffer), "Windows Vista");
53+
}
54+
else if (versionInfo.dwMajorVersion == 6 &&
55+
versionInfo.dwMinorVersion == 1)
56+
{
57+
sprintf_s(buffer, sizeof(buffer), "Windows 7");
58+
}
59+
else if (versionInfo.dwMajorVersion == 6 &&
60+
versionInfo.dwMinorVersion == 2)
61+
{
62+
sprintf_s(buffer, sizeof(buffer), "Windows 8");
63+
}
64+
else if (versionInfo.dwMajorVersion == 6 &&
65+
versionInfo.dwMinorVersion == 3)
66+
{
67+
sprintf_s(buffer, sizeof(buffer), "Windows 8.1");
68+
}
69+
else if (versionInfo.dwMajorVersion == 10 &&
70+
versionInfo.dwMinorVersion == 0 &&
71+
versionInfo.dwBuildNumber < 22000)
72+
{
73+
sprintf_s(buffer, sizeof(buffer), "Windows 10");
74+
}
75+
else if (versionInfo.dwMajorVersion >= 10 &&
76+
versionInfo.dwMinorVersion == 0 &&
77+
versionInfo.dwBuildNumber >= 22000)
78+
{
79+
sprintf_s(buffer, sizeof(buffer), "Windows 11");
80+
}
81+
else
82+
{
83+
sprintf_s(buffer, sizeof(buffer), "Unknown");
84+
}
85+
WriteKeyValue("OS name", buffer);
86+
87+
sprintf_s(buffer, sizeof(buffer), "%u.%u.%u", versionInfo.dwMajorVersion, versionInfo.dwMinorVersion, versionInfo.dwBuildNumber);
88+
WriteKeyValue("OS version number", buffer);
89+
90+
if (versionInfo.szCSDVersion[0] != L'\0')
91+
{
92+
sprintf_s(buffer, sizeof(buffer), "%ls", versionInfo.szCSDVersion);
93+
WriteKeyValue("OS service pack", buffer);
94+
}
95+
96+
}
97+
}
98+
}
99+
100+
WriteKeyValue("Debugger present", (IsDebuggerPresent() ? "yes" : "no"));
101+
102+
// GetSystemInfo() does not return correct information
103+
// when we're running on a x86_64 CPU while in a x86 process,
104+
// so use GetNativeSystemInfo() instead.
105+
SYSTEM_INFO systemInfo = { 0 };
106+
GetNativeSystemInfo(&systemInfo);
107+
108+
sprintf_s(buffer, sizeof(buffer), "%u", systemInfo.dwNumberOfProcessors);
109+
WriteKeyValue("CPU count", buffer);
110+
111+
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
112+
{
113+
sprintf_s(buffer, sizeof(buffer), "x86-64");
114+
}
115+
else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA32_ON_WIN64)
116+
{
117+
sprintf_s(buffer, sizeof(buffer), "x86 on x86-64");
118+
}
119+
else
120+
{
121+
sprintf_s(buffer, sizeof(buffer), "x86");
122+
}
123+
WriteKeyValue("Processor type", buffer);
124+
125+
sprintf_s(buffer, sizeof(buffer), "%u", systemInfo.wProcessorLevel);
126+
WriteKeyValue("Processor level", buffer);
127+
128+
sprintf_s(buffer, sizeof(buffer), "%u", systemInfo.wProcessorRevision);
129+
WriteKeyValue("Processor revision", buffer);
130+
131+
132+
MEMORYSTATUSEX memoryStatus = { 0 };
133+
memoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
134+
if (GlobalMemoryStatusEx(&memoryStatus))
135+
{
136+
sprintf_s(buffer, sizeof(buffer), "%d%%", memoryStatus.dwMemoryLoad);
137+
WriteKeyValue("Memory load", buffer);
138+
139+
sprintf_s(buffer, sizeof(buffer), "%I64d Mb", memoryStatus.ullTotalPhys / 1024 / 1024);
140+
WriteKeyValue("Total physical memory", buffer);
141+
142+
sprintf_s(buffer, sizeof(buffer), "%I64d Mb", memoryStatus.ullAvailPhys / 1024 / 1024);
143+
WriteKeyValue("Available physical memory", buffer);
144+
145+
sprintf_s(buffer, sizeof(buffer), "%I64d Mb", memoryStatus.ullTotalPageFile / 1024 / 1024);
146+
WriteKeyValue("Total page file memory", buffer);
147+
148+
sprintf_s(buffer, sizeof(buffer), "%I64d Mb", memoryStatus.ullAvailPageFile / 1024 / 1024);
149+
WriteKeyValue("Available page file memory", buffer);
150+
151+
sprintf_s(buffer, sizeof(buffer), "%I64d Mb", memoryStatus.ullTotalVirtual / 1024 / 1024);
152+
WriteKeyValue("Total virtual memory", buffer);
153+
154+
sprintf_s(buffer, sizeof(buffer), "%I64d Mb", memoryStatus.ullAvailVirtual / 1024 / 1024);
155+
WriteKeyValue("Free virtual memory", buffer);
156+
}
157+
158+
return true;
159+
}
160+
};
161+
162+
member_detour(WriteApplicationInfoDetour, Debug::ReportWriter, bool(void))
163+
{
164+
bool detoured(void)
165+
{
166+
bool ret = original_function(this);
167+
168+
char buffer[256] = { 0 };
169+
sprintf_s(buffer, sizeof(buffer), "%i.%i.%i", ModAPI::GetMajorVersion(), ModAPI::GetMinorVersion(), ModAPI::GetBuildVersion());
170+
WriteKeyValue("ModAPI Version", buffer);
171+
172+
return ret;
173+
}
174+
};
175+
176+
177+
long DebugReportWriterOverride::AttachDetour()
178+
{
179+
long result = 0;
180+
result |= WriteSystemInfoDetour::attach(Address(ModAPI::ChooseAddress(0x0091f480, 0x0091f1c0)));
181+
result |= WriteApplicationInfoDetour::attach(Address(ModAPI::ChooseAddress(0x0091f850, 0x0091f590)));
182+
return result;
183+
}
184+
#endif
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
3+
namespace DebugReportWriterOverride
4+
{
5+
long AttachDetour();
6+
}

‎Spore ModAPI/SourceCode/DLL/dllmain.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "Application.h"
88
#include "TextureOverride.h"
99
#include "SpaceToolIconOverride.h"
10+
#include "DebugReportWriterOverride.h"
1011

1112
uintptr_t baseAddress;
1213
ArgScript::PrintF_ptr ArgScript::PrintF;
@@ -27,6 +28,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
2728
ModAPI::AttachDetour();
2829
TextureOverride::AttachDetour();
2930
SpaceToolIconOverride::AttachDetour();
31+
DebugReportWriterOverride::AttachDetour();
3032
CommitDetours();
3133
break;
3234

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//#ifndef MODAPI_DLL_EXPORT
2+
/****************************************************************************
3+
* Copyright (C) 2026 Rosalie Wanders
4+
*
5+
* This file is part of Spore ModAPI.
6+
*
7+
* Spore ModAPI is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
****************************************************************************/
20+
21+
#include <Spore\Debug\ReportWriter.h>
22+
23+
namespace Debug
24+
{
25+
auto_METHOD(ReportWriter, void, GetFileNameExtension, Args(char* buffer, size_t size), Args(buffer, size));
26+
auto_METHOD(ReportWriter, bool, OpenReport, Args(char* param_1), Args(param_1));
27+
auto_METHOD_(ReportWriter, bool, CloseReport);
28+
auto_METHOD(ReportWriter, bool, BeginSection, Args(const char* name), Args(name));
29+
auto_METHOD_(ReportWriter, void, EndSection);
30+
auto_METHOD(ReportWriter, bool, WriteText, Args(const char* text), Args(text));
31+
auto_METHOD(ReportWriter, bool, WriteFormatted, Args(const char* text), Args(text));
32+
auto_METHOD(ReportWriter, bool, WriteKeyValue, Args(const char* key, const char* value), Args(key, value));
33+
auto_METHOD(ReportWriter, bool, WriteKeyValueFormatted, Args(const char* key, const char* value), Args(key, value));
34+
auto_METHOD_(ReportWriter, void, WriteBlankLine);
35+
auto_METHOD(ReportWriter, bool, Write, Args(const char* text, size_t size), Args(text, size));
36+
auto_METHOD_(ReportWriter, long, GetPosition);
37+
auto_METHOD(ReportWriter, void, SetPosition, Args(long position), Args(position));
38+
};
39+
40+
//#endif

‎Spore ModAPI/Spore ModAPI.vcxproj‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
<ClInclude Include="EASTL\version.h" />
295295
<ClInclude Include="EASTL\weak_ptr.h" />
296296
<ClInclude Include="SourceCode\DLL\Application.h" />
297+
<ClInclude Include="SourceCode\DLL\DebugReportWriterOverride.h" />
297298
<ClInclude Include="SourceCode\DLL\resource.h" />
298299
<ClInclude Include="SourceCode\DLL\SpaceToolIconOverride.h" />
299300
<ClInclude Include="SourceCode\DLL\stdafx.h" />
@@ -327,6 +328,7 @@
327328
<ClInclude Include="Spore\App\IDGenerator.h" />
328329
<ClInclude Include="Spore\App\JobManager.h" />
329330
<ClInclude Include="Spore\App\Thumbnail_cImportExport.h" />
331+
<ClInclude Include="Spore\Debug\ReportWriter.h" />
330332
<ClInclude Include="Spore\Editors\cSPEditorVerbTrayCollection.h" />
331333
<ClInclude Include="Spore\Editors\cSPEditorVerbIcon.h" />
332334
<ClInclude Include="Spore\Editors\cSPEditorVerbIconTray.h" />
@@ -958,6 +960,8 @@
958960
<ClInclude Include="Spore\UTFWin\WinTreeView.h" />
959961
</ItemGroup>
960962
<ItemGroup>
963+
<ClCompile Include="SourceCode\Debug\ReportWriter.cpp" />
964+
<ClCompile Include="SourceCode\DLL\AddressesDebug.cpp" />
961965
<ClCompile Include="SourceCode\DLL\AddressesMovie.cpp" />
962966
<ClCompile Include="SourceCode\DLL\AddressesOpenSSL.cpp" />
963967
<ClCompile Include="SourceCode\Allocator.cpp" />
@@ -996,6 +1000,7 @@
9961000
<ClCompile Include="SourceCode\DLL\AddressesUI.cpp" />
9971001
<ClCompile Include="SourceCode\DLL\AddressesUTFWin.cpp" />
9981002
<ClCompile Include="SourceCode\DLL\Application.cpp" />
1003+
<ClCompile Include="SourceCode\DLL\DebugReportWriterOverride.cpp" />
9991004
<ClCompile Include="SourceCode\DLL\dllmain.cpp" />
10001005
<ClCompile Include="SourceCode\DLL\DllModAPI.cpp" />
10011006
<ClCompile Include="SourceCode\DLL\SpaceToolIconOverride.cpp" />

‎Spore ModAPI/Spore ModAPI.vcxproj.filters‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,12 @@
23192319
<ClInclude Include="Spore\Movie\MovieSystem.h">
23202320
<Filter>Header Files</Filter>
23212321
</ClInclude>
2322+
<ClInclude Include="SourceCode\DLL\DebugReportWriterOverride.h">
2323+
<Filter>Header Files</Filter>
2324+
</ClInclude>
2325+
<ClInclude Include="Spore\Debug\ReportWriter.h">
2326+
<Filter>Header Files</Filter>
2327+
</ClInclude>
23222328
</ItemGroup>
23232329
<ItemGroup>
23242330
<ClCompile Include="SourceCode\Allocator.cpp">
@@ -2825,6 +2831,15 @@
28252831
<ClCompile Include="SourceCode\Movie\MovieSystem.cpp">
28262832
<Filter>Source Files</Filter>
28272833
</ClCompile>
2834+
<ClCompile Include="SourceCode\DLL\DebugReportWriterOverride.cpp">
2835+
<Filter>Source Files</Filter>
2836+
</ClCompile>
2837+
<ClCompile Include="SourceCode\Debug\ReportWriter.cpp">
2838+
<Filter>Source Files</Filter>
2839+
</ClCompile>
2840+
<ClCompile Include="SourceCode\DLL\AddressesDebug.cpp">
2841+
<Filter>Source Files</Filter>
2842+
</ClCompile>
28282843
</ItemGroup>
28292844
<ItemGroup>
28302845
<Natvis Include="EASTL.natvis" />
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include <Spore\Internal.h>
4+
5+
namespace Debug
6+
{
7+
class ReportWriter
8+
{
9+
public:
10+
/* 00h */ // TODO ~ReportWriter();
11+
/* 04h */ void GetFileNameExtension(char* buffer, size_t size);
12+
/* 08h */ bool OpenReport(char* param_1); // TODO
13+
/* 0Ch */ bool CloseReport(void);
14+
/* 10h */ // TODO
15+
/* 14h */ // TODO
16+
/* 18h */ bool BeginSection(const char* name);
17+
/* 1Ch */ void EndSection(void);
18+
/* 20h */ bool WriteText(const char* text);
19+
/* 24h */ bool WriteFormatted(const char* text);
20+
/* 28h */ bool WriteKeyValue(const char* key, const char* value);
21+
/* 2Ch */ bool WriteKeyValueFormatted(const char* key, const char* value);
22+
/* 30h */ void WriteBlankLine(void);
23+
/* 34h */ bool Write(const char* text, size_t size);
24+
/* 38h */ long GetPosition(void);
25+
/* 3Ch */ void SetPosition(long position);
26+
};
27+
28+
namespace Addresses(ReportWriter)
29+
{
30+
DeclareAddress(GetFileNameExtension);
31+
DeclareAddress(OpenReport);
32+
DeclareAddress(CloseReport);
33+
DeclareAddress(BeginSection);
34+
DeclareAddress(EndSection);
35+
DeclareAddress(WriteText);
36+
DeclareAddress(WriteFormatted);
37+
DeclareAddress(WriteKeyValue);
38+
DeclareAddress(WriteKeyValueFormatted);
39+
DeclareAddress(WriteBlankLine);
40+
DeclareAddress(Write);
41+
DeclareAddress(GetPosition);
42+
DeclareAddress(SetPosition);
43+
}
44+
}

0 commit comments

Comments
 (0)