qsv: Update SDK version to v2022.2.4
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / qsv / libmfx / dispatcher / windows / mfx_driver_store_loader.cpp
1 /*############################################################################
2   # Copyright (C) Intel Corporation
3   #
4   # SPDX-License-Identifier: MIT
5   ############################################################################*/
6
7 #include <tchar.h>
8
9 #include "windows/mfx_dispatcher_log.h"
10 #include "windows/mfx_driver_store_loader.h"
11 #include "windows/mfx_load_dll.h"
12 #include "windows/mfx_vector.h"
13
14 namespace MFX {
15
16 inline bool IsIntelDeviceInstanceID(const wchar_t *DeviceID) {
17     return wcsstr(DeviceID, L"VEN_8086") || wcsstr(DeviceID, L"ven_8086");
18 }
19
20 inline bool ExctractDeviceID(const wchar_t *descrString, mfxU32 &deviceID) {
21     const wchar_t *begin = wcsstr(descrString, L"DEV_");
22
23     if (!begin) {
24         begin = wcsstr(descrString, L"dev_");
25         if (!begin) {
26             DISPATCHER_LOG_WRN(("exctracting device id: failed to find device id substring\n"));
27             return false;
28         }
29     }
30
31     begin += wcslen(L"DEV_");
32     deviceID = wcstoul(begin, NULL, 16);
33     if (!deviceID) {
34         DISPATCHER_LOG_WRN(("exctracting device id: failed to convert device id str to int\n"));
35         return false;
36     }
37
38     return true;
39 }
40
41 DriverStoreLoader::DriverStoreLoader(void)
42         : m_moduleCfgMgr(NULL),
43           m_pCM_Get_Device_ID_List_Size(NULL),
44           m_pCM_Get_Device_ID_List(NULL),
45           m_pCM_Locate_DevNode(NULL),
46           m_pCM_Open_DevNode_Key(NULL) {}
47
48 DriverStoreLoader::~DriverStoreLoader(void) {}
49
50 bool DriverStoreLoader::GetDriverStorePath(wchar_t *path,
51                                            DWORD dwPathSize,
52                                            mfxU32 deviceID,
53                                            const wchar_t *driverKey) {
54     if (path == NULL || dwPathSize == 0) {
55         return false;
56     }
57
58     // Obtain a PnP handle to the Intel graphics adapter
59     CONFIGRET result       = CR_SUCCESS;
60     ULONG DeviceIDListSize = 0;
61     MFXVector<WCHAR> DeviceIDList;
62     wchar_t DisplayGUID[40];
63     DEVINST DeviceInst;
64
65     DISPATCHER_LOG_INFO(("Looking for MediaSDK in DriverStore\n"));
66
67     if (!LoadCfgMgr() || !LoadCmFuncs()) {
68         return false;
69     }
70
71     if (StringFromGUID2(GUID_DEVCLASS_DISPLAY, DisplayGUID, sizeof(DisplayGUID)) == 0) {
72         DISPATCHER_LOG_WRN(("Couldn't prepare string from GUID\n"));
73         return false;
74     }
75
76     do {
77         result =
78             m_pCM_Get_Device_ID_List_Size(&DeviceIDListSize,
79                                           DisplayGUID,
80                                           CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT);
81         if (result != CR_SUCCESS) {
82             break;
83         }
84
85         try {
86             DeviceIDList.resize(DeviceIDListSize);
87         }
88         catch (...) {
89             return false;
90         }
91         result = m_pCM_Get_Device_ID_List(DisplayGUID,
92                                           DeviceIDList.data(),
93                                           DeviceIDListSize,
94                                           CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT);
95
96     } while (result == CR_BUFFER_SMALL);
97
98     if (result != CR_SUCCESS) {
99         return false;
100     }
101
102     //Look for MediaSDK record
103     wchar_t *begin = DeviceIDList.data();
104     wchar_t *end   = begin + DeviceIDList.size();
105     size_t len     = 0;
106
107     for (; (begin < end) && (len = wcslen(begin)) > 0; begin += len + 1) {
108         if (IsIntelDeviceInstanceID(begin)) {
109             mfxU32 curDeviceID = 0;
110             if (!ExctractDeviceID(begin, curDeviceID) || curDeviceID != deviceID) {
111                 continue;
112             }
113
114             result = m_pCM_Locate_DevNode(&DeviceInst, begin, CM_LOCATE_DEVNODE_NORMAL);
115             if (result != CR_SUCCESS) {
116                 continue;
117             }
118
119             HKEY hKey_sw;
120             result = m_pCM_Open_DevNode_Key(DeviceInst,
121                                             KEY_READ,
122                                             0,
123                                             RegDisposition_OpenExisting,
124                                             &hKey_sw,
125                                             CM_REGISTRY_SOFTWARE);
126             if (result != CR_SUCCESS) {
127                 continue;
128             }
129
130             ULONG nError;
131
132             DWORD pathSize = dwPathSize;
133
134             nError = RegQueryValueExW(hKey_sw, driverKey, 0, NULL, (LPBYTE)path, &pathSize);
135
136             RegCloseKey(hKey_sw);
137
138             if (ERROR_SUCCESS == nError) {
139                 if (path[wcslen(path) - 1] != '/' && path[wcslen(path) - 1] != '\\') {
140                     wcscat_s(path, MFX_MAX_DLL_PATH, L"\\");
141                 }
142                 DISPATCHER_LOG_INFO(("DriverStore path is found\n"));
143                 return true;
144             }
145         }
146     }
147
148     DISPATCHER_LOG_INFO(("DriverStore path isn't found\n"));
149     return false;
150
151 } // bool DriverStoreLoader::GetDriverStorePath(wchar_t * path, DWORD dwPathSize, wchar_t *driverKey)
152
153 bool DriverStoreLoader::LoadCfgMgr() {
154     if (!m_moduleCfgMgr) {
155         m_moduleCfgMgr = mfx_dll_load(L"cfgmgr32.dll");
156
157         if (!m_moduleCfgMgr) {
158             DISPATCHER_LOG_WRN(("cfgmgr32.dll couldn't be loaded\n"));
159             return false;
160         }
161     }
162
163     return true;
164
165 } // bool DriverStoreLoader::LoadCfgMgr()
166
167 bool DriverStoreLoader::LoadCmFuncs() {
168     if (!m_pCM_Get_Device_ID_List || !m_pCM_Get_Device_ID_List_Size || !m_pCM_Locate_DevNode ||
169         !m_pCM_Open_DevNode_Key) {
170         m_pCM_Get_Device_ID_List =
171             (Func_CM_Get_Device_ID_ListW)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
172                                                           "CM_Get_Device_ID_ListW");
173         m_pCM_Get_Device_ID_List_Size =
174             (Func_CM_Get_Device_ID_List_SizeW)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
175                                                                "CM_Get_Device_ID_List_SizeW");
176         m_pCM_Locate_DevNode   = (Func_CM_Locate_DevNodeW)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
177                                                                          "CM_Locate_DevNodeW");
178         m_pCM_Open_DevNode_Key = (Func_CM_Open_DevNode_Key)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
179                                                                             "CM_Open_DevNode_Key");
180
181         if (!m_pCM_Get_Device_ID_List || !m_pCM_Get_Device_ID_List_Size || !m_pCM_Locate_DevNode ||
182             !m_pCM_Open_DevNode_Key) {
183             DISPATCHER_LOG_WRN(("One of cfgmgr32.dll function isn't found\n"));
184             return false;
185         }
186     }
187
188     return true;
189
190 } // bool DriverStoreLoader::LoadCmFuncs()
191
192 } // namespace MFX