qsv: Update SDK version to v2022.2.4
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / qsv / libmfx / dispatcher / windows / mfx_win_reg_key.cpp
1 /*############################################################################
2   # Copyright (C) Intel Corporation
3   #
4   # SPDX-License-Identifier: MIT
5   ############################################################################*/
6
7 #if !defined(MEDIASDK_UWP_DISPATCHER)
8     #include "windows/mfx_win_reg_key.h"
9     #include "windows/mfx_dispatcher_log.h"
10
11     #define TRACE_WINREG_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[WINREG]: " str), __VA_ARGS__))
12
13 namespace MFX {
14
15 WinRegKey::WinRegKey(void) {
16     m_hKey = (HKEY)0;
17
18 } // WinRegKey::WinRegKey(void)
19
20 WinRegKey::~WinRegKey(void) {
21     Release();
22
23 } // WinRegKey::~WinRegKey(void)
24
25 void WinRegKey::Release(void) {
26     // close the opened key
27     if (m_hKey) {
28         RegCloseKey(m_hKey);
29     }
30
31     m_hKey = (HKEY)0;
32
33 } // void WinRegKey::Release(void)
34
35 bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired) {
36     LONG lRes;
37     HKEY hTemp;
38
39     //
40     // All operation are performed in this order by intention.
41     // It makes possible to reopen the keys, using itself as a base.
42     //
43
44     // try to the open registry key
45     lRes = RegOpenKeyExW(hRootKey, pSubKey, 0, samDesired, &hTemp);
46     if (ERROR_SUCCESS != lRes) {
47         DISPATCHER_LOG_OPERATION(SetLastError(lRes));
48         TRACE_WINREG_ERROR("Opening key \"%s\\%S\" : RegOpenKeyExW()==0x%x\n",
49                            (HKEY_LOCAL_MACHINE == hRootKey)  ? ("HKEY_LOCAL_MACHINE")
50                            : (HKEY_CURRENT_USER == hRootKey) ? ("HKEY_CURRENT_USER")
51                                                              : "UNSUPPORTED_KEY",
52                            pSubKey,
53                            GetLastError());
54         return false;
55     }
56
57     // release the object before initialization
58     Release();
59
60     // save the handle
61     m_hKey = hTemp;
62
63     return true;
64
65 } // bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired)
66
67 bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired) {
68     return Open(rootKey.m_hKey, pSubKey, samDesired);
69
70 } // bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired)
71
72 bool WinRegKey::QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData) {
73     DWORD keyType = type;
74     LONG lRes;
75
76     // query the value
77     lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, 0, pcbData);
78     if (ERROR_SUCCESS != lRes) {
79         DISPATCHER_LOG_OPERATION(SetLastError(lRes));
80         TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n",
81                            pValueName,
82                            GetLastError());
83         return false;
84     }
85
86     return true;
87 }
88
89 bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData) {
90     DWORD keyType = type;
91     LONG lRes;
92     DWORD dstSize = (pcbData) ? (*pcbData) : (0);
93
94     // query the value
95     lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, pData, pcbData);
96     if (ERROR_SUCCESS != lRes) {
97         DISPATCHER_LOG_OPERATION(SetLastError(lRes));
98         TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n",
99                            pValueName,
100                            GetLastError());
101         return false;
102     }
103
104     // check the type
105     if (keyType != type) {
106         TRACE_WINREG_ERROR("Querying \"%S\" : expectedType=%d, returned=%d\n",
107                            pValueName,
108                            type,
109                            keyType);
110         return false;
111     }
112
113     // terminate the string only if pointers not NULL
114     if ((REG_SZ == type || REG_EXPAND_SZ == type) && NULL != pData && NULL != pcbData) {
115         wchar_t *pString           = (wchar_t *)pData;
116         size_t NullEndingSizeBytes = sizeof(wchar_t); // size of string termination null character
117         if (dstSize < NullEndingSizeBytes) {
118             TRACE_WINREG_ERROR("Querying \"%S\" : buffer is too small for null-terminated string",
119                                pValueName);
120             return false;
121         }
122         size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes;
123         size_t maxStringIndex       = dstSize / sizeof(wchar_t) - 1;
124
125         size_t lastIndex =
126             (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t);
127
128         pString[lastIndex] = (wchar_t)0;
129     }
130     else if (REG_MULTI_SZ == type && NULL != pData && NULL != pcbData) {
131         wchar_t *pString = (wchar_t *)pData;
132         size_t NullEndingSizeBytes =
133             sizeof(wchar_t) * 2; // size of string termination null characters
134         if (dstSize < NullEndingSizeBytes) {
135             TRACE_WINREG_ERROR(
136                 "Querying \"%S\" : buffer is too small for multi-line null-terminated string",
137                 pValueName);
138             return false;
139         }
140         size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes;
141         size_t maxStringIndex       = dstSize / sizeof(wchar_t) - 1;
142
143         size_t lastIndex =
144             (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t) + 1;
145
146         // last 2 bytes should be 0 in case of REG_MULTI_SZ
147         pString[lastIndex] = pString[lastIndex - 1] = (wchar_t)0;
148     }
149
150     return true;
151
152 } // bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData)
153
154 bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType) {
155     LONG lRes;
156
157     // enum the values
158     lRes = RegEnumValueW(m_hKey, index, pValueName, pcchValueName, 0, pType, NULL, NULL);
159     if (ERROR_SUCCESS != lRes) {
160         DISPATCHER_LOG_OPERATION(SetLastError(lRes));
161         return false;
162     }
163
164     return true;
165
166 } // bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType)
167
168 bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName) {
169     LONG lRes;
170
171     // enum the keys
172     lRes = RegEnumKeyExW(m_hKey, index, pValueName, pcchValueName, NULL, NULL, NULL, NULL);
173     if (ERROR_SUCCESS != lRes) {
174         DISPATCHER_LOG_OPERATION(SetLastError(lRes));
175         TRACE_WINREG_ERROR("EnumKey with index=%d: RegEnumKeyExW()==0x%x\n", index, GetLastError());
176         return false;
177     }
178
179     return true;
180
181 } // bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName)
182
183 bool WinRegKey::QueryInfo(LPDWORD lpcSubkeys) {
184     LONG lRes;
185
186     lRes = RegQueryInfoKeyW(m_hKey, NULL, 0, 0, lpcSubkeys, 0, 0, 0, 0, 0, 0, 0);
187     if (ERROR_SUCCESS != lRes) {
188         TRACE_WINREG_ERROR("RegQueryInfoKeyW()==0x%x\n", lRes);
189         return false;
190     }
191     return true;
192
193 } //bool QueryInfo(LPDWORD lpcSubkeys);
194
195 } // namespace MFX
196
197 #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)