From c9663a8d4e624f4d52002ea85bde7b8b42681b4f Mon Sep 17 00:00:00 2001 From: Kaldaien Date: Tue, 30 Aug 2016 20:18:48 -0400 Subject: [PATCH] Moved a LOT of shared code out of this project and into Special K DLL --- UnX/UnX.rc | Bin 4626 -> 4626 bytes UnX/cheat.cpp | 168 ++----------- UnX/command.cpp | 531 ++---------------------------------------- UnX/command.h | 178 ++++---------- UnX/compatibility.cpp | 205 +--------------- UnX/config.cpp | 39 ++-- UnX/dllmain.cpp | 40 ++-- UnX/ini.cpp | 470 ++----------------------------------- UnX/ini.h | 113 ++++----- UnX/input.cpp | 142 +++++------ UnX/language.cpp | 6 +- UnX/log.cpp | 223 ++---------------- UnX/log.h | 78 +++---- UnX/parameter.h | 10 +- UnX/timing.cpp | 10 +- UnX/window.cpp | 32 +-- UnX/window.h | 8 +- 17 files changed, 352 insertions(+), 1901 deletions(-) diff --git a/UnX/UnX.rc b/UnX/UnX.rc index 2538e8ff53e25c5ee5913baf068bc925299a674f..84db87e43af0591c66b12a830a889324f3807ebc 100644 GIT binary patch delta 37 rcmbQFGD&5_Bo0R7$&)z@8I3m|<Log ( L"[ FFXEvent ] Tick (%f)", +//s x ); float tick = __UNX_speed_mod * x; @@ -461,7 +461,7 @@ UNX_LoadLevel (char* szName) pushfd } - dll_log.Log ( L"[ FFXLevel ] FFX_LoadLevel (%hs)", + dll_log->Log ( L"[ FFXLevel ] FFX_LoadLevel (%hs)", szName ); __asm { popfd @@ -469,147 +469,9 @@ UNX_LoadLevel (char* szName) jmp FFX_LoadLevel_Original } } -class unxMemCmd : public eTB_Command { -public: - eTB_CommandResult execute (const char* szArgs); - - int getNumArgs (void) { return 2; } - int getNumOptionalArgs (void) { return 1; } - int getNumRequiredArgs (void) { - return getNumArgs () - getNumOptionalArgs (); - } - -protected: -private: -}; - -eTB_CommandResult -unxMemCmd::execute (const char* szArgs) -{ - if (szArgs == nullptr) - return eTB_CommandResult ("mem", szArgs); - - intptr_t addr; - char type; - char val [256] = { '\0' }; - - sscanf (szArgs, "%c %x %s", &type, &addr, val); - - static uint8_t* base_addr = nullptr; - - if (base_addr == nullptr) { - base_addr = (uint8_t *)GetModuleHandle (nullptr); - - MEMORY_BASIC_INFORMATION mem_info; - VirtualQuery (base_addr, &mem_info, sizeof mem_info); - - base_addr = (uint8_t *)mem_info.BaseAddress; - - //IMAGE_DOS_HEADER* pDOS = - //(IMAGE_DOS_HEADER *)mem_info.AllocationBase; - //IMAGE_NT_HEADERS* pNT = - //(IMAGE_NT_HEADERS *)((intptr_t)(pDOS + pDOS->e_lfanew)); - } - - addr += (intptr_t)base_addr; - - char result [512]; - - switch (type) { - case 'b': - if (strlen (val)) { - DWORD dwOld; - - VirtualProtect ((LPVOID)addr, 1, PAGE_READWRITE, &dwOld); - uint8_t out; - sscanf (val, "%hhx", &out); - *(uint8_t *)addr = out; - VirtualProtect ((LPVOID)addr, 1, dwOld, &dwOld); - } - - sprintf (result, "%u", *(uint8_t *)addr); - - return eTB_CommandResult ("mem", szArgs, result, 1); - break; - case 's': - if (strlen (val)) { - DWORD dwOld; - - VirtualProtect ((LPVOID)addr, 2, PAGE_READWRITE, &dwOld); - uint16_t out; - sscanf (val, "%hx", &out); - *(uint16_t *)addr = out; - VirtualProtect ((LPVOID)addr, 2, dwOld, &dwOld); - } - - sprintf (result, "%u", *(uint16_t *)addr); - return eTB_CommandResult ("mem", szArgs, result, 1); - break; - case 'i': - if (strlen (val)) { - DWORD dwOld; - - VirtualProtect ((LPVOID)addr, 4, PAGE_READWRITE, &dwOld); - uint32_t out; - sscanf (val, "%x", &out); - *(uint32_t *)addr = out; - VirtualProtect ((LPVOID)addr, 4, dwOld, &dwOld); - } - - sprintf (result, "%u", *(uint32_t *)addr); - return eTB_CommandResult ("mem", szArgs, result, 1); - break; - case 'd': - if (strlen (val)) { - DWORD dwOld; - - VirtualProtect ((LPVOID)addr, 8, PAGE_READWRITE, &dwOld); - double out; - sscanf (val, "%lf", &out); - *(double *)addr = out; - VirtualProtect ((LPVOID)addr, 8, dwOld, &dwOld); - } - - sprintf (result, "%f", *(double *)addr); - return eTB_CommandResult ("mem", szArgs, result, 1); - break; - case 'f': - if (strlen (val)) { - DWORD dwOld; - - VirtualProtect ((LPVOID)addr, 4, PAGE_READWRITE, &dwOld); - float out; - sscanf (val, "%f", &out); - *(float *)addr = out; - VirtualProtect ((LPVOID)addr, 4, dwOld, &dwOld); - } - - sprintf (result, "%f", *(float *)addr); - return eTB_CommandResult ("mem", szArgs, result, 1); - break; - case 't': - if (strlen (val)) { - DWORD dwOld; - - VirtualProtect ((LPVOID)addr, 256, PAGE_READWRITE, &dwOld); - strcpy ((char *)addr, val); - VirtualProtect ((LPVOID)addr, 256, dwOld, &dwOld); - } - sprintf (result, "%s", (char *)addr); - return eTB_CommandResult ("mem", szArgs, result, 1); - break; - } - - return eTB_CommandResult ("mem", szArgs); -} - void unx::CheatManager::Init (void) { - unxMemCmd* mem = new unxMemCmd (); - - SK_GetCommandProcessor ()->AddCommand ("mem", mem); - wchar_t* pwszShortName = UNX_GetExecutableName (); @@ -645,11 +507,13 @@ unx::CheatManager::Init (void) (LPVOID *)&UNX_FFX_GameTick_Original ); UNX_EnableHook ((LPVOID)((intptr_t)__UNX_base_img_addr + 0x420C00)); +#if 0 UNX_CreateFuncHook ( L"FFX_LoadLevel", (LPVOID)((intptr_t)__UNX_base_img_addr + 0x241F60), UNX_LoadLevel, (LPVOID *)&FFX_LoadLevel_Original); UNX_EnableHook ((LPVOID)((intptr_t)__UNX_base_img_addr + 0x241F60)); +#endif UNX_SetSensor (config.cheat.ffx.permanent_sensor); @@ -803,11 +667,15 @@ UNX_KillMeNow (void) if (UNX_IsInBattle ()) { uint8_t* inst = (uint8_t*)((intptr_t)__UNX_base_img_addr + 0x392930); - const uint8_t die [] = { 0xEB, 0x1D, 0 }; - uint8_t live [] = { 0x75, 0x1D, 0 }; + static const uint8_t die [] = { 0xEB, 0x1D, 0 }; + static uint8_t live [] = { 0x75, 0x1D, 0 }; + static bool first = true; - // Backup the original instructions - memcpy (live, inst, 2); + if (first) { + // Backup the original instructions + memcpy (live, inst, 2); + first = false; + } std::queue suspended_tids = UNX_SuspendAllOtherThreads (); @@ -917,10 +785,10 @@ UNX_FFX2_UnitTest (void) //ffx2.party->exp.current != 0; //ffx2.party->vitals.current.HP <= ffx2.party_stats->vitals.max.HP; for (int i = 0; i < 3; i++) { - dll_log.Log ( L"[UnitTest] %lu / %lu HP :: %lu / %lu MP", - ffx2.party [i].vitals.current.HP, - ffx2.party [i].vitals.max.HP, - ffx2.party [i].vitals.current.MP, - ffx2.party [i].vitals.max.MP ); + dll_log->Log ( L"[UnitTest] %lu / %lu HP :: %lu / %lu MP", + ffx2.party [i].vitals.current.HP, + ffx2.party [i].vitals.max.HP, + ffx2.party [i].vitals.current.MP, + ffx2.party [i].vitals.max.MP ); } } \ No newline at end of file diff --git a/UnX/command.cpp b/UnX/command.cpp index dcf6995..a50e280 100644 --- a/UnX/command.cpp +++ b/UnX/command.cpp @@ -18,527 +18,26 @@ * If not, see . * **/ -#define _CRT_SECURE_NO_WARNINGS - #include "command.h" -template <> -str_hash_compare >::size_type -str_hash_compare >::hash_string (const std::string& _Keyval) const -{ - const bool case_insensitive = true; - - size_type __h = 0; - const size_type __len = _Keyval.size (); - const value_type* __data = _Keyval.data (); - - for (size_type __i = 0; __i < __len; ++__i) { - /* Hash Collision Discovered: "r_window_res_x" vs. "r_window_pos_x" */ - //__h = 5 * __h + eTB_CaseAdjust (__data [__i], case_insensitive); - - /* New Hash: sdbm - Collision Free (08/04/12) */ - __h = eTB_CaseAdjust (__data [__i], case_insensitive) + - (__h << 06) + (__h << 16) - - __h; - } - - return __h; -} - - -template <> -str_hash_compare >::size_type -str_hash_compare >::operator() (const std::string& _Keyval) const -{ - return hash_string (_Keyval); -} - -template <> -bool -str_hash_compare >::operator() (const std::string& _lhs, const std::string& _rhs) const -{ - return hash_string (_lhs) < hash_string (_rhs); -} - -class eTB_SourceCmd : public eTB_Command -{ -public: - eTB_SourceCmd (eTB_CommandProcessor* cmd_proc) { - processor_ = cmd_proc; - } - - eTB_CommandResult execute (const char* szArgs) { - /* TODO: Replace with a special tokenizer / parser... */ - FILE* src = fopen (szArgs, "r"); - - if (! src) { - return - eTB_CommandResult ( "source", szArgs, - "Could not open file!", - false, - NULL, - this ); - } - - char line [1024]; - - static int num_lines = 0; - - while (fgets (line, 1024, src) != NULL) { - num_lines++; - - /* Remove the newline character... */ - line [strlen (line) - 1] = '\0'; - - processor_->ProcessCommandLine (line); - - //printf (" Source Line %d - '%s'\n", num_lines++, line); - } - - fclose (src); - - return eTB_CommandResult ( "source", szArgs, - "Success", - num_lines, - NULL, - this ); - } - - int getNumArgs (void) { - return 1; - } - - int getNumOptionalArgs (void) { - return 0; - } - - const char* getHelp (void) { - return "Load and execute a file containing multiple commands " - "(such as a config file)."; - } - -private: - eTB_CommandProcessor* processor_; - -}; - -eTB_CommandProcessor::eTB_CommandProcessor (void) -{ - eTB_Command* src = new eTB_SourceCmd (this); - - AddCommand ("source", src); -} - -const eTB_Command* -eTB_CommandProcessor::AddCommand (const char* szCommand, eTB_Command* pCommand) -{ - if (szCommand == NULL || strlen (szCommand) < 1) - return NULL; - - if (pCommand == NULL) - return NULL; - - /* Command already exists, what should we do?! */ - if (FindCommand (szCommand) != NULL) - return NULL; - - commands_.insert (eTB_CommandRecord (szCommand, pCommand)); - - return pCommand; -} - -bool -eTB_CommandProcessor::RemoveCommand (const char* szCommand) -{ - if (FindCommand (szCommand) != NULL) { - std::unordered_map >::iterator - command = commands_.find (szCommand); - - commands_.erase (command); - return true; - } - - return false; -} - -eTB_Command* -eTB_CommandProcessor::FindCommand (const char* szCommand) const -{ - std::unordered_map >::const_iterator - command = commands_.find (szCommand); - - if (command != commands_.end ()) - return (command)->second; - - return NULL; -} - - - -const eTB_Variable* -eTB_CommandProcessor::AddVariable (const char* szVariable, eTB_Variable* pVariable) -{ - if (szVariable == NULL || strlen (szVariable) < 1) - return NULL; - - if (pVariable == NULL) - return NULL; - - /* Variable already exists, what should we do?! */ - if (FindVariable (szVariable) != NULL) - return NULL; - - variables_.insert (eTB_VariableRecord (szVariable, pVariable)); - - return pVariable; -} - -bool -eTB_CommandProcessor::RemoveVariable (const char* szVariable) -{ - if (FindVariable (szVariable) != NULL) { - std::unordered_map >::iterator - variable = variables_.find (szVariable); - - variables_.erase (variable); - return true; - } - - return false; -} - -const eTB_Variable* -eTB_CommandProcessor::FindVariable (const char* szVariable) const -{ - std::unordered_map >::const_iterator - variable = variables_.find (szVariable); - - if (variable != variables_.end ()) - return (variable)->second; - - return NULL; -} - - - -eTB_CommandResult -eTB_CommandProcessor::ProcessCommandLine (const char* szCommandLine) -{ - if (szCommandLine != NULL && strlen (szCommandLine)) - { - char* command_word = _strdup (szCommandLine); - size_t command_word_len = strlen (command_word); - - char* command_args = command_word; - size_t command_args_len = 0; - - /* Terminate the command word on the first space... */ - for (size_t i = 0; i < command_word_len; i++) { - if (command_word [i] == ' ') { - command_word [i] = '\0'; - - if (i < (command_word_len - 1)) { - command_args = &command_word [i + 1]; - command_args_len = strlen (command_args); - - /* Eliminate trailing spaces */ - for (unsigned int j = 0; j < command_args_len; j++) { - if (command_word [i + j + 1] != ' ') { - command_args = &command_word [i + j + 1]; - break; - } - } - - command_args_len = strlen (command_args); - } - - break; - } - } - - //char* lowercase_cmd_word = strdup (command_word); - //for (int i = strlen (lowercase_cmd_word) - 1; i >= 0; i--) - //lowercase_cmd_word [i] = __ascii_tolower (lowercase_cmd_word [i]); - - std::string cmd_word (command_word); - //std::string cmd_word_lower (lowercase_cmd_word); - std::string cmd_args (command_args_len > 0 ? command_args : ""); - /* ^^^ cmd_args is what is passed back to the object that issued - this command... If no arguments were passed, it MUST be - an empty string. */ - - //free (lowercase_cmd_word); - free (command_word); - - eTB_Command* cmd = SK_GetCommandProcessor ()->FindCommand (cmd_word.c_str ()); - - if (cmd != NULL) { - return cmd->execute (cmd_args.c_str ()); - } - - /* No command found, perhaps the word was a variable? */ - - const eTB_Variable* var = SK_GetCommandProcessor ()->FindVariable (cmd_word.c_str ()); - - if (var != NULL) { - if (var->getType () == eTB_Variable::Boolean) - { - if (command_args_len > 0) { - eTB_VarStub * bool_var = (eTB_VarStub *) var; - bool bool_val = false; - - /* False */ - if (! (_stricmp (cmd_args.c_str (), "false") && _stricmp (cmd_args.c_str (), "0") && - _stricmp (cmd_args.c_str (), "off"))) { - bool_val = false; - bool_var->setValue (bool_val); - } - - /* True */ - else if (! (_stricmp (cmd_args.c_str (), "true") && _stricmp (cmd_args.c_str (), "1") && - _stricmp (cmd_args.c_str (), "on"))) { - bool_val = true; - bool_var->setValue (bool_val); - } - - /* Toggle */ - else if (! (_stricmp (cmd_args.c_str (), "toggle") && _stricmp (cmd_args.c_str (), "~") && - _stricmp (cmd_args.c_str (), "!"))) { - bool_val = ! bool_var->getValue (); - bool_var->setValue (bool_val); - - /* ^^^ TODO: Consider adding a toggle (...) function to - the bool specialization of eTB_VarStub... */ - } else { - // Unknown Trailing Characters - } - } - } - - else if (var->getType () == eTB_Variable::Int) - { - if (command_args_len > 0) { - int original_val = ((eTB_VarStub *) var)->getValue (); - int int_val = 0; - - /* Increment */ - if (! (_stricmp (cmd_args.c_str (), "++") && _stricmp (cmd_args.c_str (), "inc") && - _stricmp (cmd_args.c_str (), "next"))) { - int_val = original_val + 1; - } else if (! (_stricmp (cmd_args.c_str (), "--") && _stricmp (cmd_args.c_str (), "dec") && - _stricmp (cmd_args.c_str (), "prev"))) { - int_val = original_val - 1; - } else - int_val = atoi (cmd_args.c_str ()); - - ((eTB_VarStub *) var)->setValue (int_val); - } - } - - else if (var->getType () == eTB_Variable::Short) - { - if (command_args_len > 0) { - short original_val = ((eTB_VarStub *) var)->getValue (); - short short_val = 0; - - /* Increment */ - if (! (_stricmp (cmd_args.c_str (), "++") && _stricmp (cmd_args.c_str (), "inc") && - _stricmp (cmd_args.c_str (), "next"))) { - short_val = original_val + 1; - } else if (! (_stricmp (cmd_args.c_str (), "--") && _stricmp (cmd_args.c_str (), "dec") && - _stricmp (cmd_args.c_str (), "prev"))) { - short_val = original_val - 1; - } else - short_val = (short)atoi (cmd_args.c_str ()); - - ((eTB_VarStub *) var)->setValue (short_val); - } - } - - else if (var->getType () == eTB_Variable::Float) - { - if (command_args_len > 0) { -// float original_val = ((eTB_VarStub *) var)->getValue (); - float float_val = (float)atof (cmd_args.c_str ()); - - ((eTB_VarStub *) var)->setValue (float_val); - } - } - - return eTB_CommandResult (cmd_word, cmd_args, var->getValueString (), true, var, NULL); - } else { - /* Default args --> failure... */ - return eTB_CommandResult (cmd_word, cmd_args); - } - } else { - /* Invalid Command Line (not long enough). */ - return eTB_CommandResult (szCommandLine); /* Default args --> failure... */ - } -} - -#include - -eTB_CommandResult -eTB_CommandProcessor::ProcessCommandFormatted (const char* szCommandFormat, ...) -{ - va_list ap; - int len; - - va_start (ap, szCommandFormat); - len = _vscprintf (szCommandFormat, ap); - va_end (ap); - - char* szFormattedCommandLine = - (char *)malloc (sizeof (char) * (len + 1)); - - *(szFormattedCommandLine + len) = '\0'; - - va_start (ap, szCommandFormat); - vsprintf (szFormattedCommandLine, szCommandFormat, ap); - va_end (ap); +SK_GetCommandProcessor_pfn SK_GetCommandProcessor = nullptr; - eTB_CommandResult result = - ProcessCommandLine (szFormattedCommandLine); +typedef SK_IVariable* (__stdcall *SK_CreateVar_pfn)( SK_IVariable::VariableType type, + void* var, + SK_IVariableListener *pListener ); +SK_CreateVar_pfn SK_CreateVar = nullptr; - free (szFormattedCommandLine); - - return result; -} - -/** Variable Type Support **/ - - -template <> -eTB_VarStub ::eTB_VarStub ( bool* var, - eTB_iVariableListener* pListener ) : - var_ (var) -{ - listener_ = pListener; - type_ = Boolean; -} - -template <> -std::string -eTB_VarStub ::getValueString (void) const -{ - if (getValue ()) - return std::string ("true"); - else - return std::string ("false"); -} - -template <> -eTB_VarStub ::eTB_VarStub ( const char** var, - eTB_iVariableListener* pListener ) : - var_ (var) -{ - listener_ = pListener; - type_ = String; -} - -template <> -eTB_VarStub ::eTB_VarStub ( int* var, - eTB_iVariableListener* pListener ) : - var_ (var) -{ - listener_ = pListener; - type_ = Int; -} - -template <> -std::string -eTB_VarStub ::getValueString (void) const -{ - char szIntString [32]; - snprintf (szIntString, 32, "%d", getValue ()); - - return std::string (szIntString); -} - - -template <> -eTB_VarStub ::eTB_VarStub ( short* var, - eTB_iVariableListener* pListener ) : - var_ (var) -{ - listener_ = pListener; - type_ = Short; -} - -template <> -std::string -eTB_VarStub ::getValueString (void) const +SK_IVariable* +UNX_CreateVar ( SK_IVariable::VariableType type, + void* var, + SK_IVariableListener *pListener ) { - char szShortString [32]; - snprintf (szShortString, 32, "%d", getValue ()); + extern HMODULE hInjectorDLL; - return std::string (szShortString); -} - - -template <> -eTB_VarStub ::eTB_VarStub ( float* var, - eTB_iVariableListener* pListener ) : - var_ (var) -{ - listener_ = pListener; - type_ = Float; -} - -template <> -std::string -eTB_VarStub ::getValueString (void) const -{ - char szFloatString [32]; - snprintf (szFloatString, 32, "%f", getValue ()); - - // Remove trailing 0's after the . - size_t len = strlen (szFloatString); - for (size_t i = (len - 1); i > 1; i--) { - if (szFloatString [i] == '0' && szFloatString [i - 1] != '.') - len--; - if (szFloatString [i] != '0' && szFloatString [i] != '\0') - break; - } - - szFloatString [len] = '\0'; - - return std::string (szFloatString); -} - - -#include - -// -// In case the injector's command processor is not workable -// t -eTB_CommandProcessor* -__stdcall -FALLBACK_GetCommandProcessor (void) -{ - static eTB_CommandProcessor* command = nullptr; - - if (command == nullptr) { - // - // The ABI is stable, so we don't need this hack - // - //command = new eTB_CommandProcessor (); - - SK_GetCommandProcessor_pfn SK_GetCommandProcessorFromDLL = - (SK_GetCommandProcessor_pfn) - GetProcAddress (LoadLibrary (L"dxgi.dll"), "SK_GetCommandProcessor"); - - command = SK_GetCommandProcessorFromDLL (); + if (SK_CreateVar == nullptr) { + SK_CreateVar = + (SK_CreateVar_pfn)GetProcAddress (hInjectorDLL, "SK_CreateVar"); } - return command; -} - -// This _should_ be overwritten with Special K's DLL import -SK_GetCommandProcessor_pfn SK_GetCommandProcessor = &FALLBACK_GetCommandProcessor; - -//// -//// TODO: Eliminate the dual-definition of this class, and add SpecialK as a compile-time -//// dependency. That project will need some additional re-design for this -//// to happen, but it is an important step for modularity. -//// \ No newline at end of file + return SK_CreateVar (type, var, pListener); +} \ No newline at end of file diff --git a/UnX/command.h b/UnX/command.h index 586cb59..6d70d4e 100644 --- a/UnX/command.h +++ b/UnX/command.h @@ -21,55 +21,53 @@ #ifndef __EPSILON_TESTBED__COMMAND_H__ #define __EPSILON_TESTBED__COMMAND_H__ +#include + # include #include // tolower (...) -template -class eTB_VarStub;// : public eTB_Variable - -class eTB_Variable; -class eTB_Command; +interface SK_IVariable; +interface SK_ICommand; -class eTB_CommandResult +interface SK_ICommandResult { -public: - eTB_CommandResult ( std::string word, + SK_ICommandResult ( std::string word, std::string arguments = "", std::string result = "", int status = false, - const eTB_Variable* var = NULL, - const eTB_Command* cmd = NULL ) : word_ (word), - args_ (arguments), - result_ (result) { + const SK_IVariable* var = NULL, + const SK_ICommand* cmd = NULL ) : word_ (word), + args_ (arguments), + result_ (result) { var_ = var; cmd_ = cmd; status_ = status; } - std::string getWord (void) const { return word_; } - std::string getArgs (void) const { return args_; } - std::string getResult (void) const { return result_; } + std::string getWord (void) const { return word_; } + std::string getArgs (void) const { return args_; } + std::string getResult (void) const { return result_; } - const eTB_Variable* getVariable (void) const { return var_; } - const eTB_Command* getCommand (void) const { return cmd_; } + const SK_IVariable* getVariable (void) const { return var_; } + const SK_ICommand* getCommand (void) const { return cmd_; } - int getStatus (void) const { return status_; } + int getStatus (void) const { return status_; } protected: private: - const eTB_Variable* var_; - const eTB_Command* cmd_; + const SK_IVariable* var_; + const SK_ICommand* cmd_; std::string word_; std::string args_; std::string result_; int status_; }; -class eTB_Command { -public: - virtual eTB_CommandResult execute (const char* szArgs) = 0; +interface SK_ICommand +{ + virtual SK_ICommandResult execute (const char* szArgs) = 0; virtual const char* getHelp (void) { return "No Help Available"; } @@ -78,15 +76,12 @@ class eTB_Command { virtual int getNumRequiredArgs (void) { return getNumArgs () - getNumOptionalArgs (); } - -protected: -private: }; -class eTB_Variable +interface SK_IVariable { -friend class eTB_iVariableListener; -public: + friend interface SK_IVariableListener; + enum VariableType { Float, Double, @@ -102,130 +97,51 @@ friend class eTB_iVariableListener; Unknown } VariableTypes; - virtual VariableType getType (void) const = 0; - virtual std::string getValueString (void) const = 0; + virtual VariableType getType (void) const = 0; + virtual std::string getValueString (void) const = 0; + virtual void* getValuePointer (void) const = 0; protected: VariableType type_; }; -class eTB_iVariableListener -{ -public: - virtual bool OnVarChange (eTB_Variable* var, void* val = NULL) = 0; -protected: -}; - -template -class eTB_VarStub : public eTB_Variable -{ -friend class eTB_iVariableListener; -public: - eTB_VarStub (void) : type_ (Unknown), - var_ (NULL), - listener_ (NULL) { }; - - eTB_VarStub ( T* var, - eTB_iVariableListener* pListener = NULL ); - - eTB_Variable::VariableType getType (void) const - { - return type_; - } - - virtual std::string getValueString (void) const { return "(null)"; } - - const T& getValue (void) const { return *var_; } - void setValue (T& val) { - if (listener_ != NULL) - listener_->OnVarChange (this, &val); - else - *var_ = val; - } - - /// NOTE: Avoid doing this, as much as possible... - T* getValuePtr (void) { return var_; } - - typedef T _Tp; - -protected: - typename eTB_VarStub::_Tp* var_; - -private: - eTB_iVariableListener* listener_; -}; - -#define eTB_CaseAdjust(ch,lower) ((lower) ? __ascii_tolower ((ch)) : (ch)) - -// Hash function for UTF8 strings -template < class _Kty, class _Pr = std::less <_Kty> > -class str_hash_compare +interface SK_IVariableListener { -public: - typedef typename _Kty::value_type value_type; - typedef typename _Kty::size_type size_type; /* Was originally size_t ... */ - - enum - { - bucket_size = 4, - min_buckets = 8 - }; - - str_hash_compare (void) : comp () { }; - str_hash_compare (_Pr _Pred) : comp (_Pred) { }; - - size_type operator() (const _Kty& _Keyval) const; - bool operator() (const _Kty& _Keyval1, const _Kty& _Keyval2) const; - - size_type hash_string (const _Kty& _Keyval) const; - -private: - _Pr comp; + virtual bool OnVarChange (SK_IVariable* var, void* val = NULL) = 0; }; -typedef std::pair eTB_CommandRecord; -typedef std::pair eTB_VariableRecord; - - -class eTB_CommandProcessor +interface SK_ICommandProcessor { -public: - eTB_CommandProcessor (void); + SK_ICommandProcessor (void); - virtual ~eTB_CommandProcessor (void) + virtual ~SK_ICommandProcessor (void) { } - eTB_Command* FindCommand (const char* szCommand) const; + virtual SK_ICommand* FindCommand (const char* szCommand) const; - const eTB_Command* AddCommand ( const char* szCommand, - eTB_Command* pCommand ); - bool RemoveCommand ( const char* szCommand ); + virtual const SK_ICommand* AddCommand ( const char* szCommand, + SK_ICommand* pCommand ); + virtual bool RemoveCommand ( const char* szCommand ); - const eTB_Variable* FindVariable (const char* szVariable) const; + virtual const SK_IVariable* FindVariable (const char* szVariable) const; - const eTB_Variable* AddVariable ( const char* szVariable, - eTB_Variable* pVariable ); - bool RemoveVariable ( const char* szVariable ); + virtual const SK_IVariable* AddVariable ( const char* szVariable, + SK_IVariable* pVariable ); + virtual bool RemoveVariable ( const char* szVariable ); - eTB_CommandResult ProcessCommandLine (const char* szCommandLine); - eTB_CommandResult ProcessCommandFormatted (const char* szCommandFormat, ...); - - -protected: -private: - std::unordered_map < std::string, eTB_Command*, - str_hash_compare > commands_; - std::unordered_map < std::string, eTB_Variable*, - str_hash_compare > variables_; + virtual SK_ICommandResult ProcessCommandLine (const char* szCommandLine); + virtual SK_ICommandResult ProcessCommandFormatted (const char* szCommandFormat, ...); }; - -typedef eTB_CommandProcessor* (__stdcall *SK_GetCommandProcessor_pfn)(void); +typedef SK_ICommandProcessor* (__stdcall *SK_GetCommandProcessor_pfn)(void); extern SK_GetCommandProcessor_pfn SK_GetCommandProcessor; -//extern eTB_CommandProcessor command; +SK_IVariable* +UNX_CreateVar ( SK_IVariable::VariableType type, + void* var, + SK_IVariableListener *pListener = nullptr ); #endif /* __EPSILON_TESTBED__COMMAND_H */ diff --git a/UnX/compatibility.cpp b/UnX/compatibility.cpp index 53c66d3..ce1ce4d 100644 --- a/UnX/compatibility.cpp +++ b/UnX/compatibility.cpp @@ -25,191 +25,6 @@ #include "hook.h" #include "log.h" -typedef HMODULE (WINAPI *LoadLibraryA_pfn)(LPCSTR lpFileName); -typedef HMODULE (WINAPI *LoadLibraryW_pfn)(LPCWSTR lpFileName); - -LoadLibraryA_pfn LoadLibraryA_Original = nullptr; -LoadLibraryW_pfn LoadLibraryW_Original = nullptr; - -typedef HMODULE (WINAPI *LoadLibraryExA_pfn) -( _In_ LPCSTR lpFileName, - _Reserved_ HANDLE hFile, - _In_ DWORD dwFlags -); - -typedef HMODULE (WINAPI *LoadLibraryExW_pfn) -( _In_ LPCWSTR lpFileName, - _Reserved_ HANDLE hFile, - _In_ DWORD dwFlags -); - -LoadLibraryExA_pfn LoadLibraryExA_Original = nullptr; -LoadLibraryExW_pfn LoadLibraryExW_Original = nullptr; - -extern HMODULE hModSelf; - -#include -#pragma comment (lib, "Shlwapi.lib") - -BOOL -BlacklistLibraryW (LPCWSTR lpFileName) -{ - if (StrStrIW (lpFileName, L"ltc_help32") || - StrStrIW (lpFileName, L"ltc_game32")) { - dll_log.Log (L"[Black List] Preventing Raptr's overlay, evil little thing must die!"); - return TRUE; - } - - if (StrStrIW (lpFileName, L"PlayClaw")) { - dll_log.Log (L"[Black List] Incompatible software: PlayClaw disabled"); - return TRUE; - } - - if (StrStrIW (lpFileName, L"fraps")) { - dll_log.Log (L"[Black List] FRAPS is not compatible with this software"); - return TRUE; - } - -#if 0 - if (StrStrIW (lpFileName, L"igdusc32")) { - dll_log.Log (L"[Black List] Intel D3D11 Driver Bypassed"); - return TRUE; - } -#endif - -#if 0 - if (StrStrIW (lpFileName, L"ig75icd32")) { - dll_log.Log (L"[Black List] Preventing Intel Integrated OpenGL driver from activating..."); - return TRUE; - } -#endif - - return FALSE; -} - -BOOL -BlacklistLibraryA (LPCSTR lpFileName) -{ - wchar_t wszWideLibName [MAX_PATH]; - - MultiByteToWideChar (CP_OEMCP, 0x00, lpFileName, -1, wszWideLibName, MAX_PATH); - - return BlacklistLibraryW (wszWideLibName); -} - -HMODULE -WINAPI -LoadLibraryA_Detour (LPCSTR lpFileName) -{ - if (lpFileName == nullptr) - return NULL; - - HMODULE hModEarly = GetModuleHandleA (lpFileName); - - if (hModEarly == NULL && BlacklistLibraryA (lpFileName)) - return NULL; - - HMODULE hMod = LoadLibraryA_Original (lpFileName); - - if (hModEarly != hMod) - dll_log.Log (L"[DLL Loader] Game loaded '%#64hs' ", lpFileName); - - return hMod; -} - -HMODULE -WINAPI -LoadLibraryW_Detour (LPCWSTR lpFileName) -{ - if (lpFileName == nullptr) - return NULL; - - HMODULE hModEarly = GetModuleHandleW (lpFileName); - - if (hModEarly == NULL && BlacklistLibraryW (lpFileName)) - return NULL; - - HMODULE hMod = LoadLibraryW_Original (lpFileName); - - if (hModEarly != hMod) - dll_log.Log (L"[DLL Loader] Game loaded '%#64s' ", lpFileName); - - return hMod; -} - -HMODULE -WINAPI -LoadLibraryExA_Detour ( - _In_ LPCSTR lpFileName, - _Reserved_ HANDLE hFile, - _In_ DWORD dwFlags ) -{ - if (lpFileName == nullptr) - return NULL; - - HMODULE hModEarly = GetModuleHandleA (lpFileName); - - if (hModEarly == NULL && BlacklistLibraryA (lpFileName)) - return NULL; - - HMODULE hMod = LoadLibraryExA_Original (lpFileName, hFile, dwFlags); - - if (hModEarly != hMod && (! ((dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) || - (dwFlags & LOAD_LIBRARY_AS_IMAGE_RESOURCE)))) - dll_log.Log (L"[DLL Loader] Game loaded '%#64hs' ", lpFileName); - - return hMod; -} - -HMODULE -WINAPI -LoadLibraryExW_Detour ( - _In_ LPCWSTR lpFileName, - _Reserved_ HANDLE hFile, - _In_ DWORD dwFlags ) -{ - if (lpFileName == nullptr) - return NULL; - - HMODULE hModEarly = GetModuleHandleW (lpFileName); - - if (hModEarly == NULL && BlacklistLibraryW (lpFileName)) - return NULL; - - HMODULE hMod = LoadLibraryExW_Original (lpFileName, hFile, dwFlags); - - if (hModEarly != hMod && (! ((dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) || - (dwFlags & LOAD_LIBRARY_AS_IMAGE_RESOURCE)))) - dll_log.Log (L"[DLL Loader] Game loaded '%#64s' ", lpFileName); - - return hMod; -} - -void -UNX_InitCompatBlacklist (void) -{ - UNX_CreateDLLHook ( L"kernel32.dll", "LoadLibraryA", - LoadLibraryA_Detour, - (LPVOID*)&LoadLibraryA_Original ); - - UNX_CreateDLLHook ( L"kernel32.dll", "LoadLibraryW", - LoadLibraryW_Detour, - (LPVOID*)&LoadLibraryW_Original ); - - UNX_CreateDLLHook ( L"kernel32.dll", "LoadLibraryExA", - LoadLibraryExA_Detour, - (LPVOID*)&LoadLibraryExA_Original ); - - UNX_CreateDLLHook ( L"kernel32.dll", "LoadLibraryExW", - LoadLibraryExW_Detour, - (LPVOID*)&LoadLibraryExW_Original ); - - if (GetModuleHandleW (L"fraps.dll") != NULL) { - dll_log.Log (L"[Black List] FRAPS detected; expect the game to crash."); - FreeLibrary (GetModuleHandleW (L"fraps.dll")); - } -} - LPVOID __UNX_base_img_addr = nullptr; LPVOID __UNX_end_img_addr = nullptr; @@ -237,8 +52,8 @@ UNX_Scan (const uint8_t* pattern, size_t len, const uint8_t* mask) #if 0 if (base_addr != (uint8_t *)0x400000) { - dll_log.Log ( L"[ Sig Scan ] Expected module base addr. 40000h, but got: %ph", - base_addr ); + dll_log->Log ( L"[ Sig Scan ] Expected module base addr. 40000h, but got: %ph", + base_addr ); } #endif @@ -262,19 +77,19 @@ UNX_Scan (const uint8_t* pattern, size_t len, const uint8_t* mask) if (end_addr > PAGE_WALK_LIMIT) { #if 0 - dll_log.Log ( L"[ Sig Scan ] Module page walk resulted in end addr. out-of-range: %ph", - end_addr ); - dll_log.Log ( L"[ Sig Scan ] >> Restricting to %ph", - PAGE_WALK_LIMIT ); + dll_log->Log ( L"[ Sig Scan ] Module page walk resulted in end addr. out-of-range: %ph", + end_addr ); + dll_log->Log ( L"[ Sig Scan ] >> Restricting to %ph", + PAGE_WALK_LIMIT ); #endif end_addr = PAGE_WALK_LIMIT; } #if 0 - dll_log.Log ( L"[ Sig Scan ] Module image consists of %lu pages, from %ph to %ph", - pages, - base_addr, - end_addr ); + dll_log->Log ( L"[ Sig Scan ] Module image consists of %lu pages, from %ph to %ph", + pages, + base_addr, + end_addr ); #endif #endif diff --git a/UnX/config.cpp b/UnX/config.cpp index 352cde2..d21b159 100644 --- a/UnX/config.cpp +++ b/UnX/config.cpp @@ -28,17 +28,17 @@ #include static - unx::INI::File* + iSK_INI* dll_ini = nullptr; static - unx::INI::File* + iSK_INI* language_ini = nullptr; static - unx::INI::File* + iSK_INI* booster_ini = nullptr; -std::wstring UNX_VER_STR = L"0.6.2"; +std::wstring UNX_VER_STR = L"0.6.3"; unx_config_s config; typedef bool (WINAPI *SK_DXGI_EnableFlipMode_pfn) (bool); @@ -232,19 +232,30 @@ UNX_SetupTexMgmt (void) return false; } +typedef std::wstring (__stdcall *SK_GetConfigPath_pfn)(void); +SK_GetConfigPath_pfn SK_GetConfigPath = nullptr; + bool -UNX_LoadConfig (std::wstring name) { +UNX_LoadConfig (std::wstring name) +{ + SK_GetConfigPath = + (SK_GetConfigPath_pfn) + GetProcAddress ( + GetModuleHandle ( L"dxgi.dll" ), + "SK_GetConfigPath" + ); + // Load INI File - std::wstring full_name = name + L".ini"; - dll_ini = new unx::INI::File ((wchar_t *)full_name.c_str ()); + std::wstring full_name = SK_GetConfigPath () + name + L".ini"; + dll_ini = UNX_CreateINI ((wchar_t *)full_name.c_str ()); bool empty = dll_ini->get_sections ().empty (); - std::wstring language_file = name + L"_Language.ini"; - language_ini = new unx::INI::File ((wchar_t *)language_file.c_str ()); + std::wstring language_file = SK_GetConfigPath () + name + L"_Language.ini"; + language_ini = UNX_CreateINI ((wchar_t *)language_file.c_str ()); - std::wstring booster_file = name + L"_Booster.ini"; - booster_ini = new unx::INI::File ((wchar_t *)booster_file.c_str ()); + std::wstring booster_file = SK_GetConfigPath () + name + L"_Booster.ini"; + booster_ini = UNX_CreateINI ((wchar_t *)booster_file.c_str ()); // // Create Parameters @@ -803,9 +814,9 @@ UNX_SaveConfig (std::wstring name, bool close_config) { sys.version->store (UNX_VER_STR); sys.injector->store (config.system.injector); - dll_ini->write (name + L".ini"); - language_ini->write (name + L"_Language.ini"); - booster_ini->write (name + L"_Booster.ini"); + dll_ini->write (SK_GetConfigPath () + name + L".ini"); + language_ini->write (SK_GetConfigPath () + name + L"_Language.ini"); + booster_ini->write (SK_GetConfigPath () + name + L"_Booster.ini"); if (close_config) { if (dll_ini != nullptr) { diff --git a/UnX/dllmain.cpp b/UnX/dllmain.cpp index f609af6..a716116 100644 --- a/UnX/dllmain.cpp +++ b/UnX/dllmain.cpp @@ -55,14 +55,14 @@ DllThread (LPVOID user) // until initial DLL startup finishes and threads are allowed // to start. // - dll_log.init ( "logs/UnX.log", - "w" ); - dll_log.LogEx ( false, L"--------------- [Untitled X] " - L"---------------\n" ); - dll_log.Log ( L"Untitled X Plug-In\n" - L"============ (Version: v %s) " - L"============", - UNX_VER_STR.c_str () ); + dll_log = UNX_CreateLog (L"logs/UnX.log"); + + dll_log->LogEx ( false, L"--------------- [Untitled X] " + L"---------------\n" ); + dll_log->Log ( L"Untitled X Plug-In\n" + L"============ (Version: v %s) " + L"============", + UNX_VER_STR.c_str () ); if (! UNX_LoadConfig ()) { // Save a new config if none exists @@ -76,18 +76,16 @@ DllThread (LPVOID user) (SK_SetPluginName_pfn) GetProcAddress (hInjectorDLL, "SK_SetPluginName"); + SK_GetCommandProcessor = + (SK_GetCommandProcessor_pfn) + GetProcAddress (hInjectorDLL, "SK_GetCommandProcessor"); + // // If this is NULL, the injector system isn't working right!!! // if (SK_SetPluginName != nullptr) SK_SetPluginName (plugin_name); - // - // Kill Raptr instead of it killing us! - // - extern void UNX_InitCompatBlacklist (void); - UNX_InitCompatBlacklist (); - // Plugin State if (UNX_Init_MinHook () == MH_OK) { unx::LanguageManager::Init (); @@ -135,14 +133,14 @@ DllMain (HMODULE hModule, UNX_UnInit_MinHook (); UNX_SaveConfig (); - dll_log.LogEx ( false, L"============ (Version: v %s) " - L"============\n", - UNX_VER_STR.c_str () ); - dll_log.LogEx ( true, L"End unx.dll\n" ); - dll_log.LogEx ( false, L"--------------- [Untitled X] " - L"---------------" ); + dll_log->LogEx ( false, L"============ (Version: v %s) " + L"============\n", + UNX_VER_STR.c_str () ); + dll_log->LogEx ( true, L"End unx.dll\n" ); + dll_log->LogEx ( false, L"--------------- [Untitled X] " + L"---------------" ); - dll_log.close (); + dll_log->close (); } break; } diff --git a/UnX/ini.cpp b/UnX/ini.cpp index 7de5dad..4a2dee3 100644 --- a/UnX/ini.cpp +++ b/UnX/ini.cpp @@ -23,463 +23,27 @@ #include #include "ini.h" -#include "log.h" -#include - -std::wstring -ErrorMessage (errno_t err, - const char* args, - const wchar_t* ini_name, - UINT line_no, - const char* function_name, - const char* file_name) -{ - wchar_t wszFormattedError [1024]; - - *wszFormattedError = L'\0'; - - swprintf ( wszFormattedError, 1024, - L"\n" - L"Line %u of %hs (in %hs (...)):\n" - L"------------------------\n\n" - L"%hs\n\n File: %s\n\n" - L"\t>> %s <<", - line_no, - file_name, - function_name, - args, - ini_name, - _wcserror (err) ); - - return wszFormattedError; -} - -#define TRY_FILE_IO(x,y,z) { (z) = ##x; if ((z) != 0) \ -dll_log.Log (L"%ws", ErrorMessage ((z), #x, (y), __LINE__, __FUNCTION__, __FILE__)); } - -unx::INI::File::File (wchar_t* filename) -{ - sections.clear (); - - // We skip a few bytes (Unicode BOM) in crertain cirumstances, so this is the - // actual pointer we need to free... - wchar_t* alloc; - - wszName = _wcsdup (filename); - - errno_t ret; - TRY_FILE_IO (_wfopen_s (&fINI, filename, L"rb"), filename, ret); - - if (ret == 0 && fINI != 0) { - fseek (fINI, 0, SEEK_END); - long size = ftell (fINI); - rewind (fINI); - - wszData = new wchar_t [size]; - alloc = wszData; - - fread (wszData, size, 1, fINI); - - // This is essentially our Unicode BOM, if the first character is '[', then it's ANSI. - if (((char *)wszData) [0] == '[') { - char* string = new char [size + 1]; - memcpy (string, wszData, size); - string [size] = '\0'; - delete [] wszData; - wszData = new wchar_t [size + 1]; - MultiByteToWideChar (CP_OEMCP, 0, string, -1, wszData, size + 1); - alloc = wszData; - } - - // Otherwise it's Unicode, let's fix up a couple of things - else { - if (*wszData != L'[') - ++wszData; - - wszData [size / 2 - 1] = '\0'; - } - - parse (); - - delete [] alloc; - wszData = nullptr; - - fflush (fINI); - fclose (fINI); - } - else { - //AD_MessageBox (L"Unable to Locate INI File", filename, MB_OK); - delete [] wszName; - wszName = nullptr; - wszData = nullptr; - } -} - -unx::INI::File::~File (void) -{ - if (wszName != nullptr) { - delete [] wszName; - wszName = nullptr; - } - - if (wszData != nullptr) { - delete[] wszData; - wszData = nullptr; - } -} - -unx::INI::File::Section -Process_Section (wchar_t* buffer, wchar_t* name, int start, int end) -{ - unx::INI::File::Section section (name); - - int key = start; - for (int k = key; k < end; k++) { - if (k < end - 1 && buffer [k] == L'=') { - wchar_t* key_str = new wchar_t [k - key + 1]; - wcsncpy (key_str, buffer + key, k - key); - key_str [k - key] = L'\0'; - //if (! section.name.compare (L"IniVersion")) - //MessageBoxW (NULL, key_str, L"Key", MB_OK); - - int value = k + 1; - for (int l = value; l < end; l++) { - if (l > end - 1 || buffer [l] == L'\n') { - key = l + 1; - k = l + 1; - wchar_t* val_str = new wchar_t [l - value + 1]; - wcsncpy (val_str, buffer + value, l - value); - val_str [l - value] = L'\0'; - - section.add_key_value (key_str, val_str); - - delete [] val_str; - l = end; - } - } - - delete [] key_str; - } - } - - return section; -} - -bool -Import_Section (unx::INI::File::Section& section, wchar_t* buffer, int start, int end) +iSK_INI* +UNX_CreateINI (const wchar_t* const wszName) { - int key = start; - for (int k = key; k < end; k++) { - if (k < end - 1 && buffer [k] == L'=') { - wchar_t* key_str = new wchar_t [k - key + 1]; - wcsncpy (key_str, buffer + key, k - key); - key_str [k - key] = L'\0'; + typedef iSK_INI* (__stdcall *SK_CreateINI_pfn)(const wchar_t* const wszName); + static SK_CreateINI_pfn SK_CreateINI = nullptr; - int value = k + 1; - for (int l = value; l < end; l++) { - if (l > end - 1 || buffer [l] == L'\n') { - key = l + 1; - k = l + 1; - wchar_t* val_str = new wchar_t [l - value + 1]; - wcsncpy (val_str, buffer + value, l - value); - val_str [l - value] = L'\0'; - - // Prefer to change an existing value - if (section.contains_key (key_str)) { - std::wstring& val = section.get_value (key_str); - val = val_str; - } - - // But create a new one if it doesn't already exist - else { - section.add_key_value (key_str, val_str); - } - - delete [] val_str; - l = end; - } - } - - delete [] key_str; - } + if (SK_CreateINI == nullptr) { + SK_CreateINI = + (SK_CreateINI_pfn) + GetProcAddress ( + GetModuleHandle ( L"dxgi.dll" ), + "SK_CreateINI" + ); } - return true; -} - -void -unx::INI::File::parse (void) -{ - if (wszData != nullptr) { - int len = lstrlenW (wszData); - - // We don't want CrLf, just Lf - bool strip_cr = false; - - // Find if the file has any Cr's - for (int i = 0; i < len; i++) { - if (wszData [i] == L'\r') - strip_cr = true; - } - - if (strip_cr) { - // Remove all Cr's and then re-NUL terminate the truncated file - int out = 0; - for (int i = 0; i < len; i++) { - if (wszData [i] != L'\r') - wszData [out++] = wszData [i]; - } - wszData [out] = L'\0'; - - len = out; - } - - int begin = -1; - int end = -1; - - for (int i = 0; i < len; i++) - { - if (wszData [i] == L'[' && (i == 0 || wszData [i - 1] == L'\n')) { - begin = i + 1; - } - - if (wszData [i] == L']' && (i == len - 1 || wszData [i + 1] == L'\n')) - end = i; - - if (end != -1) { - wchar_t* sec_name = new wchar_t [end - begin + 1]; - wcsncpy (sec_name, wszData + begin, end - begin); - sec_name [end - begin] = L'\0'; - //MessageBoxW (NULL, sec_name, L"Section", MB_OK); - - int start = end + 2; - int finish = start; - - bool eof = false; - for (int j = start; j <= len; j++) { - if (j == len) { - finish = j; - eof = true; - break; - } - - if (wszData [j - 1] == L'\n' && wszData [j] == L'[') { - finish = j - 1; - break; - } - } - - Section section = Process_Section (wszData, sec_name, start, finish); - - sections.insert (std::pair (sec_name, section)); - ordered_sections.push_back (sec_name); - delete [] sec_name; - - if (eof) - break; - - i = finish; + iSK_INI* pINI = SK_CreateINI (wszName); - end = -1; - begin = -1; - } - } + if (pINI != nullptr) { + return pINI; + } else { + // ASSERT: WHAT THE HELL?! + return nullptr; } -} - -void -unx::INI::File::import (std::wstring import_data) -{ - wchar_t* wszImport = _wcsdup (import_data.c_str ()); - - if (wszImport != nullptr) { - int len = lstrlenW (wszImport); - - // We don't want CrLf, just Lf - bool strip_cr = false; - - // Find if the file has any Cr's - for (int i = 0; i < len; i++) { - if (wszImport [i] == L'\r') - strip_cr = true; - } - - if (strip_cr) { - // Remove all Cr's and then re-NUL terminate the truncated file - int out = 0; - for (int i = 0; i < len; i++) { - if (wszImport [i] != L'\r') - wszImport [out++] = wszImport [i]; - } - wszImport [out] = L'\0'; - - len = out; - } - - int begin = -1; - int end = -1; - - for (int i = 0; i < len; i++) - { - if (wszImport [i] == L'[' && (i == 0 || wszImport [i - 1] == L'\n')) { - begin = i + 1; - } - - if (wszImport [i] == L']' && (i == len - 1 || wszImport [i + 1] == L'\n')) - end = i; - - if (end != -1) { - wchar_t* sec_name = new wchar_t [end - begin + 1]; - wcsncpy (sec_name, wszImport + begin, end - begin); - sec_name [end - begin] = L'\0'; - //MessageBoxW (NULL, sec_name, L"Section", MB_OK); - - int start = end + 2; - int finish = start; - - bool eof = false; - for (int j = start; j <= len; j++) { - if (j == len) { - finish = j; - eof = true; - break; - } - - if (wszImport [j - 1] == L'\n' && wszImport [j] == L'[') { - finish = j - 1; - break; - } - } - - // Import if the section already exists - if (contains_section (sec_name)) { - Section& section = get_section (sec_name); - - Import_Section (section, wszImport, start, finish); - } - - // Insert otherwise - else { - Section section = Process_Section (wszImport, sec_name, start, finish); - - sections.insert (std::pair (sec_name, section)); - ordered_sections.push_back (sec_name); - } - delete [] sec_name; - - if (eof) - break; - - i = finish; - - end = -1; - begin = -1; - } - } - } - - delete [] wszImport; -} - -std::wstring invalid = L"Invalid"; - -std::wstring& -unx::INI::File::Section::get_value (std::wstring key) -{ - std::map ::iterator it_key = pairs.find (key); - - if (it_key != pairs.end ()) - return (*it_key).second; - - return invalid; -} - -bool -unx::INI::File::Section::contains_key (std::wstring key) -{ - for ( std::map ::iterator it = pairs.begin (); - it != pairs.end (); - it++ ) { - if ((*it).first == key) - return true; - } - - return false; -} - -void -unx::INI::File::Section::add_key_value (std::wstring key, std::wstring value) -{ - pairs.insert (std::pair (key, value)); - ordered_keys.push_back (key); -} - -bool -unx::INI::File::contains_section (std::wstring section) -{ - return sections.count (section) > 0; -} - -unx::INI::File::Section& -unx::INI::File::get_section (std::wstring section) -{ - if (! sections.count (section)) - ordered_sections.push_back (section); - - return sections [section]; -} - -void -unx::INI::File::write (std::wstring fname) -{ - FILE* fOut; - errno_t ret; - - // Strip Read-Only - /////////AD_SetNormalFileAttribs (fname); - - TRY_FILE_IO (_wfopen_s (&fOut, fname.c_str (), L"w,ccs=UTF-16LE"), fname.c_str (), ret); - - if (ret != 0 || fOut == 0) { - //AD_MessageBox (L"ERROR: Cannot open INI file for writing. Is it read-only?", fname.c_str (), MB_OK | MB_ICONSTOP); - return; - } - - std::vector ::iterator it = ordered_sections.begin (); - std::vector ::iterator end = ordered_sections.end (); - - while (it != end) { - Section& section = get_section (*it); - if (section.name.length ()) { - fwprintf (fOut, L"[%s]\n", section.name.c_str ()); - - std::vector ::iterator key_it = section.ordered_keys.begin (); - std::vector ::iterator key_end = section.ordered_keys.end (); - - while (key_it != key_end) { - std::wstring val = section.get_value (*key_it); - fwprintf (fOut, L"%s=%s\n", key_it->c_str (), val.c_str ()); - ++key_it; - } - - // Append a newline for everything except the last line... - if ((it + 1) != end) - fwprintf (fOut, L"\n"); - } - - ++it; - } - - fflush (fOut); - fclose (fOut); - - // Make Read-Only - ////SetFileAttributes (fname.c_str (), FILE_ATTRIBUTE_READONLY); -} - - -const std::map & -unx::INI::File::get_sections (void) -{ - return sections; } \ No newline at end of file diff --git a/UnX/ini.h b/UnX/ini.h index f4cf8a5..f8cada1 100644 --- a/UnX/ini.h +++ b/UnX/ini.h @@ -25,60 +25,65 @@ #include #include -namespace unx { -namespace INI { - class File - { - public: - File (wchar_t* filename); - virtual ~File (void); - - void parse (void); - void import (std::wstring import_data); - void write (std::wstring fname); - - class Section - { - public: - Section (void) { - } - - Section (std::wstring section_name) { - name = section_name; - } - - std::wstring& get_value (std::wstring key); - bool contains_key (std::wstring key); - void add_key_value (std::wstring key, std::wstring value); - - //protected: - //private: - std::wstring name; - std::map pairs; - std::vector ordered_keys; - }; - - const std::map & get_sections (void); - - Section& get_section (std::wstring section); - bool contains_section (std::wstring section); - - protected: - private: - FILE* fINI; - - wchar_t* wszName; - wchar_t* wszData; - - std::map - sections; - - // Preserve insertion order so that we write the INI file in the - // same order we read it. Otherwise things get jumbled around - // arbitrarily as the map is re-hashed. - std::vector - ordered_sections; +#include + +// {B526D074-2F4D-4BAE-B6EC-11CB3779B199} +static const GUID IID_SK_INISection = +{ 0xb526d074, 0x2f4d, 0x4bae, { 0xb6, 0xec, 0x11, 0xcb, 0x37, 0x79, 0xb1, 0x99 } }; + +interface iSK_INISection : public IUnknown +{ +public: + iSK_INISection (void) { + AddRef (); + } + + iSK_INISection (std::wstring section_name) { + Release (); + } + + /*** IUnknown methods ***/ + STDMETHOD ( QueryInterface)(THIS_ REFIID riid, void** ppvObj) = 0; + STDMETHOD_ (ULONG, AddRef) (THIS) = 0; + STDMETHOD_ (ULONG, Release) (THIS) = 0; + + STDMETHOD_ (std::wstring&, get_value) (std::wstring key) = 0; + STDMETHOD_ (void, set_name) (std::wstring name) = 0; + STDMETHOD_ (bool, contains_key) (std::wstring key) = 0; + STDMETHOD_ (void, add_key_value)(std::wstring key, std::wstring value) = 0; +}; + +// {DD2B1E00-6C14-4659-8B45-FCEF1BC2C724} +static const GUID IID_SK_INI = +{ 0xdd2b1e00, 0x6c14, 0x4659, { 0x8b, 0x45, 0xfc, 0xef, 0x1b, 0xc2, 0xc7, 0x24 } }; + +interface iSK_INI : public IUnknown +{ + typedef const std::map _TSectionMap; + + iSK_INI (const wchar_t* filename) { + AddRef (); }; -}} + + virtual ~iSK_INI (void) { + Release (); + } + + /*** IUnknown methods ***/ + STDMETHOD ( QueryInterface)(THIS_ REFIID riid, void** ppvObj) = 0; + STDMETHOD_ (ULONG, AddRef) (THIS) = 0; + STDMETHOD_ (ULONG, Release) (THIS) = 0; + + STDMETHOD_ (void, parse) (THIS) = 0; + STDMETHOD_ (void, import) (THIS_ std::wstring import_data) = 0; + STDMETHOD_ (void, write) (THIS_ std::wstring fname) = 0; + + STDMETHOD_ (_TSectionMap&, get_sections) (THIS) = 0; + STDMETHOD_ (iSK_INISection&, get_section) (std::wstring section) = 0; + STDMETHOD_ (bool, contains_section)(std::wstring section) = 0; +}; + +iSK_INI* +UNX_CreateINI (const wchar_t* const wszName); #endif diff --git a/UnX/input.cpp b/UnX/input.cpp index fb15475..8dcf7b2 100644 --- a/UnX/input.cpp +++ b/UnX/input.cpp @@ -133,14 +133,6 @@ typedef HRESULT (WINAPI *IDirectInput8_CreateDevice_pfn)( LPUNKNOWN pUnkOuter ); -typedef HRESULT (WINAPI *DirectInput8Create_pfn)( - HINSTANCE hinst, - DWORD dwVersion, - REFIID riidltf, - LPVOID *ppvOut, - LPUNKNOWN punkOuter -); - typedef HRESULT (WINAPI *IDirectInputDevice8_GetDeviceState_pfn)( LPDIRECTINPUTDEVICE This, DWORD cbData, @@ -153,10 +145,6 @@ typedef HRESULT (WINAPI *IDirectInputDevice8_SetCooperativeLevel_pfn)( DWORD dwFlags ); -DirectInput8Create_pfn - DirectInput8Create_Original = nullptr; -LPVOID - DirectInput8Create_Hook = nullptr; IDirectInput8_CreateDevice_pfn IDirectInput8_CreateDevice_Original = nullptr; IDirectInputDevice8_GetDeviceState_pfn @@ -167,14 +155,14 @@ IDirectInputDevice8_SetCooperativeLevel_pfn #define DINPUT8_CALL(_Ret, _Call) { \ - dll_log.LogEx (true, L"[ Input ] Calling original function: "); \ + dll_log->LogEx (true, L"[ Input ] Calling original function: "); \ (_Ret) = (_Call); \ _com_error err ((_Ret)); \ if ((_Ret) != S_OK) \ - dll_log.LogEx (false, L"(ret=0x%04x - %s)\n", err.WCode (), \ + dll_log->LogEx (false, L"(ret=0x%04x - %s)\n", err.WCode (), \ err.ErrorMessage ()); \ else \ - dll_log.LogEx (false, L"(ret=S_OK)\n"); \ + dll_log->LogEx (false, L"(ret=S_OK)\n"); \ } #define __PTR_SIZE sizeof LPCVOID @@ -324,11 +312,11 @@ IDirectInput8_CreateDevice_Detour ( IDirectInput8 *This, (rguid == GUID_SysMouse) ? L"Default System Mouse" : L"Other Device"; - dll_log.Log ( L"[ Input ][!] IDirectInput8::CreateDevice (%08Xh, %s, %08Xh, %08Xh)", - This, - wszDevice, - lplpDirectInputDevice, - pUnkOuter ); + dll_log->Log ( L"[ Input ][!] IDirectInput8::CreateDevice (%08Xh, %s, %08Xh, %08Xh)", + This, + wszDevice, + lplpDirectInputDevice, + pUnkOuter ); HRESULT hr; DINPUT8_CALL ( hr, @@ -389,56 +377,6 @@ IDirectInput8_CreateDevice_Detour ( IDirectInput8 *This, } #endif - return hr; -} - -HRESULT -WINAPI -DirectInput8Create_Detour ( HINSTANCE hinst, - DWORD dwVersion, - REFIID riidltf, - LPVOID *ppvOut, - LPUNKNOWN punkOuter ) -{ - dll_log.Log ( L"[ Input ][!] DirectInput8Create (0x%X, %lu, ..., %08Xh, %08Xh)", - hinst, dwVersion, /*riidltf,*/ ppvOut, punkOuter ); - - HRESULT hr; - DINPUT8_CALL (hr, - DirectInput8Create_Original ( hinst, - dwVersion, - riidltf, - ppvOut, - punkOuter )); - - if (hinst != GetModuleHandle (nullptr)) { - dll_log.Log (L"[ Input ] >> A third-party DLL is manipulating DirectInput 8; bad things may happen."); - return hr; - } - - // Avoid multiple hooks for third-party compatibility - static bool hooked = false; - - if (SUCCEEDED (hr) && (! hooked)) { -#if 1 - void** vftable = *(void***)*ppvOut; - - UNX_CreateFuncHook ( L"IDirectInput8::CreateDevice", - vftable [3], - IDirectInput8_CreateDevice_Detour, - (LPVOID*)&IDirectInput8_CreateDevice_Original ); - - UNX_EnableHook (vftable [3]); -#else - DI8_VIRTUAL_OVERRIDE ( ppvOut, 3, - L"IDirectInput8::CreateDevice", - IDirectInput8_CreateDevice_Detour, - IDirectInput8_CreateDevice_Original, - IDirectInput8_CreateDevice_pfn ); -#endif - hooked = true; - } - return hr; } @@ -639,7 +577,7 @@ SK_UNX_PluginKeyPress ( BOOL Control, } if (Control && Shift && vkCode == 'V') { - eTB_CommandResult result = + SK_ICommandResult result = SK_GetCommandProcessor ()->ProcessCommandLine ("PresentationInterval"); if (result.getVariable ()->getValueString () != "0") @@ -651,6 +589,9 @@ SK_UNX_PluginKeyPress ( BOOL Control, //SK_PluginKeyPress_Original (Control, Shift, Alt, vkCode); } +typedef std::wstring (__stdcall *SK_GetConfigPath_pfn)(void); +extern SK_GetConfigPath_pfn SK_GetConfigPath; + void unx::InputManager::Init (void) { @@ -660,7 +601,12 @@ unx::InputManager::Init (void) "SK_GetGameWindow" ); unx::ParameterFactory factory; - unx::INI::File* pad_cfg = new unx::INI::File (L"UnX_Gamepad.ini"); + iSK_INI* pad_cfg = + UNX_CreateINI ( + std::wstring ( + SK_GetConfigPath () + L"UnX_Gamepad.ini" + ).c_str () + ); pad_cfg->parse (); unx::ParameterStringW* texture_set = @@ -689,13 +635,13 @@ unx::InputManager::Init (void) lstrcatW (wszPadRoot, config.textures.gamepad.c_str ()); lstrcatW (wszPadRoot, L"\\"); - dll_log.Log (L"[Button Map] Button Pack: %s", wszPadRoot); + dll_log->Log (L"[Button Map] Button Pack: %s", wszPadRoot); wchar_t wszPadIcons [MAX_PATH] = { L'\0' }; lstrcatW (wszPadIcons, wszPadRoot); lstrcatW (wszPadIcons, L"ButtonMap.dds"); - dll_log.Log (L"[Button Map] Button Map: %s", wszPadIcons); + dll_log->Log (L"[Button Map] Button Map: %s", wszPadIcons); SK_D3D11_AddTexHash ( wszPadIcons, config.textures.pad.icons.high, @@ -736,18 +682,18 @@ unx::InputManager::Init (void) { if (new_button) { if (i > 0) { - dll_log.LogEx + dll_log->LogEx ( false, L"\n" ); } - dll_log.LogEx ( true, L"[Button Map] Button %10s: '%#38s' ( %08x :: ", - wszButtons [i / pad_lods], - wszPadButton, - hash ); + dll_log->LogEx ( true, L"[Button Map] Button %10s: '%#38s' ( %08x :: ", + wszButtons [i / pad_lods], + wszPadButton, + hash ); new_button = false; } else { - dll_log.LogEx ( false, L"%08x )", hash ); + dll_log->LogEx ( false, L"%08x )", hash ); } SK_D3D11_AddTexHash ( @@ -758,7 +704,7 @@ unx::InputManager::Init (void) } } - dll_log.LogEx ( false, L"\n" ); + dll_log->LogEx ( false, L"\n" ); } unx::ParameterBool* supports_XInput = @@ -982,15 +928,35 @@ unx::InputManager::Init (void) ); } - pad_cfg->write (L"UnX_Gamepad.ini"); + pad_cfg->write (SK_GetConfigPath () + L"UnX_Gamepad.ini"); delete pad_cfg; if (config.input.remap_dinput8) { - UNX_CreateDLLHook ( L"dinput8.dll", "DirectInput8Create", - DirectInput8Create_Detour, - (LPVOID*)&DirectInput8Create_Original, - (LPVOID*)&DirectInput8Create_Hook ); - UNX_EnableHook (DirectInput8Create_Hook); + CoInitializeEx (nullptr, COINIT_MULTITHREADED); + + IDirectInput8W* pDInput8 = nullptr; + + HRESULT hr = + CoCreateInstance ( CLSID_DirectInput8, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IDirectInput8, + (LPVOID *)&pDInput8 ); + + if (SUCCEEDED (hr)) { + void** vftable = *(void***)*&pDInput8; + + pDInput8->Initialize (GetModuleHandle (nullptr), DIRECTINPUT_VERSION); + + UNX_CreateFuncHook ( L"IDirectInput8::CreateDevice", + vftable [3], + IDirectInput8_CreateDevice_Detour, + (LPVOID*)&IDirectInput8_CreateDevice_Original ); + + UNX_EnableHook (vftable [3]); + + pDInput8->Release (); + } } @@ -1151,7 +1117,7 @@ UNX_ParseButtonCombo (std::wstring combo, int* out) out [state.buttons++] = button; } - //dll_log.Log (L"Button%lu: %s", state.buttons-1, wszTok); + //dll_log->Log (L"Button%lu: %s", state.buttons-1, wszTok); wszTok = wcstok (nullptr, L"+"); if (state.buttons > 1) diff --git a/UnX/language.cpp b/UnX/language.cpp index d0bfe36..099b0e7 100644 --- a/UnX/language.cpp +++ b/UnX/language.cpp @@ -76,10 +76,10 @@ UNX_PatchLanguageRef (asset_type_t type, int idx, const char* jp, const char* us DWORD dwOld; if (dst != nullptr) { - dll_log.LogEx (true, L"[ Language ] %s%lu: %42hs ==> ", wszType, idx, dst); + dll_log->LogEx (true, L"[ Language ] %s%lu: %42hs ==> ", wszType, idx, dst); VirtualProtect (dst, strlen ((const char *)dst)+1, PAGE_READWRITE, &dwOld); strcpy ((char *)dst, (const char *)src); - dll_log.LogEx (false, L"%hs\n", dst); + dll_log->LogEx (false, L"%hs\n", dst); #if 0 extern LPVOID __UNX_base_img_addr; @@ -88,7 +88,7 @@ UNX_PatchLanguageRef (asset_type_t type, int idx, const char* jp, const char* us __UNX_base_img_addr = (LPVOID)(src-expected); } - dll_log.Log (L"[ Language ] >> SRC addr: %ph :: Base addr: %ph, File addr: %ph", src, __UNX_base_img_addr, (uintptr_t)src-(uintptr_t)__UNX_base_img_addr); + dll_log->Log (L"[ Language ] >> SRC addr: %ph :: Base addr: %ph, File addr: %ph", src, __UNX_base_img_addr, (uintptr_t)src-(uintptr_t)__UNX_base_img_addr); #endif } } diff --git a/UnX/log.cpp b/UnX/log.cpp index 0d208a0..eb1f98c 100644 --- a/UnX/log.cpp +++ b/UnX/log.cpp @@ -23,216 +23,29 @@ #include #include "log.h" -#include +iSK_Logger* dll_log; -WORD -UNX_Timestamp (wchar_t* const out) +iSK_Logger* +UNX_CreateLog (const wchar_t* const wszName) { - SYSTEMTIME stLogTime; + typedef iSK_Logger* (__stdcall *SK_CreateLog_pfn)(const wchar_t* const wszName); + static SK_CreateLog_pfn SK_CreateLog = nullptr; -#if 0 - // Check for Windows 8 / Server 2012 - static bool __hasSystemTimePrecise = - (LOBYTE (LOWORD (GetVersion ())) == 6 && - HIBYTE (LOWORD (GetVersion ())) >= 2) || - LOBYTE (LOWORD (GetVersion () > 6)); - - // More accurate timestamp is available on Windows 6.2+ - if (__hasSystemTimePrecise) { - FILETIME ftLogTime; - GetSystemTimePreciseAsFileTime (&ftLogTime); - FileTimeToSystemTime (&ftLogTime, &stLogTime); - } else { -#else - GetLocalTime (&stLogTime); -#endif - //} - - wchar_t date [64] = { L'\0' }; - wchar_t time [64] = { L'\0' }; - - GetDateFormat (LOCALE_INVARIANT,DATE_SHORTDATE, &stLogTime,NULL,date,64); - GetTimeFormat (LOCALE_INVARIANT,TIME_NOTIMEMARKER,&stLogTime,NULL,time,64); - - out [0] = L'\0'; - - lstrcatW (out, date); - lstrcatW (out, L" "); - lstrcatW (out, time); - lstrcatW (out, L"."); - - return stLogTime.wMilliseconds; -} - -unx_logger_s dll_log; - - -void -unx_logger_s::close (void) -{ - if (fLog != NULL) { - fflush (fLog); - fclose (fLog); - } - - initialized = false; - silent = true; - - DeleteCriticalSection (&log_mutex); -} - -bool -unx_logger_s::init (const char* const szFileName, - const char* const szMode) -{ - if (initialized) - return true; - - // - // Split the path, so we can create the log directory if necessary - // - if (strstr (szFileName, "\\")) { - char* szSplitPath = _strdup (szFileName); - - // Replace all instances of '/' with '\' - size_t len = strlen (szSplitPath); - for (size_t i = 0; i < len; i++) { - if (szSplitPath [i] == '/') - szSplitPath [i] = '\\'; - } - - char* szSplitter = strrchr (szSplitPath, '\\'); - *szSplitter = '\0'; - - char path [MAX_PATH] = { '\0' }; - - char* subpath = strtok (szSplitPath, "\\"); - - // For each subdirectory, create it... - while (subpath != nullptr) { - strcat (path, subpath); - CreateDirectoryA (path, NULL); - strcat (path, "\\"); - - subpath = strtok (NULL, "\\"); - } - - free (szSplitPath); + if (SK_CreateLog == nullptr) { + SK_CreateLog = + (SK_CreateLog_pfn) + GetProcAddress ( + GetModuleHandle ( L"dxgi.dll" ), + "SK_CreateLog" + ); } - fLog = fopen (szFileName, szMode); - - BOOL bRet = InitializeCriticalSectionAndSpinCount (&log_mutex, 25000); - - if ((! bRet) || (fLog == NULL)) { - silent = true; - return false; - } - - initialized = true; - return initialized; -} - -void -unx_logger_s::LogEx (bool _Timestamp, - _In_z_ _Printf_format_string_ - wchar_t const* const _Format, ...) -{ - va_list _ArgList; - - if (! initialized) - return; - - EnterCriticalSection (&log_mutex); - - if ((! fLog) || silent) { - LeaveCriticalSection (&log_mutex); - return; - } + iSK_Logger* pLog = SK_CreateLog (wszName); - if (_Timestamp) { - wchar_t wszLogTime [128]; - - WORD ms = UNX_Timestamp (wszLogTime); - - fwprintf (fLog, L"%s%03u: ", wszLogTime, ms); - } - - va_start (_ArgList, _Format); - { - vfwprintf (fLog, _Format, _ArgList); - } - va_end (_ArgList); - - fflush (fLog); - - LeaveCriticalSection (&log_mutex); -} - -void -unx_logger_s::Log (_In_z_ _Printf_format_string_ - wchar_t const* const _Format, ...) -{ - va_list _ArgList; - - if (! initialized) - return; - - EnterCriticalSection (&log_mutex); - - if ((! fLog) || silent) { - LeaveCriticalSection (&log_mutex); - return; - } - - wchar_t wszLogTime [128]; - - WORD ms = UNX_Timestamp (wszLogTime); - - fwprintf (fLog, L"%s%03u: ", wszLogTime, ms); - - va_start (_ArgList, _Format); - { - vfwprintf (fLog, _Format, _ArgList); - } - va_end (_ArgList); - - fwprintf (fLog, L"\n"); - fflush (fLog); - - LeaveCriticalSection (&log_mutex); -} - -void -unx_logger_s::Log (_In_z_ _Printf_format_string_ - char const* const _Format, ...) -{ - va_list _ArgList; - - if (! initialized) - return; - - EnterCriticalSection (&log_mutex); - - if ((! fLog) || silent) { - LeaveCriticalSection (&log_mutex); - return; - } - - wchar_t wszLogTime [128]; - - WORD ms = UNX_Timestamp (wszLogTime); - - fwprintf (fLog, L"%s%03u: ", wszLogTime, ms); - - va_start (_ArgList, _Format); - { - vfprintf (fLog, _Format, _ArgList); + if (pLog != nullptr) { + return pLog; + } else { + // ASSERT: WHAT THE HELL?! + return nullptr; } - va_end (_ArgList); - - fwprintf (fLog, L"\n"); - fflush (fLog); - - LeaveCriticalSection (&log_mutex); } \ No newline at end of file diff --git a/UnX/log.h b/UnX/log.h index 84ba193..74007cb 100644 --- a/UnX/log.h +++ b/UnX/log.h @@ -21,29 +21,17 @@ #ifndef __UNX__LOG_H__ #define __UNX__LOG_H__ -#include +#include -#include -#include +// {A4BF1773-CAAB-48F3-AD88-C2AB5C23BD6F} +static const GUID IID_SK_Logger = +{ 0xa4bf1773, 0xcaab, 0x48f3, { 0xad, 0x88, 0xc2, 0xab, 0x5c, 0x23, 0xbd, 0x6f } }; -#define UNX_AutoClose_Log(log) ad_logger_t::AutoClose closeme_##log = (log).auto_close (); - -// -// NOTE: This is a barbaric approach to the problem... we clearly have a -// multi-threaded execution model but the logging assumes otherwise. -// -// The log system _is_ thread-safe, but the output can be non-sensical -// when multiple threads are logging calls or even when a recursive -// call is logged in a single thread. -// -// * Consdier using a stack-based approach if these logs become -// indecipherable in the future. -// -struct unx_logger_s +interface iSK_Logger : public IUnknown { class AutoClose { - friend struct unx_logger_s; + friend interface iSK_Logger; public: ~AutoClose (void) { @@ -54,40 +42,48 @@ struct unx_logger_s } protected: - AutoClose (unx_logger_s* log) : log_ (log) { } + AutoClose (iSK_Logger* log) : log_ (log) { } private: - unx_logger_s* log_; + iSK_Logger* log_; }; AutoClose auto_close (void) { return AutoClose (this); } - bool init (const char* const szFilename, - const char* const szMode); - - void close (void); - - void LogEx (bool _Timestamp, - _In_z_ _Printf_format_string_ - wchar_t const* const _Format, ...); - - void Log (_In_z_ _Printf_format_string_ - wchar_t const* const _Format, ...); + iSK_Logger (void) { + AddRef (); + } - void Log (_In_z_ _Printf_format_string_ - char const* const _Format, ...); + virtual ~iSK_Logger (void) { + Release (); + } - FILE* fLog = NULL; - bool silent = false; - bool initialized = false; - CRITICAL_SECTION log_mutex = { 0 }; + /*** IUnknown methods ***/ + STDMETHOD ( QueryInterface)(THIS_ REFIID riid, void** ppvObj) = 0; + STDMETHOD_ (ULONG, AddRef) (THIS) = 0; + STDMETHOD_ (ULONG, Release) (THIS) = 0; + + STDMETHOD_ (bool, init)(THIS_ const wchar_t* const wszFilename, + const wchar_t* const wszMode ) = 0; + STDMETHOD_ (void, close)(THIS) = 0; + + STDMETHOD_ (void, LogEx)(THIS_ bool _Timestamp, + _In_z_ _Printf_format_string_ + wchar_t const* const _Format, + ... ) = 0; + STDMETHOD_ (void, Log) (THIS_ _In_z_ _Printf_format_string_ + wchar_t const* const _Format, + ... ) = 0; + STDMETHOD_ (void, Log) (THIS_ _In_z_ _Printf_format_string_ + char const* const _Format, + ... ) = 0; }; -// -// TODO, we may want to wrap some synchronization construct around these -// -extern unx_logger_s dll_log; +extern iSK_Logger* dll_log; + +iSK_Logger* +UNX_CreateLog (const wchar_t* const wszName); #endif /* __UNX__LOG_H__ */ diff --git a/UnX/parameter.h b/UnX/parameter.h index 2b9885e..7d448db 100644 --- a/UnX/parameter.h +++ b/UnX/parameter.h @@ -42,7 +42,7 @@ class iParameter bool load (void) { if (ini != nullptr) { - INI::File::Section& section = ini->get_section (ini_section); + iSK_INISection& section = ini->get_section (ini_section); if (section.contains_key (ini_key)) { set_value_str (section.get_value (ini_key)); @@ -59,11 +59,11 @@ class iParameter bool ret = false; if (ini != nullptr) { - INI::File::Section& section = ini->get_section (ini_section); + iSK_INISection& section = ini->get_section (ini_section); // If this operation actually creates a section, we need to make sure // that section has a name! - section.name = ini_section; + section.set_name (ini_section); if (section.contains_key (ini_key)) { section.get_value (ini_key) = get_value_str ().c_str (); @@ -80,7 +80,7 @@ class iParameter return ret; } - void register_to_ini (INI::File* file, std::wstring section, std::wstring key) + void register_to_ini (iSK_INI* file, std::wstring section, std::wstring key) { ini = file; ini_section = section; @@ -89,7 +89,7 @@ class iParameter protected: private: - INI::File* ini; + iSK_INI* ini; std::wstring ini_section; std::wstring ini_key; }; diff --git a/UnX/timing.cpp b/UnX/timing.cpp index 0a50c9e..1c624aa 100644 --- a/UnX/timing.cpp +++ b/UnX/timing.cpp @@ -84,7 +84,7 @@ int __cdecl VSYNCEmulation_Detour (int x) { - dll_log.Log (L"[ Time ] VSYNC Emulation Thread Created By Game", x); + dll_log->Log (L"[ Time ] VSYNC Emulation Thread Created By Game", x); return (VSYNCEmulation_Original (x)); } @@ -128,11 +128,11 @@ unx::TimingFix::Init (void) NtSetTimerResolution != nullptr) { ULONG min, max, cur; NtQueryTimerResolution (&min, &max, &cur); - dll_log.Log ( L"[ Timing ] Kernel resolution.: %f ms", - (float)(cur * 100)/1000000.0f ); + dll_log->Log ( L"[ Timing ] Kernel resolution.: %f ms", + (float)(cur * 100)/1000000.0f ); NtSetTimerResolution (max, TRUE, &cur); - dll_log.Log ( L"[ Timing ] New resolution....: %f ms", - (float)(cur * 100)/1000000.0f ); + dll_log->Log ( L"[ Timing ] New resolution....: %f ms", + (float)(cur * 100)/1000000.0f ); } } diff --git a/UnX/window.cpp b/UnX/window.cpp index 1c509db..6d5c710 100644 --- a/UnX/window.cpp +++ b/UnX/window.cpp @@ -171,7 +171,7 @@ UNX_SetFullscreenState (unx_fullscreen_op_t op) if (op == Fullscreen) { if (fs != TRUE) { - dll_log.Log (L"[Fullscreen] Transition: Window -> Full"); + dll_log->Log (L"[Fullscreen] Transition: Window -> Full"); last_fullscreen = fs; @@ -179,14 +179,14 @@ UNX_SetFullscreenState (unx_fullscreen_op_t op) } } else { if (op == Restore) { - dll_log.Log (L"[Fullscreen] Operation: *Restore"); + dll_log->Log (L"[Fullscreen] Operation: *Restore"); UNX_SetFullscreenState (last_fullscreen ? Fullscreen : Window); last_fullscreen = fs; } if (op == Window) { if (fs == TRUE) { - dll_log.Log (L"[Fullscreen] Transition: Full -> Window"); + dll_log->Log (L"[Fullscreen] Transition: Full -> Window"); last_fullscreen = fs; @@ -349,9 +349,9 @@ DetourWindowProc ( _In_ HWND hWnd, UNX_SetGameMute (bMute); } - dll_log.Log ( L"[Window Mgr] Activation: %s", - unx::window.active ? L"ACTIVE" : - L"INACTIVE" ); + dll_log->Log ( L"[Window Mgr] Activation: %s", + unx::window.active ? L"ACTIVE" : + L"INACTIVE" ); // // Allow Alt+Tab to work @@ -540,11 +540,11 @@ UNX_MWA_Thread (LPVOID pUser) SUCCEEDED (pDevDXGI->GetAdapter (&pAdapter) )&& SUCCEEDED ( pAdapter->GetParent (IID_PPV_ARGS (&pFactory)) ) ) { - dll_log.Log( L"[Fullscreen] Setting DXGI Window Association " - L"(HWND: Game=%X,SwapChain=%X)", - SK_GetGameWindow (), desc.OutputWindow ); - dll_log.Log( L"[Fullscreen] >> flags: " - L"DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER" ); + dll_log->Log( L"[Fullscreen] Setting DXGI Window Association " + L"(HWND: Game=%X,SwapChain=%X)", + SK_GetGameWindow (), desc.OutputWindow ); + dll_log->Log( L"[Fullscreen] >> flags: " + L"DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER" ); pFactory->MakeWindowAssociation ( desc.OutputWindow, DXGI_MWA_NO_WINDOW_CHANGES | @@ -693,16 +693,16 @@ unx::WindowManager:: bool unx::WindowManager:: - CommandProcessor::OnVarChange (eTB_Variable* var, void* val) + CommandProcessor::OnVarChange (SK_IVariable* var, void* val) { - eTB_CommandProcessor* pCommandProc = SK_GetCommandProcessor (); + SK_ICommandProcessor* pCommandProc = SK_GetCommandProcessor (); bool known = false; if (! known) { - dll_log.Log ( L"[Window Mgr] UNKNOWN Variable Changed (%p --> %p)", - var, - val ); + dll_log->Log ( L"[Window Mgr] UNKNOWN Variable Changed (%p --> %p)", + var, + val ); } return false; diff --git a/UnX/window.h b/UnX/window.h index 06202b2..9875277 100644 --- a/UnX/window.h +++ b/UnX/window.h @@ -169,11 +169,11 @@ namespace unx void Init (); void Shutdown (); - class CommandProcessor : public eTB_iVariableListener { + class CommandProcessor : public SK_IVariableListener { public: CommandProcessor (void); - virtual bool OnVarChange (eTB_Variable* var, void* val = NULL); + virtual bool OnVarChange (SK_IVariable* var, void* val = NULL); static CommandProcessor* getInstance (void) { @@ -184,8 +184,8 @@ namespace unx } protected: - eTB_Variable* foreground_fps_; - eTB_Variable* background_fps_; + SK_IVariable* foreground_fps_; + SK_IVariable* background_fps_; private: static CommandProcessor* pCommProc;