diff --git a/src/infra/infra.cpp b/src/infra/infra.cpp index 42e2a0c..739ef65 100644 --- a/src/infra/infra.cpp +++ b/src/infra/infra.cpp @@ -6,57 +6,91 @@ namespace Infra { -HMODULE g_mod_infra_dll; -sqlite3_open_v2_t sqlite3_open_v2; -sqlite3_key_t sqlite3_key; -sqlite3_prepare_v2_t sqlite3_prepare_v2; -sqlite3_step_t sqlite3_step; -sqlite3_column_text_t sqlite3_column_text; -sqlite3_close_v2_t sqlite3_close_v2; -sqlite3_finalize_t sqlite3_finalize; +SqliteDB::SqliteDB(const std::filesystem::path& infra_dll_path) { + ok_ = InitInfraDll(infra_dll_path); +} -bool g_init_sqlite_ok = []() { - g_mod_infra_dll = LoadLibraryA("infra.dll"); - if (g_mod_infra_dll == nullptr) { +bool SqliteDB::Open(const std::filesystem::path& db_path, std::string_view key) { + if (infra_ == nullptr) { return false; } - sqlite3_open_v2 = reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_open_v2")); - sqlite3_key = reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_key")); - sqlite3_prepare_v2 = reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_prepare_v2")); - sqlite3_step = reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_step")); - sqlite3_column_text = - reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_column_text")); - sqlite3_close_v2 = reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_close_v2")); - sqlite3_finalize = reinterpret_cast(GetProcAddress(g_mod_infra_dll, "sqlite3_finalize")); - - return sqlite3_open_v2 && sqlite3_key && sqlite3_prepare_v2 && sqlite3_step && sqlite3_column_text && - sqlite3_close_v2 && sqlite3_finalize; -}(); - -SQLite::SQLite(const std::filesystem::path& db_path) { - ok_ = false; - int rc{-1}; - if (!g_init_sqlite_ok) { - return; - } - auto db_path_u8 = db_path.generic_u8string(); - rc = sqlite3_open_v2(reinterpret_cast(db_path_u8.c_str()), &db_, SQLITE_OPEN_READONLY, nullptr); + int rc = sqlite3_open_v2_(reinterpret_cast(db_path_u8.c_str()), &db_, SQLITE_OPEN_READONLY, nullptr); if (rc != SQLITE_OK) { - return; + return false; } - rc = sqlite3_key(db_, "7777B48756BA491BB4CEE771A3E2727E", 0x20); - if (rc != SQLITE_OK) { - return; + if (!key.empty()) { + rc = sqlite3_key_(db_, key.data(), static_cast(key.size())); + if (rc != SQLITE_OK) { + sqlite3_close_v2_(db_); + db_ = nullptr; + return false; + } } - ok_ = true; + return true; } -kgm_ekey_db_t SQLite::dump_ekey(int& error) { - if (ok_ == false) { +void SqliteDB::Close() { + if (db_) { + sqlite3_close_v2_(db_); + db_ = nullptr; + } +} +void SqliteDB::FreeInfraDll() { + if (infra_ != nullptr) { + FreeLibrary(reinterpret_cast(infra_)); + infra_ = nullptr; + } + + sqlite3_open_v2_ = nullptr; + sqlite3_key_ = nullptr; + sqlite3_prepare_v2_ = nullptr; + sqlite3_step_ = nullptr; + sqlite3_column_text_ = nullptr; + sqlite3_close_v2_ = nullptr; + sqlite3_finalize_ = nullptr; +} + +bool SqliteDB::InitInfraDll(const std::filesystem::path& infra_dll_path) { + auto path_unicode = infra_dll_path.wstring(); + HMODULE hMod = LoadLibraryW(path_unicode.c_str()); + infra_ = hMod; + if (hMod == nullptr) { + return false; + } + + sqlite3_open_v2_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_open_v2")); + sqlite3_key_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_key")); + sqlite3_prepare_v2_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_prepare_v2")); + sqlite3_step_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_step")); + sqlite3_column_text_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_column_text")); + sqlite3_close_v2_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_close_v2")); + sqlite3_finalize_ = reinterpret_cast(GetProcAddress(hMod, "sqlite3_finalize")); + + if (!sqlite3_open_v2_ || !sqlite3_key_ || !sqlite3_prepare_v2_ || !sqlite3_step_ || !sqlite3_column_text_ || + !sqlite3_close_v2_ || !sqlite3_finalize_) { + infra_ = nullptr; + return false; + } + + return true; +} + +KugouDb::KugouDb(const std::filesystem::path& infra_dll_path, const std::filesystem::path& db_path) + : SqliteDB(infra_dll_path) { + int rc{-1}; + if (!IsInfraOk()) { + return; + } + + Open(db_path); +} + +kgm_ekey_db_t KugouDb::dump_ekey(int& error) { + if (!IsOpen()) { error = SQLITE_ERROR; return {}; } @@ -64,19 +98,19 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) { int rc{-1}; sqlite3_stmt* stmt{nullptr}; - rc = sqlite3_prepare_v2(db_, - "select EncryptionKeyId, EncryptionKey from ShareFileItems" - " where EncryptionKey != ''", - -1, &stmt, nullptr); + rc = sqlite3_prepare_v2_(db_, + "select EncryptionKeyId, EncryptionKey from ShareFileItems" + " where EncryptionKey != ''", + -1, &stmt, nullptr); if (rc != SQLITE_OK) { error = rc; return {}; } kgm_ekey_db_t result{}; - while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { - const auto* ekey_id = reinterpret_cast(sqlite3_column_text(stmt, 0)); - const auto* ekey = reinterpret_cast(sqlite3_column_text(stmt, 1)); + while ((rc = sqlite3_step_(stmt)) == SQLITE_ROW) { + const auto* ekey_id = reinterpret_cast(sqlite3_column_text_(stmt, 0)); + const auto* ekey = reinterpret_cast(sqlite3_column_text_(stmt, 1)); result[ekey_id] = ekey; } @@ -84,16 +118,20 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) { error = rc; } - sqlite3_finalize(stmt); + sqlite3_finalize_(stmt); error = 0; return result; } -SQLite::~SQLite() { +KugouDb::~KugouDb() { if (db_ != nullptr) { - sqlite3_close_v2(db_); + sqlite3_close_v2_(db_); db_ = nullptr; } } +bool KugouDb::Open(const std::filesystem::path& db_path) { + return SqliteDB::Open(db_path, {"7777B48756BA491BB4CEE771A3E2727E"}); +} + } // namespace Infra diff --git a/src/infra/infra.h b/src/infra/infra.h index 41dbece..4f87093 100644 --- a/src/infra/infra.h +++ b/src/infra/infra.h @@ -4,23 +4,46 @@ #include #include "sqlite_base.h" +#include "sqlite_fn.h" namespace Infra { typedef std::unordered_map kgm_ekey_db_t; extern bool g_init_sqlite_ok; -class SQLite { +class SqliteDB { public: - explicit SQLite(const std::filesystem::path& db_path); - ~SQLite(); - - [[nodiscard]] bool is_ok() const { return ok_; } - kgm_ekey_db_t dump_ekey(int& error); + explicit SqliteDB(const std::filesystem::path& infra_dll_path); + bool Open(const std::filesystem::path& db_path, std::string_view key); + void Close(); + [[nodiscard]] bool IsInfraOk() const { return ok_; } + [[nodiscard]] bool IsOpen() const { return db_ != nullptr; } private: - bool ok_ = false; + bool InitInfraDll(const std::filesystem::path& infra_dll_path); + bool ok_{false}; + + protected: + void FreeInfraDll(); + + void* infra_{nullptr}; + sqlite3_open_v2_t sqlite3_open_v2_{nullptr}; + sqlite3_key_t sqlite3_key_{nullptr}; + sqlite3_prepare_v2_t sqlite3_prepare_v2_{nullptr}; + sqlite3_step_t sqlite3_step_{nullptr}; + sqlite3_column_text_t sqlite3_column_text_{nullptr}; + sqlite3_close_v2_t sqlite3_close_v2_{nullptr}; + sqlite3_finalize_t sqlite3_finalize_{nullptr}; sqlite3* db_{nullptr}; }; +class KugouDb : public SqliteDB { + public: + explicit KugouDb(const std::filesystem::path& infra_dll_path, const std::filesystem::path& db_path); + ~KugouDb(); + + bool Open(const std::filesystem::path& db_path); + kgm_ekey_db_t dump_ekey(int& error); +}; + } // namespace Infra diff --git a/src/main.cpp b/src/main.cpp index fb97864..ee8eef7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,8 +116,8 @@ int main() { kgmPath = kgmPath / L"Kugou8" / L"KGMusicV3.db"; int error{-1}; - Infra::SQLite db{kgmPath}; - if (!db.is_ok()) { + Infra::KugouDb db{L"infra.dll", kgmPath}; + if (!db.IsOpen()) { fprintf(stderr, "[ERR ] db init error: is infra.dll ok?\n"); return 1; } @@ -126,6 +126,7 @@ int main() { fprintf(stderr, "[ERR ] dump ekey failed %d (%s)", error, sqlite_get_error(error)); return 1; } + db.Close(); #ifdef _DEBUG printf("ekey_db:\n");