1 /*############################################################################
2 # Copyright (C) 2012-2020 Intel Corporation
3 #
4 # SPDX-License-Identifier: MIT
5 ############################################################################*/
6
7 #include "windows/mfx_library_iterator.h"
8
9 #include "windows/mfx_dispatcher.h"
10 #include "windows/mfx_dispatcher_log.h"
11
12 #include "windows/mfx_dxva2_device.h"
13 #include "windows/mfx_load_dll.h"
14
15 #include <tchar.h>
16 #include <windows.h>
17
18 #include <vector>
19
20 namespace MFX {
21
22 enum { MFX_MAX_MERIT = 0x7fffffff };
23
24 //
25 // declare registry keys
26 //
27
28 const wchar_t rootDispPath[] = L"Software\\Intel\\MediaSDK\\Dispatch";
29 const wchar_t vendorIDKeyName[] = L"VendorID";
30 const wchar_t deviceIDKeyName[] = L"DeviceID";
31 const wchar_t meritKeyName[] = L"Merit";
32 const wchar_t pathKeyName[] = L"Path";
33 const wchar_t apiVersionName[] = L"APIVersion";
34
SelectImplementationType(const mfxU32 adapterNum,mfxIMPL * pImplInterface,mfxU32 * pVendorID,mfxU32 * pDeviceID,mfxU64 * pLUID)35 mfxStatus SelectImplementationType(const mfxU32 adapterNum,
36 mfxIMPL *pImplInterface,
37 mfxU32 *pVendorID,
38 mfxU32 *pDeviceID,
39 mfxU64 *pLUID) {
40 if (NULL == pImplInterface) {
41 return MFX_ERR_NULL_PTR;
42 }
43 mfxIMPL impl_via = *pImplInterface;
44
45 DXVA2Device dxvaDevice;
46 if (MFX_IMPL_VIA_D3D9 == impl_via) {
47 // try to create the Direct3D 9 device and find right adapter
48 if (!dxvaDevice.InitD3D9(adapterNum)) {
49 DISPATCHER_LOG_INFO((("dxvaDevice.InitD3D9(%d) Failed "), adapterNum));
50 return MFX_ERR_UNSUPPORTED;
51 }
52 }
53 else if (MFX_IMPL_VIA_D3D11 == impl_via) {
54 // try to open DXGI 1.1 device to get hardware ID
55 if (!dxvaDevice.InitDXGI1(adapterNum)) {
56 DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed "), adapterNum));
57 return MFX_ERR_UNSUPPORTED;
58 }
59 }
60 else if (MFX_IMPL_VIA_ANY == impl_via) {
61 // try the Direct3D 9 device
62 if (dxvaDevice.InitD3D9(adapterNum)) {
63 *pImplInterface = MFX_IMPL_VIA_D3D9; // store value for GetImplementationType() call
64 }
65 // else try to open DXGI 1.1 device to get hardware ID
66 else if (dxvaDevice.InitDXGI1(adapterNum)) {
67 *pImplInterface = MFX_IMPL_VIA_D3D11; // store value for GetImplementationType() call
68 }
69 else {
70 DISPATCHER_LOG_INFO((("Unsupported adapter %d "), adapterNum));
71 return MFX_ERR_UNSUPPORTED;
72 }
73 }
74 else {
75 DISPATCHER_LOG_ERROR((("Unknown implementation type %d "), *pImplInterface));
76 return MFX_ERR_UNSUPPORTED;
77 }
78
79 // obtain card's parameters
80 if (pVendorID && pDeviceID) {
81 *pVendorID = dxvaDevice.GetVendorID();
82 *pDeviceID = dxvaDevice.GetDeviceID();
83 }
84
85 if (pLUID) {
86 *pLUID = dxvaDevice.GetLUID();
87 }
88
89 return MFX_ERR_NONE;
90 }
91
SelectImplementationType(const mfxU32 adapterNum,mfxIMPL * pImplInterface,mfxU32 * pVendorID,mfxU32 * pDeviceID)92 mfxStatus SelectImplementationType(const mfxU32 adapterNum,
93 mfxIMPL *pImplInterface,
94 mfxU32 *pVendorID,
95 mfxU32 *pDeviceID) {
96 // do not return LUID
97 return SelectImplementationType(adapterNum, pImplInterface, pVendorID, pDeviceID, nullptr);
98 }
99
MFXLibraryIterator(void)100 MFXLibraryIterator::MFXLibraryIterator(void)
101 #if !defined(MEDIASDK_UWP_DISPATCHER)
102 : m_baseRegKey()
103 #endif
104 {
105 m_implType = MFX_LIB_PSEUDO;
106 m_implInterface = MFX_IMPL_UNSUPPORTED;
107
108 m_vendorID = 0;
109 m_deviceID = 0;
110
111 m_lastLibIndex = 0;
112 m_lastLibMerit = MFX_MAX_MERIT;
113
114 m_bIsSubKeyValid = 0;
115 m_StorageID = 0;
116
117 m_SubKeyName[0] = 0;
118 m_driverStoreDir[0] = 0;
119 } // MFXLibraryIterator::MFXLibraryIterator(void)
120
~MFXLibraryIterator(void)121 MFXLibraryIterator::~MFXLibraryIterator(void) {
122 Release();
123
124 } // MFXLibraryIterator::~MFXLibraryIterator(void)
125
Release(void)126 void MFXLibraryIterator::Release(void) {
127 m_implType = MFX_LIB_PSEUDO;
128 m_implInterface = MFX_IMPL_UNSUPPORTED;
129
130 m_vendorID = 0;
131 m_deviceID = 0;
132
133 m_lastLibIndex = 0;
134 m_lastLibMerit = MFX_MAX_MERIT;
135 m_SubKeyName[0] = 0;
136
137 } // void MFXLibraryIterator::Release(void)
138
GetThisDllModuleHandle()139 DECLSPEC_NOINLINE HMODULE GetThisDllModuleHandle() {
140 HMODULE hDll = NULL;
141
142 GetModuleHandleExW(
143 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
144 reinterpret_cast<LPCWSTR>(&GetThisDllModuleHandle),
145 &hDll);
146 return hDll;
147 }
148
149 // wchar_t* sImplPath must be allocated with size not less then msdk_disp_path_len
GetImplPath(int storageID,wchar_t * sImplPath)150 bool GetImplPath(int storageID, wchar_t *sImplPath) {
151 HMODULE hModule = NULL;
152
153 sImplPath[0] = L'\0';
154
155 switch (storageID) {
156 case MFX_APP_FOLDER:
157 hModule = 0;
158 break;
159 case MFX_PATH_MSDK_FOLDER:
160 hModule = GetThisDllModuleHandle();
161 HMODULE exeModule = GetModuleHandleW(NULL);
162 //It should works only if Dispatcher is linked with Dynamic Linked Library
163 if (!hModule || !exeModule || hModule == exeModule)
164 return false;
165 break;
166 }
167
168 DWORD nSize = 0;
169 DWORD allocSize = msdk_disp_path_len;
170
171 nSize = GetModuleFileNameW(hModule, &sImplPath[0], allocSize);
172
173 if (nSize == 0 || nSize == allocSize) {
174 // nSize == 0 meanse that system can't get this info for hModule
175 // nSize == allocSize buffer is too small
176 return false;
177 }
178
179 // for any case because WinXP implementation of GetModuleFileName does not add \0 to the end of string
180 sImplPath[nSize] = L'\0';
181
182 wchar_t *dirSeparator = wcsrchr(sImplPath, L'\\');
183 if (dirSeparator != NULL && dirSeparator < (sImplPath + msdk_disp_path_len)) {
184 *++dirSeparator = 0;
185 }
186 return true;
187 }
188
Init(eMfxImplType implType,mfxIMPL implInterface,const mfxU32 adapterNum,int storageID)189 mfxStatus MFXLibraryIterator::Init(eMfxImplType implType,
190 mfxIMPL implInterface,
191 const mfxU32 adapterNum,
192 int storageID) {
193 // check error(s)
194 if ((MFX_LIB_SOFTWARE != implType) && (MFX_LIB_HARDWARE != implType)) {
195 return MFX_ERR_UNSUPPORTED;
196 }
197
198 // release the object before initialization
199 Release();
200 m_StorageID = storageID;
201 m_lastLibIndex = 0;
202 m_implType = implType;
203 m_implInterface = implInterface != 0 ? implInterface : MFX_IMPL_VIA_ANY;
204
205 // for HW impl check impl interface, check adapter, obtain deviceID and vendorID
206 if (m_implType != MFX_LIB_SOFTWARE) {
207 mfxStatus mfxRes =
208 MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID);
209 if (MFX_ERR_NONE != mfxRes) {
210 return mfxRes;
211 }
212 }
213
214 #if !defined(MEDIASDK_UWP_DISPATCHER)
215 if (storageID == MFX_CURRENT_USER_KEY || storageID == MFX_LOCAL_MACHINE_KEY ||
216 storageID == MFX_CURRENT_USER_KEY_ONEVPL || storageID == MFX_LOCAL_MACHINE_KEY_ONEVPL) {
217 return InitRegistry(storageID);
218 }
219
220 #if defined(MFX_TRACER_WA_FOR_DS)
221 if (storageID == MFX_TRACER) {
222 return InitRegistryTracer();
223 }
224 #endif
225
226 #endif
227 if (storageID == MFX_DRIVER_STORE) {
228 m_driverStoreDir[0] = 0;
229 if (!m_driverStoreLoader.GetDriverStorePath(m_driverStoreDir,
230 sizeof(m_driverStoreDir),
231 m_deviceID,
232 L"DriverStorePathForMediaSDK")) {
233 return MFX_ERR_UNSUPPORTED;
234 }
235 }
236 else if (storageID == MFX_DRIVER_STORE_ONEVPL || storageID == MFX_DRIVER_STORE_ONEVPL_MFXINIT) {
237 // get path to runtime directory only (without library name)
238 m_driverStoreDir[0] = 0;
239 if (!m_driverStoreLoader.GetDriverStorePath(m_driverStoreDir,
240 sizeof(m_driverStoreDir),
241 m_deviceID,
242 L"DriverStorePathForVPL")) {
243 return MFX_ERR_UNSUPPORTED;
244 }
245 }
246 else if (!GetImplPath(storageID, m_driverStoreDir)) {
247 return MFX_ERR_UNSUPPORTED;
248 }
249
250 // only need the path for oneVPL loader
251 if (storageID == MFX_DRIVER_STORE_ONEVPL || storageID == MFX_CURRENT_USER_KEY_ONEVPL ||
252 storageID == MFX_LOCAL_MACHINE_KEY_ONEVPL) {
253 return MFX_ERR_NONE;
254 }
255
256 return InitFolder(implType, m_driverStoreDir, storageID);
257
258 } // mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID)
259
InitRegistry(int storageID)260 mfxStatus MFXLibraryIterator::InitRegistry(int storageID) {
261 #if !defined(MEDIASDK_UWP_DISPATCHER)
262 HKEY rootHKey;
263 bool bRes;
264
265 // open required registry key
266 switch (storageID) {
267 case MFX_LOCAL_MACHINE_KEY:
268 case MFX_LOCAL_MACHINE_KEY_ONEVPL:
269 rootHKey = HKEY_LOCAL_MACHINE;
270 break;
271 default:
272 rootHKey = HKEY_CURRENT_USER;
273 break;
274 }
275
276 bRes = m_baseRegKey.Open(rootHKey, rootDispPath, KEY_READ);
277 if (false == bRes) {
278 DISPATCHER_LOG_WRN(
279 (("Can't open %s\\%S : RegOpenKeyExA()==0x%x\n"),
280 (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
281 rootDispPath,
282 GetLastError()))
283 return MFX_ERR_UNKNOWN;
284 }
285
286 DISPATCHER_LOG_INFO(
287 (("Inspecting %s\\%S\n"),
288 (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
289 rootDispPath))
290
291 return MFX_ERR_NONE;
292 #else
293 (void)storageID;
294 return MFX_ERR_UNSUPPORTED;
295 #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
296
297 } // mfxStatus MFXLibraryIterator::InitRegistry(int storageID)
298
299 #if defined(MFX_TRACER_WA_FOR_DS)
InitRegistryTracer()300 mfxStatus MFXLibraryIterator::InitRegistryTracer() {
301 #if !defined(MEDIASDK_UWP_DISPATCHER)
302
303 const wchar_t tracerRegKeyPath[] = L"Software\\Intel\\MediaSDK\\Dispatch\\tracer";
304
305 if (!m_baseRegKey.Open(HKEY_LOCAL_MACHINE, tracerRegKeyPath, KEY_READ) &&
306 !m_baseRegKey.Open(HKEY_CURRENT_USER, tracerRegKeyPath, KEY_READ)) {
307 DISPATCHER_LOG_WRN(("can't find tracer registry key\n"))
308 return MFX_ERR_UNKNOWN;
309 }
310
311 DISPATCHER_LOG_INFO(("found tracer registry key\n"))
312 return MFX_ERR_NONE;
313
314 #else
315 return MFX_ERR_UNSUPPORTED;
316 #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
317
318 } // mfxStatus MFXLibraryIterator::InitRegistryTracer()
319 #endif
320
InitFolder(eMfxImplType implType,const wchar_t * path,const int storageID)321 mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType,
322 const wchar_t *path,
323 const int storageID) {
324 const int maxPathLen = sizeof(m_path) / sizeof(m_path[0]);
325 m_path[0] = 0;
326 wcscpy_s(m_path, maxPathLen, path);
327 size_t pathLen = wcslen(m_path);
328
329 if (storageID == MFX_APP_FOLDER) {
330 // we looking for runtime in application folder, it should be named libmfxsw64 or libmfxsw32
331 mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, MFX_LIB_SOFTWARE);
332 }
333 else if (storageID == MFX_DRIVER_STORE_ONEVPL_MFXINIT) {
334 mfx_get_default_onevpl_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen);
335 }
336 else {
337 mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, implType);
338 }
339
340 return MFX_ERR_NONE;
341 } // mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, const wchar_t * path, const int storageID)
342
SelectDLLVersion(wchar_t * pPath,size_t pathSize,eMfxImplType * pImplType,mfxVersion minVersion)343 mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath,
344 size_t pathSize,
345 eMfxImplType *pImplType,
346 mfxVersion minVersion) {
347 UNREFERENCED_PARAMETER(minVersion);
348
349 if (m_StorageID == MFX_APP_FOLDER) {
350 if (m_lastLibIndex != 0)
351 return MFX_ERR_NOT_FOUND;
352 if (m_vendorID != INTEL_VENDOR_ID)
353 return MFX_ERR_UNKNOWN;
354
355 m_lastLibIndex = 1;
356 wcscpy_s(pPath, pathSize, m_path);
357 *pImplType = MFX_LIB_SOFTWARE;
358 return MFX_ERR_NONE;
359 }
360
361 if (m_StorageID == MFX_PATH_MSDK_FOLDER || m_StorageID == MFX_DRIVER_STORE ||
362 m_StorageID == MFX_DRIVER_STORE_ONEVPL_MFXINIT) {
363 if (m_lastLibIndex != 0)
364 return MFX_ERR_NOT_FOUND;
365 if (m_vendorID != INTEL_VENDOR_ID)
366 return MFX_ERR_UNKNOWN;
367
368 m_lastLibIndex = 1;
369 wcscpy_s(pPath, pathSize, m_path);
370 // do not change impl type
371 return MFX_ERR_NONE;
372 }
373
374 #if !defined(MEDIASDK_UWP_DISPATCHER)
375
376 #if defined(MFX_TRACER_WA_FOR_DS)
377 if (m_StorageID == MFX_TRACER) {
378 if (m_lastLibIndex != 0)
379 return MFX_ERR_NOT_FOUND;
380 if (m_vendorID != INTEL_VENDOR_ID)
381 return MFX_ERR_UNKNOWN;
382
383 m_lastLibIndex = 1;
384
385 if (m_baseRegKey.Query(pathKeyName, REG_SZ, (LPBYTE)pPath, (DWORD *)&pathSize)) {
386 DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, pPath));
387 }
388 else {
389 DISPATCHER_LOG_WRN(
390 (("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
391 }
392 return MFX_ERR_NONE;
393 }
394 #endif
395
396 wchar_t libPath[MFX_MAX_DLL_PATH] = L"";
397 DWORD libIndex = 0;
398 DWORD libMerit = 0;
399 DWORD index;
400 bool enumRes;
401
402 // main query cycle
403 index = 0;
404 m_bIsSubKeyValid = false;
405 do {
406 WinRegKey subKey;
407 wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME] = { 0 };
408 DWORD subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]);
409
410 // query next value name
411 enumRes = m_baseRegKey.EnumKey(index, subKeyName, &subKeyNameSize);
412 if (!enumRes) {
413 DISPATCHER_LOG_WRN((("no more subkeys : RegEnumKeyExA()==0x%x\n"), GetLastError()))
414 }
415 else {
416 DISPATCHER_LOG_INFO((("found subkey: %S\n"), subKeyName))
417
418 bool bRes;
419
420 // open the sub key
421 bRes = subKey.Open(m_baseRegKey, subKeyName, KEY_READ);
422 if (!bRes) {
423 DISPATCHER_LOG_WRN((("error opening key %S :RegOpenKeyExA()==0x%x\n"),
424 subKeyName,
425 GetLastError()));
426 }
427 else {
428 DISPATCHER_LOG_INFO((("opened key: %S\n"), subKeyName));
429
430 mfxU32 vendorID = 0, deviceID = 0, merit = 0;
431 DWORD size;
432
433 // query vendor and device IDs
434 size = sizeof(vendorID);
435 bRes = subKey.Query(vendorIDKeyName, REG_DWORD, (LPBYTE)&vendorID, &size);
436 DISPATCHER_LOG_OPERATION({
437 if (bRes) {
438 DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), vendorIDKeyName, vendorID));
439 }
440 else {
441 DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"),
442 vendorIDKeyName,
443 GetLastError()));
444 }
445 })
446
447 if (bRes) {
448 size = sizeof(deviceID);
449 bRes = subKey.Query(deviceIDKeyName, REG_DWORD, (LPBYTE)&deviceID, &size);
450 DISPATCHER_LOG_OPERATION({
451 if (bRes) {
452 DISPATCHER_LOG_INFO(
453 (("loaded %S : 0x%x\n"), deviceIDKeyName, deviceID));
454 }
455 else {
456 DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"),
457 deviceIDKeyName,
458 GetLastError()));
459 }
460 })
461 }
462 // query merit value
463 if (bRes) {
464 size = sizeof(merit);
465 bRes = subKey.Query(meritKeyName, REG_DWORD, (LPBYTE)&merit, &size);
466 DISPATCHER_LOG_OPERATION({
467 if (bRes) {
468 DISPATCHER_LOG_INFO((("loaded %S : %d\n"), meritKeyName, merit));
469 }
470 else {
471 DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"),
472 meritKeyName,
473 GetLastError()));
474 }
475 })
476 }
477
478 // if the library fits required parameters,
479 // query the library's path
480 if (bRes) {
481 // compare device's and library's IDs
482 if (MFX_LIB_HARDWARE == m_implType) {
483 if (m_vendorID != vendorID) {
484 bRes = false;
485 DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"),
486 vendorIDKeyName,
487 m_vendorID,
488 vendorID));
489 }
490 if (bRes && m_deviceID != deviceID) {
491 bRes = false;
492 DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"),
493 deviceIDKeyName,
494 m_deviceID,
495 deviceID));
496 }
497 }
498
499 DISPATCHER_LOG_OPERATION({
500 if (bRes) {
501 if (!(((m_lastLibMerit > merit) ||
502 ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
503 (libMerit < merit))) {
504 DISPATCHER_LOG_WRN((
505 ("merit conflict: lastMerit = 0x%x, requiredMerit = 0x%x, libraryMerit = 0x%x, lastindex = %d, index = %d\n"),
506 m_lastLibMerit,
507 merit,
508 libMerit,
509 m_lastLibIndex,
510 index));
511 }
512 }
513 })
514
515 if ((bRes) &&
516 ((m_lastLibMerit > merit) ||
517 ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
518 (libMerit < merit)) {
519 wchar_t tmpPath[MFX_MAX_DLL_PATH];
520 DWORD tmpPathSize = sizeof(tmpPath);
521
522 bRes = subKey.Query(pathKeyName, REG_SZ, (LPBYTE)tmpPath, &tmpPathSize);
523 if (!bRes) {
524 DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"),
525 pathKeyName,
526 GetLastError()));
527 }
528 else {
529 DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, tmpPath));
530
531 wcscpy_s(libPath, sizeof(libPath) / sizeof(libPath[0]), tmpPath);
532 wcscpy_s(m_SubKeyName,
533 sizeof(m_SubKeyName) / sizeof(m_SubKeyName[0]),
534 subKeyName);
535
536 libMerit = merit;
537 libIndex = index;
538
539 // set the library's type
540 if ((0 == vendorID) || (0 == deviceID)) {
541 *pImplType = MFX_LIB_SOFTWARE;
542 DISPATCHER_LOG_INFO((("Library type is MFX_LIB_SOFTWARE\n")));
543 }
544 else {
545 *pImplType = MFX_LIB_HARDWARE;
546 DISPATCHER_LOG_INFO((("Library type is MFX_LIB_HARDWARE\n")));
547 }
548 }
549 }
550 }
551 }
552 }
553
554 // advance key index
555 index += 1;
556
557 } while (enumRes);
558
559 // if the library's path was successfully read,
560 // the merit variable holds valid value
561 if (0 == libMerit) {
562 return MFX_ERR_NOT_FOUND;
563 }
564
565 wcscpy_s(pPath, pathSize, libPath);
566
567 m_lastLibIndex = libIndex;
568 m_lastLibMerit = libMerit;
569 m_bIsSubKeyValid = true;
570
571 #endif
572
573 return MFX_ERR_NONE;
574
575 } // mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion)
576
GetImplementationType()577 mfxIMPL MFXLibraryIterator::GetImplementationType() {
578 return m_implInterface;
579 } // mfxIMPL MFXLibraryIterator::GetImplementationType()
580
GetSubKeyName(wchar_t * subKeyName,size_t length) const581 bool MFXLibraryIterator::GetSubKeyName(wchar_t *subKeyName, size_t length) const {
582 wcscpy_s(subKeyName, length, m_SubKeyName);
583 return m_bIsSubKeyValid;
584 }
585
586 // lightweight implementation that takes deviceID as an argument, avoiding need to init the adapter
GetDriverStoreDir(std::wstring & driverStoreDir,size_t length,mfxU32 deviceID,int storageID)587 mfxStatus MFXLibraryIterator::GetDriverStoreDir(std::wstring &driverStoreDir,
588 size_t length,
589 mfxU32 deviceID,
590 int storageID) {
591 wchar_t wcDir[MFX_MAX_DLL_PATH];
592 wcDir[0] = 0;
593
594 DriverStoreLoader dsLoader;
595
596 if (storageID == MFX_DRIVER_STORE_ONEVPL) {
597 // pass size of wcDir in bytes (see implementation of GetDriverStorePath)
598 if (!dsLoader.GetDriverStorePath(wcDir, sizeof(wcDir), deviceID, L"DriverStorePathForVPL"))
599 return MFX_ERR_UNSUPPORTED;
600 }
601 else if (storageID == MFX_DRIVER_STORE) {
602 if (!dsLoader.GetDriverStorePath(wcDir,
603 sizeof(wcDir),
604 deviceID,
605 L"DriverStorePathForMediaSDK"))
606 return MFX_ERR_UNSUPPORTED;
607 }
608
609 if (wcslen(wcDir) == 0)
610 return MFX_ERR_UNSUPPORTED;
611
612 // return path to driverStorDir
613 driverStoreDir = wcDir;
614
615 return MFX_ERR_NONE;
616 }
617
GetRegkeyDir(std::wstring & regDir,size_t length,int storageID)618 mfxStatus MFXLibraryIterator::GetRegkeyDir(std::wstring ®Dir, size_t length, int storageID) {
619 mfxStatus sts = MFX_ERR_UNSUPPORTED;
620 MFX::MFXLibraryIterator libIterator;
621 wchar_t wRegDir[MFX_MAX_DLL_PATH];
622
623 regDir.clear();
624 sts = libIterator.Init(MFX_LIB_HARDWARE, MFX_IMPL_VIA_D3D11, 0, storageID);
625 if (sts)
626 return MFX_ERR_UNSUPPORTED;
627
628 eMfxImplType implType = MFX_LIB_HARDWARE;
629 mfxVersion ver = { 0, 1 };
630 sts =
631 libIterator.SelectDLLVersion(wRegDir, sizeof(wRegDir) / sizeof(wRegDir[0]), &implType, ver);
632 if (sts)
633 return MFX_ERR_UNSUPPORTED;
634
635 // remove DLL name - only need the path
636 std::wstring s = wRegDir;
637 size_t f = s.find_last_of('\\');
638 if (f == std::string::npos)
639 return MFX_ERR_UNSUPPORTED;
640
641 regDir = s.substr(0, f);
642
643 return MFX_ERR_NONE;
644 }
645
646 } // namespace MFX
647