├── .gitignore ├── include ├── win32 │ ├── events │ │ └── events.h │ ├── patchresult.h │ ├── controls │ │ ├── label.h │ │ ├── statusbar.h │ │ ├── groupbox.h │ │ ├── button.h │ │ ├── checkbox.h │ │ ├── progress.h │ │ ├── editbox.h │ │ ├── control.h │ │ └── window.h │ ├── resources.h │ ├── unpatchertask.h │ ├── task.h │ ├── patchertask.h │ ├── downloadtoolstask.h │ └── mainwindow.h ├── logging │ ├── logstrategy.h │ ├── terminallogstrategy.h │ ├── streamlogstrategy.h │ ├── statusbarlogstrategy.h │ └── combinedlogstrategy.h ├── colors.h ├── archive.h ├── buildsparser.h ├── installinfo.h ├── ziparchive.h ├── toolsdownloader.h ├── unlocker_win.h ├── unlocker_lnx.h ├── patchversioner.h ├── winservices.h ├── debug.h ├── network.h ├── filesystem.hpp ├── patcher.h ├── tar.h ├── versionparser.h └── config.h ├── src ├── logging │ ├── logstrategy.cpp │ ├── terminallogstrategy.cpp │ ├── statusbarlogstrategy.cpp │ ├── streamlogstrategy.cpp │ └── combinedlogstrategy.cpp ├── win32 │ ├── controls │ │ ├── groupbox.cpp │ │ ├── label.cpp │ │ ├── button.cpp │ │ ├── checkbox.cpp │ │ ├── statusbar.cpp │ │ ├── progress.cpp │ │ ├── editbox.cpp │ │ ├── control.cpp │ │ └── window.cpp │ ├── downloadtoolstask.cpp │ ├── unpatchertask.cpp │ ├── patchertask.cpp │ └── mainwindow.cpp ├── buildsparser.cpp ├── versionparser.cpp ├── archive.cpp ├── patchversioner.cpp ├── ziparchive.cpp ├── installinfo.cpp ├── debug.cpp ├── toolsdownloader.cpp ├── main.cpp ├── tar.cpp ├── network.cpp ├── unlocker_win.cpp ├── unlocker_lnx.cpp ├── winservices.cpp └── patcher.cpp ├── tests ├── test_zip.cpp ├── test_tar.cpp ├── test.h └── test_patch.cpp ├── modules └── FindLibZip.cmake ├── Makefile ├── Unlocker.exe.manifest ├── README.md └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /.vs 2 | /exe 3 | /out 4 | CMakeSettings.json 5 | /testing 6 | /LIBS 7 | /debug.log 8 | /test.tar 9 | /test.zip 10 | /testtar 11 | /tools 12 | -------------------------------------------------------------------------------- /include/win32/events/events.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTS_H 2 | #define EVENTS_H 3 | 4 | #include 5 | 6 | enum class EventType { 7 | CLICK_EVENT 8 | }; 9 | 10 | using EventCallback = std::function; 11 | 12 | #endif -------------------------------------------------------------------------------- /include/win32/patchresult.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCHRESULT_H 2 | #define PATCHRESULT_H 3 | 4 | #include 5 | 6 | struct PatchResult 7 | { 8 | bool result; 9 | std::string errorMessage; 10 | std::string logFilePath; 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /include/win32/controls/label.h: -------------------------------------------------------------------------------- 1 | #ifndef LABEL_H 2 | #define LABEL_H 3 | 4 | #include 5 | #include "win32\controls\control.h" 6 | 7 | class Label : public Control 8 | { 9 | public: 10 | Label(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height); 11 | 12 | private: 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /include/logging/logstrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGSTRATEGY_H 2 | #define LOGSTRATEGY_H 3 | 4 | class LogStrategy 5 | { 6 | public: 7 | virtual void verbose(const char* message) = 0; 8 | virtual void debug(const char* message) = 0; 9 | virtual void info(const char* message) = 0; 10 | virtual void error(const char* message) = 0; 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /include/win32/controls/statusbar.h: -------------------------------------------------------------------------------- 1 | #ifndef STATUSBAR_H 2 | #define STATUSBAR_H 3 | 4 | #include 5 | #include 6 | #include "win32/controls/control.h" 7 | 8 | class StatusBar : Control 9 | { 10 | public: 11 | StatusBar(HWND parent, int menuId, LPCSTR text); 12 | 13 | void setText(LPCSTR text); 14 | }; 15 | 16 | #endif -------------------------------------------------------------------------------- /src/logging/logstrategy.cpp: -------------------------------------------------------------------------------- 1 | #ifndef LOGSTRATEGY_H 2 | #define LOGSTRATEGY_H 3 | 4 | class LogStrategy 5 | { 6 | public: 7 | virtual void verbose(const char* message) = 0; 8 | virtual void debug(const char* message) = 0; 9 | virtual void info(const char* message) = 0; 10 | virtual void error(const char* message) = 0; 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /include/win32/controls/groupbox.h: -------------------------------------------------------------------------------- 1 | #ifndef GROUPBOX_H 2 | #define GROUPBOX_H 3 | 4 | #include 5 | #include 6 | #include "win32/controls/control.h" 7 | 8 | class GroupBox : public Control 9 | { 10 | public: 11 | GroupBox(HWND parent, LPCSTR text, int x, int y, int width, int height); 12 | 13 | private: 14 | }; 15 | 16 | #endif -------------------------------------------------------------------------------- /include/colors.h: -------------------------------------------------------------------------------- 1 | #ifndef COLORS_H 2 | #define COLORS_H 3 | 4 | #define ANSI_COLOR_RED "\x1b[31m" 5 | #define ANSI_COLOR_GREEN "\x1b[32m" 6 | #define ANSI_COLOR_YELLOW "\x1b[33m" 7 | #define ANSI_COLOR_BLUE "\x1b[34m" 8 | #define ANSI_COLOR_MAGENTA "\x1b[35m" 9 | #define ANSI_COLOR_CYAN "\x1b[36m" 10 | #define ANSI_COLOR_RESET "\x1b[0m" 11 | 12 | #endif // COLORS_H -------------------------------------------------------------------------------- /include/win32/controls/button.h: -------------------------------------------------------------------------------- 1 | #ifndef BUTTON_H 2 | #define BUTTON_H 3 | 4 | #include 5 | #include 6 | #include "win32/events/events.h" 7 | #include "win32/controls/control.h" 8 | 9 | class Button : public Control 10 | { 11 | public: 12 | Button(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height); 13 | 14 | private: 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /include/win32/controls/checkbox.h: -------------------------------------------------------------------------------- 1 | #ifndef CHECKBOX_H 2 | #define CHECKBOX_H 3 | 4 | #include 5 | #include 6 | #include "win32/events/events.h" 7 | #include "win32/controls/control.h" 8 | 9 | class CheckBox : public Control 10 | { 11 | public: 12 | CheckBox(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height); 13 | void set(bool checked); 14 | bool isChecked(); 15 | 16 | private: 17 | }; 18 | 19 | #endif -------------------------------------------------------------------------------- /src/win32/controls/groupbox.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\win32\controls\groupbox.h" 2 | 3 | GroupBox::GroupBox(HWND parent, LPCSTR text, int x, int y, int width, int height) 4 | { 5 | hWnd = CreateWindow( 6 | "Button", 7 | text, 8 | WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 9 | x, y, width, height, 10 | parent, 11 | NULL, 12 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), 13 | NULL 14 | ); 15 | 16 | applySystemFont(); 17 | } 18 | -------------------------------------------------------------------------------- /include/win32/controls/progress.h: -------------------------------------------------------------------------------- 1 | #ifndef PROGRESS_H 2 | #define PROGRESS_H 3 | 4 | #include 5 | #include 6 | #include "win32/controls/control.h" 7 | 8 | class Progress : public Control 9 | { 10 | public: 11 | Progress(HWND parent, int menuId, int x, int y, int width, int height); 12 | void setRange(int range); 13 | void setStep(int step); 14 | void setProgress(int progress); 15 | void advance(); 16 | 17 | private: 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /src/win32/controls/label.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\win32\controls\label.h" 2 | 3 | Label::Label(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height) 4 | { 5 | parentHwnd = parent; 6 | hWnd = CreateWindow( 7 | "STATIC", 8 | text, 9 | WS_VISIBLE | WS_CHILD, 10 | x, y, width, height, 11 | parent, 12 | (HMENU)menuId, 13 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), 14 | NULL 15 | ); 16 | 17 | applySystemFont(); 18 | } 19 | -------------------------------------------------------------------------------- /src/win32/controls/button.cpp: -------------------------------------------------------------------------------- 1 | #include "win32\controls\button.h" 2 | 3 | Button::Button(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height) 4 | { 5 | parentHwnd = parent; 6 | hWnd = CreateWindow( 7 | "BUTTON", 8 | text, 9 | WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_FLAT, 10 | x, y, width, height, 11 | parent, 12 | (HMENU)menuId, 13 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), 14 | NULL 15 | ); 16 | 17 | applySystemFont(); 18 | } 19 | -------------------------------------------------------------------------------- /include/logging/terminallogstrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef TERMINALLOGSTRATEGY_H 2 | #define TERMINALLOGSTRATEGY_H 3 | 4 | #include 5 | #include "colors.h" 6 | #include "logging/logstrategy.h" 7 | 8 | class TerminalLogStrategy : public LogStrategy 9 | { 10 | public: 11 | virtual void verbose(const char* message) override; 12 | virtual void debug(const char* message) override; 13 | virtual void info(const char* message) override; 14 | virtual void error(const char* message) override; 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /include/win32/controls/editbox.h: -------------------------------------------------------------------------------- 1 | #ifndef EDITBOX_H 2 | #define EDITBOX_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "win32/controls/control.h" 8 | 9 | class EditBox : public Control 10 | { 11 | public: 12 | EditBox(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height); 13 | 14 | void setReadOnly(bool readOnly); 15 | bool isReadOnly() const; 16 | void setText(std::string text); 17 | std::string getText() const; 18 | private: 19 | }; 20 | 21 | #endif -------------------------------------------------------------------------------- /include/archive.h: -------------------------------------------------------------------------------- 1 | #ifndef ARCHIVEUTILS_H 2 | #define ARCHIVEUTILS_H 3 | 4 | #include "filesystem.hpp" 5 | #ifdef __linux__ 6 | #include 7 | #endif 8 | 9 | #include "ziparchive.h" 10 | #include "tar.h" 11 | #include "debug.h" 12 | #include 13 | 14 | class Archive 15 | { 16 | public: 17 | static bool extractZip(fs::path from, std::string filename, fs::path to); 18 | static bool extractTar(fs::path from, std::string filename, fs::path to); 19 | static void extractionProgress(float progress); 20 | }; 21 | 22 | #endif // ARCHIVEUTILS_H 23 | -------------------------------------------------------------------------------- /include/logging/streamlogstrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef STREAMLOGSTRATEGY_H 2 | #define STREAMLOGSTRATEGY_H 3 | 4 | #include 5 | #include "logging/logstrategy.h" 6 | 7 | class StreamLogStrategy : public LogStrategy 8 | { 9 | public: 10 | StreamLogStrategy(std::ostream& stream); 11 | 12 | virtual void verbose(const char* message) override; 13 | virtual void debug(const char* message) override; 14 | virtual void info(const char* message) override; 15 | virtual void error(const char* message) override; 16 | private: 17 | std::ostream& stream; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /include/logging/statusbarlogstrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef STATUSBARLOGSTRATEGY_H 2 | #define STATUSBARLOGSTRATEGY_H 3 | 4 | #include "logging/logstrategy.h" 5 | #include "win32/controls/statusbar.h" 6 | 7 | class StatusBarLogStrategy : public LogStrategy 8 | { 9 | public: 10 | StatusBarLogStrategy(StatusBar* statusBar); 11 | 12 | virtual void verbose(const char* message) override; 13 | virtual void debug(const char* message) override; 14 | virtual void info(const char* message) override; 15 | virtual void error(const char* message) override; 16 | private: 17 | StatusBar* statusBar; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /src/logging/terminallogstrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "logging/terminallogstrategy.h" 2 | 3 | void TerminalLogStrategy::verbose(const char* message) 4 | { 5 | printf(ANSI_COLOR_BLUE "%s" ANSI_COLOR_RESET "\n", message); 6 | } 7 | 8 | void TerminalLogStrategy::debug(const char* message) 9 | { 10 | printf(ANSI_COLOR_CYAN "%s" ANSI_COLOR_RESET "\n", message); 11 | } 12 | 13 | void TerminalLogStrategy::info(const char* message) 14 | { 15 | printf("%s\n", message); 16 | } 17 | 18 | void TerminalLogStrategy::error(const char* message) 19 | { 20 | fprintf(stderr, ANSI_COLOR_RED "%s" ANSI_COLOR_RESET "\n", message); 21 | } -------------------------------------------------------------------------------- /include/logging/combinedlogstrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef COMBINEDLOGSTRATEGY_H 2 | #define COMBINEDLOGSTRATEGY_H 3 | 4 | #include 5 | #include "logging/logstrategy.h" 6 | 7 | class CombinedLogStrategy : public LogStrategy 8 | { 9 | public: 10 | CombinedLogStrategy() {}; 11 | 12 | void add(LogStrategy* strategy); 13 | 14 | virtual void verbose(const char* message) override; 15 | virtual void debug(const char* message) override; 16 | virtual void info(const char* message) override; 17 | virtual void error(const char* message) override; 18 | private: 19 | std::vector logStrategies; 20 | }; 21 | 22 | #endif -------------------------------------------------------------------------------- /include/win32/controls/control.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTROL_H 2 | #define CONTROL_H 3 | 4 | #include 5 | #include 6 | #include "win32/events/events.h" 7 | 8 | class Control 9 | { 10 | public: 11 | Control(); 12 | 13 | void addEventListener(EventType eventType, EventCallback callback); 14 | void triggerEvent(EventType eventType); 15 | 16 | void setEnabled(bool enabled); 17 | bool isEnabled(); 18 | 19 | HWND getHwnd() const; 20 | 21 | protected: 22 | std::map events; 23 | HWND hWnd = NULL; 24 | HWND parentHwnd = NULL; 25 | 26 | void applySystemFont(); 27 | }; 28 | 29 | #endif -------------------------------------------------------------------------------- /src/logging/statusbarlogstrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "logging/statusbarlogstrategy.h" 2 | 3 | StatusBarLogStrategy::StatusBarLogStrategy(StatusBar* statusBar) 4 | : statusBar(statusBar) 5 | { 6 | 7 | } 8 | 9 | void StatusBarLogStrategy::verbose(const char* message) 10 | { 11 | statusBar->setText(message); 12 | } 13 | 14 | void StatusBarLogStrategy::debug(const char* message) 15 | { 16 | statusBar->setText(message); 17 | } 18 | 19 | void StatusBarLogStrategy::info(const char* message) 20 | { 21 | statusBar->setText(message); 22 | } 23 | 24 | void StatusBarLogStrategy::error(const char* message) 25 | { 26 | statusBar->setText(message); 27 | } -------------------------------------------------------------------------------- /include/win32/resources.h: -------------------------------------------------------------------------------- 1 | #ifndef RESOURCES_H 2 | #define RESOURCES_H 3 | 4 | #define IDC_PATH_EDITBOX 50 5 | #define IDC_PATH_BROWSEBTN 51 6 | #define IDC_PATH_EDITBOXX64 52 7 | #define IDC_PATH_BROWSEBTNX64 53 8 | #define IDC_BROWSELABEL 54 9 | #define IDC_BROWSELABEL_X64 55 10 | #define IDC_TOOLS_GROUPBOX 56 11 | #define IDC_DOWNLOADTOOLS_CHECKBOX 57 12 | #define IDC_TOOLSPATH_LABEL 58 13 | #define IDC_TOOLSPATH_EDITBOX 59 14 | #define IDC_TOOLSPATH_BROWSE_BTN 60 15 | #define IDC_PATCH_BTN 61 16 | #define IDC_REVERT_PATCH_BTN 62 17 | #define IDC_PROGRESSBAR 63 18 | #define IDC_STATUSBAR 64 19 | #define IDC_TOOLS_DOWNLOAD_BTN 65 20 | 21 | #endif -------------------------------------------------------------------------------- /src/logging/streamlogstrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "logging/streamlogstrategy.h" 2 | 3 | StreamLogStrategy::StreamLogStrategy(std::ostream& stream) 4 | : stream(stream) 5 | { 6 | } 7 | 8 | void StreamLogStrategy::verbose(const char* message) 9 | { 10 | stream << "::VERBOSE " << message << std::endl; 11 | } 12 | 13 | void StreamLogStrategy::debug(const char* message) 14 | { 15 | stream << "::DEBUG " << message << std::endl; 16 | } 17 | 18 | void StreamLogStrategy::info(const char* message) 19 | { 20 | stream << "::INFO " << message << std::endl; 21 | } 22 | 23 | void StreamLogStrategy::error(const char* message) 24 | { 25 | stream << "::ERROR " << message << std::endl; 26 | } -------------------------------------------------------------------------------- /include/buildsparser.h: -------------------------------------------------------------------------------- 1 | #ifndef BUILDSPARSER_H 2 | #define BUILDSPARSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "config.h" 10 | 11 | class BuildsParser 12 | { 13 | public: 14 | BuildsParser(const std::string& buildshtmltext); 15 | const std::string& getLatest() const; 16 | std::list::const_iterator cbegin() const; 17 | std::list::const_iterator cend() const; 18 | int size() const; 19 | private: 20 | std::string htmltext; 21 | std::list builds; 22 | std::regex pattern = std::regex(VERSION_REGEX_PATTERN, std::regex::icase); 23 | }; 24 | 25 | #endif // BUILDSPARSER_H 26 | -------------------------------------------------------------------------------- /include/installinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef INSTALLINFOUTILS_H 2 | #define INSTALLINFOUTILS_H 3 | 4 | #include 5 | #include 6 | 7 | #include "config.h" 8 | 9 | class VMWareInfoException : public std::runtime_error 10 | { 11 | public: 12 | VMWareInfoException(const char* message) : std::runtime_error(message) {} 13 | VMWareInfoException(const std::string& message) : std::runtime_error(message) {} 14 | }; 15 | 16 | class VMWareInfoRetriever 17 | { 18 | public: 19 | VMWareInfoRetriever(); 20 | std::string getInstallPath(); 21 | std::string getInstallPath64(); 22 | std::string getProductVersion(); 23 | 24 | private: 25 | std::string installPath, installPath64, prodVersion; 26 | }; 27 | 28 | #endif // INSTALLINFOUTILS_H 29 | -------------------------------------------------------------------------------- /src/win32/controls/checkbox.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\win32\controls\checkbox.h" 2 | 3 | CheckBox::CheckBox(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height) 4 | { 5 | hWnd = CreateWindow( 6 | "BUTTON", 7 | text, 8 | WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, 9 | x, y, width, height, 10 | parent, 11 | (HMENU)menuId, 12 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), 13 | NULL 14 | ); 15 | 16 | applySystemFont(); 17 | } 18 | 19 | void CheckBox::set(bool checked) 20 | { 21 | SendMessage(hWnd, BM_SETCHECK, checked ? BST_CHECKED : BST_UNCHECKED, 0); 22 | } 23 | 24 | bool CheckBox::isChecked() 25 | { 26 | HRESULT res = SendMessageA(hWnd, BM_GETCHECK, 0, 0); 27 | return res == BST_CHECKED; 28 | } 29 | -------------------------------------------------------------------------------- /include/ziparchive.h: -------------------------------------------------------------------------------- 1 | #ifndef UNLOCKER_ZIP_H 2 | #define UNLOCKER_ZIP_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define LIBZIP_STATIC 9 | 10 | #include 11 | #include 12 | 13 | class ZipException : public std::runtime_error 14 | { 15 | public: 16 | ZipException(const char* message) : std::runtime_error(message) {} 17 | ZipException(const std::string& message) : std::runtime_error(message) {} 18 | }; 19 | 20 | class Zip { 21 | public: 22 | Zip(const std::string& zipFile); 23 | ~Zip(); 24 | bool extract(const std::string& fileName, const std::string& to, void(*progressCallback)(float) = nullptr); 25 | private: 26 | static constexpr size_t AR_BUFFER_SIZE = 1024*16; 27 | zip_t* zip_archive = nullptr; 28 | }; 29 | 30 | 31 | #endif // UNLOCKER_ZIP_H -------------------------------------------------------------------------------- /include/toolsdownloader.h: -------------------------------------------------------------------------------- 1 | #ifndef TOOLSDOWNLOADER_H 2 | #define TOOLSDOWNLOADER_H 3 | 4 | #include 5 | #include "filesystem.hpp" 6 | #include "network.h" 7 | #include "archive.h" 8 | #include "buildsparser.h" 9 | #include "debug.h" 10 | 11 | class ToolsDownloaderException : public std::runtime_error 12 | { 13 | public: 14 | ToolsDownloaderException(const char* message) : std::runtime_error(message) {} 15 | ToolsDownloaderException(const std::string& message) : std::runtime_error(message) {} 16 | }; 17 | 18 | class ToolsDownloader 19 | { 20 | public: 21 | ToolsDownloader(Network& network); 22 | bool download(const fs::path& to); 23 | private: 24 | Network& network; 25 | 26 | bool downloadFromCore(const fs::path& to); 27 | bool downloadDirectly(const fs::path& to); 28 | }; 29 | 30 | #endif // TOOLSDOWNLOADER_H -------------------------------------------------------------------------------- /src/win32/controls/statusbar.cpp: -------------------------------------------------------------------------------- 1 | #include "win32\controls\statusbar.h" 2 | 3 | StatusBar::StatusBar(HWND parent, int menuId, LPCSTR text) 4 | { 5 | hWnd = CreateWindowEx( 6 | 0, // no extended styles 7 | STATUSCLASSNAME, // name of status bar class 8 | text, 9 | WS_CHILD | WS_VISIBLE, // creates a visible child window 10 | 0, 0, 0, 0, // ignores size and position 11 | parent, // handle to parent window 12 | (HMENU)menuId, // child window identifier 13 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), // handle to application instance 14 | NULL); 15 | } 16 | 17 | void StatusBar::setText(LPCSTR text) 18 | { 19 | SetWindowText(hWnd, text); 20 | } 21 | -------------------------------------------------------------------------------- /src/logging/combinedlogstrategy.cpp: -------------------------------------------------------------------------------- 1 | #include "logging/combinedlogstrategy.h" 2 | 3 | void CombinedLogStrategy::add(LogStrategy* strategy) 4 | { 5 | logStrategies.emplace_back(strategy); 6 | } 7 | 8 | void CombinedLogStrategy::verbose(const char* message) 9 | { 10 | for (LogStrategy* strategy : logStrategies) { 11 | strategy->verbose(message); 12 | } 13 | } 14 | 15 | void CombinedLogStrategy::debug(const char* message) 16 | { 17 | for (LogStrategy* strategy : logStrategies) { 18 | strategy->debug(message); 19 | } 20 | } 21 | 22 | void CombinedLogStrategy::info(const char* message) 23 | { 24 | for (LogStrategy* strategy : logStrategies) { 25 | strategy->info(message); 26 | } 27 | } 28 | 29 | void CombinedLogStrategy::error(const char* message) 30 | { 31 | for (LogStrategy* strategy : logStrategies) { 32 | strategy->error(message); 33 | } 34 | } -------------------------------------------------------------------------------- /tests/test_zip.cpp: -------------------------------------------------------------------------------- 1 | #include "ziparchive.h" 2 | #include "test.h" 3 | 4 | void zip_extraction(); 5 | 6 | int main(int argc, char** argv) { 7 | test_info("Running TEST: Zip Extraction"); 8 | 9 | zip_extraction(); 10 | 11 | #ifdef WIN32 12 | system("pause"); 13 | #endif 14 | return 0; 15 | } 16 | 17 | void zip_extraction() { 18 | BEGIN_TEST("Testing ZIP Extraction"); 19 | 20 | test_status("CWD is: %s", getCwd().c_str()); 21 | 22 | if (!fileExists("./test.zip")) 23 | { 24 | TEST_ERROR("File test.zip does not exist in current directory"); 25 | } 26 | 27 | try { 28 | Zip testZip("./test.zip"); 29 | 30 | printf("\n"); 31 | testZip.extract("test.file", "./test.file", updateProgress); 32 | printf("\n"); 33 | 34 | remove("./test.file"); 35 | 36 | TEST_SUCCESS(); 37 | } 38 | catch (const std::exception& exc) { 39 | TEST_ERROR(exc.what()); 40 | } 41 | } -------------------------------------------------------------------------------- /src/win32/controls/progress.cpp: -------------------------------------------------------------------------------- 1 | #include "win32\controls\progress.h" 2 | 3 | 4 | Progress::Progress(HWND parent, int menuId, int x, int y, int width, int height) 5 | { 6 | hWnd = CreateWindow( 7 | PROGRESS_CLASS, 8 | "", 9 | WS_CHILD | WS_VISIBLE, 10 | x, y, width, height, 11 | parent, 12 | (HMENU)menuId, 13 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), 14 | NULL 15 | ); 16 | 17 | applySystemFont(); 18 | } 19 | 20 | void Progress::setRange(int range) 21 | { 22 | SendMessage(hWnd, PBM_SETRANGE, 0, MAKELPARAM(0, range)); 23 | } 24 | 25 | void Progress::setStep(int step) 26 | { 27 | SendMessage(hWnd, PBM_SETSTEP, (WPARAM)step, 0); 28 | } 29 | 30 | void Progress::setProgress(int progress) 31 | { 32 | SendMessage(hWnd, PBM_SETPOS, (WPARAM)progress, 0); 33 | } 34 | 35 | void Progress::advance() 36 | { 37 | SendMessage(hWnd, PBM_STEPIT, 0, 0); 38 | } 39 | -------------------------------------------------------------------------------- /include/win32/unpatchertask.h: -------------------------------------------------------------------------------- 1 | #ifndef UNPATCHERTASK_H 2 | #define UNPATCHERTASK_H 3 | 4 | #include 5 | #include "win32/task.h" 6 | #include "win32/patchresult.h" 7 | #include "unlocker_win.h" 8 | 9 | class MainWindow; 10 | 11 | class UnpatcherTask : public Task 12 | { 13 | public: 14 | UnpatcherTask(MainWindow& mainWindow); 15 | void setOnCompleteCallback(std::function completeCallback); 16 | void setOnProgressCallback(std::function progressCallback); 17 | protected: 18 | void onProgressUpdate(float progress) override; 19 | PatchResult doInBackground(void* arg) override; 20 | void onPostExecute(PatchResult result) override; 21 | private: 22 | MainWindow& mainWindow; 23 | 24 | std::function onCompleteCallback = nullptr; 25 | std::function onProgressCallback = nullptr; 26 | }; 27 | 28 | #endif -------------------------------------------------------------------------------- /include/unlocker_win.h: -------------------------------------------------------------------------------- 1 | #ifndef UNLOCKERWIN_H 2 | #define UNLOCKERWIN_H 3 | 4 | #include 5 | #include "filesystem.hpp" 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "config.h" 12 | #include "network.h" 13 | #include "versionparser.h" 14 | #include "debug.h" 15 | #include "toolsdownloader.h" 16 | #include "installinfo.h" 17 | #include "winservices.h" 18 | #include "patcher.h" 19 | #include "patchversioner.h" 20 | 21 | #include 22 | 23 | bool downloadTools(fs::path path, std::function progressCallback = nullptr); 24 | void copyTools(fs::path toolspath, fs::path copyTo); 25 | 26 | void preparePatchWin(fs::path backupPath, fs::path vmInstallPath); 27 | void applyPatchWin(const fs::path& vmwareInstallPath, const fs::path& vmwareInstallPath64); 28 | void stopServices(); 29 | void restartServices(); 30 | 31 | #endif // UNLOCKERWIN_H -------------------------------------------------------------------------------- /src/buildsparser.cpp: -------------------------------------------------------------------------------- 1 | #include "buildsparser.h" 2 | 3 | BuildsParser::BuildsParser(const std::string& buildshtmltext) 4 | : htmltext(buildshtmltext) 5 | { 6 | std::istringstream iss(htmltext); 7 | 8 | std::string line; 9 | while (std::getline(iss, line)) 10 | { 11 | std::smatch vmatch; 12 | if (std::regex_match(line, vmatch, pattern)) 13 | { 14 | builds.emplace_back(vmatch.str(1)); 15 | } 16 | } 17 | } 18 | 19 | const std::string& BuildsParser::getLatest() const 20 | { 21 | if (builds.size() == 0) 22 | throw std::runtime_error("No elements in the list"); 23 | 24 | return *builds.cbegin(); 25 | } 26 | 27 | std::list::const_iterator BuildsParser::cbegin() const 28 | { 29 | return builds.cbegin(); 30 | } 31 | 32 | std::list::const_iterator BuildsParser::cend() const 33 | { 34 | return builds.end(); 35 | } 36 | 37 | int BuildsParser::size() const 38 | { 39 | return builds.size(); 40 | } 41 | -------------------------------------------------------------------------------- /include/unlocker_lnx.h: -------------------------------------------------------------------------------- 1 | #ifndef UNLOCKERLNX_H 2 | #define UNLOCKERLNX_H 3 | 4 | #include 5 | #include "filesystem.hpp" 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "config.h" 12 | #include "network.h" 13 | #include "versionparser.h" 14 | #include "debug.h" 15 | #include "toolsdownloader.h" 16 | #include "installinfo.h" 17 | #include "patcher.h" 18 | 19 | #include 20 | #include 21 | 22 | #include "patchversioner.h" 23 | 24 | #define stricmp(a, b) strcasecmp(a, b) 25 | 26 | #include 27 | 28 | #define CHECKRES(x) try{ (x); } catch (const PatchException& exc) { Logger::error(exc.what()); } 29 | #define KILL(x) (x); exit(1); 30 | 31 | bool downloadTools(fs::path path); 32 | void copyTools(fs::path toolspath); 33 | 34 | void installLnx(); 35 | void preparePatchLnx(fs::path backupPath); 36 | void applyPatchLnx(); 37 | void uninstallLnx(); 38 | 39 | #endif // UNLOKERLNX_H -------------------------------------------------------------------------------- /src/win32/controls/editbox.cpp: -------------------------------------------------------------------------------- 1 | #include "win32\controls\editbox.h" 2 | 3 | EditBox::EditBox(HWND parent, int menuId, LPCSTR text, int x, int y, int width, int height) 4 | { 5 | hWnd = CreateWindow( 6 | "Edit", 7 | text, 8 | WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL, 9 | x, y, width, height, 10 | parent, 11 | (HMENU)menuId, 12 | (HINSTANCE)GetWindowLongPtr(parent, GWLP_HINSTANCE), 13 | NULL 14 | ); 15 | 16 | applySystemFont(); 17 | } 18 | 19 | void EditBox::setReadOnly(bool readOnly) 20 | { 21 | SendMessage(hWnd, EM_SETREADONLY, readOnly, 0); 22 | } 23 | 24 | bool EditBox::isReadOnly() const 25 | { 26 | return GetWindowLongPtr(hWnd, GWL_STYLE) & ES_READONLY; 27 | } 28 | 29 | void EditBox::setText(std::string text) 30 | { 31 | SetWindowText(hWnd, text.c_str()); 32 | } 33 | 34 | std::string EditBox::getText() const 35 | { 36 | char buffer[4096]; 37 | GetWindowText(hWnd, buffer, 4096); 38 | return std::string(buffer); 39 | } 40 | -------------------------------------------------------------------------------- /include/patchversioner.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCHVERSIONER_H 2 | #define PATCHVERSIONER_H 3 | 4 | #ifdef _WIN32 5 | #include 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "filesystem.hpp" 14 | #include "config.h" 15 | 16 | class PatchVersionerException : public std::runtime_error 17 | { 18 | public: 19 | PatchVersionerException(const char* msg) : std::runtime_error(msg) {} 20 | PatchVersionerException(const std::string& msg) : std::runtime_error(msg) {} 21 | }; 22 | 23 | class PatchVersioner 24 | { 25 | public: 26 | PatchVersioner(const fs::path& installPath); 27 | time_t getPatchTime() const; 28 | std::string getPatchVersion() const; 29 | void writePatchData(); 30 | void removePatchVersion(); 31 | bool hasPatch() const; 32 | 33 | private: 34 | typedef struct _patch_version_t { 35 | char timestamp[256]; 36 | char version[256]; 37 | } patch_version_t; 38 | 39 | std::string versionFile; 40 | bool haspatch = false; 41 | patch_version_t vData = {}; 42 | }; 43 | 44 | #endif -------------------------------------------------------------------------------- /include/win32/controls/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "debug.h" 10 | #include "win32/controls/control.h" 11 | #include "win32/events/events.h" 12 | 13 | class Window : public Control 14 | { 15 | public: 16 | Window(HINSTANCE hInstance, int nCmdShow, const std::string& className, const std::string& title, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int width = CW_USEDEFAULT, int height = CW_USEDEFAULT); 17 | ~Window(); 18 | // Override to setup buttons, controls, etc. 19 | virtual void onCreate(HWND hWnd) {}; 20 | void show(); 21 | void registerControl(int menuId, Control* control); 22 | protected: 23 | std::string className; 24 | std::string title; 25 | HINSTANCE hInstance = NULL; 26 | int nCmdShow, 27 | x, 28 | y, 29 | width, 30 | height; 31 | 32 | private: 33 | static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMSG, WPARAM wParam, LPARAM lParam); 34 | std::map controls; 35 | 36 | void messageLoop(); 37 | }; 38 | 39 | #endif -------------------------------------------------------------------------------- /include/winservices.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVICESTOPUTILS_H 2 | #define SERVICESTOPUTILS_H 3 | 4 | #include 5 | #include 6 | 7 | #include "Windows.h" 8 | 9 | class ServiceStopper 10 | { 11 | public: 12 | class ServiceStopException : public std::exception 13 | { 14 | public: 15 | ServiceStopException(const char* msg, ...) { 16 | char formatted[512]; 17 | va_list args; 18 | va_start(args, msg); 19 | vsprintf(formatted, msg, args); 20 | va_end(args); 21 | sprintf(message, "Error: %s", formatted); 22 | } 23 | const char* what() const noexcept { return message; } 24 | private: 25 | char message[1024]; 26 | }; 27 | 28 | // TODO: check if linux needs these functions and if so reimplement them 29 | // or alternatively wrap them in ifdef if it doesn't need them 30 | static void StopService_s(std::string serviceName); 31 | static bool StopDependantServices(SC_HANDLE schService, SC_HANDLE schSCManager); 32 | 33 | static bool StartService_s(std::string serviceName); 34 | 35 | static bool KillProcess(std::string procName); 36 | }; 37 | 38 | #endif // SERVICESTOPUTILS_H 39 | -------------------------------------------------------------------------------- /src/win32/controls/control.cpp: -------------------------------------------------------------------------------- 1 | #include "win32\controls\control.h" 2 | 3 | Control::Control() 4 | { 5 | } 6 | 7 | void Control::addEventListener(EventType eventType, EventCallback callback) 8 | { 9 | events[eventType] = callback; 10 | } 11 | 12 | void Control::triggerEvent(EventType eventType) 13 | { 14 | std::map::iterator e; 15 | if ((e = events.find(eventType)) != events.end()) { 16 | e->second(); 17 | } 18 | } 19 | 20 | void Control::setEnabled(bool enabled) 21 | { 22 | //SendMessage(hWnd, WM_ENABLE, enabled ? TRUE : FALSE, 0); 23 | EnableWindow(hWnd, enabled); 24 | } 25 | 26 | bool Control::isEnabled() 27 | { 28 | return IsWindowEnabled(hWnd); 29 | } 30 | 31 | HWND Control::getHwnd() const 32 | { 33 | return hWnd; 34 | } 35 | 36 | void Control::applySystemFont() 37 | { 38 | // Set system font 39 | NONCLIENTMETRICS metrics; 40 | metrics.cbSize = sizeof(metrics); 41 | SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(metrics), &metrics, 0); 42 | HFONT sysFont = CreateFontIndirect(&metrics.lfMessageFont); 43 | SendMessage(hWnd, WM_SETFONT, (WPARAM)sysFont, MAKELPARAM(TRUE, 0)); 44 | } 45 | -------------------------------------------------------------------------------- /modules/FindLibZip.cmake: -------------------------------------------------------------------------------- 1 | FIND_PATH(LIBZIP_INCLUDE_DIR 2 | zip.h 3 | "$ENV{LIB_DIR}/include" 4 | "$ENV{INCLUDE}" 5 | /usr/local/include 6 | /usr/include 7 | ) 8 | 9 | FIND_PATH(LIBZIP_CONF_INCLUDE_DIR 10 | zipconf.h 11 | "$ENV{LIB_DIR}/include" 12 | "$ENV{LIB_DIR}/lib/libzip/include" 13 | "$ENV{LIB}/lib/libzip/include" 14 | /usr/local/lib/libzip/include 15 | /usr/lib/libzip/include 16 | /usr/local/include 17 | /usr/include 18 | "$ENV{INCLUDE}" 19 | ) 20 | 21 | FIND_LIBRARY(LIBZIP_LIBRARY NAMES zip PATHS "$ENV{LIB_DIR}/lib" "$ENV{LIB}" /usr/local/lib /usr/lib ) 22 | 23 | INCLUDE(FindPackageHandleStandardArgs) 24 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibZip DEFAULT_MSG 25 | LIBZIP_LIBRARY LIBZIP_INCLUDE_DIR LIBZIP_CONF_INCLUDE_DIR) 26 | 27 | SET(LIBZIP_INCLUDE_DIRS ${LIBZIP_INCLUDE_DIR} ${LIBZIP_CONF_INCLUDE_DIR}) 28 | MARK_AS_ADVANCED(LIBZIP_LIBRARY LIBZIP_INCLUDE_DIR LIBZIP_CONF_INCLUDE_DIR LIBZIP_INCLUDE_DIRS) 29 | 30 | IF (LIBZIP_FOUND) 31 | MESSAGE(STATUS "Found libzip: ${LIBZIP_LIBRARY}") 32 | ELSE (LIPZIP_FOUND) 33 | MESSAGE(FATAL_ERROR "Could not find libzip") 34 | ENDIF (LIBZIP_FOUND) -------------------------------------------------------------------------------- /include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUGUTILS_H 2 | #define DEBUGUTILS_H 3 | 4 | #include "config.h" 5 | #include 6 | #include 7 | #include "colors.h" 8 | #include "logging/logstrategy.h" 9 | 10 | #ifdef _WIN32 11 | #include 12 | #include "win32/controls/statusbar.h" 13 | #endif 14 | 15 | #define LOGLEVEL_VERBOSE 3 16 | #define LOGLEVEL_DEBUG 2 17 | #define LOGLEVEL_INFO 1 18 | #define LOGLEVEL_NONE 0 19 | 20 | class Logger 21 | { 22 | public: 23 | static void init(LogStrategy* strategy); 24 | static void free(); 25 | 26 | static void verbose(std::string msg); 27 | static void verbose(const char* msg, ...); 28 | 29 | static void debug(std::string msg); 30 | static void debug(const char* msg, ...); 31 | 32 | static void info(std::string msg); 33 | static void info(const char* msg, ...); 34 | 35 | static void error(std::string err); 36 | static void error(const char* err, ...); 37 | 38 | #ifdef _WIN32 39 | static void printWinDebug(const char* fmt, ...); 40 | #endif 41 | private: 42 | Logger(LogStrategy* strategy); 43 | 44 | static Logger* instance; 45 | LogStrategy* logStrategy; 46 | }; 47 | 48 | #endif // DEBUGUTILS_H 49 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX = /usr 2 | 3 | CXX ?= g++ 4 | 5 | src = src/versionparser.cpp \ 6 | src/buildsparser.cpp \ 7 | src/archive.cpp \ 8 | src/network.cpp \ 9 | src/debug.cpp \ 10 | src/installinfo.cpp \ 11 | src/patcher.cpp \ 12 | src/tar.cpp \ 13 | src/main.cpp \ 14 | src/ziparchive.cpp \ 15 | src/toolsdownloader.cpp \ 16 | src/logging/combinedlogstrategy.cpp \ 17 | src/logging/terminallogstrategy.cpp \ 18 | src/logging/streamlogstrategy.cpp \ 19 | src/logging/logstrategy.cpp \ 20 | src/patchversioner.cpp \ 21 | src/unlocker_lnx.cpp 22 | 23 | obj = $(src:.cpp=.o) 24 | 25 | INCLUDE = -Iinclude 26 | CXXFLAGS = -Wall -std=c++17 $(INCLUDE) 27 | 28 | LIBS += -lcurl -lzip -lstdc++fs 29 | 30 | auto-unlocker: $(obj) 31 | $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) 32 | 33 | .PHONY: clean 34 | clean: 35 | rm -f $(obj) auto-unlocker 36 | 37 | depend: $(src) 38 | makedepend -- $(INCLUDE) $^ 39 | 40 | .PHONY: install 41 | install: auto-unlocker 42 | install -D $< $(DESTDIR)$(PREFIX)/bin/auto-unlocker 43 | # mkdir -p $(DESTDIR)$(PREFIX)/bin 44 | # cp $< $(DESTDIR)$(PREFIX)/bin/auto-unlocker 45 | 46 | .PHONY: uninstall 47 | uninstall: auto-unlocker 48 | -rm -f $(DESTDIR)$(PREFIX)/bin/auto-unlocker 49 | -------------------------------------------------------------------------------- /src/versionparser.cpp: -------------------------------------------------------------------------------- 1 | #include "versionparser.h" 2 | 3 | VersionParser::VersionParser(const std::string& versionhtmltext) 4 | : htmltext(versionhtmltext) 5 | { 6 | std::istringstream iss(htmltext); 7 | 8 | std::string line; 9 | while (std::getline(iss, line)) 10 | { 11 | try 12 | { 13 | std::smatch vmatch; 14 | if (std::regex_match(line, vmatch, pattern)) 15 | { 16 | Version v(vmatch.str(1)); 17 | versions.emplace_back(v); 18 | } 19 | } 20 | catch (const Version::VersionException & exc) 21 | { 22 | // Not a good version number 23 | // Could implement debug messages 24 | } 25 | } 26 | 27 | // Sort by latest first 28 | versions.sort(std::greater<>()); 29 | } 30 | 31 | const Version& VersionParser::getLatest() const 32 | { 33 | if (versions.size() == 0) 34 | throw std::runtime_error("No elements in the list"); 35 | 36 | return *versions.cbegin(); 37 | } 38 | 39 | std::list::const_iterator VersionParser::cbegin() const 40 | { 41 | return versions.cbegin(); 42 | } 43 | 44 | std::list::const_iterator VersionParser::cend() const 45 | { 46 | return versions.cend(); 47 | } 48 | 49 | int VersionParser::size() const 50 | { 51 | return versions.size(); 52 | } 53 | -------------------------------------------------------------------------------- /include/win32/task.h: -------------------------------------------------------------------------------- 1 | #ifndef TASK_H 2 | #define TASK_H 3 | 4 | #include 5 | 6 | /** 7 | * @brief An imitation of the Android AsyncTask class 8 | * 9 | * @tparam T The type of the argument passed to the task function 10 | * @tparam E The type of the progress argument 11 | * @tparam V The type of the result argument 12 | */ 13 | template 14 | class Task 15 | { 16 | public: 17 | Task() = default; 18 | 19 | virtual void run(T* arg) final 20 | { 21 | pArg = arg; 22 | tHandle = CreateThread( 23 | NULL, 24 | 0, 25 | &Task::threadFunction, 26 | this, 27 | 0, 28 | &dwThreadId); 29 | } 30 | protected: 31 | virtual V doInBackground(T* arg) = 0; 32 | virtual void onProgressUpdate(E progress) {} 33 | virtual void onPostExecute(V result) {} 34 | 35 | virtual void postProgress(E progress) final 36 | { 37 | onProgressUpdate(progress); 38 | } 39 | 40 | DWORD dwThreadId; 41 | HANDLE tHandle; 42 | 43 | private: 44 | T* pArg; 45 | static DWORD threadFunction(void* tParam) 46 | { 47 | Task* instance = reinterpret_cast(tParam); 48 | V result = instance->doInBackground(instance->pArg); 49 | instance->onPostExecute(result); 50 | 51 | return 0; 52 | } 53 | }; 54 | 55 | #endif -------------------------------------------------------------------------------- /src/archive.cpp: -------------------------------------------------------------------------------- 1 | #include "archive.h" 2 | 3 | bool Archive::extractTar(fs::path from, std::string filename, fs::path to) 4 | { 5 | try 6 | { 7 | Tar tarfile(from.string()); 8 | if (!tarfile.extract(filename, to.string(), Archive::extractionProgress)) { 9 | Logger::error("TAR: Error while extracting %s. Not in the archive", filename.c_str()); 10 | return false; 11 | } 12 | printf("\n"); 13 | return true; 14 | } 15 | catch (const std::exception& exc) 16 | { 17 | Logger::error("TAR: An error occurred while extracting %s. %s", from.string().c_str(), exc.what()); 18 | return false; 19 | } 20 | } 21 | 22 | bool Archive::extractZip(fs::path from, std::string filename, fs::path to) 23 | { 24 | try { 25 | Zip zip(from.string()); 26 | if (!zip.extract(filename, to.string(), Archive::extractionProgress)) { 27 | Logger::error("ZIP: Error while extracting %s. Not in the archive", filename.c_str()); 28 | return false; 29 | } 30 | printf("\n"); 31 | 32 | return true; 33 | } 34 | catch (const std::exception& exc) { 35 | Logger::error("ZIP: An error occurred while extracting %s. %s", from.string().c_str(), exc.what()); 36 | return false; 37 | } 38 | } 39 | 40 | void Archive::extractionProgress(float progress) { 41 | printf("Extraction progress: %.0f %% \r", progress*100); 42 | fflush(stdout); 43 | } -------------------------------------------------------------------------------- /include/win32/patchertask.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCHERTASK_H 2 | #define PATCHERTASK_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "win32/task.h" 10 | #include "win32/patchresult.h" 11 | #include "logging/streamlogstrategy.h" 12 | #include "logging/statusbarlogstrategy.h" 13 | #include "logging/combinedlogstrategy.h" 14 | #include "unlocker_win.h" 15 | 16 | class MainWindow; 17 | 18 | class PatcherTask : public Task 19 | { 20 | public: 21 | PatcherTask(MainWindow& mainWindow); 22 | void setOnCompleteCallback(std::function completeCallback); 23 | void setOnProgressCallback(std::function progressCallback); 24 | protected: 25 | void onProgressUpdate(float progress) override; 26 | PatchResult doInBackground(void* arg) override; 27 | void onPostExecute(PatchResult result) override; 28 | private: 29 | static constexpr int PROG_PERIOD_MS = 200; 30 | 31 | MainWindow& mainWindow; 32 | 33 | std::function onCompleteCallback = nullptr; 34 | std::function onProgressCallback = nullptr; 35 | 36 | std::chrono::milliseconds lastProgressUpdate = std::chrono::duration_cast( 37 | std::chrono::system_clock::now().time_since_epoch() 38 | ); 39 | double lastDlNow = 0.0; 40 | 41 | void downloadProgress(double dltotal, double dlnow, double ultotal, double ulnow); 42 | }; 43 | 44 | #endif -------------------------------------------------------------------------------- /include/win32/downloadtoolstask.h: -------------------------------------------------------------------------------- 1 | #ifndef DOWNLOADTOOLSTASK_H 2 | #define DOWNLOADTOOLSTASK_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "win32/task.h" 10 | #include "win32/patchresult.h" 11 | #include "logging/streamlogstrategy.h" 12 | #include "logging/statusbarlogstrategy.h" 13 | #include "logging/combinedlogstrategy.h" 14 | #include "unlocker_win.h" 15 | 16 | class MainWindow; 17 | 18 | class DownloadToolsTask : public Task 19 | { 20 | public: 21 | DownloadToolsTask(MainWindow& mainWindow); 22 | void setOnCompleteCallback(std::function completeCallback); 23 | void setOnProgressCallback(std::function progressCallback); 24 | protected: 25 | void onProgressUpdate(float progress) override; 26 | PatchResult doInBackground(void* arg) override; 27 | void onPostExecute(PatchResult result) override; 28 | private: 29 | static constexpr int PROG_PERIOD_MS = 200; 30 | 31 | MainWindow& mainWindow; 32 | 33 | std::function onCompleteCallback = nullptr; 34 | std::function onProgressCallback = nullptr; 35 | 36 | void downloadProgress(double dltotal, double dlnow, double ultotal, double ulnow); 37 | 38 | std::chrono::milliseconds lastProgressUpdate = std::chrono::duration_cast( 39 | std::chrono::system_clock::now().time_since_epoch() 40 | ); 41 | double lastDlNow = 0.0; 42 | }; 43 | 44 | #endif -------------------------------------------------------------------------------- /src/patchversioner.cpp: -------------------------------------------------------------------------------- 1 | #include "patchversioner.h" 2 | 3 | PatchVersioner::PatchVersioner(const fs::path& installPath) 4 | { 5 | versionFile = (installPath / PATCH_VER_FILE).string(); 6 | 7 | FILE* vFile = fopen(versionFile.c_str(), "rb"); 8 | 9 | if (vFile != NULL) 10 | { 11 | vData = {}; 12 | 13 | fread(&vData, sizeof(patch_version_t), 1, vFile); 14 | 15 | fclose(vFile); 16 | 17 | haspatch = true; 18 | } 19 | } 20 | 21 | time_t PatchVersioner::getPatchTime() const 22 | { 23 | time_t pTime; 24 | sscanf(vData.timestamp, "%lld", &pTime); 25 | return pTime; 26 | } 27 | 28 | std::string PatchVersioner::getPatchVersion() const 29 | { 30 | return std::string(vData.version); 31 | } 32 | 33 | void PatchVersioner::writePatchData() 34 | { 35 | FILE* vFile = fopen(versionFile.c_str(), "wb"); 36 | 37 | if (vFile == NULL) 38 | { 39 | throw PatchVersionerException("Can't open version file for writing at: " + versionFile); 40 | } 41 | 42 | time_t pTime = time(NULL); 43 | 44 | vData = {}; 45 | sprintf(vData.timestamp, "%lld", pTime); 46 | strcpy(vData.version, PROG_VERSION); 47 | 48 | fwrite(&vData, sizeof(patch_version_t), 1, vFile); 49 | fclose(vFile); 50 | 51 | #ifdef _WIN32 52 | // Set file to hidden on Windows 53 | SetFileAttributes(versionFile.c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); 54 | #endif 55 | } 56 | 57 | void PatchVersioner::removePatchVersion() 58 | { 59 | fs::remove(versionFile); 60 | } 61 | 62 | bool PatchVersioner::hasPatch() const 63 | { 64 | return haspatch; 65 | } 66 | -------------------------------------------------------------------------------- /Unlocker.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /include/network.h: -------------------------------------------------------------------------------- 1 | #ifndef NETUTILS_H 2 | #define NETUTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "debug.h" 14 | 15 | #define CURL_DEBUG false 16 | 17 | class NetworkException : public std::runtime_error 18 | { 19 | public: 20 | NetworkException(const char* message, CURLcode code) : std::runtime_error(message), code(code) {} 21 | NetworkException(const std::string& message, CURLcode code) : std::runtime_error(message), code(code) {} 22 | CURLcode getCode() const { return code; } 23 | private: 24 | CURLcode code; 25 | }; 26 | 27 | struct NetworkProgress { 28 | double mBytesDownloadedLastTime = 0.0; 29 | long long lastProgressUpdateTime = 0; 30 | }; 31 | 32 | class Network 33 | { 34 | public: 35 | Network(); 36 | ~Network(); 37 | void setProgressCallback(std::function progressCallback); 38 | void curlDownload(const std::string& url, const std::string& fileName); 39 | std::string curlGet(const std::string& url); 40 | private: 41 | static constexpr double mBytesProgressUpdateDelta = 0.1; // 0.1 MB 42 | static constexpr long long updatePeriodMs = 200; // update every 100ms 43 | 44 | std::function progressCallback = nullptr; 45 | 46 | NetworkProgress networkProgress = {}; 47 | static size_t write_data_file(char* ptr, size_t size, size_t nmemb, void* stream); 48 | static int progress_callback(void* clientp, double dltotal, double dlnow, double ultotal, double ulnow); 49 | static int progress_callback_external(void* clientp, double dltotal, double dlnow, double ultotal, double ulnow); 50 | }; 51 | 52 | #endif // NETUTILS_H 53 | -------------------------------------------------------------------------------- /tests/test_tar.cpp: -------------------------------------------------------------------------------- 1 | #include "tar.h" 2 | #include "test.h" 3 | 4 | void tar_extraction(); 5 | void testTarSearch(); 6 | 7 | int main(int argc, char** argv) { 8 | test_info("Running TEST: Tar Extraction"); 9 | 10 | tar_extraction(); 11 | //testTarSearch(); 12 | 13 | #ifdef WIN32 14 | system("pause"); 15 | #endif 16 | return 0; 17 | } 18 | 19 | void tar_extraction() { 20 | BEGIN_TEST("Testing TAR Extraction"); 21 | 22 | test_status("CWD is: %s", getCwd().c_str()); 23 | 24 | if(!fileExists("./test.tar")) 25 | { 26 | TEST_ERROR("File test.tar does not exist in current directory"); 27 | } 28 | 29 | try { 30 | Tar testTar("./test.tar"); 31 | 32 | ASSERT_TRUE(testTar.contains("test.file")); 33 | 34 | printf("\n"); 35 | testTar.extract("test.file", "./test.file", updateProgress); 36 | printf("\n"); 37 | 38 | remove("./test.file"); 39 | 40 | TEST_SUCCESS(); 41 | } 42 | catch (const std::exception& exc) { 43 | TEST_ERROR(exc.what()); 44 | } 45 | } 46 | 47 | void testTarSearch() 48 | { 49 | try { 50 | Tar testTar("./test.tar"); 51 | 52 | BEGIN_TEST("Testing Tar Search: test.file"); 53 | auto res = testTar.search("test.file"); 54 | 55 | bool found = false; 56 | for (const Tar::File& f : res) { 57 | if (f.name == "test.file") { 58 | found = true; 59 | break; 60 | } 61 | } 62 | ASSERT_TRUE(res.size() == 1); 63 | ASSERT_TRUE(found); 64 | TEST_SUCCESS(); 65 | 66 | BEGIN_TEST("Testing Tar Search: fff"); 67 | auto res2 = testTar.search("fff"); 68 | found = false; 69 | for (const Tar::File& f : res2) { 70 | if (f.name == "test/fff.txt") { 71 | found = true; 72 | break; 73 | } 74 | } 75 | ASSERT_TRUE(res2.size() == 1); 76 | ASSERT_TRUE(found); 77 | 78 | TEST_SUCCESS(); 79 | } 80 | catch (const std::exception& exc) { 81 | TEST_ERROR(exc.what()); 82 | } 83 | } -------------------------------------------------------------------------------- /src/ziparchive.cpp: -------------------------------------------------------------------------------- 1 | #include "ziparchive.h" 2 | 3 | Zip::Zip(const std::string& zipFile) 4 | { 5 | // Open the zip file 6 | const char* from_c = zipFile.c_str(); 7 | int zerr = ZIP_ER_OK; 8 | zip_archive = zip_open(from_c, ZIP_RDONLY, &zerr); 9 | 10 | if (zerr != ZIP_ER_OK) { 11 | throw ZipException("Error while opening " + zipFile); 12 | } 13 | } 14 | 15 | Zip::~Zip() 16 | { 17 | if (zip_archive != nullptr) { 18 | zip_close(zip_archive); 19 | zip_archive = nullptr; 20 | } 21 | } 22 | 23 | bool Zip::extract(const std::string& fileName, const std::string& to, void(*progressCallback)(float)) 24 | { 25 | const char* fileName_c = fileName.c_str(), * to_c = to.c_str(); 26 | 27 | // Get the size of the file to extract 28 | zip_stat_t target_file_stat; 29 | zip_stat_init(&target_file_stat); 30 | int res = zip_stat(zip_archive, fileName_c, 0, &target_file_stat); 31 | 32 | if (res != 0) 33 | { 34 | return false; 35 | } 36 | 37 | size_t target_fsize = target_file_stat.size; 38 | 39 | // Open the file to extract 40 | zip_file_t* target_file = zip_fopen(zip_archive, fileName_c, 0); 41 | 42 | if (target_file == NULL) { 43 | return false; 44 | } 45 | 46 | // Open the output file 47 | FILE* out_f = fopen(to_c, "wb"); 48 | 49 | if (out_f == NULL) { 50 | throw ZipException("Can't open the file " + to + " for writing"); 51 | } 52 | 53 | size_t elapsed = 0; 54 | 55 | // Extract the file, printing the progress through the function 56 | std::array buffer; 57 | size_t sz = 0; 58 | while ((sz = zip_fread(target_file, buffer.data(), AR_BUFFER_SIZE)) > 0) { 59 | fwrite(buffer.data(), sizeof(char), sz, out_f); 60 | elapsed += sz; 61 | if (progressCallback != nullptr) { 62 | progressCallback(static_cast(elapsed) / target_fsize); 63 | } 64 | } 65 | 66 | fclose(out_f); 67 | 68 | zip_fclose(target_file); 69 | 70 | return true; 71 | } 72 | -------------------------------------------------------------------------------- /src/installinfo.cpp: -------------------------------------------------------------------------------- 1 | #include "installinfo.h" 2 | 3 | #ifdef _WIN32 4 | #include "Windows.h" 5 | #endif 6 | 7 | VMWareInfoRetriever::VMWareInfoRetriever() 8 | { 9 | #ifdef _WIN32 10 | char regBuf[MAX_PATH]; 11 | memset(regBuf, 0, MAX_PATH); 12 | 13 | DWORD regSize = MAX_PATH; 14 | DWORD regType = 0; 15 | 16 | HKEY hResult; 17 | LONG res = RegOpenKeyEx(HKEY_VMWARE, HKEY_SUBKEY_VMWARE, 0, KEY_QUERY_VALUE, &hResult); 18 | 19 | if (res != ERROR_SUCCESS) 20 | { 21 | throw VMWareInfoException("Couldn't open VMWare registry key. Make sure VMWare is correctly installed"); 22 | } 23 | 24 | res = RegQueryValueEx(hResult, HKEY_QUERY_VALUE_INSTALLPATH, NULL, ®Type, (LPBYTE)regBuf, ®Size); 25 | 26 | if (res != ERROR_SUCCESS) 27 | { 28 | RegCloseKey(hResult); 29 | throw VMWareInfoException("Couldn't read VMWare InstallPath registry value. Make sure VMWare is correctly installed"); 30 | } 31 | 32 | installPath = std::string(reinterpret_cast(regBuf)); 33 | 34 | memset(regBuf, 0, MAX_PATH); 35 | regSize = MAX_PATH; 36 | res = RegQueryValueEx(hResult, HKEY_QUERY_VALUE_INSTALLPATH64, NULL, ®Type, (LPBYTE)regBuf, ®Size); 37 | 38 | if (res != ERROR_SUCCESS) 39 | { 40 | RegCloseKey(hResult); 41 | throw VMWareInfoException("Couldn't read VMWare InstallPath64 registry value. Make sure VMWare is correctly installed"); 42 | } 43 | 44 | installPath64 = std::string(regBuf); 45 | 46 | memset(regBuf, 0, MAX_PATH); 47 | regSize = MAX_PATH; 48 | res = RegQueryValueEx(hResult, HKEY_QUERY_VALUE_PRODUCTVERSION, NULL, ®Type, (LPBYTE)regBuf, ®Size); 49 | 50 | if (res != ERROR_SUCCESS) 51 | { 52 | RegCloseKey(hResult); 53 | throw VMWareInfoException("Couldn't read VMWare ProductVersion registry value. Make sure VMWare is correctly installed"); 54 | } 55 | 56 | prodVersion = std::string(regBuf); 57 | 58 | RegCloseKey(hResult); 59 | #endif 60 | } 61 | 62 | std::string VMWareInfoRetriever::getInstallPath() 63 | { 64 | return installPath; 65 | } 66 | 67 | std::string VMWareInfoRetriever::getInstallPath64() 68 | { 69 | return installPath64; 70 | } 71 | 72 | std::string VMWareInfoRetriever::getProductVersion() 73 | { 74 | return prodVersion; 75 | } 76 | -------------------------------------------------------------------------------- /tests/test.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_H 2 | #define TEST_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "colors.h" 9 | 10 | #include 11 | #ifdef WIN32 12 | #include 13 | #elif defined(__linux__) 14 | #include 15 | #include 16 | #endif 17 | 18 | void test_info(const char* message, ...) { 19 | va_list argp; 20 | va_start(argp, message); 21 | char msg[512] = ANSI_COLOR_BLUE; 22 | strcat(msg, message); 23 | strcat(msg, ANSI_COLOR_RESET "\n"); 24 | vprintf(msg, argp); 25 | va_end(argp); 26 | } 27 | 28 | void test_status(const char* message, ...) { 29 | va_list argp; 30 | va_start(argp, message); 31 | char msg[512] = ANSI_COLOR_YELLOW; 32 | strcat(msg, message); 33 | strcat(msg, ANSI_COLOR_RESET "\n"); 34 | vprintf(msg, argp); 35 | va_end(argp); 36 | } 37 | 38 | void test_error(const char* message, ...) { 39 | va_list argp; 40 | va_start(argp, message); 41 | char msg[512] = ANSI_COLOR_RED; 42 | strcat(msg, message); 43 | strcat(msg, ANSI_COLOR_RESET "\n"); 44 | vprintf(msg, argp); 45 | va_end(argp); 46 | } 47 | 48 | void test_success(const char* message, ...) { 49 | va_list argp; 50 | va_start(argp, message); 51 | char msg[512] = ANSI_COLOR_GREEN; 52 | strcat(msg, message); 53 | strcat(msg, ANSI_COLOR_RESET "\n"); 54 | vprintf(msg, argp); 55 | va_end(argp); 56 | } 57 | 58 | void updateProgress(float progress) 59 | { 60 | printf("Status: %.0f %% \r", progress * 100); 61 | } 62 | 63 | bool fileExists(const std::string& file) 64 | { 65 | #ifdef WIN32 66 | DWORD dwAttrib = GetFileAttributesA(file.c_str()); 67 | return dwAttrib != INVALID_FILE_ATTRIBUTES; 68 | #elif defined(__linux__) 69 | return access("./test.tar", F_OK) == 0; 70 | #endif 71 | } 72 | 73 | std::string getCwd() 74 | { 75 | char cwd[1024] = {}; 76 | #ifdef WIN32 77 | GetCurrentDirectoryA(1024, cwd); 78 | #elif defined(__linux__) 79 | getcwd(cwd, 1024); 80 | #endif 81 | return std::string(cwd); 82 | } 83 | 84 | #define TEST_ERROR(reason) test_error("Test failed: %s", reason); exit(1) 85 | #define TEST_SUCCESS() test_success("Test succeeded") 86 | 87 | #define BEGIN_TEST(what) test_status("Testing: %s", what) 88 | #define ASSERT_TRUE(condition) if(!(condition)) { test_error("Test failed at condition: %s", #condition); exit(1); } 89 | 90 | #endif // TEST_H -------------------------------------------------------------------------------- /src/debug.cpp: -------------------------------------------------------------------------------- 1 | #include "debug.h" 2 | 3 | Logger* Logger::instance = nullptr; 4 | 5 | void Logger::init(LogStrategy* strategy) 6 | { 7 | Logger::instance = new Logger(strategy); 8 | } 9 | 10 | void Logger::free() 11 | { 12 | delete Logger::instance; 13 | } 14 | 15 | void Logger::verbose(std::string msg) 16 | { 17 | #if LOGLEVEL >= LOGLEVEL_VERBOSE 18 | Logger::instance->logStrategy->verbose(msg.c_str()); 19 | #endif 20 | } 21 | void Logger::verbose(const char* msg, ...) 22 | { 23 | #if LOGLEVEL >= LOGLEVEL_VERBOSE 24 | va_list args; 25 | va_start(args, msg); 26 | char fmt[1024]; 27 | vsprintf(fmt, msg, args); 28 | 29 | Logger::instance->logStrategy->verbose(fmt); 30 | 31 | va_end(args); 32 | #endif 33 | } 34 | 35 | void Logger::debug(std::string msg) 36 | { 37 | #if LOGLEVEL > LOGLEVEL_DEBUG 38 | Logger::instance->logStrategy->debug(msg.c_str()); 39 | #endif 40 | } 41 | void Logger::debug(const char* msg, ...) 42 | { 43 | #if LOGLEVEL > LOGLEVEL_DEBUG 44 | va_list args; 45 | va_start(args, msg); 46 | char fmt[1024]; 47 | vsprintf(fmt, msg, args); 48 | 49 | Logger::instance->logStrategy->debug(fmt); 50 | 51 | va_end(args); 52 | #endif 53 | } 54 | 55 | void Logger::info(std::string msg) 56 | { 57 | #if LOGLEVEL >= LOGLEVEL_INFO 58 | Logger::instance->logStrategy->info(msg.c_str()); 59 | #endif 60 | } 61 | void Logger::info(const char* msg, ...) 62 | { 63 | #if LOGLEVEL >= LOGLEVEL_INFO 64 | va_list args; 65 | va_start(args, msg); 66 | char fmt[1024]; 67 | vsprintf(fmt, msg, args); 68 | 69 | Logger::instance->logStrategy->info(fmt); 70 | 71 | va_end(args); 72 | #endif 73 | } 74 | 75 | void Logger::error(std::string err) 76 | { 77 | Logger::instance->logStrategy->error(err.c_str()); 78 | } 79 | void Logger::error(const char* msg, ...) 80 | { 81 | va_list args; 82 | va_start(args, msg); 83 | char fmt[1024]; 84 | vsprintf(fmt, msg, args); 85 | 86 | Logger::instance->logStrategy->error(fmt); 87 | 88 | va_end(args); 89 | } 90 | 91 | #ifdef _WIN32 92 | void Logger::printWinDebug(const char* fmt, ...) 93 | { 94 | char message[2048]; 95 | va_list args; 96 | va_start(args, fmt); 97 | vsprintf(message, fmt, args); 98 | va_end(args); 99 | 100 | OutputDebugStringA(message); 101 | } 102 | #endif 103 | 104 | Logger::Logger(LogStrategy* strategy) 105 | : logStrategy(strategy) 106 | { 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/win32/controls/window.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\win32\controls\window.h" 2 | 3 | Window::Window(HINSTANCE hInstance, int nCmdShow, const std::string& className, const std::string& title, int x, int y, int width, int height) 4 | : hInstance(hInstance), nCmdShow(nCmdShow), className(className), x(x), y(y), width(width), height(height), title(title) 5 | { 6 | hWnd = NULL; 7 | parentHwnd = NULL; 8 | } 9 | 10 | Window::~Window() 11 | { 12 | } 13 | 14 | LRESULT Window::WindowProc(HWND hWnd, UINT uMSG, WPARAM wParam, LPARAM lParam) 15 | { 16 | Window* window = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); 17 | 18 | switch (uMSG) 19 | { 20 | case WM_NCCREATE: 21 | SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT*)lParam)->lpCreateParams); 22 | break; 23 | 24 | case WM_DESTROY: 25 | PostQuitMessage(0); 26 | break; 27 | 28 | case WM_CREATE: 29 | window->onCreate(hWnd); 30 | break; 31 | 32 | /*case WM_PAINT: 33 | { 34 | PAINTSTRUCT ps; 35 | HDC hdc = BeginPaint(hWnd, &ps); 36 | 37 | FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_BTNFACE + 1)); 38 | EndPaint(hWnd, &ps); 39 | break; 40 | }*/ 41 | case WM_COMMAND: 42 | switch (HIWORD(wParam)) { 43 | case BN_CLICKED: 44 | Logger::printWinDebug("Button click ID: %d\n", LOWORD(wParam)); 45 | for (const auto& val : window->controls) 46 | { 47 | if (val.first == LOWORD(wParam) && val.second != nullptr) { 48 | val.second->triggerEvent(EventType::CLICK_EVENT); 49 | break; 50 | } 51 | } 52 | break; 53 | } 54 | break; 55 | } 56 | 57 | return DefWindowProc(hWnd, uMSG, wParam, lParam); 58 | } 59 | 60 | void Window::show() 61 | { 62 | WNDCLASS wc = {}; 63 | 64 | wc.lpfnWndProc = Window::WindowProc; 65 | wc.hInstance = hInstance; 66 | wc.lpszClassName = className.c_str(); 67 | wc.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); 68 | wc.hCursor = LoadCursor(0, IDC_ARROW); 69 | 70 | RegisterClass(&wc); 71 | 72 | hWnd = CreateWindowEx( 73 | 0, 74 | className.c_str(), 75 | this->title.c_str(), 76 | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, 77 | x, y, width, height, 78 | NULL, 79 | NULL, 80 | hInstance, 81 | this 82 | ); 83 | 84 | if (hWnd == NULL) 85 | { 86 | throw std::runtime_error("Couldn't initialize main window"); 87 | } 88 | 89 | ShowWindow(hWnd, nCmdShow); 90 | 91 | messageLoop(); 92 | } 93 | 94 | void Window::registerControl(int menuId, Control* control) 95 | { 96 | controls[menuId] = control; 97 | } 98 | 99 | void Window::messageLoop() 100 | { 101 | MSG msg = {}; 102 | while (GetMessage(&msg, NULL, 0, 0)) 103 | { 104 | TranslateMessage(&msg); 105 | DispatchMessage(&msg); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /include/filesystem.hpp: -------------------------------------------------------------------------------- 1 | // We haven't checked which filesystem to include yet 2 | #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 3 | 4 | // Check for feature test macro for 5 | # if defined(__cpp_lib_filesystem) 6 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 7 | 8 | // Check for feature test macro for 9 | # elif defined(__cpp_lib_experimental_filesystem) 10 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 11 | 12 | // We can't check if headers exist... 13 | // Let's assume experimental to be safe 14 | # elif !defined(__has_include) 15 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 16 | 17 | // Check if the header "" exists 18 | # elif __has_include() 19 | 20 | // If we're compiling on Visual Studio and are not compiling with C++17, we need to use experimental 21 | # ifdef _MSC_VER 22 | 23 | // Check and include header that defines "_HAS_CXX17" 24 | # if __has_include() 25 | # include 26 | 27 | // Check for enabled C++17 support 28 | # if defined(_HAS_CXX17) && _HAS_CXX17 29 | // We're using C++17, so let's use the normal version 30 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 31 | # endif 32 | # endif 33 | 34 | // If the marco isn't defined yet, that means any of the other VS specific checks failed, so we need to use experimental 35 | # ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 36 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 37 | # endif 38 | 39 | // Not on Visual Studio. Let's use the normal version 40 | # else // #ifdef _MSC_VER 41 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 42 | # endif 43 | 44 | // Check if the header "" exists 45 | # elif __has_include() 46 | # define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 47 | 48 | // Fail if neither header is available with a nice error message 49 | # else 50 | # error Could not find system header "" or "" 51 | # endif 52 | 53 | // We priously determined that we need the exprimental version 54 | # if INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 55 | // Include it 56 | # include 57 | 58 | // We need the alias from std::experimental::filesystem to std::filesystem 59 | //namespace std { 60 | // namespace filesystem = experimental::filesystem; 61 | //} 62 | 63 | namespace fs = std::experimental::filesystem; 64 | 65 | // We have a decent compiler and can use the normal version 66 | # else 67 | // Include it 68 | # include 69 | namespace fs = std::filesystem; 70 | 71 | # endif 72 | 73 | #endif // #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 74 | -------------------------------------------------------------------------------- /include/win32/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "filesystem.hpp" 11 | 12 | #include "config.h" 13 | #include "controls/button.h"; 14 | #include "controls/editbox.h" 15 | #include "controls/label.h" 16 | #include "controls/window.h" 17 | #include "controls/progress.h" 18 | #include "controls/groupbox.h" 19 | #include "controls/checkbox.h" 20 | #include "controls/statusbar.h" 21 | #include "patchertask.h" 22 | #include "unpatchertask.h" 23 | #include "downloadtoolstask.h" 24 | #include "resources.h" 25 | 26 | #include "installinfo.h" 27 | #include "unlocker_win.h" 28 | 29 | struct DialogState 30 | { 31 | bool pathEnabled, 32 | path64Enabled, 33 | pathBrowseEnabled, 34 | path64BrowseEnabled, 35 | downloadToolsEnabled, 36 | downloadToolsChecked, 37 | toolsPathEnabled, 38 | toolsBrowseEnabled, 39 | downloadToolsBtnEnabled, 40 | patchEnabled, 41 | unpatchEnabled; 42 | }; 43 | 44 | class MainWindow : public Window 45 | { 46 | public: 47 | MainWindow(HINSTANCE hInstance, int nCmdShow); 48 | ~MainWindow(); 49 | virtual void onCreate(HWND hWnd) override; 50 | 51 | std::unique_ptr