mfx_library_iterator.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. // Copyright (c) 2012-2020 Intel Corporation
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in all
  11. // copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. // SOFTWARE.
  20. #include "mfx_library_iterator.h"
  21. #include "mfx_dispatcher.h"
  22. #include "mfx_dispatcher_log.h"
  23. #include "mfx_dxva2_device.h"
  24. #include "mfx_load_dll.h"
  25. #include <tchar.h>
  26. #include <windows.h>
  27. namespace MFX
  28. {
  29. enum
  30. {
  31. MFX_MAX_MERIT = 0x7fffffff
  32. };
  33. //
  34. // declare registry keys
  35. //
  36. const
  37. wchar_t rootDispPath[] = L"Software\\Intel\\MediaSDK\\Dispatch";
  38. const
  39. wchar_t vendorIDKeyName[] = L"VendorID";
  40. const
  41. wchar_t deviceIDKeyName[] = L"DeviceID";
  42. const
  43. wchar_t meritKeyName[] = L"Merit";
  44. const
  45. wchar_t pathKeyName[] = L"Path";
  46. const
  47. wchar_t apiVersionName[] = L"APIVersion";
  48. mfxStatus SelectImplementationType(const mfxU32 adapterNum, mfxIMPL *pImplInterface, mfxU32 *pVendorID, mfxU32 *pDeviceID)
  49. {
  50. if (NULL == pImplInterface)
  51. {
  52. return MFX_ERR_NULL_PTR;
  53. }
  54. #if (MFX_VERSION >= MFX_VERSION_NEXT)
  55. mfxIMPL impl_via = (*pImplInterface & ~MFX_IMPL_EXTERNAL_THREADING);
  56. #else
  57. mfxIMPL impl_via = *pImplInterface;
  58. #endif
  59. DXVA2Device dxvaDevice;
  60. if (MFX_IMPL_VIA_D3D9 == impl_via)
  61. {
  62. // try to create the Direct3D 9 device and find right adapter
  63. if (!dxvaDevice.InitD3D9(adapterNum))
  64. {
  65. DISPATCHER_LOG_INFO((("dxvaDevice.InitD3D9(%d) Failed\n"), adapterNum ));
  66. return MFX_ERR_UNSUPPORTED;
  67. }
  68. }
  69. else if (MFX_IMPL_VIA_D3D11 == impl_via)
  70. {
  71. // try to open DXGI 1.1 device to get hardware ID
  72. if (!dxvaDevice.InitDXGI1(adapterNum))
  73. {
  74. DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed\n"), adapterNum ));
  75. return MFX_ERR_UNSUPPORTED;
  76. }
  77. }
  78. else if (MFX_IMPL_VIA_ANY == impl_via)
  79. {
  80. // try the Direct3D 9 device
  81. if (dxvaDevice.InitD3D9(adapterNum))
  82. {
  83. *pImplInterface = MFX_IMPL_VIA_D3D9; // store value for GetImplementationType() call
  84. }
  85. // else try to open DXGI 1.1 device to get hardware ID
  86. else if (dxvaDevice.InitDXGI1(adapterNum))
  87. {
  88. *pImplInterface = MFX_IMPL_VIA_D3D11; // store value for GetImplementationType() call
  89. }
  90. else
  91. {
  92. DISPATCHER_LOG_INFO((("Unsupported adapter %d\n"), adapterNum ));
  93. return MFX_ERR_UNSUPPORTED;
  94. }
  95. }
  96. else
  97. {
  98. DISPATCHER_LOG_ERROR((("Unknown implementation type %d\n"), *pImplInterface ));
  99. return MFX_ERR_UNSUPPORTED;
  100. }
  101. // obtain card's parameters
  102. if (pVendorID && pDeviceID)
  103. {
  104. *pVendorID = dxvaDevice.GetVendorID();
  105. *pDeviceID = dxvaDevice.GetDeviceID();
  106. }
  107. return MFX_ERR_NONE;
  108. }
  109. MFXLibraryIterator::MFXLibraryIterator(void)
  110. #if !defined(MEDIASDK_UWP_DISPATCHER)
  111. : m_baseRegKey()
  112. #endif
  113. {
  114. m_implType = MFX_LIB_PSEUDO;
  115. m_implInterface = MFX_IMPL_UNSUPPORTED;
  116. m_vendorID = 0;
  117. m_deviceID = 0;
  118. m_lastLibIndex = 0;
  119. m_lastLibMerit = MFX_MAX_MERIT;
  120. m_bIsSubKeyValid = 0;
  121. m_StorageID = 0;
  122. m_SubKeyName[0] = 0;
  123. } // MFXLibraryIterator::MFXLibraryIterator(void)
  124. MFXLibraryIterator::~MFXLibraryIterator(void)
  125. {
  126. Release();
  127. } // MFXLibraryIterator::~MFXLibraryIterator(void)
  128. void MFXLibraryIterator::Release(void)
  129. {
  130. m_implType = MFX_LIB_PSEUDO;
  131. m_implInterface = MFX_IMPL_UNSUPPORTED;
  132. m_vendorID = 0;
  133. m_deviceID = 0;
  134. m_lastLibIndex = 0;
  135. m_lastLibMerit = MFX_MAX_MERIT;
  136. m_SubKeyName[0] = 0;
  137. } // void MFXLibraryIterator::Release(void)
  138. DECLSPEC_NOINLINE HMODULE GetThisDllModuleHandle()
  139. {
  140. HMODULE hDll = NULL;
  141. GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
  142. GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
  143. reinterpret_cast<LPCWSTR>(&GetThisDllModuleHandle), &hDll);
  144. return hDll;
  145. }
  146. // wchar_t* sImplPath must be allocated with size not less then msdk_disp_path_len
  147. bool GetImplPath(int storageID, wchar_t* sImplPath)
  148. {
  149. HMODULE hModule = NULL;
  150. sImplPath[0] = L'\0';
  151. switch (storageID) {
  152. case MFX_APP_FOLDER:
  153. hModule = 0;
  154. break;
  155. case MFX_PATH_MSDK_FOLDER:
  156. hModule = GetThisDllModuleHandle();
  157. HMODULE exeModule = GetModuleHandleW(NULL);
  158. //It should works only if Dispatcher is linked with Dynamic Linked Library
  159. if (!hModule || !exeModule || hModule == exeModule)
  160. return false;
  161. break;
  162. }
  163. DWORD nSize = 0;
  164. DWORD allocSize = msdk_disp_path_len;
  165. nSize = GetModuleFileNameW(hModule, &sImplPath[0], allocSize);
  166. if (nSize == 0 || nSize == allocSize) {
  167. // nSize == 0 meanse that system can't get this info for hModule
  168. // nSize == allocSize buffer is too small
  169. return false;
  170. }
  171. // for any case because WinXP implementation of GetModuleFileName does not add \0 to the end of string
  172. sImplPath[nSize] = L'\0';
  173. wchar_t * dirSeparator = wcsrchr(sImplPath, L'\\');
  174. if (dirSeparator != NULL && dirSeparator < (sImplPath + msdk_disp_path_len))
  175. {
  176. *++dirSeparator = 0;
  177. }
  178. return true;
  179. }
  180. mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID)
  181. {
  182. // check error(s)
  183. if ((MFX_LIB_SOFTWARE != implType) &&
  184. (MFX_LIB_HARDWARE != implType))
  185. {
  186. return MFX_ERR_UNSUPPORTED;
  187. }
  188. // release the object before initialization
  189. Release();
  190. m_StorageID = storageID;
  191. m_lastLibIndex = 0;
  192. m_implType = implType;
  193. m_implInterface = implInterface != 0
  194. ? implInterface
  195. : MFX_IMPL_VIA_ANY;
  196. // for HW impl check impl interface, check adapter, obtain deviceID and vendorID
  197. if (m_implType != MFX_LIB_SOFTWARE)
  198. {
  199. mfxStatus mfxRes = MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID);
  200. if (MFX_ERR_NONE != mfxRes)
  201. {
  202. return mfxRes;
  203. }
  204. }
  205. #if !defined(MEDIASDK_UWP_DISPATCHER)
  206. if (storageID == MFX_CURRENT_USER_KEY || storageID == MFX_LOCAL_MACHINE_KEY)
  207. {
  208. return InitRegistry(storageID);
  209. }
  210. #if defined(MFX_TRACER_WA_FOR_DS)
  211. if (storageID == MFX_TRACER)
  212. {
  213. return InitRegistryTracer();
  214. }
  215. #endif
  216. #endif
  217. wchar_t sMediaSDKPath[msdk_disp_path_len] = {};
  218. if (storageID == MFX_DRIVER_STORE)
  219. {
  220. if (!m_driverStoreLoader.GetDriverStorePath(sMediaSDKPath, sizeof(sMediaSDKPath), m_deviceID))
  221. {
  222. return MFX_ERR_UNSUPPORTED;
  223. }
  224. }
  225. else if(!GetImplPath(storageID, sMediaSDKPath))
  226. {
  227. return MFX_ERR_UNSUPPORTED;
  228. }
  229. return InitFolder(implType, sMediaSDKPath, storageID);
  230. } // mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID)
  231. mfxStatus MFXLibraryIterator::InitRegistry(int storageID)
  232. {
  233. #if !defined(MEDIASDK_UWP_DISPATCHER)
  234. HKEY rootHKey;
  235. bool bRes;
  236. // open required registry key
  237. rootHKey = (MFX_LOCAL_MACHINE_KEY == storageID) ? (HKEY_LOCAL_MACHINE) : (HKEY_CURRENT_USER);
  238. bRes = m_baseRegKey.Open(rootHKey, rootDispPath, KEY_READ);
  239. if (false == bRes)
  240. {
  241. DISPATCHER_LOG_WRN((("Can't open %s\\%S : RegOpenKeyExA()==0x%x\n"),
  242. (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
  243. rootDispPath, GetLastError()))
  244. return MFX_ERR_UNKNOWN;
  245. }
  246. DISPATCHER_LOG_INFO((("Inspecting %s\\%S\n"),
  247. (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
  248. rootDispPath))
  249. return MFX_ERR_NONE;
  250. #else
  251. (void) storageID;
  252. return MFX_ERR_UNSUPPORTED;
  253. #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
  254. } // mfxStatus MFXLibraryIterator::InitRegistry(int storageID)
  255. #if defined(MFX_TRACER_WA_FOR_DS)
  256. mfxStatus MFXLibraryIterator::InitRegistryTracer()
  257. {
  258. #if !defined(MEDIASDK_UWP_DISPATCHER)
  259. const wchar_t tracerRegKeyPath[] = L"Software\\Intel\\MediaSDK\\Dispatch\\tracer";
  260. if (!m_baseRegKey.Open(HKEY_LOCAL_MACHINE, tracerRegKeyPath, KEY_READ) && !m_baseRegKey.Open(HKEY_CURRENT_USER, tracerRegKeyPath, KEY_READ))
  261. {
  262. DISPATCHER_LOG_WRN(("can't find tracer registry key\n"))
  263. return MFX_ERR_UNKNOWN;
  264. }
  265. DISPATCHER_LOG_INFO(("found tracer registry key\n"))
  266. return MFX_ERR_NONE;
  267. #else
  268. return MFX_ERR_UNSUPPORTED;
  269. #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
  270. } // mfxStatus MFXLibraryIterator::InitRegistryTracer()
  271. #endif
  272. mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, const wchar_t * path, const int storageID)
  273. {
  274. const int maxPathLen = sizeof(m_path)/sizeof(m_path[0]);
  275. m_path[0] = 0;
  276. wcscpy_s(m_path, maxPathLen, path);
  277. size_t pathLen = wcslen(m_path);
  278. if(storageID==MFX_APP_FOLDER)
  279. {
  280. // we looking for runtime in application folder, it should be named libmfxsw64 or libmfxsw32
  281. mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, MFX_LIB_SOFTWARE);
  282. }
  283. else
  284. {
  285. mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, implType);
  286. }
  287. return MFX_ERR_NONE;
  288. } // mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, const wchar_t * path, const int storageID)
  289. mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath
  290. , size_t pathSize
  291. , eMfxImplType *pImplType, mfxVersion minVersion)
  292. {
  293. UNREFERENCED_PARAMETER(minVersion);
  294. if (m_StorageID == MFX_APP_FOLDER)
  295. {
  296. if (m_lastLibIndex != 0)
  297. return MFX_ERR_NOT_FOUND;
  298. if (m_vendorID != INTEL_VENDOR_ID)
  299. return MFX_ERR_UNKNOWN;
  300. m_lastLibIndex = 1;
  301. wcscpy_s(pPath, pathSize, m_path);
  302. *pImplType = MFX_LIB_SOFTWARE;
  303. return MFX_ERR_NONE;
  304. }
  305. if (m_StorageID == MFX_PATH_MSDK_FOLDER || m_StorageID == MFX_DRIVER_STORE)
  306. {
  307. if (m_lastLibIndex != 0)
  308. return MFX_ERR_NOT_FOUND;
  309. if (m_vendorID != INTEL_VENDOR_ID)
  310. return MFX_ERR_UNKNOWN;
  311. m_lastLibIndex = 1;
  312. wcscpy_s(pPath, pathSize, m_path);
  313. // do not change impl type
  314. return MFX_ERR_NONE;
  315. }
  316. #if !defined(MEDIASDK_UWP_DISPATCHER)
  317. #if defined(MFX_TRACER_WA_FOR_DS)
  318. if (m_StorageID == MFX_TRACER)
  319. {
  320. if (m_lastLibIndex != 0)
  321. return MFX_ERR_NOT_FOUND;
  322. if (m_vendorID != INTEL_VENDOR_ID)
  323. return MFX_ERR_UNKNOWN;
  324. m_lastLibIndex = 1;
  325. if (m_baseRegKey.Query(pathKeyName, REG_SZ, (LPBYTE)pPath, (DWORD*)&pathSize))
  326. {
  327. DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, pPath));
  328. }
  329. else
  330. {
  331. DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
  332. }
  333. return MFX_ERR_NONE;
  334. }
  335. #endif
  336. wchar_t libPath[MFX_MAX_DLL_PATH] = L"";
  337. DWORD libIndex = 0;
  338. DWORD libMerit = 0;
  339. DWORD index;
  340. bool enumRes;
  341. // main query cycle
  342. index = 0;
  343. m_bIsSubKeyValid = false;
  344. do
  345. {
  346. WinRegKey subKey;
  347. wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME] = { 0 };
  348. DWORD subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]);
  349. // query next value name
  350. enumRes = m_baseRegKey.EnumKey(index, subKeyName, &subKeyNameSize);
  351. if (!enumRes)
  352. {
  353. DISPATCHER_LOG_WRN((("no more subkeys : RegEnumKeyExA()==0x%x\n"), GetLastError()))
  354. }
  355. else
  356. {
  357. DISPATCHER_LOG_INFO((("found subkey: %S\n"), subKeyName))
  358. bool bRes;
  359. // open the sub key
  360. bRes = subKey.Open(m_baseRegKey, subKeyName, KEY_READ);
  361. if (!bRes)
  362. {
  363. DISPATCHER_LOG_WRN((("error opening key %S :RegOpenKeyExA()==0x%x\n"), subKeyName, GetLastError()));
  364. }
  365. else
  366. {
  367. DISPATCHER_LOG_INFO((("opened key: %S\n"), subKeyName));
  368. mfxU32 vendorID = 0, deviceID = 0, merit = 0;
  369. DWORD size;
  370. // query vendor and device IDs
  371. size = sizeof(vendorID);
  372. bRes = subKey.Query(vendorIDKeyName, REG_DWORD, (LPBYTE) &vendorID, &size);
  373. DISPATCHER_LOG_OPERATION({
  374. if (bRes)
  375. {
  376. DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), vendorIDKeyName, vendorID));
  377. }
  378. else
  379. {
  380. DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), vendorIDKeyName, GetLastError()));
  381. }
  382. })
  383. if (bRes)
  384. {
  385. size = sizeof(deviceID);
  386. bRes = subKey.Query(deviceIDKeyName, REG_DWORD, (LPBYTE) &deviceID, &size);
  387. DISPATCHER_LOG_OPERATION({
  388. if (bRes)
  389. {
  390. DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), deviceIDKeyName, deviceID));
  391. }
  392. else
  393. {
  394. DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), deviceIDKeyName, GetLastError()));
  395. }
  396. })
  397. }
  398. // query merit value
  399. if (bRes)
  400. {
  401. size = sizeof(merit);
  402. bRes = subKey.Query(meritKeyName, REG_DWORD, (LPBYTE) &merit, &size);
  403. DISPATCHER_LOG_OPERATION({
  404. if (bRes)
  405. {
  406. DISPATCHER_LOG_INFO((("loaded %S : %d\n"), meritKeyName, merit));
  407. }
  408. else
  409. {
  410. DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), meritKeyName, GetLastError()));
  411. }
  412. })
  413. }
  414. // if the library fits required parameters,
  415. // query the library's path
  416. if (bRes)
  417. {
  418. // compare device's and library's IDs
  419. if (MFX_LIB_HARDWARE == m_implType)
  420. {
  421. if (m_vendorID != vendorID)
  422. {
  423. bRes = false;
  424. DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), vendorIDKeyName, m_vendorID, vendorID));
  425. }
  426. if (bRes && m_deviceID != deviceID)
  427. {
  428. bRes = false;
  429. DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), deviceIDKeyName, m_deviceID, deviceID));
  430. }
  431. }
  432. DISPATCHER_LOG_OPERATION({
  433. if (bRes)
  434. {
  435. if (!(((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
  436. (libMerit < merit)))
  437. {
  438. DISPATCHER_LOG_WRN((("merit conflict: lastMerit = 0x%x, requiredMerit = 0x%x, libraryMerit = 0x%x, lastindex = %d, index = %d\n")
  439. , m_lastLibMerit, merit, libMerit, m_lastLibIndex, index));
  440. }
  441. }})
  442. if ((bRes) &&
  443. ((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
  444. (libMerit < merit))
  445. {
  446. wchar_t tmpPath[MFX_MAX_DLL_PATH];
  447. DWORD tmpPathSize = sizeof(tmpPath);
  448. bRes = subKey.Query(pathKeyName, REG_SZ, (LPBYTE) tmpPath, &tmpPathSize);
  449. if (!bRes)
  450. {
  451. DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
  452. }
  453. else
  454. {
  455. DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, tmpPath));
  456. wcscpy_s(libPath, sizeof(libPath) / sizeof(libPath[0]), tmpPath);
  457. wcscpy_s(m_SubKeyName, sizeof(m_SubKeyName) / sizeof(m_SubKeyName[0]), subKeyName);
  458. libMerit = merit;
  459. libIndex = index;
  460. // set the library's type
  461. if ((0 == vendorID) || (0 == deviceID))
  462. {
  463. *pImplType = MFX_LIB_SOFTWARE;
  464. DISPATCHER_LOG_INFO((("Library type is MFX_LIB_SOFTWARE\n")));
  465. }
  466. else
  467. {
  468. *pImplType = MFX_LIB_HARDWARE;
  469. DISPATCHER_LOG_INFO((("Library type is MFX_LIB_HARDWARE\n")));
  470. }
  471. }
  472. }
  473. }
  474. }
  475. }
  476. // advance key index
  477. index += 1;
  478. } while (enumRes);
  479. // if the library's path was successfully read,
  480. // the merit variable holds valid value
  481. if (0 == libMerit)
  482. {
  483. return MFX_ERR_NOT_FOUND;
  484. }
  485. wcscpy_s(pPath, pathSize, libPath);
  486. m_lastLibIndex = libIndex;
  487. m_lastLibMerit = libMerit;
  488. m_bIsSubKeyValid = true;
  489. #endif
  490. return MFX_ERR_NONE;
  491. } // mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion)
  492. mfxIMPL MFXLibraryIterator::GetImplementationType()
  493. {
  494. return m_implInterface;
  495. } // mfxIMPL MFXLibraryIterator::GetImplementationType()
  496. bool MFXLibraryIterator::GetSubKeyName(wchar_t *subKeyName, size_t length) const
  497. {
  498. wcscpy_s(subKeyName, length, m_SubKeyName);
  499. return m_bIsSubKeyValid;
  500. }
  501. } // namespace MFX