| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- // Copyright (c) 2012-2020 Intel Corporation
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in all
- // copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- // SOFTWARE.
- #include "mfx_library_iterator.h"
- #include "mfx_dispatcher.h"
- #include "mfx_dispatcher_log.h"
- #include "mfx_dxva2_device.h"
- #include "mfx_load_dll.h"
- #include <tchar.h>
- #include <windows.h>
- namespace MFX
- {
- enum
- {
- MFX_MAX_MERIT = 0x7fffffff
- };
- //
- // declare registry keys
- //
- const
- wchar_t rootDispPath[] = L"Software\\Intel\\MediaSDK\\Dispatch";
- const
- wchar_t vendorIDKeyName[] = L"VendorID";
- const
- wchar_t deviceIDKeyName[] = L"DeviceID";
- const
- wchar_t meritKeyName[] = L"Merit";
- const
- wchar_t pathKeyName[] = L"Path";
- const
- wchar_t apiVersionName[] = L"APIVersion";
- mfxStatus SelectImplementationType(const mfxU32 adapterNum, mfxIMPL *pImplInterface, mfxU32 *pVendorID, mfxU32 *pDeviceID)
- {
- if (NULL == pImplInterface)
- {
- return MFX_ERR_NULL_PTR;
- }
- #if (MFX_VERSION >= MFX_VERSION_NEXT)
- mfxIMPL impl_via = (*pImplInterface & ~MFX_IMPL_EXTERNAL_THREADING);
- #else
- mfxIMPL impl_via = *pImplInterface;
- #endif
- DXVA2Device dxvaDevice;
- if (MFX_IMPL_VIA_D3D9 == impl_via)
- {
- // try to create the Direct3D 9 device and find right adapter
- if (!dxvaDevice.InitD3D9(adapterNum))
- {
- DISPATCHER_LOG_INFO((("dxvaDevice.InitD3D9(%d) Failed\n"), adapterNum ));
- return MFX_ERR_UNSUPPORTED;
- }
- }
- else if (MFX_IMPL_VIA_D3D11 == impl_via)
- {
- // try to open DXGI 1.1 device to get hardware ID
- if (!dxvaDevice.InitDXGI1(adapterNum))
- {
- DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed\n"), adapterNum ));
- return MFX_ERR_UNSUPPORTED;
- }
- }
- else if (MFX_IMPL_VIA_ANY == impl_via)
- {
- // try the Direct3D 9 device
- if (dxvaDevice.InitD3D9(adapterNum))
- {
- *pImplInterface = MFX_IMPL_VIA_D3D9; // store value for GetImplementationType() call
- }
- // else try to open DXGI 1.1 device to get hardware ID
- else if (dxvaDevice.InitDXGI1(adapterNum))
- {
- *pImplInterface = MFX_IMPL_VIA_D3D11; // store value for GetImplementationType() call
- }
- else
- {
- DISPATCHER_LOG_INFO((("Unsupported adapter %d\n"), adapterNum ));
- return MFX_ERR_UNSUPPORTED;
- }
- }
- else
- {
- DISPATCHER_LOG_ERROR((("Unknown implementation type %d\n"), *pImplInterface ));
- return MFX_ERR_UNSUPPORTED;
- }
- // obtain card's parameters
- if (pVendorID && pDeviceID)
- {
- *pVendorID = dxvaDevice.GetVendorID();
- *pDeviceID = dxvaDevice.GetDeviceID();
- }
- return MFX_ERR_NONE;
- }
- MFXLibraryIterator::MFXLibraryIterator(void)
- #if !defined(MEDIASDK_UWP_DISPATCHER)
- : m_baseRegKey()
- #endif
- {
- m_implType = MFX_LIB_PSEUDO;
- m_implInterface = MFX_IMPL_UNSUPPORTED;
- m_vendorID = 0;
- m_deviceID = 0;
- m_lastLibIndex = 0;
- m_lastLibMerit = MFX_MAX_MERIT;
- m_bIsSubKeyValid = 0;
- m_StorageID = 0;
- m_SubKeyName[0] = 0;
- } // MFXLibraryIterator::MFXLibraryIterator(void)
- MFXLibraryIterator::~MFXLibraryIterator(void)
- {
- Release();
- } // MFXLibraryIterator::~MFXLibraryIterator(void)
- void MFXLibraryIterator::Release(void)
- {
- m_implType = MFX_LIB_PSEUDO;
- m_implInterface = MFX_IMPL_UNSUPPORTED;
- m_vendorID = 0;
- m_deviceID = 0;
- m_lastLibIndex = 0;
- m_lastLibMerit = MFX_MAX_MERIT;
- m_SubKeyName[0] = 0;
- } // void MFXLibraryIterator::Release(void)
- DECLSPEC_NOINLINE HMODULE GetThisDllModuleHandle()
- {
- HMODULE hDll = NULL;
- GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- reinterpret_cast<LPCWSTR>(&GetThisDllModuleHandle), &hDll);
- return hDll;
- }
- // wchar_t* sImplPath must be allocated with size not less then msdk_disp_path_len
- bool GetImplPath(int storageID, wchar_t* sImplPath)
- {
- HMODULE hModule = NULL;
- sImplPath[0] = L'\0';
- switch (storageID) {
- case MFX_APP_FOLDER:
- hModule = 0;
- break;
- case MFX_PATH_MSDK_FOLDER:
- hModule = GetThisDllModuleHandle();
- HMODULE exeModule = GetModuleHandleW(NULL);
- //It should works only if Dispatcher is linked with Dynamic Linked Library
- if (!hModule || !exeModule || hModule == exeModule)
- return false;
- break;
- }
- DWORD nSize = 0;
- DWORD allocSize = msdk_disp_path_len;
- nSize = GetModuleFileNameW(hModule, &sImplPath[0], allocSize);
- if (nSize == 0 || nSize == allocSize) {
- // nSize == 0 meanse that system can't get this info for hModule
- // nSize == allocSize buffer is too small
- return false;
- }
- // for any case because WinXP implementation of GetModuleFileName does not add \0 to the end of string
- sImplPath[nSize] = L'\0';
- wchar_t * dirSeparator = wcsrchr(sImplPath, L'\\');
- if (dirSeparator != NULL && dirSeparator < (sImplPath + msdk_disp_path_len))
- {
- *++dirSeparator = 0;
- }
- return true;
- }
- mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, mfxIMPL implInterface, const mfxU32 adapterNum, int storageID)
- {
- // check error(s)
- if ((MFX_LIB_SOFTWARE != implType) &&
- (MFX_LIB_HARDWARE != implType))
- {
- return MFX_ERR_UNSUPPORTED;
- }
- // release the object before initialization
- Release();
- m_StorageID = storageID;
- m_lastLibIndex = 0;
- m_implType = implType;
- m_implInterface = implInterface != 0
- ? implInterface
- : MFX_IMPL_VIA_ANY;
- // for HW impl check impl interface, check adapter, obtain deviceID and vendorID
- if (m_implType != MFX_LIB_SOFTWARE)
- {
- mfxStatus mfxRes = MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID);
- if (MFX_ERR_NONE != mfxRes)
- {
- return mfxRes;
- }
- }
- #if !defined(MEDIASDK_UWP_DISPATCHER)
- if (storageID == MFX_CURRENT_USER_KEY || storageID == MFX_LOCAL_MACHINE_KEY)
- {
- return InitRegistry(storageID);
- }
- #if defined(MFX_TRACER_WA_FOR_DS)
- if (storageID == MFX_TRACER)
- {
- return InitRegistryTracer();
- }
- #endif
- #endif
- wchar_t sMediaSDKPath[msdk_disp_path_len] = {};
- if (storageID == MFX_DRIVER_STORE)
- {
- if (!m_driverStoreLoader.GetDriverStorePath(sMediaSDKPath, sizeof(sMediaSDKPath), m_deviceID))
- {
- return MFX_ERR_UNSUPPORTED;
- }
- }
- else if(!GetImplPath(storageID, sMediaSDKPath))
- {
- return MFX_ERR_UNSUPPORTED;
- }
- return InitFolder(implType, sMediaSDKPath, storageID);
- } // mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID)
- mfxStatus MFXLibraryIterator::InitRegistry(int storageID)
- {
- #if !defined(MEDIASDK_UWP_DISPATCHER)
- HKEY rootHKey;
- bool bRes;
- // open required registry key
- rootHKey = (MFX_LOCAL_MACHINE_KEY == storageID) ? (HKEY_LOCAL_MACHINE) : (HKEY_CURRENT_USER);
- bRes = m_baseRegKey.Open(rootHKey, rootDispPath, KEY_READ);
- if (false == bRes)
- {
- DISPATCHER_LOG_WRN((("Can't open %s\\%S : RegOpenKeyExA()==0x%x\n"),
- (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
- rootDispPath, GetLastError()))
- return MFX_ERR_UNKNOWN;
- }
- DISPATCHER_LOG_INFO((("Inspecting %s\\%S\n"),
- (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
- rootDispPath))
- return MFX_ERR_NONE;
- #else
- (void) storageID;
- return MFX_ERR_UNSUPPORTED;
- #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
- } // mfxStatus MFXLibraryIterator::InitRegistry(int storageID)
- #if defined(MFX_TRACER_WA_FOR_DS)
- mfxStatus MFXLibraryIterator::InitRegistryTracer()
- {
- #if !defined(MEDIASDK_UWP_DISPATCHER)
- const wchar_t tracerRegKeyPath[] = L"Software\\Intel\\MediaSDK\\Dispatch\\tracer";
- if (!m_baseRegKey.Open(HKEY_LOCAL_MACHINE, tracerRegKeyPath, KEY_READ) && !m_baseRegKey.Open(HKEY_CURRENT_USER, tracerRegKeyPath, KEY_READ))
- {
- DISPATCHER_LOG_WRN(("can't find tracer registry key\n"))
- return MFX_ERR_UNKNOWN;
- }
- DISPATCHER_LOG_INFO(("found tracer registry key\n"))
- return MFX_ERR_NONE;
- #else
- return MFX_ERR_UNSUPPORTED;
- #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
- } // mfxStatus MFXLibraryIterator::InitRegistryTracer()
- #endif
- mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, const wchar_t * path, const int storageID)
- {
- const int maxPathLen = sizeof(m_path)/sizeof(m_path[0]);
- m_path[0] = 0;
- wcscpy_s(m_path, maxPathLen, path);
- size_t pathLen = wcslen(m_path);
- if(storageID==MFX_APP_FOLDER)
- {
- // we looking for runtime in application folder, it should be named libmfxsw64 or libmfxsw32
- mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, MFX_LIB_SOFTWARE);
- }
- else
- {
- mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, implType);
- }
- return MFX_ERR_NONE;
- } // mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, const wchar_t * path, const int storageID)
- mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath
- , size_t pathSize
- , eMfxImplType *pImplType, mfxVersion minVersion)
- {
- UNREFERENCED_PARAMETER(minVersion);
- if (m_StorageID == MFX_APP_FOLDER)
- {
- if (m_lastLibIndex != 0)
- return MFX_ERR_NOT_FOUND;
- if (m_vendorID != INTEL_VENDOR_ID)
- return MFX_ERR_UNKNOWN;
- m_lastLibIndex = 1;
- wcscpy_s(pPath, pathSize, m_path);
- *pImplType = MFX_LIB_SOFTWARE;
- return MFX_ERR_NONE;
- }
- if (m_StorageID == MFX_PATH_MSDK_FOLDER || m_StorageID == MFX_DRIVER_STORE)
- {
- if (m_lastLibIndex != 0)
- return MFX_ERR_NOT_FOUND;
- if (m_vendorID != INTEL_VENDOR_ID)
- return MFX_ERR_UNKNOWN;
- m_lastLibIndex = 1;
- wcscpy_s(pPath, pathSize, m_path);
- // do not change impl type
- return MFX_ERR_NONE;
- }
- #if !defined(MEDIASDK_UWP_DISPATCHER)
- #if defined(MFX_TRACER_WA_FOR_DS)
- if (m_StorageID == MFX_TRACER)
- {
- if (m_lastLibIndex != 0)
- return MFX_ERR_NOT_FOUND;
- if (m_vendorID != INTEL_VENDOR_ID)
- return MFX_ERR_UNKNOWN;
- m_lastLibIndex = 1;
- if (m_baseRegKey.Query(pathKeyName, REG_SZ, (LPBYTE)pPath, (DWORD*)&pathSize))
- {
- DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, pPath));
- }
- else
- {
- DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
- }
- return MFX_ERR_NONE;
- }
- #endif
- wchar_t libPath[MFX_MAX_DLL_PATH] = L"";
- DWORD libIndex = 0;
- DWORD libMerit = 0;
- DWORD index;
- bool enumRes;
- // main query cycle
- index = 0;
- m_bIsSubKeyValid = false;
- do
- {
- WinRegKey subKey;
- wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME] = { 0 };
- DWORD subKeyNameSize = sizeof(subKeyName) / sizeof(subKeyName[0]);
- // query next value name
- enumRes = m_baseRegKey.EnumKey(index, subKeyName, &subKeyNameSize);
- if (!enumRes)
- {
- DISPATCHER_LOG_WRN((("no more subkeys : RegEnumKeyExA()==0x%x\n"), GetLastError()))
- }
- else
- {
- DISPATCHER_LOG_INFO((("found subkey: %S\n"), subKeyName))
- bool bRes;
- // open the sub key
- bRes = subKey.Open(m_baseRegKey, subKeyName, KEY_READ);
- if (!bRes)
- {
- DISPATCHER_LOG_WRN((("error opening key %S :RegOpenKeyExA()==0x%x\n"), subKeyName, GetLastError()));
- }
- else
- {
- DISPATCHER_LOG_INFO((("opened key: %S\n"), subKeyName));
- mfxU32 vendorID = 0, deviceID = 0, merit = 0;
- DWORD size;
- // query vendor and device IDs
- size = sizeof(vendorID);
- bRes = subKey.Query(vendorIDKeyName, REG_DWORD, (LPBYTE) &vendorID, &size);
- DISPATCHER_LOG_OPERATION({
- if (bRes)
- {
- DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), vendorIDKeyName, vendorID));
- }
- else
- {
- DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), vendorIDKeyName, GetLastError()));
- }
- })
- if (bRes)
- {
- size = sizeof(deviceID);
- bRes = subKey.Query(deviceIDKeyName, REG_DWORD, (LPBYTE) &deviceID, &size);
- DISPATCHER_LOG_OPERATION({
- if (bRes)
- {
- DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), deviceIDKeyName, deviceID));
- }
- else
- {
- DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), deviceIDKeyName, GetLastError()));
- }
- })
- }
- // query merit value
- if (bRes)
- {
- size = sizeof(merit);
- bRes = subKey.Query(meritKeyName, REG_DWORD, (LPBYTE) &merit, &size);
- DISPATCHER_LOG_OPERATION({
- if (bRes)
- {
- DISPATCHER_LOG_INFO((("loaded %S : %d\n"), meritKeyName, merit));
- }
- else
- {
- DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"), meritKeyName, GetLastError()));
- }
- })
- }
- // if the library fits required parameters,
- // query the library's path
- if (bRes)
- {
- // compare device's and library's IDs
- if (MFX_LIB_HARDWARE == m_implType)
- {
- if (m_vendorID != vendorID)
- {
- bRes = false;
- DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), vendorIDKeyName, m_vendorID, vendorID));
- }
- if (bRes && m_deviceID != deviceID)
- {
- bRes = false;
- DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"), deviceIDKeyName, m_deviceID, deviceID));
- }
- }
- DISPATCHER_LOG_OPERATION({
- if (bRes)
- {
- if (!(((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
- (libMerit < merit)))
- {
- DISPATCHER_LOG_WRN((("merit conflict: lastMerit = 0x%x, requiredMerit = 0x%x, libraryMerit = 0x%x, lastindex = %d, index = %d\n")
- , m_lastLibMerit, merit, libMerit, m_lastLibIndex, index));
- }
- }})
- if ((bRes) &&
- ((m_lastLibMerit > merit) || ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
- (libMerit < merit))
- {
- wchar_t tmpPath[MFX_MAX_DLL_PATH];
- DWORD tmpPathSize = sizeof(tmpPath);
- bRes = subKey.Query(pathKeyName, REG_SZ, (LPBYTE) tmpPath, &tmpPathSize);
- if (!bRes)
- {
- DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
- }
- else
- {
- DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, tmpPath));
- wcscpy_s(libPath, sizeof(libPath) / sizeof(libPath[0]), tmpPath);
- wcscpy_s(m_SubKeyName, sizeof(m_SubKeyName) / sizeof(m_SubKeyName[0]), subKeyName);
- libMerit = merit;
- libIndex = index;
- // set the library's type
- if ((0 == vendorID) || (0 == deviceID))
- {
- *pImplType = MFX_LIB_SOFTWARE;
- DISPATCHER_LOG_INFO((("Library type is MFX_LIB_SOFTWARE\n")));
- }
- else
- {
- *pImplType = MFX_LIB_HARDWARE;
- DISPATCHER_LOG_INFO((("Library type is MFX_LIB_HARDWARE\n")));
- }
- }
- }
- }
- }
- }
- // advance key index
- index += 1;
- } while (enumRes);
- // if the library's path was successfully read,
- // the merit variable holds valid value
- if (0 == libMerit)
- {
- return MFX_ERR_NOT_FOUND;
- }
- wcscpy_s(pPath, pathSize, libPath);
- m_lastLibIndex = libIndex;
- m_lastLibMerit = libMerit;
- m_bIsSubKeyValid = true;
- #endif
- return MFX_ERR_NONE;
- } // mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion)
- mfxIMPL MFXLibraryIterator::GetImplementationType()
- {
- return m_implInterface;
- } // mfxIMPL MFXLibraryIterator::GetImplementationType()
- bool MFXLibraryIterator::GetSubKeyName(wchar_t *subKeyName, size_t length) const
- {
- wcscpy_s(subKeyName, length, m_SubKeyName);
- return m_bIsSubKeyValid;
- }
- } // namespace MFX
|