diff --git a/code/base/base.h b/code/base/base.h index 9a5d733..73d7123 100644 --- a/code/base/base.h +++ b/code/base/base.h @@ -129,4 +129,205 @@ DECL_API(int) func_test_go(const wchar_t* name // test name , ui_helper* helper); // Function: uninitialize module -DECL_API(int) func_test_uninit(void*); \ No newline at end of file +DECL_API(int) func_test_uninit(void*); + + + +////////////////////////////////////////////////////////////////////////////////////////////////// +/*/ testing-DLL load code ... +#include +#include +#include +#include + +class json : public ref +{ +public: + json(); + +protected: + ~json(); + +public: + bool attach(const wchar_t* text); + bool get_value(const wchar_t* key, int& val); + bool get_value(const wchar_t* key, std::wstring& val); + bool get_value(const wchar_t* key, json*& val); +}; + +class test_factory +{ + typedef struct _test_func + { + std::wstring name; + int ver; + int(__stdcall* test_api)(const wchar_t*, const wchar_t*, ui_helper*); + + struct _test_func() + { + name = L""; + ver = 0; + test_api = NULL; + } + bool operator==(const wchar_t* n) + { + return name == n; + } + }TESTFUNC, *LPTESTFUNC; + std::vector test_; + + void add_api(const wchar_t* name, int ver, int(__stdcall* test_api)(const wchar_t*, const wchar_t*, ui_helper*)) + { + std::vector::iterator it = std::find(test_.begin(), test_.end(), name); + + if (it == test_.end()) + { + TESTFUNC tf; + + tf.name = name; + tf.ver = ver; + tf.test_api = test_api; + test_.push_back(tf); + } + else if (ver > it->ver) + { + it->test_api = test_api; + it->ver = ver; + } + } + void load_test_dll(const wchar_t* path_dll) + { + HMODULE mod = LoadLibraryW(path_dll); + int(__stdcall * init)(void*) = NULL; + int(__stdcall * get)(void*, size_t*) = NULL; + int(__stdcall * go)(const wchar_t*, const wchar_t*, ui_helper*) = NULL; + FARPROC* api = (FARPROC*)&init; + wchar_t* buf = NULL; + size_t len = 0; + json* root = NULL, * child = NULL; + + if (!mod) + return; + + *api = GetProcAddress(mod, "func_test_init"); + if (!api) + { + FreeLibrary(mod); + return; + } + init(NULL); + + api = (FARPROC*)&get; + *api = GetProcAddress(mod, "func_test_get_list"); + if(!api) + { + FreeLibrary(mod); + return; + } + + api = (FARPROC*)&go; + *api = GetProcAddress(mod, "func_test_go"); + if (!api) + { + FreeLibrary(mod); + return; + } + + if(get(buf, &len) != ERROR_INSUFFICIENT_BUFFER) + { + FreeLibrary(mod); + return; + } + + buf = new wchar_t[len + 8]; + memset(buf, 0, (len + 8) * 2); + if (get(buf, &len)) + { + delete[] buf; + FreeLibrary(mod); + return; + } + + // parse json ... + len = 0; + root = new json(); + if (root->attach(buf)) + { + for (int i = 1; 1; ++i) + { + swprintf_s(buf, 20, L"%d", i); + if (!root->get_value(buf, child) || !child) + break; + + std::wstring name(L""); + int ver = 0; + if (child->get_value(L"name", name) && child->get_value(L"ver", ver)) + { + add_api(name.c_str(), ver, go); + len++; + } + child->release(); + } + } + + root->release(); + delete[] buf; + if (len == 0) + FreeLibrary(mod); + } + void init(void) + { + wchar_t path[MAX_PATH] = { 0 }; + std::wstring dir(L""); + size_t pos = 0; + HANDLE hf = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAW fd = { 0 }; + + GetModuleFileNameW(NULL, path, _countof(path) - 1); + dir = pos; + pos = dir.rfind(L'\\'); + if (pos++ == std::wstring::npos) + return; + + dir.erase(pos); + dir += L"dlls\\"; + hf = FindFirstFileW((dir + L"*.dll").c_str(), &fd); + if (hf != INVALID_HANDLE_VALUE) + { + do + { + load_test_dll((dir + fd.cFileName).c_str()); + } while (FindNextFileW(hf, &fd)); + + FindClose(hf); + } + } + +public: + test_factory() + { + init(); + } + ~test_factory() + { + + } + +public: + bool is_test_available(const wchar_t* name) // check if the test item with name 'name' is supported + { + std::vector::iterator it = std::find(test_.begin(), test_.end(), name); + + return it != test_.end(); + } + int test(const wchar_t* name, ui_helper* ui, const wchar_t* oper = L"start") + { + std::vector::iterator it = std::find(test_.begin(), test_.end(), name); + + if (it == test_.end()) + return ERROR_NOT_SUPPORTED; + + return it->test_api(name, oper, ui); + } +}; +/////////////////////////*//////////////////////////////////////////////////////////////////////// \ No newline at end of file