You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

uoDynamicModuleTest.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*********************************************************************
  2. * Software License Agreement (AGPL-3 License)
  3. *
  4. * OpenViBE SDK Test Software
  5. * Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
  6. * Copyright (C) Inria, 2015-2017,V1.0
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License version 3,
  10. * as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License
  18. * along with this program.
  19. * If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include "gtest/gtest.h"
  22. #include "system/ovCDynamicModule.h"
  23. #if defined TARGET_OS_Windows
  24. #include <winreg.h>
  25. #endif
  26. #include <algorithm>
  27. namespace {
  28. #if defined TARGET_OS_Windows
  29. //const std::string LIB_PATH = OV_CMAKE_PATH_LIB;
  30. // Microsoft specific
  31. const std::string EXISTING_MODULE_NAME = "NTDLL.dll";
  32. std::string existingModulePath;
  33. #if defined _WIN64
  34. #define CSIDL_SYSTEM_PLATFORM CSIDL_SYSTEM
  35. #else
  36. #define CSIDL_SYSTEM_PLATFORM CSIDL_SYSTEMX86
  37. #endif
  38. std::string existingModulePathName;
  39. const std::string NON_EXISTING_MODULE_NAME = "randomRandomRandom.dll";
  40. const std::string NON_EXISTING_SYMBOL = "nonExistingSymbol";
  41. const std::string EXISTING_ENVIRONMENT_PATH = "PATH";
  42. const std::string EXISTING_REGISTRY_MODULE_NAME = EXISTING_MODULE_NAME;
  43. const std::string SYMBOL_NAME_NTDLL = "toupper";
  44. const HKEY EXISTING_REGISTRY_KEY = HKEY_LOCAL_MACHINE; // 0x80000002
  45. const HKEY NON_EXISTING_REGISTRY_KEY = HKEY(ULONG_PTR(LONG(0x800000FF)));
  46. const std::string EXISTING_REGISTRY_PATH = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer"; // Present on all Windows versions
  47. const std::string NON_EXISTING_REGISTRY_PATH = "SOFTWARE\\Random\\Random\\Random";
  48. int (*toupperSymbol)(int c);
  49. bool (*randomRandomRandomSymbol)(int number);
  50. #elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
  51. static const std::string EXISTING_SYMBOL = "createCSVLib";
  52. static const std::string NON_EXISTING_SYMBOL = "nonExistingSymbol";
  53. static const std::string LIB_PATH = OV_CMAKE_PATH_LIB;
  54. static const std::string EXISTING_MODULE_NAME = "libopenvibe-module-csv.so";
  55. static const std::string existingModulePath = LIB_PATH + "/";
  56. static const std::string existingModulePathName = existingModulePath + EXISTING_MODULE_NAME;
  57. static const std::string NON_EXISTING_MODULE_NAME = "randomRandomRandom.so";
  58. #endif
  59. } // namespace
  60. #if defined TARGET_OS_Windows
  61. TEST(DynamicModule_Test_Case, loadFromExistingSuccessNoSymbolCheck)
  62. {
  63. System::CDynamicModule dynamicModule;
  64. ASSERT_TRUE(dynamicModule.loadFromExisting(EXISTING_MODULE_NAME.c_str()));
  65. ASSERT_TRUE(dynamicModule.isLoaded());
  66. std::string moduleNameExpected = EXISTING_MODULE_NAME;
  67. std::string moduleName = dynamicModule.getFilename();
  68. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  69. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  70. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  71. ASSERT_TRUE(dynamicModule.unload());
  72. }
  73. #endif
  74. #if defined TARGET_OS_Windows
  75. TEST(DynamicModule_Test_Case, loadFromExistingFailNoSymbolCheck)
  76. {
  77. System::CDynamicModule dynamicModule;
  78. ASSERT_FALSE(dynamicModule.loadFromExisting(NON_EXISTING_MODULE_NAME.c_str()));
  79. ASSERT_EQ(System::CDynamicModule::LogErrorCodes_FailToLoadModule, dynamicModule.getLastError());
  80. ASSERT_FALSE(dynamicModule.isLoaded());
  81. }
  82. #endif
  83. TEST(DynamicModule_Test_Case, loadFromPathSuccessNoSymbolCheck)
  84. {
  85. System::CDynamicModule dynamicModule;
  86. ASSERT_TRUE(dynamicModule.loadFromPath(existingModulePathName.c_str()));
  87. ASSERT_TRUE(dynamicModule.isLoaded());
  88. std::string moduleNameExpected = existingModulePathName;
  89. std::string moduleName = dynamicModule.getFilename();
  90. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  91. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  92. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  93. ASSERT_TRUE(dynamicModule.unload());
  94. }
  95. TEST(DynamicModule_Test_Case, loadFromPathFailNoSymbolCheck)
  96. {
  97. System::CDynamicModule dynamicModule;
  98. ASSERT_FALSE(dynamicModule.loadFromPath(NON_EXISTING_MODULE_NAME.c_str()));
  99. ASSERT_EQ(System::CDynamicModule::LogErrorCodes_FailToLoadModule, dynamicModule.getLastError());
  100. ASSERT_FALSE(dynamicModule.isLoaded());
  101. }
  102. #if defined TARGET_OS_Windows // Must be tested on Linux
  103. TEST(DynamicModule_Test_Case, loadFromPathSuccessSymbolCheck)
  104. {
  105. System::CDynamicModule dynamicModule;
  106. ASSERT_TRUE(dynamicModule.loadFromPath(existingModulePathName.c_str(), SYMBOL_NAME_NTDLL.c_str()));
  107. ASSERT_TRUE(dynamicModule.isLoaded());
  108. std::string moduleNameExpected = existingModulePathName;
  109. std::string moduleName = dynamicModule.getFilename();
  110. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  111. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  112. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  113. ASSERT_TRUE(dynamicModule.unload());
  114. }
  115. #endif
  116. TEST(DynamicModule_Test_Case, loadFromPathSymbolCheckFail)
  117. {
  118. System::CDynamicModule dynamicModule;
  119. ASSERT_FALSE(dynamicModule.loadFromPath(existingModulePathName.c_str(), NON_EXISTING_SYMBOL.c_str()));
  120. ASSERT_EQ(System::CDynamicModule::LogErrorCodes_InvalidSymbol, dynamicModule.getLastError());
  121. ASSERT_FALSE(dynamicModule.isLoaded());
  122. }
  123. #if defined TARGET_OS_Windows
  124. TEST(DynamicModule_Test_Case, loadFromKnownPathSuccessNoSymbolCheck)
  125. {
  126. System::CDynamicModule dynamicModule;
  127. ASSERT_TRUE(dynamicModule.loadFromKnownPath(CSIDL_SYSTEM_PLATFORM, EXISTING_MODULE_NAME.c_str()));
  128. ASSERT_TRUE(dynamicModule.isLoaded());
  129. std::string moduleNameExpected = existingModulePathName;
  130. std::string moduleName = dynamicModule.getFilename();
  131. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  132. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  133. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  134. ASSERT_TRUE(System::CDynamicModuleSymbolLoader::getSymbol<>(dynamicModule, SYMBOL_NAME_NTDLL.c_str(), &toupperSymbol));
  135. ASSERT_TRUE(dynamicModule.unload());
  136. }
  137. TEST(DynamicModule_Test_Case, loadFromKnownPathFailNoSymbolCheck)
  138. {
  139. System::CDynamicModule dynamicModule;
  140. ASSERT_FALSE(dynamicModule.loadFromKnownPath(CSIDL_SYSTEM_PLATFORM, NON_EXISTING_MODULE_NAME.c_str()));
  141. ASSERT_EQ(System::CDynamicModule::LogErrorCodes_FailToLoadModule, dynamicModule.getLastError());
  142. ASSERT_FALSE(dynamicModule.isLoaded());
  143. }
  144. #endif
  145. #if defined TARGET_OS_Windows
  146. TEST(DynamicModule_Test_Case, loadFromEnvironmentSuccessNoSymbolCheck)
  147. {
  148. System::CDynamicModule dynamicModule;
  149. ASSERT_TRUE(dynamicModule.loadFromEnvironment(EXISTING_ENVIRONMENT_PATH.c_str(), EXISTING_MODULE_NAME.c_str()));
  150. ASSERT_TRUE(dynamicModule.isLoaded());
  151. std::string moduleNameExpected = "C:\\WINDOWS\\system32\\ntdll.dll";
  152. std::string moduleName = dynamicModule.getFilename();
  153. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  154. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  155. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  156. ASSERT_TRUE(System::CDynamicModuleSymbolLoader::getSymbol<>(dynamicModule, SYMBOL_NAME_NTDLL.c_str(), &toupperSymbol));
  157. ASSERT_TRUE(dynamicModule.unload());
  158. }
  159. TEST(DynamicModule_Test_Case, loadFromEnvironmentFailNoSymbolCheck)
  160. {
  161. System::CDynamicModule dynamicModule;
  162. ASSERT_FALSE(dynamicModule.loadFromEnvironment(EXISTING_ENVIRONMENT_PATH.c_str(), NON_EXISTING_MODULE_NAME.c_str()));
  163. ASSERT_EQ(System::CDynamicModule::LogErrorCodes_ModuleNotFound, dynamicModule.getLastError());
  164. ASSERT_FALSE(dynamicModule.isLoaded());
  165. }
  166. #endif
  167. #if defined TARGET_OS_Windows
  168. TEST(DynamicModule_Test_Case, loadFromRegistrySuccessNoSymbolCheck)
  169. {
  170. System::CDynamicModule dynamicModule;
  171. ASSERT_TRUE(
  172. dynamicModule.loadFromRegistry(EXISTING_REGISTRY_KEY, EXISTING_REGISTRY_PATH.c_str(), nullptr, KEY_READ | KEY_WOW64_64KEY, EXISTING_REGISTRY_MODULE_NAME
  173. .c_str()));
  174. ASSERT_TRUE(dynamicModule.isLoaded());
  175. std::string moduleNameExpected = EXISTING_MODULE_NAME;
  176. std::string moduleName = dynamicModule.getFilename();
  177. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  178. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  179. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  180. ASSERT_TRUE(System::CDynamicModuleSymbolLoader::getSymbol<>(dynamicModule, SYMBOL_NAME_NTDLL.c_str(), &toupperSymbol));
  181. ASSERT_TRUE(dynamicModule.unload());
  182. }
  183. TEST(DynamicModule_Test_Case, loadFromRegistrySuccessSymbolCheck)
  184. {
  185. System::CDynamicModule dynamicModule;
  186. ASSERT_TRUE(
  187. dynamicModule.loadFromRegistry(EXISTING_REGISTRY_KEY, EXISTING_REGISTRY_PATH.c_str(), nullptr, KEY_READ | KEY_WOW64_64KEY, EXISTING_REGISTRY_MODULE_NAME
  188. .c_str(), SYMBOL_NAME_NTDLL.c_str()));
  189. ASSERT_TRUE(dynamicModule.isLoaded());
  190. std::string moduleNameExpected = EXISTING_MODULE_NAME;
  191. std::string moduleName = dynamicModule.getFilename();
  192. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  193. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  194. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  195. ASSERT_TRUE(System::CDynamicModuleSymbolLoader::getSymbol<>(dynamicModule, SYMBOL_NAME_NTDLL.c_str(), &toupperSymbol));
  196. ASSERT_TRUE(dynamicModule.unload());
  197. }
  198. TEST(DynamicModule_Test_Case, loadFromRegistryFailNoSymbolCheck)
  199. {
  200. System::CDynamicModule dynamicModule;
  201. ASSERT_FALSE(
  202. dynamicModule.loadFromRegistry(NON_EXISTING_REGISTRY_KEY, EXISTING_REGISTRY_PATH.c_str(), nullptr, KEY_READ | KEY_WOW64_32KEY,
  203. EXISTING_REGISTRY_MODULE_NAME.c_str()));
  204. ASSERT_FALSE(dynamicModule.isLoaded());
  205. ASSERT_FALSE(
  206. dynamicModule.loadFromRegistry(EXISTING_REGISTRY_KEY, NON_EXISTING_REGISTRY_PATH.c_str(), nullptr, KEY_READ | KEY_WOW64_32KEY,
  207. EXISTING_REGISTRY_MODULE_NAME.c_str()));
  208. ASSERT_FALSE(dynamicModule.isLoaded());
  209. ASSERT_FALSE(
  210. dynamicModule.loadFromRegistry(NON_EXISTING_REGISTRY_KEY, EXISTING_REGISTRY_PATH.c_str(), nullptr, KEY_READ | KEY_WOW64_32KEY,
  211. EXISTING_REGISTRY_MODULE_NAME.c_str()));
  212. ASSERT_FALSE(dynamicModule.isLoaded());
  213. }
  214. #endif
  215. #if defined TARGET_OS_Windows // Must be tested on Linux
  216. TEST(DynamicModule_Test_Case, getSymbolSuccess)
  217. {
  218. System::CDynamicModule dynamicModule;
  219. ASSERT_TRUE(dynamicModule.loadFromPath(existingModulePathName.c_str()));
  220. ASSERT_TRUE(dynamicModule.isLoaded());
  221. std::string moduleNameExpected = existingModulePathName;
  222. std::string moduleName = dynamicModule.getFilename();
  223. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  224. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  225. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  226. ASSERT_TRUE(System::CDynamicModuleSymbolLoader::getSymbol<>(dynamicModule, SYMBOL_NAME_NTDLL.c_str(), &toupperSymbol));
  227. const char lowerCase = 'r';
  228. char upperCase = char(toupperSymbol(lowerCase));
  229. ASSERT_EQ(upperCase, 'R');
  230. ASSERT_TRUE(dynamicModule.unload());
  231. }
  232. TEST(DynamicModule_Test_Case, getSymbolFail)
  233. {
  234. System::CDynamicModule dynamicModule;
  235. ASSERT_TRUE(dynamicModule.loadFromPath(existingModulePathName.c_str()));
  236. ASSERT_TRUE(dynamicModule.isLoaded());
  237. std::string moduleNameExpected = existingModulePathName;
  238. std::string moduleName = dynamicModule.getFilename();
  239. std::transform(moduleNameExpected.begin(), moduleNameExpected.end(), moduleNameExpected.begin(), tolower);
  240. std::transform(moduleName.begin(), moduleName.end(), moduleName.begin(), tolower);
  241. ASSERT_STREQ(moduleNameExpected.c_str(), moduleName.c_str());
  242. ASSERT_FALSE(System::CDynamicModuleSymbolLoader::getSymbol<>(dynamicModule, NON_EXISTING_SYMBOL.c_str(), &randomRandomRandomSymbol));
  243. }
  244. #endif
  245. #if defined TARGET_OS_Windows
  246. TEST(DynamicModule_Test_Case, isModulecompatibleSuccess)
  247. {
  248. #if defined _WIN64
  249. ASSERT_FALSE(System::CDynamicModule::isModuleCompatible(existingModulePathName.c_str(), 0x014c)); // x86
  250. ASSERT_TRUE(System::CDynamicModule::isModuleCompatible(existingModulePathName.c_str(), 0x8664)); // x64
  251. ASSERT_FALSE(System::CDynamicModule::isModuleCompatible(existingModulePathName.c_str(), 0x0200)); // ia64
  252. #else
  253. ASSERT_TRUE(System::CDynamicModule::isModuleCompatible(existingModulePathName.c_str(), 0x014c)); // x86
  254. ASSERT_FALSE(System::CDynamicModule::isModuleCompatible(existingModulePathName.c_str(), 0x8664)); // x64
  255. ASSERT_FALSE(System::CDynamicModule::isModuleCompatible(existingModulePathName.c_str(), 0x0200)); // ia64
  256. #endif
  257. }
  258. #endif
  259. #if defined TARGET_OS_Windows
  260. TEST(DynamicModule_Test_Case, isModulecompatibleFail)
  261. {
  262. System::CDynamicModule dynamicModule;
  263. ASSERT_FALSE(dynamicModule.loadFromPath(NON_EXISTING_MODULE_NAME.c_str()));
  264. ASSERT_FALSE(dynamicModule.isLoaded());
  265. }
  266. #endif
  267. TEST(DynamicModule_Test_Case, unloadSuccess)
  268. {
  269. System::CDynamicModule dynamicModule;
  270. ASSERT_TRUE(dynamicModule.loadFromPath(existingModulePathName.c_str()));
  271. ASSERT_TRUE(dynamicModule.unload());
  272. }
  273. TEST(DynamicModule_Test_Case, unloadFail)
  274. {
  275. System::CDynamicModule dynamicModule;
  276. ASSERT_FALSE(dynamicModule.loadFromPath(NON_EXISTING_MODULE_NAME.c_str()));
  277. ASSERT_FALSE(dynamicModule.isLoaded());
  278. ASSERT_FALSE(dynamicModule.unload());
  279. }
  280. int uoDynamicModuleTest(int argc, char* argv[])
  281. {
  282. testing::InitGoogleTest(&argc, argv);
  283. #if defined TARGET_OS_Windows
  284. BOOL bIsWow64 = FALSE;
  285. if (!IsWow64Process(GetCurrentProcess(), &bIsWow64)) { return false; }
  286. existingModulePath = bIsWow64 ? "C:\\WINDOWS\\SysWOW64\\" : "C:\\WINDOWS\\system32\\";
  287. existingModulePathName = existingModulePath + EXISTING_MODULE_NAME;
  288. #endif
  289. return RUN_ALL_TESTS();
  290. }