Skip to content

Commit

Permalink
make loader version-independent
Browse files Browse the repository at this point in the history
  • Loading branch information
ianpatt committed Mar 22, 2024
1 parent 5b593fa commit fe4ae03
Show file tree
Hide file tree
Showing 14 changed files with 221 additions and 111 deletions.
4 changes: 2 additions & 2 deletions sfse/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ source_group(
FILES
sfse.cpp
sfse.def
${sfse_common_SOURCE_DIR}/sfse_version.rc
sfse_version.rc
)

source_group(
Expand Down Expand Up @@ -145,7 +145,7 @@ add_library(
${headers}
${sources}
sfse.def
${sfse_common_SOURCE_DIR}/sfse_version.rc
sfse_version.rc
)

add_library(sfse64::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
Expand Down
8 changes: 8 additions & 0 deletions sfse/sfse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "sfse_common/Utilities.h"
#include "sfse_common/SafeWrite.h"
#include "sfse_common/BranchTrampoline.h"
#include "sfse_common/CoreInfo.h"
#include "PluginManager.h"

#include "Hooks_Version.h"
Expand Down Expand Up @@ -175,4 +176,11 @@ extern "C" {

return TRUE;
}

__declspec(dllexport) SFSECoreVersionData SFSECore_Version =
{
SFSECoreVersionData::kVersion,

RUNTIME_VERSION,
};
}
3 changes: 2 additions & 1 deletion sfse/sfse.def
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
EXPORTS
StartSFSE @1
StartSFSE @1
SFSECore_Version
64 changes: 32 additions & 32 deletions sfse_common/sfse_version.rc → sfse/sfse_version.rc
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
#include "sfse_version.h"
1 VERSIONINFO
FILEVERSION 0,SFSE_VERSION_INTEGER,SFSE_VERSION_INTEGER_MINOR,SFSE_VERSION_INTEGER_BETA
PRODUCTVERSION 0,SFSE_VERSION_INTEGER,SFSE_VERSION_INTEGER_MINOR,SFSE_VERSION_INTEGER_BETA
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "A component of the Starfield Script Extender"
VALUE "FileVersion", SFSE_VERSION_VERSTRING
VALUE "InternalName", "SFSE"
VALUE "LegalCopyright", "Copyright (C) 2006-2023"
VALUE "ProductName", "SFSE"
VALUE "ProductVersion", SFSE_VERSION_VERSTRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#include "sfse_common/sfse_version.h"

1 VERSIONINFO
FILEVERSION 0,SFSE_VERSION_INTEGER,SFSE_VERSION_INTEGER_MINOR,SFSE_VERSION_INTEGER_BETA
PRODUCTVERSION 0,SFSE_VERSION_INTEGER,SFSE_VERSION_INTEGER_MINOR,SFSE_VERSION_INTEGER_BETA
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Starfield Script Extender core DLL"
VALUE "FileVersion", SFSE_VERSION_VERSTRING
VALUE "InternalName", "SFSE"
VALUE "LegalCopyright", "Copyright (C) 2006-2024"
VALUE "ProductName", "SFSE"
VALUE "ProductVersion", SFSE_VERSION_VERSTRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
2 changes: 0 additions & 2 deletions sfse_common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ source_group(
FILES
${headers}
${sources}
sfse_version.rc
)

# ---- Create library ----
Expand All @@ -39,7 +38,6 @@ add_library(
STATIC
${headers}
${sources}
sfse_version.rc
)

add_library(sfse::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
Expand Down
15 changes: 15 additions & 0 deletions sfse_common/CoreInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <cstdint>

struct SFSECoreVersionData
{
enum
{
kVersion = 1,
};

std::uint32_t dataVersion;

std::uint32_t runtimeVersion;
};
3 changes: 3 additions & 0 deletions sfse_common/sfse_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,7 @@
#error unknown runtime type
#endif

#define LOADER_VERSION_1_0_0 MAKE_EXE_VERSION(1, 0, 0)
#define LOADER_VERSION LOADER_VERSION_1_0_0

#endif /* __SFSE_VERSION_H__ */
12 changes: 3 additions & 9 deletions sfse_loader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/versioning.cmake)

project(
sfse_loader
VERSION ${SFSE_VERSION_MAJOR}.${SFSE_VERSION_MINOR}.${SFSE_VERSION_PATCH}
VERSION 1.0.0
LANGUAGES CXX
)

Expand Down Expand Up @@ -40,7 +40,7 @@ source_group(
FILES
${headers}
${sources}
${sfse_common_SOURCE_DIR}/sfse_version.rc
sfse_loader_version.rc
sfse_loader.manifest
)

Expand All @@ -50,20 +50,14 @@ add_executable(
${PROJECT_NAME}
${headers}
${sources}
${sfse_common_SOURCE_DIR}/sfse_version.rc
sfse_loader_version.rc
sfse_loader.manifest
)

add_executable(sfse::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/configuration.cmake)

target_compile_definitions(
${PROJECT_NAME}
PRIVATE
RUNTIME_VERSION=${RUNTIME_VERSION_PACKED}
)

target_compile_features(
${PROJECT_NAME}
PUBLIC
Expand Down
130 changes: 70 additions & 60 deletions sfse_loader/IdentifyEXE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,
_MESSAGE("product name = %s", productName.c_str());

hookInfo->version = version;
hookInfo->packedVersion = MAKE_EXE_VERSION(version >> 48, version >> 32, version >> 16);

if(productName == "SFSE")
{
Expand Down Expand Up @@ -331,16 +332,78 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,

bool result = false;

if(isEditor)
{
switch(hookInfo->procType)
{
case kProcType_Steam:
case kProcType_Normal:
case kProcType_WinStore:
case kProcType_GOG:
*dllSuffix = "";

result = true;

break;
case kProcType_Unknown:
default:
PrintLoaderError("Unsupported editor executable type.");
break;
}
}
else
{
char versionStr[256];
sprintf_s(versionStr, "%d_%d_%d", hookInfo->getVersionMajor(), hookInfo->getVersionMinor(), hookInfo->getVersionBuild());
*dllSuffix = versionStr;

switch(hookInfo->procType)
{
case kProcType_Steam:
case kProcType_Normal:
result = true;

break;

case kProcType_GOG:
*dllSuffix += "_gog";

result = true;
break;

case kProcType_WinStore:
*dllSuffix += "_winstore";

result = true;

break;

case kProcType_Packed:
PrintLoaderError("Packed versions of Starfield are not supported.");
break;

case kProcType_Unknown:
default:
PrintLoaderError("Unknown executable type.");
break;
}
}

return result;
}

bool VersionCheck(const ProcHookInfo & procInfo, u64 RUNTIME_VERSION)
{
const u64 kCurVersion =
(u64(GET_EXE_VERSION_MAJOR(RUNTIME_VERSION)) << 48) |
(u64(GET_EXE_VERSION_MINOR(RUNTIME_VERSION)) << 32) |
(u64(GET_EXE_VERSION_BUILD(RUNTIME_VERSION)) << 16);

// convert version resource to internal version format
u32 versionInternal = MAKE_EXE_VERSION(version >> 48, version >> 32, version >> 16);
u32 versionInternal = MAKE_EXE_VERSION(procInfo.version >> 48, procInfo.version >> 32, procInfo.version >> 16);

// version mismatch could mean exe type mismatch
if(version != kCurVersion)
if(procInfo.version != kCurVersion)
{
#if GET_EXE_VERSION_SUB(RUNTIME_VERSION) == RUNTIME_TYPE_BETHESDA
const int expectedProcType = kProcType_Steam;
Expand All @@ -355,7 +418,7 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,
// we only care about steam/gog for this check
const char * foundProcTypeName = nullptr;

switch(hookInfo->procType)
switch(procInfo.procType)
{
case kProcType_Steam:
foundProcTypeName = "Steam";
Expand All @@ -366,7 +429,7 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,
break;
}

if(foundProcTypeName && (hookInfo->procType != expectedProcType))
if(foundProcTypeName && (procInfo.procType != expectedProcType))
{
// different build
PrintLoaderError(
Expand All @@ -382,7 +445,7 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,
}
}

if(version < kCurVersion)
if(procInfo.version < kCurVersion)
{
#if SFSE_TARGETING_BETA_VERSION
if(versionInternal == CURRENT_RELEASE_RUNTIME)
Expand All @@ -402,7 +465,7 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,
SFSE_VERSION_INTEGER, SFSE_VERSION_INTEGER_MINOR, SFSE_VERSION_INTEGER_BETA);
#endif
}
else if(version > kCurVersion)
else if(procInfo.version > kCurVersion)
{
PrintLoaderError(
"You are using a newer version of Starfield than this version of SFSE supports.\n"
Expand All @@ -414,59 +477,6 @@ bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix,
GET_EXE_VERSION_MAJOR(versionInternal), GET_EXE_VERSION_MINOR(versionInternal), GET_EXE_VERSION_BUILD(versionInternal),
SFSE_VERSION_INTEGER, SFSE_VERSION_INTEGER_MINOR, SFSE_VERSION_INTEGER_BETA);
}
else if(isEditor)
{
switch(hookInfo->procType)
{
case kProcType_Steam:
case kProcType_Normal:
case kProcType_WinStore:
case kProcType_GOG:
*dllSuffix = "";

result = true;

break;
case kProcType_Unknown:
default:
PrintLoaderError("Unsupported editor executable type.");
break;
}
}
else
{
char versionStr[256];
sprintf_s(versionStr, "%d_%d_%d", GET_EXE_VERSION_MAJOR(versionInternal), GET_EXE_VERSION_MINOR(versionInternal), GET_EXE_VERSION_BUILD(versionInternal));

switch(hookInfo->procType)
{
case kProcType_Steam:
case kProcType_Normal:
case kProcType_GOG:
*dllSuffix = versionStr;

result = true;

break;

case kProcType_WinStore:
*dllSuffix = versionStr;
*dllSuffix += "_winstore";

result = true;

break;

case kProcType_Packed:
PrintLoaderError("Packed versions of Starfield are not supported.");
break;

case kProcType_Unknown:
default:
PrintLoaderError("Unknown executable type.");
break;
}
}

return result;
return true;
}
9 changes: 7 additions & 2 deletions sfse_loader/IdentifyEXE.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ enum

struct ProcHookInfo
{
u64 version;
u32 procType;
u64 version; // version from resource
u32 packedVersion; // internal packed version number
u32 procType; // kProcType_*

u16 getVersionMajor() { return u16(version >> 48); }
u16 getVersionMinor() { return u16(version >> 32); }
u16 getVersionBuild() { return u16(version >> 16); }
};

bool IdentifyEXE(const char * procName, bool isEditor, std::string * dllSuffix, ProcHookInfo * hookInfo);
Loading

0 comments on commit fe4ae03

Please sign in to comment.